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

EIP-1186: add eth_getProof RPC-Method #9001

Merged
merged 100 commits into from
Nov 21, 2018
Merged
Show file tree
Hide file tree
Changes from 99 commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
c99e021
added eth_getAccount
simon-jentzsch Mar 27, 2018
f6d95f8
changed to getProof
simon-jentzsch Mar 28, 2018
d13364d
implemented storage_proof
simon-jentzsch Mar 28, 2018
767847b
better formatting of storage proof
simon-jentzsch Mar 28, 2018
35e522c
fixed imports;2C
simon-jentzsch Jun 19, 2018
7a62f08
removed spaces
simon-jentzsch Jun 29, 2018
388947f
fixed whitespace
simon-jentzsch Jun 29, 2018
f4090a9
fixed docker
simon-jentzsch Jun 29, 2018
2ba4396
added doc
simon-jentzsch Jun 29, 2018
bbfbaa5
fixed Compile-error
simon-jentzsch Sep 20, 2018
2621b4a
expose more ports
simon-jentzsch Sep 21, 2018
080ce05
added eth_getAccount
simon-jentzsch Mar 27, 2018
4f9f285
changed to getProof
simon-jentzsch Mar 28, 2018
a66db7f
implemented storage_proof
simon-jentzsch Mar 28, 2018
f5f3e1c
better formatting of storage proof
simon-jentzsch Mar 28, 2018
ad50c15
fixed docker
simon-jentzsch Jun 19, 2018
2f1f536
removed slockit-changes
simon-jentzsch Jun 29, 2018
f024622
fixed Dockerfile
simon-jentzsch Jun 29, 2018
c119551
intend
simon-jentzsch Jun 29, 2018
7a26db8
spaces
simon-jentzsch Jun 29, 2018
0fa4456
removed spaces
simon-jentzsch Jun 29, 2018
ddd2db5
fixed whitespace
simon-jentzsch Jun 29, 2018
b55131d
fixed docker
simon-jentzsch Jun 29, 2018
fc4da1c
tabs
simon-jentzsch Jun 29, 2018
be62ef5
fixed Compile-error
simon-jentzsch Sep 20, 2018
b616a20
added eth_getAccount
simon-jentzsch Mar 27, 2018
e2cc24e
changed to getProof
simon-jentzsch Mar 28, 2018
0b4ad47
implemented storage_proof
simon-jentzsch Mar 28, 2018
345712b
fixed docker
simon-jentzsch Jun 19, 2018
8c3adb4
removed slockit-changes
simon-jentzsch Jun 29, 2018
a3348c7
fixed Dockerfile
simon-jentzsch Jun 29, 2018
cbc8f64
intend
simon-jentzsch Jun 29, 2018
8f59da2
spaces
simon-jentzsch Jun 29, 2018
785d35b
removed spaces
simon-jentzsch Jun 29, 2018
0807ea3
fixed whitespace
simon-jentzsch Jun 29, 2018
2663199
fixed docker
simon-jentzsch Jun 29, 2018
8128639
tabs
simon-jentzsch Jun 29, 2018
aa194da
merged changes
simon-jentzsch Oct 18, 2018
e5b4e21
fixed warnings
simon-jentzsch Oct 18, 2018
eeceb4d
added eth_getAccount
simon-jentzsch Mar 27, 2018
81fc2a2
changed to getProof
simon-jentzsch Mar 28, 2018
44327c6
implemented storage_proof
simon-jentzsch Mar 28, 2018
90c24f5
better formatting of storage proof
simon-jentzsch Mar 28, 2018
1c2c603
Update Dockerfile
simon-jentzsch May 15, 2018
ce9d30d
fixed docker
simon-jentzsch Jun 19, 2018
8394d82
removed slockit-changes
simon-jentzsch Jun 29, 2018
ddbf8db
fixed Dockerfile
simon-jentzsch Jun 29, 2018
690d94c
intend
simon-jentzsch Jun 29, 2018
be46184
spaces
simon-jentzsch Jun 29, 2018
6f91025
removed spaces
simon-jentzsch Jun 29, 2018
39fd491
fixed whitespace
simon-jentzsch Jun 29, 2018
1831b00
fixed docker
simon-jentzsch Jun 29, 2018
d09e66e
tabs
simon-jentzsch Jun 29, 2018
9888eac
added eth_getAccount
simon-jentzsch Mar 27, 2018
8beaa27
changed to getProof
simon-jentzsch Mar 28, 2018
f69855c
implemented storage_proof
simon-jentzsch Mar 28, 2018
3340d80
removed spaces
simon-jentzsch Jun 29, 2018
2e4e809
fixed whitespace
simon-jentzsch Jun 29, 2018
501cd20
fixed docker
simon-jentzsch Jun 29, 2018
2ec8ecb
added eth_getAccount
simon-jentzsch Mar 27, 2018
0297c27
changed to getProof
simon-jentzsch Mar 28, 2018
61a27f3
implemented storage_proof
simon-jentzsch Mar 28, 2018
2ae1e30
better formatting of storage proof
simon-jentzsch Mar 28, 2018
232558b
fixed docker
simon-jentzsch Jun 19, 2018
76ecd30
removed slockit-changes
simon-jentzsch Jun 29, 2018
8101a00
fixed Dockerfile
simon-jentzsch Jun 29, 2018
529efe9
intend
simon-jentzsch Jun 29, 2018
940690b
spaces
simon-jentzsch Jun 29, 2018
6cc9084
removed spaces
simon-jentzsch Jun 29, 2018
e33d262
fixed whitespace
simon-jentzsch Jun 29, 2018
9649190
fixed docker
simon-jentzsch Jun 29, 2018
412ff56
tabs
simon-jentzsch Jun 29, 2018
76f5618
merged changes
simon-jentzsch Oct 18, 2018
ddbc0cd
fixed merge error
simon-jentzsch Oct 18, 2018
4c3d318
fixed formatting
simon-jentzsch Oct 28, 2018
16abb5e
fixed rename_all = "camelCase"
simon-jentzsch Nov 5, 2018
1e4216a
fixed tabs
simon-jentzsch Nov 5, 2018
d3a2497
fixed spaces
simon-jentzsch Nov 5, 2018
df7a9ff
removed port exposer
simon-jentzsch Nov 5, 2018
468f82f
formatting
simon-jentzsch Nov 5, 2018
8edb13b
fixed comment
simon-jentzsch Nov 5, 2018
85860f7
use filter_map
simon-jentzsch Nov 5, 2018
b988548
formatting
simon-jentzsch Nov 5, 2018
8662f39
use better variable names
simon-jentzsch Nov 5, 2018
c35cfbf
changed casting
simon-jentzsch Nov 6, 2018
b3dd659
fixed tabs
simon-jentzsch Nov 6, 2018
e766cb1
remote into() from address
simon-jentzsch Nov 6, 2018
179bb78
remove space
niklasad1 Nov 6, 2018
70c48a9
fixed storage_index
niklasad1 Nov 6, 2018
3a9c3d8
fixed clone
simon-jentzsch Nov 6, 2018
0c6c8a9
fixed format
niklasad1 Nov 6, 2018
972c4c2
fixed empty lines
simon-jentzsch Nov 6, 2018
6f67a42
Merge branch 'in3' of github.com:slockit/parity into in3
simon-jentzsch Nov 6, 2018
fa05357
removed Option from EthAccount
simon-jentzsch Nov 6, 2018
4db8cec
fixed storage_index
simon-jentzsch Nov 6, 2018
1d652dc
implemented test and fixed the struct-spaces
simon-jentzsch Nov 8, 2018
094898a
Merge branch 'master' into in3
5chdn Nov 17, 2018
b27be88
fixed tests
simon-jentzsch Nov 19, 2018
151ff09
added experimental RPCs flag for getProof
simon-jentzsch Nov 19, 2018
ad9c241
optmized code
simon-jentzsch Nov 19, 2018
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 parity/rpc_apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ impl FullDependencies {
allow_pending_receipt_query: !self.geth_compatibility,
send_block_number_in_get_work: !self.geth_compatibility,
gas_price_percentile: self.gas_price_percentile,
allow_experimental_rpcs: self.experimental_rpcs,
}
);
handler.extend_with(client.to_delegate());
Expand Down
58 changes: 54 additions & 4 deletions rpc/src/v1/impls/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH};
use std::sync::Arc;

