diff --git a/go.mod b/go.mod index 7388d6d74..181001fa5 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/golang-migrate/migrate/v4 v4.15.2 github.com/gorilla/mux v1.8.0 github.com/gorilla/websocket v1.5.0 - github.com/hyperledger/firefly-common v0.1.15 + github.com/hyperledger/firefly-common v0.1.16 github.com/hyperledger/firefly-signer v0.9.12 github.com/jarcoal/httpmock v1.1.0 github.com/karlseguin/ccache v2.0.3+incompatible diff --git a/go.sum b/go.sum index 1cacd7213..145c4e015 100644 --- a/go.sum +++ b/go.sum @@ -727,8 +727,8 @@ github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpT github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hyperledger/firefly-common v0.1.13/go.mod h1:2NqPi5Ud9H6rSlZXkLbotxW7z4EAD89p3/8oNOpm9Gs= -github.com/hyperledger/firefly-common v0.1.15 h1:hOAMSz+YuGP1ulLstVFoWxrCAB+0OrbnfUO3v4etvEw= -github.com/hyperledger/firefly-common v0.1.15/go.mod h1:MNbaI2spBsdZYOub6Duj9xueE7Qyu9itOmJ4vE8tjYw= +github.com/hyperledger/firefly-common v0.1.16 h1:21xidDEKrJhtGdBSRqHN4PfDi7aYxF0HOFuAa04V1AE= +github.com/hyperledger/firefly-common v0.1.16/go.mod h1:MNbaI2spBsdZYOub6Duj9xueE7Qyu9itOmJ4vE8tjYw= github.com/hyperledger/firefly-signer v0.9.12 h1:pCPiGHx1+MbTsIQuRkoQmfWxvpcvtGHVavls0NnH0po= github.com/hyperledger/firefly-signer v0.9.12/go.mod h1:GPQRUZOFOAjkLmg8GDjZUjEdUD0gcar+CSVhwltIwyw= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= diff --git a/internal/blockchain/ethereum/ethereum.go b/internal/blockchain/ethereum/ethereum.go index d7710304a..ac6575bb0 100644 --- a/internal/blockchain/ethereum/ethereum.go +++ b/internal/blockchain/ethereum/ethereum.go @@ -348,8 +348,13 @@ func (e *Ethereum) handleReceipt(ctx context.Context, reply fftypes.JSONObject) l.Errorf("Reply cannot be processed - missing fields: %+v", reply) return } - updateType := core.OpStatusSucceeded - if replyType != "TransactionSuccess" { + var updateType core.OpStatus + switch replyType { + case "TransactionSuccess": + updateType = core.OpStatusSucceeded + case "TransactionUpdate": + updateType = core.OpStatusPending + default: updateType = core.OpStatusFailed } l.Infof("Received operation update: status=%s request=%s tx=%s message=%s", updateType, requestID, txHash, message) @@ -387,6 +392,10 @@ func (e *Ethereum) handleMessageBatch(ctx context.Context, messages []interface{ return err } + firstColon := strings.Index(signature, ":") + if firstColon >= 0 { + signature = signature[firstColon+1:] + } switch signature { case broadcastBatchEventSignature: if err := e.handleBatchPinEvent(eventCtx, location, subInfo, msgJSON); err != nil { diff --git a/internal/blockchain/ethereum/ethereum_test.go b/internal/blockchain/ethereum/ethereum_test.go index 0aa7292fd..b8664c6de 100644 --- a/internal/blockchain/ethereum/ethereum_test.go +++ b/internal/blockchain/ethereum/ethereum_test.go @@ -975,7 +975,7 @@ func TestHandleMessageBatchPinOK(t *testing.T) { ] }, "subId": "sb-b5b97a4e-a317-4053-6400-1474650efcb5", - "signature": "BatchPin(address,uint256,string,bytes32,bytes32,string,bytes32[])", + "signature": "0x1C197604587F046FD40684A8f21f4609FB811A7b:BatchPin(address,uint256,string,bytes32,bytes32,string,bytes32[])", "logIndex": "50", "timestamp": "1620576488" }, @@ -1062,7 +1062,7 @@ func TestHandleMessageBatchPinOK(t *testing.T) { "address": "0x1C197604587F046FD40684A8f21f4609FB811A7b", "blockNumber": "38011", "logIndex": "50", - "signature": "BatchPin(address,uint256,string,bytes32,bytes32,string,bytes32[])", + "signature": "0x1C197604587F046FD40684A8f21f4609FB811A7b:BatchPin(address,uint256,string,bytes32,bytes32,string,bytes32[])", "subId": "sb-b5b97a4e-a317-4053-6400-1474650efcb5", "transactionHash": "0xc26df2bf1a733e9249372d61eb11bd8662d26c8129df76890b1beb2f6fa72628", "transactionIndex": "0x0", @@ -1352,6 +1352,90 @@ func TestHandleReceiptTXSuccess(t *testing.T) { em.AssertExpectations(t) } +func TestHandleReceiptTXUpdateEVMConnect(t *testing.T) { + em := &coremocks.OperationCallbacks{} + wsm := &wsmocks.WSClient{} + e := &Ethereum{ + ctx: context.Background(), + topic: "topic1", + callbacks: common.NewBlockchainCallbacks(), + wsconn: wsm, + } + e.SetOperationHandler("ns1", em) + + var reply fftypes.JSONObject + operationID := fftypes.NewUUID() + data := fftypes.JSONAnyPtr(`{ + "created": "2022-08-03T18:55:42.671166Z", + "errorHistory": null, + "firstSubmit": "2022-08-03T18:55:42.762254Z", + "gas": "48049", + "gasPrice": 0, + "headers": { + "requestId": "ns1:` + operationID.String() + `", + "type": "TransactionUpdate" + }, + "id": "ns1:` + operationID.String() + `", + "lastSubmit": "2022-08-03T18:55:42.762254Z", + "nonce": "1", + "policyInfo": null, + "receipt": { + "blockHash": "0x972713d879efd32573fe4d88ed0cde94a094367d50f7e5bc8262dd41fe07d9e6", + "blockNumber": "3", + "extraInfo": { + "blockHash": "0x972713d879efd32573fe4d88ed0cde94a094367d50f7e5bc8262dd41fe07d9e6", + "blockNumber": "0x3", + "contractAddress": null, + "cumulativeGasUsed": "0x7d21", + "from": "0x081afaa6792a524ff2fb0654e615d19f9a600e57", + "gasUsed": "0x7d21", + "logs": [ + { + "address": "0x9da7ecba282387ecd696dd9aecfc14efeb5f5fce", + "blockHash": "0x972713d879efd32573fe4d88ed0cde94a094367d50f7e5bc8262dd41fe07d9e6", + "blockNumber": "0x3", + "data": "0x000000000000000000000000081afaa6792a524ff2fb0654e615d19f9a600e570000000000000000000000000000000000000000000000000000000062eac4ae00000000000000000000000000000000000000000000000000000000000000e05fbe3d02be9341f492917ec5aecfb151d243287ac95c49f780a4259ab53a8d14ec218052055a2b541712ab3246354c36f3aa189e1f31a7a8b33cbf957014d2e6000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d50535551486f5852617553346a5434544b55356f414167616d334d4132315642575777634c6e66536e35696d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018319d70666de18ed7d1c17e1bbd8ac0b16716fbe2059a8ae356a09d3bd067e14", + "logIndex": "0x0", + "removed": false, + "topics": [ + "0x805721bc246bccc732581be0c0aa2dd8f7ec93e97ba4b307be84428c98b0a12f" + ], + "transactionHash": "0x929c898a46762d91e9f4b0b8e2800863dcf4a40f694109dc4cd19dbd334fa4cc", + "transactionIndex": "0x0" + } + ], + "status": "0x1", + "to": "0x9da7ecba282387ecd696dd9aecfc14efeb5f5fce", + "transactionHash": "0x929c898a46762d91e9f4b0b8e2800863dcf4a40f694109dc4cd19dbd334fa4cc", + "transactionIndex": "0x0" + }, + "success": true, + "transactionIndex": "0" + }, + "sequenceId": "dfd7c5e6-135d-11ed-80ff-b67a78953577", + "status": "Succeeded", + "transactionData": "0x48ce1dcc5fbe3d02be9341f492917ec5aecfb151d243287ac95c49f780a4259ab53a8d14ec218052055a2b541712ab3246354c36f3aa189e1f31a7a8b33cbf957014d2e6000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000002e516d50535551486f5852617553346a5434544b55356f414167616d334d4132315642575777634c6e66536e35696d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018319d70666de18ed7d1c17e1bbd8ac0b16716fbe2059a8ae356a09d3bd067e14", + "transactionHash": "0x929c898a46762d91e9f4b0b8e2800863dcf4a40f694109dc4cd19dbd334fa4cc", + "transactionHeaders": { + "from": "0x081afaa6792a524ff2fb0654e615d19f9a600e57", + "to": "0x9da7ecba282387ecd696dd9aecfc14efeb5f5fce" + }, + "updated": "2022-08-03T18:55:43.781941Z" + }`) + + em.On("OperationUpdate", e, mock.MatchedBy(func(update *core.OperationUpdate) bool { + return update.NamespacedOpID == "ns1:"+operationID.String() && + update.Status == core.OpStatusPending && + update.BlockchainTXID == "0x929c898a46762d91e9f4b0b8e2800863dcf4a40f694109dc4cd19dbd334fa4cc" + })).Return(nil) + + err := json.Unmarshal(data.Bytes(), &reply) + assert.NoError(t, err) + e.handleReceipt(context.Background(), reply) + + em.AssertExpectations(t) +} + func TestHandleBadPayloadsAndThenReceiptFailure(t *testing.T) { e, cancel := newTestEthereum() defer cancel() diff --git a/internal/coremsgs/en_config_descriptions.go b/internal/coremsgs/en_config_descriptions.go index cd26b5283..5c0b44421 100644 --- a/internal/coremsgs/en_config_descriptions.go +++ b/internal/coremsgs/en_config_descriptions.go @@ -328,6 +328,4 @@ var ( ConfigPluginsAuth = ffc("config.plugins.auth", "Authorization plugin configuration", i18n.MapStringStringType) ConfigPluginsAuthName = ffc("config.plugins.auth[].name", "The name of the auth plugin to use", i18n.StringType) ConfigPluginsAuthType = ffc("config.plugins.auth[].type", "The type of the auth plugin to use", i18n.StringType) - - ConfigGlobalAuthBasicPasswordFile = ffc("config.global.basic.passwordfile", "The path to a .htpasswd file to use for authenticating requests. Passwords should be hashed with bcrypt.", i18n.StringType) )