Merge pull request #314 from ethcore/rpc_raw_continue

Rpc raw continue
This commit is contained in:
Svyatoslav Nikolsky 2016-12-13 18:15:53 +03:00 committed by GitHub
commit 145634ed29
12 changed files with 492 additions and 71 deletions

View File

@ -1,6 +1,6 @@
use v1::traits::BlockChain;
use v1::types::{GetBlockResponse, VerboseBlock, RawBlock};
use v1::types::{GetTxOutResponse, TxOutScriptPubKey};
use v1::types::{GetTxOutResponse, TransactionOutputScript};
use v1::types::GetTxOutSetInfoResponse;
use v1::types::H256;
use v1::types::U256;
@ -144,7 +144,7 @@ impl BlockChainClientCoreApi for BlockChainClientCore {
bestblock: block_header.hash().into(),
confirmations: best_block.number - meta.height() + 1,
value: 0.00000001f64 * (transaction.outputs[prev_out.index as usize].value as f64),
script_pub_key: TxOutScriptPubKey {
script: TransactionOutputScript {
asm: script_asm,
hex: script_bytes.clone().into(),
req_sigs: script.num_signatures_required() as u32,
@ -227,7 +227,7 @@ pub mod tests {
use primitives::hash::H256 as GlobalH256;
use v1::types::{VerboseBlock, RawBlock};
use v1::traits::BlockChain;
use v1::types::{GetTxOutResponse, TxOutScriptPubKey};
use v1::types::{GetTxOutResponse, TransactionOutputScript};
use v1::helpers::errors::block_not_found;
use v1::types::Bytes;
use v1::types::H256;
@ -291,7 +291,7 @@ pub mod tests {
bestblock: H256::from(0x56),
confirmations: 777,
value: 100000.56,
script_pub_key: TxOutScriptPubKey {
script: TransactionOutputScript {
asm: "Hello, world!!!".to_owned(),
hex: Bytes::new(vec![1, 2, 3, 4]),
req_sigs: 777,
@ -559,7 +559,7 @@ pub mod tests {
bestblock: "6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000".into(),
confirmations: 1,
value: 50.0,
script_pub_key: TxOutScriptPubKey {
script: TransactionOutputScript {
asm: "OP_PUSHBYTES_65 0x04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f\nOP_CHECKSIG\n".to_owned(),
hex: Bytes::from("4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac"),
req_sigs: 1,

View File

@ -1,9 +1,10 @@
use v1::traits::Raw;
use v1::types::RawTransaction;
use v1::types::{RawTransaction, TransactionInput, TransactionOutputs, Transaction, GetRawTransactionResponse};
use v1::types::H256;
use v1::helpers::errors::{execution, invalid_params};
use jsonrpc_core::Error;
use chain::Transaction;
use jsonrpc_macros::Trailing;
use chain::Transaction as GlobalTransaction;
use sync;
use ser::{Reader, deserialize};
use primitives::hash::H256 as GlobalH256;
@ -13,7 +14,7 @@ pub struct RawClient<T: RawClientCoreApi> {
}
pub trait RawClientCoreApi: Send + Sync + 'static {
fn accept_transaction(&self, transaction: Transaction) -> Result<GlobalH256, String>;
fn accept_transaction(&self, transaction: GlobalTransaction) -> Result<GlobalH256, String>;
}
pub struct RawClientCore {
@ -29,10 +30,10 @@ impl RawClientCore {
}
impl RawClientCoreApi for RawClientCore {
fn accept_transaction(&self, transaction: Transaction) -> Result<GlobalH256, String> {
fn accept_transaction(&self, transaction: GlobalTransaction) -> Result<GlobalH256, String> {
self.local_sync_node.accept_transaction(transaction)
}
}
}
impl<T> RawClient<T> where T: RawClientCoreApi {
pub fn new(core: T) -> Self {
@ -50,6 +51,18 @@ impl<T> Raw for RawClient<T> where T: RawClientCoreApi {
.map(|h| h.reversed().into())
.map_err(|e| execution(e))
}
fn create_raw_transaction(&self, _inputs: Vec<TransactionInput>, _outputs: TransactionOutputs, _lock_time: Trailing<u32>) -> Result<RawTransaction, Error> {
rpc_unimplemented!()
}
fn decode_raw_transaction(&self, _transaction: RawTransaction) -> Result<Transaction, Error> {
rpc_unimplemented!()
}
fn get_raw_transaction(&self, _hash: H256, _verbose: Trailing<bool>) -> Result<GetRawTransactionResponse, Error> {
rpc_unimplemented!()
}
}
#[cfg(test)]

View File

@ -11,21 +11,27 @@ build_rpc_trait! {
/// Parity-bitcoin blockchain data interface.
pub trait BlockChain {
/// Get hash of best block.
/// @curl-example: curl --data-binary '{"jsonrpc": "2.0", "method": "getbestblockhash", "params": [], "id":1 }' -H 'content-type: application/json;' http://127.0.0.1:8332/
#[rpc(name = "getbestblockhash")]
fn best_block_hash(&self) -> Result<H256, Error>;
/// Get hash of block at given height.
/// @curl-example: curl --data-binary '{"jsonrpc": "2.0", "method": "getblockhash", "params": [0], "id":1 }' -H 'content-type: application/json;' http://127.0.0.1:8332/
#[rpc(name = "getblockhash")]
fn block_hash(&self, u32) -> Result<H256, Error>;
/// Get proof-of-work difficulty as a multiple of the minimum difficulty
/// @curl-example: curl --data-binary '{"jsonrpc": "2.0", "method": "getdifficulty", "params": [], "id":1 }' -H 'content-type: application/json;' http://127.0.0.1:8332/
#[rpc(name = "getdifficulty")]
fn difficulty(&self) -> Result<f64, Error>;
/// Get information on given block.
/// @curl-example: curl --data-binary '{"jsonrpc": "2.0", "method": "getblock", "params": ["000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"], "id":1 }' -H 'content-type: application/json;' http://127.0.0.1:8332/
#[rpc(name = "getblock")]
fn block(&self, H256, Trailing<bool>) -> Result<GetBlockResponse, Error>;
/// Get details about an unspent transaction output.
/// @curl-example: curl --data-binary '{"jsonrpc": "2.0", "method": "gettxout", "params": ["4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", 0], "id":1 }' -H 'content-type: application/json;' http://127.0.0.1:8332/
#[rpc(name = "gettxout")]
fn transaction_out(&self, H256, u32, Trailing<bool>) -> Result<GetTxOutResponse, Error>;
/// Get statistics about the unspent transaction output set.
/// @curl-example: curl --data-binary '{"jsonrpc": "2.0", "method": "gettxoutsetinfo", "params": [], "id":1 }' -H 'content-type: application/json;' http://127.0.0.1:8332/
#[rpc(name = "gettxoutsetinfo")]
fn transaction_out_set_info(&self) -> Result<GetTxOutSetInfoResponse, Error>;
}

View File

@ -6,6 +6,7 @@ build_rpc_trait! {
/// Partiy-bitcoin miner data interface.
pub trait Miner {
/// Get block template for mining.
/// @curl-example: curl --data-binary '{"jsonrpc": "2.0", "method": "getblocktemplate", "params": [{"capabilities": ["coinbasetxn", "workid", "coinbase/append"]}], "id":1 }' -H 'content-type: application/json;' http://127.0.0.1:8332/
#[rpc(name = "getblocktemplate")]
fn get_block_template(&self, BlockTemplateRequest) -> Result<BlockTemplate, Error>;
}

View File

@ -1,13 +1,31 @@
use jsonrpc_macros::Trailing;
use jsonrpc_core::Error;
use v1::types::RawTransaction;
use v1::types::H256;
use v1::types::RawTransaction;
use v1::types::Transaction;
use v1::types::TransactionInput;
use v1::types::TransactionOutputs;
use v1::types::GetRawTransactionResponse;
build_rpc_trait! {
/// Partiy-bitcoin raw data interface.
pub trait Raw {
/// Adds transaction to the memory pool && relays it to the peers.
/// @curl-example: curl --data-binary '{"jsonrpc": "2.0", "method": "sendrawtransaction", "params": ["01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"], "id":1 }' -H 'content-type: application/json;' http://127.0.0.1:8332/
#[rpc(name = "sendrawtransaction")]
fn send_raw_transaction(&self, RawTransaction) -> Result<H256, Error>;
/// Create a transaction spending the given inputs and creating new outputs.
/// @curl-example: curl --data-binary '{"jsonrpc": "2.0", "method": "createrawtransaction", "params": [[{"txid":"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b","vout":0}],{"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa":0.01}], "id":1 }' -H 'content-type: application/json;' http://127.0.0.1:8332/
#[rpc(name = "createrawtransaction")]
fn create_raw_transaction(&self, Vec<TransactionInput>, TransactionOutputs, Trailing<u32>) -> Result<RawTransaction, Error>;
/// Return an object representing the serialized, hex-encoded transaction.
/// @curl-example: curl --data-binary '{"jsonrpc": "2.0", "method": "decoderawtransaction", "params": ["01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"], "id":1 }' -H 'content-type: application/json;' http://127.0.0.1:8332/
#[rpc(name = "decoderawtransaction")]
fn decode_raw_transaction(&self, RawTransaction) -> Result<Transaction, Error>;
/// Return the raw transaction data.
/// @curl-example: curl --data-binary '{"jsonrpc": "2.0", "method": "getrawtransaction", "params": ["4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"], "id":1 }' -H 'content-type: application/json;' http://127.0.0.1:8332/
#[rpc(name = "getrawtransaction")]
fn get_raw_transaction(&self, H256, Trailing<bool>) -> Result<GetRawTransactionResponse, Error>;
}
}

View File

@ -1,3 +1,4 @@
use super::bytes::Bytes;
/// Hex-encoded block
pub type RawBlock = Bytes;

View File

@ -1,6 +1,6 @@
use std::collections::HashMap;
use super::hash::H256;
use super::raw_transaction::RawTransaction;
use super::transaction::RawTransaction;
use db;
use miner;

View File

@ -1,7 +1,7 @@
use serde::{Serialize, Serializer};
use super::hash::H256;
use super::uint::U256;
use super::raw_block::RawBlock;
use super::block::RawBlock;
/// Response to getblock RPC request
#[derive(Debug)]

View File

@ -1,7 +1,5 @@
use super::address::Address;
use super::bytes::Bytes;
use super::hash::H256;
use super::script::ScriptType;
use super::transaction::TransactionOutputScript;
/// gettxout response
#[derive(Debug, Serialize, Deserialize, PartialEq)]
@ -15,36 +13,20 @@ pub struct GetTxOutResponse {
pub value: f64,
/// Script info
#[serde(rename = "scriptPubKey")]
pub script_pub_key: TxOutScriptPubKey,
pub script: TransactionOutputScript,
/// This transaction version
pub version: i32,
/// Is this transactio a coinbase transaction?
pub coinbase: bool,
}
/// Script pub key information
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct TxOutScriptPubKey {
/// Script code
pub asm: String,
/// Script hex
pub hex: Bytes,
/// Number of required signatures
#[serde(rename = "reqSigs")]
pub req_sigs: u32,
/// Type of script
#[serde(rename = "type")]
pub script_type: ScriptType,
/// Array of bitcoin addresses
pub addresses: Vec<Address>,
}
#[cfg(test)]
mod tests {
use serde_json;
use super::super::bytes::Bytes;
use super::super::hash::H256;
use super::super::script::ScriptType;
use super::super::transaction::TransactionOutputScript;
use super::*;
#[test]
@ -53,7 +35,7 @@ mod tests {
bestblock: H256::from(0x56),
confirmations: 777,
value: 100000.56,
script_pub_key: TxOutScriptPubKey {
script: TransactionOutputScript {
asm: "Hello, world!!!".to_owned(),
hex: Bytes::new(vec![1, 2, 3, 4]),
req_sigs: 777,
@ -72,7 +54,7 @@ mod tests {
bestblock: H256::from(0x56),
confirmations: 777,
value: 100000.56,
script_pub_key: TxOutScriptPubKey {
script: TransactionOutputScript {
asm: "Hello, world!!!".to_owned(),
hex: Bytes::new(vec![1, 2, 3, 4]),
req_sigs: 777,
@ -86,31 +68,4 @@ mod tests {
serde_json::from_str::<GetTxOutResponse>(r#"{"bestblock":"5600000000000000000000000000000000000000000000000000000000000000","confirmations":777,"value":100000.56,"scriptPubKey":{"asm":"Hello, world!!!","hex":"01020304","reqSigs":777,"type":"multisig","addresses":["1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa","1H5m1XzvHsjWX3wwU781ubctznEpNACrNC"]},"version":33,"coinbase":false}"#).unwrap(),
txout);
}
#[test]
fn tx_out_script_pubkey_serialize() {
let txout = TxOutScriptPubKey {
asm: "Hello, world!!!".to_owned(),
hex: Bytes::new(vec![1, 2, 3, 4]),
req_sigs: 777,
script_type: ScriptType::Multisig,
addresses: vec!["1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa".into(), "1H5m1XzvHsjWX3wwU781ubctznEpNACrNC".into()],
};
assert_eq!(serde_json::to_string(&txout).unwrap(), r#"{"asm":"Hello, world!!!","hex":"01020304","reqSigs":777,"type":"multisig","addresses":["1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa","1H5m1XzvHsjWX3wwU781ubctznEpNACrNC"]}"#);
}
#[test]
fn tx_out_script_pubkey_deserialize() {
let txout = TxOutScriptPubKey {
asm: "Hello, world!!!".to_owned(),
hex: Bytes::new(vec![1, 2, 3, 4]),
req_sigs: 777,
script_type: ScriptType::Multisig,
addresses: vec!["1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa".into(), "1H5m1XzvHsjWX3wwU781ubctznEpNACrNC".into()],
};
assert_eq!(
serde_json::from_str::<TxOutScriptPubKey>(r#"{"asm":"Hello, world!!!","hex":"01020304","reqSigs":777,"type":"multisig","addresses":["1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa","1H5m1XzvHsjWX3wwU781ubctznEpNACrNC"]}"#).unwrap(),
txout);
}
}

View File

@ -1,4 +1,5 @@
mod address;
mod block;
mod block_template;
mod block_template_request;
mod bytes;
@ -6,22 +7,23 @@ mod get_block_response;
mod get_tx_out_response;
mod get_tx_out_set_info_response;
mod hash;
mod raw_block;
mod raw_transaction;
mod script;
mod transaction;
mod uint;
mod nodes;
pub use self::address::Address;
pub use self::block::RawBlock;
pub use self::block_template::{BlockTemplate, BlockTemplateTransaction};
pub use self::block_template_request::{BlockTemplateRequest, BlockTemplateRequestMode};
pub use self::bytes::Bytes;
pub use self::get_block_response::{GetBlockResponse, VerboseBlock};
pub use self::get_tx_out_response::{GetTxOutResponse, TxOutScriptPubKey};
pub use self::get_tx_out_response::GetTxOutResponse;
pub use self::get_tx_out_set_info_response::GetTxOutSetInfoResponse;
pub use self::hash::{H160, H256};
pub use self::raw_block::RawBlock;
pub use self::raw_transaction::RawTransaction;
pub use self::script::ScriptType;
pub use self::transaction::{RawTransaction, Transaction, TransactionInput, TransactionOutput,
TransactionInputScript, TransactionOutputScript, SignedTransactionInput, GetRawTransactionResponse,
SignedTransactionOutput, TransactionOutputs};
pub use self::uint::U256;
pub use self::nodes::AddNodeOperation;

View File

@ -1,3 +0,0 @@
use super::bytes::Bytes;
pub type RawTransaction = Bytes;

View File

@ -0,0 +1,428 @@
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use super::address::Address;
use super::bytes::Bytes;
use super::hash::H256;
use super::script::ScriptType;
/// Hex-encoded transaction
pub type RawTransaction = Bytes;
/// Transaction input
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct TransactionInput {
/// Previous transaction id
pub txid: H256,
/// Previous transaction output index
pub vout: u32,
/// Sequence number
pub sequence: Option<u32>,
}
/// Transaction output
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct TransactionOutput {
/// Receiver' address
pub address: Address,
/// Amount in BTC
pub amount: f64,
}
/// Transaction outputs, which serializes/deserializes as KV-map
#[derive(Debug, PartialEq)]
pub struct TransactionOutputs {
/// Transaction outputs
pub outputs: Vec<TransactionOutput>,
}
/// Transaction input script
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct TransactionInputScript {
/// Script code
pub asm: String,
/// Script hex
pub hex: Bytes,
}
/// Transaction output script
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct TransactionOutputScript {
/// Script code
pub asm: String,
/// Script hex
pub hex: Bytes,
/// Number of required signatures
#[serde(rename = "reqSigs")]
pub req_sigs: u32,
/// Type of script
#[serde(rename = "type")]
pub script_type: ScriptType,
/// Array of bitcoin addresses
pub addresses: Vec<Address>,
}
/// Signed transaction input
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct SignedTransactionInput {
/// Previous transaction id
pub txid: H256,
/// Previous transaction output index
pub vout: u32,
/// Input script
pub script_sig: TransactionInputScript,
/// Sequence number
pub sequence: u32,
/// Hex-encoded witness data (if any)
pub txinwitness: Vec<String>,
}
/// Signed transaction output
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct SignedTransactionOutput {
/// Output value in BTC
pub value: f64,
/// Output index
pub n: u32,
/// Output script
#[serde(rename = "scriptPubKey")]
pub script: TransactionOutputScript,
}
/// Transaction
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct Transaction {
/// Raw transaction
pub hex: RawTransaction,
/// The transaction id (same as provided)
pub txid: H256,
/// The transaction hash (differs from txid for witness transactions)
pub hash: H256,
/// The serialized transaction size
pub size: usize,
/// The virtual transaction size (differs from size for witness transactions)
pub vsize: usize,
/// The version
pub version: i32,
/// The lock time
pub locktime: i32,
/// Transaction inputs
pub vin: Vec<SignedTransactionInput>,
/// Transaction outputs
pub vout: Vec<SignedTransactionOutput>,
/// Hash of the block this transaction is included in
pub blockhash: H256,
/// Number of confirmations of this transaction
pub confirmations: u32,
/// The transaction time in seconds since epoch (Jan 1 1970 GMT)
pub time: u32,
/// The block time in seconds since epoch (Jan 1 1970 GMT)
pub blocktime: u32,
}
/// Return value of `getrawtransaction` method
#[derive(Debug, PartialEq)]
pub enum GetRawTransactionResponse {
/// Return value when asking for raw transaction
Raw(RawTransaction),
/// Return value when asking for verbose transaction
Verbose(Transaction),
}
impl Serialize for GetRawTransactionResponse {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
match *self {
GetRawTransactionResponse::Raw(ref raw_transaction) => raw_transaction.serialize(serializer),
GetRawTransactionResponse::Verbose(ref verbose_transaction) => verbose_transaction.serialize(serializer),
}
}
}
impl TransactionOutputs {
pub fn len(&self) -> usize {
self.outputs.len()
}
}
impl Serialize for TransactionOutputs {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
let mut state = try!(serializer.serialize_map(Some(self.len())));
for output in &self.outputs {
try!(serializer.serialize_map_key(&mut state, &output.address));
try!(serializer.serialize_map_value(&mut state, &output.amount));
}
serializer.serialize_map_end(state)
}
}
impl Deserialize for TransactionOutputs {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where D: Deserializer {
use serde::de::{Visitor, MapVisitor};
struct TransactionOutputsVisitor;
impl Visitor for TransactionOutputsVisitor {
type Value = TransactionOutputs;
fn visit_map<V>(&mut self, mut visitor: V) -> Result<TransactionOutputs, V::Error> where V: MapVisitor {
let mut outputs: Vec<TransactionOutput> = Vec::with_capacity(visitor.size_hint().0);
while let Some((address, amount)) = try!(visitor.visit()) {
outputs.push(TransactionOutput {
address: address,
amount: amount,
});
}
try!(visitor.end());
Ok(TransactionOutputs {
outputs: outputs,
})
}
}
deserializer.deserialize(TransactionOutputsVisitor)
}
}
#[cfg(test)]
mod tests {
use serde_json;
use super::super::bytes::Bytes;
use super::super::hash::H256;
use super::super::script::ScriptType;
use super::*;
#[test]
fn transaction_input_serialize() {
let txinput = TransactionInput {
txid: H256::from(7),
vout: 33,
sequence: Some(88),
};
assert_eq!(serde_json::to_string(&txinput).unwrap(), r#"{"txid":"0700000000000000000000000000000000000000000000000000000000000000","vout":33,"sequence":88}"#);
}
#[test]
fn transaction_input_deserialize() {
let txinput = TransactionInput {
txid: H256::from(7),
vout: 33,
sequence: Some(88),
};
assert_eq!(
serde_json::from_str::<TransactionInput>(r#"{"txid":"0700000000000000000000000000000000000000000000000000000000000000","vout":33,"sequence":88}"#).unwrap(),
txinput);
}
#[test]
fn transaction_output_serialize() {
let txout = TransactionOutput {
address: "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa".into(),
amount: 123.45,
};
assert_eq!(serde_json::to_string(&txout).unwrap(), r#"{"address":"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa","amount":123.45}"#);
}
#[test]
fn transaction_output_deserialize() {
let txout = TransactionOutput {
address: "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa".into(),
amount: 123.45,
};
assert_eq!(
serde_json::from_str::<TransactionOutput>(r#"{"address":"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa","amount":123.45}"#).unwrap(),
txout);
}
#[test]
fn transaction_outputs_serialize() {
let txout = TransactionOutputs {
outputs: vec![
TransactionOutput {
address: "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa".into(),
amount: 123.45,
},
TransactionOutput {
address: "1H5m1XzvHsjWX3wwU781ubctznEpNACrNC".into(),
amount: 67.89,
},
]
};
assert_eq!(serde_json::to_string(&txout).unwrap(), r#"{"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa":123.45,"1H5m1XzvHsjWX3wwU781ubctznEpNACrNC":67.89}"#);
}
#[test]
fn transaction_outputs_deserialize() {
let txout = TransactionOutputs {
outputs: vec![
TransactionOutput {
address: "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa".into(),
amount: 123.45,
},
TransactionOutput {
address: "1H5m1XzvHsjWX3wwU781ubctznEpNACrNC".into(),
amount: 67.89,
},
]
};
assert_eq!(
serde_json::from_str::<TransactionOutputs>(r#"{"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa":123.45,"1H5m1XzvHsjWX3wwU781ubctznEpNACrNC":67.89}"#).unwrap(),
txout);
}
#[test]
fn transaction_input_script_serialize() {
let txin = TransactionInputScript {
asm: "Hello, world!!!".to_owned(),
hex: Bytes::new(vec![1, 2, 3, 4]),
};
assert_eq!(serde_json::to_string(&txin).unwrap(), r#"{"asm":"Hello, world!!!","hex":"01020304"}"#);
}
#[test]
fn transaction_input_script_deserialize() {
let txin = TransactionInputScript {
asm: "Hello, world!!!".to_owned(),
hex: Bytes::new(vec![1, 2, 3, 4]),
};
assert_eq!(
serde_json::from_str::<TransactionInputScript>(r#"{"asm":"Hello, world!!!","hex":"01020304"}"#).unwrap(),
txin);
}
#[test]
fn transaction_output_script_serialize() {
let txout = TransactionOutputScript {
asm: "Hello, world!!!".to_owned(),
hex: Bytes::new(vec![1, 2, 3, 4]),
req_sigs: 777,
script_type: ScriptType::Multisig,
addresses: vec!["1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa".into(), "1H5m1XzvHsjWX3wwU781ubctznEpNACrNC".into()],
};
assert_eq!(serde_json::to_string(&txout).unwrap(), r#"{"asm":"Hello, world!!!","hex":"01020304","reqSigs":777,"type":"multisig","addresses":["1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa","1H5m1XzvHsjWX3wwU781ubctznEpNACrNC"]}"#);
}
#[test]
fn transaction_output_script_deserialize() {
let txout = TransactionOutputScript {
asm: "Hello, world!!!".to_owned(),
hex: Bytes::new(vec![1, 2, 3, 4]),
req_sigs: 777,
script_type: ScriptType::Multisig,
addresses: vec!["1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa".into(), "1H5m1XzvHsjWX3wwU781ubctznEpNACrNC".into()],
};
assert_eq!(
serde_json::from_str::<TransactionOutputScript>(r#"{"asm":"Hello, world!!!","hex":"01020304","reqSigs":777,"type":"multisig","addresses":["1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa","1H5m1XzvHsjWX3wwU781ubctznEpNACrNC"]}"#).unwrap(),
txout);
}
#[test]
fn signed_transaction_input_serialize() {
let txin = SignedTransactionInput {
txid: H256::from(77),
vout: 13,
script_sig: TransactionInputScript {
asm: "Hello, world!!!".to_owned(),
hex: Bytes::new(vec![1, 2, 3, 4]),
},
sequence: 123,
txinwitness: vec![],
};
assert_eq!(serde_json::to_string(&txin).unwrap(), r#"{"txid":"4d00000000000000000000000000000000000000000000000000000000000000","vout":13,"script_sig":{"asm":"Hello, world!!!","hex":"01020304"},"sequence":123,"txinwitness":[]}"#);
}
#[test]
fn signed_transaction_input_deserialize() {
let txin = SignedTransactionInput {
txid: H256::from(77),
vout: 13,
script_sig: TransactionInputScript {
asm: "Hello, world!!!".to_owned(),
hex: Bytes::new(vec![1, 2, 3, 4]),
},
sequence: 123,
txinwitness: vec![],
};
assert_eq!(
serde_json::from_str::<SignedTransactionInput>(r#"{"txid":"4d00000000000000000000000000000000000000000000000000000000000000","vout":13,"script_sig":{"asm":"Hello, world!!!","hex":"01020304"},"sequence":123,"txinwitness":[]}"#).unwrap(),
txin);
}
#[test]
fn signed_transaction_output_serialize() {
let txout = SignedTransactionOutput {
value: 777.79,
n: 12,
script: TransactionOutputScript {
asm: "Hello, world!!!".to_owned(),
hex: Bytes::new(vec![1, 2, 3, 4]),
req_sigs: 777,
script_type: ScriptType::Multisig,
addresses: vec!["1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa".into(), "1H5m1XzvHsjWX3wwU781ubctznEpNACrNC".into()],
},
};
assert_eq!(serde_json::to_string(&txout).unwrap(), r#"{"value":777.79,"n":12,"scriptPubKey":{"asm":"Hello, world!!!","hex":"01020304","reqSigs":777,"type":"multisig","addresses":["1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa","1H5m1XzvHsjWX3wwU781ubctznEpNACrNC"]}}"#);
}
#[test]
fn signed_transaction_output_deserialize() {
let txout = SignedTransactionOutput {
value: 777.79,
n: 12,
script: TransactionOutputScript {
asm: "Hello, world!!!".to_owned(),
hex: Bytes::new(vec![1, 2, 3, 4]),
req_sigs: 777,
script_type: ScriptType::Multisig,
addresses: vec!["1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa".into(), "1H5m1XzvHsjWX3wwU781ubctznEpNACrNC".into()],
},
};
assert_eq!(
serde_json::from_str::<SignedTransactionOutput>(r#"{"value":777.79,"n":12,"scriptPubKey":{"asm":"Hello, world!!!","hex":"01020304","reqSigs":777,"type":"multisig","addresses":["1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa","1H5m1XzvHsjWX3wwU781ubctznEpNACrNC"]}}"#).unwrap(),
txout);
}
#[test]
fn transaction_serialize() {
let tx = Transaction {
hex: "DEADBEEF".into(),
txid: H256::from(4),
hash: H256::from(5),
size: 33,
vsize: 44,
version: 55,
locktime: 66,
vin: vec![],
vout: vec![],
blockhash: H256::from(6),
confirmations: 77,
time: 88,
blocktime: 99,
};
assert_eq!(serde_json::to_string(&tx).unwrap(), r#"{"hex":"deadbeef","txid":"0400000000000000000000000000000000000000000000000000000000000000","hash":"0500000000000000000000000000000000000000000000000000000000000000","size":33,"vsize":44,"version":55,"locktime":66,"vin":[],"vout":[],"blockhash":"0600000000000000000000000000000000000000000000000000000000000000","confirmations":77,"time":88,"blocktime":99}"#);
}
#[test]
fn transaction_deserialize() {
let tx = Transaction {
hex: "DEADBEEF".into(),
txid: H256::from(4),
hash: H256::from(5),
size: 33,
vsize: 44,
version: 55,
locktime: 66,
vin: vec![],
vout: vec![],
blockhash: H256::from(6),
confirmations: 77,
time: 88,
blocktime: 99,
};
assert_eq!(
serde_json::from_str::<Transaction>(r#"{"hex":"deadbeef","txid":"0400000000000000000000000000000000000000000000000000000000000000","hash":"0500000000000000000000000000000000000000000000000000000000000000","size":33,"vsize":44,"version":55,"locktime":66,"vin":[],"vout":[],"blockhash":"0600000000000000000000000000000000000000000000000000000000000000","confirmations":77,"time":88,"blocktime":99}"#).unwrap(),
tx);
}
}