Skip to content

Commit

Permalink
Merge pull request #10 from ElrondNetwork/development-07-06
Browse files Browse the repository at this point in the history
Discriminate between move-balance and other invalid transactions of sending value to non-payable contract
  • Loading branch information
andreibancioiu authored Jul 7, 2022
2 parents cb36912 + d60d84e commit 5a86727
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 17 deletions.
52 changes: 50 additions & 2 deletions checks/localnet/snippets/adder.spec.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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]);
Expand All @@ -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);

Expand Down
9 changes: 0 additions & 9 deletions server/provider/networkProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,

Expand All @@ -170,7 +162,6 @@ func NewNetworkProvider(args ArgsNewNetworkProvider) (*networkProvider, error) {
accountProcessor: accountProcessor,
transactionProcessor: transactionProcessor,
blockProcessor: blockProcessor,
nodeStatusProcessor: nodeStatusProcessor,

hasher: hasher,
marshalizerForHashing: marshalizerForHashing,
Expand Down
1 change: 1 addition & 0 deletions server/services/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Expand Down
11 changes: 7 additions & 4 deletions server/services/transactionsFeaturesDetector.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
4 changes: 3 additions & 1 deletion server/services/transactionsTransformer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}

Expand Down
2 changes: 1 addition & 1 deletion version/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 5a86727

Please sign in to comment.