runtimeverification / runtimeverification/komet

Constructor Support

Open
#89 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
WebAssembly
Stars
35
Forks
3
PR merge metrics
No merged PRs in 30d

Description

How can I use komet on a contract that has a __constructor fn?

I'm eager to use komet on my contract, which has a couple of properties that I could verify. Before I'm able to do that, I need to initialize the contract properly. Right now, the hurdle I can't seem to get past is that the contract has a constructor, and any test will fail if the constructor isn't first called by the host.

The constructor just takes three addresses as arguments:

#[contractimpl]
impl SinkContract {
    pub fn __constructor(env: Env, admin: Address, carbon_id: Address, carbonsink_id: Address) {
        env.storage().instance().set(&DataKey::Admin, &admin);
        env.storage().instance().set(&DataKey::CarbonID, &carbon_id);
        env.storage().instance().set(&DataKey::CarbonSinkID, &carbonsink_id);
        env.storage().instance().set(&DataKey::IsActive, &true);
        env.storage().instance().set(&DataKey::SinkMinimum, &1_000_000_i64);  // 100 kg
    }
    ...
}

I can't use testutils to initialize the contract as I normally do in my test suite. The only alternative I'm aware of, is to use the env.deployer() method.

#[contractimpl]
impl TestAdderContract {
    pub fn init(env: Env, wasm_hash: Bytes) {
        let sink_bytes = b"sink_ctr________________________";
        let sink_addr = komet::create_contract(&env, &Bytes::from_array(&env, sink_bytes), &wasm_hash);
        env.storage().instance().set(&DataKey::SinkID, &sink_addr);

        let admin_bytes = b"GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJXFF";
        let admin_addr = komet::address_from_bytes(&env, admin_bytes, false);
        env.storage().instance().set(&DataKey::Admin, &admin_addr);
        let carbon_bytes = b"CCABDO7UZXYE4W6GVSEGSNNZTKSLFQGKXXQTH6OX7M7GKZ4Z6CUJNGZN";
        let carbon_addr = komet::address_from_bytes(&env, carbon_bytes, true);
        env.storage().instance().set(&DataKey::CarbonID, &carbon_addr);
        let csink_bytes = b"CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG";
        let csink_addr = komet::address_from_bytes(&env, csink_bytes, true);
        env.storage().instance().set(&DataKey::CarbonSinkID, &csink_addr);

        let salt = BytesN::from_array(&env, &[0; 32]);
        let constructor_args: Vec<Val> = (admin_addr, carbon_addr, csink_addr).into_val(&env);
        let deployed_address = env
            .deployer()
            .with_address(env.current_contract_address(), salt)
            .deploy_v2(
                BytesN::<32>::from_array(&env, &wasm_hash.try_into().expect("wasm_hash must be 32 bytes")), 
                constructor_args
            );
    }
    ...
}

That crashes kasmer, unfortunately:

  File "/nix/store/wx8w33vpms3jjx7dxc6l6f1afs6y2iz0-python3.10-komet-0.1.71/lib/python3.10/site-packages/komet/kasmer.py", line 217, in deploy_test
    assert proc_res.returncode == 0
AssertionError

For more context, including the contract I want to test and my usual test setup, please see this branch:
https://github.com/stellarcarbon/sorocarbon/tree/komet

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read kasmer.py around deploy_test at line 217 and the contract deployment path using env.deployer() and deploy_v2; compare it with the testutils setup described in the issue. Done means a contract with __constructor arguments can be deployed for tests without kasmer crashing, with the constructor invoked before test execution.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, rust, wasm
Domain
blockchain, testing
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.