Skip to content

Commit 01e1728

Browse files
committed
all: add support for EIP-2718, EIP-2930 transactions (ethereum#21502)
1 parent 8973e73 commit 01e1728

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+2496
-649
lines changed

accounts/abi/bind/backends/simulated.go

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,10 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa
388388
b.mu.Lock()
389389
defer b.mu.Unlock()
390390

391-
sender, err := types.Sender(types.HomesteadSigner{}, tx)
391+
// Check transaction validity.
392+
block := b.blockchain.CurrentBlock()
393+
signer := types.MakeSigner(b.blockchain.Config(), block.Number())
394+
sender, err := types.Sender(signer, tx)
392395
if err != nil {
393396
panic(fmt.Errorf("invalid transaction: %v", err))
394397
}
@@ -397,7 +400,8 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa
397400
panic(fmt.Errorf("invalid transaction nonce: got %d, want %d", tx.Nonce(), nonce))
398401
}
399402

400-
blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), b.blockchain.Engine(), b.database, 1, func(number int, block *core.BlockGen) {
403+
// Include tx in chain.
404+
blocks, _ := core.GenerateChain(b.config, block, b.blockchain.Engine(), b.database, 1, func(number int, block *core.BlockGen) {
401405
for _, tx := range b.pendingBlock.Transactions() {
402406
block.AddTxWithChain(b.blockchain, tx)
403407
}
@@ -506,15 +510,16 @@ type callmsg struct {
506510
XDPoSChain.CallMsg
507511
}
508512

509-
func (m callmsg) From() common.Address { return m.CallMsg.From }
510-
func (m callmsg) Nonce() uint64 { return 0 }
511-
func (m callmsg) CheckNonce() bool { return false }
512-
func (m callmsg) To() *common.Address { return m.CallMsg.To }
513-
func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
514-
func (m callmsg) Gas() uint64 { return m.CallMsg.Gas }
515-
func (m callmsg) Value() *big.Int { return m.CallMsg.Value }
516-
func (m callmsg) Data() []byte { return m.CallMsg.Data }
517-
func (m callmsg) BalanceTokenFee() *big.Int { return m.CallMsg.BalanceTokenFee }
513+
func (m callmsg) From() common.Address { return m.CallMsg.From }
514+
func (m callmsg) Nonce() uint64 { return 0 }
515+
func (m callmsg) CheckNonce() bool { return false }
516+
func (m callmsg) To() *common.Address { return m.CallMsg.To }
517+
func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
518+
func (m callmsg) Gas() uint64 { return m.CallMsg.Gas }
519+
func (m callmsg) Value() *big.Int { return m.CallMsg.Value }
520+
func (m callmsg) Data() []byte { return m.CallMsg.Data }
521+
func (m callmsg) BalanceTokenFee() *big.Int { return m.CallMsg.BalanceTokenFee }
522+
func (m callmsg) AccessList() types.AccessList { return m.CallMsg.AccessList }
518523

519524
// filterBackend implements filters.Backend to support filtering for logs without
520525
// taking bloom-bits acceleration structures into account.

accounts/keystore/keystore.go

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,9 @@ func (ks *KeyStore) SignTx(a accounts.Account, tx *types.Transaction, chainID *b
288288
if !found {
289289
return nil, ErrLocked
290290
}
291-
// Depending on the presence of the chain ID, sign with EIP155 or homestead
292-
if chainID != nil {
293-
return types.SignTx(tx, types.NewEIP155Signer(chainID), unlockedKey.PrivateKey)
294-
}
295-
return types.SignTx(tx, types.HomesteadSigner{}, unlockedKey.PrivateKey)
291+
// Depending on the presence of the chain ID, sign with 2718 or homestead
292+
signer := types.LatestSignerForChainID(chainID)
293+
return types.SignTx(tx, signer, unlockedKey.PrivateKey)
296294
}
297295

298296
// SignHashWithPassphrase signs hash if the private key matching the given address
@@ -316,11 +314,9 @@ func (ks *KeyStore) SignTxWithPassphrase(a accounts.Account, passphrase string,
316314
}
317315
defer zeroKey(key.PrivateKey)
318316

319-
// Depending on the presence of the chain ID, sign with EIP155 or homestead
320-
if chainID != nil {
321-
return types.SignTx(tx, types.NewEIP155Signer(chainID), key.PrivateKey)
322-
}
323-
return types.SignTx(tx, types.HomesteadSigner{}, key.PrivateKey)
317+
// Depending on the presence of the chain ID, sign with or without replay protection.
318+
signer := types.LatestSignerForChainID(chainID)
319+
return types.SignTx(tx, signer, key.PrivateKey)
324320
}
325321

326322
// Unlock unlocks the given account indefinitely.

accounts/usbwallet/trezor.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ import (
2727
"io"
2828
"math/big"
2929

30-
"github.com/golang/protobuf/proto"
3130
"github.com/XinFinOrg/XDPoSChain/accounts"
3231
"github.com/XinFinOrg/XDPoSChain/accounts/usbwallet/internal/trezor"
3332
"github.com/XinFinOrg/XDPoSChain/common"
3433
"github.com/XinFinOrg/XDPoSChain/common/hexutil"
3534
"github.com/XinFinOrg/XDPoSChain/core/types"
3635
"github.com/XinFinOrg/XDPoSChain/log"
36+
"github.com/golang/protobuf/proto"
3737
)
3838

3939
// ErrTrezorPINNeeded is returned if opening the trezor requires a PIN code. In
@@ -80,13 +80,13 @@ func (w *trezorDriver) Status() (string, error) {
8080

8181
// Open implements usbwallet.driver, attempting to initialize the connection to
8282
// the Trezor hardware wallet. Initializing the Trezor is a two phase operation:
83-
// * The first phase is to initialize the connection and read the wallet's
84-
// features. This phase is invoked is the provided passphrase is empty. The
85-
// device will display the pinpad as a result and will return an appropriate
86-
// error to notify the user that a second open phase is needed.
87-
// * The second phase is to unlock access to the Trezor, which is done by the
88-
// user actually providing a passphrase mapping a keyboard keypad to the pin
89-
// number of the user (shuffled according to the pinpad displayed).
83+
// - The first phase is to initialize the connection and read the wallet's
84+
// features. This phase is invoked is the provided passphrase is empty. The
85+
// device will display the pinpad as a result and will return an appropriate
86+
// error to notify the user that a second open phase is needed.
87+
// - The second phase is to unlock access to the Trezor, which is done by the
88+
// user actually providing a passphrase mapping a keyboard keypad to the pin
89+
// number of the user (shuffled according to the pinpad displayed).
9090
func (w *trezorDriver) Open(device io.ReadWriter, passphrase string) error {
9191
w.device, w.failure = device, nil
9292

@@ -220,9 +220,11 @@ func (w *trezorDriver) trezorSign(derivationPath []uint32, tx *types.Transaction
220220
if chainID == nil {
221221
signer = new(types.HomesteadSigner)
222222
} else {
223+
// Trezor backend does not support typed transactions yet.
223224
signer = types.NewEIP155Signer(chainID)
224225
signature[64] = signature[64] - byte(chainID.Uint64()*2+35)
225226
}
227+
226228
// Inject the final signature into the transaction and sanity check the sender
227229
signed, err := tx.WithSignature(signer, signature)
228230
if err != nil {

consensus/tests/engine_v1_tests/helper.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ func transferTx(t *testing.T, to common.Address, transferAmount int64) *types.Tr
163163
amount := big.NewInt(transferAmount)
164164
nonce := uint64(1)
165165
tx := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data)
166-
signedTX, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(chainID)), voterKey)
166+
signedTX, err := types.SignTx(tx, types.LatestSignerForChainID(big.NewInt(chainID)), voterKey)
167167
if err != nil {
168168
t.Fatal(err)
169169
}
@@ -183,7 +183,7 @@ func voteTX(gasLimit uint64, nonce uint64, addr string) (*types.Transaction, err
183183
to := common.HexToAddress(common.MasternodeVotingSMC)
184184
tx := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data)
185185

186-
signedTX, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(chainID)), voterKey)
186+
signedTX, err := types.SignTx(tx, types.LatestSignerForChainID(big.NewInt(chainID)), voterKey)
187187
if err != nil {
188188
return nil, err
189189
}
@@ -411,7 +411,7 @@ func createBlockFromHeader(bc *BlockChain, customHeader *types.Header, txs []*ty
411411
// nonce := uint64(0)
412412
// to := common.HexToAddress("xdc35658f7b2a9e7701e65e7a654659eb1c481d1dc5")
413413
// tx := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data)
414-
// signedTX, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(chainID)), acc4Key)
414+
// signedTX, err := types.SignTx(tx, types.LatestSignerForChainID(big.NewInt(chainID)), acc4Key)
415415
// if err != nil {
416416
// t.Fatal(err)
417417
// }

consensus/tests/engine_v2_tests/helper.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func voteTX(gasLimit uint64, nonce uint64, addr string) (*types.Transaction, err
108108
to := common.HexToAddress(common.MasternodeVotingSMC)
109109
tx := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data)
110110

111-
signedTX, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(chainID)), voterKey)
111+
signedTX, err := types.SignTx(tx, types.LatestSignerForChainID(big.NewInt(chainID)), voterKey)
112112
if err != nil {
113113
return nil, err
114114
}
@@ -285,7 +285,7 @@ func getMultiCandidatesBackend(t *testing.T, chainConfig *params.ChainConfig, n
285285

286286
func signingTxWithKey(header *types.Header, nonce uint64, privateKey *ecdsa.PrivateKey) (*types.Transaction, error) {
287287
tx := contracts.CreateTxSign(header.Number, header.Hash(), nonce, common.HexToAddress(common.BlockSigners))
288-
s := types.NewEIP155Signer(big.NewInt(chainID))
288+
s := types.LatestSignerForChainID(big.NewInt(chainID))
289289
h := s.Hash(tx)
290290
sig, err := crypto.Sign(h[:], privateKey)
291291
if err != nil {
@@ -300,7 +300,7 @@ func signingTxWithKey(header *types.Header, nonce uint64, privateKey *ecdsa.Priv
300300

301301
func signingTxWithSignerFn(header *types.Header, nonce uint64, signer common.Address, signFn func(account accounts.Account, hash []byte) ([]byte, error)) (*types.Transaction, error) {
302302
tx := contracts.CreateTxSign(header.Number, header.Hash(), nonce, common.HexToAddress(common.BlockSigners))
303-
s := types.NewEIP155Signer(big.NewInt(chainID))
303+
s := types.LatestSignerForChainID(big.NewInt(chainID))
304304
h := s.Hash(tx)
305305
sig, err := signFn(accounts.Account{Address: signer}, h[:])
306306
if err != nil {

contracts/trc21issuer/trc21issuer_test.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,13 @@ func TestFeeTxWithTRC21Token(t *testing.T) {
9191
t.Fatal("check balance after fail transfer in tr20: ", err, "get", balance, "transfer", airDropAmount)
9292
}
9393

94-
//check balance fee
94+
// check balance fee
9595
balanceIssuerFee, err = trc21Issuer.GetTokenCapacity(trc21TokenAddr)
96-
if err != nil || balanceIssuerFee.Cmp(remainFee) != 0 {
97-
t.Fatal("can't get balance token fee in smart contract: ", err, "got", balanceIssuerFee, "wanted", remainFee)
96+
if err != nil {
97+
t.Fatal("can't get balance token fee in smart contract: ", err)
98+
}
99+
if balanceIssuerFee.Cmp(remainFee) != 0 {
100+
t.Fatal("check balance token fee in smart contract: got", balanceIssuerFee, "wanted", remainFee)
98101
}
99102
//check trc21 SMC balance
100103
balance, err = contractBackend.BalanceAt(nil, trc21IssuerAddr, nil)

core/bench_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func genValueTx(nbytes int) func(int, *BlockGen) {
8585
return func(i int, gen *BlockGen) {
8686
toaddr := common.Address{}
8787
data := make([]byte, nbytes)
88-
gas, _ := IntrinsicGas(data, false, false)
88+
gas, _ := IntrinsicGas(data, nil, false, false)
8989
tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(benchRootAddr), toaddr, big.NewInt(1), gas, nil, data), types.HomesteadSigner{}, benchRootKey)
9090
gen.AddTx(tx)
9191
}

core/blockchain_test.go

Lines changed: 101 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ func TestFastVsFullChains(t *testing.T) {
561561
Alloc: GenesisAlloc{address: {Balance: funds}},
562562
}
563563
genesis = gspec.MustCommit(gendb)
564-
signer = types.NewEIP155Signer(gspec.Config.ChainId)
564+
signer = types.LatestSigner(gspec.Config)
565565
)
566566
blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, 1024, func(i int, block *BlockGen) {
567567
block.SetCoinbase(common.Address{0x00})
@@ -736,7 +736,7 @@ func TestChainTxReorgs(t *testing.T) {
736736
},
737737
}
738738
genesis = gspec.MustCommit(db)
739-
signer = types.NewEIP155Signer(gspec.Config.ChainId)
739+
signer = types.LatestSigner(gspec.Config)
740740
)
741741

742742
// Create two transactions shared between the chains:
@@ -842,7 +842,7 @@ func TestLogReorgs(t *testing.T) {
842842
code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
843843
gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
844844
genesis = gspec.MustCommit(db)
845-
signer = types.NewEIP155Signer(gspec.Config.ChainId)
845+
signer = types.LatestSigner(gspec.Config)
846846
)
847847

848848
blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
@@ -889,7 +889,7 @@ func TestLogReorgs(t *testing.T) {
889889
// Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}},
890890
// }
891891
// genesis = gspec.MustCommit(db)
892-
// signer = types.NewEIP155Signer(gspec.Config.ChainId)
892+
// signer = types.LatestSigner(gspec.Config)
893893
// )
894894
//
895895
// blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
@@ -1015,7 +1015,7 @@ func TestEIP155Transition(t *testing.T) {
10151015
funds = big.NewInt(1000000000)
10161016
deleteAddr = common.Address{1}
10171017
gspec = &Genesis{
1018-
Config: &params.ChainConfig{ChainId: big.NewInt(1), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
1018+
Config: &params.ChainConfig{ChainId: big.NewInt(1), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
10191019
Alloc: GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
10201020
}
10211021
genesis = gspec.MustCommit(db)
@@ -1046,7 +1046,7 @@ func TestEIP155Transition(t *testing.T) {
10461046
}
10471047
block.AddTx(tx)
10481048

1049-
tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainId))
1049+
tx, err = basicTx(types.LatestSigner(gspec.Config))
10501050
if err != nil {
10511051
t.Fatal(err)
10521052
}
@@ -1058,7 +1058,7 @@ func TestEIP155Transition(t *testing.T) {
10581058
}
10591059
block.AddTx(tx)
10601060

1061-
tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainId))
1061+
tx, err = basicTx(types.LatestSigner(gspec.Config))
10621062
if err != nil {
10631063
t.Fatal(err)
10641064
}
@@ -1086,7 +1086,7 @@ func TestEIP155Transition(t *testing.T) {
10861086
}
10871087

10881088
// generate an invalid chain id transaction
1089-
config := &params.ChainConfig{ChainId: big.NewInt(2), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
1089+
config := &params.ChainConfig{ChainId: big.NewInt(2), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
10901090
blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
10911091
var (
10921092
tx *types.Transaction
@@ -1095,9 +1095,8 @@ func TestEIP155Transition(t *testing.T) {
10951095
return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
10961096
}
10971097
)
1098-
switch i {
1099-
case 0:
1100-
tx, err = basicTx(types.NewEIP155Signer(big.NewInt(2)))
1098+
if i == 0 {
1099+
tx, err = basicTx(types.LatestSigner(config))
11011100
if err != nil {
11021101
t.Fatal(err)
11031102
}
@@ -1136,7 +1135,7 @@ func TestEIP161AccountRemoval(t *testing.T) {
11361135
var (
11371136
tx *types.Transaction
11381137
err error
1139-
signer = types.NewEIP155Signer(gspec.Config.ChainId)
1138+
signer = types.LatestSigner(gspec.Config)
11401139
)
11411140
switch i {
11421141
case 0:
@@ -1412,3 +1411,93 @@ func TestAreTwoBlocksSamePath(t *testing.T) {
14121411
})
14131412

14141413
}
1414+
1415+
// TestEIP2718Transition tests that an EIP-2718 transaction will be accepted
1416+
// after the fork block has passed. This is verified by sending an EIP-2930
1417+
// access list transaction, which specifies a single slot access, and then
1418+
// checking that the gas usage of a hot SLOAD and a cold SLOAD are calculated
1419+
// correctly.
1420+
func TestEIP2718Transition(t *testing.T) {
1421+
var (
1422+
aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
1423+
1424+
// Generate a canonical chain to act as the main dataset
1425+
engine = ethash.NewFaker()
1426+
db = rawdb.NewMemoryDatabase()
1427+
1428+
// A sender who makes transactions, has some funds
1429+
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
1430+
address = crypto.PubkeyToAddress(key.PublicKey)
1431+
funds = big.NewInt(1000000000)
1432+
gspec = &Genesis{
1433+
Config: &params.ChainConfig{
1434+
ChainId: new(big.Int).SetBytes([]byte("eip1559")),
1435+
HomesteadBlock: big.NewInt(0),
1436+
DAOForkBlock: nil,
1437+
DAOForkSupport: true,
1438+
EIP150Block: big.NewInt(0),
1439+
EIP155Block: big.NewInt(0),
1440+
EIP158Block: big.NewInt(0),
1441+
ByzantiumBlock: big.NewInt(0),
1442+
ConstantinopleBlock: big.NewInt(0),
1443+
PetersburgBlock: big.NewInt(0),
1444+
IstanbulBlock: big.NewInt(0),
1445+
Eip1559Block: big.NewInt(0),
1446+
},
1447+
Alloc: GenesisAlloc{
1448+
address: {Balance: funds},
1449+
// The address 0xAAAA sloads 0x00 and 0x01
1450+
aa: {
1451+
Code: []byte{
1452+
byte(vm.PC),
1453+
byte(vm.PC),
1454+
byte(vm.SLOAD),
1455+
byte(vm.SLOAD),
1456+
},
1457+
Nonce: 0,
1458+
Balance: big.NewInt(0),
1459+
},
1460+
},
1461+
}
1462+
genesis = gspec.MustCommit(db)
1463+
)
1464+
1465+
blocks, _ := GenerateChain(gspec.Config, genesis, engine, db, 1, func(i int, b *BlockGen) {
1466+
b.SetCoinbase(common.Address{1})
1467+
1468+
// One transaction to 0xAAAA
1469+
signer := types.LatestSigner(gspec.Config)
1470+
tx, _ := types.SignNewTx(key, signer, &types.AccessListTx{
1471+
ChainID: gspec.Config.ChainId,
1472+
Nonce: 0,
1473+
To: &aa,
1474+
Gas: 30000,
1475+
GasPrice: big.NewInt(1),
1476+
AccessList: types.AccessList{{
1477+
Address: aa,
1478+
StorageKeys: []common.Hash{{0}},
1479+
}},
1480+
})
1481+
b.AddTx(tx)
1482+
})
1483+
1484+
// Import the canonical chain
1485+
diskdb := rawdb.NewMemoryDatabase()
1486+
gspec.MustCommit(diskdb)
1487+
1488+
chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{})
1489+
if err != nil {
1490+
t.Fatalf("failed to create tester chain: %v", err)
1491+
}
1492+
if n, err := chain.InsertChain(blocks); err != nil {
1493+
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
1494+
}
1495+
1496+
block := chain.GetBlockByNumber(1)
1497+
1498+
// Expected gas is intrinsic + 2 * pc + hot load + cold load, since only one load is in the access list
1499+
expected := params.TxGas + params.TxAccessListAddressGas + params.TxAccessListStorageKeyGas + vm.GasQuickStep*2 + vm.WarmStorageReadCostEIP2929 + vm.ColdSloadCostEIP2929
1500+
if block.GasUsed() != expected {
1501+
t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expected, block.GasUsed())
1502+
}
1503+
}

0 commit comments

Comments
 (0)