// FetchAllDBlocks gets all of the fbInfo func (db *LevelDb) FetchAllDBlocks() (dBlocks []common.DirectoryBlock, err error) { db.dbLock.Lock() defer db.dbLock.Unlock() var fromkey []byte = []byte{byte(TBL_DB)} // Table Name (1 bytes) // Timestamp (8 bytes) var tokey []byte = []byte{byte(TBL_DB + 1)} // Table Name (1 bytes) dBlockSlice := make([]common.DirectoryBlock, 0, 10) iter := db.lDb.NewIterator(&util.Range{Start: fromkey, Limit: tokey}, db.ro) for iter.Next() { var dBlock common.DirectoryBlock _, err := dBlock.UnmarshalBinaryData(iter.Value()) if err != nil { return nil, err } //TODO: to be optimized?? dBlock.DBHash = common.Sha(iter.Value()) dBlockSlice = append(dBlockSlice, dBlock) } iter.Release() err = iter.Error() return dBlockSlice, nil }
// ProcessDBlockBatche inserts the DBlock and update all it's dbentries in DB func (db *LevelDb) ProcessDBlockBatch(dblock *common.DirectoryBlock) error { if dblock != nil { if db.lbatch == nil { db.lbatch = new(leveldb.Batch) } defer db.lbatch.Reset() binaryDblock, err := dblock.MarshalBinary() if err != nil { return err } if dblock.DBHash == nil { dblock.DBHash = common.Sha(binaryDblock) } if dblock.KeyMR == nil { dblock.BuildKeyMerkleRoot() } // Insert the binary directory block var key []byte = []byte{byte(TBL_DB)} key = append(key, dblock.DBHash.Bytes()...) db.lbatch.Put(key, binaryDblock) // Insert block height cross reference var dbNumkey []byte = []byte{byte(TBL_DB_NUM)} var buf bytes.Buffer binary.Write(&buf, binary.BigEndian, dblock.Header.DBHeight) dbNumkey = append(dbNumkey, buf.Bytes()...) db.lbatch.Put(dbNumkey, dblock.DBHash.Bytes()) // Insert the directory block merkle root cross reference key = []byte{byte(TBL_DB_MR)} key = append(key, dblock.KeyMR.Bytes()...) binaryDBHash, _ := dblock.DBHash.MarshalBinary() db.lbatch.Put(key, binaryDBHash) // Update the chain head reference key = []byte{byte(TBL_CHAIN_HEAD)} key = append(key, common.D_CHAINID...) db.lbatch.Put(key, dblock.KeyMR.Bytes()) err = db.lDb.Write(db.lbatch, db.wo) if err != nil { return err } // Update DirBlock Height cache db.lastDirBlkHeight = int64(dblock.Header.DBHeight) db.lastDirBlkSha, _ = wire.NewShaHash(dblock.DBHash.Bytes()) db.lastDirBlkShaCached = true } return nil }
func getAll() error { dbs := make([]*common.DirectoryBlock, 0, 100) next := DBHeadStr for { blk, err := factom.GetRaw(next) if err != nil { panic(err.Error()) } db := new(common.DirectoryBlock) err = db.UnmarshalBinary(blk) if err != nil { panic(err.Error()) } dbs = append(dbs, db) if bytes.Equal(db.Header.PrevKeyMR.Bytes(), DBHeadLast) { break } next = hex.EncodeToString(db.Header.PrevKeyMR.Bytes()) } DBHeadLast = DBHead for i := len(dbs) - 1; i >= 0; i-- { DirectoryBlocks = append(DirectoryBlocks, dbs[i]) fb := new(block.FBlock) var fcnt int for _, dbe := range dbs[i].DBEntries { if bytes.Equal(dbe.ChainID.Bytes(), common.FACTOID_CHAINID) { fcnt++ hashstr := hex.EncodeToString(dbe.KeyMR.Bytes()) fdata, err := factom.GetRaw(hashstr) if err != nil { panic(err.Error()) } err = fb.UnmarshalBinary(fdata) if err != nil { panic(err.Error()) } FactoidBlocks = append(FactoidBlocks, fb) break } } if fb == nil { panic("Missing Factoid Block from a directory block") } if fcnt > 1 { panic("More than one Factom Block found in a directory block.") } if err := ProcessFB(fb); err != nil { return err } } return nil }
// pushGetNonDirDataMsg takes the passed DBlock // and return corresponding data block like Factoid block, // EC block, Entry block, and Entry func (p *peer) pushGetNonDirDataMsg(dblock *common.DirectoryBlock) { binary, _ := dblock.MarshalBinary() commonHash := common.Sha(binary) hash, _ := wire.NewShaHash(commonHash.Bytes()) iv := wire.NewInvVect(wire.InvTypeFactomNonDirBlock, hash) gdmsg := wire.NewMsgGetNonDirData() gdmsg.AddInvVect(iv) if len(gdmsg.InvList) > 0 { p.QueueMessage(gdmsg, nil) } }
// to export individual block once at a time - for debugging ------------------------ func exportDBlock(block *common.DirectoryBlock) { if block == nil || procLog.Level() < factomlog.Info { //log.Println("no blocks to save for chain: " + string (*chain.ChainID)) return } data, err := block.MarshalBinary() if err != nil { panic(err) } strChainID := dchain.ChainID.String() if fileNotExists(dataStorePath + strChainID) { err := os.MkdirAll(dataStorePath+strChainID, 0777) if err == nil { procLog.Info("Created directory " + dataStorePath + strChainID) } else { procLog.Error(err) } } err = ioutil.WriteFile(fmt.Sprintf(dataStorePath+strChainID+"/store.%09d.block", block.Header.DBHeight), data, 0777) if err != nil { panic(err) } }
func getAll() error { dbs := make([]*common.DirectoryBlock, 0, 100) next := DBHeadStr for { blk, err := factom.GetRaw(next) if err != nil { panic(err.Error()) } db := new(common.DirectoryBlock) err = db.UnmarshalBinary(blk) if err != nil { panic(err.Error()) } dbs = append(dbs, db) if bytes.Equal(db.Header.PrevKeyMR.Bytes(), common.ZERO_HASH[:]) { break } next = hex.EncodeToString(db.Header.PrevKeyMR.Bytes()) } for i := len(dbs) - 1; i >= 0; i-- { DirectoryBlocks = append(DirectoryBlocks, dbs[i]) fb := new(block.FBlock) for _, dbe := range dbs[i].DBEntries { if bytes.Equal(dbe.ChainID.Bytes(), common.FACTOID_CHAINID) { hashstr := hex.EncodeToString(dbe.KeyMR.Bytes()) fdata, err := factom.GetRaw(hashstr) if err != nil { panic(err.Error()) } err = fb.UnmarshalBinary(fdata) if err != nil { panic(err.Error()) } FactoidBlocks = append(FactoidBlocks, fb) break } } if fb == nil { fmt.Println("Missing Factoid Block") } } return nil }
// Validate a dir block func validateDBlock(c *common.DChain, b *common.DirectoryBlock) (merkleRoot *common.Hash, dbHash *common.Hash, err error) { bodyMR, err := b.BuildBodyMR() if err != nil { return nil, nil, err } if !b.Header.BodyMR.IsSameAs(bodyMR) { return nil, nil, errors.New("Invalid body MR for dir block: " + string(b.Header.DBHeight)) } for _, dbEntry := range b.DBEntries { switch dbEntry.ChainID.String() { case ecchain.ChainID.String(): err := validateCBlockByMR(dbEntry.KeyMR) if err != nil { return nil, nil, err } case achain.ChainID.String(): err := validateABlockByMR(dbEntry.KeyMR) if err != nil { return nil, nil, err } case wire.FChainID.String(): err := validateFBlockByMR(dbEntry.KeyMR) if err != nil { return nil, nil, err } default: err := validateEBlockByMR(dbEntry.ChainID, dbEntry.KeyMR) if err != nil { return nil, nil, err } } } b.DBHash, _ = common.CreateHash(b) b.BuildKeyMerkleRoot() return b.KeyMR, b.DBHash, nil }