Skip to content

Commit

Permalink
[action] add NewEthSigner() and pass Signer as input to rlpRawHash() …
Browse files Browse the repository at this point in the history
…and rlpSignedHash() (#3967)
  • Loading branch information
dustinxie committed Nov 11, 2023
1 parent 8e73e2b commit 7e93d69
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 17 deletions.
27 changes: 21 additions & 6 deletions action/rlp_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ import (
"github.com/ethereum/go-ethereum/rlp"
"github.com/iotexproject/go-pkgs/crypto"
"github.com/iotexproject/go-pkgs/hash"
"github.com/iotexproject/iotex-proto/golang/iotextypes"
"github.com/pkg/errors"
"golang.org/x/crypto/sha3"
)

func rlpRawHash(rawTx *types.Transaction, chainID uint32) (hash.Hash256, error) {
h := types.NewEIP155Signer(big.NewInt(int64(chainID))).Hash(rawTx)
func rlpRawHash(rawTx *types.Transaction, signer types.Signer) (hash.Hash256, error) {
h := signer.Hash(rawTx)
return hash.BytesToHash256(h[:]), nil
}

func rlpSignedHash(tx *types.Transaction, chainID uint32, sig []byte) (hash.Hash256, error) {
signedTx, err := RawTxToSignedTx(tx, chainID, sig)
func rlpSignedHash(tx *types.Transaction, signer types.Signer, sig []byte) (hash.Hash256, error) {
signedTx, err := RawTxToSignedTx(tx, signer, sig)
if err != nil {
return hash.ZeroHash256, err
}
Expand All @@ -31,7 +32,7 @@ func rlpSignedHash(tx *types.Transaction, chainID uint32, sig []byte) (hash.Hash
}

// RawTxToSignedTx converts the raw tx to corresponding signed tx
func RawTxToSignedTx(rawTx *types.Transaction, chainID uint32, sig []byte) (*types.Transaction, error) {
func RawTxToSignedTx(rawTx *types.Transaction, signer types.Signer, sig []byte) (*types.Transaction, error) {
if len(sig) != 65 {
return nil, errors.Errorf("invalid signature length = %d, expecting 65", len(sig))
}
Expand All @@ -43,7 +44,7 @@ func RawTxToSignedTx(rawTx *types.Transaction, chainID uint32, sig []byte) (*typ

// 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(types.NewEIP155Signer(big.NewInt(int64(chainID))), sc)
signedTx, err := rawTx.WithSignature(signer, sc)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -83,3 +84,17 @@ func DecodeRawTx(rawData string, chainID uint32) (tx *types.Transaction, sig []b
pubkey, err = crypto.RecoverPubkey(rawHash[:], sig)
return
}

// 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:
return types.NewEIP155Signer(big.NewInt(int64(chainID))), nil
default:
return nil, ErrInvalidAct
}
}
12 changes: 9 additions & 3 deletions action/rlp_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ func TestGenerateRlp(t *testing.T) {
require.Contains(err.Error(), v.err)
continue
}
h, err := rlpSignedHash(tx, _evmNetworkID, v.sig)
signer, err := NewEthSigner(iotextypes.Encoding_ETHEREUM_RLP, _evmNetworkID)
require.NoError(err)
h, err := rlpSignedHash(tx, signer, v.sig)
if err != nil {
require.Contains(err.Error(), v.err)
}
Expand Down Expand Up @@ -333,7 +335,9 @@ func TestRlpDecodeVerify(t *testing.T) {
require.True(bytes.Equal(sig, selp.signature))
raw, err := selp.envelopeHash()
require.NoError(err)
rawHash := types.NewEIP155Signer(big.NewInt(int64(_evmNetworkID))).Hash(tx)
signer, err := NewEthSigner(iotextypes.Encoding_ETHEREUM_RLP, _evmNetworkID)
require.NoError(err)
rawHash := signer.Hash(tx)
require.True(bytes.Equal(rawHash[:], raw[:]))
require.NotEqual(raw, h)
require.NoError(selp.VerifySignature())
Expand Down Expand Up @@ -395,7 +399,9 @@ func TestIssue3944(t *testing.T) {
r.Equal("1b", v.Text(16))
r.NotEqual(hash, tx.Hash().Hex()) // hash does not match with wrong V value in signature

tx1, err := RawTxToSignedTx(tx, 4690, sig)
signer, err := NewEthSigner(iotextypes.Encoding_ETHEREUM_RLP, 4690)
r.NoError(err)
tx1, err := RawTxToSignedTx(tx, signer, sig)
r.NoError(err)
v, q, s = tx1.RawSignatureValues()
r.Equal(sig[:32], q.Bytes())
Expand Down
18 changes: 15 additions & 3 deletions action/sealedenvelope.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ func (sealed *SealedEnvelope) envelopeHash() (hash.Hash256, error) {
if err != nil {
return hash.ZeroHash256, err
}
return rlpRawHash(tx, sealed.evmNetworkID)
signer, err := NewEthSigner(sealed.encoding, sealed.evmNetworkID)
if err != nil {
return hash.ZeroHash256, err
}
return rlpRawHash(tx, signer)
case iotextypes.Encoding_IOTEX_PROTOBUF:
return hash.Hash256b(byteutil.Must(proto.Marshal(sealed.Envelope.Proto()))), nil
default:
Expand Down Expand Up @@ -71,7 +75,11 @@ func (sealed *SealedEnvelope) calcHash() (hash.Hash256, error) {
if err != nil {
return hash.ZeroHash256, err
}
return rlpSignedHash(tx, sealed.evmNetworkID, sealed.Signature())
signer, err := NewEthSigner(sealed.encoding, sealed.evmNetworkID)
if err != nil {
return hash.ZeroHash256, err
}
return rlpSignedHash(tx, signer, sealed.Signature())
case iotextypes.Encoding_IOTEX_PROTOBUF:
return hash.Hash256b(byteutil.Must(proto.Marshal(sealed.Proto()))), nil
default:
Expand Down Expand Up @@ -146,7 +154,11 @@ func (sealed *SealedEnvelope) loadProto(pbAct *iotextypes.Action, evmID uint32)
if err != nil {
return err
}
if _, err = rlpSignedHash(tx, evmID, pbAct.GetSignature()); err != nil {
signer, err := NewEthSigner(encoding, evmID)
if err != nil {
return err
}
if _, err = rlpSignedHash(tx, signer, pbAct.GetSignature()); err != nil {
return err
}
sealed.evmNetworkID = evmID
Expand Down
5 changes: 4 additions & 1 deletion api/web3server_integrity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/iotexproject/go-pkgs/util"
"github.com/iotexproject/iotex-address/address"
"github.com/iotexproject/iotex-proto/golang/iotextypes"
"github.com/stretchr/testify/require"

"github.com/iotexproject/iotex-core/action"
Expand Down Expand Up @@ -693,7 +694,9 @@ func web3Staking(t *testing.T, handler *hTTPHandler) {
big.NewInt(0),
test.data,
)
tx, err := types.SignTx(rawTx, types.NewEIP155Signer(big.NewInt(int64(_evmNetworkID))), ecdsaPvk)
signer, err := action.NewEthSigner(iotextypes.Encoding_ETHEREUM_RLP, _evmNetworkID)
require.NoError(err)
tx, err := types.SignTx(rawTx, signer, ecdsaPvk)
require.NoError(err)
BinaryData, err := tx.MarshalBinary()
require.NoError(err)
Expand Down
13 changes: 10 additions & 3 deletions api/web3server_marshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"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"
"github.com/stretchr/testify/require"

"github.com/iotexproject/iotex-core/action"
Expand Down Expand Up @@ -155,7 +156,9 @@ func TestBlockObjectMarshal(t *testing.T) {

t.Run("BlockWithDetail", func(t *testing.T) {
raw := types.NewContractCreation(2, unit.ConvertIotxToRau(1000), 21000, unit.ConvertIotxToRau(1), []byte{})
ethTx, err := action.RawTxToSignedTx(raw, 0, sevlp.Signature())
signer, err := action.NewEthSigner(iotextypes.Encoding_ETHEREUM_RLP, 0)
require.NoError(err)
ethTx, err := action.RawTxToSignedTx(raw, signer, sevlp.Signature())
require.NoError(err)
tx := &getTransactionResult{
blockHash: _testBlkHash,
Expand Down Expand Up @@ -230,7 +233,9 @@ 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")
tx, err := action.RawTxToSignedTx(raw, 4690, sig)
signer, err := action.NewEthSigner(iotextypes.Encoding_ETHEREUM_RLP, 4690)
require.NoError(err)
tx, err := action.RawTxToSignedTx(raw, signer, sig)
res, err := json.Marshal(&getTransactionResult{
blockHash: _testBlkHash,
to: nil,
Expand Down Expand Up @@ -266,7 +271,9 @@ 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)
tx, err := action.RawTxToSignedTx(raw, 0, sig)
signer, err := action.NewEthSigner(iotextypes.Encoding_ETHEREUM_RLP, 0)
require.NoError(err)
tx, err := action.RawTxToSignedTx(raw, signer, sig)
require.NoError(err)
res, err := json.Marshal(&getTransactionResult{
blockHash: blkHash,
Expand Down
7 changes: 6 additions & 1 deletion api/web3server_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/iotexproject/go-pkgs/util"
"github.com/iotexproject/iotex-address/address"
"github.com/iotexproject/iotex-proto/golang/iotexapi"
"github.com/iotexproject/iotex-proto/golang/iotextypes"
"github.com/pkg/errors"
"github.com/tidwall/gjson"
"go.uber.org/zap"
Expand Down Expand Up @@ -117,7 +118,11 @@ func (svr *web3Handler) getTransactionFromActionInfo(blkHash hash.Hash256, selp
if err != nil {
return nil, err
}
tx, err := action.RawTxToSignedTx(ethTx, svr.coreService.EVMNetworkID(), selp.Signature())
signer, err := action.NewEthSigner(iotextypes.Encoding(selp.Encoding()), svr.coreService.EVMNetworkID())
if err != nil {
return nil, err
}
tx, err := action.RawTxToSignedTx(ethTx, signer, selp.Signature())
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 7e93d69

Please sign in to comment.