forked from cerc-io/plugeth
Merge pull request #1475 from obscuren/issue1473
core: during chain reorg rewrite receipts and transactions
This commit is contained in:
commit
9addb3df3a
@ -342,7 +342,7 @@ func (sm *BlockProcessor) VerifyUncles(statedb *state.StateDB, block, parent *ty
|
||||
// GetBlockReceipts returns the receipts beloniging to the block hash
|
||||
func (sm *BlockProcessor) GetBlockReceipts(bhash common.Hash) types.Receipts {
|
||||
if block := sm.ChainManager().GetBlock(bhash); block != nil {
|
||||
return GetReceiptsFromBlock(sm.extraDb, block)
|
||||
return GetBlockReceipts(sm.extraDb, block.Hash())
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -352,7 +352,7 @@ func (sm *BlockProcessor) GetBlockReceipts(bhash common.Hash) types.Receipts {
|
||||
// where it tries to get it from the (updated) method which gets them from the receipts or
|
||||
// the depricated way by re-processing the block.
|
||||
func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err error) {
|
||||
receipts := GetReceiptsFromBlock(sm.extraDb, block)
|
||||
receipts := GetBlockReceipts(sm.extraDb, block.Hash())
|
||||
if len(receipts) > 0 {
|
||||
// coalesce logs
|
||||
for _, receipt := range receipts {
|
||||
|
@ -667,6 +667,8 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
|
||||
queue[i] = ChainSplitEvent{block, logs}
|
||||
queueEvent.splitCount++
|
||||
}
|
||||
PutBlockReceipts(self.extraDb, block, receipts)
|
||||
|
||||
stats.processed++
|
||||
}
|
||||
|
||||
@ -744,7 +746,12 @@ func (self *ChainManager) merge(oldBlock, newBlock *types.Block) error {
|
||||
// insert blocks. Order does not matter. Last block will be written in ImportChain itself which creates the new head properly
|
||||
self.mu.Lock()
|
||||
for _, block := range newChain {
|
||||
// insert the block in the canonical way, re-writing history
|
||||
self.insert(block)
|
||||
// write canonical receipts and transactions
|
||||
PutTransactions(self.extraDb, block, block.Transactions())
|
||||
PutReceipts(self.extraDb, GetBlockReceipts(self.extraDb, block.Hash()))
|
||||
|
||||
}
|
||||
self.mu.Unlock()
|
||||
|
||||
|
@ -24,7 +24,10 @@ import (
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
var receiptsPre = []byte("receipts-")
|
||||
var (
|
||||
receiptsPre = []byte("receipts-")
|
||||
blockReceiptsPre = []byte("receipts-block-")
|
||||
)
|
||||
|
||||
// PutTransactions stores the transactions in the given database
|
||||
func PutTransactions(db common.Database, block *types.Block, txs types.Transactions) {
|
||||
@ -85,17 +88,40 @@ func GetReceipt(db common.Database, txHash common.Hash) *types.Receipt {
|
||||
return &receipt
|
||||
}
|
||||
|
||||
// GetReceiptFromBlock returns all receipts with the given block
|
||||
func GetReceiptsFromBlock(db common.Database, block *types.Block) types.Receipts {
|
||||
// at some point we want:
|
||||
//receipts := make(types.Receipts, len(block.Transactions()))
|
||||
// but since we need to support legacy, we can't (yet)
|
||||
var receipts types.Receipts
|
||||
for _, tx := range block.Transactions() {
|
||||
if receipt := GetReceipt(db, tx.Hash()); receipt != nil {
|
||||
receipts = append(receipts, receipt)
|
||||
}
|
||||
// GetBlockReceipts returns the receipts generated by the transactions
|
||||
// included in block's given hash.
|
||||
func GetBlockReceipts(db common.Database, hash common.Hash) types.Receipts {
|
||||
data, _ := db.Get(append(blockReceiptsPre, hash[:]...))
|
||||
if len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var receipts types.Receipts
|
||||
err := rlp.DecodeBytes(data, &receipts)
|
||||
if err != nil {
|
||||
glog.V(logger.Core).Infoln("GetReceiptse err", err)
|
||||
}
|
||||
return receipts
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user