use rlp::Rlp;
use ethereum_types::{U256, H256, Address};
use ethereum_types::{U256, H256, H160, Address};
use parking_lot::Mutex;

use ethash::{self, SeedHashCompute};
use ethcore::account_provider::AccountProvider;
use ethcore::client::{BlockChainClient, BlockId, TransactionId, UncleId, StateOrBlock, StateClient, StateInfo, Call, EngineInfo};
use ethcore::client::{BlockChainClient, BlockId, TransactionId, UncleId, StateOrBlock, StateClient, StateInfo, Call, EngineInfo, ProvingBlockChainClient};
use ethcore::filter::Filter as EthcoreFilter;
use ethcore::header::{BlockNumber as EthBlockNumber};
use ethcore::miner::{self, MinerService};
Expand All @@ -35,6 +35,7 @@ use ethcore::encoded;
use sync::SyncProvider;
use miner::external::ExternalMinerService;
use transaction::{SignedTransaction, LocalizedTransaction};
use hash::keccak;

use jsonrpc_core::{BoxFuture, Result};
use jsonrpc_core::futures::future;
Expand All @@ -46,7 +47,7 @@ use v1::helpers::block_import::is_major_importing;
use v1::traits::Eth;
use v1::types::{
RichBlock, Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo,
Transaction, CallRequest, Index, Filter, Log, Receipt, Work,
Transaction, CallRequest, Index, Filter, Log, Receipt, Work, EthAccount, StorageProof,
H64 as RpcH64, H256 as RpcH256, H160 as RpcH160, U256 as RpcU256, block_number_to_id,
U64 as RpcU64,
};
Expand All @@ -64,6 +65,8 @@ pub struct EthClientOptions {
pub send_block_number_in_get_work: bool,
/// Gas Price Percentile used as default gas price.
pub gas_price_percentile: usize,
/// Enable Experimental RPC-Calls
pub allow_experimental_rpcs: bool,
}

