StateDiff uses serde preprocessor.

This commit is contained in:
Gav Wood 2016-06-06 00:24:21 +02:00
parent f775606c37
commit 1fa8f108d9
4 changed files with 82 additions and 8 deletions

View File

@ -20,15 +20,12 @@ use std::sync::{Weak, Arc};
use jsonrpc_core::*; use jsonrpc_core::*;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use util::{H256, U256, FixedHash, Uint}; use util::{H256, U256, FixedHash, Uint};
use serde;
use ethcore::client::{BlockChainClient, CallAnalytics, TransactionID, TraceId}; use ethcore::client::{BlockChainClient, CallAnalytics, TransactionID, TraceId};
use ethcore::trace::VMTrace; use ethcore::trace::VMTrace;
use ethcore::miner::MinerService; use ethcore::miner::MinerService;
use ethcore::state_diff::StateDiff;
use ethcore::account_diff::{Diff, Existance};
use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Action}; use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Action};
use v1::traits::Traces; use v1::traits::Traces;
use v1::types::{TraceFilter, LocalizedTrace, Trace, BlockNumber, Index, CallRequest, Bytes}; use v1::types::{TraceFilter, LocalizedTrace, Trace, BlockNumber, Index, CallRequest, Bytes, StateDiff};
/// Traces api implementation. /// Traces api implementation.
pub struct TracesClient<C, M> where C: BlockChainClient, M: MinerService { pub struct TracesClient<C, M> where C: BlockChainClient, M: MinerService {
@ -108,7 +105,7 @@ fn vm_trace_to_object(t: &VMTrace) -> Value {
ret.insert("ops".to_owned(), Value::Array(ops)); ret.insert("ops".to_owned(), Value::Array(ops));
Value::Object(ret) Value::Object(ret)
} }
/*
fn diff_to_object<T>(d: &Diff<T>) -> Value where T: serde::Serialize + Eq { fn diff_to_object<T>(d: &Diff<T>) -> Value where T: serde::Serialize + Eq {
let mut ret = BTreeMap::new(); let mut ret = BTreeMap::new();
match *d { match *d {
@ -149,7 +146,7 @@ fn state_diff_to_object(t: &StateDiff) -> Value {
])) ]))
}).collect::<BTreeMap<_, _>>()) }).collect::<BTreeMap<_, _>>())
} }
*/
impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M: MinerService + 'static { impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M: MinerService + 'static {
fn filter(&self, params: Params) -> Result<Value, Error> { fn filter(&self, params: Params) -> Result<Value, Error> {
from_params::<(TraceFilter,)>(params) from_params::<(TraceFilter,)>(params)
@ -217,7 +214,7 @@ impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M:
ret.insert("vmTrace".to_owned(), vm_trace_to_object(&vm_trace)); ret.insert("vmTrace".to_owned(), vm_trace_to_object(&vm_trace));
} }
if let Some(state_diff) = executed.state_diff { if let Some(state_diff) = executed.state_diff {
ret.insert("stateDiff".to_owned(), state_diff_to_object(&state_diff)); ret.insert("stateDiff".to_owned(), to_value(&StateDiff::from(state_diff)).unwrap());
} }
return Ok(Value::Object(ret)) return Ok(Value::Object(ret))
} }

View File

@ -36,6 +36,12 @@ impl Bytes {
} }
} }
impl From<Vec<u8>> for Bytes {
fn from(bytes: Vec<u8>) -> Bytes {
Bytes(bytes)
}
}
impl Serialize for Bytes { impl Serialize for Bytes {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer { where S: Serializer {

View File

@ -41,5 +41,5 @@ pub use self::transaction::Transaction;
pub use self::transaction_request::{TransactionRequest, TransactionConfirmation, TransactionModification}; pub use self::transaction_request::{TransactionRequest, TransactionConfirmation, TransactionModification};
pub use self::call_request::CallRequest; pub use self::call_request::CallRequest;
pub use self::receipt::Receipt; pub use self::receipt::Receipt;
pub use self::trace::{Trace, LocalizedTrace}; pub use self::trace::{Trace, LocalizedTrace, StateDiff};
pub use self::trace_filter::TraceFilter; pub use self::trace_filter::TraceFilter;

View File

@ -14,11 +14,82 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::collections::BTreeMap;
use util::{Address, U256, H256}; use util::{Address, U256, H256};
use serde::{Serialize, Serializer};
use ethcore::trace::trace; use ethcore::trace::trace;
use ethcore::trace::{Trace as EthTrace, LocalizedTrace as EthLocalizedTrace}; use ethcore::trace::{Trace as EthTrace, LocalizedTrace as EthLocalizedTrace};
use ethcore::state_diff;
use ethcore::account_diff;
use v1::types::Bytes; use v1::types::Bytes;
#[derive(Debug, Serialize)]
/// Aux type for Diff::Changed.
pub struct ChangedType<T> where T: Serialize {
from: T,
to: T,
}
#[derive(Debug, Serialize)]
/// Serde-friendly `Diff` shadow.
pub enum Diff<T> where T: Serialize {
#[serde(rename="=")]
Same,
#[serde(rename="+")]
Born(T),
#[serde(rename="-")]
Died(T),
#[serde(rename="*")]
Changed(ChangedType<T>),
}
impl<T, U> From<account_diff::Diff<T>> for Diff<U> where T: Eq, U: Serialize + From<T> {
fn from(c: account_diff::Diff<T>) -> Self {
match c {
account_diff::Diff::Same => Diff::Same,
account_diff::Diff::Born(t) => Diff::Born(t.into()),
account_diff::Diff::Died(t) => Diff::Died(t.into()),
account_diff::Diff::Changed(t, u) => Diff::Changed(ChangedType{from: t.into(), to: u.into()}),
}
}
}
#[derive(Debug, Serialize)]
/// Serde-friendly `AccountDiff` shadow.
pub struct AccountDiff {
pub balance: Diff<U256>,
pub nonce: Diff<U256>,
pub code: Diff<Bytes>,
pub storage: BTreeMap<H256, Diff<H256>>,
}
impl From<account_diff::AccountDiff> for AccountDiff {
fn from(c: account_diff::AccountDiff) -> Self {
AccountDiff {
balance: c.balance.into(),
nonce: c.nonce.into(),
code: c.code.into(),
storage: c.storage.into_iter().map(|(k, v)| (k, v.into())).collect(),
}
}
}
/// Serde-friendly `StateDiff` shadow.
pub struct StateDiff(BTreeMap<Address, AccountDiff>);
impl Serialize for StateDiff {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer {
Serialize::serialize(&self.0, serializer)
}
}
impl From<state_diff::StateDiff> for StateDiff {
fn from(c: state_diff::StateDiff) -> Self {
StateDiff(c.0.into_iter().map(|(k, v)| (k, v.into())).collect())
}
}
/// Create response /// Create response
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
pub struct Create { pub struct Create {