commit
d467ac76b0
@ -34,8 +34,9 @@ impl Account {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[cfg(feature = "json-tests")]
|
||||||
/// General constructor.
|
/// General constructor.
|
||||||
#[allow(dead_code)] // Used only in test code for now.
|
|
||||||
pub fn from_pod(pod: PodAccount) -> Account {
|
pub fn from_pod(pod: PodAccount) -> Account {
|
||||||
Account {
|
Account {
|
||||||
balance: pod.balance,
|
balance: pod.balance,
|
||||||
@ -110,8 +111,8 @@ impl Account {
|
|||||||
/// return the nonce associated with this account.
|
/// return the nonce associated with this account.
|
||||||
pub fn nonce(&self) -> &U256 { &self.nonce }
|
pub fn nonce(&self) -> &U256 { &self.nonce }
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
/// return the code hash associated with this account.
|
/// return the code hash associated with this account.
|
||||||
#[allow(dead_code)] // Used only in test code for now.
|
|
||||||
pub fn code_hash(&self) -> H256 {
|
pub fn code_hash(&self) -> H256 {
|
||||||
self.code_hash.clone().unwrap_or(SHA3_EMPTY)
|
self.code_hash.clone().unwrap_or(SHA3_EMPTY)
|
||||||
}
|
}
|
||||||
@ -127,8 +128,8 @@ impl Account {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
/// Provide a byte array which hashes to the `code_hash`. returns the hash as a result.
|
/// Provide a byte array which hashes to the `code_hash`. returns the hash as a result.
|
||||||
#[allow(dead_code)] // Used only in test code for now.
|
|
||||||
pub fn note_code(&mut self, code: Bytes) -> Result<(), H256> {
|
pub fn note_code(&mut self, code: Bytes) -> Result<(), H256> {
|
||||||
let h = code.sha3();
|
let h = code.sha3();
|
||||||
match self.code_hash {
|
match self.code_hash {
|
||||||
@ -162,12 +163,12 @@ impl Account {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
/// Determine whether there are any un-`commit()`-ed storage-setting operations.
|
/// Determine whether there are any un-`commit()`-ed storage-setting operations.
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn storage_is_clean(&self) -> bool { self.storage_overlay.borrow().iter().find(|&(_, &(f, _))| f == Filth::Dirty).is_none() }
|
pub fn storage_is_clean(&self) -> bool { self.storage_overlay.borrow().iter().find(|&(_, &(f, _))| f == Filth::Dirty).is_none() }
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
/// return the storage root associated with this account or None if it has been altered via the overlay.
|
/// return the storage root associated with this account or None if it has been altered via the overlay.
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn storage_root(&self) -> Option<&H256> { if self.storage_is_clean() {Some(&self.storage_root)} else {None} }
|
pub fn storage_root(&self) -> Option<&H256> { if self.storage_is_clean() {Some(&self.storage_root)} else {None} }
|
||||||
|
|
||||||
/// return the storage overlay.
|
/// return the storage overlay.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Diff between two accounts.
|
//! Diff between two accounts.
|
||||||
|
|
||||||
use util::*;
|
use util::*;
|
||||||
|
#[cfg(test)]
|
||||||
use pod_account::*;
|
use pod_account::*;
|
||||||
|
|
||||||
#[derive(Debug,Clone,PartialEq,Eq)]
|
#[derive(Debug,Clone,PartialEq,Eq)]
|
||||||
@ -49,9 +50,9 @@ impl AccountDiff {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
/// Determine difference between two optionally existant `Account`s. Returns None
|
/// Determine difference between two optionally existant `Account`s. Returns None
|
||||||
/// if they are the same.
|
/// if they are the same.
|
||||||
#[allow(dead_code)] // Used only in test code for now.
|
|
||||||
pub fn diff_pod(pre: Option<&PodAccount>, post: Option<&PodAccount>) -> Option<AccountDiff> {
|
pub fn diff_pod(pre: Option<&PodAccount>, post: Option<&PodAccount>) -> Option<AccountDiff> {
|
||||||
match (pre, post) {
|
match (pre, post) {
|
||||||
(None, Some(x)) => Some(AccountDiff {
|
(None, Some(x)) => Some(AccountDiff {
|
||||||
|
@ -1,29 +1,39 @@
|
|||||||
//! Evm factory.
|
//! Evm factory.
|
||||||
//!
|
//!
|
||||||
//! TODO: consider spliting it into two separate files.
|
//! TODO: consider spliting it into two separate files.
|
||||||
|
#[cfg(test)]
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use evm::Evm;
|
use evm::Evm;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
/// Type of EVM to use.
|
/// Type of EVM to use.
|
||||||
pub enum VMType {
|
pub enum VMType {
|
||||||
#[allow(dead_code)] // crated only by jit
|
|
||||||
/// JIT EVM
|
/// JIT EVM
|
||||||
|
#[cfg(feature="jit")]
|
||||||
Jit,
|
Jit,
|
||||||
/// RUST EVM
|
/// RUST EVM
|
||||||
Interpreter
|
Interpreter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
impl fmt::Display for VMType {
|
impl fmt::Display for VMType {
|
||||||
|
#[cfg(feature="jit")]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", match *self {
|
write!(f, "{}", match *self {
|
||||||
VMType::Jit => "JIT",
|
VMType::Jit => "JIT",
|
||||||
VMType::Interpreter => "INT"
|
VMType::Interpreter => "INT"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
#[cfg(not(feature="jit"))]
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{}", match *self {
|
||||||
|
VMType::Interpreter => "INT"
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
#[cfg(feature = "json-tests")]
|
||||||
impl VMType {
|
impl VMType {
|
||||||
/// Return all possible VMs (JIT, Interpreter)
|
/// Return all possible VMs (JIT, Interpreter)
|
||||||
#[cfg(feature="jit")]
|
#[cfg(feature="jit")]
|
||||||
@ -45,10 +55,11 @@ pub struct Factory {
|
|||||||
|
|
||||||
impl Factory {
|
impl Factory {
|
||||||
/// Create fresh instance of VM
|
/// Create fresh instance of VM
|
||||||
|
#[cfg(feature="jit")]
|
||||||
pub fn create(&self) -> Box<Evm> {
|
pub fn create(&self) -> Box<Evm> {
|
||||||
match self.evm {
|
match self.evm {
|
||||||
VMType::Jit => {
|
VMType::Jit => {
|
||||||
Factory::jit()
|
Box::new(super::jit::JitEvm)
|
||||||
},
|
},
|
||||||
VMType::Interpreter => {
|
VMType::Interpreter => {
|
||||||
Box::new(super::interpreter::Interpreter)
|
Box::new(super::interpreter::Interpreter)
|
||||||
@ -56,6 +67,16 @@ impl Factory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create fresh instance of VM
|
||||||
|
#[cfg(not(feature="jit"))]
|
||||||
|
pub fn create(&self) -> Box<Evm> {
|
||||||
|
match self.evm {
|
||||||
|
VMType::Interpreter => {
|
||||||
|
Box::new(super::interpreter::Interpreter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Create new instance of specific `VMType` factory
|
/// Create new instance of specific `VMType` factory
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn new(evm: VMType) -> Factory {
|
pub fn new(evm: VMType) -> Factory {
|
||||||
@ -63,16 +84,6 @@ impl Factory {
|
|||||||
evm: evm
|
evm: evm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "jit")]
|
|
||||||
fn jit() -> Box<Evm> {
|
|
||||||
Box::new(super::jit::JitEvm)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "jit"))]
|
|
||||||
fn jit() -> Box<Evm> {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
impl Default for Factory {
|
impl Default for Factory {
|
||||||
/// Returns jitvm factory
|
/// Returns jitvm factory
|
||||||
|
@ -95,7 +95,7 @@ impl Ext for FakeExt {
|
|||||||
value: Option<U256>,
|
value: Option<U256>,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
code_address: &Address,
|
code_address: &Address,
|
||||||
output: &mut [u8]) -> MessageCallResult {
|
_output: &mut [u8]) -> MessageCallResult {
|
||||||
|
|
||||||
self.calls.insert(FakeCall {
|
self.calls.insert(FakeCall {
|
||||||
call_type: FakeCallType::CALL,
|
call_type: FakeCallType::CALL,
|
||||||
|
@ -23,6 +23,7 @@ impl PodState {
|
|||||||
|
|
||||||
/// Drain object to get the underlying map.
|
/// Drain object to get the underlying map.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
#[cfg(feature = "json-tests")]
|
||||||
pub fn drain(self) -> BTreeMap<Address, PodAccount> { self.0 }
|
pub fn drain(self) -> BTreeMap<Address, PodAccount> { self.0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
use common::*;
|
use common::*;
|
||||||
use engine::Engine;
|
use engine::Engine;
|
||||||
use executive::Executive;
|
use executive::Executive;
|
||||||
|
#[cfg(test)]
|
||||||
|
#[cfg(feature = "json-tests")]
|
||||||
use pod_account::*;
|
use pod_account::*;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
#[cfg(feature = "json-tests")]
|
||||||
use pod_state::PodState;
|
use pod_state::PodState;
|
||||||
//use state_diff::*; // TODO: uncomment once to_pod() works correctly.
|
//use state_diff::*; // TODO: uncomment once to_pod() works correctly.
|
||||||
|
|
||||||
@ -186,27 +189,17 @@ impl State {
|
|||||||
Self::commit_into(&mut self.db, &mut self.root, self.cache.borrow_mut().deref_mut());
|
Self::commit_into(&mut self.db, &mut self.root, self.cache.borrow_mut().deref_mut());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Populate the state from `accounts`.
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
#[cfg(feature = "json-tests")]
|
||||||
|
/// Populate the state from `accounts`.
|
||||||
pub fn populate_from(&mut self, accounts: PodState) {
|
pub fn populate_from(&mut self, accounts: PodState) {
|
||||||
for (add, acc) in accounts.drain().into_iter() {
|
for (add, acc) in accounts.drain().into_iter() {
|
||||||
self.cache.borrow_mut().insert(add, Some(Account::from_pod(acc)));
|
self.cache.borrow_mut().insert(add, Some(Account::from_pod(acc)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Populate a PodAccount map from this state.
|
|
||||||
#[allow(dead_code)] // Used only in test code for now.
|
|
||||||
pub fn to_hashmap_pod(&self) -> HashMap<Address, PodAccount> {
|
|
||||||
// TODO: handle database rather than just the cache.
|
|
||||||
self.cache.borrow().iter().fold(HashMap::new(), |mut m, (add, opt)| {
|
|
||||||
if let Some(ref acc) = *opt {
|
|
||||||
m.insert(add.clone(), PodAccount::from_account(acc));
|
|
||||||
}
|
|
||||||
m
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
#[cfg(feature = "json-tests")]
|
||||||
/// Populate a PodAccount map from this state.
|
/// Populate a PodAccount map from this state.
|
||||||
pub fn to_pod(&self) -> PodState {
|
pub fn to_pod(&self) -> PodState {
|
||||||
// TODO: handle database rather than just the cache.
|
// TODO: handle database rather than just the cache.
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use util::*;
|
use util::*;
|
||||||
|
#[cfg(test)]
|
||||||
use pod_state::*;
|
use pod_state::*;
|
||||||
use account_diff::*;
|
use account_diff::*;
|
||||||
|
|
||||||
@ -8,8 +9,8 @@ use account_diff::*;
|
|||||||
pub struct StateDiff (BTreeMap<Address, AccountDiff>);
|
pub struct StateDiff (BTreeMap<Address, AccountDiff>);
|
||||||
|
|
||||||
impl StateDiff {
|
impl StateDiff {
|
||||||
|
#[cfg(test)]
|
||||||
/// Calculate and return diff between `pre` state and `post` state.
|
/// Calculate and return diff between `pre` state and `post` state.
|
||||||
#[allow(dead_code)] // Used only in test code for now.
|
|
||||||
pub fn diff_pod(pre: &PodState, post: &PodState) -> StateDiff {
|
pub fn diff_pod(pre: &PodState, post: &PodState) -> StateDiff {
|
||||||
StateDiff(pre.get().keys().merge(post.get().keys()).filter_map(|acc| AccountDiff::diff_pod(pre.get().get(acc), post.get().get(acc)).map(|d|(acc.clone(), d))).collect())
|
StateDiff(pre.get().keys().merge(post.get().keys()).filter_map(|acc| AccountDiff::diff_pod(pre.get().get(acc), post.get().get(acc)).map(|d|(acc.clone(), d))).collect())
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use client::{BlockChainClient,Client};
|
#[cfg(feature = "json-tests")]
|
||||||
|
use client::{BlockChainClient, Client};
|
||||||
use std::env;
|
use std::env;
|
||||||
use common::*;
|
use common::*;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@ -8,6 +9,8 @@ use blockchain::{BlockChain};
|
|||||||
use state::*;
|
use state::*;
|
||||||
use rocksdb::*;
|
use rocksdb::*;
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(feature = "json-tests")]
|
||||||
pub enum ChainEra {
|
pub enum ChainEra {
|
||||||
Frontier,
|
Frontier,
|
||||||
Homestead,
|
Homestead,
|
||||||
@ -43,10 +46,10 @@ impl Drop for RandomTempPath {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[cfg(test)]
|
||||||
pub struct GuardedTempResult<T> {
|
pub struct GuardedTempResult<T> {
|
||||||
result: T,
|
result: T,
|
||||||
temp: RandomTempPath
|
_temp: RandomTempPath
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> GuardedTempResult<T> {
|
impl<T> GuardedTempResult<T> {
|
||||||
@ -111,6 +114,7 @@ pub fn create_test_block_with_data(header: &Header, transactions: &[&Transaction
|
|||||||
rlp.out()
|
rlp.out()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "json-tests")]
|
||||||
pub fn generate_dummy_client(block_number: u32) -> GuardedTempResult<Arc<Client>> {
|
pub fn generate_dummy_client(block_number: u32) -> GuardedTempResult<Arc<Client>> {
|
||||||
let dir = RandomTempPath::new();
|
let dir = RandomTempPath::new();
|
||||||
|
|
||||||
@ -145,11 +149,12 @@ pub fn generate_dummy_client(block_number: u32) -> GuardedTempResult<Arc<Client>
|
|||||||
client.import_verified_blocks(&IoChannel::disconnected());
|
client.import_verified_blocks(&IoChannel::disconnected());
|
||||||
|
|
||||||
GuardedTempResult::<Arc<Client>> {
|
GuardedTempResult::<Arc<Client>> {
|
||||||
temp: dir,
|
_temp: dir,
|
||||||
result: client
|
result: client
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "json-tests")]
|
||||||
pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> GuardedTempResult<Arc<Client>> {
|
pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> GuardedTempResult<Arc<Client>> {
|
||||||
let dir = RandomTempPath::new();
|
let dir = RandomTempPath::new();
|
||||||
let client = Client::new(get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
let client = Client::new(get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
||||||
@ -162,7 +167,7 @@ pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> GuardedTempResult<Arc<
|
|||||||
client.import_verified_blocks(&IoChannel::disconnected());
|
client.import_verified_blocks(&IoChannel::disconnected());
|
||||||
|
|
||||||
GuardedTempResult::<Arc<Client>> {
|
GuardedTempResult::<Arc<Client>> {
|
||||||
temp: dir,
|
_temp: dir,
|
||||||
result: client
|
result: client
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,7 +180,7 @@ pub fn generate_dummy_blockchain(block_number: u32) -> GuardedTempResult<BlockCh
|
|||||||
}
|
}
|
||||||
|
|
||||||
GuardedTempResult::<BlockChain> {
|
GuardedTempResult::<BlockChain> {
|
||||||
temp: temp,
|
_temp: temp,
|
||||||
result: bc
|
result: bc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -188,7 +193,7 @@ pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> GuardedTempRes
|
|||||||
}
|
}
|
||||||
|
|
||||||
GuardedTempResult::<BlockChain> {
|
GuardedTempResult::<BlockChain> {
|
||||||
temp: temp,
|
_temp: temp,
|
||||||
result: bc
|
result: bc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,7 +203,7 @@ pub fn generate_dummy_empty_blockchain() -> GuardedTempResult<BlockChain> {
|
|||||||
let bc = BlockChain::new(&create_unverifiable_block(0, H256::zero()), temp.as_path());
|
let bc = BlockChain::new(&create_unverifiable_block(0, H256::zero()), temp.as_path());
|
||||||
|
|
||||||
GuardedTempResult::<BlockChain> {
|
GuardedTempResult::<BlockChain> {
|
||||||
temp: temp,
|
_temp: temp,
|
||||||
result: bc
|
result: bc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,7 +213,7 @@ pub fn get_temp_journal_db() -> GuardedTempResult<JournalDB> {
|
|||||||
let db = DB::open_default(temp.as_str()).unwrap();
|
let db = DB::open_default(temp.as_str()).unwrap();
|
||||||
let journal_db = JournalDB::new(db);
|
let journal_db = JournalDB::new(db);
|
||||||
GuardedTempResult {
|
GuardedTempResult {
|
||||||
temp: temp,
|
_temp: temp,
|
||||||
result: journal_db
|
result: journal_db
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,7 +222,7 @@ pub fn get_temp_state() -> GuardedTempResult<State> {
|
|||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let journal_db = get_temp_journal_db_in(temp.as_path());
|
let journal_db = get_temp_journal_db_in(temp.as_path());
|
||||||
GuardedTempResult {
|
GuardedTempResult {
|
||||||
temp: temp,
|
_temp: temp,
|
||||||
result: State::new(journal_db, U256::from(0u8))
|
result: State::new(journal_db, U256::from(0u8))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,6 +251,7 @@ pub fn get_good_dummy_block() -> Bytes {
|
|||||||
create_test_block(&block_header)
|
create_test_block(&block_header)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "json-tests")]
|
||||||
pub fn get_bad_state_dummy_block() -> Bytes {
|
pub fn get_bad_state_dummy_block() -> Bytes {
|
||||||
let mut block_header = Header::new();
|
let mut block_header = Header::new();
|
||||||
let test_spec = get_test_spec();
|
let test_spec = get_test_spec();
|
||||||
|
@ -50,6 +50,7 @@ pub struct Transaction {
|
|||||||
impl Transaction {
|
impl Transaction {
|
||||||
/// Create a new transaction.
|
/// Create a new transaction.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
#[cfg(feature = "json-tests")]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Transaction {
|
Transaction {
|
||||||
nonce: x!(0),
|
nonce: x!(0),
|
||||||
@ -66,24 +67,6 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new message-call transaction.
|
|
||||||
#[cfg(test)]
|
|
||||||
pub fn new_call(to: Address, value: U256, data: Bytes, gas: U256, gas_price: U256, nonce: U256) -> Transaction {
|
|
||||||
Transaction {
|
|
||||||
nonce: nonce,
|
|
||||||
gas_price: gas_price,
|
|
||||||
gas: gas,
|
|
||||||
action: Action::Call(to),
|
|
||||||
value: value,
|
|
||||||
data: data,
|
|
||||||
v: 0,
|
|
||||||
r: x!(0),
|
|
||||||
s: x!(0),
|
|
||||||
hash: RefCell::new(None),
|
|
||||||
sender: RefCell::new(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new contract-creation transaction.
|
/// Create a new contract-creation transaction.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn new_create(value: U256, data: Bytes, gas: U256, gas_price: U256, nonce: U256) -> Transaction {
|
pub fn new_create(value: U256, data: Bytes, gas: U256, gas_price: U256, nonce: U256) -> Transaction {
|
||||||
@ -230,7 +213,9 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Do basic validation, checking for valid signature and minimum gas,
|
/// Do basic validation, checking for valid signature and minimum gas,
|
||||||
#[allow(dead_code)] // Used only in tests. TODO: consider use in block validation.
|
// TODO: consider use in block validation.
|
||||||
|
#[cfg(test)]
|
||||||
|
#[cfg(feature = "json-tests")]
|
||||||
pub fn validate(self, schedule: &Schedule, require_low: bool) -> Result<Transaction, Error> {
|
pub fn validate(self, schedule: &Schedule, require_low: bool) -> Result<Transaction, Error> {
|
||||||
if require_low && !ec::is_low_s(&self.s) {
|
if require_low && !ec::is_low_s(&self.s) {
|
||||||
return Err(Error::Util(UtilError::Crypto(CryptoError::InvalidSignature)));
|
return Err(Error::Util(UtilError::Crypto(CryptoError::InvalidSignature)));
|
||||||
|
Loading…
Reference in New Issue
Block a user