impl EthClientOptions {
Expand All @@ -83,6 +86,7 @@ impl Default for EthClientOptions {
allow_pending_receipt_query: true,
send_block_number_in_get_work: true,
gas_price_percentile: 50,
allow_experimental_rpcs: false,
}
}
}
Expand Down Expand Up @@ -450,7 +454,7 @@ fn check_known<C>(client: &C, number: BlockNumber) -> Result<()> where C: BlockC
const MAX_QUEUE_SIZE_TO_MINE_ON: usize = 4; // because uncles go back 6.

impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<C, SN, S, M, EM> where
C: miner::BlockChainClient + BlockChainClient + StateClient<State=T> + Call<State=T> + EngineInfo + 'static,
C: miner::BlockChainClient + StateClient<State=T> + ProvingBlockChainClient + Call<State=T> + EngineInfo + 'static,
SN: SnapshotService + 'static,
S: SyncProvider + 'static,
M: MinerService<State=T> + 'static,
Expand Down Expand Up @@ -547,6 +551,52 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
Box::new(future::done(res))
}

fn proof(&self, address: RpcH160, values: Vec<RpcH256>, num: Trailing<BlockNumber>) -> BoxFuture<EthAccount> {
try_bf!(errors::require_experimental(self.options.allow_experimental_rpcs, "1186"));

let a: H160 = address.clone().into();
let key1 = keccak(a);

let num = num.unwrap_or_default();
let id = match num {
BlockNumber::Num(n) => BlockId::Number(n),
BlockNumber::Earliest => BlockId::Earliest,
BlockNumber::Latest => BlockId::Latest,
BlockNumber::Pending => {
warn!("`Pending` is deprecated and may be removed in future versions. Falling back to `Latest`");
BlockId::Latest
}
};

try_bf!(check_known(&*self.client, num.clone()));
let res = match self.client.prove_account(key1, id) {
Some((proof,account)) => Ok(EthAccount {
address: address,
balance: account.balance.into(),
nonce: account.nonce.into(),
code_hash: account.code_hash.into(),
storage_hash: account.storage_root.into(),
account_proof: proof.into_iter().map(Bytes::new).collect(),
storage_proof: values.into_iter().filter_map(|storage_index| {
let key2: H256 = storage_index.into();
match self.client.prove_storage(key1, keccak(key2), id) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

could be a .map instead of match

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, changed it.

Some((storage_proof,storage_value)) => Some(StorageProof {
key: key2.into(),
value: storage_value.into(),
proof: storage_proof.into_iter().map(Bytes::new).collect()
}),
None => None
}
})
.collect::<Vec<StorageProof>>()
}),
None => Err(errors::state_pruned()),
};

