Move TransactionError into the SDK
This commit is contained in:
@ -16,9 +16,9 @@ use crate::service::Service;
|
|||||||
use crate::sigverify_stage::VerifiedPackets;
|
use crate::sigverify_stage::VerifiedPackets;
|
||||||
use bincode::deserialize;
|
use bincode::deserialize;
|
||||||
use solana_metrics::counter::Counter;
|
use solana_metrics::counter::Counter;
|
||||||
use solana_runtime::bank::{self, Bank, TransactionError};
|
use solana_runtime::bank::{self, Bank};
|
||||||
use solana_sdk::timing::{self, duration_as_us, MAX_RECENT_BLOCKHASHES};
|
use solana_sdk::timing::{self, duration_as_us, MAX_RECENT_BLOCKHASHES};
|
||||||
use solana_sdk::transaction::Transaction;
|
use solana_sdk::transaction::{Transaction, TransactionError};
|
||||||
use std::net::UdpSocket;
|
use std::net::UdpSocket;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::mpsc::{Receiver, RecvTimeoutError};
|
use std::sync::mpsc::{Receiver, RecvTimeoutError};
|
||||||
@ -445,10 +445,10 @@ mod tests {
|
|||||||
use crate::entry::EntrySlice;
|
use crate::entry::EntrySlice;
|
||||||
use crate::packet::to_packets;
|
use crate::packet::to_packets;
|
||||||
use crate::poh_recorder::WorkingBank;
|
use crate::poh_recorder::WorkingBank;
|
||||||
use solana_runtime::runtime::InstructionError;
|
|
||||||
use solana_sdk::genesis_block::GenesisBlock;
|
use solana_sdk::genesis_block::GenesisBlock;
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||||
use solana_sdk::system_transaction::SystemTransaction;
|
use solana_sdk::system_transaction::SystemTransaction;
|
||||||
|
use solana_sdk::transaction::InstructionError;
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
|
|
||||||
|
@ -229,11 +229,11 @@ mod tests {
|
|||||||
use crate::blocktree::create_new_tmp_ledger;
|
use crate::blocktree::create_new_tmp_ledger;
|
||||||
use crate::blocktree::tests::entries_to_blobs;
|
use crate::blocktree::tests::entries_to_blobs;
|
||||||
use crate::entry::{create_ticks, next_entry, Entry};
|
use crate::entry::{create_ticks, next_entry, Entry};
|
||||||
use solana_runtime::bank::TransactionError;
|
|
||||||
use solana_sdk::genesis_block::GenesisBlock;
|
use solana_sdk::genesis_block::GenesisBlock;
|
||||||
use solana_sdk::hash::Hash;
|
use solana_sdk::hash::Hash;
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||||
use solana_sdk::system_transaction::SystemTransaction;
|
use solana_sdk::system_transaction::SystemTransaction;
|
||||||
|
use solana_sdk::transaction::TransactionError;
|
||||||
|
|
||||||
fn fill_blocktree_slot_with_ticks(
|
fn fill_blocktree_slot_with_ticks(
|
||||||
blocktree: &Blocktree,
|
blocktree: &Blocktree,
|
||||||
|
@ -8,7 +8,7 @@ use crate::packet;
|
|||||||
use crate::poh_recorder;
|
use crate::poh_recorder;
|
||||||
use bincode;
|
use bincode;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use solana_runtime::bank;
|
use solana_sdk::transaction;
|
||||||
use std;
|
use std;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ pub enum Error {
|
|||||||
RecvTimeoutError(std::sync::mpsc::RecvTimeoutError),
|
RecvTimeoutError(std::sync::mpsc::RecvTimeoutError),
|
||||||
TryRecvError(std::sync::mpsc::TryRecvError),
|
TryRecvError(std::sync::mpsc::TryRecvError),
|
||||||
Serialize(std::boxed::Box<bincode::ErrorKind>),
|
Serialize(std::boxed::Box<bincode::ErrorKind>),
|
||||||
TransactionError(bank::TransactionError),
|
TransactionError(transaction::TransactionError),
|
||||||
ClusterInfoError(cluster_info::ClusterInfoError),
|
ClusterInfoError(cluster_info::ClusterInfoError),
|
||||||
BlobError(packet::BlobError),
|
BlobError(packet::BlobError),
|
||||||
#[cfg(feature = "erasure")]
|
#[cfg(feature = "erasure")]
|
||||||
@ -57,8 +57,8 @@ impl std::convert::From<std::sync::mpsc::RecvTimeoutError> for Error {
|
|||||||
Error::RecvTimeoutError(e)
|
Error::RecvTimeoutError(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl std::convert::From<bank::TransactionError> for Error {
|
impl std::convert::From<transaction::TransactionError> for Error {
|
||||||
fn from(e: bank::TransactionError) -> Error {
|
fn from(e: transaction::TransactionError) -> Error {
|
||||||
Error::TransactionError(e)
|
Error::TransactionError(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,11 @@ use bs58;
|
|||||||
use jsonrpc_core::{Error, ErrorCode, Metadata, Result};
|
use jsonrpc_core::{Error, ErrorCode, Metadata, Result};
|
||||||
use jsonrpc_derive::rpc;
|
use jsonrpc_derive::rpc;
|
||||||
use solana_drone::drone::request_airdrop_transaction;
|
use solana_drone::drone::request_airdrop_transaction;
|
||||||
use solana_runtime::bank::{self, Bank, TransactionError};
|
use solana_runtime::bank::{self, Bank};
|
||||||
use solana_sdk::account::Account;
|
use solana_sdk::account::Account;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use solana_sdk::signature::Signature;
|
use solana_sdk::signature::Signature;
|
||||||
use solana_sdk::transaction::Transaction;
|
use solana_sdk::transaction::{Transaction, TransactionError};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::net::{SocketAddr, UdpSocket};
|
use std::net::{SocketAddr, UdpSocket};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
@ -6,10 +6,11 @@ use core::hash::Hash;
|
|||||||
use jsonrpc_core::futures::Future;
|
use jsonrpc_core::futures::Future;
|
||||||
use jsonrpc_pubsub::typed::Sink;
|
use jsonrpc_pubsub::typed::Sink;
|
||||||
use jsonrpc_pubsub::SubscriptionId;
|
use jsonrpc_pubsub::SubscriptionId;
|
||||||
use solana_runtime::bank::{self, Bank, TransactionError};
|
use solana_runtime::bank::{self, Bank};
|
||||||
use solana_sdk::account::Account;
|
use solana_sdk::account::Account;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use solana_sdk::signature::Signature;
|
use solana_sdk::signature::Signature;
|
||||||
|
use solana_sdk::transaction::TransactionError;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
|
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use solana_runtime::bank::TransactionError;
|
|
||||||
use solana_runtime::loader_utils::load_program;
|
use solana_runtime::loader_utils::load_program;
|
||||||
use solana_runtime::runtime::InstructionError;
|
|
||||||
use solana_sdk::genesis_block::GenesisBlock;
|
use solana_sdk::genesis_block::GenesisBlock;
|
||||||
use solana_sdk::native_loader;
|
use solana_sdk::native_loader;
|
||||||
use solana_sdk::native_program::ProgramError;
|
use solana_sdk::native_program::ProgramError;
|
||||||
use solana_sdk::transaction::Transaction;
|
use solana_sdk::transaction::{InstructionError, Transaction, TransactionError};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_program_native_failure() {
|
fn test_program_native_failure() {
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
use solana_runtime::bank::TransactionError;
|
|
||||||
use solana_runtime::bank::{Bank, Result};
|
use solana_runtime::bank::{Bank, Result};
|
||||||
use solana_runtime::runtime::InstructionError;
|
|
||||||
use solana_sdk::genesis_block::GenesisBlock;
|
use solana_sdk::genesis_block::GenesisBlock;
|
||||||
use solana_sdk::hash::hash;
|
use solana_sdk::hash::hash;
|
||||||
use solana_sdk::native_program::ProgramError;
|
use solana_sdk::native_program::ProgramError;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||||
use solana_sdk::system_instruction::SystemInstruction;
|
use solana_sdk::system_instruction::SystemInstruction;
|
||||||
|
use solana_sdk::transaction::{InstructionError, TransactionError};
|
||||||
use solana_sdk::transaction_builder::{BuilderInstruction, TransactionBuilder};
|
use solana_sdk::transaction_builder::{BuilderInstruction, TransactionBuilder};
|
||||||
use solana_vote_api::vote_instruction::{Vote, VoteInstruction};
|
use solana_vote_api::vote_instruction::{Vote, VoteInstruction};
|
||||||
use solana_vote_api::vote_state::VoteState;
|
use solana_vote_api::vote_state::VoteState;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::append_vec::AppendVec;
|
use crate::append_vec::AppendVec;
|
||||||
use crate::bank::{Result, TransactionError};
|
use crate::bank::Result;
|
||||||
use crate::runtime::has_duplicates;
|
use crate::runtime::has_duplicates;
|
||||||
use bincode::serialize;
|
use bincode::serialize;
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
@ -11,7 +11,7 @@ use solana_sdk::hash::{hash, Hash};
|
|||||||
use solana_sdk::native_loader;
|
use solana_sdk::native_loader;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||||
use solana_sdk::transaction::Transaction;
|
use solana_sdk::transaction::{Transaction, TransactionError};
|
||||||
use solana_vote_api;
|
use solana_vote_api;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use crate::accounts::{Accounts, ErrorCounters, InstructionAccounts, InstructionLoaders};
|
use crate::accounts::{Accounts, ErrorCounters, InstructionAccounts, InstructionLoaders};
|
||||||
use crate::hash_queue::HashQueue;
|
use crate::hash_queue::HashQueue;
|
||||||
use crate::runtime::{self, InstructionError};
|
use crate::runtime;
|
||||||
use crate::status_cache::StatusCache;
|
use crate::status_cache::StatusCache;
|
||||||
use bincode::serialize;
|
use bincode::serialize;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
@ -19,7 +19,7 @@ use solana_sdk::pubkey::Pubkey;
|
|||||||
use solana_sdk::signature::{Keypair, Signature};
|
use solana_sdk::signature::{Keypair, Signature};
|
||||||
use solana_sdk::system_transaction::SystemTransaction;
|
use solana_sdk::system_transaction::SystemTransaction;
|
||||||
use solana_sdk::timing::{duration_as_us, MAX_RECENT_BLOCKHASHES, NUM_TICKS_PER_SECOND};
|
use solana_sdk::timing::{duration_as_us, MAX_RECENT_BLOCKHASHES, NUM_TICKS_PER_SECOND};
|
||||||
use solana_sdk::transaction::Transaction;
|
use solana_sdk::transaction::{Transaction, TransactionError};
|
||||||
use solana_vote_api::vote_instruction::Vote;
|
use solana_vote_api::vote_instruction::Vote;
|
||||||
use solana_vote_api::vote_state::{Lockout, VoteState};
|
use solana_vote_api::vote_state::{Lockout, VoteState};
|
||||||
use std::result;
|
use std::result;
|
||||||
@ -104,41 +104,6 @@ impl EpochSchedule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reasons a transaction might be rejected.
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
|
||||||
pub enum TransactionError {
|
|
||||||
/// This Pubkey is being processed in another transaction
|
|
||||||
AccountInUse,
|
|
||||||
|
|
||||||
/// Pubkey appears twice in the same transaction, typically in a pay-to-self
|
|
||||||
/// transaction.
|
|
||||||
AccountLoadedTwice,
|
|
||||||
|
|
||||||
/// Attempt to debit from `Pubkey`, but no found no record of a prior credit.
|
|
||||||
AccountNotFound,
|
|
||||||
|
|
||||||
/// The from `Pubkey` does not have sufficient balance to pay the fee to schedule the transaction
|
|
||||||
InsufficientFundsForFee,
|
|
||||||
|
|
||||||
/// The bank has seen `Signature` before. This can occur under normal operation
|
|
||||||
/// when a UDP packet is duplicated, as a user error from a client not updating
|
|
||||||
/// its `recent_blockhash`, or as a double-spend attack.
|
|
||||||
DuplicateSignature,
|
|
||||||
|
|
||||||
/// The bank has not seen the given `recent_blockhash` or the transaction is too old and
|
|
||||||
/// the `recent_blockhash` has been discarded.
|
|
||||||
BlockhashNotFound,
|
|
||||||
|
|
||||||
/// The program returned an error
|
|
||||||
InstructionError(u8, InstructionError),
|
|
||||||
|
|
||||||
/// Loader call chain too deep
|
|
||||||
CallChainTooDeep,
|
|
||||||
|
|
||||||
/// Transaction has a fee but has no signature present
|
|
||||||
MissingSignatureForFee,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, TransactionError>;
|
pub type Result<T> = result::Result<T, TransactionError>;
|
||||||
|
|
||||||
type BankStatusCache = StatusCache<TransactionError>;
|
type BankStatusCache = StatusCache<TransactionError>;
|
||||||
@ -882,7 +847,7 @@ mod tests {
|
|||||||
use solana_sdk::system_instruction::SystemInstruction;
|
use solana_sdk::system_instruction::SystemInstruction;
|
||||||
use solana_sdk::system_program;
|
use solana_sdk::system_program;
|
||||||
use solana_sdk::system_transaction::SystemTransaction;
|
use solana_sdk::system_transaction::SystemTransaction;
|
||||||
use solana_sdk::transaction::Instruction;
|
use solana_sdk::transaction::{Instruction, InstructionError};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bank_new() {
|
fn test_bank_new() {
|
||||||
|
@ -1,38 +1,9 @@
|
|||||||
use crate::bank::TransactionError;
|
|
||||||
use crate::native_loader;
|
use crate::native_loader;
|
||||||
use crate::system_program::SystemError;
|
|
||||||
use solana_sdk::account::{create_keyed_accounts, Account, KeyedAccount};
|
use solana_sdk::account::{create_keyed_accounts, Account, KeyedAccount};
|
||||||
use solana_sdk::native_program::ProgramError;
|
use solana_sdk::native_program::ProgramError;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use solana_sdk::system_program;
|
use solana_sdk::system_program;
|
||||||
use solana_sdk::transaction::Transaction;
|
use solana_sdk::transaction::{InstructionError, Transaction, TransactionError};
|
||||||
|
|
||||||
/// Reasons the runtime might have rejected an instruction.
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
|
||||||
pub enum InstructionError {
|
|
||||||
/// Executing the instruction produced an error.
|
|
||||||
ProgramError(ProgramError),
|
|
||||||
|
|
||||||
/// Program's instruction lamport balance does not equal the balance after the instruction
|
|
||||||
UnbalancedInstruction,
|
|
||||||
|
|
||||||
/// Program modified an account's program id
|
|
||||||
ModifiedProgramId,
|
|
||||||
|
|
||||||
/// Program spent the lamports of an account that doesn't belong to it
|
|
||||||
ExternalAccountLamportSpend,
|
|
||||||
|
|
||||||
/// Program modified the userdata of an account that doesn't belong to it
|
|
||||||
ExternalAccountUserdataModified,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InstructionError {
|
|
||||||
pub fn new_result_with_negative_lamports() -> Self {
|
|
||||||
let serialized_error =
|
|
||||||
bincode::serialize(&SystemError::ResultWithNegativeLamports).unwrap();
|
|
||||||
InstructionError::ProgramError(ProgramError::CustomError(serialized_error))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Process an instruction
|
/// Process an instruction
|
||||||
/// This method calls the instruction's program entrypoint method
|
/// This method calls the instruction's program entrypoint method
|
||||||
|
@ -167,8 +167,8 @@ impl<T: Clone> StatusCache<T> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::bank::TransactionError;
|
|
||||||
use solana_sdk::hash::hash;
|
use solana_sdk::hash::hash;
|
||||||
|
use solana_sdk::transaction::TransactionError;
|
||||||
|
|
||||||
type BankStatusCache = StatusCache<TransactionError>;
|
type BankStatusCache = StatusCache<TransactionError>;
|
||||||
|
|
||||||
|
@ -1,22 +1,14 @@
|
|||||||
use bincode::serialize;
|
use bincode::serialize;
|
||||||
use log::*;
|
use log::*;
|
||||||
use serde_derive::Serialize;
|
|
||||||
use solana_sdk::account::KeyedAccount;
|
use solana_sdk::account::KeyedAccount;
|
||||||
use solana_sdk::native_program::ProgramError;
|
use solana_sdk::native_program::ProgramError;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use solana_sdk::system_instruction::SystemInstruction;
|
use solana_sdk::system_instruction::{SystemError, SystemInstruction};
|
||||||
use solana_sdk::system_program;
|
use solana_sdk::system_program;
|
||||||
|
|
||||||
const FROM_ACCOUNT_INDEX: usize = 0;
|
const FROM_ACCOUNT_INDEX: usize = 0;
|
||||||
const TO_ACCOUNT_INDEX: usize = 1;
|
const TO_ACCOUNT_INDEX: usize = 1;
|
||||||
|
|
||||||
#[derive(Serialize, Debug, Clone, PartialEq)]
|
|
||||||
pub enum SystemError {
|
|
||||||
AccountAlreadyInUse,
|
|
||||||
ResultWithNegativeLamports,
|
|
||||||
SourceNotSystemAccount,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_system_account(
|
fn create_system_account(
|
||||||
keyed_accounts: &mut [KeyedAccount],
|
keyed_accounts: &mut [KeyedAccount],
|
||||||
lamports: u64,
|
lamports: u64,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use solana_runtime::bank::{Bank, TransactionError};
|
use solana_runtime::bank::Bank;
|
||||||
use solana_runtime::runtime::InstructionError;
|
|
||||||
use solana_sdk::genesis_block::GenesisBlock;
|
use solana_sdk::genesis_block::GenesisBlock;
|
||||||
use solana_sdk::native_program::ProgramError;
|
use solana_sdk::native_program::ProgramError;
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||||
use solana_sdk::system_instruction::SystemInstruction;
|
use solana_sdk::system_instruction::SystemInstruction;
|
||||||
use solana_sdk::system_program;
|
use solana_sdk::system_program;
|
||||||
|
use solana_sdk::transaction::{InstructionError, TransactionError};
|
||||||
use solana_sdk::transaction_builder::{BuilderInstruction, TransactionBuilder};
|
use solana_sdk::transaction_builder::{BuilderInstruction, TransactionBuilder};
|
||||||
|
|
||||||
struct SystemBank<'a> {
|
struct SystemBank<'a> {
|
||||||
|
@ -2,6 +2,13 @@ use crate::pubkey::Pubkey;
|
|||||||
use crate::system_program;
|
use crate::system_program;
|
||||||
use crate::transaction_builder::BuilderInstruction;
|
use crate::transaction_builder::BuilderInstruction;
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug, Clone, PartialEq)]
|
||||||
|
pub enum SystemError {
|
||||||
|
AccountAlreadyInUse,
|
||||||
|
ResultWithNegativeLamports,
|
||||||
|
SourceNotSystemAccount,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
pub enum SystemInstruction {
|
pub enum SystemInstruction {
|
||||||
/// Create a new account
|
/// Create a new account
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! The `transaction` module provides functionality for creating log transactions.
|
//! The `transaction` module provides functionality for creating log transactions.
|
||||||
|
|
||||||
use crate::hash::{Hash, Hasher};
|
use crate::hash::{Hash, Hasher};
|
||||||
|
use crate::native_program::ProgramError;
|
||||||
use crate::packet::PACKET_DATA_SIZE;
|
use crate::packet::PACKET_DATA_SIZE;
|
||||||
use crate::pubkey::Pubkey;
|
use crate::pubkey::Pubkey;
|
||||||
use crate::shortvec::{
|
use crate::shortvec::{
|
||||||
@ -8,6 +9,7 @@ use crate::shortvec::{
|
|||||||
serialize_vec_with,
|
serialize_vec_with,
|
||||||
};
|
};
|
||||||
use crate::signature::{Keypair, KeypairUtil, Signature};
|
use crate::signature::{Keypair, KeypairUtil, Signature};
|
||||||
|
use crate::system_instruction::SystemError;
|
||||||
use bincode::{serialize, Error};
|
use bincode::{serialize, Error};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
use serde::{Deserialize, Serialize, Serializer};
|
use serde::{Deserialize, Serialize, Serializer};
|
||||||
@ -15,6 +17,33 @@ use std::fmt;
|
|||||||
use std::io::{Cursor, Read, Write};
|
use std::io::{Cursor, Read, Write};
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
|
|
||||||
|
/// Reasons the runtime might have rejected an instruction.
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
|
pub enum InstructionError {
|
||||||
|
/// Executing the instruction produced an error.
|
||||||
|
ProgramError(ProgramError),
|
||||||
|
|
||||||
|
/// Program's instruction lamport balance does not equal the balance after the instruction
|
||||||
|
UnbalancedInstruction,
|
||||||
|
|
||||||
|
/// Program modified an account's program id
|
||||||
|
ModifiedProgramId,
|
||||||
|
|
||||||
|
/// Program spent the lamports of an account that doesn't belong to it
|
||||||
|
ExternalAccountLamportSpend,
|
||||||
|
|
||||||
|
/// Program modified the userdata of an account that doesn't belong to it
|
||||||
|
ExternalAccountUserdataModified,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InstructionError {
|
||||||
|
pub fn new_result_with_negative_lamports() -> Self {
|
||||||
|
let serialized_error =
|
||||||
|
bincode::serialize(&SystemError::ResultWithNegativeLamports).unwrap();
|
||||||
|
InstructionError::ProgramError(ProgramError::CustomError(serialized_error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An instruction to execute a program
|
/// An instruction to execute a program
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||||
pub struct Instruction<P, Q> {
|
pub struct Instruction<P, Q> {
|
||||||
@ -76,6 +105,41 @@ impl Instruction<u8, u8> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reasons a transaction might be rejected.
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
|
pub enum TransactionError {
|
||||||
|
/// This Pubkey is being processed in another transaction
|
||||||
|
AccountInUse,
|
||||||
|
|
||||||
|
/// Pubkey appears twice in the same transaction, typically in a pay-to-self
|
||||||
|
/// transaction.
|
||||||
|
AccountLoadedTwice,
|
||||||
|
|
||||||
|
/// Attempt to debit from `Pubkey`, but no found no record of a prior credit.
|
||||||
|
AccountNotFound,
|
||||||
|
|
||||||
|
/// The from `Pubkey` does not have sufficient balance to pay the fee to schedule the transaction
|
||||||
|
InsufficientFundsForFee,
|
||||||
|
|
||||||
|
/// The bank has seen `Signature` before. This can occur under normal operation
|
||||||
|
/// when a UDP packet is duplicated, as a user error from a client not updating
|
||||||
|
/// its `recent_blockhash`, or as a double-spend attack.
|
||||||
|
DuplicateSignature,
|
||||||
|
|
||||||
|
/// The bank has not seen the given `recent_blockhash` or the transaction is too old and
|
||||||
|
/// the `recent_blockhash` has been discarded.
|
||||||
|
BlockhashNotFound,
|
||||||
|
|
||||||
|
/// The program returned an error
|
||||||
|
InstructionError(u8, InstructionError),
|
||||||
|
|
||||||
|
/// Loader call chain too deep
|
||||||
|
CallChainTooDeep,
|
||||||
|
|
||||||
|
/// Transaction has a fee but has no signature present
|
||||||
|
MissingSignatureForFee,
|
||||||
|
}
|
||||||
|
|
||||||
/// An atomic transaction
|
/// An atomic transaction
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub struct Transaction {
|
pub struct Transaction {
|
||||||
|
Reference in New Issue
Block a user