Git Product home page Git Product logo

sandbox's People

Contributors

a-bahdanau avatar arterialist avatar doronaviguy avatar kardanovir avatar krigga avatar naltox avatar reveloper avatar shaharyakir avatar stanislav-povolotsky avatar thekiba avatar trinketer22 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sandbox's Issues

How to get public key from treasurecontract

I want to get public key from deployer deployer = await blockchain.treasury('deployer');. I try to run get method on treasure contract from deployer but I got error when running getMethod with get_public_key
How can I get public key from treasurecontract, Plz help

Zero value messages to Treasury gets aborted

Describe the bug

Zero value messages gets aborted.

To Reproduce

send a op::ownership_assigned message a treasury contract with value: 0 and mode: 1.

Expected behavior

treasury gets the message

Actual behavior

message aborted

How to track deep cross-contract messages?

While testing my contracts, I'll call them A, B and C, my A contract sends message to B, then B sends to C.
In my test case I send message to A. The SendMessageResult, after awaiting the send method, returns a set of messages, containing my sender and A contract interactions, but there is no B->C messages.
I assume its because of TON transactions flow, but I can't test my contracts behavior properly.
Are there facilities of being able to get the full chain messages by its transaction?

Implement flag that does not throw EmulationError on success == false

Is your feature request related to a problem? Please describe.
When writing tests for my smart contracts, there is must-fail cases which should terminate VM with my own exit code.
Before it can be done by using .toHaveTransaction matcher with success: false, exitCode: X params. Now it throws exception making this matcher useless for failed transactions.

Describe the solution you'd like
Implement this flag on Blockchain object creation

Describe alternatives you've considered
Catch EmulationError in tests and compare exit codes, which adds some boilerplate.

Additional context
image

Be able to specify non-default balance for treasury account

Is your feature request related to a problem? Please describe.
It can be helpful for some tests to initialize a treasury with a certain balance (for example 0) and then assert that the balance grows after issuing some transaction.

Describe the solution you'd like
Add a parameter to Blockchain.treasury() allowing to specify a balance

Describe alternatives you've considered

Additional context

Add support of randomSeed on blockhain entity level

Is your feature request related to a problem? Please describe.
There is a missing API that would be helpful. Provide way to set randomSeed to make RAND work properly in transactions.

Now that can be done this way only

const res = await blockchain.runGetMethod(example.address,
        'get_method',
        [],
        { randomSeed: randomBytes(32) } // randomSeed can be specified only if calling blockchain.runGetMethod or similar...
);
const number = res.stackReader.readNumber();

Describe the solution you'd like
Provide a setter randomSeed that would affect transaction result

Make treasury interface closer to ton library wallet interface

Is your feature request related to a problem? Please describe.
When porting code from ton library, I usually send with value as string:

await walletContract.sendTransfer({
    secretKey: key.secretKey,
    seqno: seqno,
    messages: [
      internal({
        to: "EQDrjaLahLkMB-hMCmkzOyBuHJ139ZUYmPHu6RRBKnbdLIYI",
        value: "0.001", // 0.001 TON
        body: "Hello", // optional comment
        bounce: false,
      })
    ]
  });

Describe the solution you'd like
Right now all of the treasury send interfaces accept only bigint, let's make them similar to accept string too and do toNano automatically like ton wallets

Get debug logs from a getter programatically

Currently it's only possible to programatically get the debug logs from transactions.
This is quite useful for expectations.
It will also be nice to have the same ability with getters.
This is not that easy because I'm not sure we have where to return them on, but it's worth brainstorming.

External messages - accept_message seems to cause silent failures

Describe the bug
External messages - accept_message seems to cause silent failures

To Reproduce

