From 8d6aa2477c69b72e57ba098a02fdfaaf0cb6f18f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 9 Feb 2023 13:12:16 +0100 Subject: [PATCH 1/2] feat: actors: Add bytecode getter --- chain/actors/builtin/evm/actor.go.template | 3 +++ chain/actors/builtin/evm/evm.go | 3 +++ chain/actors/builtin/evm/state.go.template | 20 ++++++++++++++------ chain/actors/builtin/evm/v10.go | 8 ++++++++ 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/chain/actors/builtin/evm/actor.go.template b/chain/actors/builtin/evm/actor.go.template index d20db6bcbc2..76d3cbe54b6 100644 --- a/chain/actors/builtin/evm/actor.go.template +++ b/chain/actors/builtin/evm/actor.go.template @@ -49,4 +49,7 @@ type State interface { Nonce() (uint64, error) GetState() interface{} + + GetBytecodeCID() (cid.Cid, error) + GetBytecodeHash() ([32]byte, error) } diff --git a/chain/actors/builtin/evm/evm.go b/chain/actors/builtin/evm/evm.go index 120ca66f8b2..b96761c6510 100644 --- a/chain/actors/builtin/evm/evm.go +++ b/chain/actors/builtin/evm/evm.go @@ -49,4 +49,7 @@ type State interface { Nonce() (uint64, error) GetState() interface{} + + GetBytecodeCID() (cid.Cid, error) + GetBytecodeHash() ([32]byte, error) } diff --git a/chain/actors/builtin/evm/state.go.template b/chain/actors/builtin/evm/state.go.template index acc78dc0fda..71fb553b74a 100644 --- a/chain/actors/builtin/evm/state.go.template +++ b/chain/actors/builtin/evm/state.go.template @@ -21,12 +21,12 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { func make{{.v}}(store adt.Store, bytecode cid.Cid) (State, error) { out := state{{.v}}{store: store} - s, err := evm{{.v}}.ConstructState(store, bytecode) - if err != nil { - return nil, err - } + s, err := evm{{.v}}.ConstructState(store, bytecode) + if err != nil { + return nil, err + } - out.State = *s + out.State = *s return &out, nil } @@ -42,4 +42,12 @@ func (s *state{{.v}}) Nonce() (uint64, error) { func (s *state{{.v}}) GetState() interface{} { return &s.State -} \ No newline at end of file +} + +func (s *state{{.v}}) GetBytecodeCID() (cid.Cid, error) { + return s.State.Bytecode, nil +} + +func (s *state{{.v}}) GetBytecodeHash() ([32]byte, error) { + return s.State.BytecodeHash, nil +} diff --git a/chain/actors/builtin/evm/v10.go b/chain/actors/builtin/evm/v10.go index 78a4a238307..e651b670162 100644 --- a/chain/actors/builtin/evm/v10.go +++ b/chain/actors/builtin/evm/v10.go @@ -43,3 +43,11 @@ func (s *state10) Nonce() (uint64, error) { func (s *state10) GetState() interface{} { return &s.State } + +func (s *state10) GetBytecodeCID() (cid.Cid, error) { + return s.State.Bytecode, nil +} + +func (s *state10) GetBytecodeHash() ([32]byte, error) { + return s.State.BytecodeHash, nil +} From 554dd2f1eee19ddc0de0aeade7507eec5460d7b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 9 Feb 2023 13:21:20 +0100 Subject: [PATCH 2/2] itests: Test EVM bytecode getters, check bytecode hash --- chain/actors/builtin/evm/actor.go.template | 1 + chain/actors/builtin/evm/evm.go | 1 + chain/actors/builtin/evm/state.go.template | 14 ++++++++++ chain/actors/builtin/evm/v10.go | 15 ++++++++++ itests/eth_deploy_test.go | 32 ++++++++++++++++++++++ 5 files changed, 63 insertions(+) diff --git a/chain/actors/builtin/evm/actor.go.template b/chain/actors/builtin/evm/actor.go.template index 76d3cbe54b6..aa23b5f11ab 100644 --- a/chain/actors/builtin/evm/actor.go.template +++ b/chain/actors/builtin/evm/actor.go.template @@ -50,6 +50,7 @@ type State interface { Nonce() (uint64, error) GetState() interface{} + GetBytecode() ([]byte, error) GetBytecodeCID() (cid.Cid, error) GetBytecodeHash() ([32]byte, error) } diff --git a/chain/actors/builtin/evm/evm.go b/chain/actors/builtin/evm/evm.go index b96761c6510..f55a2177df6 100644 --- a/chain/actors/builtin/evm/evm.go +++ b/chain/actors/builtin/evm/evm.go @@ -50,6 +50,7 @@ type State interface { Nonce() (uint64, error) GetState() interface{} + GetBytecode() ([]byte, error) GetBytecodeCID() (cid.Cid, error) GetBytecodeHash() ([32]byte, error) } diff --git a/chain/actors/builtin/evm/state.go.template b/chain/actors/builtin/evm/state.go.template index 71fb553b74a..eb55a84635d 100644 --- a/chain/actors/builtin/evm/state.go.template +++ b/chain/actors/builtin/evm/state.go.template @@ -51,3 +51,17 @@ func (s *state{{.v}}) GetBytecodeCID() (cid.Cid, error) { func (s *state{{.v}}) GetBytecodeHash() ([32]byte, error) { return s.State.BytecodeHash, nil } + +func (s *state{{.v}}) GetBytecode() ([]byte, error) { + bc, err := s.GetBytecodeCID() + if err != nil { + return nil, err + } + + var byteCode abi.CborBytesTransparent + if err := s.store.Get(s.store.Context(), bc, &byteCode); err != nil { + return nil, err + } + + return byteCode, nil +} diff --git a/chain/actors/builtin/evm/v10.go b/chain/actors/builtin/evm/v10.go index e651b670162..77a09037ba2 100644 --- a/chain/actors/builtin/evm/v10.go +++ b/chain/actors/builtin/evm/v10.go @@ -3,6 +3,7 @@ package evm import ( "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-state-types/abi" evm10 "github.com/filecoin-project/go-state-types/builtin/v10/evm" "github.com/filecoin-project/lotus/chain/actors/adt" @@ -51,3 +52,17 @@ func (s *state10) GetBytecodeCID() (cid.Cid, error) { func (s *state10) GetBytecodeHash() ([32]byte, error) { return s.State.BytecodeHash, nil } + +func (s *state10) GetBytecode() ([]byte, error) { + bc, err := s.GetBytecodeCID() + if err != nil { + return nil, err + } + + var byteCode abi.CborBytesTransparent + if err := s.store.Get(s.store.Context(), bc, &byteCode); err != nil { + return nil, err + } + + return byteCode, nil +} diff --git a/itests/eth_deploy_test.go b/itests/eth_deploy_test.go index 98038de7bd6..bbdadb1d5c5 100644 --- a/itests/eth_deploy_test.go +++ b/itests/eth_deploy_test.go @@ -11,12 +11,16 @@ import ( "time" "github.com/stretchr/testify/require" + "golang.org/x/crypto/sha3" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/manifest" + gstStore "github.com/filecoin-project/go-state-types/store" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin/evm" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types/ethtypes" "github.com/filecoin-project/lotus/itests/kit" @@ -219,4 +223,32 @@ func TestDeployment(t *testing.T) { require.NoError(t, err) client.AssertActorType(ctx, contractAddr, "evm") + + // Check bytecode and bytecode hash match. + contractAct, err := client.StateGetActor(ctx, contractAddr, types.EmptyTSK) + require.NoError(t, err) + + bs := blockstore.NewAPIBlockstore(client) + ctxStore := gstStore.WrapBlockStore(ctx, bs) + + evmSt, err := evm.Load(ctxStore, contractAct) + require.NoError(t, err) + + byteCodeCid, err := evmSt.GetBytecodeCID() + require.NoError(t, err) + + byteCode, err := bs.Get(ctx, byteCodeCid) + require.NoError(t, err) + + byteCodeHashChain, err := evmSt.GetBytecodeHash() + require.NoError(t, err) + + hasher := sha3.NewLegacyKeccak256() + hasher.Write(byteCode.RawData()) + byteCodeHash := hasher.Sum(nil) + require.Equal(t, byteCodeHashChain[:], byteCodeHash) + + byteCodeSt, err := evmSt.GetBytecode() + require.NoError(t, err) + require.Equal(t, byteCode.RawData(), byteCodeSt) }