blockchain transaction api
This commit is contained in:
parent
038f80437e
commit
483ee1fbce
@ -85,6 +85,9 @@ pub trait BlockProvider {
|
|||||||
/// Get the hash of given block's number.
|
/// Get the hash of given block's number.
|
||||||
fn block_hash(&self, index: BlockNumber) -> Option<H256>;
|
fn block_hash(&self, index: BlockNumber) -> Option<H256>;
|
||||||
|
|
||||||
|
/// Get the address of transaction with given hash.
|
||||||
|
fn transaction_address(&self, hash: &H256) -> Option<TransactionAddress>;
|
||||||
|
|
||||||
/// Get the partial-header of a block.
|
/// Get the partial-header of a block.
|
||||||
fn block_header(&self, hash: &H256) -> Option<Header> {
|
fn block_header(&self, hash: &H256) -> Option<Header> {
|
||||||
self.block(hash).map(|bytes| BlockView::new(&bytes).header())
|
self.block(hash).map(|bytes| BlockView::new(&bytes).header())
|
||||||
@ -107,6 +110,16 @@ pub trait BlockProvider {
|
|||||||
self.block(hash).map(|bytes| BlockView::new(&bytes).header_view().number())
|
self.block(hash).map(|bytes| BlockView::new(&bytes).header_view().number())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get transaction with given transaction hash.
|
||||||
|
fn transaction(&self, hash: &H256) -> Option<SignedTransaction> {
|
||||||
|
self.transaction_address(hash).and_then(|address| self.transaction_at(&address))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get transaction at given address.
|
||||||
|
fn transaction_at(&self, address: &TransactionAddress) -> Option<SignedTransaction> {
|
||||||
|
self.block(&address.block_hash).map(|bytes| BlockView::new(&bytes).transactions()).and_then(|t| t.into_iter().nth(address.index))
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a list of transactions for a given block.
|
/// Get a list of transactions for a given block.
|
||||||
/// Returns None if block deos not exist.
|
/// Returns None if block deos not exist.
|
||||||
fn transactions(&self, hash: &H256) -> Option<Vec<SignedTransaction>> {
|
fn transactions(&self, hash: &H256) -> Option<Vec<SignedTransaction>> {
|
||||||
@ -201,6 +214,11 @@ impl BlockProvider for BlockChain {
|
|||||||
fn block_hash(&self, index: BlockNumber) -> Option<H256> {
|
fn block_hash(&self, index: BlockNumber) -> Option<H256> {
|
||||||
self.query_extras(&index, &self.block_hashes)
|
self.query_extras(&index, &self.block_hashes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the address of transaction with given hash.
|
||||||
|
fn transaction_address(&self, hash: &H256) -> Option<TransactionAddress> {
|
||||||
|
self.query_extras(hash, &self.transaction_addresses)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const COLLECTION_QUEUE_SIZE: usize = 8;
|
const COLLECTION_QUEUE_SIZE: usize = 8;
|
||||||
@ -474,6 +492,14 @@ impl BlockChain {
|
|||||||
parent_details.children.push(hash.clone());
|
parent_details.children.push(hash.clone());
|
||||||
batch.put_extras(&parent_hash, &parent_details);
|
batch.put_extras(&parent_hash, &parent_details);
|
||||||
|
|
||||||
|
// update transaction addresses
|
||||||
|
for (i, tx_hash) in block.transaction_hashes().iter().enumerate() {
|
||||||
|
batch.put_extras(tx_hash, &TransactionAddress {
|
||||||
|
block_hash: hash.clone(),
|
||||||
|
index: i
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// if it's not new best block, just return
|
// if it's not new best block, just return
|
||||||
if !is_new_best {
|
if !is_new_best {
|
||||||
return (batch, None, details);
|
return (batch, None, details);
|
||||||
@ -824,4 +850,21 @@ mod tests {
|
|||||||
let bc = bc_result.reference();
|
let bc = bc_result.reference();
|
||||||
assert_eq!(bc.best_block_number(), 0);
|
assert_eq!(bc.best_block_number(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn find_transaction_by_hash() {
|
||||||
|
let genesis = "f901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0af81e09f8c46ca322193edfda764fa7e88e81923f802f1d325ec0b0308ac2cd0a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083023e38808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0".from_hex().unwrap();
|
||||||
|
let b1 = "f904a8f901faa0ce1f26f798dd03c8782d63b3e42e79a64eaea5694ea686ac5d7ce3df5171d1aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a65c2364cd0f1542d761823dc0109c6b072f14c20459598c5455c274601438f4a070616ebd7ad2ed6fb7860cf7e9df00163842351c38a87cac2c1cb193895035a2a05c5b4fc43c2d45787f54e1ae7d27afdb4ad16dfc567c5692070d5c4556e0b1d7b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000183023ec683021536845685109780a029f07836e4e59229b3a065913afc27702642c683bba689910b2b2fd45db310d3888957e6d004a31802f902a7f85f800a8255f094aaaf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca0575da4e21b66fa764be5f74da9389e67693d066fb0d1312e19e17e501da00ecda06baf5a5327595f6619dfc2fcb3f2e6fb410b5810af3cb52d0e7508038e91a188f85f010a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba04fa966bf34b93abc1bcd665554b7f316b50f928477b50be0f3285ead29d18c5ba017bba0eeec1625ab433746955e125d46d80b7fdc97386c51266f842d8e02192ef85f020a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca004377418ae981cc32b1312b4a427a1d69a821b28db8584f5f2bd8c6d42458adaa053a1dba1af177fac92f3b6af0a9fa46a22adf56e686c93794b6a012bf254abf5f85f030a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca04fe13febd28a05f4fcb2f451d7ddc2dda56486d9f8c79a62b0ba4da775122615a0651b2382dd402df9ebc27f8cb4b2e0f3cea68dda2dca0ee9603608f0b6f51668f85f040a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba078e6a0ba086a08f8450e208a399bb2f2d2a0d984acd2517c7c7df66ccfab567da013254002cd45a97fac049ae00afbc43ed0d9961d0c56a3b2382c80ce41c198ddf85f050a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba0a7174d8f43ea71c8e3ca9477691add8d80ac8e0ed89d8d8b572041eef81f4a54a0534ea2e28ec4da3b5b944b18c51ec84a5cf35f5b3343c5fb86521fd2d388f506f85f060a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba034bd04065833536a10c77ee2a43a5371bc6d34837088b861dd9d4b7f44074b59a078807715786a13876d3455716a6b9cb2186b7a4887a5c31160fc877454958616c0".from_hex().unwrap();
|
||||||
|
let b1_hash = H256::from_str("f53f268d23a71e85c7d6d83a9504298712b84c1a2ba220441c86eeda0bf0b6e3").unwrap();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let bc = BlockChain::new(&genesis, temp.as_path());
|
||||||
|
bc.insert_block(&b1);
|
||||||
|
|
||||||
|
let transactions = bc.transactions(&b1_hash).unwrap();
|
||||||
|
assert_eq!(transactions.len(), 7);
|
||||||
|
for t in transactions {
|
||||||
|
assert_eq!(bc.transaction(&t.hash()).unwrap(), t);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,7 @@ pub struct TransactionAddress {
|
|||||||
/// Block hash
|
/// Block hash
|
||||||
pub block_hash: H256,
|
pub block_hash: H256,
|
||||||
/// Transaction index within the block
|
/// Transaction index within the block
|
||||||
pub index: u64
|
pub index: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtrasIndexable for TransactionAddress {
|
impl ExtrasIndexable for TransactionAddress {
|
||||||
|
@ -20,7 +20,7 @@ use util::*;
|
|||||||
use error::*;
|
use error::*;
|
||||||
use evm::Schedule;
|
use evm::Schedule;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
/// Transaction action type.
|
/// Transaction action type.
|
||||||
pub enum Action {
|
pub enum Action {
|
||||||
/// Create creates new contract.
|
/// Create creates new contract.
|
||||||
@ -45,7 +45,7 @@ impl Decodable for Action {
|
|||||||
|
|
||||||
/// A set of information describing an externally-originating message call
|
/// A set of information describing an externally-originating message call
|
||||||
/// or contract creation operation.
|
/// or contract creation operation.
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct Transaction {
|
pub struct Transaction {
|
||||||
/// Nonce.
|
/// Nonce.
|
||||||
pub nonce: U256,
|
pub nonce: U256,
|
||||||
@ -158,7 +158,7 @@ impl Transaction {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Eq)]
|
||||||
pub struct SignedTransaction {
|
pub struct SignedTransaction {
|
||||||
/// Plain Transaction.
|
/// Plain Transaction.
|
||||||
unsigned: Transaction,
|
unsigned: Transaction,
|
||||||
@ -174,6 +174,12 @@ pub struct SignedTransaction {
|
|||||||
sender: RefCell<Option<Address>>
|
sender: RefCell<Option<Address>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for SignedTransaction {
|
||||||
|
fn eq(&self, other: &SignedTransaction) -> bool {
|
||||||
|
self.unsigned == other.unsigned && self.v == other.v && self.r == other.r && self.s == other.s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Deref for SignedTransaction {
|
impl Deref for SignedTransaction {
|
||||||
type Target = Transaction;
|
type Target = Transaction;
|
||||||
|
|
||||||
|
@ -294,6 +294,10 @@ mod tests {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn transaction_address(&self, _hash: &H256) -> Option<TransactionAddress> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the hash of given block's number.
|
/// Get the hash of given block's number.
|
||||||
fn block_hash(&self, index: BlockNumber) -> Option<H256> {
|
fn block_hash(&self, index: BlockNumber) -> Option<H256> {
|
||||||
self.numbers.get(&index).cloned()
|
self.numbers.get(&index).cloned()
|
||||||
|
Loading…
Reference in New Issue
Block a user