Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Main into feat/inner #501

Merged
merged 7 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ jobs:
- run: npm run lint
- run: npm run compile
- run: npm install esmify && npm run compile-browser
- run: npm test
- run: npm run tests-unit
- run: npm run tests-devnet
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@multiversx/sdk-core",
"version": "13.7.0",
"version": "13.8.0",
"description": "MultiversX SDK for JavaScript and TypeScript",
"author": "MultiversX",
"homepage": "https://multiversx.com",
Expand All @@ -22,10 +22,11 @@
],
"scripts": {
"test": "npm run tests-unit",
"tests-unit": "mocha $(find . -name '*.spec.ts' ! -name '*.local.net.spec.*' ! -name '*.devnet.spec.*' ! -name '*.testnet.spec.*')",
"tests-unit": "mocha $(find . -name '*.spec.ts' ! -name '*.local.net.spec.*' ! -name '*.test.net.spec.*' ! -name '*.dev.net.spec.*' ! -name '*.main.net.spec.*')",
"tests-localnet": "mocha $(find . -name '*.local.net.spec.ts')",
"tests-devnet": "mocha $(find . -name '*.devnet.spec.ts')",
"tests-testnet": "mocha $(find . -name '*.testnet.spec.ts')",
"tests-testnet": "mocha $(find . -name '*.test.net.spec.ts')",
"tests-devnet": "mocha $(find . -name '*.dev.net.spec.ts')",
"tests-mainnet": "mocha $(find . -name '*.main.net.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",
Expand Down
8 changes: 8 additions & 0 deletions src/converters/transactionsConverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ export class TransactionsConverter {
return Buffer.from(value || "", "hex");
}

/**
* @deprecated Where {@link TransactionOutcome} was needed (throughout the SDK), pass the {@link ITransactionOnNetwork} object instead.
*
* Summarizes the outcome of a transaction on the network, and maps it to the "standard" resources (according to the sdk-specs).
*
* In the future, this converter function will become obsolete,
* as the impedance mismatch between the network components and the "core" components will be reduced.
*/
public transactionOnNetworkToOutcome(transactionOnNetwork: ITransactionOnNetwork): TransactionOutcome {
// In the future, this will not be needed because the transaction, as returned from the API,
// will hold the data corresponding to the direct smart contract call outcome (in case of smart contract calls).
Expand Down
1 change: 1 addition & 0 deletions src/interfaceOfNetwork.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export interface IContractResultItem {
data: string;
returnMessage: string;
logs: ITransactionLogs;
previousHash?: string;
}

export interface IContractQueryResponse {
Expand Down
62 changes: 6 additions & 56 deletions src/smartcontracts/resultsParser.spec.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import BigNumber from "bignumber.js";
import { assert } from "chai";
import { Address } from "../address";
import { IAddress } from "../interface";
import {
ContractQueryResponse,
ContractResultItem,
ContractResults,
TransactionEventData,
TransactionEventOnNetwork,
TransactionEventTopic,
TransactionLogsOnNetwork,
TransactionOnNetwork,
TransactionEventData,
} from "../networkProviders";
import BigNumber from "bignumber.js";
import { assert } from "chai";
import * as fs from "fs";
import path from "path";
import { Address } from "../address";
import { IAddress } from "../interface";
import { ITransactionOnNetwork } from "../interfaceOfNetwork";
import { LogLevel, Logger } from "../logger";
import { loadAbiRegistry } from "../testutils";
import { ArgSerializer } from "./argSerializer";
import { ResultsParser } from "./resultsParser";
Expand Down Expand Up @@ -258,10 +254,7 @@ describe("test smart contract results parser", () => {

let bundle = parser.parseUntypedOutcome(transaction);
assert.deepEqual(bundle.returnCode, ReturnCode.Ok);
assert.equal(
bundle.returnMessage,
"@too much gas provided for processing: gas provided = 596384500, gas used = 733010",
);
assert.equal(bundle.returnMessage, "ok");
assert.deepEqual(bundle.values, []);
});

Expand Down Expand Up @@ -383,47 +376,4 @@ describe("test smart contract results parser", () => {
assert.deepEqual(bundle.b, new BigNumber(43));
assert.deepEqual(bundle.c, new BigNumber(44));
});

// This test should be enabled manually and run against a set of sample transactions.
// 2022-04-03: test ran against ~1800 transactions sampled from devnet.
it.skip("should parse real-world contract outcomes", async () => {
let oldLogLevel = Logger.logLevel;
Logger.setLevel(LogLevel.Trace);

let folder = path.resolve(process.env["SAMPLES"] || "SAMPLES");
let samples = loadRealWorldSamples(folder);

for (const [transaction, _] of samples) {
console.log("Transaction:", transaction.hash.toString());

let bundle = parser.parseUntypedOutcome(transaction);

console.log("Return code:", bundle.returnCode.toString());
console.log("Return message:", bundle.returnMessage);
console.log("Num values:", bundle.values.length);
console.log("=".repeat(80));

assert.include(KnownReturnCodes, bundle.returnCode.valueOf());
}

Logger.setLevel(oldLogLevel);
});

function loadRealWorldSamples(folder: string): [ITransactionOnNetwork, string][] {
let transactionFiles = fs.readdirSync(folder);
let samples: [ITransactionOnNetwork, string][] = [];

for (const file of transactionFiles) {
let txHash = path.basename(file, ".json");
let filePath = path.resolve(folder, file);
let jsonContent: string = fs.readFileSync(filePath, { encoding: "utf8" });
let json = JSON.parse(jsonContent);
let payload = json["data"]["transaction"];
let transaction = TransactionOnNetwork.fromProxyHttpResponse(txHash, payload);

samples.push([transaction, jsonContent]);
}

return samples;
}
});
23 changes: 20 additions & 3 deletions src/smartcontracts/resultsParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,12 +284,10 @@ export class ResultsParser {
}

let { returnCode, returnDataParts } = this.sliceDataFieldInParts(eventTooMuchGas.data);
let lastTopic = eventTooMuchGas.getLastTopic();
let returnMessage = lastTopic?.toString() || returnCode.toString();

return {
returnCode: returnCode,
returnMessage: returnMessage,
returnMessage: returnCode.toString(),
values: returnDataParts,
};
}
Expand Down Expand Up @@ -355,6 +353,25 @@ export class ResultsParser {
}
}

