Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Transaction timestamp condition #4419

Merged
merged 4 commits into from
Feb 3, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ethcore/light/src/client/header_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ impl HeaderChain {
pub fn get_header(&self, id: BlockId) -> Option<Bytes> {
match id {
BlockId::Earliest | BlockId::Number(0) => Some(self.genesis_header.clone()),
BlockId::Latest if self.headers.read().is_empty() => Some(self.genesis_header.clone()),
BlockId::Hash(hash) => self.headers.read().get(&hash).map(|x| x.to_vec()),
BlockId::Number(num) => {
if self.best_block.read().number < num { return None }
Expand Down
11 changes: 9 additions & 2 deletions ethcore/light/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ use ethcore::block_status::BlockStatus;
use ethcore::client::ClientReport;
use ethcore::ids::BlockId;
use ethcore::header::Header;
use ethcore::views::HeaderView;
use ethcore::verification::queue::{self, HeaderQueue};
use ethcore::transaction::PendingTransaction;
use ethcore::transaction::{PendingTransaction, Condition as TransactionCondition};
use ethcore::blockchain_info::BlockChainInfo;
use ethcore::spec::Spec;
use ethcore::service::ClientIoMessage;
Expand All @@ -34,6 +35,7 @@ use util::{Bytes, Mutex, RwLock};

use provider::Provider;
use request;
use time;

use self::header_chain::HeaderChain;

Expand Down Expand Up @@ -110,7 +112,11 @@ impl Client {
let best_num = self.chain.best_block().number;
self.tx_pool.lock()
.values()
.filter(|t| t.min_block.as_ref().map_or(true, |x| x <= &best_num))
.filter(|t| match t.condition {
Some(TransactionCondition::Number(ref x)) => x <= &best_num,
Some(TransactionCondition::Timestamp(ref x)) => *x <= time::get_time().sec as u64,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this condition check needs updating as well. probably would be best done after changing HeaderChain to use ethcore::encoded (done locally).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given that it's "dead" code I don't mind merging this PR without it

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll leave it to you then :)

None => true,
})
.cloned()
.collect()
}
Expand All @@ -135,6 +141,7 @@ impl Client {
genesis_hash: genesis_hash,
best_block_hash: best_block.hash,
best_block_number: best_block.number,
best_block_timestamp: HeaderView::new(&self.chain.get_header(BlockId::Latest).expect("Latest hash is always in the chain")).timestamp(),
ancient_block_hash: if first_block.is_some() { Some(genesis_hash) } else { None },
ancient_block_number: if first_block.is_some() { Some(0) } else { None },
first_block_hash: first_block.as_ref().map(|first| first.hash),
Expand Down
2 changes: 2 additions & 0 deletions ethcore/src/blockchain/best_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub struct BestBlock {
pub hash: H256,
/// Best block number.
pub number: BlockNumber,
/// Best block timestamp.
pub timestamp: u64,
/// Best block total difficulty.
pub total_difficulty: U256,
/// Best block uncompressed bytes
Expand Down
13 changes: 13 additions & 0 deletions ethcore/src/blockchain/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ impl BlockChain {
let best_block_number = bc.block_number(&best_block_hash).unwrap();
let best_block_total_difficulty = bc.block_details(&best_block_hash).unwrap().total_difficulty;
let best_block_rlp = bc.block(&best_block_hash).unwrap().into_inner();
let best_block_timestamp = BlockView::new(&best_block_rlp).header().timestamp();

let raw_first = bc.db.get(db::COL_EXTRA, b"first").unwrap().map(|v| v.to_vec());
let mut best_ancient = bc.db.get(db::COL_EXTRA, b"ancient").unwrap().map(|h| H256::from_slice(&h));
Expand Down Expand Up @@ -533,6 +534,7 @@ impl BlockChain {
number: best_block_number,
total_difficulty: best_block_total_difficulty,
hash: best_block_hash,
timestamp: best_block_timestamp,
block: best_block_rlp,
};

Expand Down Expand Up @@ -585,6 +587,7 @@ impl BlockChain {
number: extras.number - 1,
total_difficulty: best_block_total_difficulty,
hash: hash,
timestamp: BlockView::new(&best_block_rlp).header().timestamp(),
block: best_block_rlp,
};
// update parent extras
Expand Down Expand Up @@ -738,6 +741,7 @@ impl BlockChain {
blocks_blooms: self.prepare_block_blooms_update(bytes, &info),
transactions_addresses: self.prepare_transaction_addresses_update(bytes, &info),
info: info,
timestamp: header.timestamp(),
block: bytes
}, is_best);

Expand Down Expand Up @@ -786,6 +790,7 @@ impl BlockChain {
blocks_blooms: self.prepare_block_blooms_update(bytes, &info),
transactions_addresses: self.prepare_transaction_addresses_update(bytes, &info),
info: info,
timestamp: header.timestamp(),
block: bytes,
}, is_best);
true
Expand Down Expand Up @@ -850,6 +855,7 @@ impl BlockChain {
blocks_blooms: self.prepare_block_blooms_update(bytes, &info),
transactions_addresses: self.prepare_transaction_addresses_update(bytes, &info),
info: info.clone(),
timestamp: header.timestamp(),
block: bytes,
}, true);

Expand Down Expand Up @@ -921,6 +927,7 @@ impl BlockChain {
hash: update.info.hash,
number: update.info.number,
total_difficulty: update.info.total_difficulty,
timestamp: update.timestamp,
block: update.block.to_vec(),
});
},
Expand Down Expand Up @@ -1206,6 +1213,11 @@ impl BlockChain {
self.best_block.read().number
}

/// Get best block timestamp.
pub fn best_block_timestamp(&self) -> u64 {
self.best_block.read().timestamp
}

/// Get best block total difficulty.
pub fn best_block_total_difficulty(&self) -> U256 {
self.best_block.read().total_difficulty
Expand Down Expand Up @@ -1293,6 +1305,7 @@ impl BlockChain {
genesis_hash: self.genesis_hash(),
best_block_hash: best_block.hash.clone(),
best_block_number: best_block.number,
best_block_timestamp: best_block.timestamp,
first_block_hash: self.first_block(),
first_block_number: From::from(self.first_block_number()),
ancient_block_hash: best_ancient_block.as_ref().map(|b| b.hash.clone()),
Expand Down
2 changes: 2 additions & 0 deletions ethcore/src/blockchain/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use super::extras::{BlockDetails, BlockReceipts, TransactionAddress, LogGroupPos
pub struct ExtrasUpdate<'a> {
/// Block info.
pub info: BlockInfo,
/// Block timestamp.
pub timestamp: u64,
/// Current block uncompressed rlp bytes
pub block: &'a [u8],
/// Modified block hashes.
Expand Down
6 changes: 5 additions & 1 deletion ethcore/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1406,7 +1406,11 @@ impl BlockChainClient for Client {
}

fn ready_transactions(&self) -> Vec<PendingTransaction> {
self.miner.ready_transactions(self.chain.read().best_block_number())
let (number, timestamp) = {
let chain = self.chain.read();
(chain.best_block_number(), chain.best_block_timestamp())
};
self.miner.ready_transactions(number, timestamp)
}

fn queue_consensus_message(&self, message: Bytes) {
Expand Down
7 changes: 5 additions & 2 deletions ethcore/src/client/test_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,12 +669,14 @@ impl BlockChainClient for TestBlockChainClient {
}

fn chain_info(&self) -> BlockChainInfo {
let number = self.blocks.read().len() as BlockNumber - 1;
BlockChainInfo {
total_difficulty: *self.difficulty.read(),
pending_total_difficulty: *self.difficulty.read(),
genesis_hash: self.genesis_hash.clone(),
best_block_hash: self.last_hash.read().clone(),
best_block_number: self.blocks.read().len() as BlockNumber - 1,
best_block_number: number,
best_block_timestamp: number,
first_block_hash: self.first_block.read().as_ref().map(|x| x.0),
first_block_number: self.first_block.read().as_ref().map(|x| x.1),
ancient_block_hash: self.ancient_block.read().as_ref().map(|x| x.0),
Expand Down Expand Up @@ -709,7 +711,8 @@ impl BlockChainClient for TestBlockChainClient {
}

fn ready_transactions(&self) -> Vec<PendingTransaction> {
self.miner.ready_transactions(self.chain_info().best_block_number)
let info = self.chain_info();
self.miner.ready_transactions(info.best_block_number, info.best_block_timestamp)
}

fn signing_network_id(&self) -> Option<u64> { None }
Expand Down
24 changes: 12 additions & 12 deletions ethcore/src/miner/miner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use client::TransactionImportResult;
use executive::contract_address;
use block::{ClosedBlock, IsBlock, Block};
use error::*;
use transaction::{Action, UnverifiedTransaction, PendingTransaction, SignedTransaction};
use transaction::{Action, UnverifiedTransaction, PendingTransaction, SignedTransaction, Condition as TransactionCondition};
use receipt::{Receipt, RichReceipt};
use spec::Spec;
use engines::{Engine, Seal};
Expand Down Expand Up @@ -325,7 +325,7 @@ impl Miner {
let _timer = PerfTimer::new("prepare_block");
let chain_info = chain.chain_info();
let (transactions, mut open_block, original_work_hash) = {
let transactions = {self.transaction_queue.lock().top_transactions_at(chain_info.best_block_number)};
let transactions = {self.transaction_queue.lock().top_transactions_at(chain_info.best_block_number, chain_info.best_block_timestamp)};
let mut sealing_work = self.sealing_work.lock();
let last_work_hash = sealing_work.queue.peek_last_ref().map(|pb| pb.block().fields().header.hash());
let best_hash = chain_info.best_block_hash;
Expand Down Expand Up @@ -597,7 +597,7 @@ impl Miner {
client: &MiningBlockChainClient,
transactions: Vec<UnverifiedTransaction>,
default_origin: TransactionOrigin,
min_block: Option<BlockNumber>,
condition: Option<TransactionCondition>,
transaction_queue: &mut BanningTransactionQueue,
) -> Vec<Result<TransactionImportResult, Error>> {
let accounts = self.accounts.as_ref()
Expand Down Expand Up @@ -635,7 +635,7 @@ impl Miner {
let details_provider = TransactionDetailsProvider::new(client, &self.service_transaction_action);
match origin {
TransactionOrigin::Local | TransactionOrigin::RetractedBlock => {
transaction_queue.add(transaction, origin, insertion_time, min_block, &details_provider)
transaction_queue.add(transaction, origin, insertion_time, condition.clone(), &details_provider)
},
TransactionOrigin::External => {
transaction_queue.add_with_banlist(transaction, insertion_time, &details_provider)
Expand Down Expand Up @@ -892,7 +892,7 @@ impl MinerService for Miner {
let mut transaction_queue = self.transaction_queue.lock();
// We need to re-validate transactions
let import = self.add_transactions_to_queue(
chain, vec![pending.transaction.into()], TransactionOrigin::Local, pending.min_block, &mut transaction_queue
chain, vec![pending.transaction.into()], TransactionOrigin::Local, pending.condition, &mut transaction_queue
).pop().expect("one result returned per added transaction; one added => one result; qed");

match import {
Expand Down Expand Up @@ -927,7 +927,7 @@ impl MinerService for Miner {

fn pending_transactions(&self) -> Vec<PendingTransaction> {
let queue = self.transaction_queue.lock();
queue.pending_transactions(BlockNumber::max_value())
queue.pending_transactions(BlockNumber::max_value(), u64::max_value())
}

fn local_transactions(&self) -> BTreeMap<H256, LocalTransactionStatus> {
Expand All @@ -942,14 +942,14 @@ impl MinerService for Miner {
self.transaction_queue.lock().future_transactions()
}

fn ready_transactions(&self, best_block: BlockNumber) -> Vec<PendingTransaction> {
fn ready_transactions(&self, best_block: BlockNumber, best_block_timestamp: u64) -> Vec<PendingTransaction> {
let queue = self.transaction_queue.lock();
match self.options.pending_set {
PendingSet::AlwaysQueue => queue.pending_transactions(best_block),
PendingSet::AlwaysQueue => queue.pending_transactions(best_block, best_block_timestamp),
PendingSet::SealingOrElseQueue => {
self.from_pending_block(
best_block,
|| queue.pending_transactions(best_block),
|| queue.pending_transactions(best_block, best_block_timestamp),
|sealing| sealing.transactions().iter().map(|t| t.clone().into()).collect()
)
},
Expand Down Expand Up @@ -1325,7 +1325,7 @@ mod tests {
// then
assert_eq!(res.unwrap(), TransactionImportResult::Current);
assert_eq!(miner.pending_transactions().len(), 1);
assert_eq!(miner.ready_transactions(best_block).len(), 1);
assert_eq!(miner.ready_transactions(best_block, 0).len(), 1);
assert_eq!(miner.pending_transactions_hashes(best_block).len(), 1);
assert_eq!(miner.pending_receipts(best_block).len(), 1);
// This method will let us know if pending block was created (before calling that method)
Expand All @@ -1345,7 +1345,7 @@ mod tests {
// then
assert_eq!(res.unwrap(), TransactionImportResult::Current);
assert_eq!(miner.pending_transactions().len(), 1);
assert_eq!(miner.ready_transactions(best_block).len(), 0);
assert_eq!(miner.ready_transactions(best_block, 0).len(), 0);
assert_eq!(miner.pending_transactions_hashes(best_block).len(), 0);
assert_eq!(miner.pending_receipts(best_block).len(), 0);
}
Expand All @@ -1364,7 +1364,7 @@ mod tests {
assert_eq!(res.unwrap(), TransactionImportResult::Current);
assert_eq!(miner.pending_transactions().len(), 1);
assert_eq!(miner.pending_transactions_hashes(best_block).len(), 0);
assert_eq!(miner.ready_transactions(best_block).len(), 0);
assert_eq!(miner.ready_transactions(best_block, 0).len(), 0);
assert_eq!(miner.pending_receipts(best_block).len(), 0);
// This method will let us know if pending block was created (before calling that method)
assert!(miner.prepare_work_sealing(&client));
Expand Down
2 changes: 1 addition & 1 deletion ethcore/src/miner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ pub trait MinerService : Send + Sync {
fn pending_transactions(&self) -> Vec<PendingTransaction>;

/// Get a list of all transactions that can go into the given block.
fn ready_transactions(&self, best_block: BlockNumber) -> Vec<PendingTransaction>;
fn ready_transactions(&self, best_block: BlockNumber, best_block_timestamp: u64) -> Vec<PendingTransaction>;

/// Get a list of all future transactions.
fn future_transactions(&self) -> Vec<PendingTransaction>;
Expand Down
Loading