Skip to content

Commit

Permalink
parent state root in execution witness (#456)
Browse files Browse the repository at this point in the history
* parent state root in execution witness

* generate headers with go 1.21
  • Loading branch information
gballet authored Jul 29, 2024
1 parent 4133497 commit 0fe1b30
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 83 deletions.
4 changes: 2 additions & 2 deletions beacon/engine/gen_ed.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 18 additions & 19 deletions beacon/engine/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,24 @@ type payloadAttributesMarshaling struct {

// ExecutableData is the data necessary to execute an EL payload.
type ExecutableData struct {
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
LogsBloom []byte `json:"logsBloom" gencodec:"required"`
Random common.Hash `json:"prevRandao" gencodec:"required"`
Number uint64 `json:"blockNumber" gencodec:"required"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
Timestamp uint64 `json:"timestamp" gencodec:"required"`
ExtraData []byte `json:"extraData" gencodec:"required"`
BaseFeePerGas *big.Int `json:"baseFeePerGas" gencodec:"required"`
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
Transactions [][]byte `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
BlobGasUsed *uint64 `json:"blobGasUsed"`
ExcessBlobGas *uint64 `json:"excessBlobGas"`

ExecutionWitness *types.ExecutionWitness `json:"executionWitness"`
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
LogsBloom []byte `json:"logsBloom" gencodec:"required"`
Random common.Hash `json:"prevRandao" gencodec:"required"`
Number uint64 `json:"blockNumber" gencodec:"required"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
Timestamp uint64 `json:"timestamp" gencodec:"required"`
ExtraData []byte `json:"extraData" gencodec:"required"`
BaseFeePerGas *big.Int `json:"baseFeePerGas" gencodec:"required"`
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
Transactions [][]byte `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
BlobGasUsed *uint64 `json:"blobGasUsed"`
ExcessBlobGas *uint64 `json:"excessBlobGas"`
ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"`
}

// JSON type overrides for executableData.
Expand Down
10 changes: 6 additions & 4 deletions consensus/beacon/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,16 +398,18 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
state.Database().SaveTransitionState(header.Root)

var (
p *verkle.VerkleProof
k verkle.StateDiff
keys = state.Witness().Keys()
p *verkle.VerkleProof
k verkle.StateDiff
keys = state.Witness().Keys()
proot common.Hash
)
if chain.Config().IsPrague(header.Number, header.Time) {
// Open the pre-tree to prove the pre-state against
parent := chain.GetHeaderByNumber(header.Number.Uint64() - 1)
if parent == nil {
return nil, fmt.Errorf("nil parent header for block %d", header.Number)
}
proot = parent.Root

// Load transition state at beginning of block, because
// OpenTrie needs to know what the conversion status is.
Expand Down Expand Up @@ -467,7 +469,7 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
// Assemble and return the final block.
block := types.NewBlockWithWithdrawals(header, txs, uncles, receipts, withdrawals, trie.NewStackTrie(nil))
if chain.Config().IsPrague(header.Number, header.Time) && chain.Config().ProofInBlocks {
block.SetVerkleProof(p, k)
block.SetVerkleProof(p, k, proot)
}
return block, nil
}
Expand Down
8 changes: 5 additions & 3 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,19 +358,20 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int,
panic(err)
}
if genesis.Config != nil && genesis.Config.IsPrague(genesis.ToBlock().Number(), genesis.ToBlock().Time()) {
blocks, receipts, _, _ := GenerateVerkleChain(genesis.Config, genesis.ToBlock(), engine, db, n, gen)
blocks, receipts, _, _, _ := GenerateVerkleChain(genesis.Config, genesis.ToBlock(), engine, db, n, gen)
return db, blocks, receipts
}
blocks, receipts := GenerateChain(genesis.Config, genesis.ToBlock(), engine, db, n, gen)
return db, blocks, receipts
}

func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, diskdb ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts, []*verkle.VerkleProof, []verkle.StateDiff) {
func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, diskdb ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts, []*verkle.VerkleProof, []verkle.StateDiff, []common.Hash) {
if config == nil {
config = params.TestChainConfig
}
proofs := make([]*verkle.VerkleProof, 0, n)
keyvals := make([]verkle.StateDiff, 0, n)
proots := make([]common.Hash, 0, n)
blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n)
chainreader := &generatedLinearChainReader{
config: config,
Expand Down Expand Up @@ -428,6 +429,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine

proofs = append(proofs, block.ExecutionWitness().VerkleProof)
keyvals = append(keyvals, block.ExecutionWitness().StateDiff)
proots = append(proots, parent.Root())

return block, b.receipts
}
Expand All @@ -450,7 +452,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine
parent = block
snaps = statedb.Snaps()
}
return blocks, receipts, proofs, keyvals
return blocks, receipts, proofs, keyvals, proots
}

