From 434a02eccc6d0cb0104586d0bb0a78a8ddb99d77 Mon Sep 17 00:00:00 2001 From: simlecode <69969590+simlecode@users.noreply.github.com> Date: Tue, 7 Feb 2023 11:13:10 +0800 Subject: [PATCH 1/4] fix: ethtypes: Correct 'no uncles' hash in NewEthBlock --- app/submodule/eth/eth_api.go | 2 +- venus-shared/actors/types/eth.go | 23 +++++++++++++++-------- venus-shared/actors/types/param.go | 9 ++++----- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/app/submodule/eth/eth_api.go b/app/submodule/eth/eth_api.go index 15e758105f..7140b61844 100644 --- a/app/submodule/eth/eth_api.go +++ b/app/submodule/eth/eth_api.go @@ -945,7 +945,7 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx return types.EthBlock{}, fmt.Errorf("error loading messages for tipset: %v: %w", ts, err) } - block := types.NewEthBlock() + block := types.NewEthBlock(len(msgs) > 0) // this seems to be a very expensive way to get gasUsed of the block. may need to find an efficient way to do it gasUsed := int64(0) diff --git a/venus-shared/actors/types/eth.go b/venus-shared/actors/types/eth.go index d54a97e4fb..88ad894b42 100644 --- a/venus-shared/actors/types/eth.go +++ b/venus-shared/actors/types/eth.go @@ -164,17 +164,19 @@ type EthBlock struct { } var ( - EmptyEthBloom = [256]byte{} - EmptyEthHash = EthHash{} - EmptyEthInt = EthUint64(0) - EmptyEthNonce = [8]byte{0, 0, 0, 0, 0, 0, 0, 0} + EmptyEthBloom = [256]byte{} + EmptyEthHash = EthHash{} + EmptyUncleHash = One(ParseEthHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")) // Keccak-256 of an RLP of an empty array + EmptyRootHash = One(ParseEthHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")) // Keccak-256 hash of the RLP of null + EmptyEthInt = EthUint64(0) + EmptyEthNonce = [8]byte{0, 0, 0, 0, 0, 0, 0, 0} ) -func NewEthBlock() EthBlock { - return EthBlock{ - Sha3Uncles: EmptyEthHash, +func NewEthBlock(hasTransactions bool) EthBlock { + b := EthBlock{ + Sha3Uncles: EmptyUncleHash, // Sha3Uncles set to a hardcoded value which is used by some clients to determine if has no uncles., StateRoot: EmptyEthHash, - TransactionsRoot: EmptyEthHash, + TransactionsRoot: EmptyRootHash, // TransactionsRoot set to a hardcoded value which is used by some clients to determine if has no transactions., ReceiptsRoot: EmptyEthHash, Difficulty: EmptyEthInt, LogsBloom: EmptyEthBloom[:], @@ -185,6 +187,11 @@ func NewEthBlock() EthBlock { Uncles: []EthHash{}, Transactions: []interface{}{}, } + if hasTransactions { + b.TransactionsRoot = EmptyEthHash + } + + return b } type EthCall struct { diff --git a/venus-shared/actors/types/param.go b/venus-shared/actors/types/param.go index 252340686c..763053f8ba 100644 --- a/venus-shared/actors/types/param.go +++ b/venus-shared/actors/types/param.go @@ -10,13 +10,12 @@ var bigZero = big.Zero() var TotalFilecoinInt = FromFil(params.FilBase) -var ZeroAddress = func() address.Address { - addr := "f3yaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaby2smx7a" +var ZeroAddress address.Address = One(address.NewFromString("f3yaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaby2smx7a")) - ret, err := address.NewFromString(addr) +func One[R any](r R, err error) R { if err != nil { panic(err) } - return ret -}() + return r +} From a74889875a5a84032b4121599bc5eb8a24f6a3b3 Mon Sep 17 00:00:00 2001 From: simlecode <69969590+simlecode@users.noreply.github.com> Date: Tue, 7 Feb 2023 11:17:38 +0800 Subject: [PATCH 2/4] fix: fix eth_FeeHistory --- app/submodule/eth/eth_api.go | 7 ++++++- venus-shared/actors/types/eth.go | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/submodule/eth/eth_api.go b/app/submodule/eth/eth_api.go index 7140b61844..6052af38db 100644 --- a/app/submodule/eth/eth_api.go +++ b/app/submodule/eth/eth_api.go @@ -384,6 +384,11 @@ func (a *ethAPI) EthGetCode(ctx context.Context, ethAddr types.EthAddress, blkPa return nil, fmt.Errorf("cannot parse block param: %s", blkParam) } + // StateManager.Call will panic if there is no parent + if ts.Height() == 0 { + return nil, fmt.Errorf("block param must not specify genesis block") + } + // Try calling until we find a height with no migration. var res *vm.Ret for { @@ -574,7 +579,7 @@ func (a *ethAPI) EthFeeHistory(ctx context.Context, blkCount types.EthUint64, ne } return types.EthFeeHistory{ - OldestBlock: oldestBlkHeight, + OldestBlock: types.EthUint64(oldestBlkHeight), BaseFeePerGas: baseFeeArray, GasUsedRatio: gasUsedRatioArray, }, nil diff --git a/venus-shared/actors/types/eth.go b/venus-shared/actors/types/eth.go index 88ad894b42..c9ac525fed 100644 --- a/venus-shared/actors/types/eth.go +++ b/venus-shared/actors/types/eth.go @@ -153,7 +153,7 @@ type EthBlock struct { GasLimit EthUint64 `json:"gasLimit"` GasUsed EthUint64 `json:"gasUsed"` Timestamp EthUint64 `json:"timestamp"` - Extradata []byte `json:"extraData"` + Extradata EthBytes `json:"extraData"` MixHash EthHash `json:"mixHash"` Nonce EthNonce `json:"nonce"` BaseFeePerGas EthBigInt `json:"baseFeePerGas"` @@ -480,7 +480,7 @@ func EthHashFromTxBytes(b []byte) EthHash { } type EthFeeHistory struct { - OldestBlock uint64 `json:"oldestBlock"` + OldestBlock EthUint64 `json:"oldestBlock"` BaseFeePerGas []EthBigInt `json:"baseFeePerGas"` GasUsedRatio []float64 `json:"gasUsedRatio"` Reward *[][]EthBigInt `json:"reward,omitempty"` From 5c0f750e77a0480ad9d532a4bef6216542d08982 Mon Sep 17 00:00:00 2001 From: simlecode <69969590+simlecode@users.noreply.github.com> Date: Wed, 8 Feb 2023 10:05:08 +0800 Subject: [PATCH 3/4] chore: make api-gen --- venus-shared/api/chain/v1/method.md | 6 +++--- venus-shared/compatible-checks/api-diff.txt | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/venus-shared/api/chain/v1/method.md b/venus-shared/api/chain/v1/method.md index 5ec24f0bf1..2814e5bd15 100644 --- a/venus-shared/api/chain/v1/method.md +++ b/venus-shared/api/chain/v1/method.md @@ -2205,7 +2205,7 @@ Inputs: Response: ```json { - "oldestBlock": 42, + "oldestBlock": "0x5", "baseFeePerGas": [ "0x0" ], @@ -2270,7 +2270,7 @@ Response: "gasLimit": "0x5", "gasUsed": "0x5", "timestamp": "0x5", - "extraData": "Ynl0ZSBhcnJheQ==", + "extraData": "0x07", "mixHash": "0x0707070707070707070707070707070707070707070707070707070707070707", "nonce": "0x0707070707070707", "baseFeePerGas": "0x0", @@ -2314,7 +2314,7 @@ Response: "gasLimit": "0x5", "gasUsed": "0x5", "timestamp": "0x5", - "extraData": "Ynl0ZSBhcnJheQ==", + "extraData": "0x07", "mixHash": "0x0707070707070707070707070707070707070707070707070707070707070707", "nonce": "0x0707070707070707", "baseFeePerGas": "0x0", diff --git a/venus-shared/compatible-checks/api-diff.txt b/venus-shared/compatible-checks/api-diff.txt index 33eb37f9e0..13a65dd666 100644 --- a/venus-shared/compatible-checks/api-diff.txt +++ b/venus-shared/compatible-checks/api-diff.txt @@ -155,6 +155,9 @@ github.com/filecoin-project/venus/venus-shared/api/chain/v1.FullNode <> github.c + Concurrent - CreateBackup - Discover + > EthFeeHistory {[func(context.Context, types.EthUint64, string, []float64) (types.EthFeeHistory, error) <> func(context.Context, ethtypes.EthUint64, string, []float64) (ethtypes.EthFeeHistory, error)] base=func out type: #0 input; nested={[types.EthFeeHistory <> ethtypes.EthFeeHistory] base=struct field; nested={[types.EthFeeHistory <> ethtypes.EthFeeHistory] base=exported field type: #0 field named OldestBlock; nested={[types.EthUint64 <> uint64] base=codec marshaler implementations for codec JSON: true != false; nested=nil}}}} + > EthGetBlockByHash {[func(context.Context, types.EthHash, bool) (types.EthBlock, error) <> func(context.Context, ethtypes.EthHash, bool) (ethtypes.EthBlock, error)] base=func out type: #0 input; nested={[types.EthBlock <> ethtypes.EthBlock] base=struct field; nested={[types.EthBlock <> ethtypes.EthBlock] base=exported field type: #14 field named Extradata; nested={[types.EthBytes <> []uint8] base=codec marshaler implementations for codec JSON: true != false; nested=nil}}}} + > EthGetBlockByNumber {[func(context.Context, string, bool) (types.EthBlock, error) <> func(context.Context, string, bool) (ethtypes.EthBlock, error)] base=func out type: #0 input; nested={[types.EthBlock <> ethtypes.EthBlock] base=struct field; nested={[types.EthBlock <> ethtypes.EthBlock] base=exported field type: #14 field named Extradata; nested={[types.EthBytes <> []uint8] base=codec marshaler implementations for codec JSON: true != false; nested=nil}}}} + GasBatchEstimateMessageGas > GasEstimateMessageGas {[func(context.Context, *types.Message, *types.MessageSendSpec, types.TipSetKey) (*types.Message, error) <> func(context.Context, *types.Message, *api.MessageSendSpec, types.TipSetKey) (*types.Message, error)] base=func in type: #2 input; nested={[*types.MessageSendSpec <> *api.MessageSendSpec] base=pointed type; nested={[types.MessageSendSpec <> api.MessageSendSpec] base=struct field; nested={[types.MessageSendSpec <> api.MessageSendSpec] base=exported fields count: 3 != 2; nested=nil}}}} + GetActor From 9f38d72b118f0297a099bbce22b81860009a4446 Mon Sep 17 00:00:00 2001 From: simlecode <69969590+simlecode@users.noreply.github.com> Date: Wed, 8 Feb 2023 10:12:49 +0800 Subject: [PATCH 4/4] chain: explicitly check that gasLimit is above zero --- venus-shared/actors/types/message.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/venus-shared/actors/types/message.go b/venus-shared/actors/types/message.go index c53dc1b0ec..1917cf9606 100644 --- a/venus-shared/actors/types/message.go +++ b/venus-shared/actors/types/message.go @@ -153,10 +153,18 @@ func (m *Message) ValidForBlockInclusion(minGas int64, version network.Version) return fmt.Errorf("invalid 'To' address") } + if !abi.AddressValidForNetworkVersion(m.To, version) { + return fmt.Errorf("'To' address protocol unsupported for network version") + } + if m.From == address.Undef { return fmt.Errorf("'From' address cannot be empty") } + if !abi.AddressValidForNetworkVersion(m.From, version) { + return fmt.Errorf("'From' address protocol unsupported for network version") + } + if m.Value.Int == nil { return fmt.Errorf("'Value' cannot be nil") } @@ -193,6 +201,10 @@ func (m *Message) ValidForBlockInclusion(minGas int64, version network.Version) return fmt.Errorf("'GasLimit' field cannot be greater than a block's gas limit") } + if m.GasLimit <= 0 { + return fmt.Errorf("'GasLimit' field %d must be positive", m.GasLimit) + } + // since prices might vary with time, this is technically semantic validation if m.GasLimit < minGas { return fmt.Errorf("'GasLimit' field cannot be less than the cost of storing a message on chain %d < %d", m.GasLimit, minGas)