// 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 }
// 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 }