diff --git a/core/blockchain_test.go b/core/blockchain_test.go index fc0e3d8446ca..e247ce3d7d37 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -4274,12 +4274,11 @@ func TestEIP7702(t *testing.T) { // 2. addr1:0xaaaa calls into addr2:0xbbbb // 3. addr2:0xbbbb writes to storage auth1, _ := types.SignSetCode(key1, types.SetCodeAuthorization{ - ChainID: gspec.Config.ChainID.Uint64(), + ChainID: *uint256.MustFromBig(gspec.Config.ChainID), Address: aa, Nonce: 1, }) auth2, _ := types.SignSetCode(key2, types.SetCodeAuthorization{ - ChainID: 0, Address: bb, Nonce: 0, }) @@ -4287,7 +4286,7 @@ func TestEIP7702(t *testing.T) { _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) { b.SetCoinbase(aa) txdata := &types.SetCodeTx{ - ChainID: gspec.Config.ChainID.Uint64(), + ChainID: uint256.MustFromBig(gspec.Config.ChainID), Nonce: 0, To: addr1, Gas: 500000, diff --git a/core/state_transition.go b/core/state_transition.go index 93d72d16b715..8083701c8e98 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -529,8 +529,8 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { // validateAuthorization validates an EIP-7702 authorization against the state. func (st *stateTransition) validateAuthorization(auth *types.SetCodeAuthorization) (authority common.Address, err error) { - // Verify chain ID is 0 or equal to current chain ID. - if auth.ChainID != 0 && st.evm.ChainConfig().ChainID.Uint64() != auth.ChainID { + // Verify chain ID is null or equal to current chain ID. + if !auth.ChainID.IsZero() && auth.ChainID.CmpBig(st.evm.ChainConfig().ChainID) != 0 { return authority, ErrAuthorizationWrongChainID } // Limit nonce to 2^64-1 per EIP-2681. diff --git a/core/types/gen_authorization.go b/core/types/gen_authorization.go index be5467c50d0d..57069cbb1f06 100644 --- a/core/types/gen_authorization.go +++ b/core/types/gen_authorization.go @@ -16,7 +16,7 @@ var _ = (*authorizationMarshaling)(nil) // MarshalJSON marshals as JSON. func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) { type SetCodeAuthorization struct { - ChainID hexutil.Uint64 `json:"chainId" gencodec:"required"` + ChainID hexutil.U256 `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce hexutil.Uint64 `json:"nonce" gencodec:"required"` V hexutil.Uint64 `json:"yParity" gencodec:"required"` @@ -24,7 +24,7 @@ func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) { S hexutil.U256 `json:"s" gencodec:"required"` } var enc SetCodeAuthorization - enc.ChainID = hexutil.Uint64(s.ChainID) + enc.ChainID = hexutil.U256(s.ChainID) enc.Address = s.Address enc.Nonce = hexutil.Uint64(s.Nonce) enc.V = hexutil.Uint64(s.V) @@ -36,7 +36,7 @@ func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (s *SetCodeAuthorization) UnmarshalJSON(input []byte) error { type SetCodeAuthorization struct { - ChainID *hexutil.Uint64 `json:"chainId" gencodec:"required"` + ChainID *hexutil.U256 `json:"chainId" gencodec:"required"` Address *common.Address `json:"address" gencodec:"required"` Nonce *hexutil.Uint64 `json:"nonce" gencodec:"required"` V *hexutil.Uint64 `json:"yParity" gencodec:"required"` @@ -50,7 +50,7 @@ func (s *SetCodeAuthorization) UnmarshalJSON(input []byte) error { if dec.ChainID == nil { return errors.New("missing required field 'chainId' for SetCodeAuthorization") } - s.ChainID = uint64(*dec.ChainID) + s.ChainID = uint256.Int(*dec.ChainID) if dec.Address == nil { return errors.New("missing required field 'address' for SetCodeAuthorization") } diff --git a/core/types/transaction_marshalling.go b/core/types/transaction_marshalling.go index 993d633c6fb6..1bbb97a3ec04 100644 --- a/core/types/transaction_marshalling.go +++ b/core/types/transaction_marshalling.go @@ -155,7 +155,7 @@ func (tx *Transaction) MarshalJSON() ([]byte, error) { enc.Proofs = itx.Sidecar.Proofs } case *SetCodeTx: - enc.ChainID = (*hexutil.Big)(new(big.Int).SetUint64(itx.ChainID)) + enc.ChainID = (*hexutil.Big)(itx.ChainID.ToBig()) enc.Nonce = (*hexutil.Uint64)(&itx.Nonce) enc.To = tx.To() enc.Gas = (*hexutil.Uint64)(&itx.Gas) @@ -353,7 +353,11 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { if dec.ChainID == nil { return errors.New("missing required field 'chainId' in transaction") } - itx.ChainID = uint256.MustFromBig((*big.Int)(dec.ChainID)) + var overflow bool + itx.ChainID, overflow = uint256.FromBig(dec.ChainID.ToInt()) + if overflow { + return errors.New("'chainId' value overflows uint256") + } if dec.Nonce == nil { return errors.New("missing required field 'nonce' in transaction") } @@ -395,7 +399,6 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { itx.BlobHashes = dec.BlobVersionedHashes // signature R - var overflow bool if dec.R == nil { return errors.New("missing required field 'r' in transaction") } @@ -432,7 +435,11 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { if dec.ChainID == nil { return errors.New("missing required field 'chainId' in transaction") } - itx.ChainID = dec.ChainID.ToInt().Uint64() + var overflow bool + itx.ChainID, overflow = uint256.FromBig(dec.ChainID.ToInt()) + if overflow { + return errors.New("'chainId' value overflows uint256") + } if dec.Nonce == nil { return errors.New("missing required field 'nonce' in transaction") } @@ -470,7 +477,6 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error { itx.AuthList = dec.AuthorizationList // signature R - var overflow bool if dec.R == nil { return errors.New("missing required field 'r' in transaction") } diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index d72643b4a8d4..4d70f37bd350 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -219,7 +219,7 @@ func (s pragueSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big } // Check that chain ID of tx matches the signer. We also accept ID zero here, // because it indicates that the chain ID was not specified in the tx. - if txdata.ChainID != 0 && new(big.Int).SetUint64(txdata.ChainID).Cmp(s.chainId) != 0 { + if txdata.ChainID != nil && txdata.ChainID.CmpBig(s.chainId) != 0 { return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId) } R, S, _ = decodeSignature(sig) diff --git a/core/types/tx_blob.go b/core/types/tx_blob.go index ce1f287caaf8..88251ab95729 100644 --- a/core/types/tx_blob.go +++ b/core/types/tx_blob.go @@ -47,9 +47,9 @@ type BlobTx struct { Sidecar *BlobTxSidecar `rlp:"-"` // Signature values - V *uint256.Int `json:"v" gencodec:"required"` - R *uint256.Int `json:"r" gencodec:"required"` - S *uint256.Int `json:"s" gencodec:"required"` + V *uint256.Int + R *uint256.Int + S *uint256.Int } // BlobTxSidecar contains the blobs of a blob transaction. diff --git a/core/types/tx_dynamic_fee.go b/core/types/tx_dynamic_fee.go index 8b5b514fdec5..981755cf7007 100644 --- a/core/types/tx_dynamic_fee.go +++ b/core/types/tx_dynamic_fee.go @@ -37,9 +37,9 @@ type DynamicFeeTx struct { AccessList AccessList // Signature values - V *big.Int `json:"v" gencodec:"required"` - R *big.Int `json:"r" gencodec:"required"` - S *big.Int `json:"s" gencodec:"required"` + V *big.Int + R *big.Int + S *big.Int } // copy creates a deep copy of the transaction data and initializes all fields. diff --git a/core/types/tx_setcode.go b/core/types/tx_setcode.go index f14ae3bc9d2f..0fb5362c26c1 100644 --- a/core/types/tx_setcode.go +++ b/core/types/tx_setcode.go @@ -49,7 +49,7 @@ func AddressToDelegation(addr common.Address) []byte { // SetCodeTx implements the EIP-7702 transaction type which temporarily installs // the code at the signer's address. type SetCodeTx struct { - ChainID uint64 + ChainID *uint256.Int Nonce uint64 GasTipCap *uint256.Int // a.k.a. maxPriorityFeePerGas GasFeeCap *uint256.Int // a.k.a. maxFeePerGas @@ -61,16 +61,16 @@ type SetCodeTx struct { AuthList []SetCodeAuthorization // Signature values - V *uint256.Int `json:"v" gencodec:"required"` - R *uint256.Int `json:"r" gencodec:"required"` - S *uint256.Int `json:"s" gencodec:"required"` + V *uint256.Int + R *uint256.Int + S *uint256.Int } //go:generate go run github.com/fjl/gencodec -type SetCodeAuthorization -field-override authorizationMarshaling -out gen_authorization.go // SetCodeAuthorization is an authorization from an account to deploy code at its address. type SetCodeAuthorization struct { - ChainID uint64 `json:"chainId" gencodec:"required"` + ChainID uint256.Int `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce uint64 `json:"nonce" gencodec:"required"` V uint8 `json:"yParity" gencodec:"required"` @@ -80,7 +80,7 @@ type SetCodeAuthorization struct { // field type overrides for gencodec type authorizationMarshaling struct { - ChainID hexutil.Uint64 + ChainID hexutil.U256 Nonce hexutil.Uint64 V hexutil.Uint64 R hexutil.U256 @@ -180,7 +180,7 @@ func (tx *SetCodeTx) copy() TxData { // accessors for innerTx. func (tx *SetCodeTx) txType() byte { return SetCodeTxType } -func (tx *SetCodeTx) chainID() *big.Int { return big.NewInt(int64(tx.ChainID)) } +func (tx *SetCodeTx) chainID() *big.Int { return tx.ChainID.ToBig() } func (tx *SetCodeTx) accessList() AccessList { return tx.AccessList } func (tx *SetCodeTx) data() []byte { return tx.Data } func (tx *SetCodeTx) gas() uint64 { return tx.Gas } @@ -207,7 +207,7 @@ func (tx *SetCodeTx) rawSignatureValues() (v, r, s *big.Int) { } func (tx *SetCodeTx) setSignatureValues(chainID, v, r, s *big.Int) { - tx.ChainID = chainID.Uint64() + tx.ChainID = uint256.MustFromBig(chainID) tx.V.SetFromBig(v) tx.R.SetFromBig(r) tx.S.SetFromBig(s) diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index a39a6666f497..175ac13a0f9b 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -503,7 +503,7 @@ func (args *TransactionArgs) ToTransaction(defaultType int) *types.Transaction { } data = &types.SetCodeTx{ To: *args.To, - ChainID: args.ChainID.ToInt().Uint64(), + ChainID: uint256.MustFromBig(args.ChainID.ToInt()), Nonce: uint64(*args.Nonce), Gas: uint64(*args.Gas), GasFeeCap: uint256.MustFromBig((*big.Int)(args.MaxFeePerGas)), diff --git a/tests/gen_stauthorization.go b/tests/gen_stauthorization.go index fbafd6fdea03..4f2c50bd9ffc 100644 --- a/tests/gen_stauthorization.go +++ b/tests/gen_stauthorization.go @@ -16,7 +16,7 @@ var _ = (*stAuthorizationMarshaling)(nil) // MarshalJSON marshals as JSON. func (s stAuthorization) MarshalJSON() ([]byte, error) { type stAuthorization struct { - ChainID math.HexOrDecimal64 + ChainID *math.HexOrDecimal256 `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce math.HexOrDecimal64 `json:"nonce" gencodec:"required"` V math.HexOrDecimal64 `json:"v" gencodec:"required"` @@ -24,7 +24,7 @@ func (s stAuthorization) MarshalJSON() ([]byte, error) { S *math.HexOrDecimal256 `json:"s" gencodec:"required"` } var enc stAuthorization - enc.ChainID = math.HexOrDecimal64(s.ChainID) + enc.ChainID = (*math.HexOrDecimal256)(s.ChainID) enc.Address = s.Address enc.Nonce = math.HexOrDecimal64(s.Nonce) enc.V = math.HexOrDecimal64(s.V) @@ -36,7 +36,7 @@ func (s stAuthorization) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (s *stAuthorization) UnmarshalJSON(input []byte) error { type stAuthorization struct { - ChainID *math.HexOrDecimal64 + ChainID *math.HexOrDecimal256 `json:"chainId" gencodec:"required"` Address *common.Address `json:"address" gencodec:"required"` Nonce *math.HexOrDecimal64 `json:"nonce" gencodec:"required"` V *math.HexOrDecimal64 `json:"v" gencodec:"required"` @@ -47,9 +47,10 @@ func (s *stAuthorization) UnmarshalJSON(input []byte) error { if err := json.Unmarshal(input, &dec); err != nil { return err } - if dec.ChainID != nil { - s.ChainID = uint64(*dec.ChainID) + if dec.ChainID == nil { + return errors.New("missing required field 'chainId' for stAuthorization") } + s.ChainID = (*big.Int)(dec.ChainID) if dec.Address == nil { return errors.New("missing required field 'address' for stAuthorization") } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 6e66bbaa7218..740ebd4afdcc 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -140,7 +140,7 @@ type stTransactionMarshaling struct { // Authorization is an authorization from an account to deploy code at it's address. type stAuthorization struct { - ChainID uint64 + ChainID *big.Int `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce uint64 `json:"nonce" gencodec:"required"` V uint8 `json:"v" gencodec:"required"` @@ -150,7 +150,7 @@ type stAuthorization struct { // field type overrides for gencodec type stAuthorizationMarshaling struct { - ChainID math.HexOrDecimal64 + ChainID *math.HexOrDecimal256 Nonce math.HexOrDecimal64 V math.HexOrDecimal64 R *math.HexOrDecimal256 @@ -446,7 +446,7 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Mess authList = make([]types.SetCodeAuthorization, len(tx.AuthorizationList)) for i, auth := range tx.AuthorizationList { authList[i] = types.SetCodeAuthorization{ - ChainID: auth.ChainID, + ChainID: *uint256.MustFromBig(auth.ChainID), Address: auth.Address, Nonce: auth.Nonce, V: auth.V,