// Initialize the entry chains in memory from db func initEChainFromDB(chain *common.EChain) { eBlocks, _ := db.FetchAllEBlocksByChain(chain.ChainID) sort.Sort(util.ByEBlockIDAccending(*eBlocks)) for i := 0; i < len(*eBlocks); i = i + 1 { if uint32(i) != (*eBlocks)[i].Header.EBSequence { panic(errors.New("BlockID does not equal index for chain:" + chain.ChainID.String() + " block:" + fmt.Sprintf("%v", (*eBlocks)[i].Header.EBSequence))) } } var err error if len(*eBlocks) == 0 { chain.NextBlockHeight = 0 chain.NextBlock, err = common.MakeEBlock(chain, nil) if err != nil { panic(err) } } else { chain.NextBlockHeight = uint32(len(*eBlocks)) chain.NextBlock, err = common.MakeEBlock(chain, &(*eBlocks)[len(*eBlocks)-1]) if err != nil { panic(err) } } // Initialize chain with the first entry (Name and rules) for non-server mode if nodeMode != common.SERVER_NODE && chain.FirstEntry == nil && len(*eBlocks) > 0 { chain.FirstEntry, _ = db.FetchEntryByHash((*eBlocks)[0].Body.EBEntries[0]) if chain.FirstEntry != nil { db.InsertChain(chain) } } }
func (db *LevelDb) InsertChainMultiBatch(chain *common.EChain) error { if chain == nil { return nil } if db.lbatch == nil { return fmt.Errorf("db.lbatch == nil") } binaryChain, err := chain.MarshalBinary() if err != nil { return err } var chainByHashKey []byte = []byte{byte(TBL_CHAIN_HASH)} chainByHashKey = append(chainByHashKey, chain.ChainID.Bytes()...) db.lbatch.Put(chainByHashKey, binaryChain) return nil }
// InsertChain inserts the newly created chain into db func (db *LevelDb) InsertChain(chain *common.EChain) (err error) { db.dbLock.Lock() defer db.dbLock.Unlock() if db.lbatch == nil { db.lbatch = new(leveldb.Batch) } defer db.lbatch.Reset() binaryChain, _ := chain.MarshalBinary() var chainByHashKey []byte = []byte{byte(TBL_CHAIN_HASH)} chainByHashKey = append(chainByHashKey, chain.ChainID.Bytes()...) db.lbatch.Put(chainByHashKey, binaryChain) err = db.lDb.Write(db.lbatch, db.wo) if err != nil { log.Println("batch failed %v\n", err) return err } return nil }
// Validate the new blocks in mem pool and store them in db // Need to make a batch insert in db in milestone 2 func storeBlocksFromMemPool(b *common.DirectoryBlock, fMemPool *ftmMemPool, db database.Db) error { fMemPool.RLock() defer fMemPool.RUnlock() for _, dbEntry := range b.DBEntries { switch dbEntry.ChainID.String() { case ecchain.ChainID.String(): ecBlkMsg := fMemPool.blockpool[dbEntry.KeyMR.String()].(*wire.MsgECBlock) err := db.ProcessECBlockBatch(ecBlkMsg.ECBlock) if err != nil { return err } // needs to be improved?? initializeECreditMap(ecBlkMsg.ECBlock) // for debugging exportECBlock(ecBlkMsg.ECBlock) case achain.ChainID.String(): aBlkMsg := fMemPool.blockpool[dbEntry.KeyMR.String()].(*wire.MsgABlock) err := db.ProcessABlockBatch(aBlkMsg.ABlk) if err != nil { return err } // for debugging exportABlock(aBlkMsg.ABlk) case fchain.ChainID.String(): fBlkMsg := fMemPool.blockpool[dbEntry.KeyMR.String()].(*wire.MsgFBlock) err := db.ProcessFBlockBatch(fBlkMsg.SC) if err != nil { return err } // Initialize the Factoid State err = common.FactoidState.AddTransactionBlock(fBlkMsg.SC) FactoshisPerCredit = fBlkMsg.SC.GetExchRate() if err != nil { return err } // for debugging exportFctBlock(fBlkMsg.SC) default: // handle Entry Block eBlkMsg, _ := fMemPool.blockpool[dbEntry.KeyMR.String()].(*wire.MsgEBlock) // store entry in db first for _, ebEntry := range eBlkMsg.EBlk.Body.EBEntries { if msg, foundInMemPool := fMemPool.blockpool[ebEntry.String()]; foundInMemPool { err := db.InsertEntry(msg.(*wire.MsgEntry).Entry) if err != nil { return err } } } // Store Entry Block in db err := db.ProcessEBlockBatch(eBlkMsg.EBlk) if err != nil { return err } // create a chain when it's the first block of the entry chain if eBlkMsg.EBlk.Header.EBSequence == 0 { chain := new(common.EChain) chain.ChainID = eBlkMsg.EBlk.Header.ChainID chain.FirstEntry, _ = db.FetchEntryByHash(eBlkMsg.EBlk.Body.EBEntries[0]) if chain.FirstEntry == nil { return errors.New("First entry not found for chain:" + eBlkMsg.EBlk.Header.ChainID.String()) } db.InsertChain(chain) chainIDMap[chain.ChainID.String()] = chain } // for debugging exportEBlock(eBlkMsg.EBlk) } } dbhash, dbHeight, _ := db.FetchBlockHeightCache() //fmt.Printf("last block height is %d, to-be-saved block height is %d\n", dbHeight, b.Header.DBHeight) // Store the dir block err := db.ProcessDBlockBatch(b) if err != nil { return err } lastDirBlockTimestamp = b.Header.Timestamp // Update dir block height cache in db commonHash, _ := common.CreateHash(b) db.UpdateBlockHeightCache(b.Header.DBHeight, commonHash) // for debugging exportDBlock(b) // this means, there's syncup breakage happened, and let's renew syncup. if uint32(dbHeight) < b.Header.DBHeight-1 { startHash, _ := wire.NewShaHash(dbhash.Bytes()) stopHash, _ := wire.NewShaHash(commonHash.Bytes()) outMsgQueue <- &wire.MsgInt_ReSyncup{ StartHash: startHash, StopHash: stopHash, } } return nil }
// Validate the new blocks in mem pool and store them in db // Need to make a batch insert in db in milestone 2 func storeBlocksFromMemPool(b *common.DirectoryBlock, fMemPool *ftmMemPool, db database.Db) error { for _, dbEntry := range b.DBEntries { switch dbEntry.ChainID.String() { case ecchain.ChainID.String(): ecBlkMsg := fMemPool.blockpool[dbEntry.KeyMR.String()].(*wire.MsgECBlock) err := db.ProcessECBlockBatch(ecBlkMsg.ECBlock) if err != nil { return err } // needs to be improved?? initializeECreditMap(ecBlkMsg.ECBlock) // for debugging exportECBlock(ecBlkMsg.ECBlock) case achain.ChainID.String(): aBlkMsg := fMemPool.blockpool[dbEntry.KeyMR.String()].(*wire.MsgABlock) err := db.ProcessABlockBatch(aBlkMsg.ABlk) if err != nil { return err } // for debugging exportABlock(aBlkMsg.ABlk) case fchain.ChainID.String(): fBlkMsg := fMemPool.blockpool[dbEntry.KeyMR.String()].(*wire.MsgFBlock) err := db.ProcessFBlockBatch(fBlkMsg.SC) if err != nil { return err } // Initialize the Factoid State err = common.FactoidState.AddTransactionBlock(fBlkMsg.SC) FactoshisPerCredit = fBlkMsg.SC.GetExchRate() if err != nil { return err } // for debugging exportFctBlock(fBlkMsg.SC) default: // handle Entry Block eBlkMsg, _ := fMemPool.blockpool[dbEntry.KeyMR.String()].(*wire.MsgEBlock) // store entry in db first for _, ebEntry := range eBlkMsg.EBlk.Body.EBEntries { if msg, foundInMemPool := fMemPool.blockpool[ebEntry.String()]; foundInMemPool { err := db.InsertEntry(msg.(*wire.MsgEntry).Entry) if err != nil { return err } } } // Store Entry Block in db err := db.ProcessEBlockBatch(eBlkMsg.EBlk) if err != nil { return err } // create a chain when it's the first block of the entry chain if eBlkMsg.EBlk.Header.EBSequence == 0 { chain := new(common.EChain) chain.ChainID = eBlkMsg.EBlk.Header.ChainID chain.FirstEntry, _ = db.FetchEntryByHash(eBlkMsg.EBlk.Body.EBEntries[0]) if chain.FirstEntry == nil { return errors.New("First entry not found for chain:" + eBlkMsg.EBlk.Header.ChainID.String()) } db.InsertChain(chain) chainIDMap[chain.ChainID.String()] = chain } // for debugging exportEBlock(eBlkMsg.EBlk) } } // Store the dir block err := db.ProcessDBlockBatch(b) if err != nil { return err } // Update dir block height cache in db commonHash, _ := common.CreateHash(b) db.UpdateBlockHeightCache(b.Header.DBHeight, commonHash) // for debugging exportDBlock(b) return nil }