Merge pull request #838 from ethcore/tx-queue-resp
checking transaction queue for pending transaction
This commit is contained in:
commit
6b8e7bdfb3
@ -105,6 +105,9 @@ pub trait MinerService : Send + Sync {
|
|||||||
/// Submit `seal` as a valid solution for the header of `pow_hash`.
|
/// Submit `seal` as a valid solution for the header of `pow_hash`.
|
||||||
/// Will check the seal, but not actually insert the block into the chain.
|
/// Will check the seal, but not actually insert the block into the chain.
|
||||||
fn submit_seal(&self, chain: &BlockChainClient, pow_hash: H256, seal: Vec<Bytes>) -> Result<(), Error>;
|
fn submit_seal(&self, chain: &BlockChainClient, pow_hash: H256, seal: Vec<Bytes>) -> Result<(), Error>;
|
||||||
|
|
||||||
|
/// Query pending transactions for hash
|
||||||
|
fn transaction(&self, hash: &H256) -> Option<SignedTransaction>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mining status
|
/// Mining status
|
||||||
|
@ -164,6 +164,11 @@ impl MinerService for Miner {
|
|||||||
transaction_queue.pending_hashes()
|
transaction_queue.pending_hashes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn transaction(&self, hash: &H256) -> Option<SignedTransaction> {
|
||||||
|
let queue = self.transaction_queue.lock().unwrap();
|
||||||
|
queue.find(hash)
|
||||||
|
}
|
||||||
|
|
||||||
fn update_sealing(&self, chain: &BlockChainClient) {
|
fn update_sealing(&self, chain: &BlockChainClient) {
|
||||||
if self.sealing_enabled.load(atomic::Ordering::Relaxed) {
|
if self.sealing_enabled.load(atomic::Ordering::Relaxed) {
|
||||||
let current_no = chain.chain_info().best_block_number;
|
let current_no = chain.chain_info().best_block_number;
|
||||||
|
@ -504,6 +504,11 @@ impl TransactionQueue {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Finds transaction in the queue by hash (if any)
|
||||||
|
pub fn find(&self, hash: &H256) -> Option<SignedTransaction> {
|
||||||
|
match self.by_hash.get(hash) { Some(transaction_ref) => Some(transaction_ref.transaction.clone()), None => None }
|
||||||
|
}
|
||||||
|
|
||||||
/// Removes all elements (in any state) from the queue
|
/// Removes all elements (in any state) from the queue
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.current.clear();
|
self.current.clear();
|
||||||
|
@ -348,7 +348,13 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
|
|||||||
|
|
||||||
fn transaction_by_hash(&self, params: Params) -> Result<Value, Error> {
|
fn transaction_by_hash(&self, params: Params) -> Result<Value, Error> {
|
||||||
from_params::<(H256,)>(params)
|
from_params::<(H256,)>(params)
|
||||||
.and_then(|(hash,)| self.transaction(TransactionId::Hash(hash)))
|
.and_then(|(hash,)| {
|
||||||
|
let miner = take_weak!(self.miner);
|
||||||
|
match miner.transaction(&hash) {
|
||||||
|
Some(pending_tx) => to_value(&Transaction::from(pending_tx)),
|
||||||
|
None => self.transaction(TransactionId::Hash(hash))
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_by_block_hash_and_index(&self, params: Params) -> Result<Value, Error> {
|
fn transaction_by_block_hash_and_index(&self, params: Params) -> Result<Value, Error> {
|
||||||
|
@ -53,7 +53,7 @@ struct EthTester {
|
|||||||
pub client: Arc<TestBlockChainClient>,
|
pub client: Arc<TestBlockChainClient>,
|
||||||
pub sync: Arc<TestSyncProvider>,
|
pub sync: Arc<TestSyncProvider>,
|
||||||
_accounts_provider: Arc<TestAccountProvider>,
|
_accounts_provider: Arc<TestAccountProvider>,
|
||||||
_miner: Arc<TestMinerService>,
|
miner: Arc<TestMinerService>,
|
||||||
hashrates: Arc<RwLock<HashMap<H256, U256>>>,
|
hashrates: Arc<RwLock<HashMap<H256, U256>>>,
|
||||||
pub io: IoHandler,
|
pub io: IoHandler,
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ impl Default for EthTester {
|
|||||||
client: client,
|
client: client,
|
||||||
sync: sync,
|
sync: sync,
|
||||||
_accounts_provider: ap,
|
_accounts_provider: ap,
|
||||||
_miner: miner,
|
miner: miner,
|
||||||
io: io,
|
io: io,
|
||||||
hashrates: hashrates,
|
hashrates: hashrates,
|
||||||
}
|
}
|
||||||
@ -258,6 +258,27 @@ fn rpc_eth_transaction_count_by_number_pending() {
|
|||||||
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_eth_pending_transaction_by_hash() {
|
||||||
|
use util::*;
|
||||||
|
use ethcore::transaction::*;
|
||||||
|
|
||||||
|
let tester = EthTester::default();
|
||||||
|
{
|
||||||
|
let tx: SignedTransaction = decode(&FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
|
||||||
|
tester.miner.pending_transactions.lock().unwrap().insert(H256::zero(), tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x01","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","nonce":"0x00","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"value":"0x0a"},"id":1}"#;
|
||||||
|
let request = r#"{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": "eth_getTransactionByHash",
|
||||||
|
"params": ["0x0000000000000000000000000000000000000000000000000000000000000000"],
|
||||||
|
"id": 1
|
||||||
|
}"#;
|
||||||
|
assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_uncle_count_by_block_hash() {
|
fn rpc_eth_uncle_count_by_block_hash() {
|
||||||
|
@ -30,6 +30,8 @@ pub struct TestMinerService {
|
|||||||
pub imported_transactions: RwLock<Vec<H256>>,
|
pub imported_transactions: RwLock<Vec<H256>>,
|
||||||
/// Latest closed block.
|
/// Latest closed block.
|
||||||
pub latest_closed_block: Mutex<Option<ClosedBlock>>,
|
pub latest_closed_block: Mutex<Option<ClosedBlock>>,
|
||||||
|
/// Pre-existed pending transactions
|
||||||
|
pub pending_transactions: Mutex<HashMap<H256, SignedTransaction>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TestMinerService {
|
impl Default for TestMinerService {
|
||||||
@ -37,6 +39,7 @@ impl Default for TestMinerService {
|
|||||||
TestMinerService {
|
TestMinerService {
|
||||||
imported_transactions: RwLock::new(Vec::new()),
|
imported_transactions: RwLock::new(Vec::new()),
|
||||||
latest_closed_block: Mutex::new(None),
|
latest_closed_block: Mutex::new(None),
|
||||||
|
pending_transactions: Mutex::new(HashMap::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,6 +76,10 @@ impl MinerService for TestMinerService {
|
|||||||
&self.latest_closed_block
|
&self.latest_closed_block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn transaction(&self, hash: &H256) -> Option<SignedTransaction> {
|
||||||
|
self.pending_transactions.lock().unwrap().get(hash).and_then(|tx_ref| Some(tx_ref.clone()))
|
||||||
|
}
|
||||||
|
|
||||||
/// Submit `seal` as a valid solution for the header of `pow_hash`.
|
/// Submit `seal` as a valid solution for the header of `pow_hash`.
|
||||||
/// Will check the seal, but not actually insert the block into the chain.
|
/// Will check the seal, but not actually insert the block into the chain.
|
||||||
fn submit_seal(&self, _chain: &BlockChainClient, _pow_hash: H256, _seal: Vec<Bytes>) -> Result<(), Error> { unimplemented!(); }
|
fn submit_seal(&self, _chain: &BlockChainClient, _pow_hash: H256, _seal: Vec<Bytes>) -> Result<(), Error> { unimplemented!(); }
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use util::numbers::*;
|
use util::numbers::*;
|
||||||
use ethcore::transaction::{LocalizedTransaction, Action};
|
use ethcore::transaction::{LocalizedTransaction, Action, SignedTransaction};
|
||||||
use v1::types::{Bytes, OptionalValue};
|
use v1::types::{Bytes, OptionalValue};
|
||||||
|
|
||||||
#[derive(Debug, Default, Serialize)]
|
#[derive(Debug, Default, Serialize)]
|
||||||
@ -58,6 +58,27 @@ impl From<LocalizedTransaction> for Transaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<SignedTransaction> for Transaction {
|
||||||
|
fn from(t: SignedTransaction) -> Transaction {
|
||||||
|
Transaction {
|
||||||
|
hash: t.hash(),
|
||||||
|
nonce: t.nonce,
|
||||||
|
block_hash: OptionalValue::Null,
|
||||||
|
block_number: OptionalValue::Null,
|
||||||
|
transaction_index: OptionalValue::Null,
|
||||||
|
from: t.sender().unwrap(),
|
||||||
|
to: match t.action {
|
||||||
|
Action::Create => OptionalValue::Null,
|
||||||
|
Action::Call(ref address) => OptionalValue::Value(address.clone())
|
||||||
|
},
|
||||||
|
value: t.value,
|
||||||
|
gas_price: t.gas_price,
|
||||||
|
gas: t.gas,
|
||||||
|
input: Bytes::new(t.data.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
Loading…
Reference in New Issue
Block a user