Skip to content

Commit

Permalink
Extra receipt for internal EVM call when finalizing blocks (#584)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrsmkl authored and Asa Oines committed Nov 20, 2019
1 parent 6ff30e7 commit 5dbc701
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 2 deletions.
7 changes: 7 additions & 0 deletions consensus/istanbul/backend/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,13 @@ func (sb *Backend) Finalize(chain consensus.ChainReader, header *types.Header, s
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
header.UncleHash = nilUncleHash

if len(state.GetLogs(common.Hash{})) > 0 {
receipt := types.NewReceipt(nil, false, 0)
receipt.Logs = state.GetLogs(common.Hash{})
receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
receipts = append(receipts, receipt)
}

// Assemble and return the final block for sealing
return types.NewBlock(header, txs, nil, receipts, randomness), nil
}
Expand Down
17 changes: 15 additions & 2 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -786,11 +786,12 @@ func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts ty
signer := types.MakeSigner(config, block.Number())

transactions, logIndex := block.Transactions(), uint(0)
if len(transactions) != len(receipts) {
// The receipts may include an additional "block finalization" receipt
if len(transactions) != len(receipts) && len(transactions)+1 != len(receipts) {
return errors.New("transaction and receipt count mismatch")
}

for j := 0; j < len(receipts); j++ {
for j := 0; j < len(transactions); j++ {
// The transaction hash can be retrieved from the transaction itself
receipts[j].TxHash = transactions[j].Hash()

Expand All @@ -816,6 +817,18 @@ func SetReceiptsData(config *params.ChainConfig, block *types.Block, receipts ty
logIndex++
}
}
// Handle block finalization receipt
if len(transactions)+1 == len(receipts) {
j := len(transactions)
for k := 0; k < len(receipts[j].Logs); k++ {
receipts[j].Logs[k].BlockNumber = block.NumberU64()
receipts[j].Logs[k].BlockHash = block.Hash()
receipts[j].Logs[k].TxHash = block.Hash()
receipts[j].Logs[k].TxIndex = uint(j)
receipts[j].Logs[k].Index = logIndex
logIndex++
}
}
return nil
}

Expand Down
12 changes: 12 additions & 0 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,20 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
allLogs = append(allLogs, receipt.Logs...)
}
// Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
statedb.Prepare(common.Hash{}, block.Hash(), len(block.Transactions()))
p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles(), receipts, block.Randomness())

if len(statedb.GetLogs(common.Hash{})) > 0 {
receipt := types.NewReceipt(nil, false, 0)
receipt.Logs = statedb.GetLogs(common.Hash{})
receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
for i := range receipt.Logs {
receipt.Logs[i].TxIndex = uint(len(receipts))
receipt.Logs[i].TxHash = block.Hash()
}
receipts = append(receipts, receipt)
}

return receipts, allLogs, *usedGas, nil
}

Expand Down
15 changes: 15 additions & 0 deletions miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,10 @@ func (w *worker) resultLoop() {
// receipt/log of individual transactions were created.
for _, log := range receipt.Logs {
log.BlockHash = hash
// Handle block finalization receipt
if (log.TxHash == common.Hash{}) {
log.TxHash = hash
}
}
logs = append(logs, receipt.Logs...)
}
Expand Down Expand Up @@ -1068,6 +1072,17 @@ func (w *worker) commit(uncles []*types.Header, interval func(), update bool, st
}

block, err := w.engine.Finalize(w.chain, w.current.header, s, w.current.txs, uncles, w.current.receipts, w.current.randomness)

if len(s.GetLogs(common.Hash{})) > 0 {
receipt := types.NewReceipt(nil, false, 0)
receipt.Logs = s.GetLogs(common.Hash{})
for i := range receipt.Logs {
receipt.Logs[i].TxIndex = uint(len(receipts))
}
receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
receipts = append(receipts, receipt)
}

if err != nil {
log.Error("Unable to finalize block", "err", err)
return err
Expand Down

0 comments on commit 5dbc701

Please sign in to comment.