Box::new(future::done(res))
}


fn storage_at(&self, address: RpcH160, pos: RpcU256, num: Trailing<BlockNumber>) -> BoxFuture<RpcH256> {
let address: Address = RpcH160::into(address);
let position: U256 = RpcU256::into(pos);
Expand Down
6 changes: 5 additions & 1 deletion rpc/src/v1/impls/light/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use v1::helpers::light_fetch::{self, LightFetch};
use v1::traits::Eth;
use v1::types::{
RichBlock, Block, BlockTransactions, BlockNumber, LightBlockNumber, Bytes, SyncStatus, SyncInfo,
Transaction, CallRequest, Index, Filter, Log, Receipt, Work,
Transaction, CallRequest, Index, Filter, Log, Receipt, Work, EthAccount,
H64 as RpcH64, H256 as RpcH256, H160 as RpcH160, U256 as RpcU256,
U64 as RpcU64,
};
Expand Down Expand Up @@ -475,6 +475,10 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
}))
}

fn proof(&self, _address: RpcH160, _values:Vec<RpcH256>, _num: Trailing<BlockNumber>) -> BoxFuture<EthAccount> {
Box::new(future::err(errors::unimplemented(None)))
simon-jentzsch marked this conversation as resolved.
Show resolved Hide resolved
}

fn compilers(&self) -> Result<Vec<String>> {
Err(errors::deprecated("Compilation functionality is deprecated.".to_string()))
}
Expand Down
37 changes: 35 additions & 2 deletions rpc/src/v1/tests/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use parity_runtime::Runtime;
use jsonrpc_core::IoHandler;
use v1::helpers::dispatch::FullDispatcher;
use v1::helpers::nonce;
use v1::impls::{EthClient, SigningUnsafeClient};
use v1::impls::{EthClient, EthClientOptions, SigningUnsafeClient};
use v1::metadata::Metadata;
use v1::tests::helpers::{TestSnapshotService, TestSyncProvider, Config};
use v1::traits::eth::Eth;
Expand Down Expand Up @@ -140,7 +140,13 @@ impl EthTester {
&opt_account_provider,
&miner_service,
&external_miner,
Default::default(),
EthClientOptions {
pending_nonce_from_queue: false,
allow_pending_receipt_query: true,
send_block_number_in_get_work: true,
gas_price_percentile: 50,
allow_experimental_rpcs: true,
},
);

let reservations = Arc::new(Mutex::new(nonce::Reservations::new(runtime.executor())));
Expand Down Expand Up @@ -198,6 +204,33 @@ fn eth_get_balance() {
assert_eq!(tester.handler.handle_request_sync(req_new_acc).unwrap(), res_new_acc);
}

#[test]
fn eth_get_proof() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would be good to have a test already when experimental_rpcs are disabled.

let chain = extract_chain!("BlockchainTests/bcWalletTest/wallet2outOf3txs");
let tester = EthTester::from_chain(&chain);
// final account state
let req_latest = r#"{
"jsonrpc": "2.0",
"method": "eth_getProof",
"params": ["0xaaaf5374fce5edbc8e2a8697c15331677e6ebaaa", [], "latest"],
"id": 1
}"#;