;; This will throw an error, as expected (assuming the slice doesn't in fact contain a ref)
() recv_external(slice in_msg) impure {
  var x = in_msg~load_ref();
  accept_message();
  ~dump x; ;; Without this line, error doesn't get thrown
}

;; This will NOT throw an error
() recv_external(slice in_msg) impure {
  accept_message();
  var x = in_msg~load_ref();
  ~dump x;
}

Expected behavior
I'd expect:

  1. Error to be thrown upon loading of the ref (9: cell underflow), regardless of whether we're using the value (using ~dump, send_raw_message, etc.)
  2. Error to be thrown regardless of message having been accepted.

Actual behavior
Error is thrown only if the loading which causes the underflow happens before accepting the message.

System information

  • Package version: 0.4.0
  • Node version: v16.15.0
  • OS name and version: Mac OS M1 Ventura 13.0

Additional context
Add any other context about the problem here.

Change data cell of opened contracts

Is there any way to change data cell of contracts after they are opened?

When a parent smart contract deploys a child, the address is based on the init data. I want to be able to change data of the smart contract to another cell, otherwise I'd have to send many transactions to parent and/or child to change its data cell, ready for my test case.

I tried to create an instance of the child with the data that I wanted, but I can't deploy it.

TVM Instruction PREVBLOCKSINFOTUPLE return empty tuple

When i use new TVM Instructions like PREVBLOCKSINFOTUPLE, I am not getting the expected result.

Simple func contract example:

tuple get_prevblocksinfotuple() asm "PREVBLOCKSINFOTUPLE";

() recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure {
    ~dump(get_prevblocksinfotuple());
}

Expected result: [last_mc_blocks, prev_key_block]
Result: #DEBUG#: s0 = ()

Packages:
"@ton/blueprint": "^0.17.0",
"@ton/sandbox": "^0.16.0",

Trying to run get method on non-active contract

How can I test a contract that is created through another contract?
No matter what I do I always get an error Trying to run get method on non-active contract.
Or is this impossible?

My code:

import { Blockchain, SandboxContract, TreasuryContract } from '@ton/sandbox';
import { toNano } from '@ton/core';
import { MasterContract } from '../wrappers/MasterContract';
import '@ton/test-utils';
import { CoinContract } from '../wrappers/CoinContract';

describe('MasterContract', () => {
    let blockchain: Blockchain;
    let deployer: SandboxContract<TreasuryContract>;
    let masterContract: SandboxContract<MasterContract>;

    beforeEach(async () => {
        blockchain = await Blockchain.create();

        masterContract = blockchain.openContract(await MasterContract.fromInit());

        deployer = await blockchain.treasury('deployer');

        const deployResult = await masterContract.send(
            deployer.getSender(),
            {
                value: toNano('0.05'),
            },
            {
                $$type: 'Deploy',
                queryId: 0n,
            }
        );

        expect(deployResult.transactions).toHaveTransaction({
            from: deployer.address,
            to: masterContract.address,
            deploy: true,
            success: true,
        });
    });

    it('should deploy', async () => {
        // the check is done inside beforeEach
        // blockchain and masterContract are ready to use
    });

    it('should deploy master', async () => {
        // create item contract
        const deployMasterResult = await masterContract.send(deployer.getSender(), { value: toNano("7") }, {
            $$type: "MintItem",
            total: toNano("1000"),
            owner: deployer.getSender().address,
            query_id: 0n
        });

        const tokensAddress = await masterContract.getGetItemAddress(masterContract.address, 1n);

        const seqnoAfterDeploy = await masterContract.getGetSeqno();

        console.log('master seqno after deploy', seqnoAfterDeploy);

        console.log('token address', tokensAddress);

        const tokensAddressByMap = await masterContract.getGetItemAddressFromMap(1n);

        console.log('token address by map', tokensAddressByMap);

        console.log("master is init", masterContract.init);

        const item = blockchain.openContract(CoinContract.fromAddress(tokensAddress));

        const coinOwner = await item.getGetOwner();

        console.log('coin owner', coinOwner);
    });
});

Deployer balance does not change on deploying contract (Test)

    beforeEach(async () => {
        let blockchain = await Blockchain.create();

        let main = blockchain.openContract(await Main.fromInit(0n));

        let deployer = await blockchain.treasury('deployer');

        const deployResult = await main.send(
            deployer.getSender(),
            {
                value: toNano('10'),
            },
            {
                $$type: 'Deploy',
                queryId: 0n,
            }
        );

        expect(deployResult.transactions).toHaveTransaction({
            from: deployer.address,
            to: main.address,
            deploy: true,
            success: true,
        });

        console.log('Deployer Balance', fromNano(await deployer.getBalance()));
    });

I expect the deployer balance being reduced by 10 TONs (The value of deploy message). but it is not reducing the deployer's balance neither increasing the contract's balance!!

Deployment fee is not included in totalFees

When I try to deploy a child contract from a parent, the deployment fee is not returned in totalFees of the transaction. It looks like it only considers gas fees for processing the message, and not the gas fee required for providing stateInit and its deployment. Ideally, totalFees should include deployment fees, and maybe a separate field can be used for gas fees.

In my tests, I try to calculate the balance of parent smart contract, after deploying a new child, but since deployment cost is not considered in totalFees, I have to compromise and use an approximation.

Add ability to assert on exit codes and transaction success

Is your feature request related to a problem? Please describe.
Some tests expect a failure with a specific exit code.
Currently it seems that for:

  1. External -> an error with no details about exit code is thrown
  2. Internal -> no error is raised, exit code is contained in the transactions array in the result

Describe the solution you'd like

  • Ideally, external and internal should behave the same
  • Exit code should be returned in both cases (currently for internal messages it would be that of the 2nd message in transactions because the first one is the external message).
  • There should be test matchers to set expectations on exit codes

Describe alternatives you've considered

Additional context

Single-line load_ref

If you put two ~load_ref in func on the same line, it will read refs from the end. In the sandbox, everything works logically correct, reading from left to right, but it creates a difference in results with the blockchain

Bounced messages have no body

When a message is bounced from a smart contract, it doesn't have any body. I expect to see 0xFFFFFFFF plus the first 256 bits of the original body as specified in:
https://ton.org/docs/develop/smart-contracts/guidelines/processing
or
https://ton.org/docs/develop/smart-contracts/guidelines/non-bouncable-messages

Currently I see something like this in the bounced message:

      {
        from: EQBnBlCAuvnW5Vwb_msWN24xHQM68DO5kFSpmzV7rUDcmISC,
        to: Ef-fE9ukteSTIxM1y2DdcW2Thlq2kVwb6HSY0ketaGqGqlub,
        value: 901775000n,
        body: x{},
        initData: undefined,
        initCode: undefined,
        deploy: false,
        lt: 8000000n,
        now: 1676979972,
        outMessagesCount: 0,
        oldStatus: 'active',
        endStatus: 'active',
        totalFees: 17700000n,
        aborted: true,
        destroyed: false,
        exitCode: 9,
        success: false
      }

The reason for exit code 9 here is that I was trying to read from the body, which was unexpectedly empty.

Allow debug logs to be queried programatically

Is your feature request related to a problem? Please describe.
I have a contract with debug logs (strdump and dump). Right now the only way to consume the logs is by looking at them since they are printed with console.warn. It will be useful to consume them programatically too so we can set expectations on them in tests.

Describe the solution you'd like
Maybe add logs to the result object where we get the transactions after making some action.

Maybe we should support this for all logs, not just debug ones.

Open contract after a transaction that creates a new contract

I've created a parent/child contract, something like the Jetton fungible tokens. Now, to test it, I've created a wrapper for Parent and another for Child. In my tests, I've opened the parent contract with openContract and after sending it a message, now I want to call a getter function on the Child (written in wrapper). How should I do it?

If I try to call openContract with a Child.createFromAddress, it creates a new empty uninitialized contract.

I expect to be able to open the child contract using openContract. Am I missing something here?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.