ZpokenWeb3 / solana-zkvm

MIT License
18 stars 1 forks source link

Transaction Processing Errors #2

Open staaason opened 2 months ago

staaason commented 2 months ago

An error occurs when processing some transactions from Mainnet in solana simulator, even though they are successful on Solscan:

  1. Transfer method Tx link. Request:

    let signature = Signature::from_str("2HhAkLFU8mQns6QDKaYjbXriz5YVa5zL9qKrqYQe6KpvNsFXcgnNpZVknqCD1RbLLVyTFKhiALTBhcyuqp6vgCUH").unwrap();
    let transaction = rpc.get_transaction(&signature).await.unwrap().unwrap();
    
    let mut transactions: Vec<VersionedTransaction> = vec![];
    transactions.push(transaction);
    
    let request = SimulateSolanaRequest{
        compute_units: None,
        heap_size: None,
        account_limit: None,
        verify: Some(true),
        blockhash: Hash::from_str("FWoJner1DV78aturADK1tutbU9nPUiC1XYv9SupJ89BG").unwrap().to_bytes(),
        transactions,
        id: None,
    };

    Full log:

    SimulateSolanaTransactionResult { error: Some(InstructionError(2, Custom(1))), logs: ["Program ComputeBudget111111111111111111111111111111 invoke [1]", "Program ComputeBudget111111111111111111111111111111 success", "Program ComputeBudget111111111111111111111111111111 invoke [1]", "Program ComputeBudget111111111111111111111111111111 success", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [1]", "Program log: Instruction: Transfer", "Program log: Error: insufficient funds", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4381 of 1399700 compute units", "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA failed: custom program error: 0x1"], executed_units: 4737 }

  2. Monaco cancel order program Tx link Request:

    let signature = Signature::from_str("61HojDTQ1yHgarHwM3uSPxYsQ4stbAY6QJ79jifmwuEQ2kbmfNVopcnnLYhoPstLGThB9By17w1mrC1j5aPA8qtK").unwrap();
    let transaction = rpc.get_transaction(&signature).await.unwrap().unwrap();
    
    let mut transactions: Vec<VersionedTransaction> = vec![];
    transactions.push(transaction);
    
    let request = SimulateSolanaRequest{
        compute_units: None,
        heap_size: None,
        account_limit: None,
        verify: Some(true),
        blockhash: Hash::from_str("F9cTsMny8dpUneZU7vvskCpd7D61HT8u6Wy2nUzH2qxb").unwrap().to_bytes(),
        transactions,
        id: None,
    };

    Full log:

SimulateSolanaTransactionResult { error: Some(InstructionError(0, Custom(3012))), logs: ["Program monacoUXKtUi6vKsQwaLyxmXKSievfNWEcYXTgkbCih invoke [1]", "Program log: Instruction: CancelOrder", "Program log: AnchorError caused by account: order. Error Code: AccountNotInitialized. Error Number: 3012. Error Message: The program expected this account to be already initialized.", "Program monacoUXKtUi6vKsQwaLyxmXKSievfNWEcYXTgkbCih consumed 6195 of 1400000 compute units", "Program monacoUXKtUi6vKsQwaLyxmXKSievfNWEcYXTgkbCih failed: custom program error: 0xbc4"], executed_units: 6251 }

Calls were made from the host in this file and link to the program logic .

The exact issues occurred in the native Solana simulator.

afalaleev commented 2 months ago

The root cause is that Solana doesn't have a Merkle Patricie Tree like Ethereum, and it doesn't have methods to get an account state BEFORE the transaction execution. It just has the RPC method to get not-committed/confirmed/finalized account state.

So the simulator in the following method loads the CURRENT account state: https://github.com/ZpokenWeb3/solana-zkvm/blob/203ec62cdc253b09805808a929fc3fa746e96ad5/risczero/methods/core/src/solana_simulator/mod.rs#L160

Case 1. Account https://solscan.io/account/8yjT3DD1ZfYDDrVJe23hhPsU1ag591s3WYKRP7sQkVBH in the current Solana state doesn't have tokens, and the transaction simulation failed with the corresponding error:

Program log: Error: insufficient funds

Case 2. Account https://solscan.io/account/3QCk918PfqHFaT8c3fewVT3JAXcgdXo9keDX3reXp5Sf doesn't exist anymore in the current Solana state, and the transaction simulation failed with the corresponding error:

Program log: AnchorError caused by account: order. Error Code: AccountNotInitialized. Error Number: 3012. Error Message: The program expected this account to be already initialized.

So, to resolve the issue, you should provide the account state that is valid for the transaction execution.