Skip to content

Commit cc33a21

Browse files
CoderZhiclaude
andcommitted
feat: add SetCodeAuthorization wrapper using IoTeX chain IDs
Add SetCodeAuthorization struct that accepts IoTeX chain IDs (1/2/3) and maps them to EVM network IDs (4689/4690/4691) in authListToProto, consistent with ActionCore.chainID handling. The proto field retains EVM network IDs as iotex-core fromProto expects. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 3f629d5 commit cc33a21

7 files changed

Lines changed: 49 additions & 37 deletions

File tree

iotex/caller_contract.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ func (c *executeContractCaller) SetBlobTxData(b *BlobData) ExecuteContractCaller
157157
return c
158158
}
159159

160-
func (c *executeContractCaller) SetSetCodeAuthList(a []types.SetCodeAuthorization) ExecuteContractCaller {
160+
func (c *executeContractCaller) SetSetCodeAuthList(a []SetCodeAuthorization) ExecuteContractCaller {
161161
c.sendActionCaller.setSetCodeAuthList(a)
162162
return c
163163
}

iotex/callers.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type sendActionCaller struct {
4444
gasFeeCap *big.Int
4545
accessList types.AccessList
4646
blobTxData *iotextypes.BlobTxData
47-
setCodeAuthList []types.SetCodeAuthorization
47+
setCodeAuthList []SetCodeAuthorization
4848
}
4949

5050
// API returns api
@@ -97,7 +97,7 @@ func (c *sendActionCaller) setAccessList(l types.AccessList) {
9797
func (c *sendActionCaller) setBlobTxData(b *iotextypes.BlobTxData) {
9898
c.blobTxData = b
9999
}
100-
func (c *sendActionCaller) setSetCodeAuthList(a []types.SetCodeAuthorization) {
100+
func (c *sendActionCaller) setSetCodeAuthList(a []SetCodeAuthorization) {
101101
c.setCodeAuthList = a
102102
}
103103

iotex/callers_typed_test.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313

1414
"github.com/ethereum/go-ethereum/common"
1515
"github.com/ethereum/go-ethereum/core/types"
16-
"github.com/holiman/uint256"
1716
"github.com/iotexproject/iotex-address/address"
1817
"github.com/iotexproject/iotex-proto/golang/iotexapi"
1918
"github.com/iotexproject/iotex-proto/golang/iotexapi/mock_iotexapi"
@@ -37,8 +36,8 @@ func TestExecuteCaller_TypedSettersPropagate(t *testing.T) {
3736
BlobFeeCap: big.NewInt(7),
3837
BlobHashes: []common.Hash{common.HexToHash("0x01")},
3938
}
40-
auths := []types.SetCodeAuthorization{{
41-
ChainID: *uint256.NewInt(2),
39+
auths := []SetCodeAuthorization{{
40+
ChainID: 2,
4241
Address: common.HexToAddress("0xab"),
4342
Nonce: 3,
4443
}}
@@ -103,8 +102,8 @@ func TestApplyTypedFields_SetCode(t *testing.T) {
103102
txType: setCodeTxType,
104103
gasTipCap: big.NewInt(1),
105104
gasFeeCap: big.NewInt(2),
106-
setCodeAuthList: []types.SetCodeAuthorization{{
107-
ChainID: *uint256.NewInt(4690),
105+
setCodeAuthList: []SetCodeAuthorization{{
106+
ChainID: 2, // IoTeX testnet → maps to EVM 4690
108107
Address: common.HexToAddress("0xab"),
109108
Nonce: 1,
110109
}},
@@ -127,20 +126,20 @@ func TestApplyTypedFields_SetCodeEmptyList(t *testing.T) {
127126
require.Contains(t, err.Error(), "non-empty auth list")
128127
}
129128

130-
func TestApplyTypedFields_SetCodeChainIDOverflow(t *testing.T) {
129+
func TestApplyTypedFields_SetCodeInvalidChainID(t *testing.T) {
131130
c := &sendActionCaller{
132131
core: execCore(),
133132
txType: setCodeTxType,
134133
gasTipCap: big.NewInt(1),
135134
gasFeeCap: big.NewInt(2),
136-
setCodeAuthList: []types.SetCodeAuthorization{{
137-
ChainID: *new(uint256.Int).Lsh(uint256.NewInt(1), 33),
135+
setCodeAuthList: []SetCodeAuthorization{{
136+
ChainID: 4, // invalid IoTeX chain ID (must be 1, 2, or 3)
138137
Address: common.HexToAddress("0xab"),
139138
}},
140139
}
141140
err := c.applyTypedFields()
142141
require.Error(t, err)
143-
require.Contains(t, err.Error(), "overflows uint32")
142+
require.Contains(t, err.Error(), "invalid chain id")
144143
}
145144

146145
// TestCall_TypedTx_RoutesToContainer drives a full typed-tx Call() against a

iotex/interfaces.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ type ExecuteContractCaller interface {
9999
SetGasFeeCap(*big.Int) ExecuteContractCaller
100100
SetAccessList(types.AccessList) ExecuteContractCaller
101101
SetBlobTxData(*BlobData) ExecuteContractCaller
102-
SetSetCodeAuthList([]types.SetCodeAuthorization) ExecuteContractCaller
102+
SetSetCodeAuthList([]SetCodeAuthorization) ExecuteContractCaller
103103
}
104104

105105
// DeployContractCaller is used to perform a deploy contract call.

iotex/interfaces_mock.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

iotex/typed_tx.go

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ package iotex
77

88
import (
99
"fmt"
10-
"math"
1110
"math/big"
1211

1312
"github.com/ethereum/go-ethereum/common"
@@ -65,25 +64,43 @@ func sidecarToProto(sc *types.BlobTxSidecar) *iotextypes.BlobTxSidecar {
6564
return out
6665
}
6766

68-
// authListToProto converts go-ethereum SetCodeAuthorization tuples to the
69-
// proto form. The proto ChainID field is uint32, so an authorization whose
70-
// ChainID does not fit is rejected rather than silently truncated.
71-
func authListToProto(list []types.SetCodeAuthorization) ([]*iotextypes.SetCodeAuthorization, error) {
67+
// SetCodeAuthorization is an IoTeX-chain-ID-aware EIP-7702 authorization tuple.
68+
// ChainID uses IoTeX chain IDs (1=mainnet, 2=testnet, 3=nightly), which are
69+
// mapped to EVM network IDs (4689/4690/4691) before submission.
70+
type SetCodeAuthorization struct {
71+
ChainID uint32 // IoTeX chain ID: 1=mainnet, 2=testnet, 3=nightly
72+
Address common.Address
73+
Nonce uint64
74+
V uint8
75+
R, S *big.Int
76+
}
77+
78+
// authListToProto converts IoTeX SetCodeAuthorization tuples to proto form,
79+
// mapping IoTeX chain IDs to EVM network IDs in the process.
80+
func authListToProto(list []SetCodeAuthorization) ([]*iotextypes.SetCodeAuthorization, error) {
7281
if len(list) == 0 {
7382
return nil, nil
7483
}
7584
out := make([]*iotextypes.SetCodeAuthorization, len(list))
7685
for i, a := range list {
77-
if !a.ChainID.IsUint64() || a.ChainID.Uint64() > math.MaxUint32 {
78-
return nil, fmt.Errorf("setcode authorization %d: chainID %s overflows uint32", i, a.ChainID.String())
86+
evmID, err := toEVMChainID(a.ChainID)
87+
if err != nil {
88+
return nil, fmt.Errorf("setcode authorization %d: %w", i, err)
89+
}
90+
var r, s []byte
91+
if a.R != nil {
92+
r = a.R.Bytes()
93+
}
94+
if a.S != nil {
95+
s = a.S.Bytes()
7996
}
8097
out[i] = &iotextypes.SetCodeAuthorization{
81-
ChainID: uint32(a.ChainID.Uint64()),
98+
ChainID: uint32(evmID.Uint64()),
8299
Address: a.Address.Bytes(),
83100
Nonce: a.Nonce,
84101
V: uint64(a.V),
85-
R: a.R.Bytes(),
86-
S: a.S.Bytes(),
102+
R: r,
103+
S: s,
87104
}
88105
}
89106
return out, nil

iotex/typed_tx_conv_test.go

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import (
1010
"testing"
1111

1212
"github.com/ethereum/go-ethereum/common"
13-
"github.com/ethereum/go-ethereum/core/types"
14-
"github.com/holiman/uint256"
1513
"github.com/stretchr/testify/require"
1614
)
1715

@@ -35,13 +33,13 @@ func TestBlobData_toProto_NilSafe(t *testing.T) {
3533

3634
func TestAuthListToProto(t *testing.T) {
3735
addr := common.HexToAddress("0xababababababababababababababababababab01")
38-
auths := []types.SetCodeAuthorization{{
39-
ChainID: *uint256.NewInt(4690),
36+
auths := []SetCodeAuthorization{{
37+
ChainID: 2, // IoTeX testnet → maps to EVM 4690
4038
Address: addr,
4139
Nonce: 7,
4240
V: 1,
43-
R: *new(uint256.Int).SetBytes([]byte{0xaa, 0xbb}),
44-
S: *new(uint256.Int).SetBytes([]byte{0xcc, 0xdd}),
41+
R: new(big.Int).SetBytes([]byte{0xaa, 0xbb}),
42+
S: new(big.Int).SetBytes([]byte{0xcc, 0xdd}),
4543
}}
4644
pb, err := authListToProto(auths)
4745
require.NoError(t, err)
@@ -58,19 +56,17 @@ func TestAuthListToProto_Empty(t *testing.T) {
5856
pb, err := authListToProto(nil)
5957
require.NoError(t, err)
6058
require.Nil(t, pb)
61-
pb, err = authListToProto([]types.SetCodeAuthorization{})
59+
pb, err = authListToProto([]SetCodeAuthorization{})
6260
require.NoError(t, err)
6361
require.Nil(t, pb)
6462
}
6563

66-
func TestAuthListToProto_ChainIDOverflow(t *testing.T) {
67-
// a chainID that does not fit in uint32 must be rejected, not truncated
68-
big33bit := new(uint256.Int).Lsh(uint256.NewInt(1), 33)
69-
auths := []types.SetCodeAuthorization{{
70-
ChainID: *big33bit,
64+
func TestAuthListToProto_InvalidChainID(t *testing.T) {
65+
auths := []SetCodeAuthorization{{
66+
ChainID: 4, // invalid IoTeX chain ID (must be 1, 2, or 3)
7167
Address: common.HexToAddress("0x01"),
7268
}}
7369
_, err := authListToProto(auths)
7470
require.Error(t, err)
75-
require.Contains(t, err.Error(), "overflows uint32")
71+
require.Contains(t, err.Error(), "invalid chain id")
7672
}

0 commit comments

Comments
 (0)