diff --git a/go.mod b/go.mod index 75fd2b3..1325c1c 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/hashicorp/golang-lru v0.5.4 github.com/hyperledger/firefly-common v1.1.3 github.com/hyperledger/firefly-signer v0.9.21 - github.com/hyperledger/firefly-transaction-manager v1.1.1 + github.com/hyperledger/firefly-transaction-manager v1.1.2 github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.4.0 github.com/stretchr/testify v1.8.0 diff --git a/go.sum b/go.sum index aeca8d7..07cf911 100644 --- a/go.sum +++ b/go.sum @@ -288,17 +288,12 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hyperledger/firefly-common v0.1.13/go.mod h1:2NqPi5Ud9H6rSlZXkLbotxW7z4EAD89p3/8oNOpm9Gs= -github.com/hyperledger/firefly-common v0.1.17-0.20220808193503-961a6b241a1a/go.mod h1:MNbaI2spBsdZYOub6Duj9xueE7Qyu9itOmJ4vE8tjYw= -github.com/hyperledger/firefly-common v1.1.2 h1:tSsptTxlgOlbbsyU6Ae83rOWA6tx1o0oNdqI8PAgzsk= -github.com/hyperledger/firefly-common v1.1.2/go.mod h1:gMlv4Iy5JjnzXmSEdb+tWVDIc/2GhL9MRcgNX+VmI4M= github.com/hyperledger/firefly-common v1.1.3 h1:srCodaJSLl8/qaq+Cse6HfHZbzYFzguerX370YGxnXU= github.com/hyperledger/firefly-common v1.1.3/go.mod h1:gMlv4Iy5JjnzXmSEdb+tWVDIc/2GhL9MRcgNX+VmI4M= github.com/hyperledger/firefly-signer v0.9.21 h1:xgR5/rH1KLSU8HFoXVXrDm4sTJAI7qS1MCnPucpORFE= github.com/hyperledger/firefly-signer v0.9.21/go.mod h1:Ng3UzN1He1zrNBYMVQOeRs69aHobfVPMKXKyettjZk0= -github.com/hyperledger/firefly-transaction-manager v1.1.0 h1:XEAYuAN+uqnMHsyUplc7OxuvCYsb7WwbknWmluZw4Vs= -github.com/hyperledger/firefly-transaction-manager v1.1.0/go.mod h1:wB5YXPIL4sXXWLXO2pwjdAj9q4+iJsYt4NVaWtuttRI= -github.com/hyperledger/firefly-transaction-manager v1.1.1 h1:KlMs2Uhi5IoIJjCa6yCwr0TnxGvHFZpbKtedHlnMI2E= -github.com/hyperledger/firefly-transaction-manager v1.1.1/go.mod h1:jr9d7t1fEE45SuWs6+0GonZI/E0O69cGFecX2fmsGKU= +github.com/hyperledger/firefly-transaction-manager v1.1.2 h1:CQUVtuKT32gkoXd7LXz2i0kRc68Czo6bLVXlDL3Kkhc= +github.com/hyperledger/firefly-transaction-manager v1.1.2/go.mod h1:jr9d7t1fEE45SuWs6+0GonZI/E0O69cGFecX2fmsGKU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= @@ -471,7 +466,6 @@ github.com/spf13/viper v1.12.1-0.20220712161005-5247643f0235 h1:azjn5/lAGpcMny6s github.com/spf13/viper v1.12.1-0.20220712161005-5247643f0235/go.mod h1:f40df4ovE8V1ot0NXmYP1zUDS+X1D5AXGviq9fCJqZU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= diff --git a/internal/ethereum/send_transaction.go b/internal/ethereum/send_transaction.go index c160677..070c1e0 100644 --- a/internal/ethereum/send_transaction.go +++ b/internal/ethereum/send_transaction.go @@ -32,29 +32,33 @@ import ( ) func (c *ethConnector) TransactionSend(ctx context.Context, req *ffcapi.TransactionSendRequest) (*ffcapi.TransactionSendResponse, ffcapi.ErrorReason, error) { + var rpcError error + var txHash ethtypes.HexBytes0xPrefix + if req.PreSigned { + rpcError = c.backend.CallRPC(ctx, &txHash, "eth_sendRawTransaction", req.TransactionData) + } else { + txData, err := hex.DecodeString(strings.TrimPrefix(req.TransactionData, "0x")) + if err != nil { + return nil, ffcapi.ErrorReasonInvalidInputs, i18n.NewError(ctx, msgs.MsgInvalidTXData, req.TransactionData, err) + } - txData, err := hex.DecodeString(strings.TrimPrefix(req.TransactionData, "0x")) - if err != nil { - return nil, ffcapi.ErrorReasonInvalidInputs, i18n.NewError(ctx, msgs.MsgInvalidTXData, req.TransactionData, err) - } - - tx, err := c.buildTx(ctx, txTypePrePrepared, req.From, req.To, req.Nonce, req.Gas, req.Value, txData) - if err != nil { - return nil, ffcapi.ErrorReasonInvalidInputs, err - } + tx, err := c.buildTx(ctx, txTypePrePrepared, req.From, req.To, req.Nonce, req.Gas, req.Value, txData) + if err != nil { + return nil, ffcapi.ErrorReasonInvalidInputs, err + } - err = c.mapGasPrice(ctx, req.GasPrice, tx) - if err != nil { - return nil, ffcapi.ErrorReasonInvalidInputs, err + err = c.mapGasPrice(ctx, req.GasPrice, tx) + if err != nil { + return nil, ffcapi.ErrorReasonInvalidInputs, err + } + rpcError = c.backend.CallRPC(ctx, &txHash, "eth_sendTransaction", tx) } - var txHash ethtypes.HexBytes0xPrefix - err = c.backend.CallRPC(ctx, &txHash, "eth_sendTransaction", tx) - if err == nil && len(txHash) != 32 { - err = i18n.NewError(ctx, msgs.MsgInvalidTXHashReturned, len(txHash)) + if rpcError == nil && len(txHash) != 32 { + rpcError = i18n.NewError(ctx, msgs.MsgInvalidTXHashReturned, len(txHash)) } - if err != nil { - return nil, mapError(sendRPCMethods, err), err + if rpcError != nil { + return nil, mapError(sendRPCMethods, rpcError), rpcError } return &ffcapi.TransactionSendResponse{ TransactionHash: txHash.String(), diff --git a/internal/ethereum/send_transaction_test.go b/internal/ethereum/send_transaction_test.go index 42a0dd9..ded9ac3 100644 --- a/internal/ethereum/send_transaction_test.go +++ b/internal/ethereum/send_transaction_test.go @@ -42,6 +42,16 @@ const sampleSendTX = `{ "transactionData": "0x60fe47b100000000000000000000000000000000000000000000000000000000feedbeef" }` +const sampleSendRawTX = `{ + "ffcapi": { + "version": "v1.0.0", + "id": "904F177C-C790-4B01-BDF4-F2B4E52E607E", + "type": "send_transaction" + }, + "transactionData": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675", + "preSigned": true +}` + const sampleSendTXBadFrom = `{ "ffcapi": { "version": "v1.0.0", @@ -158,6 +168,34 @@ func TestSendTransactionOK(t *testing.T) { } +func TestSendPreSignedTransactionOK(t *testing.T) { + + ctx, c, mRPC, done := newTestConnector(t) + defer done() + + mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_sendRawTransaction", + mock.MatchedBy(func(data string) bool { + assert.Equal(t, "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675", data) + return true + })). + Run(func(args mock.Arguments) { + *(args[1].(*ethtypes.HexBytes0xPrefix)) = ethtypes.MustNewHexBytes0xPrefix("0x332db2d926128920c2dc1b2067de4e86d073975fd018e22ed2470449e755b508") + }). + Return(nil) + + var req ffcapi.TransactionSendRequest + err := json.Unmarshal([]byte(sampleSendRawTX), &req) + assert.NoError(t, err) + res, reason, err := c.TransactionSend(ctx, &req) + assert.NoError(t, err) + assert.Empty(t, reason) + + assert.Equal(t, "0x332db2d926128920c2dc1b2067de4e86d073975fd018e22ed2470449e755b508", res.TransactionHash) + + mRPC.AssertExpectations(t) + +} + func TestSendTransactionFail(t *testing.T) { ctx, c, mRPC, done := newTestConnector(t)