From 11755422e326de524eacceb6ec9c2f32f2415757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Wed, 3 Apr 2024 17:43:33 +0300 Subject: [PATCH 1/6] Fix decision on event identifier to be used for parsing. --- .../transactionEventsParser.spec.ts | 7 ++++--- .../transactionEventsParser.ts | 11 ++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/transactionsOutcomeParsers/transactionEventsParser.spec.ts b/src/transactionsOutcomeParsers/transactionEventsParser.spec.ts index f709cc9bb..d31e2ee81 100644 --- a/src/transactionsOutcomeParsers/transactionEventsParser.spec.ts +++ b/src/transactionsOutcomeParsers/transactionEventsParser.spec.ts @@ -102,17 +102,18 @@ describe("test transaction events parser", () => { events: [ new TransactionEvent({ identifier: "foobar", + topics: [Buffer.from("doFoobar")], }), ], }); - }, "Invariant failed: [event [foobar] not found]"); + }, "Invariant failed: [event [doFoobar] not found]"); }); it("parses event (with multi-values)", async function () { const abi = AbiRegistry.create({ events: [ { - identifier: "foobar", + identifier: "doFoobar", inputs: [ { name: "a", @@ -139,7 +140,7 @@ describe("test transaction events parser", () => { event: new TransactionEvent({ identifier: "foobar", topics: [ - Buffer.from("foobar"), + Buffer.from("doFoobar"), Buffer.from([42]), Buffer.from("test"), Buffer.from([43]), diff --git a/src/transactionsOutcomeParsers/transactionEventsParser.ts b/src/transactionsOutcomeParsers/transactionEventsParser.ts index 326d65cfe..4288d8812 100644 --- a/src/transactionsOutcomeParsers/transactionEventsParser.ts +++ b/src/transactionsOutcomeParsers/transactionEventsParser.ts @@ -17,9 +17,9 @@ export class TransactionEventsParser { // By default, we consider that the first topic is the event identifier. // This is true for log entries emitted by smart contracts: + // https://github.com/multiversx/mx-chain-vm-go/blob/v1.5.27/vmhost/contexts/output.go#L270 // https://github.com/multiversx/mx-chain-vm-go/blob/v1.5.27/vmhost/contexts/output.go#L283 - this.firstTopicIsIdentifier = - options.firstTopicIsIdentifier === undefined ? true : options.firstTopicIsIdentifier; + this.firstTopicIsIdentifier = options.firstTopicIsIdentifier ?? true; } parseEvents(options: { events: TransactionEvent[] }): any[] { @@ -35,14 +35,15 @@ export class TransactionEventsParser { parseEvent(options: { event: TransactionEvent }): any { const topics = options.event.topics.map((topic) => Buffer.from(topic)); - const dataItems = options.event.dataItems.map((dataItem) => Buffer.from(dataItem)); - const eventDefinition = this.abi.getEvent(options.event.identifier); + const eventIdentifier = this.firstTopicIsIdentifier ? topics[0]?.toString() : options.event.identifier; if (this.firstTopicIsIdentifier) { - // Discard the first topic (not useful). topics.shift(); } + const dataItems = options.event.dataItems.map((dataItem) => Buffer.from(dataItem)); + const eventDefinition = this.abi.getEvent(eventIdentifier); + const parsedEvent = this.legacyResultsParser.doParseEvent({ topics: topics, dataItems: dataItems, From 09cac50d6df1f34dae72f0d716df4255e50504d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Wed, 3 Apr 2024 17:43:42 +0300 Subject: [PATCH 2/6] Rename file. --- ...ry.test.net.spec.ts => tokenOperationsFactory.testnet.spec.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/tokenOperations/{tokenOperationsFactory.test.net.spec.ts => tokenOperationsFactory.testnet.spec.ts} (100%) diff --git a/src/tokenOperations/tokenOperationsFactory.test.net.spec.ts b/src/tokenOperations/tokenOperationsFactory.testnet.spec.ts similarity index 100% rename from src/tokenOperations/tokenOperationsFactory.test.net.spec.ts rename to src/tokenOperations/tokenOperationsFactory.testnet.spec.ts From 65453ce10140e2597abe7c92bd91efebde7776cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Wed, 3 Apr 2024 17:44:11 +0300 Subject: [PATCH 3/6] Use latest multisig for tests. --- ...ltisig.abi.json => multisig-full.abi.json} | 999 ++++++++++++++---- src/testdata/multisig-full.wasm | Bin 0 -> 26610 bytes 2 files changed, 768 insertions(+), 231 deletions(-) rename src/testdata/{multisig.abi.json => multisig-full.abi.json} (57%) create mode 100644 src/testdata/multisig-full.wasm diff --git a/src/testdata/multisig.abi.json b/src/testdata/multisig-full.abi.json similarity index 57% rename from src/testdata/multisig.abi.json rename to src/testdata/multisig-full.abi.json index 01a363c5a..401de7cc0 100644 --- a/src/testdata/multisig.abi.json +++ b/src/testdata/multisig-full.abi.json @@ -1,19 +1,20 @@ { "buildInfo": { "rustc": { - "version": "1.59.0-nightly", - "commitHash": "399ba6bb377ce02224b57c4d6e127e160fa76b34", - "commitDate": "2022-01-03", + "version": "1.71.0-nightly", + "commitHash": "a2b1646c597329d0a25efa3889b66650f65de1de", + "commitDate": "2023-05-25", "channel": "Nightly", - "short": "rustc 1.59.0-nightly (399ba6bb3 2022-01-03)" + "short": "rustc 1.71.0-nightly (a2b1646c5 2023-05-25)" }, "contractCrate": { "name": "multisig", - "version": "1.0.0" + "version": "1.0.0", + "gitVersion": "v0.45.2.1-reproducible-169-g37d970c" }, "framework": { - "name": "elrond-wasm", - "version": "0.25.0" + "name": "multiversx-sc", + "version": "0.47.2" } }, "docs": [ @@ -38,127 +39,30 @@ }, "endpoints": [ { - "docs": [ - "Allows the contract to receive funds even if it is marked as unpayable in the protocol." - ], - "name": "deposit", + "name": "upgrade", "mutability": "mutable", - "payableInTokens": [ - "*" - ], "inputs": [], "outputs": [] }, { "docs": [ - "Iterates through all actions and retrieves those that are still pending.", - "Serialized full action data:", - "- the action id", - "- the serialized action data", - "- (number of signers followed by) list of signer addresses." - ], - "name": "getPendingActionFullInfo", - "mutability": "readonly", - "inputs": [], - "outputs": [ - { - "type": "variadic", - "multi_result": true - } - ] - }, - { - "docs": [ - "Returns `true` (`1`) if the user has signed the action.", - "Does not check whether or not the user is still a board member and the signature valid." - ], - "name": "signed", - "mutability": "readonly", - "inputs": [ - { - "name": "user", - "type": "Address" - }, - { - "name": "action_id", - "type": "u32" - } - ], - "outputs": [ - { - "type": "bool" - } - ] - }, - { - "docs": [ - "Indicates user rights.", - "`0` = no rights,", - "`1` = can propose, but not sign,", - "`2` = can propose and sign." - ], - "name": "userRole", - "mutability": "readonly", - "inputs": [ - { - "name": "user", - "type": "Address" - } - ], - "outputs": [ - { - "type": "UserRole" - } - ] - }, - { - "docs": [ - "Lists all users that can sign actions." - ], - "name": "getAllBoardMembers", - "mutability": "readonly", - "inputs": [], - "outputs": [ - { - "type": "variadic
", - "multi_result": true - } - ] - }, - { - "docs": [ - "Lists all proposers that are not board members." - ], - "name": "getAllProposers", - "mutability": "readonly", - "inputs": [], - "outputs": [ - { - "type": "variadic
", - "multi_result": true - } - ] - }, - { - "docs": [ - "Used by board members to sign actions." + "Allows the contract to receive funds even if it is marked as unpayable in the protocol." ], - "name": "sign", + "name": "deposit", "mutability": "mutable", - "inputs": [ - { - "name": "action_id", - "type": "u32" - } + "payableInTokens": [ + "*" ], + "inputs": [], "outputs": [] }, { "docs": [ - "Board members can withdraw their signatures if they no longer desire for the action to be executed.", - "Actions that are left with no valid signatures can be then deleted to free up storage." + "Clears storage pertaining to an action that is no longer supposed to be executed.", + "Any signatures that the action received must first be removed, via `unsign`.", + "Otherwise this endpoint would be prone to abuse." ], - "name": "unsign", + "name": "discardAction", "mutability": "mutable", "inputs": [ { @@ -170,16 +74,15 @@ }, { "docs": [ - "Clears storage pertaining to an action that is no longer supposed to be executed.", - "Any signatures that the action received must first be removed, via `unsign`.", - "Otherwise this endpoint would be prone to abuse." + "Discard all the actions with the given IDs" ], - "name": "discardAction", + "name": "discardBatch", "mutability": "mutable", "inputs": [ { - "name": "action_id", - "type": "u32" + "name": "action_ids", + "type": "variadic", + "multi_arg": true } ], "outputs": [] @@ -212,11 +115,7 @@ ] }, { - "docs": [ - "Denormalized proposer count.", - "It is kept in sync with the user list by the contract." - ], - "name": "getNumProposers", + "name": "getNumGroups", "mutability": "readonly", "inputs": [], "outputs": [ @@ -227,10 +126,10 @@ }, { "docs": [ - "The index of the last proposed action.", - "0 means that no action was ever proposed yet." + "Denormalized proposer count.", + "It is kept in sync with the user list by the contract." ], - "name": "getActionLastIndex", + "name": "getNumProposers", "mutability": "readonly", "inputs": [], "outputs": [ @@ -240,56 +139,25 @@ ] }, { - "docs": [ - "Serialized action data of an action with index." - ], - "name": "getActionData", - "mutability": "readonly", - "inputs": [ - { - "name": "action_id", - "type": "u32" - } - ], - "outputs": [ - { - "type": "Action" - } - ] - }, - { - "docs": [ - "Gets addresses of all users who signed an action.", - "Does not check if those users are still board members or not,", - "so the result may contain invalid signers." - ], - "name": "getActionSigners", + "name": "getActionGroup", "mutability": "readonly", "inputs": [ { - "name": "action_id", + "name": "group_id", "type": "u32" } ], "outputs": [ { - "type": "List
" + "type": "variadic", + "multi_result": true } ] }, { - "docs": [ - "Gets addresses of all users who signed an action and are still board members.", - "All these signatures are currently valid." - ], - "name": "getActionSignerCount", + "name": "getLastGroupActionId", "mutability": "readonly", - "inputs": [ - { - "name": "action_id", - "type": "u32" - } - ], + "inputs": [], "outputs": [ { "type": "u32" @@ -298,20 +166,12 @@ }, { "docs": [ - "It is possible for board members to lose their role.", - "They are not automatically removed from all actions when doing so,", - "therefore the contract needs to re-check every time when actions are performed.", - "This function is used to validate the signers before performing an action.", - "It also makes it easy to check before performing an action." + "The index of the last proposed action.", + "0 means that no action was ever proposed yet." ], - "name": "getActionValidSignerCount", + "name": "getActionLastIndex", "mutability": "readonly", - "inputs": [ - { - "name": "action_id", - "type": "u32" - } - ], + "inputs": [], "outputs": [ { "type": "u32" @@ -408,12 +268,39 @@ "type": "BigUint" }, { - "name": "opt_function", - "type": "optional", + "name": "opt_gas_limit", + "type": "Option" + }, + { + "name": "function_call", + "type": "variadic", "multi_arg": true + } + ], + "outputs": [ + { + "type": "u32" + } + ] + }, + { + "name": "proposeTransferExecuteEsdt", + "mutability": "mutable", + "inputs": [ + { + "name": "to", + "type": "Address" }, { - "name": "arguments", + "name": "tokens", + "type": "List" + }, + { + "name": "opt_gas_limit", + "type": "Option" + }, + { + "name": "function_call", "type": "variadic", "multi_arg": true } @@ -426,7 +313,7 @@ }, { "docs": [ - "Propose a transaction in which the contract will perform a transfer-execute call.", + "Propose a transaction in which the contract will perform an async call call.", "Can call smart contract endpoints directly.", "Can use ESDTTransfer/ESDTNFTTransfer/MultiESDTTransfer to send tokens, while also optionally calling endpoints.", "Works well with builtin functions.", @@ -444,12 +331,11 @@ "type": "BigUint" }, { - "name": "opt_function", - "type": "optional", - "multi_arg": true + "name": "opt_gas_limit", + "type": "Option" }, { - "name": "arguments", + "name": "function_call", "type": "variadic", "multi_arg": true } @@ -521,28 +407,51 @@ ] }, { - "docs": [ - "Returns `true` (`1`) if `getActionValidSignerCount >= getQuorum`." - ], - "name": "quorumReached", - "mutability": "readonly", + "name": "proposeBatch", + "mutability": "mutable", "inputs": [ { - "name": "action_id", - "type": "u32" + "name": "actions", + "type": "variadic", + "multi_arg": true } ], "outputs": [ { - "type": "bool" + "type": "u32" } ] }, { "docs": [ - "Proposers and board members use this to launch signed actions." + "Used by board members to sign actions." ], - "name": "performAction", + "name": "sign", + "mutability": "mutable", + "inputs": [ + { + "name": "action_id", + "type": "u32" + } + ], + "outputs": [] + }, + { + "docs": [ + "Sign all the actions in the given batch" + ], + "name": "signBatch", + "mutability": "mutable", + "inputs": [ + { + "name": "group_id", + "type": "u32" + } + ], + "outputs": [] + }, + { + "name": "signAndPerform", "mutability": "mutable", "inputs": [ { @@ -552,34 +461,597 @@ ], "outputs": [ { - "type": "PerformActionResult" + "type": "optional
", + "multi_result": true } ] - } - ], - "hasCallback": false, - "types": { - "CallActionData": { - "type": "struct", - "fields": [ + }, + { + "name": "signBatchAndPerform", + "mutability": "mutable", + "inputs": [ + { + "name": "group_id", + "type": "u32" + } + ], + "outputs": [] + }, + { + "docs": [ + "Board members can withdraw their signatures if they no longer desire for the action to be executed.", + "Actions that are left with no valid signatures can be then deleted to free up storage." + ], + "name": "unsign", + "mutability": "mutable", + "inputs": [ + { + "name": "action_id", + "type": "u32" + } + ], + "outputs": [] + }, + { + "docs": [ + "Unsign all actions with the given IDs" + ], + "name": "unsignBatch", + "mutability": "mutable", + "inputs": [ + { + "name": "group_id", + "type": "u32" + } + ], + "outputs": [] + }, + { + "docs": [ + "Returns `true` (`1`) if the user has signed the action.", + "Does not check whether or not the user is still a board member and the signature valid." + ], + "name": "signed", + "mutability": "readonly", + "inputs": [ + { + "name": "user", + "type": "Address" + }, + { + "name": "action_id", + "type": "u32" + } + ], + "outputs": [ + { + "type": "bool" + } + ] + }, + { + "name": "unsignForOutdatedBoardMembers", + "mutability": "mutable", + "inputs": [ + { + "name": "action_id", + "type": "u32" + }, + { + "name": "outdated_board_members", + "type": "variadic", + "multi_arg": true + } + ], + "outputs": [] + }, + { + "docs": [ + "Returns `true` (`1`) if `getActionValidSignerCount >= getQuorum`." + ], + "name": "quorumReached", + "mutability": "readonly", + "inputs": [ + { + "name": "action_id", + "type": "u32" + } + ], + "outputs": [ + { + "type": "bool" + } + ] + }, + { + "docs": [ + "Proposers and board members use this to launch signed actions." + ], + "name": "performAction", + "mutability": "mutable", + "inputs": [ + { + "name": "action_id", + "type": "u32" + } + ], + "outputs": [ + { + "type": "optional
", + "multi_result": true + } + ] + }, + { + "docs": [ + "Perform all the actions in the given batch" + ], + "name": "performBatch", + "mutability": "mutable", + "inputs": [ + { + "name": "group_id", + "type": "u32" + } + ], + "outputs": [] + }, + { + "name": "dnsRegister", + "onlyOwner": true, + "mutability": "mutable", + "payableInTokens": [ + "EGLD" + ], + "inputs": [ + { + "name": "dns_address", + "type": "Address" + }, + { + "name": "name", + "type": "bytes" + } + ], + "outputs": [] + }, + { + "docs": [ + "Iterates through all actions and retrieves those that are still pending.", + "Serialized full action data:", + "- the action id", + "- the serialized action data", + "- (number of signers followed by) list of signer addresses." + ], + "name": "getPendingActionFullInfo", + "mutability": "readonly", + "inputs": [ + { + "name": "opt_range", + "type": "optional>", + "multi_arg": true + } + ], + "outputs": [ + { + "type": "variadic", + "multi_result": true + } + ], + "labels": [ + "multisig-external-view" + ], + "allow_multiple_var_args": true + }, + { + "docs": [ + "Indicates user rights.", + "`0` = no rights,", + "`1` = can propose, but not sign,", + "`2` = can propose and sign." + ], + "name": "userRole", + "mutability": "readonly", + "inputs": [ + { + "name": "user", + "type": "Address" + } + ], + "outputs": [ + { + "type": "UserRole" + } + ], + "labels": [ + "multisig-external-view" + ] + }, + { + "docs": [ + "Lists all users that can sign actions." + ], + "name": "getAllBoardMembers", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "variadic
", + "multi_result": true + } + ], + "labels": [ + "multisig-external-view" + ] + }, + { + "docs": [ + "Lists all proposers that are not board members." + ], + "name": "getAllProposers", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "variadic
", + "multi_result": true + } + ], + "labels": [ + "multisig-external-view" + ] + }, + { + "docs": [ + "Serialized action data of an action with index." + ], + "name": "getActionData", + "mutability": "readonly", + "inputs": [ + { + "name": "action_id", + "type": "u32" + } + ], + "outputs": [ + { + "type": "Action" + } + ], + "labels": [ + "multisig-external-view" + ] + }, + { + "docs": [ + "Gets addresses of all users who signed an action.", + "Does not check if those users are still board members or not,", + "so the result may contain invalid signers." + ], + "name": "getActionSigners", + "mutability": "readonly", + "inputs": [ + { + "name": "action_id", + "type": "u32" + } + ], + "outputs": [ + { + "type": "List
" + } + ], + "labels": [ + "multisig-external-view" + ] + }, + { + "docs": [ + "Gets addresses of all users who signed an action and are still board members.", + "All these signatures are currently valid." + ], + "name": "getActionSignerCount", + "mutability": "readonly", + "inputs": [ + { + "name": "action_id", + "type": "u32" + } + ], + "outputs": [ + { + "type": "u32" + } + ], + "labels": [ + "multisig-external-view" + ] + }, + { + "docs": [ + "It is possible for board members to lose their role.", + "They are not automatically removed from all actions when doing so,", + "therefore the contract needs to re-check every time when actions are performed.", + "This function is used to validate the signers before performing an action.", + "It also makes it easy to check before performing an action." + ], + "name": "getActionValidSignerCount", + "mutability": "readonly", + "inputs": [ + { + "name": "action_id", + "type": "u32" + } + ], + "outputs": [ + { + "type": "u32" + } + ], + "labels": [ + "multisig-external-view" + ] + } + ], + "events": [ + { + "identifier": "asyncCallSuccess", + "inputs": [ + { + "name": "results", + "type": "variadic", + "indexed": true + } + ] + }, + { + "identifier": "asyncCallError", + "inputs": [ + { + "name": "err_code", + "type": "u32", + "indexed": true + }, + { + "name": "err_message", + "type": "bytes", + "indexed": true + } + ] + }, + { + "identifier": "startPerformAction", + "inputs": [ + { + "name": "data", + "type": "ActionFullInfo" + } + ] + }, + { + "identifier": "performChangeUser", + "inputs": [ + { + "name": "action_id", + "type": "u32", + "indexed": true + }, + { + "name": "changed_user", + "type": "Address", + "indexed": true + }, + { + "name": "old_role", + "type": "UserRole", + "indexed": true + }, + { + "name": "new_role", + "type": "UserRole", + "indexed": true + } + ] + }, + { + "identifier": "performChangeQuorum", + "inputs": [ + { + "name": "action_id", + "type": "u32", + "indexed": true + }, + { + "name": "new_quorum", + "type": "u32", + "indexed": true + } + ] + }, + { + "identifier": "performAsyncCall", + "inputs": [ + { + "name": "action_id", + "type": "u32", + "indexed": true + }, { "name": "to", - "type": "Address" + "type": "Address", + "indexed": true }, { - "name": "egld_amount", - "type": "BigUint" + "name": "egld_value", + "type": "BigUint", + "indexed": true }, { - "name": "endpoint_name", - "type": "bytes" + "name": "gas", + "type": "u64", + "indexed": true + }, + { + "name": "endpoint", + "type": "bytes", + "indexed": true }, { "name": "arguments", - "type": "List" + "type": "variadic", + "indexed": true + } + ] + }, + { + "identifier": "performTransferExecuteEgld", + "inputs": [ + { + "name": "action_id", + "type": "u32", + "indexed": true + }, + { + "name": "to", + "type": "Address", + "indexed": true + }, + { + "name": "egld_value", + "type": "BigUint", + "indexed": true + }, + { + "name": "gas", + "type": "u64", + "indexed": true + }, + { + "name": "endpoint", + "type": "bytes", + "indexed": true + }, + { + "name": "arguments", + "type": "variadic", + "indexed": true + } + ] + }, + { + "identifier": "performTransferExecuteEsdt", + "inputs": [ + { + "name": "action_id", + "type": "u32", + "indexed": true + }, + { + "name": "to", + "type": "Address", + "indexed": true + }, + { + "name": "tokens", + "type": "List", + "indexed": true + }, + { + "name": "gas", + "type": "u64", + "indexed": true + }, + { + "name": "endpoint", + "type": "bytes", + "indexed": true + }, + { + "name": "arguments", + "type": "variadic", + "indexed": true + } + ] + }, + { + "identifier": "performDeployFromSource", + "inputs": [ + { + "name": "action_id", + "type": "u32", + "indexed": true + }, + { + "name": "egld_value", + "type": "BigUint", + "indexed": true + }, + { + "name": "source_address", + "type": "Address", + "indexed": true + }, + { + "name": "code_metadata", + "type": "CodeMetadata", + "indexed": true + }, + { + "name": "gas", + "type": "u64", + "indexed": true + }, + { + "name": "arguments", + "type": "variadic", + "indexed": true } ] }, + { + "identifier": "performUpgradeFromSource", + "inputs": [ + { + "name": "action_id", + "type": "u32", + "indexed": true + }, + { + "name": "target_address", + "type": "Address", + "indexed": true + }, + { + "name": "egld_value", + "type": "BigUint", + "indexed": true + }, + { + "name": "source_address", + "type": "Address", + "indexed": true + }, + { + "name": "code_metadata", + "type": "CodeMetadata", + "indexed": true + }, + { + "name": "gas", + "type": "u64", + "indexed": true + }, + { + "name": "arguments", + "type": "variadic", + "indexed": true + } + ] + } + ], + "esdtAttributes": [], + "hasCallback": true, + "types": { "Action": { "type": "enum", "variants": [ @@ -628,7 +1100,7 @@ ] }, { - "name": "SendTransferExecute", + "name": "SendTransferExecuteEgld", "discriminant": 5, "fields": [ { @@ -638,8 +1110,18 @@ ] }, { - "name": "SendAsyncCall", + "name": "SendTransferExecuteEsdt", "discriminant": 6, + "fields": [ + { + "name": "0", + "type": "EsdtTransferExecuteData" + } + ] + }, + { + "name": "SendAsyncCall", + "discriminant": 7, "fields": [ { "name": "0", @@ -649,7 +1131,7 @@ }, { "name": "SCDeployFromSource", - "discriminant": 7, + "discriminant": 8, "fields": [ { "name": "amount", @@ -671,7 +1153,7 @@ }, { "name": "SCUpgradeFromSource", - "discriminant": 8, + "discriminant": 9, "fields": [ { "name": "sc_address", @@ -707,6 +1189,10 @@ "name": "action_id", "type": "u32" }, + { + "name": "group_id", + "type": "u32" + }, { "name": "action_data", "type": "Action" @@ -717,32 +1203,83 @@ } ] }, - "PerformActionResult": { + "ActionStatus": { "type": "enum", "variants": [ { - "name": "Nothing", + "name": "Available", "discriminant": 0 }, { - "name": "DeployResult", - "discriminant": 1, - "fields": [ - { - "name": "0", - "type": "Address" - } - ] + "name": "Aborted", + "discriminant": 1 + } + ] + }, + "CallActionData": { + "type": "struct", + "fields": [ + { + "name": "to", + "type": "Address" }, { - "name": "SendAsyncCall", - "discriminant": 2, - "fields": [ - { - "name": "0", - "type": "AsyncCall" - } - ] + "name": "egld_amount", + "type": "BigUint" + }, + { + "name": "opt_gas_limit", + "type": "Option" + }, + { + "name": "endpoint_name", + "type": "bytes" + }, + { + "name": "arguments", + "type": "List" + } + ] + }, + "EsdtTokenPayment": { + "type": "struct", + "fields": [ + { + "name": "token_identifier", + "type": "TokenIdentifier" + }, + { + "name": "token_nonce", + "type": "u64" + }, + { + "name": "amount", + "type": "BigUint" + } + ] + }, + "EsdtTransferExecuteData": { + "type": "struct", + "fields": [ + { + "name": "to", + "type": "Address" + }, + { + "name": "tokens", + "type": "List" + }, + { + "name": "opt_gas_limit", + "type": "Option" + }, + { + "name": "endpoint_name", + "type": "bytes" + }, + { + "name": "arguments", + "type": "List" } ] }, diff --git a/src/testdata/multisig-full.wasm b/src/testdata/multisig-full.wasm new file mode 100644 index 0000000000000000000000000000000000000000..acb183e628c562f2c976d3d05d258baf09f7ab29 GIT binary patch literal 26610 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 literal 0 HcmV?d00001 From 1bea5fd732dd4897f3c46cf8dac8c2f30020b1d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Wed, 3 Apr 2024 17:44:49 +0300 Subject: [PATCH 4/6] Adjust naming convention for integration tests. --- package-lock.json | 4 ++-- package.json | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index bf54b9f9c..920874bda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@multiversx/sdk-core", - "version": "13.0.0-beta.16", + "version": "13.0.0-beta.17", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@multiversx/sdk-core", - "version": "13.0.0-beta.16", + "version": "13.0.0-beta.17", "license": "MIT", "dependencies": { "@multiversx/sdk-transaction-decoder": "1.0.2", diff --git a/package.json b/package.json index 6a1534a4c..c2f537e52 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@multiversx/sdk-core", - "version": "13.0.0-beta.16", + "version": "13.0.0-beta.17", "description": "MultiversX SDK for JavaScript and TypeScript", "main": "out/index.js", "types": "out/index.d.js", @@ -10,10 +10,10 @@ ], "scripts": { "test": "npm run tests-unit", - "tests-unit": "mocha $(find . -name '*.spec.ts' ! -name '*.net.spec.*')", + "tests-unit": "mocha $(find . -name '*.spec.ts' ! -name '*.local.net.spec.*' ! -name '*.devnet.spec.*' ! -name '*.testnet.spec.*')", "tests-localnet": "mocha $(find . -name '*.local.net.spec.ts')", - "tests-devnet": "mocha $(find . -name '*.dev.net.spec.ts')", - "tests-testnet": "mocha $(find . -name '*.test.net.spec.ts')", + "tests-devnet": "mocha $(find . -name '*.devnet.spec.ts')", + "tests-testnet": "mocha $(find . -name '*.testnet.spec.ts')", "compile-browser": "tsc -p tsconfig.json && browserify out/index.js -o out-browser/sdk-core.js --standalone multiversxSdkCore -p esmify", "compile": "tsc -p tsconfig.json", "compile-proto": "npx pbjs -t static-module -w default -o src/proto/compiled.js src/proto/transaction.proto", From 68ea74e49ce55d213133eaa66ef00815c71ec5b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Wed, 3 Apr 2024 17:45:11 +0300 Subject: [PATCH 5/6] Fix test to work with newer multisig data. --- src/smartcontracts/typesystem/abiRegistry.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/smartcontracts/typesystem/abiRegistry.spec.ts b/src/smartcontracts/typesystem/abiRegistry.spec.ts index e9930b4ec..d3d966e8e 100644 --- a/src/smartcontracts/typesystem/abiRegistry.spec.ts +++ b/src/smartcontracts/typesystem/abiRegistry.spec.ts @@ -63,20 +63,20 @@ describe("test abi registry", () => { it("binary codec correctly decodes perform action result", async () => { let bc = new BinaryCodec(); let buff = Buffer.from( - "0588c738a5d26c0e3a2b4f9e8110b540ee9c0b71a3be057569a5a7b0fcb482c8f70000000806f05b59d3b200000000000b68656c6c6f20776f726c6400000000", + "0500000000000000000500d006f73c4221216fa679bc559005584c4f1160e569e1000000012a0000000003616464000000010000000107", "hex", ); - let registry = await loadAbiRegistry("src/testdata/multisig.abi.json"); + let registry = await loadAbiRegistry("src/testdata/multisig-full.abi.json"); let performAction = registry.getEndpoint("getActionData"); assert.equal(performAction.output[0].type.getName(), "Action"); let result = bc.decodeTopLevel(buff, performAction.output[0].type); assert.deepEqual( JSON.stringify(result.valueOf()), - `{"name":"SendTransferExecute","fields":[{"to":{"bech32":"erd13rrn3fwjds8r5260n6q3pd2qa6wqkudrhczh26d957c0edyzermshds0k8","pubkey":"88c738a5d26c0e3a2b4f9e8110b540ee9c0b71a3be057569a5a7b0fcb482c8f7"},"egld_amount":"500000000000000000","endpoint_name":{"type":"Buffer","data":[104,101,108,108,111,32,119,111,114,108,100]},"arguments":[]}]}`, + `{"name":"SendTransferExecuteEgld","fields":[{"to":{"bech32":"erd1qqqqqqqqqqqqqpgq6qr0w0zzyysklfneh32eqp2cf383zc89d8sstnkl60","pubkey":"00000000000000000500d006f73c4221216fa679bc559005584c4f1160e569e1"},"egld_amount":"42","opt_gas_limit":null,"endpoint_name":{"type":"Buffer","data":[97,100,100]},"arguments":[{"type":"Buffer","data":[7]}]}]}`, ); - assert.equal(result.valueOf().name, "SendTransferExecute"); + assert.equal(result.valueOf().name, "SendTransferExecuteEgld"); }); it("should load ABI containing arrayN and nested structs", async () => { From 726542ffdbf3f2ae5a2d67e631c391352b9bdf25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20B=C4=83ncioiu?= Date: Wed, 3 Apr 2024 23:01:29 +0300 Subject: [PATCH 6/6] Find by first topic. Additional tests. --- .../resources.spec.ts | 69 +++++++++++++++++++ src/transactionsOutcomeParsers/resources.ts | 4 ++ .../transactionEventsParser.spec.ts | 65 ++++++++++++++++- .../transactionEventsParser.ts | 4 +- 4 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 src/transactionsOutcomeParsers/resources.spec.ts diff --git a/src/transactionsOutcomeParsers/resources.spec.ts b/src/transactionsOutcomeParsers/resources.spec.ts new file mode 100644 index 000000000..1d8fbd8ea --- /dev/null +++ b/src/transactionsOutcomeParsers/resources.spec.ts @@ -0,0 +1,69 @@ +import { assert } from "chai"; +import { + SmartContractResult, + TransactionEvent, + TransactionLogs, + TransactionOutcome, + findEventsByFirstTopic, + findEventsByIdentifier, +} from "./resources"; + +describe("test resources", () => { + it("finds events by identifier, by first topic", async function () { + const outcome = new TransactionOutcome({ + logs: new TransactionLogs({ + events: [ + new TransactionEvent({ + identifier: "foo", + topics: [Buffer.from("a")], + }), + ], + }), + smartContractResults: [ + new SmartContractResult({ + logs: new TransactionLogs({ + events: [ + new TransactionEvent({ + identifier: "foo", + topics: [Buffer.from("b")], + }), + new TransactionEvent({ + identifier: "bar", + topics: [Buffer.from("c")], + }), + ], + }), + }), + ], + }); + + const foundByIdentifierFoo = findEventsByIdentifier(outcome, "foo"); + const foundByIdentifierBar = findEventsByIdentifier(outcome, "bar"); + const foundByTopic = findEventsByFirstTopic(outcome, "b"); + + assert.deepEqual(foundByIdentifierFoo, [ + new TransactionEvent({ + identifier: "foo", + topics: [Buffer.from("a")], + }), + new TransactionEvent({ + identifier: "foo", + topics: [Buffer.from("b")], + }), + ]); + + assert.deepEqual(foundByIdentifierBar, [ + new TransactionEvent({ + identifier: "bar", + topics: [Buffer.from("c")], + }), + ]); + + assert.deepEqual(foundByTopic, [ + new TransactionEvent({ + identifier: "foo", + topics: [Buffer.from("b")], + }), + ]); + }); +}); diff --git a/src/transactionsOutcomeParsers/resources.ts b/src/transactionsOutcomeParsers/resources.ts index 93a4d1e5f..b30bd2f1c 100644 --- a/src/transactionsOutcomeParsers/resources.ts +++ b/src/transactionsOutcomeParsers/resources.ts @@ -83,6 +83,10 @@ export function findEventsByIdentifier(transactionOutcome: TransactionOutcome, i return findEventsByPredicate(transactionOutcome, (event) => event.identifier == identifier); } +export function findEventsByFirstTopic(transactionOutcome: TransactionOutcome, topic: string): TransactionEvent[] { + return findEventsByPredicate(transactionOutcome, (event) => event.topics[0]?.toString() == topic); +} + export function gatherAllEvents(transactionOutcome: TransactionOutcome): TransactionEvent[] { const allEvents = []; diff --git a/src/transactionsOutcomeParsers/transactionEventsParser.spec.ts b/src/transactionsOutcomeParsers/transactionEventsParser.spec.ts index d31e2ee81..9ed01c91c 100644 --- a/src/transactionsOutcomeParsers/transactionEventsParser.spec.ts +++ b/src/transactionsOutcomeParsers/transactionEventsParser.spec.ts @@ -13,7 +13,7 @@ import { Address } from "../address"; import { TransactionsConverter } from "../converters/transactionsConverter"; import { AbiRegistry } from "../smartcontracts"; import { loadAbiRegistry } from "../testutils"; -import { TransactionEvent, findEventsByIdentifier } from "./resources"; +import { TransactionEvent, findEventsByFirstTopic } from "./resources"; import { TransactionEventsParser } from "./transactionEventsParser"; describe("test transaction events parser", () => { @@ -39,7 +39,7 @@ describe("test transaction events parser", () => { ]); }); - it("parses events", async function () { + it("parses events (esdt-safe, deposit)", async function () { const parser = new TransactionEventsParser({ abi: await loadAbiRegistry("src/testdata/esdt-safe.abi.json"), }); @@ -69,7 +69,7 @@ describe("test transaction events parser", () => { }); const transactionOutcome = transactionsConverter.transactionOnNetworkToOutcome(transactionOnNetwork); - const events = findEventsByIdentifier(transactionOutcome, "deposit"); + const events = findEventsByFirstTopic(transactionOutcome, "deposit"); const parsed = parser.parseEvents({ events }); assert.deepEqual(parsed, [ @@ -92,6 +92,65 @@ describe("test transaction events parser", () => { ]); }); + it("parses events (multisig, startPerformAction)", async function () { + const parser = new TransactionEventsParser({ + abi: await loadAbiRegistry("src/testdata/multisig-full.abi.json"), + }); + + const transactionsConverter = new TransactionsConverter(); + const transactionOnNetwork = new TransactionOnNetwork({ + nonce: 7, + contractResults: new ContractResults([ + new ContractResultItem({ + nonce: 8, + data: "@6f6b", + }), + ]), + logs: new TransactionLogsOnNetwork({ + events: [ + new TransactionEventOnNetwork({ + identifier: "performAction", + topics: [new TransactionEventTopic("c3RhcnRQZXJmb3JtQWN0aW9u")], + dataPayload: new TransactionEventData( + Buffer.from( + "00000001000000000500000000000000000500d006f73c4221216fa679bc559005584c4f1160e569e1000000000000000003616464000000010000000107000000010139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "hex", + ), + ), + }), + ], + }), + }); + + const transactionOutcome = transactionsConverter.transactionOnNetworkToOutcome(transactionOnNetwork); + const events = findEventsByFirstTopic(transactionOutcome, "startPerformAction"); + const parsed = parser.parseEvents({ events }); + + assert.deepEqual(parsed, [ + { + data: { + action_id: new BigNumber("1"), + group_id: new BigNumber("0"), + action_data: { + name: "SendTransferExecuteEgld", + fields: [ + { + to: Address.fromBech32( + "erd1qqqqqqqqqqqqqpgq6qr0w0zzyysklfneh32eqp2cf383zc89d8sstnkl60", + ), + egld_amount: new BigNumber("0"), + opt_gas_limit: null, + endpoint_name: Buffer.from("add"), + arguments: [Buffer.from("07", "hex")], + }, + ], + }, + signers: [Address.fromBech32("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th")], + }, + }, + ]); + }); + it("cannot parse events, when definition is missing", async function () { const parser = new TransactionEventsParser({ abi: await loadAbiRegistry("src/testdata/esdt-safe.abi.json"), diff --git a/src/transactionsOutcomeParsers/transactionEventsParser.ts b/src/transactionsOutcomeParsers/transactionEventsParser.ts index 4288d8812..4d568e077 100644 --- a/src/transactionsOutcomeParsers/transactionEventsParser.ts +++ b/src/transactionsOutcomeParsers/transactionEventsParser.ts @@ -35,14 +35,14 @@ export class TransactionEventsParser { parseEvent(options: { event: TransactionEvent }): any { const topics = options.event.topics.map((topic) => Buffer.from(topic)); - const eventIdentifier = this.firstTopicIsIdentifier ? topics[0]?.toString() : options.event.identifier; + const abiIdentifier = this.firstTopicIsIdentifier ? topics[0]?.toString() : options.event.identifier; if (this.firstTopicIsIdentifier) { topics.shift(); } const dataItems = options.event.dataItems.map((dataItem) => Buffer.from(dataItem)); - const eventDefinition = this.abi.getEvent(eventIdentifier); + const eventDefinition = this.abi.getEvent(abiIdentifier); const parsedEvent = this.legacyResultsParser.doParseEvent({ topics: topics,