// Additional fallback heuristics (alter search constraints):
for (const resultItem of transaction.contractResults.items) {
let writeLogWithReturnData = resultItem.logs.findSingleOrNoneEvent(WellKnownEvents.OnWriteLog, (event) => {
const addressIsContract = event.address.bech32() == contractAddress.toBech32();
return addressIsContract;
});

if (writeLogWithReturnData) {
const { returnCode, returnDataParts } = this.sliceDataFieldInParts(writeLogWithReturnData.data);
const returnMessage = returnCode.toString();

return {
returnCode: returnCode,
returnMessage: returnMessage,
values: returnDataParts,
};
}
}

return null;
}

Expand Down
111 changes: 111 additions & 0 deletions src/testdata/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Testdata

## Files `transactions.mainnet.json`

Transactions were sampled from the mainnet BigQuery dataset:

```sql
DECLARE
TIMESTAMP_START DATE DEFAULT '2024-09-01';
DECLARE
TIMESTAMP_END DATE DEFAULT '2024-09-03';
-- Contract execute, with success
(
SELECT
`_id`,
'execute_success' `kind`
FROM
`multiversx-blockchain-etl.crypto_multiversx_mainnet_eu.transactions`
WHERE
DATE(`timestamp`) >= TIMESTAMP_START
AND DATE(`timestamp`) <= TIMESTAMP_END
AND `isScCall` = TRUE
AND ARRAY_LENGTH(`esdtValues`) = 0
AND `status` = 'success'
AND RAND() < 0.25
LIMIT
250 )
UNION ALL
-- Contract execute, with error
(
SELECT
`_id`,
'execute_error' `kind`
FROM
`multiversx-blockchain-etl.crypto_multiversx_mainnet_eu.transactions`
WHERE
DATE(`timestamp`) >= TIMESTAMP_START
AND DATE(`timestamp`) <= TIMESTAMP_END
AND `isScCall` = TRUE
AND ARRAY_LENGTH(`esdtValues`) = 0
AND `status` = 'fail'
AND RAND() < 0.25
LIMIT
250 )
UNION ALL
-- Contract transfer & execute, with success
(
SELECT
`_id`,
'transfer_execute_success' `kind`
FROM
`multiversx-blockchain-etl.crypto_multiversx_mainnet_eu.transactions`
WHERE
DATE(`timestamp`) >= TIMESTAMP_START
AND DATE(`timestamp`) <= TIMESTAMP_END
AND `isScCall` = TRUE
AND ARRAY_LENGTH(`esdtValues`) > 0
AND `status` = 'success'
AND RAND() < 0.25
LIMIT
250 )
UNION ALL
-- Contract transfer & execute, with error
(
SELECT
`_id`,
'transfer_execute_error' `kind`
FROM
`multiversx-blockchain-etl.crypto_multiversx_mainnet_eu.transactions`
WHERE
DATE(`timestamp`) >= TIMESTAMP_START
AND DATE(`timestamp`) <= TIMESTAMP_END
AND `isScCall` = TRUE
AND ARRAY_LENGTH(`esdtValues`) > 0
AND `status` = 'fail'
AND RAND() < 0.25
LIMIT
250)
UNION ALL
-- Relayed, with success
(
SELECT
`_id`,
'relayed_success' `kind`
FROM
`multiversx-blockchain-etl.crypto_multiversx_mainnet_eu.transactions`
WHERE
DATE(`timestamp`) >= TIMESTAMP_START
AND DATE(`timestamp`) <= TIMESTAMP_END
AND `isRelayed` = TRUE
AND `status` = 'success'
AND RAND() < 0.25
LIMIT
50)
UNION ALL
-- Relayed, with failure
(
SELECT
`_id`,
'relayed_error' `kind`
FROM
`multiversx-blockchain-etl.crypto_multiversx_mainnet_eu.transactions`
WHERE
DATE(`timestamp`) >= TIMESTAMP_START
AND DATE(`timestamp`) <= TIMESTAMP_END
AND `isRelayed` = TRUE
AND `status` = 'fail'
AND RAND() < 0.25
LIMIT
50)
```
Loading
Loading