From 64ebcd0f24bda255647daa31bcda07e6fa4dd3e2 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Thu, 8 Dec 2016 16:12:00 +0100 Subject: [PATCH] fix contract code response encoding; add test --- ethcore/light/src/net/mod.rs | 2 +- ethcore/light/src/net/tests/mod.rs | 531 ++++++++++++++++------------- 2 files changed, 294 insertions(+), 239 deletions(-) diff --git a/ethcore/light/src/net/mod.rs b/ethcore/light/src/net/mod.rs index 57d091f75..57dc77a86 100644 --- a/ethcore/light/src/net/mod.rs +++ b/ethcore/light/src/net/mod.rs @@ -863,7 +863,7 @@ impl LightProtocol { stream.append(&req_id).append(&cur_buffer); for code in response { - stream.append_raw(&code, 1); + stream.append(&code); } stream.out() diff --git a/ethcore/light/src/net/tests/mod.rs b/ethcore/light/src/net/tests/mod.rs index 555f6d19c..e659d0681 100644 --- a/ethcore/light/src/net/tests/mod.rs +++ b/ethcore/light/src/net/tests/mod.rs @@ -31,62 +31,62 @@ use provider::Provider; use request::{self, Request, Headers}; use rlp::*; -use util::{Bytes, H256}; +use util::{Bytes, H256, U256}; use std::sync::Arc; // expected result from a call. #[derive(Debug, PartialEq, Eq)] enum Expect { - /// Expect to have message sent to peer. - Send(PeerId, u8, Vec), - /// Expect this response. - Respond(u8, Vec), - /// Expect a punishment (disconnect/disable) - Punish(PeerId), - /// Expect nothing. - Nothing, + /// Expect to have message sent to peer. + Send(PeerId, u8, Vec), + /// Expect this response. + Respond(u8, Vec), + /// Expect a punishment (disconnect/disable) + Punish(PeerId), + /// Expect nothing. + Nothing, } impl IoContext for Expect { - fn send(&self, peer: PeerId, packet_id: u8, packet_body: Vec) { - assert_eq!(self, &Expect::Send(peer, packet_id, packet_body)); - } + fn send(&self, peer: PeerId, packet_id: u8, packet_body: Vec) { + assert_eq!(self, &Expect::Send(peer, packet_id, packet_body)); + } - fn respond(&self, packet_id: u8, packet_body: Vec) { - assert_eq!(self, &Expect::Respond(packet_id, packet_body)); - } + fn respond(&self, packet_id: u8, packet_body: Vec) { + assert_eq!(self, &Expect::Respond(packet_id, packet_body)); + } - fn disconnect_peer(&self, peer: PeerId) { - assert_eq!(self, &Expect::Punish(peer)); - } + fn disconnect_peer(&self, peer: PeerId) { + assert_eq!(self, &Expect::Punish(peer)); + } - fn disable_peer(&self, peer: PeerId) { - assert_eq!(self, &Expect::Punish(peer)); - } + fn disable_peer(&self, peer: PeerId) { + assert_eq!(self, &Expect::Punish(peer)); + } } // can't implement directly for Arc due to cross-crate orphan rules. struct TestProvider(Arc); struct TestProviderInner { - client: TestBlockChainClient, + client: TestBlockChainClient, } impl Provider for TestProvider { - fn chain_info(&self) -> BlockChainInfo { - self.0.client.chain_info() - } + fn chain_info(&self) -> BlockChainInfo { + self.0.client.chain_info() + } - fn reorg_depth(&self, a: &H256, b: &H256) -> Option { - self.0.client.tree_route(a, b).map(|route| route.index as u64) - } + fn reorg_depth(&self, a: &H256, b: &H256) -> Option { + self.0.client.tree_route(a, b).map(|route| route.index as u64) + } - fn earliest_state(&self) -> Option { - None - } + fn earliest_state(&self) -> Option { + None + } - fn block_headers(&self, req: request::Headers) -> Vec { + fn block_headers(&self, req: request::Headers) -> Vec { let best_num = self.0.client.chain_info().best_block_number; let start_num = req.block_num; @@ -124,22 +124,26 @@ impl Provider for TestProvider { fn proofs(&self, req: request::StateProofs) -> Vec { req.requests.into_iter() - .map(|req| { - match req.key2 { - Some(key2) => ::util::sha3::SHA3_NULL_RLP.to_owned(), - None => { - // sort of a leaf node - let mut stream = RlpStream::new_list(2); - stream.append(&req.key1).append_empty_data(); - stream.out() - } - } - }) - .collect() + .map(|req| { + match req.key2 { + Some(_) => ::util::sha3::SHA3_NULL_RLP.to_vec(), + None => { + // sort of a leaf node + let mut stream = RlpStream::new_list(2); + stream.append(&req.key1).append_empty_data(); + stream.out() + } + } + }) + .collect() } fn contract_code(&self, req: request::ContractCodes) -> Vec { - req.code_requests.into_iter().map(|_| Vec::new()).collect() + req.code_requests.into_iter() + .map(|req| { + req.account_key.iter().chain(req.account_key.iter()).cloned().collect() + }) + .collect() } fn header_proofs(&self, req: request::HeaderProofs) -> Vec { @@ -152,104 +156,104 @@ impl Provider for TestProvider { } fn make_flow_params() -> FlowParams { - FlowParams::new(5_000_000.into(), Default::default(), 100_000.into()) + FlowParams::new(5_000_000.into(), Default::default(), 100_000.into()) } fn capabilities() -> Capabilities { - Capabilities { - serve_headers: true, - serve_chain_since: Some(1), - serve_state_since: Some(1), - tx_relay: true, - } + Capabilities { + serve_headers: true, + serve_chain_since: Some(1), + serve_state_since: Some(1), + tx_relay: true, + } } // helper for setting up the protocol handler and provider. fn setup(flow_params: FlowParams, capabilities: Capabilities) -> (Arc, LightProtocol) { - let provider = Arc::new(TestProviderInner { - client: TestBlockChainClient::new(), - }); + let provider = Arc::new(TestProviderInner { + client: TestBlockChainClient::new(), + }); - let proto = LightProtocol::new(Box::new(TestProvider(provider.clone())), Params { - network_id: NetworkId::Testnet, - flow_params: flow_params, - capabilities: capabilities, - }); + let proto = LightProtocol::new(Box::new(TestProvider(provider.clone())), Params { + network_id: NetworkId::Testnet, + flow_params: flow_params, + capabilities: capabilities, + }); - (provider, proto) + (provider, proto) } fn status(chain_info: BlockChainInfo) -> Status { - Status { - protocol_version: ::net::PROTOCOL_VERSION, - network_id: NetworkId::Testnet, - head_td: chain_info.total_difficulty, - head_hash: chain_info.best_block_hash, - head_num: chain_info.best_block_number, - genesis_hash: chain_info.genesis_hash, - last_head: None, - } + Status { + protocol_version: ::net::PROTOCOL_VERSION, + network_id: NetworkId::Testnet, + head_td: chain_info.total_difficulty, + head_hash: chain_info.best_block_hash, + head_num: chain_info.best_block_number, + genesis_hash: chain_info.genesis_hash, + last_head: None, + } } #[test] fn handshake_expected() { - let flow_params = make_flow_params(); - let capabilities = capabilities(); + let flow_params = make_flow_params(); + let capabilities = capabilities(); - let (provider, proto) = setup(flow_params.clone(), capabilities.clone()); + let (provider, proto) = setup(flow_params.clone(), capabilities.clone()); - let status = status(provider.client.chain_info()); + let status = status(provider.client.chain_info()); - let packet_body = write_handshake(&status, &capabilities, &flow_params); + let packet_body = write_handshake(&status, &capabilities, &flow_params); - proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body)); + proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body)); } #[test] #[should_panic] fn genesis_mismatch() { - let flow_params = make_flow_params(); - let capabilities = capabilities(); + let flow_params = make_flow_params(); + let capabilities = capabilities(); - let (provider, proto) = setup(flow_params.clone(), capabilities.clone()); + let (provider, proto) = setup(flow_params.clone(), capabilities.clone()); - let mut status = status(provider.client.chain_info()); - status.genesis_hash = H256::default(); + let mut status = status(provider.client.chain_info()); + status.genesis_hash = H256::default(); - let packet_body = write_handshake(&status, &capabilities, &flow_params); + let packet_body = write_handshake(&status, &capabilities, &flow_params); - proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body)); + proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body)); } #[test] fn buffer_overflow() { - let flow_params = make_flow_params(); - let capabilities = capabilities(); + let flow_params = make_flow_params(); + let capabilities = capabilities(); - let (provider, proto) = setup(flow_params.clone(), capabilities.clone()); + let (provider, proto) = setup(flow_params.clone(), capabilities.clone()); - let status = status(provider.client.chain_info()); + let status = status(provider.client.chain_info()); - { - let packet_body = write_handshake(&status, &capabilities, &flow_params); - proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body)); - } + { + let packet_body = write_handshake(&status, &capabilities, &flow_params); + proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body)); + } - { - let my_status = write_handshake(&status, &capabilities, &flow_params); - proto.handle_packet(&Expect::Nothing, &1, packet::STATUS, &my_status); - } + { + let my_status = write_handshake(&status, &capabilities, &flow_params); + proto.handle_packet(&Expect::Nothing, &1, packet::STATUS, &my_status); + } - // 1000 requests is far too many for the default flow params. - let request = encode_request(&Request::Headers(Headers { - block_num: 1, - block_hash: provider.client.chain_info().genesis_hash, - max: 1000, - skip: 0, - reverse: false, - }), 111); + // 1000 requests is far too many for the default flow params. + let request = encode_request(&Request::Headers(Headers { + block_num: 1, + block_hash: provider.client.chain_info().genesis_hash, + max: 1000, + skip: 0, + reverse: false, + }), 111); - proto.handle_packet(&Expect::Punish(1), &1, packet::GET_BLOCK_HEADERS, &request); + proto.handle_packet(&Expect::Punish(1), &1, packet::GET_BLOCK_HEADERS, &request); } // test the basic request types -- these just make sure that requests are parsed @@ -257,197 +261,248 @@ fn buffer_overflow() { #[test] fn get_block_headers() { - let flow_params = FlowParams::new(5_000_000.into(), Default::default(), 0.into()); - let capabilities = capabilities(); + let flow_params = FlowParams::new(5_000_000.into(), Default::default(), 0.into()); + let capabilities = capabilities(); - let (provider, proto) = setup(flow_params.clone(), capabilities.clone()); + let (provider, proto) = setup(flow_params.clone(), capabilities.clone()); - let cur_status = status(provider.client.chain_info()); - let my_status = write_handshake(&cur_status, &capabilities, &flow_params); + let cur_status = status(provider.client.chain_info()); + let my_status = write_handshake(&cur_status, &capabilities, &flow_params); - provider.client.add_blocks(100, EachBlockWith::Nothing); + provider.client.add_blocks(100, EachBlockWith::Nothing); - let cur_status = status(provider.client.chain_info()); + let cur_status = status(provider.client.chain_info()); - { - let packet_body = write_handshake(&cur_status, &capabilities, &flow_params); - proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body)); - proto.handle_packet(&Expect::Nothing, &1, packet::STATUS, &my_status); - } + { + let packet_body = write_handshake(&cur_status, &capabilities, &flow_params); + proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body)); + proto.handle_packet(&Expect::Nothing, &1, packet::STATUS, &my_status); + } - let request = Headers { - block_num: 1, - block_hash: provider.client.block_hash(BlockID::Number(1)).unwrap(), - max: 10, - skip: 0, - reverse: false, - }; - let req_id = 111; + let request = Headers { + block_num: 1, + block_hash: provider.client.block_hash(BlockID::Number(1)).unwrap(), + max: 10, + skip: 0, + reverse: false, + }; + let req_id = 111; - let request_body = encode_request(&Request::Headers(request.clone()), req_id); - let response = { - let headers: Vec<_> = (0..10).map(|i| provider.client.block_header(BlockID::Number(i + 1)).unwrap()).collect(); - assert_eq!(headers.len(), 10); + let request_body = encode_request(&Request::Headers(request.clone()), req_id); + let response = { + let headers: Vec<_> = (0..10).map(|i| provider.client.block_header(BlockID::Number(i + 1)).unwrap()).collect(); + assert_eq!(headers.len(), 10); - let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Headers, 10); + let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Headers, 10); - let mut response_stream = RlpStream::new_list(12); - - response_stream.append(&req_id).append(&new_buf); - for header in headers { - response_stream.append_raw(&header, 1); - } + let mut response_stream = RlpStream::new_list(12); + + response_stream.append(&req_id).append(&new_buf); + for header in headers { + response_stream.append_raw(&header, 1); + } - response_stream.out() - }; + response_stream.out() + }; - let expected = Expect::Respond(packet::BLOCK_HEADERS, response); - proto.handle_packet(&expected, &1, packet::GET_BLOCK_HEADERS, &request_body); + let expected = Expect::Respond(packet::BLOCK_HEADERS, response); + proto.handle_packet(&expected, &1, packet::GET_BLOCK_HEADERS, &request_body); } #[test] fn get_block_bodies() { - let flow_params = FlowParams::new(5_000_000.into(), Default::default(), 0.into()); - let capabilities = capabilities(); + let flow_params = FlowParams::new(5_000_000.into(), Default::default(), 0.into()); + let capabilities = capabilities(); - let (provider, proto) = setup(flow_params.clone(), capabilities.clone()); + let (provider, proto) = setup(flow_params.clone(), capabilities.clone()); - let cur_status = status(provider.client.chain_info()); - let my_status = write_handshake(&cur_status, &capabilities, &flow_params); + let cur_status = status(provider.client.chain_info()); + let my_status = write_handshake(&cur_status, &capabilities, &flow_params); - provider.client.add_blocks(100, EachBlockWith::Nothing); + provider.client.add_blocks(100, EachBlockWith::Nothing); - let cur_status = status(provider.client.chain_info()); + let cur_status = status(provider.client.chain_info()); - { - let packet_body = write_handshake(&cur_status, &capabilities, &flow_params); - proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body)); - proto.handle_packet(&Expect::Nothing, &1, packet::STATUS, &my_status); - } + { + let packet_body = write_handshake(&cur_status, &capabilities, &flow_params); + proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body)); + proto.handle_packet(&Expect::Nothing, &1, packet::STATUS, &my_status); + } - let request = request::Bodies { - block_hashes: (0..10).map(|i| provider.client.block_hash(BlockID::Number(i)).unwrap()).collect(), - }; + let request = request::Bodies { + block_hashes: (0..10).map(|i| provider.client.block_hash(BlockID::Number(i)).unwrap()).collect(), + }; - let req_id = 111; + let req_id = 111; - let request_body = encode_request(&Request::Bodies(request.clone()), req_id); - let response = { - let bodies: Vec<_> = (0..10).map(|i| provider.client.block_body(BlockID::Number(i + 1)).unwrap()).collect(); - assert_eq!(bodies.len(), 10); + let request_body = encode_request(&Request::Bodies(request.clone()), req_id); + let response = { + let bodies: Vec<_> = (0..10).map(|i| provider.client.block_body(BlockID::Number(i + 1)).unwrap()).collect(); + assert_eq!(bodies.len(), 10); - let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Bodies, 10); + let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Bodies, 10); - let mut response_stream = RlpStream::new_list(12); - - response_stream.append(&req_id).append(&new_buf); - for body in bodies { - response_stream.append_raw(&body, 1); - } + let mut response_stream = RlpStream::new_list(12); + + response_stream.append(&req_id).append(&new_buf); + for body in bodies { + response_stream.append_raw(&body, 1); + } - response_stream.out() - }; + response_stream.out() + }; - let expected = Expect::Respond(packet::BLOCK_BODIES, response); - proto.handle_packet(&expected, &1, packet::GET_BLOCK_BODIES, &request_body); + let expected = Expect::Respond(packet::BLOCK_BODIES, response); + proto.handle_packet(&expected, &1, packet::GET_BLOCK_BODIES, &request_body); } #[test] fn get_block_receipts() { - let flow_params = FlowParams::new(5_000_000.into(), Default::default(), 0.into()); - let capabilities = capabilities(); + let flow_params = FlowParams::new(5_000_000.into(), Default::default(), 0.into()); + let capabilities = capabilities(); - let (provider, proto) = setup(flow_params.clone(), capabilities.clone()); + let (provider, proto) = setup(flow_params.clone(), capabilities.clone()); - let cur_status = status(provider.client.chain_info()); - let my_status = write_handshake(&cur_status, &capabilities, &flow_params); + let cur_status = status(provider.client.chain_info()); + let my_status = write_handshake(&cur_status, &capabilities, &flow_params); - provider.client.add_blocks(1000, EachBlockWith::Nothing); + provider.client.add_blocks(1000, EachBlockWith::Nothing); - let cur_status = status(provider.client.chain_info()); + let cur_status = status(provider.client.chain_info()); - { - let packet_body = write_handshake(&cur_status, &capabilities, &flow_params); - proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body)); - proto.handle_packet(&Expect::Nothing, &1, packet::STATUS, &my_status); - } + { + let packet_body = write_handshake(&cur_status, &capabilities, &flow_params); + proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body)); + proto.handle_packet(&Expect::Nothing, &1, packet::STATUS, &my_status); + } - // find the first 10 block hashes starting with `f` because receipts are only provided - // by the test client in that case. - let block_hashes: Vec<_> = (0..1000).map(|i| provider.client.block_hash(BlockID::Number(i)).unwrap()) - .filter(|hash| format!("{}", hash).starts_with("f")).take(10).collect(); + // find the first 10 block hashes starting with `f` because receipts are only provided + // by the test client in that case. + let block_hashes: Vec<_> = (0..1000).map(|i| provider.client.block_hash(BlockID::Number(i)).unwrap()) + .filter(|hash| format!("{}", hash).starts_with("f")).take(10).collect(); - let request = request::Receipts { - block_hashes: block_hashes.clone(), - }; + let request = request::Receipts { + block_hashes: block_hashes.clone(), + }; - let req_id = 111; + let req_id = 111; - let request_body = encode_request(&Request::Receipts(request.clone()), req_id); - let response = { - let receipts: Vec<_> = block_hashes.iter() - .map(|hash| provider.client.block_receipts(hash).unwrap()) - .collect(); + let request_body = encode_request(&Request::Receipts(request.clone()), req_id); + let response = { + let receipts: Vec<_> = block_hashes.iter() + .map(|hash| provider.client.block_receipts(hash).unwrap()) + .collect(); - let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Receipts, receipts.len()); + let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Receipts, receipts.len()); - let mut response_stream = RlpStream::new_list(2 + receipts.len()); - - response_stream.append(&req_id).append(&new_buf); - for block_receipts in receipts { - response_stream.append_raw(&block_receipts, 1); - } + let mut response_stream = RlpStream::new_list(2 + receipts.len()); + + response_stream.append(&req_id).append(&new_buf); + for block_receipts in receipts { + response_stream.append_raw(&block_receipts, 1); + } - response_stream.out() - }; + response_stream.out() + }; - let expected = Expect::Respond(packet::RECEIPTS, response); - proto.handle_packet(&expected, &1, packet::GET_RECEIPTS, &request_body); + let expected = Expect::Respond(packet::RECEIPTS, response); + proto.handle_packet(&expected, &1, packet::GET_RECEIPTS, &request_body); } #[test] -fn get_block_bodies() { - let flow_params = FlowParams::new(5_000_000.into(), Default::default(), 0.into()); - let capabilities = capabilities(); +fn get_state_proofs() { + let flow_params = FlowParams::new(5_000_000.into(), Default::default(), 0.into()); + let capabilities = capabilities(); - let (provider, proto) = setup(flow_params.clone(), capabilities.clone()); + let (provider, proto) = setup(flow_params.clone(), capabilities.clone()); - let cur_status = status(provider.client.chain_info()); - let my_status = write_handshake(&cur_status, &capabilities, &flow_params); + let cur_status = status(provider.client.chain_info()); - provider.client.add_blocks(100, EachBlockWith::Nothing); + { + let packet_body = write_handshake(&cur_status, &capabilities, &flow_params); + proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body.clone())); + proto.handle_packet(&Expect::Nothing, &1, packet::STATUS, &packet_body); + } - let cur_status = status(provider.client.chain_info()); + let req_id = 112; + let key1 = U256::from(11223344).into(); + let key2 = U256::from(99988887).into(); - { - let packet_body = write_handshake(&cur_status, &capabilities, &flow_params); - proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body)); - proto.handle_packet(&Expect::Nothing, &1, packet::STATUS, &my_status); - } + let request = Request::StateProofs (request::StateProofs { + requests: vec![ + request::StateProof { block: H256::default(), key1: key1, key2: None, from_level: 0 }, + request::StateProof { block: H256::default(), key1: key1, key2: Some(key2), from_level: 0}, + ] + }); - let request = request::Bodies { - block_hashes: (0..10).map(|i| provider.client.block_hash(BlockID::Number(i)).unwrap()).collect(), - }; + let request_body = encode_request(&request, req_id); + let response = { + let proofs = vec![ + { let mut stream = RlpStream::new_list(2); stream.append(&key1).append_empty_data(); stream.out() }, + ::util::sha3::SHA3_NULL_RLP.to_vec(), + ]; - let req_id = 111; + let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::StateProofs, 2); - let request_body = encode_request(&Request::Bodies(request.clone()), req_id); - let response = { - let bodies: Vec<_> = (0..10).map(|i| provider.client.block_body(BlockID::Number(i + 1)).unwrap()).collect(); - assert_eq!(bodies.len(), 10); + let mut response_stream = RlpStream::new_list(4); + + response_stream.append(&req_id).append(&new_buf); + for proof in proofs { + response_stream.append_raw(&proof, 1); + } - let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Bodies, 10); + response_stream.out() + }; - let mut response_stream = RlpStream::new_list(12); - - response_stream.append(&req_id).append(&new_buf); - for body in bodies { - response_stream.append_raw(&body, 1); - } + let expected = Expect::Respond(packet::PROOFS, response); + proto.handle_packet(&expected, &1, packet::GET_PROOFS, &request_body); +} - response_stream.out() - }; +#[test] +fn get_contract_code() { + let flow_params = FlowParams::new(5_000_000.into(), Default::default(), 0.into()); + let capabilities = capabilities(); - let expected = Expect::Respond(packet::BLOCK_BODIES, response); - proto.handle_packet(&expected, &1, packet::GET_BLOCK_BODIES, &request_body); + let (provider, proto) = setup(flow_params.clone(), capabilities.clone()); + + let cur_status = status(provider.client.chain_info()); + + { + let packet_body = write_handshake(&cur_status, &capabilities, &flow_params); + proto.on_connect(&1, &Expect::Send(1, packet::STATUS, packet_body.clone())); + proto.handle_packet(&Expect::Nothing, &1, packet::STATUS, &packet_body); + } + + let req_id = 112; + let key1 = U256::from(11223344).into(); + let key2 = U256::from(99988887).into(); + + let request = Request::Codes (request::ContractCodes { + code_requests: vec![ + request::ContractCode { block_hash: H256::default(), account_key: key1 }, + request::ContractCode { block_hash: H256::default(), account_key: key2 }, + ], + }); + + let request_body = encode_request(&request, req_id); + let response = { + let codes: Vec> = vec![ + key1.iter().chain(key1.iter()).cloned().collect(), + key2.iter().chain(key2.iter()).cloned().collect(), + ]; + + let new_buf = *flow_params.limit() - flow_params.compute_cost(request::Kind::Codes, 2); + + let mut response_stream = RlpStream::new_list(4); + + response_stream.append(&req_id).append(&new_buf); + for code in codes { + response_stream.append(&code); + } + + response_stream.out() + }; + + let expected = Expect::Respond(packet::CONTRACT_CODES, response); + proto.handle_packet(&expected, &1, packet::GET_CONTRACT_CODES, &request_body); } \ No newline at end of file