func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header {
Expand Down
18 changes: 9 additions & 9 deletions core/state_processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ func TestProcessVerkle(t *testing.T) {
txCost1*2 + txCost2 + contractCreationCost + codeWithExtCodeCopyGas,
}
// TODO utiliser GenerateChainWithGenesis pour le rendre plus pratique
chain, _, proofs, keyvals := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) {
chain, _, proofs, keyvals, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) {
gen.SetPoS()

// TODO need to check that the tx cost provided is the exact amount used (no remaining left-over)
Expand Down Expand Up @@ -642,7 +642,7 @@ func TestProcessVerkleInvalidContractCreation(t *testing.T) {
// Create two blocks that reproduce what is happening on kaustinen.
// - The first block contains two failing contract creation transactions, that write to storage before they revert.
// - The second block contains a single failing contract creation transaction, that fails right off the bat.
_, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) {
_, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) {
gen.SetPoS()

if i == 0 {
Expand Down Expand Up @@ -797,7 +797,7 @@ func TestProcessVerkleContractWithEmptyCode(t *testing.T) {
// is now independent of the blockchain database.
gspec.MustCommit(gendb)

_, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) {
_, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) {
gen.SetPoS()
var tx types.Transaction
// a transaction that does some PUSH1n but returns a 0-sized contract
Expand Down Expand Up @@ -922,7 +922,7 @@ func TestProcessVerklExtCodeHashOpcode(t *testing.T) {
0x3F, // EXTCODEHASH
}
extCodeHashContractAddr := common.HexToAddress("db7d6ab1f17c6b31909ae466702703daef9269cf")
_, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) {
_, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) {
gen.SetPoS()

if i == 0 {
Expand Down Expand Up @@ -1023,7 +1023,7 @@ func TestProcessVerkleBalanceOpcode(t *testing.T) {
// is now independent of the blockchain database.
gspec.MustCommit(gendb)

_, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) {
_, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) {
gen.SetPoS()
txData := []byte{
0x73, // PUSH20
Expand Down Expand Up @@ -1132,7 +1132,7 @@ func TestProcessVerkleSelfDestructInSeparateTx(t *testing.T) {
0xFF, // SELFDESTRUCT
}
selfDestructContractAddr := common.HexToAddress("3a220f351252089d385b29beca14e27f204c296a")
_, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) {
_, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) {
gen.SetPoS()

if i == 0 {
Expand Down Expand Up @@ -1269,7 +1269,7 @@ func TestProcessVerkleSelfDestructInSameTx(t *testing.T) {
0xFF, // SELFDESTRUCT
}
selfDestructContractAddr := common.HexToAddress("3a220f351252089d385b29beca14e27f204c296a")
_, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) {
_, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) {
gen.SetPoS()
tx, _ := types.SignTx(types.NewContractCreation(0, big.NewInt(42), 100_000, big.NewInt(875000000), selfDestructContract), signer, testKey)
gen.AddTx(tx)
Expand Down Expand Up @@ -1403,7 +1403,7 @@ func TestProcessVerkleSelfDestructInSeparateTxWithSelfBeneficiary(t *testing.T)
0xFF, // SELFDESTRUCT
}
selfDestructContractAddr := common.HexToAddress("3a220f351252089d385b29beca14e27f204c296a")
_, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) {
_, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 2, func(i int, gen *BlockGen) {
gen.SetPoS()
if i == 0 {
// Create selfdestruct contract, sending 42 wei.
Expand Down Expand Up @@ -1514,7 +1514,7 @@ func TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiary(t *testing.T) {
0xFF, // SELFDESTRUCT
}
selfDestructContractAddr := common.HexToAddress("3a220f351252089d385b29beca14e27f204c296a")
_, _, _, statediff := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) {
_, _, _, statediff, _ := GenerateVerkleChain(gspec.Config, genesis, beacon.New(ethash.NewFaker()), gendb, 1, func(i int, gen *BlockGen) {
gen.SetPoS()
tx, _ := types.SignTx(types.NewContractCreation(0, big.NewInt(42), 100_000, big.NewInt(875000000), selfDestructContract), signer, testKey)
gen.AddTx(tx)
Expand Down
14 changes: 8 additions & 6 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,16 @@ func (n *BlockNonce) UnmarshalText(input []byte) error {
}

type ExecutionWitness struct {
StateDiff verkle.StateDiff `json:"stateDiff"`
VerkleProof *verkle.VerkleProof `json:"verkleProof"`
StateDiff verkle.StateDiff `json:"stateDiff"`
VerkleProof *verkle.VerkleProof `json:"verkleProof"`
ParentStateRoot common.Hash `json:"parentStateRoot"`
}

func (ew *ExecutionWitness) Copy() *ExecutionWitness {
return &ExecutionWitness{
StateDiff: ew.StateDiff.Copy(),
VerkleProof: ew.VerkleProof.Copy(),
StateDiff: ew.StateDiff.Copy(),
VerkleProof: ew.VerkleProof.Copy(),
ParentStateRoot: ew.ParentStateRoot,
}
}

Expand Down Expand Up @@ -421,8 +423,8 @@ func (b *Block) SanityCheck() error {
return b.header.SanityCheck()
}

func (b *Block) SetVerkleProof(vp *verkle.VerkleProof, statediff verkle.StateDiff) {
b.header.ExecutionWitness = &ExecutionWitness{statediff, vp}
func (b *Block) SetVerkleProof(vp *verkle.VerkleProof, statediff verkle.StateDiff, parentRoot common.Hash) {
b.header.ExecutionWitness = &ExecutionWitness{statediff, vp, parentRoot}
if statediff == nil {
b.header.ExecutionWitness.StateDiff = []verkle.StemStateDiff{}
}
Expand Down
Loading

0 comments on commit 0fe1b30

Please sign in to comment.