lotus/chain/eth/eth_transactions_test.go

198 lines
161 KiB
Go
Raw Normal View History

2022-12-14 06:12:52 +00:00
package eth
import (
"bytes"
"encoding/hex"
"encoding/json"
"fmt"
"testing"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/sha3"
"github.com/filecoin-project/go-address"
gocrypto "github.com/filecoin-project/go-crypto"
2022-11-09 17:54:07 +00:00
actorstypes "github.com/filecoin-project/go-state-types/actors"
builtintypes "github.com/filecoin-project/go-state-types/builtin"
2022-11-09 17:54:07 +00:00
"github.com/filecoin-project/go-state-types/builtin/v10/evm"
init10 "github.com/filecoin-project/go-state-types/builtin/v10/init"
crypto1 "github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/chain/actors"
2022-12-14 19:08:38 +00:00
"github.com/filecoin-project/lotus/chain/types/ethtypes"
"github.com/filecoin-project/lotus/lib/sigs"
_ "github.com/filecoin-project/lotus/lib/sigs/delegated"
)
type TxTestcase struct {
TxJSON string
NosigTx string
2022-12-14 19:08:38 +00:00
Input ethtypes.EthBytes
Output EthTxArgs
}
func TestTxArgs(t *testing.T) {
testcases, err := prepareTxTestcases()
require.Nil(t, err)
require.NotEmpty(t, testcases)
for i, tc := range testcases {
comment := fmt.Sprintf("case %d: \n%s\n%s", i, tc.TxJSON, hex.EncodeToString(tc.Input))
// parse txargs
txArgs, err := ParseEthTxArgs(tc.Input)
2022-11-11 03:49:06 +00:00
require.NoError(t, err)
msgRecovered, err := txArgs.OriginalRlpMsg()
2022-11-11 03:49:06 +00:00
require.NoError(t, err)
require.Equal(t, tc.NosigTx, "0x"+hex.EncodeToString(msgRecovered), comment)
// verify signatures
from, err := txArgs.Sender()
2022-11-11 03:49:06 +00:00
require.NoError(t, err)
smsg, err := txArgs.ToSignedMessage()
2022-11-11 03:49:06 +00:00
require.NoError(t, err)
err = sigs.Verify(&smsg.Signature, from, msgRecovered)
2022-11-11 03:49:06 +00:00
require.NoError(t, err)
// verify data
require.Equal(t, tc.Output.ChainID, txArgs.ChainID)
require.Equal(t, tc.Output.Nonce, txArgs.Nonce)
require.Equal(t, tc.Output.To, txArgs.To)
}
}
func TestTransformParams(t *testing.T) {
constructorParams, err := actors.SerializeParams(&evm.ConstructorParams{
2022-10-21 10:59:09 +00:00
Initcode: mustDecodeHex("0x1122334455"),
})
require.Nil(t, err)
2022-11-09 17:54:07 +00:00
evmActorCid, ok := actors.GetActorCodeID(actorstypes.Version10, "reward")
require.True(t, ok)
2022-11-09 17:54:07 +00:00
params, err := actors.SerializeParams(&init10.ExecParams{
CodeCID: evmActorCid,
ConstructorParams: constructorParams,
})
require.Nil(t, err)
2022-11-09 17:54:07 +00:00
var exec init10.ExecParams
reader := bytes.NewReader(params)
err1 := exec.UnmarshalCBOR(reader)
require.Nil(t, err1)
var evmParams evm.ConstructorParams
reader1 := bytes.NewReader(exec.ConstructorParams)
err1 = evmParams.UnmarshalCBOR(reader1)
require.Nil(t, err1)
2022-10-21 10:59:09 +00:00
require.Equal(t, mustDecodeHex("0x1122334455"), evmParams.Initcode)
}
func TestEcRecover(t *testing.T) {
rHex := "0x479ff7fa64cf8bf641eb81635d1e8a698530d2f219951d234539e6d074819529"
sHex := "0x4b6146d27be50cdbb2853ba9a42f207af8d730272f1ebe9c9a78aeef1d6aa924"
fromHex := "0x3947D223fc5415f43ea099866AB62B1d4D33814D"
v := byte(0)
msgHex := "0x02f1030185012a05f2008504a817c800825208942b87d1cb599bc2a606db9a0169fcec96af04ad3a880de0b6b3a764000080c0"
pubKeyHex := "0x048362749392a0e192eff600d21155236c5a0648d300a8e0e44d8617712c7c96384c75825dc5c7595df2a5005fd8a0f7c809119fb9ab36403ed712244fc329348e"
msg := mustDecodeHex(msgHex)
pubKey := mustDecodeHex(pubKeyHex)
r := mustDecodeHex(rHex)
s := mustDecodeHex(sHex)
from := mustDecodeHex(fromHex)
sig := append(r, s...)
sig = append(sig, v)
require.Equal(t, 65, len(sig))
sha := sha3.NewLegacyKeccak256()
sha.Write(msg)
h := sha.Sum(nil)
pubk, err := gocrypto.EcRecover(h, sig)
require.Nil(t, err)
require.Equal(t, pubKey, pubk)
sha.Reset()
sha.Write(pubk[1:])
h = sha.Sum(nil)
h = h[len(h)-20:]
require.Equal(t, from, h)
}
func TestDelegatedSigner(t *testing.T) {
rHex := "0xcf1fa52fae9154ba21d67aeca9b42adfe186eb9e426c441051a8473efd190848"
sHex := "0x0e6c8c79ffaf35fb8f136c8cf6c5656f1f3befad21f2644321aa6dba58d68737"
v := byte(0)
msgHex := "0x02f08401df5e76038502540be400843b9aca008398968094ff000000000000000000000000000000000003f2832dc6c080c0"
pubKeyHex := "0x04cfecc0520d906cbfea387759246e89d85e2998843e56ad1c41de247ce10b3e4c453aa73c8de13c178d94461b6fa3f8b6f74406ce43d2fbab6992d0b283394242"
msg := mustDecodeHex(msgHex)
pubk := mustDecodeHex(pubKeyHex)
r := mustDecodeHex(rHex)
s := mustDecodeHex(sHex)
if pubk[0] == 0x04 {
pubk = pubk[1:]
}
hasher := sha3.NewLegacyKeccak256()
hasher.Reset()
hasher.Write(pubk)
addrHash := hasher.Sum(nil)
from, err := address.NewDelegatedAddress(builtintypes.EthereumAddressManagerActorID, addrHash[12:])
require.NoError(t, err)
sig := append(r, s...)
sig = append(sig, v)
require.Equal(t, 65, len(sig))
signature := &crypto1.Signature{
Type: crypto1.SigTypeDelegated,
Data: sig,
}
err = sigs.Verify(signature, from, msg)
require.NoError(t, err)
}
func prepareTxTestcases() ([]TxTestcase, error) {
tcstr := `[{"input":"0x02f84e82013a80808080808080c080a002d9af9415b94bac9fb29efa168e800fe8390ec22dd6dd3b6848632f999e5fa6a04b0bd833d6993eb37c3b0b5f89551cbbd5412b3a1fed84ca1e94ab2b936be12b","output":"{\"to\":null,\"value\":\"0\",\"gasLimit\":0,\"maxFeePerGas\":\"0\",\"maxPriorityFeePerGas\":\"0\",\"data\":null,\"nonce\":0,\"type\":2,\"chainId\":314}","nosigTx":"0x02cb82013a80808080808080c0"},{"input":"0x02f84f82013a81c8808080808080c080a0a9177c9fc995b0f83480113a62b797a3520e6bc15d0e9c722c662c40d443b893a01eec355e019308be6acf89a55288a40ae247b6f57c0ca31545efea5954f788d5","output":"{\"to\":null,\"value\":\"0\",\"gasLimit\":0,\"maxFeePerGas\":\"0\",\"maxPriorityFeePerGas\":\"0\",\"data\":null,\"nonce\":200,\"type\":2,\"chainId\":314}","nosigTx":"0x02cc82013a81c8808080808080c0"},{"input":"0x02f84e82013a80808080808080c080a002d9af9415b94bac9fb29efa168e800fe8390ec22dd6dd3b6848632f999e5fa6a04b0bd833d6993eb37c3b0b5f89551cbbd5412b3a1fed84ca1e94ab2b936be12b","output":"{\"to\":null,\"value\":\"0\",\"gasLimit\":0,\"maxFeePerGas\":\"0\",\"maxPriorityFeePerGas\":\"0\",\"data\":\"\",\"nonce\":0,\"type\":2,\"chainId\":314}","nosigTx":"0x02cb82013a80808080808080c0"},{"input":"0x02f84f82013a81c8808080808080c080a0a9177c9fc995b0f83480113a62b797a3520e6bc15d0e9c722c662c40d443b893a01eec355e019308be6acf89a55288a40ae247b6f57c0ca31545efea5954f788d5","output":"{\"to\":null,\"value\":\"0\",\"gasLimit\":0,\"maxFeePerGas\":\"0\",\"maxPriorityFeePerGas\":\"0\",\"data\":\"\",\"nonce\":200,\"type\":2,\"chainId\":314}","nosigTx":"0x02cc82013a81c8808080808080c0"},{"input":"0x02f87282013a808080808080a4f8b2cb4f000000000000000000000000ff00000000000000000000000000000000000064c001a0a0ab14f6fcca6c9905f447e961f128f2c00f5a00e7b1ae18f5d4f9e024a9b7a6a06c4126378d89035f4ab6085fa9a01d92bf798cd799b9338f7818bc48bcba0c8e","output":"{\"to\":null,\"value\":\"0\",\"gasLimit\":0,\"maxFeePerGas\":\"0\",\"maxPriorityFeePerGas\":\"0\",\"data\":\"0xf8b2cb4f000000000000000000000000ff00000000000000000000000000000000000064\",\"nonce\":0,\"type\":2,\"chainId\":314}","nosigTx":"0x02ef82013a808080808080a4f8b2cb4f000000000000000000000000ff00000000000000000000000000000000000064c0"},{"input":"0x02f87382013a81c88080808080a4f8b2cb4f000000000000000000000000ff00000000000000000000000000000000000064c080a0884e063f65a2986844a9e92f9e02561789c231136976715d5afb581435359e87a044295113d06dd7b8bdf105dd412c76fbd966ef6dbe1d8ace984886296a36018c","output":"{\"to\":null,\"value\":\"0\",\"gasLimit\":0,\"maxFeePerGas\":\"0\",\"maxPriorityFeePerGas\":\"0\",\"data\":\"0xf8b2cb4f000000000000000000000000ff00000000000000000000000000000000000064\",\"nonce\":200,\"type\":2,\"chainId\":314}","nosigTx":"0x02f082013a81c88080808080a4f8b2cb4f000000000000000000000000ff00000000000000000000000000000000000064c0"},{"input":"0x02f85082013a808082ea6080808080c080a02b86cbd16667f7e035bd908d250d842e7d06f888716131de27897655dce01666a055f43bf2a758e6c250a14a31d33056fcb764e0fce4fffdeb0e11d84caa5ca57b","output":"{\"to\":null,\"value\":\"0\",\"gasLimit\":0,\"maxFeePerGas\":\"60000\",\"maxPriorityFeePerGas\":\"0\",\"data\":null,\"nonce\":0,\"type\":2,\"chainId\":314}","nosigTx":"0x02cd82013a808082ea6080808080c0"},{"input":"0x02f85182013a81c88082ea6080808080c001a07f1e363b3d38607f8854013e68a80750befd3ba78cc9ce116d6ef6a09359a7aea05ef2c89ffc70ef7f2eaae90a2b4b2a4ffb418108d458e1237b26469e6381fdce","output":"{\"to\":null,\"value\":\"0\",\"gasLimit\":0,\"maxFeePerGas\":\"60000\",\"maxPriorityFeePerGas\":\"0\",\"data\":null,\"nonce\":200,\"type\":2,\"chainId\":314}","nosigTx":"0x02ce82013a81c88082ea6080808080c0"},{"input":"0x02f85082013a808082ea6080808080c080a02b86cbd16667f7e035bd908d250d842e7d06f888716131de27897655dce01666a055f43bf2a758e6c250a14a31d33056fcb764e0fce4fffdeb0e11d84caa5ca57b","output":"{\"to\":null,\"value\":\"0\",\"gasLimit\":0,\"maxFeePerGas\":\"60000\",\"maxPriorityFeePerGas\":\"0\",\"data\":\"\",\"nonce\":0,\"type\":2,\"chainId\":314}","nosigTx":"0x02cd82013a808082ea6080808080c0"},{"input":"0x02f85182013a81c88082ea6080808080c001a07f1e363b3d38607f8854013e68a80750befd3ba78cc9ce116d6ef6a09359a7aea05ef2c89ffc70ef7f2eaae90a2b4b2a4ffb418108d4
testcases := []struct {
2022-12-14 19:08:38 +00:00
Input ethtypes.EthBytes `json:"input"`
Output string `json:"output"`
NosigTx string `json:"nosigTx"`
}{}
err := json.Unmarshal([]byte(tcstr), &testcases)
if err != nil {
return nil, err
}
res := []TxTestcase{}
for _, tc := range testcases {
tx := EthTxArgs{}
err := json.Unmarshal([]byte(tc.Output), &tx)
if err != nil {
return nil, err
}
res = append(res, TxTestcase{
Input: tc.Input,
Output: tx,
TxJSON: tc.Output,
NosigTx: tc.NosigTx,
})
}
return res, err
}