diff --git a/changelog.md b/changelog.md index a97efce164..21fd879a02 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,11 @@ # CHANGELOG +## V19.2.1 + +### Features + +* [2778](https://github.com/zeta-chain/node/pull/2778) - ask for 3 accounts (signer, pda, system_program) on solana gateway deposit + ## v19.2.0 ### Features diff --git a/e2e/runner/solana.go b/e2e/runner/solana.go index 7854e62716..9b9f0c40af 100644 --- a/e2e/runner/solana.go +++ b/e2e/runner/solana.go @@ -43,7 +43,6 @@ func (r *E2ERunner) CreateDepositInstruction( accountSlice = append(accountSlice, solana.Meta(signer).WRITE().SIGNER()) accountSlice = append(accountSlice, solana.Meta(pdaComputed).WRITE()) accountSlice = append(accountSlice, solana.Meta(solana.SystemProgramID)) - accountSlice = append(accountSlice, solana.Meta(programID)) inst.ProgID = programID inst.AccountValues = accountSlice diff --git a/pkg/contracts/solana/gateway.go b/pkg/contracts/solana/gateway.go index 356614e4ce..a8f0c571e5 100644 --- a/pkg/contracts/solana/gateway.go +++ b/pkg/contracts/solana/gateway.go @@ -14,8 +14,8 @@ const ( PDASeed = "meta" // AccountsNumberOfDeposit is the number of accounts required for Solana gateway deposit instruction - // [signer, pda, system_program, gateway_program] - AccountsNumDeposit = 4 + // [signer, pda, system_program] + AccountsNumDeposit = 3 ) // DiscriminatorInitialize returns the discriminator for Solana gateway 'initialize' instruction diff --git a/zetaclient/chains/solana/observer/inbound.go b/zetaclient/chains/solana/observer/inbound.go index cf05f94cf9..3a905e83e9 100644 --- a/zetaclient/chains/solana/observer/inbound.go +++ b/zetaclient/chains/solana/observer/inbound.go @@ -285,10 +285,11 @@ func (ob *Observer) ParseInboundAsDeposit( return nil, nil } - // get the sender address (the signer must exist) + // get the sender address (skip if unable to parse signer address) sender, err := ob.GetSignerDeposit(tx, &instruction) if err != nil { - return nil, errors.Wrap(err, "error GetSignerDeposit") + ob.Logger().Inbound.Err(err).Msgf("unable to get signer for sig %s instruction %d", tx.Signatures[0], instructionIndex) + return nil, nil } // build inbound event @@ -323,13 +324,13 @@ func (ob *Observer) ParseInboundAsDepositSPL( // GetSignerDeposit returns the signer address of the deposit instruction // Note: solana-go is not able to parse the AccountMeta 'is_signer' ATM. This is a workaround. func (ob *Observer) GetSignerDeposit(tx *solana.Transaction, inst *solana.CompiledInstruction) (string, error) { - // there should be 4 accounts for a deposit instruction + // there should be 3 accounts for a deposit instruction if len(inst.Accounts) != solanacontracts.AccountsNumDeposit { return "", fmt.Errorf("want %d accounts, got %d", solanacontracts.AccountsNumDeposit, len(inst.Accounts)) } - // the accounts are [signer, pda, system_program, gateway_program] - signerIndex, pdaIndex, systemIndex, gatewayIndex := -1, -1, -1, -1 + // the accounts are [signer, pda, system_program] + signerIndex, pdaIndex, systemIndex := -1, -1, -1 // try to find the indexes of all above accounts for _, accIndex := range inst.Accounts { @@ -340,8 +341,6 @@ func (ob *Observer) GetSignerDeposit(tx *solana.Transaction, inst *solana.Compil switch accKey { case ob.pda: pdaIndex = accIndexInt - case ob.gatewayID: - gatewayIndex = accIndexInt case solana.SystemProgramID: systemIndex = accIndexInt default: @@ -351,7 +350,7 @@ func (ob *Observer) GetSignerDeposit(tx *solana.Transaction, inst *solana.Compil } // all above accounts must be found - if signerIndex == -1 || pdaIndex == -1 || systemIndex == -1 || gatewayIndex == -1 { + if signerIndex == -1 || pdaIndex == -1 || systemIndex == -1 { return "", fmt.Errorf("invalid accounts for deposit instruction") } diff --git a/zetaclient/chains/solana/observer/inbound_test.go b/zetaclient/chains/solana/observer/inbound_test.go index 40f53ce0bc..2ead330d12 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/5LuQMorgd11p8GWEw6pmyHCDtA26NUyeNFhLWPNk2oBoM9pkag1LzhwGSRos3j4TJLhKjswFhZkGtvSGdLDkmqsk?cluster=devnet - txHash := "5LuQMorgd11p8GWEw6pmyHCDtA26NUyeNFhLWPNk2oBoM9pkag1LzhwGSRos3j4TJLhKjswFhZkGtvSGdLDkmqsk" + // https://explorer.solana.com/tx/MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j?cluster=devnet + txHash := "MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j" chain := chains.SolanaDevnet txResult := testutils.LoadSolanaInboundTxResult(t, TestDataDir, chain.ChainId, txHash, false) @@ -51,8 +51,8 @@ func Test_FilterInboundEventAndVote(t *testing.T) { func Test_FilterInboundEvents(t *testing.T) { // load archived inbound deposit tx result - // https://explorer.solana.com/tx/5LuQMorgd11p8GWEw6pmyHCDtA26NUyeNFhLWPNk2oBoM9pkag1LzhwGSRos3j4TJLhKjswFhZkGtvSGdLDkmqsk?cluster=devnet - txHash := "5LuQMorgd11p8GWEw6pmyHCDtA26NUyeNFhLWPNk2oBoM9pkag1LzhwGSRos3j4TJLhKjswFhZkGtvSGdLDkmqsk" + // https://explorer.solana.com/tx/MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j?cluster=devnet + txHash := "MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j" chain := chains.SolanaDevnet txResult := testutils.LoadSolanaInboundTxResult(t, TestDataDir, chain.ChainId, txHash, false) @@ -61,20 +61,20 @@ func Test_FilterInboundEvents(t *testing.T) { // create observer chainParams := sample.ChainParams(chain.ChainId) - chainParams.GatewayAddress = GatewayAddressTest + chainParams.GatewayAddress = testutils.GatewayAddresses[chain.ChainId] ob, err := observer.NewObserver(chain, nil, *chainParams, nil, nil, database, base.DefaultLogger(), nil) require.NoError(t, err) // expected result - sender := "AKbG83jg2V65R7XvaPFrnUvUTWsFENEzDPbLJFEiAk6L" + sender := "AS48jKNQsDGkEdDvfwu1QpqjtqbCadrAq9nGXjFmdX3Z" eventExpected := &clienttypes.InboundEvent{ SenderChainID: chain.ChainId, Sender: sender, Receiver: sender, TxOrigin: sender, - Amount: 1280, - Memo: []byte("hello this is a good memo for you to enjoy"), + Amount: 100000, + Memo: []byte("0x7F8ae2ABb69A558CE6bAd546f25F0464D9e09e5B4955a3F38ff86ae92A914445099caa8eA2B9bA32"), BlockNumber: txResult.Slot, TxHash: txHash, Index: 0, // not a EVM smart contract call @@ -156,8 +156,8 @@ func Test_BuildInboundVoteMsgFromEvent(t *testing.T) { func Test_ParseInboundAsDeposit(t *testing.T) { // load archived inbound deposit tx result - // https://explorer.solana.com/tx/5LuQMorgd11p8GWEw6pmyHCDtA26NUyeNFhLWPNk2oBoM9pkag1LzhwGSRos3j4TJLhKjswFhZkGtvSGdLDkmqsk?cluster=devnet - txHash := "5LuQMorgd11p8GWEw6pmyHCDtA26NUyeNFhLWPNk2oBoM9pkag1LzhwGSRos3j4TJLhKjswFhZkGtvSGdLDkmqsk" + // https://explorer.solana.com/tx/MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j?cluster=devnet + txHash := "MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j" chain := chains.SolanaDevnet txResult := testutils.LoadSolanaInboundTxResult(t, TestDataDir, chain.ChainId, txHash, false) @@ -169,19 +169,19 @@ func Test_ParseInboundAsDeposit(t *testing.T) { // create observer chainParams := sample.ChainParams(chain.ChainId) - chainParams.GatewayAddress = GatewayAddressTest + chainParams.GatewayAddress = testutils.GatewayAddresses[chain.ChainId] ob, err := observer.NewObserver(chain, nil, *chainParams, nil, nil, database, base.DefaultLogger(), nil) require.NoError(t, err) // expected result - sender := "AKbG83jg2V65R7XvaPFrnUvUTWsFENEzDPbLJFEiAk6L" + sender := "AS48jKNQsDGkEdDvfwu1QpqjtqbCadrAq9nGXjFmdX3Z" eventExpected := &clienttypes.InboundEvent{ SenderChainID: chain.ChainId, Sender: sender, Receiver: sender, TxOrigin: sender, - Amount: 1280, - Memo: []byte("hello this is a good memo for you to enjoy"), + Amount: 100000, + Memo: []byte("0x7F8ae2ABb69A558CE6bAd546f25F0464D9e09e5B4955a3F38ff86ae92A914445099caa8eA2B9bA32"), BlockNumber: txResult.Slot, TxHash: txHash, Index: 0, // not a EVM smart contract call diff --git a/zetaclient/testdata/solana/chain_901_inbound_tx_result_5LuQMorgd11p8GWEw6pmyHCDtA26NUyeNFhLWPNk2oBoM9pkag1LzhwGSRos3j4TJLhKjswFhZkGtvSGdLDkmqsk.json b/zetaclient/testdata/solana/chain_901_inbound_tx_result_5LuQMorgd11p8GWEw6pmyHCDtA26NUyeNFhLWPNk2oBoM9pkag1LzhwGSRos3j4TJLhKjswFhZkGtvSGdLDkmqsk.json deleted file mode 100644 index 4e5b8bdb98..0000000000 --- a/zetaclient/testdata/solana/chain_901_inbound_tx_result_5LuQMorgd11p8GWEw6pmyHCDtA26NUyeNFhLWPNk2oBoM9pkag1LzhwGSRos3j4TJLhKjswFhZkGtvSGdLDkmqsk.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "slot": 309926562, - "blockTime": 1720328277, - "transaction": { - "signatures": [ - "5LuQMorgd11p8GWEw6pmyHCDtA26NUyeNFhLWPNk2oBoM9pkag1LzhwGSRos3j4TJLhKjswFhZkGtvSGdLDkmqsk" - ], - "message": { - "accountKeys": [ - "AKbG83jg2V65R7XvaPFrnUvUTWsFENEzDPbLJFEiAk6L", - "4pA5vqGeo4ipLoJzH3rdvguhifj1tCzoNM8vDRc4Xbmq", - "11111111111111111111111111111111", - "2kJndCL9NBR36ySiQ4bmArs4YgWQu67LmCDfLzk5Gb7s" - ], - "header": { - "numRequiredSignatures": 1, - "numReadonlySignedAccounts": 0, - "numReadonlyUnsignedAccounts": 2 - }, - "recentBlockhash": "9BYDuzjYhac5AqhsV3H3wNtj3tK1aT6k2oFLpTo1h3nL", - "instructions": [ - { - "programIdIndex": 3, - "accounts": [0, 1, 2, 3], - "data": "FQx87VJVvGQu6jGz7VmavZREFcSxTNNuB5hWd7npbi5M9CzWRjjcAaW9woj8WpxPcB9C9gmQYeYXTEsJ1mZ7W" - } - ] - } - }, - "meta": { - "err": null, - "fee": 5000, - "preBalances": [3171104080, 1447680, 1, 1141440], - "postBalances": [3171097800, 1448960, 1, 1141440], - "innerInstructions": [ - { - "index": 0, - "instructions": [ - { - "programIdIndex": 2, - "accounts": [0, 1], - "data": "3Bxs3zrrEsuzMyc3" - } - ] - } - ], - "preTokenBalances": [], - "postTokenBalances": [], - "logMessages": [ - "Program 2kJndCL9NBR36ySiQ4bmArs4YgWQu67LmCDfLzk5Gb7s invoke [1]", - "Program log: Instruction: Deposit", - "Program 11111111111111111111111111111111 invoke [2]", - "Program 11111111111111111111111111111111 success", - "Program log: AKbG83jg2V65R7XvaPFrnUvUTWsFENEzDPbLJFEiAk6L deposits 1280 lamports to PDA", - "Program 2kJndCL9NBR36ySiQ4bmArs4YgWQu67LmCDfLzk5Gb7s consumed 16968 of 200000 compute units", - "Program 2kJndCL9NBR36ySiQ4bmArs4YgWQu67LmCDfLzk5Gb7s success" - ], - "status": { "Ok": null }, - "rewards": [], - "loadedAddresses": { "readonly": [], "writable": [] }, - "computeUnitsConsumed": 16968 - }, - "version": 0 -} diff --git a/zetaclient/testdata/solana/chain_901_inbound_tx_result_MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j.json b/zetaclient/testdata/solana/chain_901_inbound_tx_result_MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j.json new file mode 100644 index 0000000000..210d639ead --- /dev/null +++ b/zetaclient/testdata/solana/chain_901_inbound_tx_result_MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j.json @@ -0,0 +1,64 @@ +{ + "slot": 321701608, + "blockTime": 1724732369, + "transaction": { + "signatures": [ + "MS3MPLN7hkbyCZFwKqXcg8fmEvQMD74fN6Ps2LSWXJoRxPW5ehaxBorK9q1JFVbqnAvu9jXm6ertj7kT7HpYw1j" + ], + "message": { + "accountKeys": [ + "AS48jKNQsDGkEdDvfwu1QpqjtqbCadrAq9nGXjFmdX3Z", + "2f9SLuUNb7TNeM6gzBwT4ZjbL5ZyKzzHg1Ce9yiquEjj", + "11111111111111111111111111111111", + "ZETAjseVjuFsxdRxo6MmTCvqFwb3ZHUx56Co3vCmGis" + ], + "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 ZETAjseVjuFsxdRxo6MmTCvqFwb3ZHUx56Co3vCmGis invoke [1]", + "Program log: Instruction: Deposit", + "Program 11111111111111111111111111111111 invoke [2]", + "Program 11111111111111111111111111111111 success", + "Program log: AS48jKNQsDGkEdDvfwu1QpqjtqbCadrAq9nGXjFmdX3Z deposits 100000 lamports to PDA", + "Program ZETAjseVjuFsxdRxo6MmTCvqFwb3ZHUx56Co3vCmGis consumed 17006 of 200000 compute units", + "Program ZETAjseVjuFsxdRxo6MmTCvqFwb3ZHUx56Co3vCmGis success" + ], + "status": { "Ok": null }, + "rewards": [], + "loadedAddresses": { "readonly": [], "writable": [] }, + "computeUnitsConsumed": 17006 + }, + "version": 0 +} diff --git a/zetaclient/testutils/constant.go b/zetaclient/testutils/constant.go index 3036035db4..a5af7f7d09 100644 --- a/zetaclient/testutils/constant.go +++ b/zetaclient/testutils/constant.go @@ -36,7 +36,7 @@ const ( // GatewayAddresses contains constants gateway addresses for testing var GatewayAddresses = map[int64]string{ // Gateway address on Solana devnet - chains.SolanaDevnet.ChainId: "94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d", + chains.SolanaDevnet.ChainId: "ZETAjseVjuFsxdRxo6MmTCvqFwb3ZHUx56Co3vCmGis", } // ConnectorAddresses contains constants ERC20 connector addresses for testing