diff --git a/checks/localnet/snippets/adder.spec.ts b/checks/localnet/snippets/adder.spec.ts index 3cddefcb..8431aa06 100644 --- a/checks/localnet/snippets/adder.spec.ts +++ b/checks/localnet/snippets/adder.spec.ts @@ -1,4 +1,4 @@ -import { FiveMinutesInMilliseconds, INetworkConfig, INetworkProvider, ITestSession, ITestUser, TestSession } from "@elrondnetwork/erdjs-snippets"; +import { createESDTInteractor, FiveMinutesInMilliseconds, INetworkConfig, INetworkProvider, ITestSession, ITestUser, ITokenPayment, TestSession } from "@elrondnetwork/erdjs-snippets"; import { Address, DefaultGasConfiguration, GasEstimator, IAddress, TokenPayment, Transaction, TransactionFactory, TransactionPayload, TransactionWatcher } from "@elrondnetwork/erdjs"; import { assert } from "chai"; import { createAdderInteractor } from "./adderInteractor"; @@ -35,6 +35,16 @@ describe("adder snippet", async function () { session.correlation.step = this.currentTest?.fullTitle() || ""; }); + it("issue token", async function () { + this.timeout(FiveMinutesInMilliseconds); + + const interactor = await createESDTInteractor(session); + await session.syncUsers([bob]); + + const token = await interactor.issueFungibleToken(bob, { name: "FOO", ticker: "FOO", decimals: 0, supply: "100000000" }); + await session.saveToken({ name: "fooToken", token: token }); + }); + it("setup", async function () { this.timeout(FiveMinutesInMilliseconds); @@ -72,7 +82,7 @@ describe("adder snippet", async function () { assert.isTrue(returnCode.isSuccess()); }); - it("send value to non-payable (intra-shard)", async function () { + it("send value to non-payable, badly formatted (intra-shard)", async function () { this.timeout(FiveMinutesInMilliseconds); await session.syncUsers([bob]); @@ -86,6 +96,44 @@ describe("adder snippet", async function () { session.audit.onTransactionCompleted({ transactionHash, transaction: transactionOnNetwork }); }); + it("send value to non-payable (intra-shard)", async function () { + this.timeout(FiveMinutesInMilliseconds); + + await session.syncUsers([bob]); + + let contractAddress = await session.loadAddress("adderInShard0"); + + const { transaction, transactionHash } = await sendToContract(bob, contractAddress, 1, "", 10000000) + console.log("Transaction:", transactionHash); + + const transactionOnNetwork = await transactionWatcher.awaitCompleted(transaction); + session.audit.onTransactionCompleted({ transactionHash, transaction: transactionOnNetwork }); + }); + + it("send ESDT (built-in function) to non-payable (intra-shard)", async function () { + this.timeout(FiveMinutesInMilliseconds); + + await session.syncUsers([bob]); + + const contractAddress = await session.loadAddress("adderInShard0"); + const token = await session.loadToken("fooToken"); + const payment = TokenPayment.fungibleFromAmount(token.identifier, 1, 0); + + const transaction = transactionFactory.createESDTTransfer({ + payment: payment, + nonce: bob.account.getNonceThenIncrement(), + sender: bob.address, + receiver: contractAddress, + chainID: networkConfig.ChainID + }); + + await bob.signer.sign(transaction); + const transactionHash = await provider.sendTransaction(transaction); + console.log("Transaction:", transactionHash); + + await transactionWatcher.awaitCompleted(transaction); + }); + it("send value to non-payable (cross-shard)", async function () { this.timeout(FiveMinutesInMilliseconds); diff --git a/server/provider/networkProvider.go b/server/provider/networkProvider.go index 72d8e765..a9206985 100644 --- a/server/provider/networkProvider.go +++ b/server/provider/networkProvider.go @@ -21,7 +21,6 @@ import ( "github.com/ElrondNetwork/elrond-proxy-go/facade" "github.com/ElrondNetwork/elrond-proxy-go/observer" "github.com/ElrondNetwork/elrond-proxy-go/process" - "github.com/ElrondNetwork/elrond-proxy-go/process/cache" processFactory "github.com/ElrondNetwork/elrond-proxy-go/process/factory" "github.com/ElrondNetwork/rosetta/server/resources" ) @@ -63,7 +62,6 @@ type networkProvider struct { accountProcessor facade.AccountProcessor transactionProcessor facade.TransactionProcessor blockProcessor facade.BlockProcessor - nodeStatusProcessor facade.NodeStatusProcessor hasher hashing.Hasher marshalizerForHashing marshal.Marshalizer @@ -156,12 +154,6 @@ func NewNetworkProvider(args ArgsNewNetworkProvider) (*networkProvider, error) { return nil, err } - economicMetricsCacher := cache.NewGenericApiResponseMemoryCacher() - nodeStatusProcessor, err := process.NewNodeStatusProcessor(baseProcessor, economicMetricsCacher, nodeStatusCacheDuration) - if err != nil { - return nil, err - } - return &networkProvider{ isOffline: args.IsOffline, @@ -170,7 +162,6 @@ func NewNetworkProvider(args ArgsNewNetworkProvider) (*networkProvider, error) { accountProcessor: accountProcessor, transactionProcessor: transactionProcessor, blockProcessor: blockProcessor, - nodeStatusProcessor: nodeStatusProcessor, hasher: hasher, marshalizerForHashing: marshalizerForHashing, diff --git a/server/services/constants.go b/server/services/constants.go index 9d511cf8..1b7ac3fd 100644 --- a/server/services/constants.go +++ b/server/services/constants.go @@ -6,6 +6,7 @@ var ( transactionVersion = 1 transactionProcessingTypeRelayed = "RelayedTx" transactionProcessingTypeBuiltInFunctionCall = "BuiltInFunctionCall" + transactionProcessingTypeMoveBalance = "MoveBalance" builtInFunctionClaimDeveloperRewards = "ClaimDeveloperRewards" refundGasMessage = "refundedGas" sendingValueToNonPayableContractDataPrefix = "@" + hex.EncodeToString([]byte("sending value to non payable contract")) diff --git a/server/services/transactionsFeaturesDetector.go b/server/services/transactionsFeaturesDetector.go index 4d28d561..2f6ea768 100644 --- a/server/services/transactionsFeaturesDetector.go +++ b/server/services/transactionsFeaturesDetector.go @@ -41,10 +41,13 @@ func (extractor *transactionsFeaturesDetector) doesContractResultHoldRewardsOfCl return isResultOfClaimDeveloperRewards && hasNoData && hasZeroNonce } -// isInvalidTransactionOfSendingValueToNonPayableContract detects intra-shard transactions -// bearing the error "sending value to non-payable contract", which are included in invalid mini-block. -func (extractor *transactionsFeaturesDetector) isInvalidTransactionOfSendingValueToNonPayableContract(tx *data.FullTransaction) bool { - if tx.Type != string(transaction.TxTypeInvalid) { +// isInvalidTransactionOfSendingValueToNonPayableContractOfTypeMoveBalance detects intra-shard transactions +// bearing the error "sending value to non-payable contract", which are included in invalid mini-block, +func (extractor *transactionsFeaturesDetector) isInvalidTransactionOfSendingValueToNonPayableContractOfTypeMoveBalance(tx *data.FullTransaction) bool { + isInvalid := tx.Type == string(transaction.TxTypeInvalid) + isMoveBalance := tx.ProcessingTypeOnSource == transactionProcessingTypeMoveBalance && tx.ProcessingTypeOnDestination == transactionProcessingTypeMoveBalance + + if !isInvalid || !isMoveBalance { return false } diff --git a/server/services/transactionsTransformer.go b/server/services/transactionsTransformer.go index 29a1c195..7ea9971c 100644 --- a/server/services/transactionsTransformer.go +++ b/server/services/transactionsTransformer.go @@ -217,9 +217,11 @@ func (transformer *transactionsTransformer) refundReceiptToRosettaTx(receipt *tr func (transformer *transactionsTransformer) invalidTxToRosettaTx(tx *data.FullTransaction) *types.Transaction { fee := tx.InitiallyPaidFee - if transformer.featuresDetector.isInvalidTransactionOfSendingValueToNonPayableContract(tx) { + if transformer.featuresDetector.isInvalidTransactionOfSendingValueToNonPayableContractOfTypeMoveBalance(tx) { // For this type of transactions, the fee only has the "data movement" component // (we ignore tx.InitiallyPaidFee, which is not correctly provided in this case). + // Though, note that for built-in function calls (e.g. sending tokens using a transfer function) etc., + // the fee has the "execution" component, as well. fee = transformer.provider.ComputeTransactionFeeForMoveBalance(tx).String() } diff --git a/version/constants.go b/version/constants.go index 2693cd84..64f6d35a 100644 --- a/version/constants.go +++ b/version/constants.go @@ -5,7 +5,7 @@ const ( RosettaVersion = "v1.4.12" // RosettaMiddlewareVersion is the version of this package (application) - RosettaMiddlewareVersion = "v0.1.1" + RosettaMiddlewareVersion = "v0.1.2" // NodeVersion is the canonical version of the node runtime NodeVersion = "rc/2022-july"