From da696e4a1f7282e3c5a6e228e3121f3c41e5ba06 Mon Sep 17 00:00:00 2001 From: maciejhirsz Date: Thu, 16 Feb 2017 18:39:13 +0100 Subject: [PATCH] Added support for contract code by hash. This is done by requests sending CID with raw binary codec (0x55). Note: this functionality is exactly the same as fetching state-trie due to how db internals work in Parity atm. --- ipfs/src/error.rs | 2 ++ ipfs/src/handler.rs | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/ipfs/src/error.rs b/ipfs/src/error.rs index 774763786..f379f254b 100644 --- a/ipfs/src/error.rs +++ b/ipfs/src/error.rs @@ -36,6 +36,7 @@ pub enum Error { BlockNotFound, TransactionNotFound, StateRootNotFound, + ContractNotFound, } /// Convert Error into Out, handy when switching from Rust's Result-based @@ -51,6 +52,7 @@ impl From for Out { BlockNotFound => Out::NotFound("Block not found"), TransactionNotFound => Out::NotFound("Transaction not found"), StateRootNotFound => Out::NotFound("State root not found"), + ContractNotFound => Out::NotFound("Contract not found"), } } } diff --git a/ipfs/src/handler.rs b/ipfs/src/handler.rs index 5197e8a1a..543792fa5 100644 --- a/ipfs/src/handler.rs +++ b/ipfs/src/handler.rs @@ -86,6 +86,7 @@ impl IpfsHandler { Codec::EthereumBlockList => self.block_list(hash), Codec::EthereumTx => self.transaction(hash), Codec::EthereumStateTrie => self.state_trie(hash), + Codec::Raw => self.contract_code(hash), _ => return Err(Error::UnsupportedCid), } } @@ -119,6 +120,13 @@ impl IpfsHandler { Ok(Out::OctetStream(data)) } + + /// Get state trie node by hash and return as raw binary. + fn contract_code(&self, hash: H256) -> Result { + let data = self.client.state_data(&hash).ok_or(Error::ContractNotFound)?; + + Ok(Out::OctetStream(data)) + } } /// Get a query parameter's value by name. @@ -192,6 +200,16 @@ mod tests { assert_eq!(Err(Error::StateRootNotFound), handler.route_cid(&cid)); } + #[test] + fn cid_route_contract_code() { + let handler = get_mocked_handler(); + + // `raw` with Keccak-256 + let cid = "zb34WAp1Q5fhtLGZ3w3jhnTWaNbVV5ZZvGq4vuJQzERj6Pu3H"; + + assert_eq!(Err(Error::ContractNotFound), handler.route_cid(&cid)); + } + #[test] fn cid_route_invalid_hash() { let handler = get_mocked_handler();