Skip to content

Commit

Permalink
Move TransactionError into the SDK
Browse files Browse the repository at this point in the history
  • Loading branch information
garious committed Mar 14, 2019
1 parent 4ca4038 commit e582202
Show file tree
Hide file tree
Showing 15 changed files with 95 additions and 98 deletions.
6 changes: 3 additions & 3 deletions core/src/banking_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ use crate::service::Service;
use crate::sigverify_stage::VerifiedPackets;
use bincode::deserialize;
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::transaction::Transaction;
use solana_sdk::transaction::{Transaction, TransactionError};
use std::net::UdpSocket;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{Receiver, RecvTimeoutError};
Expand Down Expand Up @@ -445,10 +445,10 @@ mod tests {
use crate::entry::EntrySlice;
use crate::packet::to_packets;
use crate::poh_recorder::WorkingBank;
use solana_runtime::runtime::InstructionError;
use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_transaction::SystemTransaction;
use solana_sdk::transaction::InstructionError;
use std::sync::mpsc::channel;
use std::thread::sleep;

Expand Down
2 changes: 1 addition & 1 deletion core/src/blocktree_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,11 @@ mod tests {
use crate::blocktree::create_new_tmp_ledger;
use crate::blocktree::tests::entries_to_blobs;
use crate::entry::{create_ticks, next_entry, Entry};
use solana_runtime::bank::TransactionError;
use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::hash::Hash;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_transaction::SystemTransaction;
use solana_sdk::transaction::TransactionError;

fn fill_blocktree_slot_with_ticks(
blocktree: &Blocktree,
Expand Down
8 changes: 4 additions & 4 deletions core/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::packet;
use crate::poh_recorder;
use bincode;
use serde_json;
use solana_runtime::bank;
use solana_sdk::transaction;
use std;
use std::any::Any;

Expand All @@ -22,7 +22,7 @@ pub enum Error {
RecvTimeoutError(std::sync::mpsc::RecvTimeoutError),
TryRecvError(std::sync::mpsc::TryRecvError),
Serialize(std::boxed::Box<bincode::ErrorKind>),
TransactionError(bank::TransactionError),
TransactionError(transaction::TransactionError),
ClusterInfoError(cluster_info::ClusterInfoError),
BlobError(packet::BlobError),
#[cfg(feature = "erasure")]
Expand Down Expand Up @@ -57,8 +57,8 @@ impl std::convert::From<std::sync::mpsc::RecvTimeoutError> for Error {
Error::RecvTimeoutError(e)
}
}
impl std::convert::From<bank::TransactionError> for Error {
fn from(e: bank::TransactionError) -> Error {
impl std::convert::From<transaction::TransactionError> for Error {
fn from(e: transaction::TransactionError) -> Error {
Error::TransactionError(e)
}
}
Expand Down
4 changes: 2 additions & 2 deletions core/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ use bs58;
use jsonrpc_core::{Error, ErrorCode, Metadata, Result};
use jsonrpc_derive::rpc;
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::pubkey::Pubkey;
use solana_sdk::signature::Signature;
use solana_sdk::transaction::Transaction;
use solana_sdk::transaction::{Transaction, TransactionError};
use std::mem;
use std::net::{SocketAddr, UdpSocket};
use std::sync::atomic::{AtomicBool, Ordering};
Expand Down
3 changes: 2 additions & 1 deletion core/src/rpc_subscriptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ use core::hash::Hash;
use jsonrpc_core::futures::Future;
use jsonrpc_pubsub::typed::Sink;
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::pubkey::Pubkey;
use solana_sdk::signature::Signature;
use solana_sdk::transaction::TransactionError;
use std::collections::HashMap;
use std::sync::RwLock;

Expand Down
4 changes: 1 addition & 3 deletions programs/failure/tests/failure.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use solana_runtime::bank::Bank;
use solana_runtime::bank::TransactionError;
use solana_runtime::loader_utils::load_program;
use solana_runtime::runtime::InstructionError;
use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::native_loader;
use solana_sdk::native_program::ProgramError;
use solana_sdk::transaction::Transaction;
use solana_sdk::transaction::{InstructionError, Transaction, TransactionError};

#[test]
fn test_program_native_failure() {
Expand Down
3 changes: 1 addition & 2 deletions programs/vote/tests/vote.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use solana_runtime::bank::TransactionError;
use solana_runtime::bank::{Bank, Result};
use solana_runtime::runtime::InstructionError;
use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::hash::hash;
use solana_sdk::native_program::ProgramError;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_instruction::SystemInstruction;
use solana_sdk::transaction::{InstructionError, TransactionError};
use solana_sdk::transaction_builder::{BuilderInstruction, TransactionBuilder};
use solana_vote_api::vote_instruction::{Vote, VoteInstruction};
use solana_vote_api::vote_state::VoteState;
Expand Down
4 changes: 2 additions & 2 deletions runtime/src/accounts.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::append_vec::AppendVec;
use crate::bank::{Result, TransactionError};
use crate::bank::Result;
use crate::runtime::has_duplicates;
use bincode::serialize;
use hashbrown::{HashMap, HashSet};
Expand All @@ -11,7 +11,7 @@ use solana_sdk::hash::{hash, Hash};
use solana_sdk::native_loader;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::transaction::Transaction;
use solana_sdk::transaction::{Transaction, TransactionError};
use solana_vote_api;
use std::collections::BTreeMap;
use std::env;
Expand Down
41 changes: 3 additions & 38 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use crate::accounts::{Accounts, ErrorCounters, InstructionAccounts, InstructionLoaders};
use crate::hash_queue::HashQueue;
use crate::runtime::{self, InstructionError};
use crate::runtime;
use crate::status_cache::StatusCache;
use bincode::serialize;
use hashbrown::HashMap;
Expand All @@ -19,7 +19,7 @@ use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, Signature};
use solana_sdk::system_transaction::SystemTransaction;
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_state::{Lockout, VoteState};
use std::result;
Expand Down Expand Up @@ -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>;

type BankStatusCache = StatusCache<TransactionError>;
Expand Down Expand Up @@ -882,7 +847,7 @@ mod tests {
use solana_sdk::system_instruction::SystemInstruction;
use solana_sdk::system_program;
use solana_sdk::system_transaction::SystemTransaction;
use solana_sdk::transaction::Instruction;
use solana_sdk::transaction::{Instruction, InstructionError};

#[test]
fn test_bank_new() {
Expand Down
31 changes: 1 addition & 30 deletions runtime/src/runtime.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,9 @@
use crate::bank::TransactionError;
use crate::native_loader;
use crate::system_program::SystemError;
use solana_sdk::account::{create_keyed_accounts, Account, KeyedAccount};
use solana_sdk::native_program::ProgramError;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::system_program;
use solana_sdk::transaction::Transaction;

/// 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))
}
}
use solana_sdk::transaction::{InstructionError, Transaction, TransactionError};

/// Process an instruction
/// This method calls the instruction's program entrypoint method
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/status_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ impl<T: Clone> StatusCache<T> {
#[cfg(test)]
mod tests {
use super::*;
use crate::bank::TransactionError;
use solana_sdk::hash::hash;
use solana_sdk::transaction::TransactionError;

type BankStatusCache = StatusCache<TransactionError>;

Expand Down
10 changes: 1 addition & 9 deletions runtime/src/system_program.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
use bincode::serialize;
use log::*;
use serde_derive::Serialize;
use solana_sdk::account::KeyedAccount;
use solana_sdk::native_program::ProgramError;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::system_instruction::SystemInstruction;
use solana_sdk::system_instruction::{SystemError, SystemInstruction};
use solana_sdk::system_program;

const FROM_ACCOUNT_INDEX: usize = 0;
const TO_ACCOUNT_INDEX: usize = 1;

#[derive(Serialize, Debug, Clone, PartialEq)]
pub enum SystemError {
AccountAlreadyInUse,
ResultWithNegativeLamports,
SourceNotSystemAccount,
}

fn create_system_account(
keyed_accounts: &mut [KeyedAccount],
lamports: u64,
Expand Down
4 changes: 2 additions & 2 deletions runtime/tests/system.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use solana_runtime::bank::{Bank, TransactionError};
use solana_runtime::runtime::InstructionError;
use solana_runtime::bank::Bank;
use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::native_program::ProgramError;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_instruction::SystemInstruction;
use solana_sdk::system_program;
use solana_sdk::transaction::{InstructionError, TransactionError};
use solana_sdk::transaction_builder::{BuilderInstruction, TransactionBuilder};

struct SystemBank<'a> {
Expand Down
7 changes: 7 additions & 0 deletions sdk/src/system_instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ use crate::pubkey::Pubkey;
use crate::system_program;
use crate::transaction_builder::BuilderInstruction;

#[derive(Serialize, Debug, Clone, PartialEq)]
pub enum SystemError {
AccountAlreadyInUse,
ResultWithNegativeLamports,
SourceNotSystemAccount,
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub enum SystemInstruction {
/// Create a new account
Expand Down
64 changes: 64 additions & 0 deletions sdk/src/transaction.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,49 @@
//! The `transaction` module provides functionality for creating log transactions.
use crate::hash::{Hash, Hasher};
use crate::native_program::ProgramError;
use crate::packet::PACKET_DATA_SIZE;
use crate::pubkey::Pubkey;
use crate::shortvec::{
deserialize_vec_bytes, deserialize_vec_with, encode_len, serialize_vec_bytes,
serialize_vec_with,
};
use crate::signature::{Keypair, KeypairUtil, Signature};
use crate::system_instruction::SystemError;
use bincode::{serialize, Error};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use serde::{Deserialize, Serialize, Serializer};
use std::fmt;
use std::io::{Cursor, Read, Write};
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
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Instruction<P, Q> {
Expand Down Expand Up @@ -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
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Transaction {
Expand Down

0 comments on commit e582202

Please sign in to comment.