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

Ndev 3380 compasability for iterative trx #456

Open
wants to merge 22 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d7b8a00
added iterative tests for compasibility
kristinaNikolaevaa Nov 21, 2024
2b4b2d4
added proxy tests
kristinaNikolaevaa Nov 21, 2024
09f7fac
Merge branch 'develop' into NDEV-3380
kristinaNikolaevaa Nov 25, 2024
aeeb02a
added one more test for evm
kristinaNikolaevaa Nov 27, 2024
99ffd1e
Merge branch 'develop' into NDEV-3380
kristinaNikolaevaa Dec 11, 2024
76ecb68
fix test_step_from_instruction_for_counter: use holder account with f…
romanova-natasha Dec 12, 2024
817e0d9
fix iterative transaction tests: reduce iteration lenght
romanova-natasha Dec 12, 2024
327b649
Merge branch 'develop' into NDEV-3380
kristinaNikolaevaa Dec 12, 2024
1b4e143
fix: new holder account for all interoperability tests
romanova-natasha Dec 12, 2024
d19510e
add composability test cases: iterative actions + solana call/calls, …
romanova-natasha Dec 13, 2024
834d901
fix deploy contract and solana call test
romanova-natasha Dec 13, 2024
104b7a0
rm tests with no iterative txs check
romanova-natasha Dec 13, 2024
01e2828
check holder account state after tx execution
romanova-natasha Dec 13, 2024
53c473c
rename test test_solana_call_before_iterative_actions
romanova-natasha Dec 13, 2024
8b95fbb
add case: eip 1559 iterative tx check with program_id = transfer_toke…
romanova-natasha Dec 17, 2024
05d9542
add case: failed solana call
romanova-natasha Dec 17, 2024
1604cab
add case: iterative tx with solana call in sol network
romanova-natasha Dec 17, 2024
0392e6a
rm dbg info
romanova-natasha Dec 18, 2024
92ddd80
add case: iterative tx with send tokens
romanova-natasha Dec 19, 2024
0ad085e
add case of solana call with 2 programs, minor refactoring
romanova-natasha Dec 19, 2024
ab96edc
fix review
romanova-natasha Dec 19, 2024
4e9f1ab
NDEV-3380 change tests order for tests test_iterative_actions_and_mul…
artem-yazkov Dec 23, 2024
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
51 changes: 48 additions & 3 deletions contracts/precompiled/CallSolanaCaller.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,18 @@ pragma solidity >=0.7.0 <0.9.0;
pragma abicoder v2;

import "../external/neon-evm/call_solana.sol";
import "../common/StorageSoliditySource.sol";


