From 9a9d640ce7719c23300e0f3399966deec6d7904f Mon Sep 17 00:00:00 2001 From: Dustin Xie Date: Wed, 8 Nov 2023 22:00:09 -0800 Subject: [PATCH 1/2] [action] support pre-EIP155 unprotected transaction --- action/rlp_tx.go | 72 +++- action/rlp_tx_test.go | 343 +++++++++++++++++- action/sealedenvelope.go | 6 +- action/sealedenvelope_test.go | 2 +- api/coreservice.go | 7 + api/web3server.go | 36 +- api/web3server_integrity_test.go | 2 +- api/web3server_marshal_test.go | 7 +- api/web3server_test.go | 3 + go.mod | 2 +- go.sum | 4 +- .../mock_apicoreservice.go | 15 + test/mock/mock_blocksync/mock_blocksync.go | 14 + 13 files changed, 489 insertions(+), 24 deletions(-) diff --git a/action/rlp_tx.go b/action/rlp_tx.go index 9d23b2617f..ef5bdca4a3 100644 --- a/action/rlp_tx.go +++ b/action/rlp_tx.go @@ -42,8 +42,6 @@ func RawTxToSignedTx(rawTx *types.Transaction, signer types.Signer, sig []byte) sc[64] -= 27 } - // TODO: currently all our web3 tx are EIP-155 protected tx - // in the future release, use proper signer for other supported tx types (EIP-1559, EIP-2930) signedTx, err := rawTx.WithSignature(signer, sc) if err != nil { return nil, err @@ -87,14 +85,80 @@ func DecodeRawTx(rawData string, chainID uint32) (tx *types.Transaction, sig []b // NewEthSigner returns the proper signer for Eth-compatible tx func NewEthSigner(txType iotextypes.Encoding, chainID uint32) (types.Signer, error) { - // TODO: use proper signer according to tx type switch txType { case iotextypes.Encoding_IOTEX_PROTOBUF: // native tx use same signature format as that of Homestead return types.HomesteadSigner{}, nil - case iotextypes.Encoding_ETHEREUM_RLP: + case iotextypes.Encoding_ETHEREUM_EIP155: return types.NewEIP155Signer(big.NewInt(int64(chainID))), nil + case iotextypes.Encoding_ETHEREUM_UNPROTECTED: + return types.HomesteadSigner{}, nil default: return nil, ErrInvalidAct } } + +// DecodeEtherTx decodes raw data string into eth tx +func DecodeEtherTx(rawData string) (*types.Transaction, error) { + //remove Hex prefix and decode string to byte + if strings.HasPrefix(rawData, "0x") || strings.HasPrefix(rawData, "0X") { + rawData = rawData[2:] + } + rawTxBytes, err := hex.DecodeString(rawData) + if err != nil { + return nil, err + } + + // decode raw data into eth tx + tx := types.Transaction{} + if err = tx.UnmarshalBinary(rawTxBytes); err != nil { + return nil, err + } + return &tx, nil +} + +// ExtractTypeSigPubkey extracts tx type, signature, and pubkey +func ExtractTypeSigPubkey(tx *types.Transaction) (iotextypes.Encoding, []byte, crypto.PublicKey, error) { + var ( + encoding iotextypes.Encoding + signer types.Signer + V, R, S = tx.RawSignatureValues() + ) + // extract correct V value + switch tx.Type() { + case types.LegacyTxType: + if tx.Protected() { + chainIDMul := tx.ChainId() + V = new(big.Int).Sub(V, chainIDMul.Lsh(chainIDMul, 1)) + V.Sub(V, big.NewInt(8)) + encoding = iotextypes.Encoding_ETHEREUM_EIP155 + signer = types.NewEIP155Signer(tx.ChainId()) + } else { + // tx has pre-EIP155 signature + encoding = iotextypes.Encoding_ETHEREUM_UNPROTECTED + signer = types.HomesteadSigner{} + } + default: + return encoding, nil, nil, ErrNotSupported + } + + // construct signature + if V.BitLen() > 8 { + return encoding, nil, nil, ErrNotSupported + } + + var ( + r, s = R.Bytes(), S.Bytes() + sig = make([]byte, 65) + pubkey crypto.PublicKey + err error + ) + copy(sig[32-len(r):32], r) + copy(sig[64-len(s):64], s) + sig[64] = byte(V.Uint64()) + + // recover public key + rawHash := signer.Hash(tx) + pubkey, err = crypto.RecoverPubkey(rawHash[:], sig) + return encoding, sig, pubkey, err +} diff --git a/action/rlp_tx_test.go b/action/rlp_tx_test.go index 62304643d5..de81672c4b 100644 --- a/action/rlp_tx_test.go +++ b/action/rlp_tx_test.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/iotexproject/go-pkgs/crypto" "github.com/iotexproject/go-pkgs/hash" "github.com/iotexproject/iotex-address/address" "github.com/iotexproject/iotex-proto/golang/iotextypes" @@ -78,7 +79,7 @@ func TestGenerateRlp(t *testing.T) { require.Contains(err.Error(), v.err) continue } - signer, err := NewEthSigner(iotextypes.Encoding_ETHEREUM_RLP, _evmNetworkID) + signer, err := NewEthSigner(iotextypes.Encoding_ETHEREUM_EIP155, _evmNetworkID) require.NoError(err) h, err := rlpSignedHash(tx, signer, v.sig) if err != nil { @@ -293,12 +294,15 @@ func TestRlpDecodeVerify(t *testing.T) { // decode received RLP tx tx, sig, pubkey, err := DecodeRawTx(v.raw, _evmNetworkID) require.NoError(err) + require.EqualValues(types.LegacyTxType, tx.Type()) + require.True(tx.Protected()) + require.EqualValues(_evmNetworkID, tx.ChainId().Uint64()) require.Equal(v.pubkey, pubkey.HexString()) require.Equal(v.pkhash, hex.EncodeToString(pubkey.Hash())) // convert to our Execution pb := &iotextypes.Action{ - Encoding: iotextypes.Encoding_ETHEREUM_RLP, + Encoding: iotextypes.Encoding_ETHEREUM_EIP155, } pb.Core = convertToNativeProto(tx, v.actType) pb.SenderPubKey = pubkey.Bytes() @@ -344,6 +348,323 @@ func TestRlpDecodeVerify(t *testing.T) { } } +func TestEthTxDecodeVerify(t *testing.T) { + require := require.New(t) + + rlpTests := []struct { + actType string + raw string + nonce uint64 + limit uint64 + price string + amount string + to string + chainID uint32 + encoding iotextypes.Encoding + dataLen int + hash string + pubkey string + pkhash string + }{ + { + "transfer", + "f86e8085e8d4a51000825208943141df3f2e4415533bb6d6be2a351b2db9ee84ef88016345785d8a0000808224c6a0204d25fc0d7d8b3fdf162c6ee820f888f5533b1c382d79d5cbc8ec1d9091a9a8a016f1a58d7e0d0fd24be800f64a2d6433c5fcb31e3fc7562b7fbe62bc382a95bb", + 0, + 21000, + "1000000000000", + "100000000000000000", + "0x3141df3f2e4415533bb6d6be2A351B2db9ee84EF", + _evmNetworkID, + iotextypes.Encoding_ETHEREUM_EIP155, + 0, + "eead45fe6b510db9ed6dce9187280791c04bbaadd90c54a7f4b1f75ced382ff1", + "041ba784140be115e8fa8698933e9318558a895c75c7943100f0677e4d84ff2763ff68720a0d22c12d093a2d692d1e8292c3b7672fccf3b3db46a6e0bdad93be17", + "87eea07540789af85b64947aea21a3f00400b597", + }, + { + "execution", + "f8ab0d85e8d4a5100082520894ac7ac39de679b19aae042c0ce19facb86e0a411780b844a9059cbb0000000000000000000000003141df3f2e4415533bb6d6be2a351b2db9ee84ef000000000000000000000000000000000000000000000000000000003b9aca008224c5a0fac4e25db03c99fec618b74a962d322a334234696eb62c7e5b9889132ff4f4d7a02c88e451572ca36b6f690ce23ff9d6695dd71e888521fa706a8fc8c279099a61", + 13, + 21000, + "1000000000000", + "0", + "0xAC7AC39De679b19AaE042c0cE19fAcB86e0A4117", + _evmNetworkID, + iotextypes.Encoding_ETHEREUM_EIP155, + 68, + "7467dd6ccd4f3d7b6dc0002b26a45ad0b75a1793da4e3557cf6ff2582cbe25c9", + "041ba784140be115e8fa8698933e9318558a895c75c7943100f0677e4d84ff2763ff68720a0d22c12d093a2d692d1e8292c3b7672fccf3b3db46a6e0bdad93be17", + "87eea07540789af85b64947aea21a3f00400b597", + }, + { + "execution", + "f9024f2e830f42408381b3208080b901fc608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061019c806100606000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063445df0ac146100465780638da5cb5b14610064578063fdacd576146100ae575b600080fd5b61004e6100dc565b6040518082815260200191505060405180910390f35b61006c6100e2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100da600480360360208110156100c457600080fd5b8101908080359060200190929190505050610107565b005b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561016457806001819055505b5056fea265627a7a72315820e54fe55a78b9d8bec22b4d3e6b94b7e59799daee3940423eb1aa30fe643eeb9a64736f6c634300051000328224c5a0439310c2d5509fc42486171b910cf8107542c86e23202a3a8ba43129cabcdbfea038966d36b41916f619c64bdc8c3ddcb021b35ea95d44875eb8201e9422fd98f0", + 46, + 8500000, + "1000000", + "0", + EmptyAddress, + _evmNetworkID, + iotextypes.Encoding_ETHEREUM_EIP155, + 508, + "b676128dae841742e3ab6e518acb30badc6b26230fe870821d1de08c85823067", + "049c6567f527f8fc98c0875d3d80097fcb4d5b7bfe037fc9dd5dbeaf563d58d7ff17a4f2b85df9734ecdb276622738e28f0b7cf224909ab7b128c5ca748729b0d2", + "1904bfcb93edc9bf961eead2e5c0de81dcc1d37d", + }, + { + "stakeCreate", + "f901670980828ca09404c22afae6a03438b8fed74cb1cf441168df3f1280b90104a3d374c400000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000004746573740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008224c6a02d359322fb1eb0ef44008b587d28160fb237ae716da2735aef9ce2702af52151a03518f334c585c31cec1d9c0ec81fd4c4f70d3ab661502a5aeb1f6eb07bc01854", + 9, + 36000, + "0", + "0", + "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", + _evmNetworkID, + iotextypes.Encoding_ETHEREUM_EIP155, + 260, + "f59e5f9ba10ec50fdd1ebb41c75c6d54cfc634428620930b6ba6300847127241", + "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", + "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", + }, + { + "stakeAddDeposit", + "f8e60980825aa09404c22afae6a03438b8fed74cb1cf441168df3f1280b88434e8e14500000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000008224c6a0b4af40981b992eab4f15afe1bab1d4c498069cae8fa4ea3e0800d732f282fadea073de47b280905d5ccd4fc329e9c1f10b0bdefe1f4a3f4f8b00918680428ae7dd", + 9, + 23200, + "0", + "0", + "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", + _evmNetworkID, + iotextypes.Encoding_ETHEREUM_EIP155, + 132, + "8823b599b46cd907c4691aa71b5668b835be76a8358fa9beb866610e27598592", + "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", + "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", + }, + { + "changeCandidate", + "f9012609808273a09404c22afae6a03438b8fed74cb1cf441168df3f1280b8c4fb3d51380000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000004746573740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008224c6a06087932dec4df781917c12d31feb80c8e61b2317e3a0820401f3c095746a765da0549df65b7d94fdec196bc70e6dda056fec873664c064036e55fd3bc7e766a595", + 9, + 29600, + "0", + "0", + "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", + _evmNetworkID, + iotextypes.Encoding_ETHEREUM_EIP155, + 196, + "23f29aebf4b193b02dd78866d56ea7a7b1cdbf27604d34868bb82993c216b4ec", + "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", + "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", + }, + { + "unstake", + "f8c609808252089404c22afae6a03438b8fed74cb1cf441168df3f1280b8642bde151d0000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008224c6a0bd261cf9c6a2412272c660742a902965611d838176b2ad22b39219dadeedb312a02beef231cc90e4fbd6b928b28aea6ca1ccaf4f793f9d05bc0186e0e09b920a0a", + 9, + 21000, + "0", + "0", + "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", + _evmNetworkID, + iotextypes.Encoding_ETHEREUM_EIP155, + 100, + "0c8560b135d325573e6aad484d71e2887835acce7fd4a78eddcb24efe6071516", + "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", + "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", + }, + { + "withdrawStake", + "f8c609808252089404c22afae6a03438b8fed74cb1cf441168df3f1280b864d179ffb50000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008224c5a0526ec8247ce5ae1c8542776cf28a85c7bc2f17e1abc3de5cfbfd20fd85aeeca3a07a6db0a7ae08b6b6aeeae4a1446dcc6f090589e7835d63ebc0a1db783c5e2c89", + 9, + 21000, + "0", + "0", + "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", + _evmNetworkID, + iotextypes.Encoding_ETHEREUM_EIP155, + 100, + "49cc2e14f3d1c03d7e36686d962995ea0f30f65f948d5a59181a5504bc58c102", + "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", + "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", + }, + { + "restake", + "f9010609808267209404c22afae6a03438b8fed74cb1cf441168df3f1280b8a44c4fee4b000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000008224c5a0078638f1f00ab532522558e2e4f394f13bfe134a8687ac4639ebead60f63e0dba019dc91f08c1f422de44aa7e6b25ada0632f29bc22242900b3a60f7f371301f02", + 9, + 26400, + "0", + "0", + "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", + _evmNetworkID, + iotextypes.Encoding_ETHEREUM_EIP155, + 164, + "c3d30b0fccf9d59ece79419d329e50082a8b6d86dee1b9f424f8852e154713d1", + "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", + "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", + }, + { + "transferStake", + "f8e60980825aa09404c22afae6a03438b8fed74cb1cf441168df3f1280b8849cb560bb0000000000000000000000003041a575c7a70021e3082929798c8c3fdaa9d8240000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000008224c5a07fd84321b04de059cbfdf12dcd383d3e554c569705f32035bc435b8d996c8bdba00df629ef4d9135d73bb60d49815761bc0a6ee7eb66770106dc9e809cd105d570", + 9, + 23200, + "0", + "0", + "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", + _evmNetworkID, + iotextypes.Encoding_ETHEREUM_EIP155, + 132, + "a60b2546839e889a0ef89be4f224fb70dab3e4ddb6f65391ff708b01116593c1", + "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", + "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", + }, + { + "candidateRegister", + "f901c709808252089404c22afae6a03438b8fed74cb1cf441168df3f1280b90164bee5f7b700000000000000000000000000000000000000000000000000000000000001000000000000000000000000003041a575c7a70021e3082929798c8c3fdaa9d8240000000000000000000000003041a575c7a70021e3082929798c8c3fdaa9d8240000000000000000000000003041a575c7a70021e3082929798c8c3fdaa9d82400000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000004746573740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008224c5a07b4fd9921e47c13bb52fc5e0df47f4dc0bffcf6e7877e13c7e559b4a7d3b9825a0073a3a029822aa43506834bef8b1ed30d6bb436d758d7cf583deb48a4efefd6a", + 9, + 21000, + "0", + "0", + "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", + _evmNetworkID, + iotextypes.Encoding_ETHEREUM_EIP155, + 356, + "9aa470cbdc3b3fd8f51aae4770d6a58cf4016be18201f0efbae6d83d0b2aa096", + "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", + "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", + }, + { + "candidateUpdate", + "f9010609808252089404c22afae6a03438b8fed74cb1cf441168df3f1280b8a4435f9f2200000000000000000000000000000000000000000000000000000000000000600000000000000000000000003041a575c7a70021e3082929798c8c3fdaa9d8240000000000000000000000003041a575c7a70021e3082929798c8c3fdaa9d824000000000000000000000000000000000000000000000000000000000000000474657374000000000000000000000000000000000000000000000000000000008224c6a04df6545da871debef84476198e76167d4dfe6fb83098a5a49dbab734352f20f1a0220686494f8b09751bbeb5c63729e7ecc5c504f952c67e926461db98588854b6", + 9, + 21000, + "0", + "0", + "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", + _evmNetworkID, + iotextypes.Encoding_ETHEREUM_EIP155, + 164, + "7a8d96d35c939bf1634d587b1f471c0f3f96ba750d64d43289c9eef267718ef0", + "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", + "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", + }, + { + "rewardingClaim", + "f8c6806482520894a576c141e5659137ddda4223d209d4744b2106be80b8642df163ef0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008224c6a03d62943431b8ca0e8ea0a9c79dc8f64df14c965ca5486da124804013778ed566a065956b185116b65cec0ec9bcf9539e924784a4b448190b0aa9d017f1719be921", + 0, + 21000, + "100", + "0", + "0xA576C141e5659137ddDa4223d209d4744b2106BE", + _evmNetworkID, + iotextypes.Encoding_ETHEREUM_EIP155, + 100, + "4d26d0736ebd9e69bd5994f3730b05a2d48c810b3bb54818be65d02004cf4ff4", + "04830579b50e01602c2015c24e72fbc48bca1cca1e601b119ca73abe2e0b5bd61fcb7874567e091030d6b644f927445d80e00b3f9ca0c566c21c30615e94c343da", + "8d38efe45794d7fceea10b2262c23c12245959db", + }, + { + "rewardingDeposit", + "f8c6016482520894a576c141e5659137ddda4223d209d4744b2106be80b86427852a6b0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008224c6a013b7679dbabcb0f97b93942436f5072cca3c7fe43451a8fedcdf3c84c1344e1da02af4cc67594c0200b59f4e30ba149af15e546acbfc69fa31f14e8788ab063d85", + 1, + 21000, + "100", + "0", + "0xA576C141e5659137ddDa4223d209d4744b2106BE", + _evmNetworkID, + iotextypes.Encoding_ETHEREUM_EIP155, + 100, + "842fea9a292c0bc7a1e05a14a8255ed8dc945fdae7c01a6b70f5213ebe35583b", + "04830579b50e01602c2015c24e72fbc48bca1cca1e601b119ca73abe2e0b5bd61fcb7874567e091030d6b644f927445d80e00b3f9ca0c566c21c30615e94c343da", + "8d38efe45794d7fceea10b2262c23c12245959db", + }, + { + "unprotected", + "0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222", + 0, + 100000, + "100000000000", + "0", + EmptyAddress, + 0, + iotextypes.Encoding_ETHEREUM_UNPROTECTED, + 83, + "eddf9e61fb9d8f5111840daef55e5fde0041f5702856532cdbb5a02998033d26", // https://etherscan.io/tx/0xeddf9e61fb9d8f5111840daef55e5fde0041f5702856532cdbb5a02998033d26 + "040a98b1acb38ed9cd8d0e8f1f03b1588bae140586f8a8049197b65013a3c17690151ae422e3fdfb26be2e6a4465b1f9cf5c26a5635109929a0d0a11734124d50a", + "3fab184622dc19b6109349b94811493bf2a45362", + }, + } + + for _, v := range rlpTests { + // decode received RLP tx + tx, err := DecodeEtherTx(v.raw) + require.NoError(err) + encoding, sig, pubkey, err := ExtractTypeSigPubkey(tx) + require.Equal(v.encoding, encoding) + V, _, _ := tx.RawSignatureValues() + recID := V.Uint64() + if encoding == iotextypes.Encoding_ETHEREUM_EIP155 { + require.EqualValues(types.LegacyTxType, tx.Type()) + require.True(tx.Protected()) + require.Less(uint64(28), recID) + } else if encoding == iotextypes.Encoding_ETHEREUM_UNPROTECTED { + require.EqualValues(types.LegacyTxType, tx.Type()) + require.False(tx.Protected()) + require.Zero(tx.ChainId().Uint64()) + // unprotected tx has V = 27, 28 + require.True(27 == recID || 28 == recID) + require.True(27 == sig[64] || 28 == sig[64]) + } + require.EqualValues(v.chainID, tx.ChainId().Uint64()) + require.Equal(v.pubkey, pubkey.HexString()) + require.Equal(v.pkhash, hex.EncodeToString(pubkey.Hash())) + + // convert to our Execution + pb := &iotextypes.Action{ + Encoding: encoding, + } + pb.Core = convertToNativeProto(tx, v.actType) + pb.SenderPubKey = pubkey.Bytes() + pb.Signature = sig + + // send on wire + bs, err := proto.Marshal(pb) + require.NoError(err) + + // receive from API + proto.Unmarshal(bs, pb) + selp := SealedEnvelope{} + require.NoError(selp.loadProto(pb, uint32(tx.ChainId().Uint64()))) + act, ok := selp.Action().(EthCompatibleAction) + require.True(ok) + rlpTx, err := act.ToEthTx() + require.NoError(err) + + // verify against original tx + require.Equal(v.nonce, rlpTx.Nonce()) + require.Equal(v.price, rlpTx.GasPrice().String()) + require.Equal(v.limit, rlpTx.Gas()) + if v.to == "" { + require.Nil(rlpTx.To()) + } else { + require.Equal(v.to, rlpTx.To().Hex()) + } + require.Equal(v.amount, rlpTx.Value().String()) + require.Equal(v.dataLen, len(rlpTx.Data())) + h, err := selp.Hash() + require.NoError(err) + require.Equal(v.hash, hex.EncodeToString(h[:])) + require.Equal(pubkey, selp.SrcPubkey()) + require.True(bytes.Equal(sig, selp.signature)) + raw, err := selp.envelopeHash() + require.NoError(err) + signer, err := NewEthSigner(encoding, uint32(tx.ChainId().Uint64())) + require.NoError(err) + rawHash := signer.Hash(tx) + require.True(bytes.Equal(rawHash[:], raw[:])) + require.NotEqual(raw, h) + require.NoError(selp.VerifySignature()) + } +} + func convertToNativeProto(tx *types.Transaction, actType string) *iotextypes.ActionCore { elpBuilder := &EnvelopeBuilder{} elpBuilder.SetGasLimit(tx.Gas()).SetGasPrice(tx.GasPrice()).SetNonce(tx.Nonce()) @@ -351,7 +672,7 @@ func convertToNativeProto(tx *types.Transaction, actType string) *iotextypes.Act case "transfer": elp, _ := elpBuilder.BuildTransfer(tx) return elp.Proto() - case "execution": + case "execution", "unprotected": elp, _ := elpBuilder.BuildExecution(tx) return elp.Proto() case "stakeCreate", "stakeAddDeposit", "changeCandidate", "unstake", "withdrawStake", "restake", @@ -393,19 +714,33 @@ func TestIssue3944(t *testing.T) { S: new(big.Int).SetBytes(sig[32:64]), }) + r.EqualValues(types.LegacyTxType, tx.Type()) + r.False(tx.Protected()) v, q, s := tx.RawSignatureValues() r.Equal(sig[:32], q.Bytes()) r.Equal(sig[32:64], s.Bytes()) r.Equal("1b", v.Text(16)) r.NotEqual(hash, tx.Hash().Hex()) // hash does not match with wrong V value in signature - signer, err := NewEthSigner(iotextypes.Encoding_ETHEREUM_RLP, 4690) + signer, err := NewEthSigner(iotextypes.Encoding_ETHEREUM_EIP155, 4690) r.NoError(err) tx1, err := RawTxToSignedTx(tx, signer, sig) r.NoError(err) + r.True(tx1.Protected()) + r.EqualValues(4690, tx1.ChainId().Uint64()) v, q, s = tx1.RawSignatureValues() r.Equal(sig[:32], q.Bytes()) r.Equal(sig[32:64], s.Bytes()) r.Equal("9415", v.String()) // this is the correct V value corresponding to chainID = 4690 r.Equal(hash, tx1.Hash().Hex()) } + +func TestBackwardComp(t *testing.T) { + r := require.New(t) + // example unprotected tx at https://etherscan.io/tx/0xeddf9e61fb9d8f5111840daef55e5fde0041f5702856532cdbb5a02998033d26 + unprotectedTx := "0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222" + for _, chainID := range []uint32{_evmNetworkID, _evmNetworkID + 1, 0} { + _, _, _, err := DecodeRawTx(unprotectedTx, chainID) + r.Equal(crypto.ErrInvalidKey, err) + } +} diff --git a/action/sealedenvelope.go b/action/sealedenvelope.go index 396a0eff76..56cce003b7 100644 --- a/action/sealedenvelope.go +++ b/action/sealedenvelope.go @@ -30,7 +30,7 @@ type SealedEnvelope struct { // an all-0 return value means the transaction is invalid func (sealed *SealedEnvelope) envelopeHash() (hash.Hash256, error) { switch sealed.encoding { - case iotextypes.Encoding_ETHEREUM_RLP: + case iotextypes.Encoding_ETHEREUM_EIP155, iotextypes.Encoding_ETHEREUM_UNPROTECTED: act, ok := sealed.Action().(EthCompatibleAction) if !ok { return hash.ZeroHash256, ErrInvalidAct @@ -66,7 +66,7 @@ func (sealed *SealedEnvelope) Hash() (hash.Hash256, error) { func (sealed *SealedEnvelope) calcHash() (hash.Hash256, error) { switch sealed.encoding { - case iotextypes.Encoding_ETHEREUM_RLP: + case iotextypes.Encoding_ETHEREUM_EIP155, iotextypes.Encoding_ETHEREUM_UNPROTECTED: act, ok := sealed.Action().(EthCompatibleAction) if !ok { return hash.ZeroHash256, ErrInvalidAct @@ -144,7 +144,7 @@ func (sealed *SealedEnvelope) loadProto(pbAct *iotextypes.Action, evmID uint32) } encoding := pbAct.GetEncoding() switch encoding { - case iotextypes.Encoding_ETHEREUM_RLP: + case iotextypes.Encoding_ETHEREUM_EIP155, iotextypes.Encoding_ETHEREUM_UNPROTECTED: // verify action type can support RLP-encoding act, ok := elp.Action().(EthCompatibleAction) if !ok { diff --git a/action/sealedenvelope_test.go b/action/sealedenvelope_test.go index ec95509bfc..c1b5402583 100644 --- a/action/sealedenvelope_test.go +++ b/action/sealedenvelope_test.go @@ -62,7 +62,7 @@ func TestSealedEnvelope_InvalidType(t *testing.T) { SetAction(r). SetGasLimit(100000).Build() selp := FakeSeal(elp, identityset.PrivateKey(27).PublicKey()) - selp.encoding = iotextypes.Encoding_ETHEREUM_RLP + selp.encoding = iotextypes.Encoding_ETHEREUM_EIP155 hash1, err := selp.envelopeHash() require.Equal(hash1, hash.ZeroHash256) require.Contains(err.Error(), "invalid action type") diff --git a/api/coreservice.go b/api/coreservice.go index 36d1ce6668..2a5cb68ea1 100644 --- a/api/coreservice.go +++ b/api/coreservice.go @@ -125,6 +125,8 @@ type ( LogsInBlockByHash(filter *logfilter.LogFilter, blockHash hash.Hash256) ([]*action.Log, error) // LogsInRange filter logs among [start, end] blocks LogsInRange(filter *logfilter.LogFilter, start, end, paginationSize uint64) ([]*action.Log, []hash.Hash256, error) + // Genesis returns the genesis of the chain + Genesis() genesis.Genesis // EVMNetworkID returns the network id of evm EVMNetworkID() uint32 // ChainID returns the chain id of evm @@ -1589,6 +1591,11 @@ func (core *coreService) ActionsInActPool(actHashes []string) ([]action.SealedEn return ret, nil } +// Genesis returns the genesis of the chain +func (core *coreService) Genesis() genesis.Genesis { + return core.bc.Genesis() +} + // EVMNetworkID returns the network id of evm func (core *coreService) EVMNetworkID() uint32 { return core.bc.EvmNetworkID() diff --git a/api/web3server.go b/api/web3server.go index 44c6b7f3b0..ee25da35f7 100644 --- a/api/web3server.go +++ b/api/web3server.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/tracers/logger" + "github.com/iotexproject/go-pkgs/crypto" "github.com/iotexproject/go-pkgs/hash" "github.com/iotexproject/go-pkgs/util" "github.com/iotexproject/iotex-address/address" @@ -73,6 +74,7 @@ var ( errInvalidFormat = errors.New("invalid format of request") errNotImplemented = errors.New("method not implemented") errInvalidFilterID = errors.New("filter not found") + errInvalidEvmChainID = errors.New("invalid EVM chain ID") errInvalidBlock = errors.New("invalid block") errUnsupportedAction = errors.New("the type of action is not supported") errMsgBatchTooLarge = errors.New("batch too large") @@ -433,9 +435,33 @@ func (svr *web3Handler) sendRawTransaction(in *gjson.Result) (interface{}, error return nil, errInvalidFormat } // parse raw data string from json request - tx, sig, pubkey, err := action.DecodeRawTx(dataStr.String(), svr.coreService.EVMNetworkID()) - if err != nil { - return nil, err + var ( + cs = svr.coreService + tx *types.Transaction + encoding iotextypes.Encoding + sig []byte + pubkey crypto.PublicKey + err error + ) + if g := cs.Genesis(); g.IsSumatra(cs.TipHeight()) { + tx, err = action.DecodeEtherTx(dataStr.String()) + if err != nil { + return nil, err + } + if tx.Protected() && tx.ChainId().Uint64() != uint64(cs.EVMNetworkID()) { + return nil, errors.Wrapf(errInvalidEvmChainID, "expect chainID = %d, got %d", cs.EVMNetworkID(), tx.ChainId().Uint64()) + } + encoding, sig, pubkey, err = action.ExtractTypeSigPubkey(tx) + if err != nil { + return nil, err + } + } else { + tx, sig, pubkey, err = action.DecodeRawTx(dataStr.String(), cs.EVMNetworkID()) + if err != nil { + return nil, err + } + // before Sumatra height, all tx are EIP-155 format + encoding = iotextypes.Encoding_ETHEREUM_EIP155 } elp, err := svr.ethTxToEnvelope(tx) if err != nil { @@ -445,9 +471,9 @@ func (svr *web3Handler) sendRawTransaction(in *gjson.Result) (interface{}, error Core: elp.Proto(), SenderPubKey: pubkey.Bytes(), Signature: sig, - Encoding: iotextypes.Encoding_ETHEREUM_RLP, + Encoding: encoding, } - actionHash, err := svr.coreService.SendAction(context.Background(), req) + actionHash, err := cs.SendAction(context.Background(), req) if err != nil { return nil, err } diff --git a/api/web3server_integrity_test.go b/api/web3server_integrity_test.go index ba93323640..70f6eea7d7 100644 --- a/api/web3server_integrity_test.go +++ b/api/web3server_integrity_test.go @@ -694,7 +694,7 @@ func web3Staking(t *testing.T, handler *hTTPHandler) { big.NewInt(0), test.data, ) - signer, err := action.NewEthSigner(iotextypes.Encoding_ETHEREUM_RLP, _evmNetworkID) + signer, err := action.NewEthSigner(iotextypes.Encoding_ETHEREUM_EIP155, _evmNetworkID) require.NoError(err) tx, err := types.SignTx(rawTx, signer, ecdsaPvk) require.NoError(err) diff --git a/api/web3server_marshal_test.go b/api/web3server_marshal_test.go index 618058c61d..8a0281c89c 100644 --- a/api/web3server_marshal_test.go +++ b/api/web3server_marshal_test.go @@ -156,7 +156,7 @@ func TestBlockObjectMarshal(t *testing.T) { t.Run("BlockWithDetail", func(t *testing.T) { raw := types.NewContractCreation(2, unit.ConvertIotxToRau(1000), 21000, unit.ConvertIotxToRau(1), []byte{}) - signer, err := action.NewEthSigner(iotextypes.Encoding_ETHEREUM_RLP, 0) + signer, err := action.NewEthSigner(iotextypes.Encoding_ETHEREUM_EIP155, 0) require.NoError(err) ethTx, err := action.RawTxToSignedTx(raw, signer, sevlp.Signature()) require.NoError(err) @@ -233,9 +233,10 @@ func TestTransactionObjectMarshal(t *testing.T) { t.Run("ContractCreation", func(t *testing.T) { raw := types.NewContractCreation(1, big.NewInt(10), 21000, big.NewInt(0), []byte{}) sig, _ := hex.DecodeString("363964383961306166323764636161363766316236326133383335393464393735393961616464326237623136346362343131326161386464666434326638391b") - signer, err := action.NewEthSigner(iotextypes.Encoding_ETHEREUM_RLP, 4690) + signer, err := action.NewEthSigner(iotextypes.Encoding_ETHEREUM_EIP155, 4690) require.NoError(err) tx, err := action.RawTxToSignedTx(raw, signer, sig) + require.NoError(err) res, err := json.Marshal(&getTransactionResult{ blockHash: _testBlkHash, to: nil, @@ -271,7 +272,7 @@ func TestTransactionObjectMarshal(t *testing.T) { pubkey, _ := crypto.HexStringToPublicKey("04806b217cb0b6a675974689fd99549e525d967287eee9a62dc4e598eea981b8158acfe026da7bf58397108abd0607672832c28ef3bc7b5855077f6e67ab5fc096") actHash, _ := hash.HexStringToHash256("cbc2560d986d79a46bfd96a08d18c6045b29f97352c1360289e371d9cffd6b6a") raw := types.NewContractCreation(305, big.NewInt(0), 297131, big.NewInt(1000000000000), data) - signer, err := action.NewEthSigner(iotextypes.Encoding_ETHEREUM_RLP, 0) + signer, err := action.NewEthSigner(iotextypes.Encoding_ETHEREUM_EIP155, 0) require.NoError(err) tx, err := action.RawTxToSignedTx(raw, signer, sig) require.NoError(err) diff --git a/api/web3server_test.go b/api/web3server_test.go index 4a6524635a..2f987a600f 100644 --- a/api/web3server_test.go +++ b/api/web3server_test.go @@ -29,6 +29,7 @@ import ( "github.com/iotexproject/iotex-core/action" apitypes "github.com/iotexproject/iotex-core/api/types" "github.com/iotexproject/iotex-core/blockchain/block" + "github.com/iotexproject/iotex-core/blockchain/genesis" "github.com/iotexproject/iotex-core/test/identityset" "github.com/iotexproject/iotex-core/test/mock/mock_apicoreservice" mock_apitypes "github.com/iotexproject/iotex-core/test/mock/mock_apiresponder" @@ -383,6 +384,8 @@ func TestSendRawTransaction(t *testing.T) { defer ctrl.Finish() core := mock_apicoreservice.NewMockCoreService(ctrl) web3svr := &web3Handler{core, nil, _defaultBatchRequestLimit} + core.EXPECT().Genesis().Return(genesis.Default) + core.EXPECT().TipHeight().Return(uint64(0)) core.EXPECT().EVMNetworkID().Return(uint32(1)) core.EXPECT().ChainID().Return(uint32(1)) core.EXPECT().Account(gomock.Any()).Return(&iotextypes.AccountMeta{IsContract: true}, nil, nil) diff --git a/go.mod b/go.mod index 6b8849d3df..356c829b21 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/iotexproject/iotex-address v0.2.8 github.com/iotexproject/iotex-antenna-go/v2 v2.5.1 github.com/iotexproject/iotex-election v0.3.5-0.20210611041425-20ddf674363d - github.com/iotexproject/iotex-proto v0.5.14 + github.com/iotexproject/iotex-proto v0.5.15-0.20231108184801-bc89358f2344 github.com/libp2p/go-libp2p-core v0.8.5 github.com/mackerelio/go-osstat v0.2.4 github.com/miguelmota/go-ethereum-hdwallet v0.1.1 diff --git a/go.sum b/go.sum index 04f3c46c55..45dc06ddad 100644 --- a/go.sum +++ b/go.sum @@ -511,8 +511,8 @@ github.com/iotexproject/iotex-antenna-go/v2 v2.5.1/go.mod h1:8pDZcM45M0gY6jm3PoM github.com/iotexproject/iotex-election v0.3.5-0.20210611041425-20ddf674363d h1:/j1xCAC9YiG/8UKqYvycS/v3ddVsb1G7AMyLXOjeYI0= github.com/iotexproject/iotex-election v0.3.5-0.20210611041425-20ddf674363d/go.mod h1:GRWevxtqQ4gPMrd7Qxhr29/7aTgvjiTp+rFI9KMMZEo= github.com/iotexproject/iotex-proto v0.5.0/go.mod h1:Xg6REkv+nTZN+OC22xXIQuqKdTWWHwOAJEXCoMpDwtI= -github.com/iotexproject/iotex-proto v0.5.14 h1:03UuHO5M1Dr6mjPk+72zoJfY2OEm93k9Z0oggHuzA6s= -github.com/iotexproject/iotex-proto v0.5.14/go.mod h1:wQpCk3Df0fPID+K8ohiICGj+cWRmcQ3wanT+aSrnIPo= +github.com/iotexproject/iotex-proto v0.5.15-0.20231108184801-bc89358f2344 h1:Io64R5K/xpDIvvRXVzRq8Z1QQr/C+MN9780Jj2aj6u8= +github.com/iotexproject/iotex-proto v0.5.15-0.20231108184801-bc89358f2344/go.mod h1:wQpCk3Df0fPID+K8ohiICGj+cWRmcQ3wanT+aSrnIPo= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= diff --git a/test/mock/mock_apicoreservice/mock_apicoreservice.go b/test/mock/mock_apicoreservice/mock_apicoreservice.go index bcec385938..7d2dc60beb 100644 --- a/test/mock/mock_apicoreservice/mock_apicoreservice.go +++ b/test/mock/mock_apicoreservice/mock_apicoreservice.go @@ -18,6 +18,7 @@ import ( logfilter "github.com/iotexproject/iotex-core/api/logfilter" apitypes "github.com/iotexproject/iotex-core/api/types" block "github.com/iotexproject/iotex-core/blockchain/block" + genesis "github.com/iotexproject/iotex-core/blockchain/genesis" iotexapi "github.com/iotexproject/iotex-proto/golang/iotexapi" iotextypes "github.com/iotexproject/iotex-proto/golang/iotextypes" ) @@ -334,6 +335,20 @@ func (mr *MockCoreServiceMockRecorder) EstimateGasForNonExecution(arg0 interface return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimateGasForNonExecution", reflect.TypeOf((*MockCoreService)(nil).EstimateGasForNonExecution), arg0) } +// Genesis mocks base method. +func (m *MockCoreService) Genesis() genesis.Genesis { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Genesis") + ret0, _ := ret[0].(genesis.Genesis) + return ret0 +} + +// Genesis indicates an expected call of Genesis. +func (mr *MockCoreServiceMockRecorder) Genesis() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Genesis", reflect.TypeOf((*MockCoreService)(nil).Genesis)) +} + // LogsInBlockByHash mocks base method. func (m *MockCoreService) LogsInBlockByHash(filter *logfilter.LogFilter, blockHash hash.Hash256) ([]*action.Log, error) { m.ctrl.T.Helper() diff --git a/test/mock/mock_blocksync/mock_blocksync.go b/test/mock/mock_blocksync/mock_blocksync.go index 220368100e..4099894d66 100644 --- a/test/mock/mock_blocksync/mock_blocksync.go +++ b/test/mock/mock_blocksync/mock_blocksync.go @@ -36,6 +36,20 @@ func (m *MockBlockSync) EXPECT() *MockBlockSyncMockRecorder { return m.recorder } +// BuildReport mocks base method. +func (m *MockBlockSync) BuildReport() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BuildReport") + ret0, _ := ret[0].(string) + return ret0 +} + +// BuildReport indicates an expected call of BuildReport. +func (mr *MockBlockSyncMockRecorder) BuildReport() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildReport", reflect.TypeOf((*MockBlockSync)(nil).BuildReport)) +} + // ProcessBlock mocks base method. func (m *MockBlockSync) ProcessBlock(arg0 context.Context, arg1 string, arg2 *block.Block) error { m.ctrl.T.Helper() From 16e0be070566871fdcdbb7f83e923f0ec6feb84b Mon Sep 17 00:00:00 2001 From: Dustin Xie Date: Wed, 15 Nov 2023 10:32:27 -0800 Subject: [PATCH 2/2] address comment --- action/rlp_tx_test.go | 211 ++---------------------------------------- 1 file changed, 8 insertions(+), 203 deletions(-) diff --git a/action/rlp_tx_test.go b/action/rlp_tx_test.go index de81672c4b..20e0019cad 100644 --- a/action/rlp_tx_test.go +++ b/action/rlp_tx_test.go @@ -92,205 +92,8 @@ func TestGenerateRlp(t *testing.T) { func TestRlpDecodeVerify(t *testing.T) { require := require.New(t) - rlpTests := []struct { - actType string - raw string - nonce uint64 - limit uint64 - price string - amount string - to string - - dataLen int - hash string - pubkey string - pkhash string - }{ - { - "transfer", - "f86e8085e8d4a51000825208943141df3f2e4415533bb6d6be2a351b2db9ee84ef88016345785d8a0000808224c6a0204d25fc0d7d8b3fdf162c6ee820f888f5533b1c382d79d5cbc8ec1d9091a9a8a016f1a58d7e0d0fd24be800f64a2d6433c5fcb31e3fc7562b7fbe62bc382a95bb", - 0, - 21000, - "1000000000000", - "100000000000000000", - "0x3141df3f2e4415533bb6d6be2A351B2db9ee84EF", - 0, - "eead45fe6b510db9ed6dce9187280791c04bbaadd90c54a7f4b1f75ced382ff1", - "041ba784140be115e8fa8698933e9318558a895c75c7943100f0677e4d84ff2763ff68720a0d22c12d093a2d692d1e8292c3b7672fccf3b3db46a6e0bdad93be17", - "87eea07540789af85b64947aea21a3f00400b597", - }, - { - "execution", - "f8ab0d85e8d4a5100082520894ac7ac39de679b19aae042c0ce19facb86e0a411780b844a9059cbb0000000000000000000000003141df3f2e4415533bb6d6be2a351b2db9ee84ef000000000000000000000000000000000000000000000000000000003b9aca008224c5a0fac4e25db03c99fec618b74a962d322a334234696eb62c7e5b9889132ff4f4d7a02c88e451572ca36b6f690ce23ff9d6695dd71e888521fa706a8fc8c279099a61", - 13, - 21000, - "1000000000000", - "0", - "0xAC7AC39De679b19AaE042c0cE19fAcB86e0A4117", - 68, - "7467dd6ccd4f3d7b6dc0002b26a45ad0b75a1793da4e3557cf6ff2582cbe25c9", - "041ba784140be115e8fa8698933e9318558a895c75c7943100f0677e4d84ff2763ff68720a0d22c12d093a2d692d1e8292c3b7672fccf3b3db46a6e0bdad93be17", - "87eea07540789af85b64947aea21a3f00400b597", - }, - { - "execution", - "f9024f2e830f42408381b3208080b901fc608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061019c806100606000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063445df0ac146100465780638da5cb5b14610064578063fdacd576146100ae575b600080fd5b61004e6100dc565b6040518082815260200191505060405180910390f35b61006c6100e2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100da600480360360208110156100c457600080fd5b8101908080359060200190929190505050610107565b005b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561016457806001819055505b5056fea265627a7a72315820e54fe55a78b9d8bec22b4d3e6b94b7e59799daee3940423eb1aa30fe643eeb9a64736f6c634300051000328224c5a0439310c2d5509fc42486171b910cf8107542c86e23202a3a8ba43129cabcdbfea038966d36b41916f619c64bdc8c3ddcb021b35ea95d44875eb8201e9422fd98f0", - 46, - 8500000, - "1000000", - "0", - EmptyAddress, - 508, - "b676128dae841742e3ab6e518acb30badc6b26230fe870821d1de08c85823067", - "049c6567f527f8fc98c0875d3d80097fcb4d5b7bfe037fc9dd5dbeaf563d58d7ff17a4f2b85df9734ecdb276622738e28f0b7cf224909ab7b128c5ca748729b0d2", - "1904bfcb93edc9bf961eead2e5c0de81dcc1d37d", - }, - { - "stakeCreate", - "f901670980828ca09404c22afae6a03438b8fed74cb1cf441168df3f1280b90104a3d374c400000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000004746573740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008224c6a02d359322fb1eb0ef44008b587d28160fb237ae716da2735aef9ce2702af52151a03518f334c585c31cec1d9c0ec81fd4c4f70d3ab661502a5aeb1f6eb07bc01854", - 9, - 36000, - "0", - "0", - "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", - 260, - "f59e5f9ba10ec50fdd1ebb41c75c6d54cfc634428620930b6ba6300847127241", - "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", - "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", - }, - { - "stakeAddDeposit", - "f8e60980825aa09404c22afae6a03438b8fed74cb1cf441168df3f1280b88434e8e14500000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000008224c6a0b4af40981b992eab4f15afe1bab1d4c498069cae8fa4ea3e0800d732f282fadea073de47b280905d5ccd4fc329e9c1f10b0bdefe1f4a3f4f8b00918680428ae7dd", - 9, - 23200, - "0", - "0", - "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", - 132, - "8823b599b46cd907c4691aa71b5668b835be76a8358fa9beb866610e27598592", - "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", - "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", - }, - { - "changeCandidate", - "f9012609808273a09404c22afae6a03438b8fed74cb1cf441168df3f1280b8c4fb3d51380000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000004746573740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008224c6a06087932dec4df781917c12d31feb80c8e61b2317e3a0820401f3c095746a765da0549df65b7d94fdec196bc70e6dda056fec873664c064036e55fd3bc7e766a595", - 9, - 29600, - "0", - "0", - "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", - 196, - "23f29aebf4b193b02dd78866d56ea7a7b1cdbf27604d34868bb82993c216b4ec", - "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", - "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", - }, - { - "unstake", - "f8c609808252089404c22afae6a03438b8fed74cb1cf441168df3f1280b8642bde151d0000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008224c6a0bd261cf9c6a2412272c660742a902965611d838176b2ad22b39219dadeedb312a02beef231cc90e4fbd6b928b28aea6ca1ccaf4f793f9d05bc0186e0e09b920a0a", - 9, - 21000, - "0", - "0", - "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", - 100, - "0c8560b135d325573e6aad484d71e2887835acce7fd4a78eddcb24efe6071516", - "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", - "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", - }, - { - "withdrawStake", - "f8c609808252089404c22afae6a03438b8fed74cb1cf441168df3f1280b864d179ffb50000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008224c5a0526ec8247ce5ae1c8542776cf28a85c7bc2f17e1abc3de5cfbfd20fd85aeeca3a07a6db0a7ae08b6b6aeeae4a1446dcc6f090589e7835d63ebc0a1db783c5e2c89", - 9, - 21000, - "0", - "0", - "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", - 100, - "49cc2e14f3d1c03d7e36686d962995ea0f30f65f948d5a59181a5504bc58c102", - "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", - "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", - }, - { - "restake", - "f9010609808267209404c22afae6a03438b8fed74cb1cf441168df3f1280b8a44c4fee4b000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000008224c5a0078638f1f00ab532522558e2e4f394f13bfe134a8687ac4639ebead60f63e0dba019dc91f08c1f422de44aa7e6b25ada0632f29bc22242900b3a60f7f371301f02", - 9, - 26400, - "0", - "0", - "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", - 164, - "c3d30b0fccf9d59ece79419d329e50082a8b6d86dee1b9f424f8852e154713d1", - "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", - "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", - }, - { - "transferStake", - "f8e60980825aa09404c22afae6a03438b8fed74cb1cf441168df3f1280b8849cb560bb0000000000000000000000003041a575c7a70021e3082929798c8c3fdaa9d8240000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000008224c5a07fd84321b04de059cbfdf12dcd383d3e554c569705f32035bc435b8d996c8bdba00df629ef4d9135d73bb60d49815761bc0a6ee7eb66770106dc9e809cd105d570", - 9, - 23200, - "0", - "0", - "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", - 132, - "a60b2546839e889a0ef89be4f224fb70dab3e4ddb6f65391ff708b01116593c1", - "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", - "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", - }, - { - "candidateRegister", - "f901c709808252089404c22afae6a03438b8fed74cb1cf441168df3f1280b90164bee5f7b700000000000000000000000000000000000000000000000000000000000001000000000000000000000000003041a575c7a70021e3082929798c8c3fdaa9d8240000000000000000000000003041a575c7a70021e3082929798c8c3fdaa9d8240000000000000000000000003041a575c7a70021e3082929798c8c3fdaa9d82400000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000004746573740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008224c5a07b4fd9921e47c13bb52fc5e0df47f4dc0bffcf6e7877e13c7e559b4a7d3b9825a0073a3a029822aa43506834bef8b1ed30d6bb436d758d7cf583deb48a4efefd6a", - 9, - 21000, - "0", - "0", - "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", - 356, - "9aa470cbdc3b3fd8f51aae4770d6a58cf4016be18201f0efbae6d83d0b2aa096", - "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", - "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", - }, - { - "candidateUpdate", - "f9010609808252089404c22afae6a03438b8fed74cb1cf441168df3f1280b8a4435f9f2200000000000000000000000000000000000000000000000000000000000000600000000000000000000000003041a575c7a70021e3082929798c8c3fdaa9d8240000000000000000000000003041a575c7a70021e3082929798c8c3fdaa9d824000000000000000000000000000000000000000000000000000000000000000474657374000000000000000000000000000000000000000000000000000000008224c6a04df6545da871debef84476198e76167d4dfe6fb83098a5a49dbab734352f20f1a0220686494f8b09751bbeb5c63729e7ecc5c504f952c67e926461db98588854b6", - 9, - 21000, - "0", - "0", - "0x04C22AfaE6a03438b8FED74cb1Cf441168DF3F12", - 164, - "7a8d96d35c939bf1634d587b1f471c0f3f96ba750d64d43289c9eef267718ef0", - "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", - "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", - }, - { - "rewardingClaim", - "f8c6806482520894a576c141e5659137ddda4223d209d4744b2106be80b8642df163ef0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008224c6a03d62943431b8ca0e8ea0a9c79dc8f64df14c965ca5486da124804013778ed566a065956b185116b65cec0ec9bcf9539e924784a4b448190b0aa9d017f1719be921", - 0, - 21000, - "100", - "0", - "0xA576C141e5659137ddDa4223d209d4744b2106BE", - 100, - "4d26d0736ebd9e69bd5994f3730b05a2d48c810b3bb54818be65d02004cf4ff4", - "04830579b50e01602c2015c24e72fbc48bca1cca1e601b119ca73abe2e0b5bd61fcb7874567e091030d6b644f927445d80e00b3f9ca0c566c21c30615e94c343da", - "8d38efe45794d7fceea10b2262c23c12245959db", - }, - { - "rewardingDeposit", - "f8c6016482520894a576c141e5659137ddda4223d209d4744b2106be80b86427852a6b0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008224c6a013b7679dbabcb0f97b93942436f5072cca3c7fe43451a8fedcdf3c84c1344e1da02af4cc67594c0200b59f4e30ba149af15e546acbfc69fa31f14e8788ab063d85", - 1, - 21000, - "100", - "0", - "0xA576C141e5659137ddDa4223d209d4744b2106BE", - 100, - "842fea9a292c0bc7a1e05a14a8255ed8dc945fdae7c01a6b70f5213ebe35583b", - "04830579b50e01602c2015c24e72fbc48bca1cca1e601b119ca73abe2e0b5bd61fcb7874567e091030d6b644f927445d80e00b3f9ca0c566c21c30615e94c343da", - "8d38efe45794d7fceea10b2262c23c12245959db", - }, - } - - for _, v := range rlpTests { + oldTests := rlpTests[:len(rlpTests)-1] + for _, v := range oldTests { // decode received RLP tx tx, sig, pubkey, err := DecodeRawTx(v.raw, _evmNetworkID) require.NoError(err) @@ -348,10 +151,8 @@ func TestRlpDecodeVerify(t *testing.T) { } } -func TestEthTxDecodeVerify(t *testing.T) { - require := require.New(t) - - rlpTests := []struct { +var ( + rlpTests = []struct { actType string raw string nonce uint64 @@ -592,6 +393,10 @@ func TestEthTxDecodeVerify(t *testing.T) { "3fab184622dc19b6109349b94811493bf2a45362", }, } +) + +func TestEthTxDecodeVerify(t *testing.T) { + require := require.New(t) for _, v := range rlpTests { // decode received RLP tx