Skip to content

Commit

Permalink
Merge pull request #5542 from onflow/ramtin/5509-populate-receipt-root
Browse files Browse the repository at this point in the history
[Flow EVM] populate receipt root hash in blocks
  • Loading branch information
ramtinms authored Mar 20, 2024
2 parents 00e4924 + b621329 commit dcb7fee
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 7 deletions.
7 changes: 5 additions & 2 deletions fvm/evm/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ func (h *ContractHandler) run(

bp.AppendTxHash(res.TxHash)

// TODO: in the future we might update the receipt hash here
// Populate receipt root
bp.PopulateReceiptRoot([]types.Result{*res})

blockHash, err := bp.Hash()
if err != nil {
Expand Down Expand Up @@ -307,7 +308,9 @@ func (h *ContractHandler) executeAndHandleCall(
}

bp.AppendTxHash(res.TxHash)
// TODO: in the future we might update the receipt hash here

// Populate receipt root
bp.PopulateReceiptRoot([]types.Result{*res})

if totalSupplyDiff != nil {
if deductSupplyDiff {
Expand Down
24 changes: 21 additions & 3 deletions fvm/evm/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import (
gethCommon "github.com/ethereum/go-ethereum/common"
gethTypes "github.com/ethereum/go-ethereum/core/types"
gethCrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
gethRLP "github.com/ethereum/go-ethereum/rlp"
gethTrie "github.com/ethereum/go-ethereum/trie"
)

// Block represents a evm block.
Expand All @@ -22,6 +23,9 @@ type Block struct {
TotalSupply *big.Int

// ReceiptRoot returns the root hash of the receipts emitted in this block
// Note that this value won't be unique to each block, for example for the
// case of empty trie of receipts or a single receipt with no logs and failed state
// the same receipt root would be reported for block.
ReceiptRoot gethCommon.Hash

// transaction hashes
Expand All @@ -30,7 +34,7 @@ type Block struct {

// ToBytes encodes the block into bytes
func (b *Block) ToBytes() ([]byte, error) {
return rlp.EncodeToBytes(b)
return gethRLP.EncodeToBytes(b)
}

// Hash returns the hash of the block
Expand All @@ -39,6 +43,20 @@ func (b *Block) Hash() (gethCommon.Hash, error) {
return gethCrypto.Keccak256Hash(data), err
}

// PopulateReceiptRoot populates receipt root with the given results
func (b *Block) PopulateReceiptRoot(results []Result) {
if len(results) == 0 {
b.ReceiptRoot = gethTypes.EmptyReceiptsHash
return
}

receipts := make(gethTypes.Receipts, len(results))
for i, res := range results {
receipts[i] = res.Receipt()
}
b.ReceiptRoot = gethTypes.DeriveSha(receipts, gethTrie.NewStackTrie(nil))
}

// AppendTxHash appends a transaction hash to the list of transaction hashes of the block
func (b *Block) AppendTxHash(txHash gethCommon.Hash) {
b.TransactionHashes = append(b.TransactionHashes, txHash)
Expand All @@ -64,7 +82,7 @@ func NewBlock(
// NewBlockFromBytes constructs a new block from encoded data
func NewBlockFromBytes(encoded []byte) (*Block, error) {
res := &Block{}
err := rlp.DecodeBytes(encoded, res)
err := gethRLP.DecodeBytes(encoded, res)
return res, err
}

Expand Down
10 changes: 10 additions & 0 deletions fvm/evm/types/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

gethCommon "github.com/ethereum/go-ethereum/common"
gethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand All @@ -30,4 +31,13 @@ func Test_BlockHash(t *testing.T) {

// hashes should not equal if any data is changed
assert.NotEqual(t, h1, h2)

b.PopulateReceiptRoot(nil)
require.Equal(t, gethTypes.EmptyReceiptsHash, b.ReceiptRoot)

res := Result{
GasConsumed: 10,
}
b.PopulateReceiptRoot([]Result{res})
require.NotEqual(t, gethTypes.EmptyReceiptsHash, b.ReceiptRoot)
}
10 changes: 8 additions & 2 deletions fvm/evm/types/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ func (res *Result) VMErrorString() string {

// Receipt constructs an EVM-style receipt
// can be used by json-rpc and other integration to be returned.
func (res *Result) Receipt() *gethTypes.ReceiptForStorage {
//
// This is method is also used to construct block receipt root hash
// which requires the return receipt satisfy RLP encoding and cover these feilds
// Type (txType), PostState or Status, CumulativeGasUsed, Logs and Logs Bloom
// and for each log, Address, Topics, Data (consensus fields)
// During execution we also do fill in BlockNumber, TxIndex, Index (event index)
func (res *Result) Receipt() *gethTypes.Receipt {
receipt := &gethTypes.Receipt{
Type: res.TxType,
CumulativeGasUsed: res.GasConsumed, // TODO: update to capture cumulative
Expand All @@ -56,7 +62,7 @@ func (res *Result) Receipt() *gethTypes.ReceiptForStorage {
}

receipt.Bloom = gethTypes.CreateBloom(gethTypes.Receipts{receipt})
return (*gethTypes.ReceiptForStorage)(receipt)
return receipt
}

// Status captures the status of an interaction to the emulator
Expand Down

0 comments on commit dcb7fee

Please sign in to comment.