contract CallSolanaCaller {

CallSolana constant _callSolana = CallSolana(0xFF00000000000000000000000000000000000006);
struct Data {
uint256 value1;
uint256 value2;
}
mapping(uint256 => Data) public dataMap;

struct ExecuteArgs {
uint64 lamports;
bytes instruction;
Expand All @@ -17,7 +24,6 @@ contract CallSolanaCaller {
bytes instruction;
}


event LogBytes(bytes32 value);
event LogStr(string value);
event LogData(bytes32 program, bytes value);
Expand All @@ -28,9 +34,48 @@ contract CallSolanaCaller {
}

function execute(uint64 lamports, bytes calldata instruction) public {
bytes32 returnData = bytes32(_callSolana.execute(lamports, instruction));
emit LogBytes(returnData);
bytes32 returnData = bytes32(_callSolana.execute(lamports, instruction));
emit LogBytes(returnData);
}

function executeInIterativeMode(uint256 iterations, uint64 lamports, bytes calldata instruction) public {
doIterativeActions(iterations);
execute(lamports, instruction);
}

function executeAndDoSomeIterativeActions(uint256 iterations, uint64 lamports, bytes calldata instruction) public {
execute(lamports, instruction);
doIterativeActions(iterations);
}

function executeMultipleCallsAndDoIterativeActions(uint256 calls, uint256 iterations, uint64 lamports, bytes calldata instruction) public {
romanova-natasha marked this conversation as resolved.
Show resolved Hide resolved
for (uint256 i = 0; i < calls; i++) {
execute(lamports, instruction);
}

doIterativeActions(iterations);
}

function doSomeIterativeActions(uint256 iterations) public {
doIterativeActions(iterations);
emit LogStr("iterative actions status: done");
}

function doIterativeActions(uint iterations) public {
// some actions to make the call iterative
for (uint256 i = 0; i < iterations; i++) {
Data memory newData = Data({
value1: 1,
value2: 2
});
dataMap[i] = newData;
}
}

function deployStorageAndCallSolana(string memory message, uint64 lamports, bytes calldata instruction) public {
Storage storageContract = new Storage();
execute(lamports, instruction);
emit LogStr(message);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is better to return storageContract address and try to call it in the test or at least to check that address exist and contains some code

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added call contract function and I return contract address

}

function execute_with_get_return_data(uint64 lamports, bytes calldata instruction) public {
Expand Down
185 changes: 184 additions & 1 deletion integration/tests/basic/evm/test_solana_interoperability.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import typing as tp
import web3.exceptions

import pytest
import spl
Expand Down Expand Up @@ -290,7 +291,7 @@ def test_limit_of_simple_instr_in_one_trx(self, call_solana_caller, counter_reso

for _ in range(24):
instruction = Instruction(
program_id=COUNTER_ID,
program_id=COUNTER_ID,
accounts=[
AccountMeta(Pubkey(counter_resource_address), is_signer=False, is_writable=True),
],
Expand All @@ -303,3 +304,185 @@ def test_limit_of_simple_instr_in_one_trx(self, call_solana_caller, counter_reso
instruction_tx = call_solana_caller.functions.batchExecute(call_params).build_transaction(tx)
resp = self.web3_client.send_transaction(sender, instruction_tx)
assert resp["status"] == 0

@pytest.mark.parametrize("iterations_number", [29, 52])
romanova-natasha marked this conversation as resolved.
Show resolved Hide resolved
def test_solana_call_after_iterative_actions(self, iterations_number, counter_resource_address, call_solana_caller, get_counter_value):
sender = self.accounts[0]
lamports = 0

instruction = Instruction(
program_id=COUNTER_ID,
accounts=[
AccountMeta(Pubkey(counter_resource_address), is_signer=False, is_writable=True),
],
data=bytes([0x1]),
)
serialized = serialize_instruction(COUNTER_ID, instruction)

tx = self.web3_client.make_raw_tx(sender.address)
instruction_tx = call_solana_caller.functions.executeInIterativeMode(iterations_number, lamports, serialized).build_transaction(tx)
resp = self.web3_client.send_transaction(sender, instruction_tx)
assert resp["status"] == 1
event_logs = call_solana_caller.events.LogBytes().process_receipt(resp)
assert int.from_bytes(event_logs[0].args.value, byteorder="little") == next(get_counter_value)

def test_solana_call_after_iterative_actions_exceed_accounts_limit(self, counter_resource_address, call_solana_caller):
iterations = 53
sender = self.accounts[0]
lamports = 0

instruction = Instruction(
program_id=COUNTER_ID,
accounts=[
AccountMeta(Pubkey(counter_resource_address), is_signer=False, is_writable=True),
],
data=bytes([0x1]),
)
serialized = serialize_instruction(COUNTER_ID, instruction)

tx = self.web3_client.make_raw_tx(sender.address)

with pytest.raises(
web3.exceptions.ContractLogicError,
match="too many accounts: 65 > 64",
):
call_solana_caller.functions.executeInIterativeMode(iterations, lamports, serialized).build_transaction(tx)

@pytest.mark.parametrize("iterations_number", [40, 55])
def test_iterative_actions_no_solana_call(self, iterations_number, call_solana_caller):
romanova-natasha marked this conversation as resolved.
Show resolved Hide resolved
sender = self.accounts[0]

tx = self.web3_client.make_raw_tx(sender.address)
instruction_tx = call_solana_caller.functions.doSomeIterativeActions(iterations_number).build_transaction(tx)

resp = self.web3_client.send_transaction(sender, instruction_tx)
assert resp["status"] == 1

event_logs = call_solana_caller.events.LogStr().process_receipt(resp)
assert event_logs[0].args.value == "iterative actions status: done"

def test_iterative_actions_no_solana_call_exceed_accounts_limit(self, call_solana_caller):
sender = self.accounts[0]
tx = self.web3_client.make_raw_tx(sender.address)

with pytest.raises(
web3.exceptions.ContractLogicError,
match="too many accounts: 65 > 64",
):
call_solana_caller.functions.doSomeIterativeActions(56).build_transaction(tx)

@pytest.mark.parametrize("iterations_number", [29, 52])
def test_iterative_actions_after_solana_call(self, iterations_number, counter_resource_address, call_solana_caller, get_counter_value):
sender = self.accounts[0]
lamports = 0

instruction = Instruction(
program_id=COUNTER_ID,
accounts=[
AccountMeta(Pubkey(counter_resource_address), is_signer=False, is_writable=True),
],
data=bytes([0x1]),
)
serialized = serialize_instruction(COUNTER_ID, instruction)

tx = self.web3_client.make_raw_tx(sender.address)
instruction_tx = call_solana_caller.functions.executeAndDoSomeIterativeActions(iterations_number,
lamports,
serialized).build_transaction(tx)
resp = self.web3_client.send_transaction(sender, instruction_tx)
assert resp["status"] == 1
event_logs = call_solana_caller.events.LogBytes().process_receipt(resp)
assert int.from_bytes(event_logs[0].args.value, byteorder="little") == next(get_counter_value)

def test_iterative_actions_after_solana_call_exceed_accounts_limit(self, counter_resource_address, call_solana_caller, get_counter_value):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test can be deleted
iterative actions after solana call can't be called at all

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is working now and idk why, I asked the core team about this and wait for their response

iterations = 53
sender = self.accounts[0]
lamports = 0

instruction = Instruction(
program_id=COUNTER_ID,
accounts=[
AccountMeta(Pubkey(counter_resource_address), is_signer=False, is_writable=True),
],
data=bytes([0x1]),
)
serialized = serialize_instruction(COUNTER_ID, instruction)

tx = self.web3_client.make_raw_tx(sender.address)

with pytest.raises(
web3.exceptions.ContractLogicError,
match="too many accounts: 65 > 64",
):
call_solana_caller.functions.executeAndDoSomeIterativeActions(iterations, lamports, serialized).build_transaction(tx)

def test_multiple_solana_calls_and_iterative_actions(self, counter_resource_address, call_solana_caller, get_counter_value):
solana_calls = 5
iterations = 20
sender = self.accounts[0]
lamports = 0

instruction = Instruction(
program_id=COUNTER_ID,
accounts=[
AccountMeta(Pubkey(counter_resource_address), is_signer=False, is_writable=True),
],
data=bytes([0x1]),
)
serialized = serialize_instruction(COUNTER_ID, instruction)

tx = self.web3_client.make_raw_tx(sender.address)
instruction_tx = call_solana_caller.functions.executeMultipleCallsAndDoIterativeActions(solana_calls,
iterations,
lamports,
serialized).build_transaction(tx)
resp = self.web3_client.send_transaction(sender, instruction_tx)
assert resp["status"] == 1
event_logs = call_solana_caller.events.LogBytes().process_receipt(resp)
assert int.from_bytes(event_logs[0].args.value, byteorder="little") == next(get_counter_value)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what the value of next(get_counter_value) here? I think it should be = solana_calls

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed: I check a number of logged solana calls now


def test_multiple_solana_calls_and_iterative_actions_instructions_limit(self, counter_resource_address, call_solana_caller, get_counter_value):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't need this test
the same as with 1 call

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was an issue, where the instruction limit test had failed for an iterative transaction only. I kept this test to check the issue is fixed, and I still want to keep it. What do you think?

solana_calls = 15
iterations = 40
sender = self.accounts[0]
lamports = 0

instruction = Instruction(
program_id=COUNTER_ID,
accounts=[
AccountMeta(Pubkey(counter_resource_address), is_signer=False, is_writable=True),
],
data=bytes([0x1]),
)
serialized = serialize_instruction(COUNTER_ID, instruction)

tx = self.web3_client.make_raw_tx(sender.address)
instruction_tx = call_solana_caller.functions.executeMultipleCallsAndDoIterativeActions(solana_calls,
iterations,
lamports,
serialized).build_transaction(tx)
resp = self.web3_client.send_transaction(sender, instruction_tx)
assert resp["status"] == 0

def test_deploy_contract_and_call_solana(self, counter_resource_address, call_solana_caller):
sender = self.accounts[0]
lamports = 0

instruction = Instruction(
program_id=COUNTER_ID,
accounts=[
AccountMeta(Pubkey(counter_resource_address), is_signer=False, is_writable=True),
],
data=bytes([0x1]),
)
serialized = serialize_instruction(COUNTER_ID, instruction)

tx = self.web3_client.make_raw_tx(sender.address)
instruction_tx = call_solana_caller.functions.deployStorageAndCallSolana("deploy contracts status: done",
lamports,
serialized).build_transaction(tx)
resp = self.web3_client.send_transaction(sender, instruction_tx)
assert resp["status"] == 1

event_logs = call_solana_caller.events.LogStr().process_receipt(resp)
assert event_logs[0].args.value == "deploy contracts status: done"
Loading
Loading