From 6774e96b986449bd92ecff818a187304291f43af Mon Sep 17 00:00:00 2001 From: galaio Date: Fri, 11 Oct 2024 14:06:03 +0800 Subject: [PATCH 1/2] ethclient: move TransactionOpts to avoid import internal package; --- accounts/abi/bind/backend.go | 3 +- accounts/abi/bind/base_test.go | 3 +- .../ethapi => core/types}/gen_tx_opts_json.go | 3 +- core/types/transaction_options.go | 42 +++++++++++++++++ .../types}/transaction_options_test.go | 33 +++++++------ ethclient/ethclient.go | 3 +- ethclient/ethclient_test.go | 7 ++- ethclient/simulated/backend.go | 3 +- internal/ethapi/api.go | 4 +- ...n_options.go => transaction_opts_utils.go} | 46 ++----------------- 10 files changed, 72 insertions(+), 75 deletions(-) rename {internal/ethapi => core/types}/gen_tx_opts_json.go (99%) create mode 100644 core/types/transaction_options.go rename {internal/ethapi => core/types}/transaction_options_test.go (80%) rename internal/ethapi/{transaction_options.go => transaction_opts_utils.go} (51%) diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go index 153ba46415..f43142d60a 100644 --- a/accounts/abi/bind/backend.go +++ b/accounts/abi/bind/backend.go @@ -24,7 +24,6 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/internal/ethapi" ) var ( @@ -101,7 +100,7 @@ type ContractTransactor interface { PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) // SendTransactionConditional injects the conditional transaction into the pending pool for execution after verification. - SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts ethapi.TransactionOpts) error + SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts types.TransactionOpts) error } // DeployBackend wraps the operations needed by WaitMined and WaitDeployed. diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index 99621767ff..181cd43753 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -31,7 +31,6 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/rlp" "github.com/stretchr/testify/assert" ) @@ -76,7 +75,7 @@ func (mt *mockTransactor) SendTransaction(ctx context.Context, tx *types.Transac return nil } -func (mt *mockTransactor) SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts ethapi.TransactionOpts) error { +func (mt *mockTransactor) SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts types.TransactionOpts) error { return nil } diff --git a/internal/ethapi/gen_tx_opts_json.go b/core/types/gen_tx_opts_json.go similarity index 99% rename from internal/ethapi/gen_tx_opts_json.go rename to core/types/gen_tx_opts_json.go index 19832cede1..e5ac99bd2d 100644 --- a/internal/ethapi/gen_tx_opts_json.go +++ b/core/types/gen_tx_opts_json.go @@ -1,10 +1,9 @@ // Code generated by github.com/fjl/gencodec. DO NOT EDIT. -package ethapi +package types import ( "encoding/json" - "github.com/ethereum/go-ethereum/common/hexutil" ) diff --git a/core/types/transaction_options.go b/core/types/transaction_options.go new file mode 100644 index 0000000000..0901bf6e05 --- /dev/null +++ b/core/types/transaction_options.go @@ -0,0 +1,42 @@ +package types + +import ( + "encoding/json" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +type AccountStorage struct { + StorageRoot *common.Hash + StorageSlots map[common.Hash]common.Hash +} + +func (a *AccountStorage) UnmarshalJSON(data []byte) error { + var hash common.Hash + if err := json.Unmarshal(data, &hash); err == nil { + a.StorageRoot = &hash + return nil + } + return json.Unmarshal(data, &a.StorageSlots) +} + +func (a AccountStorage) MarshalJSON() ([]byte, error) { + if a.StorageRoot != nil { + return json.Marshal(*a.StorageRoot) + } + return json.Marshal(a.StorageSlots) +} + +type KnownAccounts map[common.Address]AccountStorage + +// It is known that marshaling is broken +// https://github.com/golang/go/issues/55890 + +//go:generate go run github.com/fjl/gencodec -type TransactionOpts -out gen_tx_opts_json.go +type TransactionOpts struct { + KnownAccounts KnownAccounts `json:"knownAccounts"` + BlockNumberMin *hexutil.Uint64 `json:"blockNumberMin,omitempty"` + BlockNumberMax *hexutil.Uint64 `json:"blockNumberMax,omitempty"` + TimestampMin *hexutil.Uint64 `json:"timestampMin,omitempty"` + TimestampMax *hexutil.Uint64 `json:"timestampMax,omitempty"` +} diff --git a/internal/ethapi/transaction_options_test.go b/core/types/transaction_options_test.go similarity index 80% rename from internal/ethapi/transaction_options_test.go rename to core/types/transaction_options_test.go index 479f46a145..59627c0a36 100644 --- a/internal/ethapi/transaction_options_test.go +++ b/core/types/transaction_options_test.go @@ -1,4 +1,4 @@ -package ethapi_test +package types import ( "encoding/json" @@ -7,7 +7,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/internal/ethapi" ) func ptr(hash common.Hash) *common.Hash { @@ -23,15 +22,15 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) { name string input string mustFail bool - expected ethapi.TransactionOpts + expected TransactionOpts }{ { "StateRoot", `{"knownAccounts":{"0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0":"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"}}`, false, - ethapi.TransactionOpts{ - KnownAccounts: map[common.Address]ethapi.AccountStorage{ - common.HexToAddress("0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0"): ethapi.AccountStorage{ + TransactionOpts{ + KnownAccounts: map[common.Address]AccountStorage{ + common.HexToAddress("0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0"): AccountStorage{ StorageRoot: ptr(common.HexToHash("0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563")), }, }, @@ -41,9 +40,9 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) { "StorageSlots", `{"knownAccounts":{"0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0":{"0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8":"0x0000000000000000000000000000000000000000000000000000000000000000"}}}`, false, - ethapi.TransactionOpts{ - KnownAccounts: map[common.Address]ethapi.AccountStorage{ - common.HexToAddress("0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0"): ethapi.AccountStorage{ + TransactionOpts{ + KnownAccounts: map[common.Address]AccountStorage{ + common.HexToAddress("0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0"): AccountStorage{ StorageRoot: nil, StorageSlots: map[common.Hash]common.Hash{ common.HexToHash("0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8"): common.HexToHash("0x"), @@ -56,15 +55,15 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) { "EmptyObject", `{"knownAccounts":{}}`, false, - ethapi.TransactionOpts{ - KnownAccounts: make(map[common.Address]ethapi.AccountStorage), + TransactionOpts{ + KnownAccounts: make(map[common.Address]AccountStorage), }, }, { "EmptyStrings", `{"knownAccounts":{"":""}}`, true, - ethapi.TransactionOpts{ + TransactionOpts{ KnownAccounts: nil, }, }, @@ -72,7 +71,7 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) { "BlockNumberMin", `{"blockNumberMin":"0x1"}`, false, - ethapi.TransactionOpts{ + TransactionOpts{ BlockNumberMin: u64Ptr(1), }, }, @@ -80,7 +79,7 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) { "BlockNumberMax", `{"blockNumberMin":"0x1", "blockNumberMax":"0x2"}`, false, - ethapi.TransactionOpts{ + TransactionOpts{ BlockNumberMin: u64Ptr(1), BlockNumberMax: u64Ptr(2), }, @@ -89,7 +88,7 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) { "TimestampMin", `{"timestampMin":"0xffff"}`, false, - ethapi.TransactionOpts{ + TransactionOpts{ TimestampMin: u64Ptr(0xffff), }, }, @@ -97,7 +96,7 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) { "TimestampMax", `{"timestampMax":"0xffffff"}`, false, - ethapi.TransactionOpts{ + TransactionOpts{ TimestampMax: u64Ptr(0xffffff), }, }, @@ -105,7 +104,7 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - var opts ethapi.TransactionOpts + var opts TransactionOpts err := json.Unmarshal([]byte(test.input), &opts) if test.mustFail && err == nil { t.Errorf("Test %s should fail", test.name) diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 8cf50eb528..1a586ec039 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -29,7 +29,6 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/rpc" ) @@ -737,7 +736,7 @@ func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) er // // If the transaction was a contract creation use the TransactionReceipt method to get the // contract address after the transaction has been mined. -func (ec *Client) SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts ethapi.TransactionOpts) error { +func (ec *Client) SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts types.TransactionOpts) error { data, err := tx.MarshalBinary() if err != nil { return err diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go index 54ce597b09..7abc104fd1 100644 --- a/ethclient/ethclient_test.go +++ b/ethclient/ethclient_test.go @@ -34,7 +34,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/ethconfig" - "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" @@ -770,9 +769,9 @@ func sendTransactionConditional(ec *Client) error { } root := common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") - return ec.SendTransactionConditional(context.Background(), tx, ethapi.TransactionOpts{ - KnownAccounts: map[common.Address]ethapi.AccountStorage{ - testAddr: ethapi.AccountStorage{ + return ec.SendTransactionConditional(context.Background(), tx, types.TransactionOpts{ + KnownAccounts: map[common.Address]types.AccountStorage{ + testAddr: types.AccountStorage{ StorageRoot: &root, }, }, diff --git a/ethclient/simulated/backend.go b/ethclient/simulated/backend.go index 13e7cad586..a577343df3 100644 --- a/ethclient/simulated/backend.go +++ b/ethclient/simulated/backend.go @@ -30,7 +30,6 @@ import ( "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/ethclient" - "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/params" @@ -39,7 +38,7 @@ import ( // TransactionConditionalSender injects the conditional transaction into the pending pool for execution after verification. type TransactionConditionalSender interface { - SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts ethapi.TransactionOpts) error + SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts types.TransactionOpts) error } // Client exposes the methods provided by the Ethereum RPC client. diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 6a2ac19319..0f029a503d 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -2314,7 +2314,7 @@ func (s *TransactionAPI) SendRawTransaction(ctx context.Context, input hexutil.B // SendRawTransactionConditional will add the signed transaction to the transaction pool. // The sender/bundler is responsible for signing the transaction -func (s *TransactionAPI) SendRawTransactionConditional(ctx context.Context, input hexutil.Bytes, opts TransactionOpts) (common.Hash, error) { +func (s *TransactionAPI) SendRawTransactionConditional(ctx context.Context, input hexutil.Bytes, opts types.TransactionOpts) (common.Hash, error) { tx := new(types.Transaction) if err := tx.UnmarshalBinary(input); err != nil { return common.Hash{}, err @@ -2324,7 +2324,7 @@ func (s *TransactionAPI) SendRawTransactionConditional(ctx context.Context, inpu if state == nil || err != nil { return common.Hash{}, err } - if err := opts.Check(header.Number.Uint64(), header.Time, state); err != nil { + if err := TxOptsCheck(opts, header.Number.Uint64(), header.Time, state); err != nil { return common.Hash{}, err } return SubmitTransaction(ctx, s.b, tx) diff --git a/internal/ethapi/transaction_options.go b/internal/ethapi/transaction_opts_utils.go similarity index 51% rename from internal/ethapi/transaction_options.go rename to internal/ethapi/transaction_opts_utils.go index 77b1729037..c85b995957 100644 --- a/internal/ethapi/transaction_options.go +++ b/internal/ethapi/transaction_opts_utils.go @@ -2,52 +2,14 @@ package ethapi import ( "bytes" - "encoding/json" "errors" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" ) -type AccountStorage struct { - StorageRoot *common.Hash - StorageSlots map[common.Hash]common.Hash -} - -func (a *AccountStorage) UnmarshalJSON(data []byte) error { - var hash common.Hash - if err := json.Unmarshal(data, &hash); err == nil { - a.StorageRoot = &hash - return nil - } - return json.Unmarshal(data, &a.StorageSlots) -} - -func (a AccountStorage) MarshalJSON() ([]byte, error) { - if a.StorageRoot != nil { - return json.Marshal(*a.StorageRoot) - } - return json.Marshal(a.StorageSlots) -} - -type KnownAccounts map[common.Address]AccountStorage - -// It is known that marshaling is broken -// https://github.com/golang/go/issues/55890 - -//go:generate go run github.com/fjl/gencodec -type TransactionOpts -out gen_tx_opts_json.go -type TransactionOpts struct { - KnownAccounts KnownAccounts `json:"knownAccounts"` - BlockNumberMin *hexutil.Uint64 `json:"blockNumberMin,omitempty"` - BlockNumberMax *hexutil.Uint64 `json:"blockNumberMax,omitempty"` - TimestampMin *hexutil.Uint64 `json:"timestampMin,omitempty"` - TimestampMax *hexutil.Uint64 `json:"timestampMax,omitempty"` -} - const MaxNumberOfEntries = 1000 -func (o *TransactionOpts) Check(blockNumber uint64, timeStamp uint64, statedb *state.StateDB) error { +func TxOptsCheck(o types.TransactionOpts, blockNumber uint64, timeStamp uint64, statedb *state.StateDB) error { if o.BlockNumberMin != nil && blockNumber < uint64(*o.BlockNumberMin) { return errors.New("BlockNumberMin condition not met") } @@ -71,10 +33,10 @@ func (o *TransactionOpts) Check(blockNumber uint64, timeStamp uint64, statedb *s if counter > MaxNumberOfEntries { return errors.New("knownAccounts too large") } - return o.CheckStorage(statedb) + return TxOptsCheckStorage(o, statedb) } -func (o *TransactionOpts) CheckStorage(statedb *state.StateDB) error { +func TxOptsCheckStorage(o types.TransactionOpts, statedb *state.StateDB) error { for address, accountStorage := range o.KnownAccounts { if accountStorage.StorageRoot != nil { rootHash := statedb.GetRoot(address) From 89ea9803e4d936a8460b713279b7fbc27257a30d Mon Sep 17 00:00:00 2001 From: galaio Date: Fri, 11 Oct 2024 14:49:48 +0800 Subject: [PATCH 2/2] ethclient: fix some lint issues; --- core/types/transaction_options.go | 1 + internal/ethapi/transaction_opts_utils.go | 1 + 2 files changed, 2 insertions(+) diff --git a/core/types/transaction_options.go b/core/types/transaction_options.go index 0901bf6e05..4f0484b3fd 100644 --- a/core/types/transaction_options.go +++ b/core/types/transaction_options.go @@ -2,6 +2,7 @@ package types import ( "encoding/json" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" ) diff --git a/internal/ethapi/transaction_opts_utils.go b/internal/ethapi/transaction_opts_utils.go index c85b995957..131ac82e29 100644 --- a/internal/ethapi/transaction_opts_utils.go +++ b/internal/ethapi/transaction_opts_utils.go @@ -3,6 +3,7 @@ package ethapi import ( "bytes" "errors" + "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" )