let res_latest = r#","address":"0xaaaf5374fce5edbc8e2a8697c15331677e6ebaaa","balance":"0x9","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","nonce":"0x0","storageHash":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","storageProof":[]},"id":1}"#.to_owned();
assert!(tester.handler.handle_request_sync(req_latest).unwrap().to_string().ends_with(res_latest.as_str()));

// non-existant account
let req_new_acc = r#"{
"jsonrpc": "2.0",
"method": "eth_getProof",
"params": ["0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",[],"latest"],
"id": 3
}"#;

let res_new_acc = r#","address":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","balance":"0x0","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","nonce":"0x0","storageHash":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","storageProof":[]},"id":3}"#.to_owned();
assert!(tester.handler.handle_request_sync(req_new_acc).unwrap().to_string().ends_with(res_new_acc.as_str()));
}

#[test]
fn eth_block_number() {
let chain = extract_chain!("BlockchainTests/bcGasPricerTest/RPC_API_Test");
Expand Down
6 changes: 5 additions & 1 deletion rpc/src/v1/traits/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
use jsonrpc_core::{Result, BoxFuture};
use jsonrpc_macros::Trailing;

use v1::types::{RichBlock, BlockNumber, Bytes, CallRequest, Filter, FilterChanges, Index};
use v1::types::{RichBlock, BlockNumber, Bytes, CallRequest, Filter, FilterChanges, Index, EthAccount};
use v1::types::{Log, Receipt, SyncStatus, Transaction, Work};
use v1::types::{H64, H160, H256, U256, U64};

Expand Down Expand Up @@ -69,6 +69,10 @@ build_rpc_trait! {
#[rpc(name = "eth_getBalance")]
fn balance(&self, H160, Trailing<BlockNumber>) -> BoxFuture<U256>;

/// Returns the account- and storage-values of the specified account including the Merkle-proof
#[rpc(name = "eth_getProof")]
fn proof(&self, H160, Vec<H256>, Trailing<BlockNumber>) -> BoxFuture<EthAccount>;

/// Returns content of the storage at given address.
#[rpc(name = "eth_getStorageAt")]
fn storage_at(&self, H160, U256, Trailing<BlockNumber>) -> BoxFuture<H256>;
Expand Down
23 changes: 23 additions & 0 deletions rpc/src/v1/types/account_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use v1::types::{H160, H256, U256, Bytes};

/// Account information.
#[derive(Debug, Default, Clone, PartialEq, Serialize)]
Expand All @@ -21,6 +22,28 @@ pub struct AccountInfo {
pub name: String,
}

/// Datastructure with proof for one single storage-entry
simon-jentzsch marked this conversation as resolved.
Show resolved Hide resolved
#[derive(Debug, Default, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StorageProof {
pub key: U256,
pub value: U256,
pub proof: Vec<Bytes>
}

/// Account information.
#[derive(Debug, Default, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EthAccount {
pub address: H160,
pub balance: U256,
pub nonce: U256,
pub code_hash: H256,
pub storage_hash: H256,
pub account_proof: Vec<Bytes>,
pub storage_proof: Vec<StorageProof>,
}
simon-jentzsch marked this conversation as resolved.
Show resolved Hide resolved

/// Extended account information (used by `parity_allAccountInfo`).
#[derive(Debug, Default, Clone, PartialEq, Serialize)]
pub struct ExtAccountInfo {
Expand Down
3 changes: 2 additions & 1 deletion rpc/src/v1/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ mod private_receipt;
mod eip191;

pub mod pubsub;

pub use self::eip191::{EIP191Version, PresignedTransaction};
pub use self::account_info::{AccountInfo, ExtAccountInfo, HwAccountInfo};
pub use self::account_info::{AccountInfo, ExtAccountInfo, HwAccountInfo, EthAccount, StorageProof};
pub use self::bytes::Bytes;
pub use self::block::{RichBlock, Block, BlockTransactions, Header, RichHeader, Rich};
pub use self::block_number::{BlockNumber, LightBlockNumber, block_number_to_id};
Expand Down