// PutReceipts stores the receipts in the current database func PutReceipts(db common.Database, receipts types.Receipts) error { batch := new(leveldb.Batch) _, batchWrite := db.(*ethdb.LDBDatabase) for _, receipt := range receipts { storageReceipt := (*types.ReceiptForStorage)(receipt) bytes, err := rlp.EncodeToBytes(storageReceipt) if err != nil { return err } if batchWrite { batch.Put(append(receiptsPre, receipt.TxHash[:]...), bytes) } else { err = db.Put(append(receiptsPre, receipt.TxHash[:]...), bytes) if err != nil { return err } } } if db, ok := db.(*ethdb.LDBDatabase); ok { if err := db.LDB().Write(batch, nil); err != nil { return err } } return nil }
// WriteCanonNumber writes the canonical hash for the given block func WriteCanonNumber(db common.Database, block *types.Block) error { key := append(blockNumPre, block.Number().Bytes()...) err := db.Put(key, block.Hash().Bytes()) if err != nil { return err } return nil }
func saveBlockchainVersion(db common.Database, bcVersion int) { d, _ := db.Get([]byte("BlockchainVersion")) blockchainVersion := common.NewValue(d).Uint() if blockchainVersion == 0 { db.Put([]byte("BlockchainVersion"), common.NewValue(bcVersion).Bytes()) } }
// WriteHead force writes the current head func WriteHead(db common.Database, block *types.Block) error { err := WriteCanonNumber(db, block) if err != nil { return err } err = db.Put([]byte("LastBlock"), block.Hash().Bytes()) if err != nil { return err } return nil }
// WriteBlock writes a block to the database func WriteBlock(db common.Database, block *types.Block) error { tstart := time.Now() enc, _ := rlp.EncodeToBytes((*types.StorageBlock)(block)) key := append(blockHashPre, block.Hash().Bytes()...) err := db.Put(key, enc) if err != nil { glog.Fatal("db write fail:", err) return err } if glog.V(logger.Debug) { glog.Infof("wrote block #%v %s. Took %v\n", block.Number(), common.PP(block.Hash().Bytes()), time.Since(tstart)) } return nil }
// PutBlockReceipts stores the block's transactions associated receipts // and stores them by block hash in a single slice. This is required for // forks and chain reorgs func PutBlockReceipts(db common.Database, block *types.Block, receipts types.Receipts) error { rs := make([]*types.ReceiptForStorage, len(receipts)) for i, receipt := range receipts { rs[i] = (*types.ReceiptForStorage)(receipt) } bytes, err := rlp.EncodeToBytes(rs) if err != nil { return err } hash := block.Hash() err = db.Put(append(blockReceiptsPre, hash[:]...), bytes) if err != nil { return err } return nil }
// PutTransactions stores the transactions in the given database func PutTransactions(db common.Database, block *types.Block, txs types.Transactions) { batch := new(leveldb.Batch) _, batchWrite := db.(*ethdb.LDBDatabase) for i, tx := range block.Transactions() { rlpEnc, err := rlp.EncodeToBytes(tx) if err != nil { glog.V(logger.Debug).Infoln("Failed encoding tx", err) return } if batchWrite { batch.Put(tx.Hash().Bytes(), rlpEnc) } else { db.Put(tx.Hash().Bytes(), rlpEnc) } var txExtra struct { BlockHash common.Hash BlockIndex uint64 Index uint64 } txExtra.BlockHash = block.Hash() txExtra.BlockIndex = block.NumberU64() txExtra.Index = uint64(i) rlpMeta, err := rlp.EncodeToBytes(txExtra) if err != nil { glog.V(logger.Debug).Infoln("Failed encoding tx meta data", err) return } if batchWrite { batch.Put(append(tx.Hash().Bytes(), 0x0001), rlpMeta) } else { db.Put(append(tx.Hash().Bytes(), 0x0001), rlpMeta) } } if db, ok := db.(*ethdb.LDBDatabase); ok { if err := db.LDB().Write(batch, nil); err != nil { glog.V(logger.Error).Infoln("db write err:", err) } } }