eth_sign improvements backport (#4473)
* Fix postsign (#4347) * Fix whitespace. * Fix post sign. * Fix message. * Fix tests. * Rest of the problems. * All hail the linter and its omniscience. * ...and its divine omniscience. * Grumbles and wording. * Make signing compatible with geth. (#4468)
This commit is contained in:
		
							parent
							
								
									2bfcfd3813
								
							
						
					
					
						commit
						8c049e5d05
					
				| @ -313,6 +313,11 @@ export default class Parity { | |||||||
|       .execute('parity_postTransaction', inOptions(options)); |       .execute('parity_postTransaction', inOptions(options)); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   postSign (from, message) { | ||||||
|  |     return this._transport | ||||||
|  |       .execute('parity_postSign', from, message); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   registryAddress () { |   registryAddress () { | ||||||
|     return this._transport |     return this._transport | ||||||
|       .execute('parity_registryAddress') |       .execute('parity_registryAddress') | ||||||
|  | |||||||
| @ -61,7 +61,7 @@ export default class RequestPending extends Component { | |||||||
|           address={ sign.address } |           address={ sign.address } | ||||||
|           className={ className } |           className={ className } | ||||||
|           focus={ focus } |           focus={ focus } | ||||||
|           hash={ sign.hash } |           data={ sign.data } | ||||||
|           id={ id } |           id={ id } | ||||||
|           isFinished={ false } |           isFinished={ false } | ||||||
|           isSending={ isSending } |           isSending={ isSending } | ||||||
|  | |||||||
| @ -27,8 +27,20 @@ | |||||||
|   min-height: $pendingHeight; |   min-height: $pendingHeight; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .signData { | ||||||
|  |     border: 0.25em solid red; | ||||||
|  |     padding: 0.5em; | ||||||
|  |     margin-left: -2em; | ||||||
|  |     overflow: auto; | ||||||
|  |     max-height: 6em; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .signData > p { | ||||||
|  |     color: white; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .signDetails { | .signDetails { | ||||||
|   flex: 1; |   flex: 10; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .address, .info { | .address, .info { | ||||||
|  | |||||||
| @ -19,16 +19,30 @@ import { observer } from 'mobx-react'; | |||||||
| 
 | 
 | ||||||
| import Account from '../Account'; | import Account from '../Account'; | ||||||
| import TransactionPendingForm from '../TransactionPendingForm'; | import TransactionPendingForm from '../TransactionPendingForm'; | ||||||
| import TxHashLink from '../TxHashLink'; |  | ||||||
| 
 | 
 | ||||||
| import styles from './signRequest.css'; | import styles from './signRequest.css'; | ||||||
| 
 | 
 | ||||||
|  | function isAscii (data) { | ||||||
|  |   for (var i = 2; i < data.length; i += 2) { | ||||||
|  |     let n = parseInt(data.substr(i, 2), 16); | ||||||
|  | 
 | ||||||
|  |     if (n < 32 || n >= 128) { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| @observer | @observer | ||||||
| export default class SignRequest extends Component { | export default class SignRequest extends Component { | ||||||
|  |   static contextTypes = { | ||||||
|  |     api: PropTypes.object | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|   static propTypes = { |   static propTypes = { | ||||||
|     id: PropTypes.object.isRequired, |     id: PropTypes.object.isRequired, | ||||||
|     address: PropTypes.string.isRequired, |     address: PropTypes.string.isRequired, | ||||||
|     hash: PropTypes.string.isRequired, |     data: PropTypes.string.isRequired, | ||||||
|     isFinished: PropTypes.bool.isRequired, |     isFinished: PropTypes.bool.isRequired, | ||||||
|     isTest: PropTypes.bool.isRequired, |     isTest: PropTypes.bool.isRequired, | ||||||
|     store: PropTypes.object.isRequired, |     store: PropTypes.object.isRequired, | ||||||
| @ -62,8 +76,23 @@ export default class SignRequest extends Component { | |||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   renderAsciiDetails (ascii) { | ||||||
|  |     return ( | ||||||
|  |       <div className={ styles.signData }> | ||||||
|  |         <p>{ascii}</p> | ||||||
|  |       </div> | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   renderBinaryDetails (data) { | ||||||
|  |     return (<div className={ styles.signData }> | ||||||
|  |       <p>(Unknown binary data)</p> | ||||||
|  |     </div>); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   renderDetails () { |   renderDetails () { | ||||||
|     const { address, hash, isTest, store } = this.props; |     const { api } = this.context; | ||||||
|  |     const { address, isTest, store, data } = this.props; | ||||||
|     const balance = store.balances[address]; |     const balance = store.balances[address]; | ||||||
| 
 | 
 | ||||||
|     if (!balance) { |     if (!balance) { | ||||||
| @ -78,9 +107,14 @@ export default class SignRequest extends Component { | |||||||
|             balance={ balance } |             balance={ balance } | ||||||
|             isTest={ isTest } /> |             isTest={ isTest } /> | ||||||
|         </div> |         </div> | ||||||
|         <div className={ styles.info } title={ hash }> |         <div className={ styles.info } title={ api.util.sha3(data) }> | ||||||
|           <p>Dapp is requesting to sign arbitrary transaction using this account.</p> |           <p>A request to sign data using your account:</p> | ||||||
|           <p><strong>Confirm the transaction only if you trust the app.</strong></p> |           { | ||||||
|  |             isAscii(data) | ||||||
|  |               ? this.renderAsciiDetails(api.util.hexToAscii(data)) | ||||||
|  |               : this.renderBinaryDetails(data) | ||||||
|  |           } | ||||||
|  |           <p><strong>WARNING: This consequences of doing this may be grave. Confirm the request only if you are sure.</strong></p> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
| @ -91,18 +125,9 @@ export default class SignRequest extends Component { | |||||||
| 
 | 
 | ||||||
|     if (isFinished) { |     if (isFinished) { | ||||||
|       if (status === 'confirmed') { |       if (status === 'confirmed') { | ||||||
|         const { hash, isTest } = this.props; |  | ||||||
| 
 |  | ||||||
|         return ( |         return ( | ||||||
|           <div className={ styles.actions }> |           <div className={ styles.actions }> | ||||||
|             <span className={ styles.isConfirmed }>Confirmed</span> |             <span className={ styles.isConfirmed }>Confirmed</span> | ||||||
|             <div> |  | ||||||
|               Transaction hash: |  | ||||||
|               <TxHashLink |  | ||||||
|                 isTest={ isTest } |  | ||||||
|                 txHash={ hash } |  | ||||||
|                 className={ styles.txHash } /> |  | ||||||
|             </div> |  | ||||||
|           </div> |           </div> | ||||||
|         ); |         ); | ||||||
|       } |       } | ||||||
|  | |||||||
| @ -147,7 +147,7 @@ class TransactionPendingFormConfirm extends Component { | |||||||
|               label={ |               label={ | ||||||
|                 isSending |                 isSending | ||||||
|                   ? 'Confirming...' |                   ? 'Confirming...' | ||||||
|                   : 'Confirm Transaction' |                   : 'Confirm Request' | ||||||
|               } |               } | ||||||
|               onTouchTap={ this.onConfirm } |               onTouchTap={ this.onConfirm } | ||||||
|               primary /> |               primary /> | ||||||
| @ -251,7 +251,7 @@ function mapStateToProps (_, initProps) { | |||||||
| 
 | 
 | ||||||
|   return (state) => { |   return (state) => { | ||||||
|     const { accounts } = state.personal; |     const { accounts } = state.personal; | ||||||
|     let gotAddress = Object.keys(accounts).find(a => a.toLowerCase() === address.toLowerCase()); |     const gotAddress = Object.keys(accounts).find(a => a.toLowerCase() === address.toLowerCase()); | ||||||
|     const account = gotAddress ? accounts[gotAddress] : {}; |     const account = gotAddress ? accounts[gotAddress] : {}; | ||||||
| 
 | 
 | ||||||
|     return { account }; |     return { account }; | ||||||
|  | |||||||
| @ -33,14 +33,14 @@ export default class TransactionPendingFormReject extends Component { | |||||||
|     return ( |     return ( | ||||||
|       <div> |       <div> | ||||||
|         <div className={ styles.rejectText }> |         <div className={ styles.rejectText }> | ||||||
|           Are you sure you want to reject transaction? <br /> |           Are you sure you want to reject request? <br /> | ||||||
|           <strong>This cannot be undone</strong> |           <strong>This cannot be undone</strong> | ||||||
|         </div> |         </div> | ||||||
|         <RaisedButton |         <RaisedButton | ||||||
|           onTouchTap={ onReject } |           onTouchTap={ onReject } | ||||||
|           className={ styles.rejectButton } |           className={ styles.rejectButton } | ||||||
|           fullWidth |           fullWidth | ||||||
|           label={ 'Reject Transaction' } |           label={ 'Reject Request' } | ||||||
|         /> |         /> | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|  | |||||||
| @ -76,7 +76,7 @@ export default class TransactionPendingForm extends Component { | |||||||
|     let html; |     let html; | ||||||
| 
 | 
 | ||||||
|     if (!isRejectOpen) { |     if (!isRejectOpen) { | ||||||
|       html = <span>reject transaction</span>; |       html = <span>reject request</span>; | ||||||
|     } else { |     } else { | ||||||
|       html = <span><BackIcon />{ "I've changed my mind" }</span>; |       html = <span><BackIcon />{ "I've changed my mind" }</span>; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -19,6 +19,7 @@ use std::ops::Deref; | |||||||
| use rlp; | use rlp; | ||||||
| use util::{Address, H520, H256, U256, Uint, Bytes}; | use util::{Address, H520, H256, U256, Uint, Bytes}; | ||||||
| use util::bytes::ToPretty; | use util::bytes::ToPretty; | ||||||
|  | use util::sha3::Hashable; | ||||||
| 
 | 
 | ||||||
| use ethkey::Signature; | use ethkey::Signature; | ||||||
| use ethcore::miner::MinerService; | use ethcore::miner::MinerService; | ||||||
| @ -108,8 +109,12 @@ pub fn execute<C, M>(client: &C, miner: &M, accounts: &AccountProvider, payload: | |||||||
| 					.map(ConfirmationResponse::SignTransaction) | 					.map(ConfirmationResponse::SignTransaction) | ||||||
| 				) | 				) | ||||||
| 		}, | 		}, | ||||||
| 		ConfirmationPayload::Signature(address, hash) => { | 		ConfirmationPayload::Signature(address, mut data) => { | ||||||
| 			signature(accounts, address, hash, pass) | 			let mut message_data = | ||||||
|  | 				format!("\x19Ethereum Signed Message:\n{}", data.len()) | ||||||
|  | 				.into_bytes(); | ||||||
|  | 			message_data.append(&mut data); | ||||||
|  | 			signature(accounts, address, message_data.sha3(), pass) | ||||||
| 				.map(|result| result | 				.map(|result| result | ||||||
| 					.map(|rsv| { | 					.map(|rsv| { | ||||||
| 						let mut vrs = [0u8; 65]; | 						let mut vrs = [0u8; 65]; | ||||||
| @ -250,8 +255,8 @@ pub fn from_rpc<C, M>(payload: RpcConfirmationPayload, client: &C, miner: &M) -> | |||||||
| 		RpcConfirmationPayload::Decrypt(RpcDecryptRequest { address, msg }) => { | 		RpcConfirmationPayload::Decrypt(RpcDecryptRequest { address, msg }) => { | ||||||
| 			ConfirmationPayload::Decrypt(address.into(), msg.into()) | 			ConfirmationPayload::Decrypt(address.into(), msg.into()) | ||||||
| 		}, | 		}, | ||||||
| 		RpcConfirmationPayload::Signature(RpcSignRequest { address, hash }) => { | 		RpcConfirmationPayload::Signature(RpcSignRequest { address, data }) => { | ||||||
| 			ConfirmationPayload::Signature(address.into(), hash.into()) | 			ConfirmationPayload::Signature(address.into(), data.into()) | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ | |||||||
| // 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 util::{Address, U256, Bytes, H256}; | use util::{Address, U256, Bytes}; | ||||||
| use v1::types::TransactionCondition; | use v1::types::TransactionCondition; | ||||||
| 
 | 
 | ||||||
| /// Transaction request coming from RPC
 | /// Transaction request coming from RPC
 | ||||||
| @ -110,7 +110,7 @@ pub enum ConfirmationPayload { | |||||||
| 	/// Sign Transaction
 | 	/// Sign Transaction
 | ||||||
| 	SignTransaction(FilledTransactionRequest), | 	SignTransaction(FilledTransactionRequest), | ||||||
| 	/// Sign request
 | 	/// Sign request
 | ||||||
| 	Signature(Address, H256), | 	Signature(Address, Bytes), | ||||||
| 	/// Decrypt request
 | 	/// Decrypt request
 | ||||||
| 	Decrypt(Address, Bytes), | 	Decrypt(Address, Bytes), | ||||||
| } | } | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ | |||||||
| 
 | 
 | ||||||
| use std::sync::{Arc, Weak}; | use std::sync::{Arc, Weak}; | ||||||
| use transient_hashmap::TransientHashMap; | use transient_hashmap::TransientHashMap; | ||||||
| use util::{U256, Mutex, Hashable}; | use util::{U256, Mutex}; | ||||||
| 
 | 
 | ||||||
| use ethcore::account_provider::AccountProvider; | use ethcore::account_provider::AccountProvider; | ||||||
| use ethcore::miner::MinerService; | use ethcore::miner::MinerService; | ||||||
| @ -122,9 +122,9 @@ impl<C: 'static, M: 'static> ParitySigning for SigningQueueClient<C, M> where | |||||||
| 	C: MiningBlockChainClient, | 	C: MiningBlockChainClient, | ||||||
| 	M: MinerService, | 	M: MinerService, | ||||||
| { | { | ||||||
| 	fn post_sign(&self, address: RpcH160, hash: RpcH256) -> Result<RpcEither<RpcU256, RpcConfirmationResponse>, Error> { | 	fn post_sign(&self, address: RpcH160, data: RpcBytes) -> Result<RpcEither<RpcU256, RpcConfirmationResponse>, Error> { | ||||||
| 		self.active()?; | 		self.active()?; | ||||||
| 		self.dispatch(RpcConfirmationPayload::Signature((address, hash).into())) | 		self.dispatch(RpcConfirmationPayload::Signature((address, data).into())) | ||||||
| 			.map(|result| match result { | 			.map(|result| match result { | ||||||
| 				DispatchResult::Value(v) => RpcEither::Or(v), | 				DispatchResult::Value(v) => RpcEither::Or(v), | ||||||
| 				DispatchResult::Promise(promise) => { | 				DispatchResult::Promise(promise) => { | ||||||
| @ -183,8 +183,8 @@ impl<C: 'static, M: 'static> EthSigning for SigningQueueClient<C, M> where | |||||||
| 	M: MinerService, | 	M: MinerService, | ||||||
| { | { | ||||||
| 	fn sign(&self, ready: Ready<RpcH520>, address: RpcH160, data: RpcBytes) { | 	fn sign(&self, ready: Ready<RpcH520>, address: RpcH160, data: RpcBytes) { | ||||||
| 		let hash = data.0.sha3().into(); | 		let res = self.active().and_then(|_| self.dispatch(RpcConfirmationPayload::Signature((address, data).into()))); | ||||||
| 		let res = self.active().and_then(|_| self.dispatch(RpcConfirmationPayload::Signature((address, hash).into()))); | 
 | ||||||
| 		self.handle_dispatch(res, |response| { | 		self.handle_dispatch(res, |response| { | ||||||
| 			match response { | 			match response { | ||||||
| 				Ok(RpcConfirmationResponse::Signature(signature)) => ready.ready(Ok(signature)), | 				Ok(RpcConfirmationResponse::Signature(signature)) => ready.ready(Ok(signature)), | ||||||
|  | |||||||
| @ -17,7 +17,6 @@ | |||||||
| //! Unsafe Signing RPC implementation.
 | //! Unsafe Signing RPC implementation.
 | ||||||
| 
 | 
 | ||||||
| use std::sync::{Arc, Weak}; | use std::sync::{Arc, Weak}; | ||||||
| use util::Hashable; |  | ||||||
| 
 | 
 | ||||||
| use ethcore::account_provider::AccountProvider; | use ethcore::account_provider::AccountProvider; | ||||||
| use ethcore::miner::MinerService; | use ethcore::miner::MinerService; | ||||||
| @ -86,8 +85,7 @@ impl<C: 'static, M: 'static> EthSigning for SigningUnsafeClient<C, M> where | |||||||
| 	M: MinerService, | 	M: MinerService, | ||||||
| { | { | ||||||
| 	fn sign(&self, ready: Ready<RpcH520>, address: RpcH160, data: RpcBytes) { | 	fn sign(&self, ready: Ready<RpcH520>, address: RpcH160, data: RpcBytes) { | ||||||
| 		let hash = data.0.sha3().into(); | 		let result = match self.handle(RpcConfirmationPayload::Signature((address, data).into())) { | ||||||
| 		let result = match self.handle(RpcConfirmationPayload::Signature((address, hash).into())) { |  | ||||||
| 			Ok(RpcConfirmationResponse::Signature(signature)) => Ok(signature), | 			Ok(RpcConfirmationResponse::Signature(signature)) => Ok(signature), | ||||||
| 			Err(e) => Err(e), | 			Err(e) => Err(e), | ||||||
| 			e => Err(errors::internal("Unexpected result", e)), | 			e => Err(errors::internal("Unexpected result", e)), | ||||||
| @ -127,7 +125,7 @@ impl<C: 'static, M: 'static> ParitySigning for SigningUnsafeClient<C, M> where | |||||||
| 		ready.ready(result); | 		ready.ready(result); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn post_sign(&self, _: RpcH160, _: RpcH256) -> Result<RpcEither<RpcU256, RpcConfirmationResponse>, Error> { | 	fn post_sign(&self, _: RpcH160, _: RpcBytes) -> Result<RpcEither<RpcU256, RpcConfirmationResponse>, Error> { | ||||||
| 		// We don't support this in non-signer mode.
 | 		// We don't support this in non-signer mode.
 | ||||||
| 		Err(errors::signer_disabled()) | 		Err(errors::signer_disabled()) | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -309,7 +309,7 @@ fn rpc_eth_sign() { | |||||||
| 		], | 		], | ||||||
| 		"id": 1 | 		"id": 1 | ||||||
| 	}"#;
 | 	}"#;
 | ||||||
| 	let res = r#"{"jsonrpc":"2.0","result":"0x1b5100b2be0aafd86271c8f49891262920bfbfeaeccb2ef1d0b2053aefc3ddb399483eb3c902ecf4add3156461a61f59e924a65eb5e6cdbab0a158d45db5f87cdf","id":1}"#; | 	let res = r#"{"jsonrpc":"2.0","result":"0x1ba2870db1d0c26ef93c7b72d2a0830fa6b841e0593f7186bc6c7cc317af8cf3a42fda03bd589a49949aa05db83300cdb553116274518dbe9d90c65d0213f4af49","id":1}"#; | ||||||
| 
 | 
 | ||||||
| 	assert_eq!(tester.io.handle_request_sync(&req), Some(res.into())); | 	assert_eq!(tester.io.handle_request_sync(&req), Some(res.into())); | ||||||
| } | } | ||||||
|  | |||||||
| @ -85,14 +85,14 @@ fn should_return_list_of_items_to_confirm() { | |||||||
| 		nonce: None, | 		nonce: None, | ||||||
| 		condition: None, | 		condition: None, | ||||||
| 	})).unwrap(); | 	})).unwrap(); | ||||||
| 	tester.signer.add_request(ConfirmationPayload::Signature(1.into(), 5.into())).unwrap(); | 	tester.signer.add_request(ConfirmationPayload::Signature(1.into(), vec![5].into())).unwrap(); | ||||||
| 
 | 
 | ||||||
| 	// when
 | 	// when
 | ||||||
| 	let request = r#"{"jsonrpc":"2.0","method":"signer_requestsToConfirm","params":[],"id":1}"#; | 	let request = r#"{"jsonrpc":"2.0","method":"signer_requestsToConfirm","params":[],"id":1}"#; | ||||||
| 	let response = concat!( | 	let response = concat!( | ||||||
| 		r#"{"jsonrpc":"2.0","result":["#, | 		r#"{"jsonrpc":"2.0","result":["#, | ||||||
| 		r#"{"id":"0x1","payload":{"sendTransaction":{"condition":null,"data":"0x","from":"0x0000000000000000000000000000000000000001","gas":"0x989680","gasPrice":"0x2710","nonce":null,"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","value":"0x1"}}},"#, | 		r#"{"id":"0x1","payload":{"sendTransaction":{"condition":null,"data":"0x","from":"0x0000000000000000000000000000000000000001","gas":"0x989680","gasPrice":"0x2710","nonce":null,"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","value":"0x1"}}},"#, | ||||||
| 		r#"{"id":"0x2","payload":{"sign":{"address":"0x0000000000000000000000000000000000000001","hash":"0x0000000000000000000000000000000000000000000000000000000000000005"}}}"#, | 		r#"{"id":"0x2","payload":{"sign":{"address":"0x0000000000000000000000000000000000000001","data":"0x05"}}}"#, | ||||||
| 		r#"],"id":1}"# | 		r#"],"id":1}"# | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| @ -156,7 +156,7 @@ fn should_not_remove_transaction_if_password_is_invalid() { | |||||||
| fn should_not_remove_sign_if_password_is_invalid() { | fn should_not_remove_sign_if_password_is_invalid() { | ||||||
| 	// given
 | 	// given
 | ||||||
| 	let tester = signer_tester(); | 	let tester = signer_tester(); | ||||||
| 	tester.signer.add_request(ConfirmationPayload::Signature(0.into(), 5.into())).unwrap(); | 	tester.signer.add_request(ConfirmationPayload::Signature(0.into(), vec![5].into())).unwrap(); | ||||||
| 	assert_eq!(tester.signer.requests().len(), 1); | 	assert_eq!(tester.signer.requests().len(), 1); | ||||||
| 
 | 
 | ||||||
| 	// when
 | 	// when
 | ||||||
|  | |||||||
| @ -201,7 +201,7 @@ fn should_sign_if_account_is_unlocked() { | |||||||
| 		], | 		], | ||||||
| 		"id": 1 | 		"id": 1 | ||||||
| 	}"#;
 | 	}"#;
 | ||||||
| 	let response = r#"{"jsonrpc":"2.0","result":"0x1bb3062482b0687e9c97c7609ea60c1649959dbb334f71b3d5cacd496e0848ba8137bc765756627722389c6c39bc77700ccdc8916916a0eb03bcf5191d4f74dc65","id":1}"#; | 	let response = r#"{"jsonrpc":"2.0","result":"0x1bdb53b32e56cf3e9735377b7664d6de5a03e125b1bf8ec55715d253668b4238503b4ac931fe6af90add73e72a585e952665376b2b9afc5b6b239b7df74c734e12","id":1}"#; | ||||||
| 	assert_eq!(tester.io.handle_request_sync(&request), Some(response.to_owned())); | 	assert_eq!(tester.io.handle_request_sync(&request), Some(response.to_owned())); | ||||||
| 	assert_eq!(tester.signer.requests().len(), 0); | 	assert_eq!(tester.signer.requests().len(), 0); | ||||||
| } | } | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ | |||||||
| use jsonrpc_core::Error; | use jsonrpc_core::Error; | ||||||
| use jsonrpc_macros::Ready; | use jsonrpc_macros::Ready; | ||||||
| 
 | 
 | ||||||
| use v1::types::{U256, H160, H256, Bytes, ConfirmationResponse, TransactionRequest, Either}; | use v1::types::{U256, H160, Bytes, ConfirmationResponse, TransactionRequest, Either}; | ||||||
| 
 | 
 | ||||||
| build_rpc_trait! { | build_rpc_trait! { | ||||||
| 	/// Signing methods implementation.
 | 	/// Signing methods implementation.
 | ||||||
| @ -26,7 +26,7 @@ build_rpc_trait! { | |||||||
| 		/// Posts sign request asynchronously.
 | 		/// Posts sign request asynchronously.
 | ||||||
| 		/// Will return a confirmation ID for later use with check_transaction.
 | 		/// Will return a confirmation ID for later use with check_transaction.
 | ||||||
| 		#[rpc(name = "parity_postSign")] | 		#[rpc(name = "parity_postSign")] | ||||||
| 		fn post_sign(&self, H160, H256) -> Result<Either<U256, ConfirmationResponse>, Error>; | 		fn post_sign(&self, H160, Bytes) -> Result<Either<U256, ConfirmationResponse>, Error>; | ||||||
| 
 | 
 | ||||||
| 		/// Posts transaction asynchronously.
 | 		/// Posts transaction asynchronously.
 | ||||||
| 		/// Will return a transaction ID for later use with check_transaction.
 | 		/// Will return a transaction ID for later use with check_transaction.
 | ||||||
|  | |||||||
| @ -19,6 +19,7 @@ | |||||||
| use std::fmt; | use std::fmt; | ||||||
| use serde::{Serialize, Serializer}; | use serde::{Serialize, Serializer}; | ||||||
| use util::log::Colour; | use util::log::Colour; | ||||||
|  | use util::bytes::ToPretty; | ||||||
| 
 | 
 | ||||||
| use v1::types::{U256, TransactionRequest, RichRawTransaction, H160, H256, H520, Bytes, TransactionCondition}; | use v1::types::{U256, TransactionRequest, RichRawTransaction, H160, H256, H520, Bytes, TransactionCondition}; | ||||||
| use v1::helpers; | use v1::helpers; | ||||||
| @ -64,14 +65,14 @@ pub struct SignRequest { | |||||||
| 	/// Address
 | 	/// Address
 | ||||||
| 	pub address: H160, | 	pub address: H160, | ||||||
| 	/// Hash to sign
 | 	/// Hash to sign
 | ||||||
| 	pub hash: H256, | 	pub data: Bytes, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl From<(H160, H256)> for SignRequest { | impl From<(H160, Bytes)> for SignRequest { | ||||||
| 	fn from(tuple: (H160, H256)) -> Self { | 	fn from(tuple: (H160, Bytes)) -> Self { | ||||||
| 		SignRequest { | 		SignRequest { | ||||||
| 			address: tuple.0, | 			address: tuple.0, | ||||||
| 			hash: tuple.1, | 			data: tuple.1, | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @ -80,8 +81,8 @@ impl fmt::Display for SignRequest { | |||||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||||
| 		write!( | 		write!( | ||||||
| 			f, | 			f, | ||||||
| 			"sign 0x{:?} with {}", | 			"sign 0x{} with {}", | ||||||
| 			self.hash, | 			self.data.0.pretty(), | ||||||
| 			Colour::White.bold().paint(format!("0x{:?}", self.address)), | 			Colour::White.bold().paint(format!("0x{:?}", self.address)), | ||||||
| 		) | 		) | ||||||
| 	} | 	} | ||||||
| @ -172,9 +173,9 @@ impl From<helpers::ConfirmationPayload> for ConfirmationPayload { | |||||||
| 		match c { | 		match c { | ||||||
| 			helpers::ConfirmationPayload::SendTransaction(t) => ConfirmationPayload::SendTransaction(t.into()), | 			helpers::ConfirmationPayload::SendTransaction(t) => ConfirmationPayload::SendTransaction(t.into()), | ||||||
| 			helpers::ConfirmationPayload::SignTransaction(t) => ConfirmationPayload::SignTransaction(t.into()), | 			helpers::ConfirmationPayload::SignTransaction(t) => ConfirmationPayload::SignTransaction(t.into()), | ||||||
| 			helpers::ConfirmationPayload::Signature(address, hash) => ConfirmationPayload::Signature(SignRequest { | 			helpers::ConfirmationPayload::Signature(address, data) => ConfirmationPayload::Signature(SignRequest { | ||||||
| 				address: address.into(), | 				address: address.into(), | ||||||
| 				hash: hash.into(), | 				data: data.into(), | ||||||
| 			}), | 			}), | ||||||
| 			helpers::ConfirmationPayload::Decrypt(address, msg) => ConfirmationPayload::Decrypt(DecryptRequest { | 			helpers::ConfirmationPayload::Decrypt(address, msg) => ConfirmationPayload::Decrypt(DecryptRequest { | ||||||
| 				address: address.into(), | 				address: address.into(), | ||||||
| @ -247,12 +248,12 @@ mod tests { | |||||||
| 		// given
 | 		// given
 | ||||||
| 		let request = helpers::ConfirmationRequest { | 		let request = helpers::ConfirmationRequest { | ||||||
| 			id: 15.into(), | 			id: 15.into(), | ||||||
| 			payload: helpers::ConfirmationPayload::Signature(1.into(), 5.into()), | 			payload: helpers::ConfirmationPayload::Signature(1.into(), vec![5].into()), | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
| 		// when
 | 		// when
 | ||||||
| 		let res = serde_json::to_string(&ConfirmationRequest::from(request)); | 		let res = serde_json::to_string(&ConfirmationRequest::from(request)); | ||||||
| 		let expected = r#"{"id":"0xf","payload":{"sign":{"address":"0x0000000000000000000000000000000000000001","hash":"0x0000000000000000000000000000000000000000000000000000000000000005"}}}"#; | 		let expected = r#"{"id":"0xf","payload":{"sign":{"address":"0x0000000000000000000000000000000000000001","data":"0x05"}}}"#; | ||||||
| 
 | 
 | ||||||
| 		// then
 | 		// then
 | ||||||
| 		assert_eq!(res.unwrap(), expected.to_owned()); | 		assert_eq!(res.unwrap(), expected.to_owned()); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user