Skip to content

Support all transaction types in Relayer #907

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

Open
wants to merge 1 commit into
base: relayer-and-pure-tokens
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion academy/lending-protocol/contracts/LendingPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ contract LendingPool is NilBase, NilTokenBase, NilAwaitable {

/// @notice Deposit function to deposit tokens into the lending pool.
/// @dev The deposited tokens are recorded in the GlobalLedger via an asynchronous call.
function deposit() public payable {
function deposit() public payable async(2_000_000) {
/// Retrieve the tokens being sent in the transaction
Nil.Token[] memory tokens = Nil.txnTokens();

Expand Down
2 changes: 1 addition & 1 deletion create-nil-hardhat-project/contracts/Caller.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import "@nilfoundation/smart-contracts/contracts/Nil.sol";
contract Caller {
using Nil for address;

function call(address dst) public {
function call(address dst) public async(500_000) {
Nil.asyncCall(
dst,
msg.sender,
Expand Down
2 changes: 1 addition & 1 deletion docs/tests/Caller.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ contract Caller {

receive() external payable {}

function call(address dst) public {
function call(address dst) public async(2_000_000) {
Nil.asyncCall(
dst,
msg.sender,
Expand Down
2 changes: 1 addition & 1 deletion docs/tests/CallerAsync.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ contract CallerAsync {

event CallCompleted(address indexed dst);

function call(address dst) public payable {
function call(address dst) public payable async(2_000_000) {
dst.asyncCall(
address(0),
msg.value,
Expand Down
2 changes: 1 addition & 1 deletion docs/tests/CallerCounter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ contract Caller {

receive() external payable {}

function call(address dst) public {
function call(address dst) public async(2_000_000) {
Nil.asyncCall(
dst,
msg.sender,
Expand Down
2 changes: 1 addition & 1 deletion docs/tests/CheckEffectsInteraction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ contract CheckEffectsInteraction is NilBase, NilAwaitable {
//startBadCheckEffectsInteraction
mapping(address => uint) balances;

function badCheckEffectsInteraction(address dst, uint amount) public {
function badCheckEffectsInteraction(address dst, uint amount) public async(2_000_000) {
require(balances[msg.sender] >= amount);

balances[msg.sender] -= amount;
Expand Down
4 changes: 2 additions & 2 deletions docs/tests/EnglishAuction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ contract EnglishAuction is Ownable {
* @notice This function starts the auction and sends a transaction
* for minting the NFT.
*/
function start() public onlyOwner {
function start() public onlyOwner async(2_000_000) {
require(!isOngoing, "the auction has already started");

Nil.asyncCall(
Expand Down Expand Up @@ -93,7 +93,7 @@ contract EnglishAuction is Ownable {
* @notice This function exists so a bidder can withdraw their funds
* if they change their mind.
*/
function withdraw() public {
function withdraw() public async(2_000_000) {
uint256 bal = bids[msg.sender];
bids[msg.sender] = 0;

Expand Down
2 changes: 1 addition & 1 deletion nil/cmd/nil_block_generator/internal/commands/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func CallContract(rpcEndpoint, smartAccountAdr, hexKey string, calls []Call, log
}

amount := types.Value0
fee := types.NewFeePackFromGas(100_000)
fee := types.NewFeePackFromGas(500_000)

ctx := context.Background()
client := GetRpcClient(rpcEndpoint, logger)
Expand Down
4 changes: 2 additions & 2 deletions nil/contracts/solidity/tests/BounceTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ contract BounceTest is NilBounceable {

constructor() payable {}

function call(address dst, int32 val) public payable {
function call(address dst, int32 val) public payable async(2_000_000) {
dst.asyncCall(
address(0), // refundTo
address(0), // bounceTo
Expand All @@ -43,7 +43,7 @@ contract BounceTest is NilBounceable {
uint8 forwardKind,
uint value,
bytes memory callData
) public payable {
) public payable async(2_000_000) {
Nil.asyncCall(dst, refundTo, bounceTo, feeCredit, forwardKind, value, callData);
}

Expand Down
2 changes: 1 addition & 1 deletion nil/contracts/solidity/tests/Deployment.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ contract Deployer is NilTokenBase {

constructor() payable {}

function deploy(uint shardId, uint32 _a, uint salt, uint value) public {
function deploy(uint shardId, uint32 _a, uint salt, uint value) public async(1_000_000) {
bytes memory data = bytes.concat(type(Deployee).creationCode, abi.encode(address(this), _a));
deployee = Nil.asyncDeploy(shardId, address(this), value, data, salt);
}
Expand Down
20 changes: 10 additions & 10 deletions nil/contracts/solidity/tests/RequestResponseTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ contract RequestResponseTest is NilTokenBase, NilAwaitable {
address counter,
uint intContext,
string memory strContext
) public {
) public async (500_000) {
bytes memory context = abi.encode(intContext, strContext);
bytes memory callData = abi.encodeWithSignature("get()");
sendRequest(
Expand Down Expand Up @@ -69,7 +69,7 @@ contract RequestResponseTest is NilTokenBase, NilAwaitable {
function nestedRequest(
address callee,
address counter
) public {
) public async (500_000) {
bytes memory callData = abi.encodeWithSelector(this.requestCounterGet.selector, counter, 123, "test");
sendRequest(
callee,
Expand All @@ -95,7 +95,7 @@ contract RequestResponseTest is NilTokenBase, NilAwaitable {
*/
function sendRequestFromCallback(
address counter
) public {
) public async (500_000) {
bytes memory context = abi.encode(int32(5), counter);
bytes memory callData = abi.encodeWithSignature("add(int32)", 5);
sendRequest(
Expand All @@ -112,7 +112,7 @@ contract RequestResponseTest is NilTokenBase, NilAwaitable {
bool success,
bytes memory,
bytes memory context
) public {
) public async (500_000) {
require(success, "Request failed");
(int32 sendNext, address counter) = abi.decode(context, (int32, address));
if (sendNext == 0) {
Expand All @@ -136,7 +136,7 @@ contract RequestResponseTest is NilTokenBase, NilAwaitable {
/**
* Test Counter's add method. No context and empty return data.
*/
function requestCounterAdd(address counter, int32 valueToAdd) public {
function requestCounterAdd(address counter, int32 valueToAdd) public async (500_000) {
bytes memory callData = abi.encodeWithSignature(
"add(int32)",
valueToAdd
Expand Down Expand Up @@ -164,7 +164,7 @@ contract RequestResponseTest is NilTokenBase, NilAwaitable {
/**
* Test failure with value.
*/
function requestCheckFail(address addr, bool fail) public {
function requestCheckFail(address addr, bool fail) public async (500_000) {
bytes memory context = abi.encode(uint(11111));
bytes memory callData = abi.encodeWithSignature(
"checkFail(bool)",
Expand Down Expand Up @@ -193,7 +193,7 @@ contract RequestResponseTest is NilTokenBase, NilAwaitable {
/**
* Test out of gas failure.
*/
function requestOutOfGasFailure(address counter) public {
function requestOutOfGasFailure(address counter) public async (500_000) {
bytes memory context = abi.encode(uint(1234567890));
bytes memory callData = abi.encodeWithSignature("outOfGasFailure()");
sendRequest(
Expand Down Expand Up @@ -229,7 +229,7 @@ contract RequestResponseTest is NilTokenBase, NilAwaitable {
/**
* Test token sending.
*/
function requestSendToken(address addr, uint256 amount) public {
function requestSendToken(address addr, uint256 amount) public async (500_000) {
bytes memory context = abi.encode(uint(11111));
bytes memory callData = abi.encodeWithSignature("get()");
Nil.Token[] memory tokens = new Nil.Token[](1);
Expand Down Expand Up @@ -260,7 +260,7 @@ contract RequestResponseTest is NilTokenBase, NilAwaitable {
/**
* Fail during request sending. Context storage should not be changed.
*/
function failDuringRequestSending(address counter) public {
function failDuringRequestSending(address counter) public async (500_000) {
bytes memory context = abi.encode(intValue, strValue);
bytes memory callData = abi.encodeWithSignature("get()");
sendRequest(
Expand All @@ -277,7 +277,7 @@ contract RequestResponseTest is NilTokenBase, NilAwaitable {
/**
* Test two consecutive requests.
*/
function makeTwoRequests(address addr1, address addr2) public {
function makeTwoRequests(address addr1, address addr2) public async (1_000_000) {
bytes memory callData = abi.encodeWithSignature("get()");
sendRequest(addr1, 0, Nil.ASYNC_REQUEST_MIN_GAS, "", callData, makeTwoRequestsResponse);
sendRequest(addr2, 0, Nil.ASYNC_REQUEST_MIN_GAS, "", callData, makeTwoRequestsResponse);
Expand Down
2 changes: 1 addition & 1 deletion nil/contracts/solidity/tests/Stresser.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ contract Stresser is NilAwaitable {
return start + n;
}

function asyncCalls(address[] memory addresses, uint256 n) public {
function asyncCalls(address[] memory addresses, uint256 n) public async(2_000_000) {
for (uint256 i = 0; i < addresses.length; i++) {
gasConsumer(n/addresses.length);
Nil.asyncCall(
Expand Down
8 changes: 5 additions & 3 deletions nil/contracts/solidity/tests/Test.sol
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,12 @@ contract Test is NilBase, NilAwaitable {
address refundTo;
bytes callData;
}
receive() external payable {}

function testForwarding(
uint256 asyncGas,
AsyncCallArgs[] memory transactions
) public payable {
) public payable async(asyncGas) {
for (uint i = 0; i < transactions.length; i++) {
AsyncCallArgs memory transaction = transactions[i];
Nil.asyncCall(
Expand All @@ -112,7 +114,7 @@ contract Test is NilBase, NilAwaitable {
uint feeCredit,
uint8 forwardKind,
bytes memory callData
) public payable {
) public payable async(1_000_000) {
Nil.asyncCall(dst, address(0), address(0), feeCredit, forwardKind, 0, callData);
}

Expand Down Expand Up @@ -147,7 +149,7 @@ contract Test is NilBase, NilAwaitable {
}

// Add output transaction, and then revert if `value` is zero. In that case output transaction should be removed.
function testFailedAsyncCall(address dst, int32 value) public onlyExternal {
function testFailedAsyncCall(address dst, int32 value) public onlyExternal async(1_000_000) {
Nil.asyncCall(
dst,
address(0),
Expand Down
2 changes: 1 addition & 1 deletion nil/contracts/solidity/tests/TokensTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ contract TokensTest is NilTokenBase {
function testCallWithTokensAsync(
address dst,
Nil.Token[] memory tokens
) public onlyExternal {
) public onlyExternal async (500_000) {
bytes memory callData = abi.encodeCall(
this.testTransactionTokens,
tokens
Expand Down
2 changes: 1 addition & 1 deletion nil/internal/collate/proposer.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (p *proposer) GenerateProposal(ctx context.Context, txFabric db.DB) (*execu
Block: prevBlock,
ConfigAccessor: configAccessor,
FeeCalculator: p.params.FeeCalculator,
Mode: execution.ModeProposal,
Mode: execution.ModeProposalGen,
})
if err != nil {
return nil, err
Expand Down
8 changes: 6 additions & 2 deletions nil/internal/collate/proposer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ func (s *ProposerTestSuite) TestBlockGas() {
func (s *ProposerTestSuite) TestCollator() {
to := contracts.CounterAddress(s.T(), s.shardId)

const asyncGass = 2_000_000

pool := &MockTxnPool{}
params := s.newParams()
p := newTestProposer(params, pool)
Expand Down Expand Up @@ -141,7 +143,8 @@ func (s *ProposerTestSuite) TestCollator() {
// Each transaction subtracts its value + actual gas used from the balance.
balance = balance.
Sub(txnValue).Sub(r1.GasUsed.ToValue(types.DefaultGasPrice)).Sub(r1.Forwarded).
Sub(txnValue).Sub(r2.GasUsed.ToValue(types.DefaultGasPrice)).Sub(r2.Forwarded)
Sub(txnValue).Sub(r2.GasUsed.ToValue(types.DefaultGasPrice)).Sub(r2.Forwarded).
Sub(types.GasToValue(asyncGass * 2))
s.Equal(balance, s.getMainBalance())
s.Equal(types.Value{}, s.getBalance(shardId, to))
})
Expand All @@ -168,7 +171,8 @@ func (s *ProposerTestSuite) TestCollator() {
// Two refund transactions
s.Len(proposal.InternalTxns, 2)

balance = balance.Add(r1.Forwarded).Add(r2.Forwarded)
balance = balance.Add(r1.Forwarded).Add(r2.Forwarded).Add(types.GasToValue(asyncGass * 2))

s.Equal(balance, s.getMainBalance())

s.checkSeqno(shardId)
Expand Down
28 changes: 20 additions & 8 deletions nil/internal/contracts/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,33 +236,45 @@ func GetFuncIdSignature(id uint32) (*Signature, error) {
return nil, fmt.Errorf("signature not found for id %x", id)
}

func DecodeCallData(method *abi.Method, calldata []byte) (string, error) {
func DecodeCallData(method *abi.Method, calldata []byte) (string, string, error) {
if len(calldata) == 0 {
return "", errors.New("empty calldata")
return "", "", errors.New("empty calldata")
}
if len(calldata) < 4 {
return "", fmt.Errorf("too short calldata: %d", len(calldata))
return "", "", fmt.Errorf("too short calldata: %d", len(calldata))
}

if method == nil {
sig, err := GetFuncIdSignatureFromBytes(calldata)
if err != nil {
return "", err
return "", "", err
}
abiContract, err := GetAbi(sig.Contracts[0])
if err != nil {
return "", fmt.Errorf("failed to get abi: %w", err)
return "", "", fmt.Errorf("failed to get abi: %w", err)
}
m, ok := abiContract.Methods[sig.FuncName]
if !ok {
return "", fmt.Errorf("method not found: %s", sig.FuncName)
return "", "", fmt.Errorf("method not found: %s", sig.FuncName)
}
method = &m
}

args, err := method.Inputs.Unpack(calldata[4:])
if err != nil {
return fmt.Sprintf("%s: failed to unpack arguments: %s", method.Name, err), nil
// We found method, but failed to unpack arguments. The user should be warned about it.
return fmt.Sprintf("%s: failed to unpack arguments: %s", method.Name, err), "", nil
}
var relayerData string
if method.Name == "receiveTx" {
data, ok := args[5].([]byte)
if !ok {
return "", "", fmt.Errorf("failed to cast relayer data: %v", args[5])
}
relayerData, _, err = DecodeCallData(nil, data)
if err != nil {
return "", "", fmt.Errorf("failed to decode relayer data: %w", err)
}
}
res := method.Name + "("
adjustArg := func(arg any) string {
Expand All @@ -282,5 +294,5 @@ func DecodeCallData(method *abi.Method, calldata []byte) (string, error) {
}
res += ")"

return res, nil
return res, relayerData, nil
}
10 changes: 5 additions & 5 deletions nil/internal/contracts/contract_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ func TestDecodeCallData(t *testing.T) {
saAbi, err := GetAbi(NameSmartAccount)
require.NoError(t, err)

data, err := saAbi.Pack("bounce", "test string")
data, err := saAbi.Pack("bounce", []byte("test string"))
require.NoError(t, err)

decoded, err := DecodeCallData(nil, data)
decoded, _, err := DecodeCallData(nil, data)
require.NoError(t, err)
require.Equal(t, "bounce(test string)", decoded)
require.Equal(t, "bounce(0x7465737420737472696e67)", decoded)
})

t.Run("tests/Test", func(t *testing.T) {
Expand All @@ -33,7 +33,7 @@ func TestDecodeCallData(t *testing.T) {
data, err := abi.Pack("emitLog", "test string", true)
require.NoError(t, err)

decoded, err := DecodeCallData(nil, data)
decoded, _, err := DecodeCallData(nil, data)
require.NoError(t, err)
require.Equal(t, "emitLog(test string, true)", decoded)
})
Expand All @@ -48,7 +48,7 @@ func TestDecodeCallData(t *testing.T) {
"setL1BlockInfo", uint64(1), uint64(2), big.NewInt(3), big.NewInt(4), [32]byte{1, 2, 3, 4})
require.NoError(t, err)

decoded, err := DecodeCallData(nil, data)
decoded, _, err := DecodeCallData(nil, data)
require.NoError(t, err)
require.Equal(t,
"setL1BlockInfo(1, 2, 3, 4, [1 2 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0])", decoded)
Expand Down
Loading
Loading