From 87bf74fecfe04cf753967a31e58861c4db1a8c8f Mon Sep 17 00:00:00 2001 From: skosito Date: Fri, 6 Dec 2024 18:29:40 +0000 Subject: [PATCH 1/2] fix: fix solana inbounds (#3255) --- e2e/e2etests/test_solana_deposit_call.go | 2 +- e2e/e2etests/test_spl_deposit_and_call.go | 2 +- e2e/runner/solana.go | 48 +++- e2e/utils/contracts.go | 23 ++ pkg/contracts/solana/gateway.go | 6 + pkg/contracts/solana/inbound.go | 132 ++++++++-- pkg/contracts/solana/inbound_test.go | 235 +++++++++++++++++- pkg/contracts/solana/instruction.go | 40 ++- ...EkFcvHx88ujq3xDnt3z7sZdZ21JK2FC7vPw1o.json | 98 ++++++++ ...PSACVkn13o7sw6Awob8EJnrwAuiKYqvi7ZkHa.json | 77 ++++++ ...gAj4HGULPEQExPKB231rMhm6666dQMwf9fNN.json} | 41 +-- ...KDtGDZBLp91oyF5eQyWdv6pEwW1vcitiB4px.json} | 48 ++-- testutil/contracts/Example.abi | 13 + testutil/contracts/Example.bin | 2 +- testutil/contracts/Example.go | 40 ++- testutil/contracts/Example.json | 15 +- testutil/contracts/Example.sol | 2 + .../chains/solana/observer/inbound_test.go | 13 +- ...inYyvyKseYM52q6i3EkotZdJuQomGGq5oxRYr.json | 102 ++++++++ ...axBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j.json | 64 ----- 20 files changed, 845 insertions(+), 158 deletions(-) create mode 100644 pkg/contracts/solana/testdata/22s5ERRRZmZXAuDMRdwUU33VnWZ7m8NHUZM6hyLH52JQPz5R7mXEkFcvHx88ujq3xDnt3z7sZdZ21JK2FC7vPw1o.json create mode 100644 pkg/contracts/solana/testdata/5b7ShhHf8dvUjUBHgMvgH8FFqpfAd7vAGygZLaeNPhugXtY5fatPSACVkn13o7sw6Awob8EJnrwAuiKYqvi7ZkHa.json rename pkg/contracts/solana/testdata/{aY8yLDze6nHSRi7L5REozKAZY1aAyPJ6TfibiqQL5JGwgSBkYux5z5JfXs5ed8LZqpXUy4VijoU3x15mBd66ZGE.json => 5bXSQaq6BY1WhhF3Qm4pLHXxuyM9Mz1MrdMeoCFbimxw4uv11raQgAj4HGULPEQExPKB231rMhm6666dQMwf9fNN.json} (66%) rename pkg/contracts/solana/testdata/{MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j.json => 8UeJoxY6RbMg6bffsUtZ9f79vSnd4HCRdk5EQgNbAEDYQWXNraiKDtGDZBLp91oyF5eQyWdv6pEwW1vcitiB4px.json} (50%) create mode 100644 zetaclient/testdata/solana/chain_901_inbound_tx_result_24GzWsxYCFcwwJ2rzAsWwWC85aYKot6Rz3jWnBP1GvoAg5A9f1WinYyvyKseYM52q6i3EkotZdJuQomGGq5oxRYr.json delete mode 100644 zetaclient/testdata/solana/chain_901_inbound_tx_result_MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j.json diff --git a/e2e/e2etests/test_solana_deposit_call.go b/e2e/e2etests/test_solana_deposit_call.go index 2692936a9e..0d7ef97975 100644 --- a/e2e/e2etests/test_solana_deposit_call.go +++ b/e2e/e2etests/test_solana_deposit_call.go @@ -31,5 +31,5 @@ func TestSolanaDepositAndCall(r *runner.E2ERunner, args []string) { utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined) // check if example contract has been called, bar value should be set to amount - utils.MustHaveCalledExampleContract(r, contract, depositAmount) + utils.MustHaveCalledExampleContractWithMsg(r, contract, depositAmount, data) } diff --git a/e2e/e2etests/test_spl_deposit_and_call.go b/e2e/e2etests/test_spl_deposit_and_call.go index d7e11cd999..9c15c8c27f 100644 --- a/e2e/e2etests/test_spl_deposit_and_call.go +++ b/e2e/e2etests/test_spl_deposit_and_call.go @@ -51,7 +51,7 @@ func TestSPLDepositAndCall(r *runner.E2ERunner, args []string) { utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined) // check if example contract has been called, bar value should be set to amount - utils.MustHaveCalledExampleContract(r, contract, big.NewInt(int64(amount))) + utils.MustHaveCalledExampleContractWithMsg(r, contract, big.NewInt(int64(amount)), data) // verify balances are updated pdaBalanceAfter, err := r.SolanaClient.GetTokenAccountBalance(r.Ctx, pdaAta, rpc.CommitmentFinalized) diff --git a/e2e/runner/solana.go b/e2e/runner/solana.go index bc940db79f..cc9e6dbe2b 100644 --- a/e2e/runner/solana.go +++ b/e2e/runner/solana.go @@ -36,12 +36,24 @@ func (r *E2ERunner) CreateDepositInstruction( data []byte, amount uint64, ) solana.Instruction { - depositData, err := borsh.Serialize(solanacontract.DepositInstructionParams{ - Discriminator: solanacontract.DiscriminatorDeposit, - Amount: amount, - Memo: append(receiver.Bytes(), data...), - }) - require.NoError(r, err) + var err error + var depositData []byte + if data == nil { + depositData, err = borsh.Serialize(solanacontract.DepositInstructionParams{ + Discriminator: solanacontract.DiscriminatorDeposit, + Amount: amount, + Receiver: receiver, + }) + require.NoError(r, err) + } else { + depositData, err = borsh.Serialize(solanacontract.DepositAndCallInstructionParams{ + Discriminator: solanacontract.DiscriminatorDepositAndCall, + Amount: amount, + Receiver: receiver, + Memo: data, + }) + require.NoError(r, err) + } return &solana.GenericInstruction{ ProgID: r.GatewayProgram, @@ -87,12 +99,24 @@ func (r *E2ERunner) CreateDepositSPLInstruction( receiver ethcommon.Address, data []byte, ) solana.Instruction { - depositSPLData, err := borsh.Serialize(solanacontract.DepositInstructionParams{ - Discriminator: solanacontract.DiscriminatorDepositSPL, - Amount: amount, - Memo: append(receiver.Bytes(), data...), - }) - require.NoError(r, err) + var err error + var depositSPLData []byte + if data == nil { + depositSPLData, err = borsh.Serialize(solanacontract.DepositSPLInstructionParams{ + Discriminator: solanacontract.DiscriminatorDepositSPL, + Amount: amount, + Receiver: receiver, + }) + require.NoError(r, err) + } else { + depositSPLData, err = borsh.Serialize(solanacontract.DepositSPLAndCallInstructionParams{ + Discriminator: solanacontract.DiscriminatorDepositSPLAndCall, + Amount: amount, + Receiver: receiver, + Memo: data, + }) + require.NoError(r, err) + } return &solana.GenericInstruction{ ProgID: r.GatewayProgram, diff --git a/e2e/utils/contracts.go b/e2e/utils/contracts.go index 7593253725..8953584b28 100644 --- a/e2e/utils/contracts.go +++ b/e2e/utils/contracts.go @@ -31,3 +31,26 @@ func MustHaveCalledExampleContract( amount.String(), ) } + +// MustHaveCalledExampleContractWithMsg checks if the contract has been called correctly with correct amount and msg +func MustHaveCalledExampleContractWithMsg( + t require.TestingT, + contract *testcontract.Example, + amount *big.Int, + msg []byte, +) { + bar, err := contract.Bar(&bind.CallOpts{}) + require.NoError(t, err) + require.Equal( + t, + 0, + bar.Cmp(amount), + "cross-chain call failed bar value %s should be equal to amount %s", + bar.String(), + amount.String(), + ) + + lastMsg, err := contract.LastMessage(&bind.CallOpts{}) + require.NoError(t, err) + require.Equal(t, string(msg), string(lastMsg)) +} diff --git a/pkg/contracts/solana/gateway.go b/pkg/contracts/solana/gateway.go index c1b859cd33..29d547d374 100644 --- a/pkg/contracts/solana/gateway.go +++ b/pkg/contracts/solana/gateway.go @@ -27,9 +27,15 @@ var ( // DiscriminatorDeposit returns the discriminator for Solana gateway 'deposit' instruction DiscriminatorDeposit = idlgateway.IDLGateway.GetDiscriminator("deposit") + // DiscriminatorDeposit returns the discriminator for Solana gateway 'deposit_and_call' instruction + DiscriminatorDepositAndCall = idlgateway.IDLGateway.GetDiscriminator("deposit_and_call") + // DiscriminatorDepositSPL returns the discriminator for Solana gateway 'deposit_spl_token' instruction DiscriminatorDepositSPL = idlgateway.IDLGateway.GetDiscriminator("deposit_spl_token") + // DiscriminatorDepositSPLAndCall returns the discriminator for Solana gateway 'deposit_spl_token_and_call' instruction + DiscriminatorDepositSPLAndCall = idlgateway.IDLGateway.GetDiscriminator("deposit_spl_token_and_call") + // DiscriminatorWithdraw returns the discriminator for Solana gateway 'withdraw' instruction DiscriminatorWithdraw = idlgateway.IDLGateway.GetDiscriminator("withdraw") diff --git a/pkg/contracts/solana/inbound.go b/pkg/contracts/solana/inbound.go index 3b2e153606..1ab4543694 100644 --- a/pkg/contracts/solana/inbound.go +++ b/pkg/contracts/solana/inbound.go @@ -20,18 +20,33 @@ type Deposit struct { Asset string } -// ParseInboundAsDeposit tries to parse an instruction as a 'deposit'. -// It returns nil if the instruction can't be parsed as a 'deposit'. +// ParseInboundAsDeposit tries to parse an instruction as a 'deposit' or 'deposit_and_call'. +// It returns nil if the instruction can't be parsed. func ParseInboundAsDeposit( tx *solana.Transaction, instructionIndex int, slot uint64, +) (*Deposit, error) { + // first try to parse as deposit, then as deposit_and_call + deposit, err := tryParseAsDeposit(tx, instructionIndex, slot) + if err != nil || deposit != nil { + return deposit, err + } + + return tryParseAsDepositAndCall(tx, instructionIndex, slot) +} + +// tryParseAsDeposit tries to parse instruction as deposit +func tryParseAsDeposit( + tx *solana.Transaction, + instructionIndex int, + slot uint64, ) (*Deposit, error) { // get instruction by index instruction := tx.Message.Instructions[instructionIndex] - // try deserializing instruction as a 'deposit' - var inst DepositInstructionParams + // try deserializing instruction as a deposit + inst := DepositInstructionParams{} err := borsh.Deserialize(&inst, instruction.Data) if err != nil { return nil, nil @@ -51,30 +66,80 @@ func ParseInboundAsDeposit( return &Deposit{ Sender: sender, Amount: inst.Amount, - Memo: inst.Memo, + Memo: inst.Receiver[:], + Slot: slot, + Asset: "", // no asset for gas token SOL + }, nil +} + +// tryParseAsDepositAndCall tries to parse instruction as deposit_and_call +func tryParseAsDepositAndCall( + tx *solana.Transaction, + instructionIndex int, + slot uint64, +) (*Deposit, error) { + // get instruction by index + instruction := tx.Message.Instructions[instructionIndex] + + // try deserializing instruction as a deposit_and_call + instDepositAndCall := DepositAndCallInstructionParams{} + err := borsh.Deserialize(&instDepositAndCall, instruction.Data) + if err != nil { + return nil, nil + } + + // check if the instruction is a deposit_and_call or not, if not, skip parsing + if instDepositAndCall.Discriminator != DiscriminatorDepositAndCall { + return nil, nil + } + + // get the sender address (skip if unable to parse signer address) + sender, err := getSignerDeposit(tx, &instruction) + if err != nil { + return nil, err + } + return &Deposit{ + Sender: sender, + Amount: instDepositAndCall.Amount, + Memo: append(instDepositAndCall.Receiver[:], instDepositAndCall.Memo...), Slot: slot, Asset: "", // no asset for gas token SOL }, nil } -// ParseInboundAsDepositSPL tries to parse an instruction as a 'deposit_spl_token'. -// It returns nil if the instruction can't be parsed as a 'deposit_spl_token'. +// ParseInboundAsDepositSPL tries to parse an instruction as a deposit_spl or deposit_spl_and_call. +// It returns nil if the instruction can't be parsed as a deposit_spl. func ParseInboundAsDepositSPL( tx *solana.Transaction, instructionIndex int, slot uint64, +) (*Deposit, error) { + // first try to parse as deposit_spl, then as deposit_spl_and_call + deposit, err := tryParseAsDepositSPL(tx, instructionIndex, slot) + if err != nil || deposit != nil { + return deposit, err + } + + return tryParseAsDepositSPLAndCall(tx, instructionIndex, slot) +} + +// tryParseAsDepositSPL tries to parse instruction as deposit_spl +func tryParseAsDepositSPL( + tx *solana.Transaction, + instructionIndex int, + slot uint64, ) (*Deposit, error) { // get instruction by index instruction := tx.Message.Instructions[instructionIndex] - // try deserializing instruction as a 'deposit_spl_token' + // try deserializing instruction as a deposit_spl var inst DepositSPLInstructionParams err := borsh.Deserialize(&inst, instruction.Data) if err != nil { return nil, nil } - // check if the instruction is a deposit spl or not, if not, skip parsing + // check if the instruction is a deposit_spl or not, if not, skip parsing if inst.Discriminator != DiscriminatorDepositSPL { return nil, nil } @@ -88,7 +153,42 @@ func ParseInboundAsDepositSPL( return &Deposit{ Sender: sender, Amount: inst.Amount, - Memo: inst.Memo, + Memo: inst.Receiver[:], + Slot: slot, + Asset: spl, + }, nil +} + +// tryParseAsDepositSPLAndCall tries to parse instruction as deposit_spl_and_call +func tryParseAsDepositSPLAndCall( + tx *solana.Transaction, + instructionIndex int, + slot uint64, +) (*Deposit, error) { + // get instruction by index + instruction := tx.Message.Instructions[instructionIndex] + + // try deserializing instruction as a deposit_spl_and_call + instDepositAndCall := DepositSPLAndCallInstructionParams{} + err := borsh.Deserialize(&instDepositAndCall, instruction.Data) + if err != nil { + return nil, nil + } + + // check if the instruction is a deposit_spl_and_call or not, if not, skip parsing + if instDepositAndCall.Discriminator != DiscriminatorDepositSPLAndCall { + return nil, nil + } + + // get the sender and spl addresses + sender, spl, err := getSignerAndSPLFromDepositSPLAccounts(tx, &instruction) + if err != nil { + return nil, err + } + return &Deposit{ + Sender: sender, + Amount: instDepositAndCall.Amount, + Memo: append(instDepositAndCall.Receiver[:], instDepositAndCall.Memo...), Slot: slot, Asset: spl, }, nil @@ -101,9 +201,9 @@ func getSignerDeposit(tx *solana.Transaction, inst *solana.CompiledInstruction) return "", err } - // there should be 3 accounts for a deposit instruction - if len(instructionAccounts) != accountsNumDeposit { - return "", fmt.Errorf("want %d accounts, got %d", accountsNumDeposit, len(instructionAccounts)) + // there should be at least all mandatory accounts for a deposit instruction + if len(instructionAccounts) < accountsNumDeposit { + return "", fmt.Errorf("want required %d accounts, got %d", accountsNumDeposit, len(instructionAccounts)) } // the accounts are [signer, pda, system_program] @@ -125,10 +225,10 @@ func getSignerAndSPLFromDepositSPLAccounts( return "", "", err } - // there should be 7 accounts for a deposit spl instruction - if len(instructionAccounts) != accountsNumberDepositSPL { + // there should be at least all mandatory accounts for a deposit spl instruction + if len(instructionAccounts) < accountsNumberDepositSPL { return "", "", fmt.Errorf( - "want %d accounts, got %d", + "want required %d accounts, got %d", accountsNumberDepositSPL, len(instructionAccounts), ) diff --git a/pkg/contracts/solana/inbound_test.go b/pkg/contracts/solana/inbound_test.go index b6550d99fd..b8d1354a1f 100644 --- a/pkg/contracts/solana/inbound_test.go +++ b/pkg/contracts/solana/inbound_test.go @@ -39,7 +39,7 @@ func LoadSolanaInboundTxResult( func Test_ParseInboundAsDeposit(t *testing.T) { // ARRANGE - txHash := "MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j" + txHash := "8UeJoxY6RbMg6bffsUtZ9f79vSnd4HCRdk5EQgNbAEDYQWXNraiKDtGDZBLp91oyF5eQyWdv6pEwW1vcitiB4px" chain := chains.SolanaDevnet txResult := LoadSolanaInboundTxResult(t, txHash) @@ -52,11 +52,15 @@ func Test_ParseInboundAsDeposit(t *testing.T) { require.NoError(t, err) // expected result - sender := "AS48jKNQsDGkEdDvfwu1QpqjtqbCadrAq9nGXjFmdX3Z" + // solana e2e deployer account + sender := "37yGiHAnLvWZUNVwu9esp74YQFqxU1qHCbABkDvRddUQ" + // solana e2e user evm account + expectedMemo, err := hex.DecodeString("103fd9224f00ce3013e95629e52dfc31d805d68d") + require.NoError(t, err) expectedDeposit := &Deposit{ Sender: sender, - Amount: 100000, - Memo: []byte("0x7F8ae2ABb69A558CE6bAd546f25F0464D9e09e5B4955a3F38ff86ae92A914445099caa8eA2B9bA32"), + Amount: 12000000, + Memo: expectedMemo, Slot: txResult.Slot, Asset: "", } @@ -87,7 +91,7 @@ func Test_ParseInboundAsDeposit(t *testing.T) { data, err := borsh.Serialize(DepositInstructionParams{ Amount: inst.Amount, Discriminator: DiscriminatorDepositSPL, - Memo: inst.Memo, + Receiver: inst.Receiver, }) require.NoError(t, err) @@ -109,7 +113,112 @@ func Test_ParseInboundAsDeposit(t *testing.T) { // append one more account to instruction tx.Message.AccountKeys = append(tx.Message.AccountKeys, solana.MustPublicKeyFromBase58(sample.SolanaAddress(t))) - tx.Message.Instructions[0].Accounts = append(tx.Message.Instructions[0].Accounts, 4) + tx.Message.Instructions[0].Accounts = tx.Message.Instructions[0].Accounts[:len(tx.Message.Instructions[0].Accounts)-1] + + // ACT + deposit, err := ParseInboundAsDeposit(tx, 0, txResult.Slot) + + // ASSERT + require.Error(t, err) + require.Nil(t, deposit) + }) + + t.Run("should fail if first account is not signer", func(t *testing.T) { + // ARRANGE + txResult := LoadSolanaInboundTxResult(t, txHash) + tx, err := txResult.Transaction.GetTransaction() + require.NoError(t, err) + + // switch account places + tx.Message.Instructions[0].Accounts[0] = 1 + tx.Message.Instructions[0].Accounts[1] = 0 + + // ACT + deposit, err := ParseInboundAsDeposit(tx, 0, txResult.Slot) + + // ASSERT + require.Error(t, err) + require.Nil(t, deposit) + }) +} + +func Test_ParseInboundAsDepositAndCall(t *testing.T) { + // ARRANGE + txHash := "5b7ShhHf8dvUjUBHgMvgH8FFqpfAd7vAGygZLaeNPhugXtY5fatPSACVkn13o7sw6Awob8EJnrwAuiKYqvi7ZkHa" + chain := chains.SolanaDevnet + + txResult := LoadSolanaInboundTxResult(t, txHash) + tx, err := txResult.Transaction.GetTransaction() + require.NoError(t, err) + + // create observer + chainParams := sample.ChainParams(chain.ChainId) + chainParams.GatewayAddress = testutils.OldSolanaGatewayAddressDevnet + require.NoError(t, err) + + // expected result + // solana e2e deployer account + sender := "37yGiHAnLvWZUNVwu9esp74YQFqxU1qHCbABkDvRddUQ" + // example contract deployed during e2e test, read from tx result + expectedReceiver := []byte{117, 160, 106, 140, 37, 135, 57, 218, 223, 226, 53, 45, 87, 151, 61, 239, 158, 231, 162, 186} + expectedMsg := []byte("hello lamports") + expectedDeposit := &Deposit{ + Sender: sender, + Amount: 1200000, + Memo: append(expectedReceiver, expectedMsg...), + Slot: txResult.Slot, + Asset: "", + } + + t.Run("should parse inbound event deposit SOL and call", func(t *testing.T) { + // ACT + deposit, err := ParseInboundAsDeposit(tx, 0, txResult.Slot) + require.NoError(t, err) + + // ASSERT + require.EqualValues(t, expectedDeposit, deposit) + }) + + t.Run("should skip parsing if wrong discriminator", func(t *testing.T) { + // ARRANGE + txResult := LoadSolanaInboundTxResult(t, txHash) + tx, err := txResult.Transaction.GetTransaction() + require.NoError(t, err) + + instruction := tx.Message.Instructions[0] + + // try deserializing instruction as a 'deposit' + var inst DepositInstructionParams + err = borsh.Deserialize(&inst, instruction.Data) + require.NoError(t, err) + + // serialize it back with wrong discriminator + data, err := borsh.Serialize(DepositInstructionParams{ + Amount: inst.Amount, + Discriminator: DiscriminatorDepositSPL, + Receiver: inst.Receiver, + }) + require.NoError(t, err) + + tx.Message.Instructions[0].Data = data + + // ACT + deposit, err := ParseInboundAsDeposit(tx, 0, txResult.Slot) + + // ASSERT + require.NoError(t, err) + require.Nil(t, deposit) + }) + + t.Run("should fail if wrong accounts count", func(t *testing.T) { + // ARRANGE + txResult := LoadSolanaInboundTxResult(t, txHash) + tx, err := txResult.Transaction.GetTransaction() + require.NoError(t, err) + + // append one more account to instruction + tx.Message.AccountKeys = append(tx.Message.AccountKeys, solana.MustPublicKeyFromBase58(sample.SolanaAddress(t))) + tx.Message.Instructions[0].Accounts = tx.Message.Instructions[0].Accounts[:len(tx.Message.Instructions[0].Accounts)-1] // ACT deposit, err := ParseInboundAsDeposit(tx, 0, txResult.Slot) @@ -140,7 +249,7 @@ func Test_ParseInboundAsDeposit(t *testing.T) { func Test_ParseInboundAsDepositSPL(t *testing.T) { // ARRANGE - txHash := "aY8yLDze6nHSRi7L5REozKAZY1aAyPJ6TfibiqQL5JGwgSBkYux5z5JfXs5ed8LZqpXUy4VijoU3x15mBd66ZGE" + txHash := "5bXSQaq6BY1WhhF3Qm4pLHXxuyM9Mz1MrdMeoCFbimxw4uv11raQgAj4HGULPEQExPKB231rMhm6666dQMwf9fNN" chain := chains.SolanaDevnet txResult := LoadSolanaInboundTxResult(t, txHash) @@ -159,10 +268,114 @@ func Test_ParseInboundAsDepositSPL(t *testing.T) { require.NoError(t, err) expectedDeposit := &Deposit{ Sender: sender, - Amount: 500000, + Amount: 12000000, Memo: expectedMemo, Slot: txResult.Slot, - Asset: "4GddKQ7baJpMyKna7bPPnhh7UQtpzfSGL1FgZ31hj4mp", // SPL address + Asset: "BTmtL9Dh2DcwhPntEbjo3rSWpmz1EhXsmohSC7CGSEWw", // SPL address + } + + t.Run("should parse inbound event deposit SPL", func(t *testing.T) { + // ACT + deposit, err := ParseInboundAsDepositSPL(tx, 0, txResult.Slot) + require.NoError(t, err) + + // ASSERT + require.EqualValues(t, expectedDeposit, deposit) + }) + + t.Run("should skip parsing if wrong discriminator", func(t *testing.T) { + // ARRANGE + txResult := LoadSolanaInboundTxResult(t, txHash) + tx, err := txResult.Transaction.GetTransaction() + require.NoError(t, err) + + instruction := tx.Message.Instructions[0] + + // try deserializing instruction as a 'deposit_spl' + var inst DepositSPLInstructionParams + err = borsh.Deserialize(&inst, instruction.Data) + require.NoError(t, err) + + // serialize it back with wrong discriminator + data, err := borsh.Serialize(DepositInstructionParams{ + Amount: inst.Amount, + Discriminator: DiscriminatorDeposit, + Receiver: inst.Receiver, + }) + require.NoError(t, err) + + tx.Message.Instructions[0].Data = data + + // ACT + deposit, err := ParseInboundAsDepositSPL(tx, 0, txResult.Slot) + + // ASSERT + require.NoError(t, err) + require.Nil(t, deposit) + }) + + t.Run("should fail if wrong accounts count", func(t *testing.T) { + // ARRANGE + txResult := LoadSolanaInboundTxResult(t, txHash) + tx, err := txResult.Transaction.GetTransaction() + require.NoError(t, err) + + // append one more account to instruction + tx.Message.AccountKeys = append(tx.Message.AccountKeys, solana.MustPublicKeyFromBase58(sample.SolanaAddress(t))) + tx.Message.Instructions[0].Accounts = tx.Message.Instructions[0].Accounts[:len(tx.Message.Instructions[0].Accounts)-1] + + // ACT + deposit, err := ParseInboundAsDepositSPL(tx, 0, txResult.Slot) + + // ASSERT + require.Error(t, err) + require.Nil(t, deposit) + }) + + t.Run("should fail if first account is not signer", func(t *testing.T) { + // ARRANGE + txResult := LoadSolanaInboundTxResult(t, txHash) + tx, err := txResult.Transaction.GetTransaction() + require.NoError(t, err) + + // switch account places + tx.Message.Instructions[0].Accounts[0] = 1 + tx.Message.Instructions[0].Accounts[1] = 0 + + // ACT + deposit, err := ParseInboundAsDepositSPL(tx, 0, txResult.Slot) + + // ASSERT + require.Error(t, err) + require.Nil(t, deposit) + }) +} + +func Test_ParseInboundAsDepositAndCallSPL(t *testing.T) { + // ARRANGE + txHash := "22s5ERRRZmZXAuDMRdwUU33VnWZ7m8NHUZM6hyLH52JQPz5R7mXEkFcvHx88ujq3xDnt3z7sZdZ21JK2FC7vPw1o" + chain := chains.SolanaDevnet + + txResult := LoadSolanaInboundTxResult(t, txHash) + tx, err := txResult.Transaction.GetTransaction() + require.NoError(t, err) + + // create observer + chainParams := sample.ChainParams(chain.ChainId) + chainParams.GatewayAddress = testutils.OldSolanaGatewayAddressDevnet + + // expected result + // solana e2e deployer account + sender := "37yGiHAnLvWZUNVwu9esp74YQFqxU1qHCbABkDvRddUQ" + // example contract deployed during e2e test, read from tx result + expectedReceiver := []byte{213, 254, 240, 66, 1, 154, 250, 238, 39, 131, 9, 45, 5, 2, 190, 192, 20, 31, 103, 209} + expectedMsg := []byte("hello spl tokens") + expectedDeposit := &Deposit{ + Sender: sender, + Amount: 12000000, + Memo: append(expectedReceiver, expectedMsg...), + Slot: txResult.Slot, + Asset: "7d4ehzE4WNgithQZMyQFDhmHyN6rQNTEC7re1bsRN7TX", // SPL address } t.Run("should parse inbound event deposit SPL", func(t *testing.T) { @@ -191,7 +404,7 @@ func Test_ParseInboundAsDepositSPL(t *testing.T) { data, err := borsh.Serialize(DepositInstructionParams{ Amount: inst.Amount, Discriminator: DiscriminatorDeposit, - Memo: inst.Memo, + Receiver: inst.Receiver, }) require.NoError(t, err) @@ -213,7 +426,7 @@ func Test_ParseInboundAsDepositSPL(t *testing.T) { // append one more account to instruction tx.Message.AccountKeys = append(tx.Message.AccountKeys, solana.MustPublicKeyFromBase58(sample.SolanaAddress(t))) - tx.Message.Instructions[0].Accounts = append(tx.Message.Instructions[0].Accounts, 4) + tx.Message.Instructions[0].Accounts = tx.Message.Instructions[0].Accounts[:len(tx.Message.Instructions[0].Accounts)-1] // ACT deposit, err := ParseInboundAsDepositSPL(tx, 0, txResult.Slot) diff --git a/pkg/contracts/solana/instruction.go b/pkg/contracts/solana/instruction.go index e11116e35f..2c0b31c2b4 100644 --- a/pkg/contracts/solana/instruction.go +++ b/pkg/contracts/solana/instruction.go @@ -30,19 +30,49 @@ type DepositInstructionParams struct { // Amount is the lamports amount for the deposit Amount uint64 - // Memo is the memo for the deposit + // Receiver is the receiver for the deposit + Receiver [20]byte +} + +// DepositAndCallInstructionParams contains the parameters for a gateway deposit_and_call instruction +type DepositAndCallInstructionParams struct { + // Discriminator is the unique identifier for the deposit_and_call instruction + Discriminator [8]byte + + // Amount is the lamports amount for the deposit_and_call + Amount uint64 + + // Receiver is the receiver for the deposit_and_call + Receiver [20]byte + + // Memo is the memo for the deposit_and_call Memo []byte } -// DepositSPLInstructionParams contains the parameters for a gateway deposit spl instruction +// DepositSPLInstructionParams contains the parameters for a gateway deposit_spl instruction type DepositSPLInstructionParams struct { - // Discriminator is the unique identifier for the deposit instruction + // Discriminator is the unique identifier for the deposit_spl instruction Discriminator [8]byte - // Amount is the lamports amount for the deposit + // Amount is the lamports amount for the deposit_spl + Amount uint64 + + // Receiver is the receiver for the deposit_spl + Receiver [20]byte +} + +// DepositSPLAndCallInstructionParams contains the parameters for a gateway deposit_spl_and_call instruction +type DepositSPLAndCallInstructionParams struct { + // Discriminator is the unique identifier for the deposit_spl_and_call instruction + Discriminator [8]byte + + // Amount is the lamports amount for the deposit_spl_and_call Amount uint64 - // Memo is the memo for the deposit + // Receiver is the receiver for the deposit_spl_and_call + Receiver [20]byte + + // Memo is the memo for the deposit_spl_and_call Memo []byte } diff --git a/pkg/contracts/solana/testdata/22s5ERRRZmZXAuDMRdwUU33VnWZ7m8NHUZM6hyLH52JQPz5R7mXEkFcvHx88ujq3xDnt3z7sZdZ21JK2FC7vPw1o.json b/pkg/contracts/solana/testdata/22s5ERRRZmZXAuDMRdwUU33VnWZ7m8NHUZM6hyLH52JQPz5R7mXEkFcvHx88ujq3xDnt3z7sZdZ21JK2FC7vPw1o.json new file mode 100644 index 0000000000..c6336051b6 --- /dev/null +++ b/pkg/contracts/solana/testdata/22s5ERRRZmZXAuDMRdwUU33VnWZ7m8NHUZM6hyLH52JQPz5R7mXEkFcvHx88ujq3xDnt3z7sZdZ21JK2FC7vPw1o.json @@ -0,0 +1,98 @@ +{ + "slot": 1111, + "blockTime": 1733490207, + "transaction": { + "signatures": [ + "22s5ERRRZmZXAuDMRdwUU33VnWZ7m8NHUZM6hyLH52JQPz5R7mXEkFcvHx88ujq3xDnt3z7sZdZ21JK2FC7vPw1o" + ], + "message": { + "accountKeys": [ + "37yGiHAnLvWZUNVwu9esp74YQFqxU1qHCbABkDvRddUQ", + "9dcAyYG4bawApZocwZSyJBi9Mynf5EuKAJfifXdfkqik", + "EKZTsmjEMAbkStqWdoqyeFh4DkgB9zXr9yxwBHzcy2Sn", + "C2vKeBZ6yeUdeFC22UR82Drnj5AaXe4oKLgFQMJRpeDv", + "2zioTPUGiVwr4XZgDCy34qo2EbHQBU86jTU568rnKKri", + "7d4ehzE4WNgithQZMyQFDhmHyN6rQNTEC7re1bsRN7TX", + "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + "11111111111111111111111111111111", + "94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d" + ], + "header": { + "numRequiredSignatures": 1, + "numReadonlySignedAccounts": 0, + "numReadonlyUnsignedAccounts": 5 + }, + "recentBlockhash": "HXK99VqYfwMDMEaJmxPgLLLygUUYpPry1mPkSJkwekDC", + "instructions": [ + { + "programIdIndex": 8, + "accounts": [ + 0, + 1, + 4, + 5, + 6, + 2, + 3, + 7 + ], + "data": "Q6siP5YLNCNi7eDfNNdsuMhgSAJvKMZiozqaPmi1rzGWxAJNPaUg8WK1a5v9GRriHGnLDuwmBZ9L" + } + ] + } + }, + "meta": { + "err": null, + "fee": 5000, + "preBalances": [ + 99967505600, + 25947680, + 2039280, + 2039280, + 946560, + 1461600, + 929020800, + 1, + 1141440 + ], + "postBalances": [ + 99965500600, + 27947680, + 2039280, + 2039280, + 946560, + 1461600, + 929020800, + 1, + 1141440 + ], + "innerInstructions": [ + { + "index": 0, + "instructions": [] + } + ], + "preTokenBalances": [], + "postTokenBalances": [], + "logMessages": [ + "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d invoke [1] Program log: Instruction: DepositSplTokenAndCall", + "Program 11111111111111111111111111111111 invoke [2]", + "Program 11111111111111111111111111111111 success Program", + "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", + "Program log: Instruction: Transfer Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 179934 compute units", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", + "Program log: deposit spl token successfully", + "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d consumed 25580 of 200000 compute units Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d success" + ], + "status": { + "Ok": null + }, + "rewards": [], + "loadedAddresses": { + "readonly": [], + "writable": [] + }, + "computeUnitsConsumed": 274902869112 + }, + "version": 0 +} \ No newline at end of file diff --git a/pkg/contracts/solana/testdata/5b7ShhHf8dvUjUBHgMvgH8FFqpfAd7vAGygZLaeNPhugXtY5fatPSACVkn13o7sw6Awob8EJnrwAuiKYqvi7ZkHa.json b/pkg/contracts/solana/testdata/5b7ShhHf8dvUjUBHgMvgH8FFqpfAd7vAGygZLaeNPhugXtY5fatPSACVkn13o7sw6Awob8EJnrwAuiKYqvi7ZkHa.json new file mode 100644 index 0000000000..e25d5d77a4 --- /dev/null +++ b/pkg/contracts/solana/testdata/5b7ShhHf8dvUjUBHgMvgH8FFqpfAd7vAGygZLaeNPhugXtY5fatPSACVkn13o7sw6Awob8EJnrwAuiKYqvi7ZkHa.json @@ -0,0 +1,77 @@ +{ + "slot": 1111, + "blockTime": 1733490207, + "transaction": { + "signatures": [ + "5b7ShhHf8dvUjUBHgMvgH8FFqpfAd7vAGygZLaeNPhugXtY5fatPSACVkn13o7sw6Awob8EJnrwAuiKYqvi7ZkHa" + ], + "message": { + "accountKeys": [ + "37yGiHAnLvWZUNVwu9esp74YQFqxU1qHCbABkDvRddUQ", + "9dcAyYG4bawApZocwZSyJBi9Mynf5EuKAJfifXdfkqik", + "11111111111111111111111111111111", + "94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d" + ], + "header": { + "numRequiredSignatures": 1, + "numReadonlySignedAccounts": 0, + "numReadonlyUnsignedAccounts": 2 + }, + "recentBlockhash": "GvTg9tWxC6UUwVESdZnB3s1GHLjSU7yozNvRgNAxinRv", + "instructions": [ + { + "programIdIndex": 3, + "accounts": [ + 0, + 1, + 2 + ], + "data": "6FaQ3EVJmN4pEjM4cxGpTqEDQdfmnwd2p3Eq9k4ZyfqZxp47KXcRDt1NghRzX186nuLHj4Nt1G" + } + ] + } + }, + "meta": { + "err": null, + "fee": 5000, + "preBalances": [ + 99994074880, + 1447680, + 1, + 1141440 + ], + "postBalances": [ + 99990869880, + 4647680, + 1, + 1141440 + ], + "innerInstructions": [ + { + "index": 0, + "instructions": [] + } + ], + "preTokenBalances": [], + "postTokenBalances": [], + "logMessages": [ + "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d invoke [1]", + "Program log: Instruction: DepositAndCall", + "Program 11111111111111111111111111111111 invoke [2]", + "Program 11111111111111111111111111111111 success", + "Program log: 37yGiHAnLvWZUNVwu9esp74YQFqxU1qHCbABkDvRddUQ deposits 1200000 lamports to PDA with fee 2000000; receiver [117, 160, 106, 140, 37, 135, 57, 218, 223, 226, 53, 45, 87, 151, 61, 239, 158, 231, 162, 186]", + "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d consumed 26765 of 200000 compute units", + "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d success" + ], + "status": { + "Ok": null + }, + "rewards": [], + "loadedAddresses": { + "readonly": [], + "writable": [] + }, + "computeUnitsConsumed": 274902869112 + }, + "version": 0 +} \ No newline at end of file diff --git a/pkg/contracts/solana/testdata/aY8yLDze6nHSRi7L5REozKAZY1aAyPJ6TfibiqQL5JGwgSBkYux5z5JfXs5ed8LZqpXUy4VijoU3x15mBd66ZGE.json b/pkg/contracts/solana/testdata/5bXSQaq6BY1WhhF3Qm4pLHXxuyM9Mz1MrdMeoCFbimxw4uv11raQgAj4HGULPEQExPKB231rMhm6666dQMwf9fNN.json similarity index 66% rename from pkg/contracts/solana/testdata/aY8yLDze6nHSRi7L5REozKAZY1aAyPJ6TfibiqQL5JGwgSBkYux5z5JfXs5ed8LZqpXUy4VijoU3x15mBd66ZGE.json rename to pkg/contracts/solana/testdata/5bXSQaq6BY1WhhF3Qm4pLHXxuyM9Mz1MrdMeoCFbimxw4uv11raQgAj4HGULPEQExPKB231rMhm6666dQMwf9fNN.json index ad4c5e62f5..8f7587d30e 100644 --- a/pkg/contracts/solana/testdata/aY8yLDze6nHSRi7L5REozKAZY1aAyPJ6TfibiqQL5JGwgSBkYux5z5JfXs5ed8LZqpXUy4VijoU3x15mBd66ZGE.json +++ b/pkg/contracts/solana/testdata/5bXSQaq6BY1WhhF3Qm4pLHXxuyM9Mz1MrdMeoCFbimxw4uv11raQgAj4HGULPEQExPKB231rMhm6666dQMwf9fNN.json @@ -1,18 +1,18 @@ { - "slot": 539, - "blockTime": 1730986363, + "slot": 1111, + "blockTime": 1733490207, "transaction": { "signatures": [ - "aY8yLDze6nHSRi7L5REozKAZY1aAyPJ6TfibiqQL5JGwgSBkYux5z5JfXs5ed8LZqpXUy4VijoU3x15mBd66ZGE" + "5bXSQaq6BY1WhhF3Qm4pLHXxuyM9Mz1MrdMeoCFbimxw4uv11raQgAj4HGULPEQExPKB231rMhm6666dQMwf9fNN" ], "message": { "accountKeys": [ "37yGiHAnLvWZUNVwu9esp74YQFqxU1qHCbABkDvRddUQ", - "HX8BXQKVw1xpoyDXMr9ujyrrpSYRWcFZ4oB3fRHpM8V7", - "5EVPJV5hjwYGYko2pSykSdJG5ZfBbMEDhYci2PrqQmby", "9dcAyYG4bawApZocwZSyJBi9Mynf5EuKAJfifXdfkqik", - "8vquQi8xNxxBTsohf1u8xQHYbo7Fv8BEWCJz63RJSaeE", - "4GddKQ7baJpMyKna7bPPnhh7UQtpzfSGL1FgZ31hj4mp", + "E4mtFD4qnS2LCe3w5Mg89WW9JUutEbV3r5ZLBZfZx7rd", + "2kFYgZBrX221xLxGPQ5ZZ39PRHY5XorAy3ZG3DfASQWb", + "7CTgzWesnoMvLMU6pGgPEht1C4maV4bctBYoSdeunVGv", + "BTmtL9Dh2DcwhPntEbjo3rSWpmz1EhXsmohSC7CGSEWw", "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "11111111111111111111111111111111", "94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d" @@ -22,21 +22,21 @@ "numReadonlySignedAccounts": 0, "numReadonlyUnsignedAccounts": 5 }, - "recentBlockhash": "5ZB2NWKwp86t47ojCHPjRyd5vMKSWBdhxqDdtSZVPUj", + "recentBlockhash": "EbmoPGUZfc9mMjbQosueT1QLoAnYfv9BKQKG8XnV3G5V", "instructions": [ { "programIdIndex": 8, "accounts": [ 0, - 3, + 1, 4, 5, 6, - 1, 2, + 3, 7 ], - "data": "5JndgWCNHDyr2qQccK9VM1NxJFrVbUDvG2hfAxRC5z6nPPAVPsj7q3A" + "data": "fAzySRSzJpZy3QTj6orjk9erMQpjbB1y9AnSSN1CH74CyovkC" } ] } @@ -45,23 +45,25 @@ "err": null, "fee": 5000, "preBalances": [ - 99992030600, + 99967505600, + 25947680, 2039280, 2039280, - 1447680, 946560, 1461600, 929020800, + 1, 1141440 ], "postBalances": [ - 99992025600, + 99965500600, + 27947680, 2039280, 2039280, - 1447680, 946560, 1461600, 929020800, + 1, 1141440 ], "innerInstructions": [ @@ -75,10 +77,13 @@ "logMessages": [ "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d invoke [1]", "Program log: Instruction: DepositSplToken", + "Program 11111111111111111111111111111111 invoke [2]", + "Program 11111111111111111111111111111111 success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]", - "Program log: Instruction: Transfer Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 181038 compute units", - "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success Program log: deposit spl token successfully", - "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d consumed 24017 of 200000 compute units", + "Program log: Instruction: Transfer", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 178636 compute units", + "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success", + "Program log: deposit spl token successfully Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d consumed 26871 of 200000 compute units", "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d success" ], "status": { diff --git a/pkg/contracts/solana/testdata/MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j.json b/pkg/contracts/solana/testdata/8UeJoxY6RbMg6bffsUtZ9f79vSnd4HCRdk5EQgNbAEDYQWXNraiKDtGDZBLp91oyF5eQyWdv6pEwW1vcitiB4px.json similarity index 50% rename from pkg/contracts/solana/testdata/MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j.json rename to pkg/contracts/solana/testdata/8UeJoxY6RbMg6bffsUtZ9f79vSnd4HCRdk5EQgNbAEDYQWXNraiKDtGDZBLp91oyF5eQyWdv6pEwW1vcitiB4px.json index cf7edb3b81..1b2634c1e6 100644 --- a/pkg/contracts/solana/testdata/MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j.json +++ b/pkg/contracts/solana/testdata/8UeJoxY6RbMg6bffsUtZ9f79vSnd4HCRdk5EQgNbAEDYQWXNraiKDtGDZBLp91oyF5eQyWdv6pEwW1vcitiB4px.json @@ -1,13 +1,13 @@ { - "slot": 321701608, - "blockTime": 1724732369, + "slot": 510, + "blockTime": 1733489933, "transaction": { "signatures": [ - "MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j" + "8UeJoxY6RbMg6bffsUtZ9f79vSnd4HCRdk5EQgNbAEDYQWXNraiKDtGDZBLp91oyF5eQyWdv6pEwW1vcitiB4px" ], "message": { "accountKeys": [ - "AS48jKNQsDGkEdDvfwu1QpqjtqbCadrAq9nGXjFmdX3Z", + "37yGiHAnLvWZUNVwu9esp74YQFqxU1qHCbABkDvRddUQ", "9dcAyYG4bawApZocwZSyJBi9Mynf5EuKAJfifXdfkqik", "11111111111111111111111111111111", "94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d" @@ -17,12 +17,16 @@ "numReadonlySignedAccounts": 0, "numReadonlyUnsignedAccounts": 2 }, - "recentBlockhash": "41txNvjedo2eu6aAofQfyLskAcgtrtgch9RpqnrKcv1a", + "recentBlockhash": "21uLyS3mMAjoDoXuxqQBkin9uD34KQi5KCEjKMJLWGEu", "instructions": [ { "programIdIndex": 3, - "accounts": [0, 1, 2], - "data": "4ALHYcAj3zFsNjmfeq7nDK1E8BsxRQRzhLjrqzmjYzL97Qkiz4rP1iQePmFAehfFEET7uczYLhhEVhtndBYNNm6ekHSkgsLzYDeSD2JSudHa6D5tqhVGjvXZ7qEouPiy9eptZfuYHE9X" + "accounts": [ + 0, + 1, + 2 + ], + "data": "2qe8pjwrUAq1Zb3QcoA54F3X4CLY59fgwDRKuGM4qzy3EutcWx" } ] } @@ -30,16 +34,19 @@ "meta": { "err": null, "fee": 5000, - "preBalances": [9999364000, 1001447680, 1, 1141440], - "postBalances": [9999259000, 1001547680, 1, 1141440], + "preBalances": [99994074880, 1447680, 1, 1141440], + "postBalances": [99980069880, 15447680, 1, 1141440], "innerInstructions": [ { "index": 0, "instructions": [ { "programIdIndex": 2, - "accounts": [0, 1], - "data": "3Bxs4ThwQbE4vyj5" + "accounts": [ + 0, + 1 + ], + "data": "3Bxs4NNUejChDhvX" } ] } @@ -48,17 +55,22 @@ "postTokenBalances": [], "logMessages": [ "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d invoke [1]", - "Program log: Instruction: Deposit", + "Program log: Instruction: Deposit", "Program 11111111111111111111111111111111 invoke [2]", - "Program 11111111111111111111111111111111 success", - "Program log: AS48jKNQsDGkEdDvfwu1QpqjtqbCadrAq9nGXjFmdX3Z deposits 100000 lamports to PDA", - "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d consumed 17006 of 200000 compute units", + "Program 11111111111111111111111111111111 success", + "Program log: 37yGiHAnLvWZUNVwu9esp74YQFqxU1qHCbABkDvRddUQ deposits 12000000 lamports to PDA with fee 2000000; receiver [16, 63, 217, 34, 79, 0, 206, 48, 19, 233, 86, 41, 229, 45, 252, 49, 216, 5, 214, 141]", + "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d consumed 26307 of 200000 compute units", "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d success" ], - "status": { "Ok": null }, + "status": { + "Ok": null + }, "rewards": [], - "loadedAddresses": { "readonly": [], "writable": [] }, + "loadedAddresses": { + "readonly": [], + "writable": [] + }, "computeUnitsConsumed": 17006 }, "version": 0 -} +} \ No newline at end of file diff --git a/testutil/contracts/Example.abi b/testutil/contracts/Example.abi index 26031cc7cf..ccf6aa55a9 100644 --- a/testutil/contracts/Example.abi +++ b/testutil/contracts/Example.abi @@ -50,6 +50,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "lastMessage", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { diff --git a/testutil/contracts/Example.bin b/testutil/contracts/Example.bin index 2243b22b87..e7a2293644 100644 --- a/testutil/contracts/Example.bin +++ b/testutil/contracts/Example.bin @@ -1 +1 @@ -6080604052348015600f57600080fd5b506000808190555061043f806100266000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c8063afc874d214610067578063d720cb4514610071578063dd8e556c1461007b578063de43156e14610085578063fd5ad965146100a1578063febb0f7e146100ab575b600080fd5b61006f6100c9565b005b6100796100fb565b005b610083610136565b005b61009f600480360381019061009a91906102be565b610179565b005b6100a9610187565b005b6100b3610191565b6040516100c09190610371565b60405180910390f35b6040517fbfb4ebcf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012d906103e9565b60405180910390fd5b6000610177576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161016e906103e9565b60405180910390fd5b565b826000819055505050505050565b6001600081905550565b60005481565b600080fd5b600080fd5b600080fd5b6000606082840312156101bc576101bb6101a1565b5b81905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101f0826101c5565b9050919050565b610200816101e5565b811461020b57600080fd5b50565b60008135905061021d816101f7565b92915050565b6000819050919050565b61023681610223565b811461024157600080fd5b50565b6000813590506102538161022d565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261027e5761027d610259565b5b8235905067ffffffffffffffff81111561029b5761029a61025e565b5b6020830191508360018202830111156102b7576102b6610263565b5b9250929050565b6000806000806000608086880312156102da576102d9610197565b5b600086013567ffffffffffffffff8111156102f8576102f761019c565b5b610304888289016101a6565b95505060206103158882890161020e565b945050604061032688828901610244565b935050606086013567ffffffffffffffff8111156103475761034661019c565b5b61035388828901610268565b92509250509295509295909350565b61036b81610223565b82525050565b60006020820190506103866000830184610362565b92915050565b600082825260208201905092915050565b7f666f6f0000000000000000000000000000000000000000000000000000000000600082015250565b60006103d360038361038c565b91506103de8261039d565b602082019050919050565b60006020820190508181036000830152610402816103c6565b905091905056fea2646970667358221220c9cedad580b18532a00be1e615813af1c20bb609a0a69b5f36d49ed76cc20b5064736f6c63430008190033 +6080604052348015600f57600080fd5b50600080819055506108e0806100266000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063dd8e556c1161005b578063dd8e556c146100b4578063de43156e146100be578063fd5ad965146100da578063febb0f7e146100e45761007d565b80633297071014610082578063afc874d2146100a0578063d720cb45146100aa575b600080fd5b61008a610102565b6040516100979190610300565b60405180910390f35b6100a8610190565b005b6100b26101c2565b005b6100bc6101fd565b005b6100d860048036038101906100d39190610449565b610240565b005b6100e2610260565b005b6100ec61026a565b6040516100f991906104fc565b60405180910390f35b6001805461010f90610546565b80601f016020809104026020016040519081016040528092919081815260200182805461013b90610546565b80156101885780601f1061015d57610100808354040283529160200191610188565b820191906000526020600020905b81548152906001019060200180831161016b57829003601f168201915b505050505081565b6040517fbfb4ebcf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f4906105d4565b60405180910390fd5b600061023e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610235906105d4565b60405180910390fd5b565b826000819055508181600191826102589291906107da565b505050505050565b6001600081905550565b60005481565b600081519050919050565b600082825260208201905092915050565b60005b838110156102aa57808201518184015260208101905061028f565b60008484015250505050565b6000601f19601f8301169050919050565b60006102d282610270565b6102dc818561027b565b93506102ec81856020860161028c565b6102f5816102b6565b840191505092915050565b6000602082019050818103600083015261031a81846102c7565b905092915050565b600080fd5b600080fd5b600080fd5b6000606082840312156103475761034661032c565b5b81905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061037b82610350565b9050919050565b61038b81610370565b811461039657600080fd5b50565b6000813590506103a881610382565b92915050565b6000819050919050565b6103c1816103ae565b81146103cc57600080fd5b50565b6000813590506103de816103b8565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610409576104086103e4565b5b8235905067ffffffffffffffff811115610426576104256103e9565b5b602083019150836001820283011115610442576104416103ee565b5b9250929050565b60008060008060006080868803121561046557610464610322565b5b600086013567ffffffffffffffff81111561048357610482610327565b5b61048f88828901610331565b95505060206104a088828901610399565b94505060406104b1888289016103cf565b935050606086013567ffffffffffffffff8111156104d2576104d1610327565b5b6104de888289016103f3565b92509250509295509295909350565b6104f6816103ae565b82525050565b600060208201905061051160008301846104ed565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061055e57607f821691505b60208210810361057157610570610517565b5b50919050565b600082825260208201905092915050565b7f666f6f0000000000000000000000000000000000000000000000000000000000600082015250565b60006105be600383610577565b91506105c982610588565b602082019050919050565b600060208201905081810360008301526105ed816105b1565b9050919050565b600082905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026106907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610653565b61069a8683610653565b95508019841693508086168417925050509392505050565b6000819050919050565b60006106d76106d26106cd846103ae565b6106b2565b6103ae565b9050919050565b6000819050919050565b6106f1836106bc565b6107056106fd826106de565b848454610660565b825550505050565b600090565b61071a61070d565b6107258184846106e8565b505050565b5b818110156107495761073e600082610712565b60018101905061072b565b5050565b601f82111561078e5761075f8161062e565b61076884610643565b81016020851015610777578190505b61078b61078385610643565b83018261072a565b50505b505050565b600082821c905092915050565b60006107b160001984600802610793565b1980831691505092915050565b60006107ca83836107a0565b9150826002028217905092915050565b6107e483836105f4565b67ffffffffffffffff8111156107fd576107fc6105ff565b5b6108078254610546565b61081282828561074d565b6000601f831160018114610841576000841561082f578287013590505b61083985826107be565b8655506108a1565b601f19841661084f8661062e565b60005b8281101561087757848901358255600182019150602085019450602081019050610852565b868310156108945784890135610890601f8916826107a0565b8355505b6001600288020188555050505b5050505050505056fea26469706673582212202506bee512af2f3acd98556baafd9afc04b2d8c95f09bbb5e387fce570c9a32764736f6c634300081a0033 diff --git a/testutil/contracts/Example.go b/testutil/contracts/Example.go index ce9cab5826..62ff9a3530 100644 --- a/testutil/contracts/Example.go +++ b/testutil/contracts/Example.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // ExamplezContext is an auto generated low-level Go binding around an user-defined struct. @@ -37,8 +38,8 @@ type ExamplezContext struct { // ExampleMetaData contains all meta data concerning the Example contract. var ExampleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"Foo\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"bar\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"doRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"doRevertWithMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"doRevertWithRequire\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"doSucceed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"origin\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainID\",\"type\":\"uint256\"}],\"internalType\":\"structExample.zContext\",\"name\":\"context\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"zrc20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"onCrossChainCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6080604052348015600f57600080fd5b506000808190555061043f806100266000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c8063afc874d214610067578063d720cb4514610071578063dd8e556c1461007b578063de43156e14610085578063fd5ad965146100a1578063febb0f7e146100ab575b600080fd5b61006f6100c9565b005b6100796100fb565b005b610083610136565b005b61009f600480360381019061009a91906102be565b610179565b005b6100a9610187565b005b6100b3610191565b6040516100c09190610371565b60405180910390f35b6040517fbfb4ebcf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012d906103e9565b60405180910390fd5b6000610177576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161016e906103e9565b60405180910390fd5b565b826000819055505050505050565b6001600081905550565b60005481565b600080fd5b600080fd5b600080fd5b6000606082840312156101bc576101bb6101a1565b5b81905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101f0826101c5565b9050919050565b610200816101e5565b811461020b57600080fd5b50565b60008135905061021d816101f7565b92915050565b6000819050919050565b61023681610223565b811461024157600080fd5b50565b6000813590506102538161022d565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261027e5761027d610259565b5b8235905067ffffffffffffffff81111561029b5761029a61025e565b5b6020830191508360018202830111156102b7576102b6610263565b5b9250929050565b6000806000806000608086880312156102da576102d9610197565b5b600086013567ffffffffffffffff8111156102f8576102f761019c565b5b610304888289016101a6565b95505060206103158882890161020e565b945050604061032688828901610244565b935050606086013567ffffffffffffffff8111156103475761034661019c565b5b61035388828901610268565b92509250509295509295909350565b61036b81610223565b82525050565b60006020820190506103866000830184610362565b92915050565b600082825260208201905092915050565b7f666f6f0000000000000000000000000000000000000000000000000000000000600082015250565b60006103d360038361038c565b91506103de8261039d565b602082019050919050565b60006020820190508181036000830152610402816103c6565b905091905056fea2646970667358221220c9cedad580b18532a00be1e615813af1c20bb609a0a69b5f36d49ed76cc20b5064736f6c63430008190033", + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"Foo\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"bar\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"doRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"doRevertWithMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"doRevertWithRequire\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"doSucceed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"origin\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainID\",\"type\":\"uint256\"}],\"internalType\":\"structExample.zContext\",\"name\":\"context\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"zrc20\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"onCrossChainCall\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6080604052348015600f57600080fd5b50600080819055506108e0806100266000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063dd8e556c1161005b578063dd8e556c146100b4578063de43156e146100be578063fd5ad965146100da578063febb0f7e146100e45761007d565b80633297071014610082578063afc874d2146100a0578063d720cb45146100aa575b600080fd5b61008a610102565b6040516100979190610300565b60405180910390f35b6100a8610190565b005b6100b26101c2565b005b6100bc6101fd565b005b6100d860048036038101906100d39190610449565b610240565b005b6100e2610260565b005b6100ec61026a565b6040516100f991906104fc565b60405180910390f35b6001805461010f90610546565b80601f016020809104026020016040519081016040528092919081815260200182805461013b90610546565b80156101885780601f1061015d57610100808354040283529160200191610188565b820191906000526020600020905b81548152906001019060200180831161016b57829003601f168201915b505050505081565b6040517fbfb4ebcf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f4906105d4565b60405180910390fd5b600061023e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610235906105d4565b60405180910390fd5b565b826000819055508181600191826102589291906107da565b505050505050565b6001600081905550565b60005481565b600081519050919050565b600082825260208201905092915050565b60005b838110156102aa57808201518184015260208101905061028f565b60008484015250505050565b6000601f19601f8301169050919050565b60006102d282610270565b6102dc818561027b565b93506102ec81856020860161028c565b6102f5816102b6565b840191505092915050565b6000602082019050818103600083015261031a81846102c7565b905092915050565b600080fd5b600080fd5b600080fd5b6000606082840312156103475761034661032c565b5b81905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061037b82610350565b9050919050565b61038b81610370565b811461039657600080fd5b50565b6000813590506103a881610382565b92915050565b6000819050919050565b6103c1816103ae565b81146103cc57600080fd5b50565b6000813590506103de816103b8565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610409576104086103e4565b5b8235905067ffffffffffffffff811115610426576104256103e9565b5b602083019150836001820283011115610442576104416103ee565b5b9250929050565b60008060008060006080868803121561046557610464610322565b5b600086013567ffffffffffffffff81111561048357610482610327565b5b61048f88828901610331565b95505060206104a088828901610399565b94505060406104b1888289016103cf565b935050606086013567ffffffffffffffff8111156104d2576104d1610327565b5b6104de888289016103f3565b92509250509295509295909350565b6104f6816103ae565b82525050565b600060208201905061051160008301846104ed565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061055e57607f821691505b60208210810361057157610570610517565b5b50919050565b600082825260208201905092915050565b7f666f6f0000000000000000000000000000000000000000000000000000000000600082015250565b60006105be600383610577565b91506105c982610588565b602082019050919050565b600060208201905081810360008301526105ed816105b1565b9050919050565b600082905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026106907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610653565b61069a8683610653565b95508019841693508086168417925050509392505050565b6000819050919050565b60006106d76106d26106cd846103ae565b6106b2565b6103ae565b9050919050565b6000819050919050565b6106f1836106bc565b6107056106fd826106de565b848454610660565b825550505050565b600090565b61071a61070d565b6107258184846106e8565b505050565b5b818110156107495761073e600082610712565b60018101905061072b565b5050565b601f82111561078e5761075f8161062e565b61076884610643565b81016020851015610777578190505b61078b61078385610643565b83018261072a565b50505b505050565b600082821c905092915050565b60006107b160001984600802610793565b1980831691505092915050565b60006107ca83836107a0565b9150826002028217905092915050565b6107e483836105f4565b67ffffffffffffffff8111156107fd576107fc6105ff565b5b6108078254610546565b61081282828561074d565b6000601f831160018114610841576000841561082f578287013590505b61083985826107be565b8655506108a1565b601f19841661084f8661062e565b60005b8281101561087757848901358255600182019150602085019450602081019050610852565b868310156108945784890135610890601f8916826107a0565b8355505b6001600288020188555050505b5050505050505056fea26469706673582212202506bee512af2f3acd98556baafd9afc04b2d8c95f09bbb5e387fce570c9a32764736f6c634300081a0033", } // ExampleABI is the input ABI used to generate the binding from. @@ -163,11 +164,11 @@ func NewExampleFilterer(address common.Address, filterer bind.ContractFilterer) // bindExample binds a generic wrapper to an already deployed contract. func bindExample(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ExampleABI)) + parsed, err := ExampleMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and @@ -239,6 +240,37 @@ func (_Example *ExampleCallerSession) Bar() (*big.Int, error) { return _Example.Contract.Bar(&_Example.CallOpts) } +// LastMessage is a free data retrieval call binding the contract method 0x32970710. +// +// Solidity: function lastMessage() view returns(bytes) +func (_Example *ExampleCaller) LastMessage(opts *bind.CallOpts) ([]byte, error) { + var out []interface{} + err := _Example.contract.Call(opts, &out, "lastMessage") + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// LastMessage is a free data retrieval call binding the contract method 0x32970710. +// +// Solidity: function lastMessage() view returns(bytes) +func (_Example *ExampleSession) LastMessage() ([]byte, error) { + return _Example.Contract.LastMessage(&_Example.CallOpts) +} + +// LastMessage is a free data retrieval call binding the contract method 0x32970710. +// +// Solidity: function lastMessage() view returns(bytes) +func (_Example *ExampleCallerSession) LastMessage() ([]byte, error) { + return _Example.Contract.LastMessage(&_Example.CallOpts) +} + // DoRevert is a paid mutator transaction binding the contract method 0xafc874d2. // // Solidity: function doRevert() returns() diff --git a/testutil/contracts/Example.json b/testutil/contracts/Example.json index 9c67ba2186..c41132ea94 100644 --- a/testutil/contracts/Example.json +++ b/testutil/contracts/Example.json @@ -51,6 +51,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "lastMessage", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -97,5 +110,5 @@ "type": "function" } ], - "bin": "6080604052348015600f57600080fd5b506000808190555061043f806100266000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c8063afc874d214610067578063d720cb4514610071578063dd8e556c1461007b578063de43156e14610085578063fd5ad965146100a1578063febb0f7e146100ab575b600080fd5b61006f6100c9565b005b6100796100fb565b005b610083610136565b005b61009f600480360381019061009a91906102be565b610179565b005b6100a9610187565b005b6100b3610191565b6040516100c09190610371565b60405180910390f35b6040517fbfb4ebcf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161012d906103e9565b60405180910390fd5b6000610177576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161016e906103e9565b60405180910390fd5b565b826000819055505050505050565b6001600081905550565b60005481565b600080fd5b600080fd5b600080fd5b6000606082840312156101bc576101bb6101a1565b5b81905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101f0826101c5565b9050919050565b610200816101e5565b811461020b57600080fd5b50565b60008135905061021d816101f7565b92915050565b6000819050919050565b61023681610223565b811461024157600080fd5b50565b6000813590506102538161022d565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261027e5761027d610259565b5b8235905067ffffffffffffffff81111561029b5761029a61025e565b5b6020830191508360018202830111156102b7576102b6610263565b5b9250929050565b6000806000806000608086880312156102da576102d9610197565b5b600086013567ffffffffffffffff8111156102f8576102f761019c565b5b610304888289016101a6565b95505060206103158882890161020e565b945050604061032688828901610244565b935050606086013567ffffffffffffffff8111156103475761034661019c565b5b61035388828901610268565b92509250509295509295909350565b61036b81610223565b82525050565b60006020820190506103866000830184610362565b92915050565b600082825260208201905092915050565b7f666f6f0000000000000000000000000000000000000000000000000000000000600082015250565b60006103d360038361038c565b91506103de8261039d565b602082019050919050565b60006020820190508181036000830152610402816103c6565b905091905056fea2646970667358221220c9cedad580b18532a00be1e615813af1c20bb609a0a69b5f36d49ed76cc20b5064736f6c63430008190033" + "bin": "6080604052348015600f57600080fd5b50600080819055506108e0806100266000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063dd8e556c1161005b578063dd8e556c146100b4578063de43156e146100be578063fd5ad965146100da578063febb0f7e146100e45761007d565b80633297071014610082578063afc874d2146100a0578063d720cb45146100aa575b600080fd5b61008a610102565b6040516100979190610300565b60405180910390f35b6100a8610190565b005b6100b26101c2565b005b6100bc6101fd565b005b6100d860048036038101906100d39190610449565b610240565b005b6100e2610260565b005b6100ec61026a565b6040516100f991906104fc565b60405180910390f35b6001805461010f90610546565b80601f016020809104026020016040519081016040528092919081815260200182805461013b90610546565b80156101885780601f1061015d57610100808354040283529160200191610188565b820191906000526020600020905b81548152906001019060200180831161016b57829003601f168201915b505050505081565b6040517fbfb4ebcf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101f4906105d4565b60405180910390fd5b600061023e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610235906105d4565b60405180910390fd5b565b826000819055508181600191826102589291906107da565b505050505050565b6001600081905550565b60005481565b600081519050919050565b600082825260208201905092915050565b60005b838110156102aa57808201518184015260208101905061028f565b60008484015250505050565b6000601f19601f8301169050919050565b60006102d282610270565b6102dc818561027b565b93506102ec81856020860161028c565b6102f5816102b6565b840191505092915050565b6000602082019050818103600083015261031a81846102c7565b905092915050565b600080fd5b600080fd5b600080fd5b6000606082840312156103475761034661032c565b5b81905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061037b82610350565b9050919050565b61038b81610370565b811461039657600080fd5b50565b6000813590506103a881610382565b92915050565b6000819050919050565b6103c1816103ae565b81146103cc57600080fd5b50565b6000813590506103de816103b8565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610409576104086103e4565b5b8235905067ffffffffffffffff811115610426576104256103e9565b5b602083019150836001820283011115610442576104416103ee565b5b9250929050565b60008060008060006080868803121561046557610464610322565b5b600086013567ffffffffffffffff81111561048357610482610327565b5b61048f88828901610331565b95505060206104a088828901610399565b94505060406104b1888289016103cf565b935050606086013567ffffffffffffffff8111156104d2576104d1610327565b5b6104de888289016103f3565b92509250509295509295909350565b6104f6816103ae565b82525050565b600060208201905061051160008301846104ed565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061055e57607f821691505b60208210810361057157610570610517565b5b50919050565b600082825260208201905092915050565b7f666f6f0000000000000000000000000000000000000000000000000000000000600082015250565b60006105be600383610577565b91506105c982610588565b602082019050919050565b600060208201905081810360008301526105ed816105b1565b9050919050565b600082905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026106907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610653565b61069a8683610653565b95508019841693508086168417925050509392505050565b6000819050919050565b60006106d76106d26106cd846103ae565b6106b2565b6103ae565b9050919050565b6000819050919050565b6106f1836106bc565b6107056106fd826106de565b848454610660565b825550505050565b600090565b61071a61070d565b6107258184846106e8565b505050565b5b818110156107495761073e600082610712565b60018101905061072b565b5050565b601f82111561078e5761075f8161062e565b61076884610643565b81016020851015610777578190505b61078b61078385610643565b83018261072a565b50505b505050565b600082821c905092915050565b60006107b160001984600802610793565b1980831691505092915050565b60006107ca83836107a0565b9150826002028217905092915050565b6107e483836105f4565b67ffffffffffffffff8111156107fd576107fc6105ff565b5b6108078254610546565b61081282828561074d565b6000601f831160018114610841576000841561082f578287013590505b61083985826107be565b8655506108a1565b601f19841661084f8661062e565b60005b8281101561087757848901358255600182019150602085019450602081019050610852565b868310156108945784890135610890601f8916826107a0565b8355505b6001600288020188555050505b5050505050505056fea26469706673582212202506bee512af2f3acd98556baafd9afc04b2d8c95f09bbb5e387fce570c9a32764736f6c634300081a0033" } diff --git a/testutil/contracts/Example.sol b/testutil/contracts/Example.sol index 1b36e7a15d..7109ebc60a 100644 --- a/testutil/contracts/Example.sol +++ b/testutil/contracts/Example.sol @@ -12,6 +12,7 @@ contract Example { } uint256 public bar; + bytes public lastMessage; constructor() { bar = 0; @@ -40,5 +41,6 @@ contract Example { bytes calldata message ) external { bar = amount; + lastMessage = message; } } \ No newline at end of file diff --git a/zetaclient/chains/solana/observer/inbound_test.go b/zetaclient/chains/solana/observer/inbound_test.go index 0b118ae55e..1b69266725 100644 --- a/zetaclient/chains/solana/observer/inbound_test.go +++ b/zetaclient/chains/solana/observer/inbound_test.go @@ -26,8 +26,8 @@ var ( func Test_FilterInboundEventAndVote(t *testing.T) { // load archived inbound vote tx result - // https://explorer.solana.com/tx/MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j?cluster=devnet - txHash := "MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j" + // https://explorer.solana.com/tx/24GzWsxYCFcwwJ2rzAsWwWC85aYKot6Rz3jWnBP1GvoAg5A9f1WinYyvyKseYM52q6i3EkotZdJuQomGGq5oxRYr?cluster=devnet + txHash := "24GzWsxYCFcwwJ2rzAsWwWC85aYKot6Rz3jWnBP1GvoAg5A9f1WinYyvyKseYM52q6i3EkotZdJuQomGGq5oxRYr" chain := chains.SolanaDevnet txResult := testutils.LoadSolanaInboundTxResult(t, TestDataDir, chain.ChainId, txHash, false) @@ -62,7 +62,7 @@ func Test_FilterInboundEventAndVote(t *testing.T) { func Test_FilterInboundEvents(t *testing.T) { // load archived inbound deposit tx result // https://explorer.solana.com/tx/MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j?cluster=devnet - txHash := "MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j" + txHash := "24GzWsxYCFcwwJ2rzAsWwWC85aYKot6Rz3jWnBP1GvoAg5A9f1WinYyvyKseYM52q6i3EkotZdJuQomGGq5oxRYr" chain := chains.SolanaDevnet txResult := testutils.LoadSolanaInboundTxResult(t, TestDataDir, chain.ChainId, txHash, false) @@ -77,14 +77,15 @@ func Test_FilterInboundEvents(t *testing.T) { require.NoError(t, err) // expected result - sender := "AS48jKNQsDGkEdDvfwu1QpqjtqbCadrAq9nGXjFmdX3Z" + sender := "HgTpiVRvjUPUcWLzdmCgdadu1GceJNgBWLoN9r66p8o3" + expectedMemo := []byte{109, 163, 11, 250, 101, 232, 90, 22, 176, 91, 206, 56, 70, 51, 158, 210, 188, 116, 99, 22} eventExpected := &clienttypes.InboundEvent{ SenderChainID: chain.ChainId, Sender: sender, Receiver: sender, TxOrigin: sender, - Amount: 100000, - Memo: []byte("0x7F8ae2ABb69A558CE6bAd546f25F0464D9e09e5B4955a3F38ff86ae92A914445099caa8eA2B9bA32"), + Amount: 100000000, + Memo: expectedMemo, BlockNumber: txResult.Slot, TxHash: txHash, Index: 0, // not a EVM smart contract call diff --git a/zetaclient/testdata/solana/chain_901_inbound_tx_result_24GzWsxYCFcwwJ2rzAsWwWC85aYKot6Rz3jWnBP1GvoAg5A9f1WinYyvyKseYM52q6i3EkotZdJuQomGGq5oxRYr.json b/zetaclient/testdata/solana/chain_901_inbound_tx_result_24GzWsxYCFcwwJ2rzAsWwWC85aYKot6Rz3jWnBP1GvoAg5A9f1WinYyvyKseYM52q6i3EkotZdJuQomGGq5oxRYr.json new file mode 100644 index 0000000000..92c3db0852 --- /dev/null +++ b/zetaclient/testdata/solana/chain_901_inbound_tx_result_24GzWsxYCFcwwJ2rzAsWwWC85aYKot6Rz3jWnBP1GvoAg5A9f1WinYyvyKseYM52q6i3EkotZdJuQomGGq5oxRYr.json @@ -0,0 +1,102 @@ +{ + "slot": 345001398, + "blockTime": 1733460726, + "transaction": { + "signatures": [ + "24GzWsxYCFcwwJ2rzAsWwWC85aYKot6Rz3jWnBP1GvoAg5A9f1WinYyvyKseYM52q6i3EkotZdJuQomGGq5oxRYr" + ], + "message": { + "accountKeys": [ + "HgTpiVRvjUPUcWLzdmCgdadu1GceJNgBWLoN9r66p8o3", + "2f9SLuUNb7TNeM6gzBwT4ZjbL5ZyKzzHg1Ce9yiquEjj", + "11111111111111111111111111111111", + "ComputeBudget111111111111111111111111111111", + "94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d" + ], + "header": { + "numRequiredSignatures": 1, + "numReadonlySignedAccounts": 0, + "numReadonlyUnsignedAccounts": 3 + }, + "recentBlockhash": "6Fu7CVZSkaSys51PsAJJ5T2UF9HrZo9QksRNWJQfSPK2", + "instructions": [ + { + "programIdIndex": 3, + "accounts": [], + "data": "3gJqkocMWaMm" + }, + { + "programIdIndex": 3, + "accounts": [], + "data": "Fj2Eoy" + }, + { + "programIdIndex": 4, + "accounts": [ + 0, + 1, + 2 + ], + "data": "2qe8pjwrUAq1a3qRZeuPZdkpNS1yz6BHwpJmE23Nou9YcXuyxZ" + } + ] + } + }, + "meta": { + "err": null, + "fee": 25000, + "preBalances": [ + 10000000000, + 21298797680, + 1, + 1, + 1141440 + ], + "postBalances": [ + 9899975000, + 21398797680, + 1, + 1, + 1141440 + ], + "innerInstructions": [ + { + "index": 0, + "instructions": [ + { + "programIdIndex": 2, + "accounts": [ + 0, + 1 + ], + "data": "3Bxs411Dtc7pkFQj" + } + ] + } + ], + "preTokenBalances": [], + "postTokenBalances": [], + "logMessages": [ + "Program ComputeBudget111111111111111111111111111111 invoke [1]", + "Program ComputeBudget111111111111111111111111111111 success", + "Program ComputeBudget111111111111111111111111111111 invoke [1]", + "Program ComputeBudget111111111111111111111111111111 success", + "Program ZETAjseVjuFsxdRxo6MmTCvqFwb3ZHUx56Co3vCmGis invoke [1]", + "Program log: Instruction: Deposit Program 11111111111111111111111111111111 invoke [2]", + "Program 11111111111111111111111111111111 success", + "Program log: HgTpiVRvjUPUcWLzdmCgdadu1GceJNgBWLoN9r66p8o3 deposits 100000000 lamports to PDA; receiver [109, 163, 11, 250, 101, 232, 90, 22, 176, 91, 206, 56, 70, 51, 158, 210, 188, 116, 99, 22]", + "Program ZETAjseVjuFsxdRxo6MmTCvqFwb3ZHUx56Co3vCmGis consumed 23371 of 199700 compute units", + "Program ZETAjseVjuFsxdRxo6MmTCvqFwb3ZHUx56Co3vCmGis success" + ], + "status": { + "Ok": null + }, + "rewards": [], + "loadedAddresses": { + "readonly": [], + "writable": [] + }, + "computeUnitsConsumed": 274899583472 + }, + "version": 0 +} \ No newline at end of file diff --git a/zetaclient/testdata/solana/chain_901_inbound_tx_result_MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j.json b/zetaclient/testdata/solana/chain_901_inbound_tx_result_MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j.json deleted file mode 100644 index cf7edb3b81..0000000000 --- a/zetaclient/testdata/solana/chain_901_inbound_tx_result_MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "slot": 321701608, - "blockTime": 1724732369, - "transaction": { - "signatures": [ - "MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j" - ], - "message": { - "accountKeys": [ - "AS48jKNQsDGkEdDvfwu1QpqjtqbCadrAq9nGXjFmdX3Z", - "9dcAyYG4bawApZocwZSyJBi9Mynf5EuKAJfifXdfkqik", - "11111111111111111111111111111111", - "94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d" - ], - "header": { - "numRequiredSignatures": 1, - "numReadonlySignedAccounts": 0, - "numReadonlyUnsignedAccounts": 2 - }, - "recentBlockhash": "41txNvjedo2eu6aAofQfyLskAcgtrtgch9RpqnrKcv1a", - "instructions": [ - { - "programIdIndex": 3, - "accounts": [0, 1, 2], - "data": "4ALHYcAj3zFsNjmfeq7nDK1E8BsxRQRzhLjrqzmjYzL97Qkiz4rP1iQePmFAehfFEET7uczYLhhEVhtndBYNNm6ekHSkgsLzYDeSD2JSudHa6D5tqhVGjvXZ7qEouPiy9eptZfuYHE9X" - } - ] - } - }, - "meta": { - "err": null, - "fee": 5000, - "preBalances": [9999364000, 1001447680, 1, 1141440], - "postBalances": [9999259000, 1001547680, 1, 1141440], - "innerInstructions": [ - { - "index": 0, - "instructions": [ - { - "programIdIndex": 2, - "accounts": [0, 1], - "data": "3Bxs4ThwQbE4vyj5" - } - ] - } - ], - "preTokenBalances": [], - "postTokenBalances": [], - "logMessages": [ - "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d invoke [1]", - "Program log: Instruction: Deposit", - "Program 11111111111111111111111111111111 invoke [2]", - "Program 11111111111111111111111111111111 success", - "Program log: AS48jKNQsDGkEdDvfwu1QpqjtqbCadrAq9nGXjFmdX3Z deposits 100000 lamports to PDA", - "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d consumed 17006 of 200000 compute units", - "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d success" - ], - "status": { "Ok": null }, - "rewards": [], - "loadedAddresses": { "readonly": [], "writable": [] }, - "computeUnitsConsumed": 17006 - }, - "version": 0 -} From ba3cd55917b4ccc2b147bc6c50ef8b446ca48cd6 Mon Sep 17 00:00:00 2001 From: skosito Date: Mon, 9 Dec 2024 19:45:34 +0100 Subject: [PATCH 2/2] fmt --- pkg/contracts/solana/inbound_test.go | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/pkg/contracts/solana/inbound_test.go b/pkg/contracts/solana/inbound_test.go index b8d1354a1f..bce251d977 100644 --- a/pkg/contracts/solana/inbound_test.go +++ b/pkg/contracts/solana/inbound_test.go @@ -160,7 +160,28 @@ func Test_ParseInboundAsDepositAndCall(t *testing.T) { // solana e2e deployer account sender := "37yGiHAnLvWZUNVwu9esp74YQFqxU1qHCbABkDvRddUQ" // example contract deployed during e2e test, read from tx result - expectedReceiver := []byte{117, 160, 106, 140, 37, 135, 57, 218, 223, 226, 53, 45, 87, 151, 61, 239, 158, 231, 162, 186} + expectedReceiver := []byte{ + 117, + 160, + 106, + 140, + 37, + 135, + 57, + 218, + 223, + 226, + 53, + 45, + 87, + 151, + 61, + 239, + 158, + 231, + 162, + 186, + } expectedMsg := []byte("hello lamports") expectedDeposit := &Deposit{ Sender: sender,