Rename network_id to chain_id where applicable.
This commit is contained in:
parent
f3e7d7c725
commit
73644adf69
@ -100,8 +100,8 @@ pub trait LightChainClient: Send + Sync {
|
|||||||
/// Get an iterator over a block and its ancestry.
|
/// Get an iterator over a block and its ancestry.
|
||||||
fn ancestry_iter<'a>(&'a self, start: BlockId) -> Box<Iterator<Item=encoded::Header> + 'a>;
|
fn ancestry_iter<'a>(&'a self, start: BlockId) -> Box<Iterator<Item=encoded::Header> + 'a>;
|
||||||
|
|
||||||
/// Get the signing network ID.
|
/// Get the signing chain ID.
|
||||||
fn signing_network_id(&self) -> Option<u64>;
|
fn signing_chain_id(&self) -> Option<u64>;
|
||||||
|
|
||||||
/// Get environment info for execution at a given block.
|
/// Get environment info for execution at a given block.
|
||||||
/// Fails if that block's header is not stored.
|
/// Fails if that block's header is not stored.
|
||||||
@ -260,9 +260,9 @@ impl Client {
|
|||||||
self.chain.ancestry_iter(start)
|
self.chain.ancestry_iter(start)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the signing network id.
|
/// Get the signing chain id.
|
||||||
pub fn signing_network_id(&self) -> Option<u64> {
|
pub fn signing_chain_id(&self) -> Option<u64> {
|
||||||
self.engine.signing_network_id(&self.latest_env_info())
|
self.engine.signing_chain_id(&self.latest_env_info())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flush the header queue.
|
/// Flush the header queue.
|
||||||
@ -448,8 +448,8 @@ impl LightChainClient for Client {
|
|||||||
Box::new(Client::ancestry_iter(self, start))
|
Box::new(Client::ancestry_iter(self, start))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signing_network_id(&self) -> Option<u64> {
|
fn signing_chain_id(&self) -> Option<u64> {
|
||||||
Client::signing_network_id(self)
|
Client::signing_chain_id(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn env_info(&self, id: BlockId) -> Option<EnvInfo> {
|
fn env_info(&self, id: BlockId) -> Option<EnvInfo> {
|
||||||
|
@ -1719,8 +1719,8 @@ impl BlockChainClient for Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signing_network_id(&self) -> Option<u64> {
|
fn signing_chain_id(&self) -> Option<u64> {
|
||||||
self.engine.signing_network_id(&self.latest_env_info())
|
self.engine.signing_chain_id(&self.latest_env_info())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_extra_info(&self, id: BlockId) -> Option<BTreeMap<String, String>> {
|
fn block_extra_info(&self, id: BlockId) -> Option<BTreeMap<String, String>> {
|
||||||
@ -1759,9 +1759,9 @@ impl BlockChainClient for Client {
|
|||||||
value: U256::zero(),
|
value: U256::zero(),
|
||||||
data: data,
|
data: data,
|
||||||
};
|
};
|
||||||
let network_id = self.engine.signing_network_id(&self.latest_env_info());
|
let chain_id = self.engine.signing_chain_id(&self.latest_env_info());
|
||||||
let signature = self.engine.sign(transaction.hash(network_id))?;
|
let signature = self.engine.sign(transaction.hash(chain_id))?;
|
||||||
let signed = SignedTransaction::new(transaction.with_signature(signature, network_id))?;
|
let signed = SignedTransaction::new(transaction.with_signature(signature, chain_id))?;
|
||||||
self.miner.import_own_transaction(self, signed.into())
|
self.miner.import_own_transaction(self, signed.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -733,7 +733,7 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
self.miner.ready_transactions(info.best_block_number, info.best_block_timestamp)
|
self.miner.ready_transactions(info.best_block_number, info.best_block_timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signing_network_id(&self) -> Option<u64> { None }
|
fn signing_chain_id(&self) -> Option<u64> { None }
|
||||||
|
|
||||||
fn mode(&self) -> Mode { Mode::Active }
|
fn mode(&self) -> Mode { Mode::Active }
|
||||||
|
|
||||||
@ -764,9 +764,9 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
value: U256::default(),
|
value: U256::default(),
|
||||||
data: data,
|
data: data,
|
||||||
};
|
};
|
||||||
let network_id = Some(self.spec.params().network_id);
|
let chain_id = Some(self.spec.chain_id());
|
||||||
let sig = self.spec.engine.sign(transaction.hash(network_id)).unwrap();
|
let sig = self.spec.engine.sign(transaction.hash(chain_id)).unwrap();
|
||||||
let signed = SignedTransaction::new(transaction.with_signature(sig, network_id)).unwrap();
|
let signed = SignedTransaction::new(transaction.with_signature(sig, chain_id)).unwrap();
|
||||||
self.miner.import_own_transaction(self, signed.into())
|
self.miner.import_own_transaction(self, signed.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,8 +239,8 @@ pub trait BlockChainClient : Sync + Send {
|
|||||||
corpus.into()
|
corpus.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the preferred network ID to sign on
|
/// Get the preferred chain ID to sign on
|
||||||
fn signing_network_id(&self) -> Option<u64>;
|
fn signing_chain_id(&self) -> Option<u64>;
|
||||||
|
|
||||||
/// Get the mode.
|
/// Get the mode.
|
||||||
fn mode(&self) -> Mode;
|
fn mode(&self) -> Mode;
|
||||||
|
@ -804,9 +804,9 @@ impl Engine for AuthorityRound {
|
|||||||
fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), Error> {
|
fn verify_transaction_basic(&self, t: &UnverifiedTransaction, header: &Header) -> Result<(), Error> {
|
||||||
t.check_low_s()?;
|
t.check_low_s()?;
|
||||||
|
|
||||||
if let Some(n) = t.network_id() {
|
if let Some(n) = t.chain_id() {
|
||||||
if header.number() >= self.params().eip155_transition && n != self.params().chain_id {
|
if header.number() >= self.params().eip155_transition && n != self.params().chain_id {
|
||||||
return Err(TransactionError::InvalidNetworkId.into());
|
return Err(TransactionError::InvalidChainId.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ pub trait Engine : Sync + Send {
|
|||||||
// TODO: Add flags for which bits of the transaction to check.
|
// TODO: Add flags for which bits of the transaction to check.
|
||||||
// TODO: consider including State in the params.
|
// TODO: consider including State in the params.
|
||||||
fn verify_transaction_basic(&self, t: &UnverifiedTransaction, _header: &Header) -> Result<(), Error> {
|
fn verify_transaction_basic(&self, t: &UnverifiedTransaction, _header: &Header) -> Result<(), Error> {
|
||||||
t.verify_basic(true, Some(self.params().network_id), true)?;
|
t.verify_basic(true, Some(self.params().chain_id), true)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,7 +273,7 @@ pub trait Engine : Sync + Send {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The network ID that transactions should be signed with.
|
/// The network ID that transactions should be signed with.
|
||||||
fn signing_network_id(&self, _env_info: &EnvInfo) -> Option<u64> {
|
fn signing_chain_id(&self, _env_info: &EnvInfo) -> Option<u64> {
|
||||||
Some(self.params().chain_id)
|
Some(self.params().chain_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +452,7 @@ mod tests {
|
|||||||
let s0: Secret = "1".sha3().into();
|
let s0: Secret = "1".sha3().into();
|
||||||
let v0 = tap.insert_account(s0.clone(), "").unwrap();
|
let v0 = tap.insert_account(s0.clone(), "").unwrap();
|
||||||
let v1 = tap.insert_account("0".sha3().into(), "").unwrap();
|
let v1 = tap.insert_account("0".sha3().into(), "").unwrap();
|
||||||
let network_id = Spec::new_validator_safe_contract().network_id();
|
let chain_id = Spec::new_validator_safe_contract().chain_id();
|
||||||
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap));
|
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap));
|
||||||
client.engine().register_client(Arc::downgrade(&client));
|
client.engine().register_client(Arc::downgrade(&client));
|
||||||
let validator_contract = "0000000000000000000000000000000000000005".parse::<Address>().unwrap();
|
let validator_contract = "0000000000000000000000000000000000000005".parse::<Address>().unwrap();
|
||||||
@ -466,7 +466,7 @@ mod tests {
|
|||||||
action: Action::Call(validator_contract),
|
action: Action::Call(validator_contract),
|
||||||
value: 0.into(),
|
value: 0.into(),
|
||||||
data: "bfc708a000000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(),
|
data: "bfc708a000000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(),
|
||||||
}.sign(&s0, Some(network_id));
|
}.sign(&s0, Some(chain_id));
|
||||||
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
|
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
|
||||||
client.update_sealing();
|
client.update_sealing();
|
||||||
assert_eq!(client.chain_info().best_block_number, 1);
|
assert_eq!(client.chain_info().best_block_number, 1);
|
||||||
@ -478,7 +478,7 @@ mod tests {
|
|||||||
action: Action::Call(validator_contract),
|
action: Action::Call(validator_contract),
|
||||||
value: 0.into(),
|
value: 0.into(),
|
||||||
data: "4d238c8e00000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(),
|
data: "4d238c8e00000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".from_hex().unwrap(),
|
||||||
}.sign(&s0, Some(network_id));
|
}.sign(&s0, Some(chain_id));
|
||||||
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
|
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
|
||||||
client.update_sealing();
|
client.update_sealing();
|
||||||
// The transaction is not yet included so still unable to seal.
|
// The transaction is not yet included so still unable to seal.
|
||||||
@ -497,7 +497,7 @@ mod tests {
|
|||||||
action: Action::Call(Address::default()),
|
action: Action::Call(Address::default()),
|
||||||
value: 0.into(),
|
value: 0.into(),
|
||||||
data: Vec::new(),
|
data: Vec::new(),
|
||||||
}.sign(&s0, Some(network_id));
|
}.sign(&s0, Some(chain_id));
|
||||||
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
|
client.miner().import_own_transaction(client.as_ref(), tx.into()).unwrap();
|
||||||
client.update_sealing();
|
client.update_sealing();
|
||||||
// Able to seal again.
|
// Able to seal again.
|
||||||
|
@ -78,8 +78,8 @@ pub enum TransactionError {
|
|||||||
RecipientBanned,
|
RecipientBanned,
|
||||||
/// Contract creation code is banned.
|
/// Contract creation code is banned.
|
||||||
CodeBanned,
|
CodeBanned,
|
||||||
/// Invalid network ID given.
|
/// Invalid chain ID given.
|
||||||
InvalidNetworkId,
|
InvalidChainId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for TransactionError {
|
impl fmt::Display for TransactionError {
|
||||||
@ -103,7 +103,7 @@ impl fmt::Display for TransactionError {
|
|||||||
SenderBanned => "Sender is temporarily banned.".into(),
|
SenderBanned => "Sender is temporarily banned.".into(),
|
||||||
RecipientBanned => "Recipient is temporarily banned.".into(),
|
RecipientBanned => "Recipient is temporarily banned.".into(),
|
||||||
CodeBanned => "Contract code is temporarily banned.".into(),
|
CodeBanned => "Contract code is temporarily banned.".into(),
|
||||||
InvalidNetworkId => "Transaction of this network ID is not allowed on this chain.".into(),
|
InvalidChainId => "Transaction of this chain ID is not allowed on this chain.".into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
f.write_fmt(format_args!("Transaction error ({})", msg))
|
f.write_fmt(format_args!("Transaction error ({})", msg))
|
||||||
|
@ -206,7 +206,7 @@ impl Engine for Arc<Ethash> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signing_network_id(&self, env_info: &EnvInfo) -> Option<u64> {
|
fn signing_chain_id(&self, env_info: &EnvInfo) -> Option<u64> {
|
||||||
if env_info.number >= self.params().eip155_transition {
|
if env_info.number >= self.params().eip155_transition {
|
||||||
Some(self.params().chain_id)
|
Some(self.params().chain_id)
|
||||||
} else {
|
} else {
|
||||||
@ -397,8 +397,8 @@ impl Engine for Arc<Ethash> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let check_low_s = header.number() >= self.ethash_params.homestead_transition;
|
let check_low_s = header.number() >= self.ethash_params.homestead_transition;
|
||||||
let network_id = if header.number() >= self.params().eip155_transition { Some(self.params().chain_id) } else { None };
|
let chain_id = if header.number() >= self.params().eip155_transition { Some(self.params().chain_id) } else { None };
|
||||||
t.verify_basic(check_low_s, network_id, false)?;
|
t.verify_basic(check_low_s, chain_id, false)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,25 +36,25 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
|||||||
Some(x) if x < 3_000_000 => &homestead_schedule,
|
Some(x) if x < 3_000_000 => &homestead_schedule,
|
||||||
Some(_) => &metropolis_schedule
|
Some(_) => &metropolis_schedule
|
||||||
};
|
};
|
||||||
let allow_network_id_of_one = number.map_or(false, |n| n >= 2_675_000);
|
let allow_chain_id_of_one = number.map_or(false, |n| n >= 2_675_000);
|
||||||
let allow_unsigned = number.map_or(false, |n| n >= 3_000_000);
|
let allow_unsigned = number.map_or(false, |n| n >= 3_000_000);
|
||||||
|
|
||||||
let rlp: Vec<u8> = test.rlp.into();
|
let rlp: Vec<u8> = test.rlp.into();
|
||||||
let res = UntrustedRlp::new(&rlp)
|
let res = UntrustedRlp::new(&rlp)
|
||||||
.as_val()
|
.as_val()
|
||||||
.map_err(From::from)
|
.map_err(From::from)
|
||||||
.and_then(|t: UnverifiedTransaction| t.validate(schedule, schedule.have_delegate_call, allow_network_id_of_one, allow_unsigned));
|
.and_then(|t: UnverifiedTransaction| t.validate(schedule, schedule.have_delegate_call, allow_chain_id_of_one, allow_unsigned));
|
||||||
|
|
||||||
fail_unless(test.transaction.is_none() == res.is_err(), "Validity different");
|
fail_unless(test.transaction.is_none() == res.is_err(), "Validity different");
|
||||||
if let (Some(tx), Some(sender)) = (test.transaction, test.sender) {
|
if let (Some(tx), Some(sender)) = (test.transaction, test.sender) {
|
||||||
let t = res.unwrap();
|
let t = res.unwrap();
|
||||||
fail_unless(SignedTransaction::new(t.clone()).unwrap().sender() == sender.into(), "sender mismatch");
|
fail_unless(SignedTransaction::new(t.clone()).unwrap().sender() == sender.into(), "sender mismatch");
|
||||||
let is_acceptable_network_id = match t.network_id() {
|
let is_acceptable_chain_id = match t.chain_id() {
|
||||||
None => true,
|
None => true,
|
||||||
Some(1) if allow_network_id_of_one => true,
|
Some(1) if allow_chain_id_of_one => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
fail_unless(is_acceptable_network_id, "Network ID unacceptable");
|
fail_unless(is_acceptable_chain_id, "Network ID unacceptable");
|
||||||
let data: Vec<u8> = tx.data.into();
|
let data: Vec<u8> = tx.data.into();
|
||||||
fail_unless(t.data == data, "data mismatch");
|
fail_unless(t.data == data, "data mismatch");
|
||||||
fail_unless(t.gas_price == tx.gas_price.into(), "gas_price mismatch");
|
fail_unless(t.gas_price == tx.gas_price.into(), "gas_price mismatch");
|
||||||
|
@ -1306,10 +1306,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn transaction() -> SignedTransaction {
|
fn transaction() -> SignedTransaction {
|
||||||
transaction_with_network_id(2)
|
transaction_with_chain_id(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_with_network_id(id: u64) -> SignedTransaction {
|
fn transaction_with_chain_id(chain_id: u64) -> SignedTransaction {
|
||||||
let keypair = Random.generate().unwrap();
|
let keypair = Random.generate().unwrap();
|
||||||
Transaction {
|
Transaction {
|
||||||
action: Action::Create,
|
action: Action::Create,
|
||||||
@ -1318,7 +1318,7 @@ mod tests {
|
|||||||
gas: U256::from(100_000),
|
gas: U256::from(100_000),
|
||||||
gas_price: U256::zero(),
|
gas_price: U256::zero(),
|
||||||
nonce: U256::zero(),
|
nonce: U256::zero(),
|
||||||
}.sign(keypair.secret(), Some(id))
|
}.sign(keypair.secret(), Some(chain_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1399,14 +1399,14 @@ mod tests {
|
|||||||
|
|
||||||
let client = generate_dummy_client(2);
|
let client = generate_dummy_client(2);
|
||||||
|
|
||||||
assert_eq!(miner.import_external_transactions(&*client, vec![transaction_with_network_id(spec.network_id()).into()]).pop().unwrap().unwrap(), TransactionImportResult::Current);
|
assert_eq!(miner.import_external_transactions(&*client, vec![transaction_with_chain_id(spec.chain_id()).into()]).pop().unwrap().unwrap(), TransactionImportResult::Current);
|
||||||
|
|
||||||
miner.update_sealing(&*client);
|
miner.update_sealing(&*client);
|
||||||
client.flush_queue();
|
client.flush_queue();
|
||||||
assert!(miner.pending_block(0).is_none());
|
assert!(miner.pending_block(0).is_none());
|
||||||
assert_eq!(client.chain_info().best_block_number, 3 as BlockNumber);
|
assert_eq!(client.chain_info().best_block_number, 3 as BlockNumber);
|
||||||
|
|
||||||
assert_eq!(miner.import_own_transaction(&*client, PendingTransaction::new(transaction_with_network_id(spec.network_id()).into(), None)).unwrap(), TransactionImportResult::Current);
|
assert_eq!(miner.import_own_transaction(&*client, PendingTransaction::new(transaction_with_chain_id(spec.chain_id()).into(), None)).unwrap(), TransactionImportResult::Current);
|
||||||
|
|
||||||
miner.update_sealing(&*client);
|
miner.update_sealing(&*client);
|
||||||
client.flush_queue();
|
client.flush_queue();
|
||||||
|
@ -130,7 +130,7 @@ fn make_chain(accounts: Arc<AccountProvider>, blocks_beyond: usize, transitions:
|
|||||||
action: Action::Call(Address::new()),
|
action: Action::Call(Address::new()),
|
||||||
value: 1.into(),
|
value: 1.into(),
|
||||||
data: Vec::new(),
|
data: Vec::new(),
|
||||||
}.sign(&*RICH_SECRET, client.signing_network_id());
|
}.sign(&*RICH_SECRET, client.signing_chain_id());
|
||||||
|
|
||||||
*nonce = *nonce + 1.into();
|
*nonce = *nonce + 1.into();
|
||||||
vec![transaction]
|
vec![transaction]
|
||||||
@ -176,7 +176,7 @@ fn make_chain(accounts: Arc<AccountProvider>, blocks_beyond: usize, transitions:
|
|||||||
action: Action::Call(addr),
|
action: Action::Call(addr),
|
||||||
value: 0.into(),
|
value: 0.into(),
|
||||||
data: data,
|
data: data,
|
||||||
}.sign(&*RICH_SECRET, client.signing_network_id());
|
}.sign(&*RICH_SECRET, client.signing_chain_id());
|
||||||
|
|
||||||
pending.push(transaction);
|
pending.push(transaction);
|
||||||
|
|
||||||
|
@ -380,6 +380,9 @@ impl Spec {
|
|||||||
/// Get the configured Network ID.
|
/// Get the configured Network ID.
|
||||||
pub fn network_id(&self) -> u64 { self.params().network_id }
|
pub fn network_id(&self) -> u64 { self.params().network_id }
|
||||||
|
|
||||||
|
/// Get the chain ID used for signing.
|
||||||
|
pub fn chain_id(&self) -> u64 { self.params().chain_id }
|
||||||
|
|
||||||
/// Get the configured subprotocol name.
|
/// Get the configured subprotocol name.
|
||||||
pub fn subprotocol_name(&self) -> String { self.params().subprotocol_name.clone() }
|
pub fn subprotocol_name(&self) -> String { self.params().subprotocol_name.clone() }
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ pub fn generate_dummy_client_with_spec_accounts_and_data<F>(get_test_spec: F, ac
|
|||||||
action: Action::Create,
|
action: Action::Create,
|
||||||
data: vec![],
|
data: vec![],
|
||||||
value: U256::zero(),
|
value: U256::zero(),
|
||||||
}.sign(kp.secret(), Some(test_spec.network_id())), None).unwrap();
|
}.sign(kp.secret(), Some(test_spec.chain_id())), None).unwrap();
|
||||||
n += 1;
|
n += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,15 +94,15 @@ pub struct Transaction {
|
|||||||
|
|
||||||
impl Transaction {
|
impl Transaction {
|
||||||
/// Append object with a without signature into RLP stream
|
/// Append object with a without signature into RLP stream
|
||||||
pub fn rlp_append_unsigned_transaction(&self, s: &mut RlpStream, network_id: Option<u64>) {
|
pub fn rlp_append_unsigned_transaction(&self, s: &mut RlpStream, chain_id: Option<u64>) {
|
||||||
s.begin_list(if network_id.is_none() { 6 } else { 9 });
|
s.begin_list(if chain_id.is_none() { 6 } else { 9 });
|
||||||
s.append(&self.nonce);
|
s.append(&self.nonce);
|
||||||
s.append(&self.gas_price);
|
s.append(&self.gas_price);
|
||||||
s.append(&self.gas);
|
s.append(&self.gas);
|
||||||
s.append(&self.action);
|
s.append(&self.action);
|
||||||
s.append(&self.value);
|
s.append(&self.value);
|
||||||
s.append(&self.data);
|
s.append(&self.data);
|
||||||
if let Some(n) = network_id {
|
if let Some(n) = chain_id {
|
||||||
s.append(&n);
|
s.append(&n);
|
||||||
s.append(&0u8);
|
s.append(&0u8);
|
||||||
s.append(&0u8);
|
s.append(&0u8);
|
||||||
@ -163,27 +163,27 @@ impl From<ethjson::transaction::Transaction> for UnverifiedTransaction {
|
|||||||
|
|
||||||
impl Transaction {
|
impl Transaction {
|
||||||
/// The message hash of the transaction.
|
/// The message hash of the transaction.
|
||||||
pub fn hash(&self, network_id: Option<u64>) -> H256 {
|
pub fn hash(&self, chain_id: Option<u64>) -> H256 {
|
||||||
let mut stream = RlpStream::new();
|
let mut stream = RlpStream::new();
|
||||||
self.rlp_append_unsigned_transaction(&mut stream, network_id);
|
self.rlp_append_unsigned_transaction(&mut stream, chain_id);
|
||||||
stream.as_raw().sha3()
|
stream.as_raw().sha3()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Signs the transaction as coming from `sender`.
|
/// Signs the transaction as coming from `sender`.
|
||||||
pub fn sign(self, secret: &Secret, network_id: Option<u64>) -> SignedTransaction {
|
pub fn sign(self, secret: &Secret, chain_id: Option<u64>) -> SignedTransaction {
|
||||||
let sig = ::ethkey::sign(secret, &self.hash(network_id))
|
let sig = ::ethkey::sign(secret, &self.hash(chain_id))
|
||||||
.expect("data is valid and context has signing capabilities; qed");
|
.expect("data is valid and context has signing capabilities; qed");
|
||||||
SignedTransaction::new(self.with_signature(sig, network_id))
|
SignedTransaction::new(self.with_signature(sig, chain_id))
|
||||||
.expect("secret is valid so it's recoverable")
|
.expect("secret is valid so it's recoverable")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Signs the transaction with signature.
|
/// Signs the transaction with signature.
|
||||||
pub fn with_signature(self, sig: Signature, network_id: Option<u64>) -> UnverifiedTransaction {
|
pub fn with_signature(self, sig: Signature, chain_id: Option<u64>) -> UnverifiedTransaction {
|
||||||
UnverifiedTransaction {
|
UnverifiedTransaction {
|
||||||
unsigned: self,
|
unsigned: self,
|
||||||
r: sig.r().into(),
|
r: sig.r().into(),
|
||||||
s: sig.s().into(),
|
s: sig.s().into(),
|
||||||
v: sig.v() as u64 + if let Some(n) = network_id { 35 + n * 2 } else { 27 },
|
v: sig.v() as u64 + if let Some(n) = chain_id { 35 + n * 2 } else { 27 },
|
||||||
hash: 0.into(),
|
hash: 0.into(),
|
||||||
}.compute_hash()
|
}.compute_hash()
|
||||||
}
|
}
|
||||||
@ -216,13 +216,13 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Add EIP-86 compatible empty signature.
|
/// Add EIP-86 compatible empty signature.
|
||||||
pub fn null_sign(self, network_id: u64) -> SignedTransaction {
|
pub fn null_sign(self, chain_id: u64) -> SignedTransaction {
|
||||||
SignedTransaction {
|
SignedTransaction {
|
||||||
transaction: UnverifiedTransaction {
|
transaction: UnverifiedTransaction {
|
||||||
unsigned: self,
|
unsigned: self,
|
||||||
r: U256::zero(),
|
r: U256::zero(),
|
||||||
s: U256::zero(),
|
s: U256::zero(),
|
||||||
v: network_id,
|
v: chain_id,
|
||||||
hash: 0.into(),
|
hash: 0.into(),
|
||||||
}.compute_hash(),
|
}.compute_hash(),
|
||||||
sender: UNSIGNED_SENDER,
|
sender: UNSIGNED_SENDER,
|
||||||
@ -250,7 +250,7 @@ pub struct UnverifiedTransaction {
|
|||||||
/// Plain Transaction.
|
/// Plain Transaction.
|
||||||
unsigned: Transaction,
|
unsigned: Transaction,
|
||||||
/// The V field of the signature; the LS bit described which half of the curve our point falls
|
/// The V field of the signature; the LS bit described which half of the curve our point falls
|
||||||
/// in. The MS bits describe which network this transaction is for. If 27/28, its for all networks.
|
/// in. The MS bits describe which chain this transaction is for. If 27/28, its for all chains.
|
||||||
v: u64,
|
v: u64,
|
||||||
/// The R field of the signature; helps describe the point on the curve.
|
/// The R field of the signature; helps describe the point on the curve.
|
||||||
r: U256,
|
r: U256,
|
||||||
@ -333,8 +333,8 @@ impl UnverifiedTransaction {
|
|||||||
/// The `v` value that appears in the RLP.
|
/// The `v` value that appears in the RLP.
|
||||||
pub fn original_v(&self) -> u64 { self.v }
|
pub fn original_v(&self) -> u64 { self.v }
|
||||||
|
|
||||||
/// The network ID, or `None` if this is a global transaction.
|
/// The chain ID, or `None` if this is a global transaction.
|
||||||
pub fn network_id(&self) -> Option<u64> {
|
pub fn chain_id(&self) -> Option<u64> {
|
||||||
match self.v {
|
match self.v {
|
||||||
v if self.is_unsigned() => Some(v),
|
v if self.is_unsigned() => Some(v),
|
||||||
v if v > 36 => Some((v - 35) / 2),
|
v if v > 36 => Some((v - 35) / 2),
|
||||||
@ -363,15 +363,15 @@ impl UnverifiedTransaction {
|
|||||||
|
|
||||||
/// Recovers the public key of the sender.
|
/// Recovers the public key of the sender.
|
||||||
pub fn recover_public(&self) -> Result<Public, Error> {
|
pub fn recover_public(&self) -> Result<Public, Error> {
|
||||||
Ok(recover(&self.signature(), &self.unsigned.hash(self.network_id()))?)
|
Ok(recover(&self.signature(), &self.unsigned.hash(self.chain_id()))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Do basic validation, checking for valid signature and minimum gas,
|
/// Do basic validation, checking for valid signature and minimum gas,
|
||||||
// TODO: consider use in block validation.
|
// TODO: consider use in block validation.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(feature = "json-tests")]
|
#[cfg(feature = "json-tests")]
|
||||||
pub fn validate(self, schedule: &Schedule, require_low: bool, allow_network_id_of_one: bool, allow_empty_signature: bool) -> Result<UnverifiedTransaction, Error> {
|
pub fn validate(self, schedule: &Schedule, require_low: bool, allow_chain_id_of_one: bool, allow_empty_signature: bool) -> Result<UnverifiedTransaction, Error> {
|
||||||
let chain_id = if allow_network_id_of_one { Some(1) } else { None };
|
let chain_id = if allow_chain_id_of_one { Some(1) } else { None };
|
||||||
self.verify_basic(require_low, chain_id, allow_empty_signature)?;
|
self.verify_basic(require_low, chain_id, allow_empty_signature)?;
|
||||||
if !allow_empty_signature || !self.is_unsigned() {
|
if !allow_empty_signature || !self.is_unsigned() {
|
||||||
self.recover_public()?;
|
self.recover_public()?;
|
||||||
@ -391,10 +391,10 @@ impl UnverifiedTransaction {
|
|||||||
if allow_empty_signature && self.is_unsigned() && !(self.gas_price.is_zero() && self.value.is_zero() && self.nonce.is_zero()) {
|
if allow_empty_signature && self.is_unsigned() && !(self.gas_price.is_zero() && self.value.is_zero() && self.nonce.is_zero()) {
|
||||||
return Err(EthkeyError::InvalidSignature.into())
|
return Err(EthkeyError::InvalidSignature.into())
|
||||||
}
|
}
|
||||||
match (self.network_id(), chain_id) {
|
match (self.chain_id(), chain_id) {
|
||||||
(None, _) => {},
|
(None, _) => {},
|
||||||
(Some(n), Some(m)) if n == m => {},
|
(Some(n), Some(m)) if n == m => {},
|
||||||
_ => return Err(TransactionError::InvalidNetworkId.into()),
|
_ => return Err(TransactionError::InvalidChainId.into()),
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -558,7 +558,7 @@ mod tests {
|
|||||||
} else { panic!(); }
|
} else { panic!(); }
|
||||||
assert_eq!(t.value, U256::from(0x0au64));
|
assert_eq!(t.value, U256::from(0x0au64));
|
||||||
assert_eq!(public_to_address(&t.recover_public().unwrap()), "0f65fe9276bc9a24ae7083ae28e2660ef72df99e".into());
|
assert_eq!(public_to_address(&t.recover_public().unwrap()), "0f65fe9276bc9a24ae7083ae28e2660ef72df99e".into());
|
||||||
assert_eq!(t.network_id(), None);
|
assert_eq!(t.chain_id(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -575,7 +575,7 @@ mod tests {
|
|||||||
data: b"Hello!".to_vec()
|
data: b"Hello!".to_vec()
|
||||||
}.sign(&key.secret(), None);
|
}.sign(&key.secret(), None);
|
||||||
assert_eq!(Address::from(key.public().sha3()), t.sender());
|
assert_eq!(Address::from(key.public().sha3()), t.sender());
|
||||||
assert_eq!(t.network_id(), None);
|
assert_eq!(t.chain_id(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -589,15 +589,15 @@ mod tests {
|
|||||||
data: b"Hello!".to_vec()
|
data: b"Hello!".to_vec()
|
||||||
}.fake_sign(Address::from(0x69));
|
}.fake_sign(Address::from(0x69));
|
||||||
assert_eq!(Address::from(0x69), t.sender());
|
assert_eq!(Address::from(0x69), t.sender());
|
||||||
assert_eq!(t.network_id(), None);
|
assert_eq!(t.chain_id(), None);
|
||||||
|
|
||||||
let t = t.clone();
|
let t = t.clone();
|
||||||
assert_eq!(Address::from(0x69), t.sender());
|
assert_eq!(Address::from(0x69), t.sender());
|
||||||
assert_eq!(t.network_id(), None);
|
assert_eq!(t.chain_id(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_recover_from_network_specific_signing() {
|
fn should_recover_from_chain_specific_signing() {
|
||||||
use ethkey::{Random, Generator};
|
use ethkey::{Random, Generator};
|
||||||
let key = Random.generate().unwrap();
|
let key = Random.generate().unwrap();
|
||||||
let t = Transaction {
|
let t = Transaction {
|
||||||
@ -609,7 +609,7 @@ mod tests {
|
|||||||
data: b"Hello!".to_vec()
|
data: b"Hello!".to_vec()
|
||||||
}.sign(&key.secret(), Some(69));
|
}.sign(&key.secret(), Some(69));
|
||||||
assert_eq!(Address::from(key.public().sha3()), t.sender());
|
assert_eq!(Address::from(key.public().sha3()), t.sender());
|
||||||
assert_eq!(t.network_id(), Some(69));
|
assert_eq!(t.chain_id(), Some(69));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -620,7 +620,7 @@ mod tests {
|
|||||||
let signed = decode(&FromHex::from_hex(tx_data).unwrap());
|
let signed = decode(&FromHex::from_hex(tx_data).unwrap());
|
||||||
let signed = SignedTransaction::new(signed).unwrap();
|
let signed = SignedTransaction::new(signed).unwrap();
|
||||||
assert_eq!(signed.sender(), address.into());
|
assert_eq!(signed.sender(), address.into());
|
||||||
flushln!("networkid: {:?}", signed.network_id());
|
flushln!("chainid: {:?}", signed.chain_id());
|
||||||
};
|
};
|
||||||
|
|
||||||
test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce");
|
test_vector("f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce");
|
||||||
|
@ -566,9 +566,9 @@ The following options are possible for the \`defaultBlock\` parameter:
|
|||||||
type: Hash,
|
type: Hash,
|
||||||
desc: 'public key of the signer.'
|
desc: 'public key of the signer.'
|
||||||
},
|
},
|
||||||
networkId: {
|
chainId: {
|
||||||
type: Quantity,
|
type: Quantity,
|
||||||
desc: 'the network id of the transaction, if any.'
|
desc: 'the chain id of the transaction, if any.'
|
||||||
},
|
},
|
||||||
creates: {
|
creates: {
|
||||||
type: Hash,
|
type: Hash,
|
||||||
@ -1111,9 +1111,9 @@ The following options are possible for the \`defaultBlock\` parameter:
|
|||||||
type: Hash,
|
type: Hash,
|
||||||
desc: 'public key of the signer.'
|
desc: 'public key of the signer.'
|
||||||
},
|
},
|
||||||
networkId: {
|
chainId: {
|
||||||
type: Quantity,
|
type: Quantity,
|
||||||
desc: 'the network id of the transaction, if any.'
|
desc: 'the chain id of the transaction, if any.'
|
||||||
},
|
},
|
||||||
creates: {
|
creates: {
|
||||||
type: Hash,
|
type: Hash,
|
||||||
|
@ -403,7 +403,7 @@ export default {
|
|||||||
condition: {
|
condition: {
|
||||||
block: 1
|
block: 1
|
||||||
},
|
},
|
||||||
networkId: null,
|
chainId: null,
|
||||||
nonce: '0x0',
|
nonce: '0x0',
|
||||||
publicKey: '0x3fa8c08c65a83f6b4ea3e04e1cc70cbe3cd391499e3e05ab7dedf28aff9afc538200ff93e3f2b2cb5029f03c7ebee820d63a4c5a9541c83acebe293f54cacf0e',
|
publicKey: '0x3fa8c08c65a83f6b4ea3e04e1cc70cbe3cd391499e3e05ab7dedf28aff9afc538200ff93e3f2b2cb5029f03c7ebee820d63a4c5a9541c83acebe293f54cacf0e',
|
||||||
raw: '0xf868808502d20cff33830e57e09400a289b43e1e4825dbedf2a78ba60a640634dc40830fffff801ca034c333b0b91cd832a3414d628e3fea29a00055cebf5ba59f7038c188404c0cf3a0524fd9b35be170439b5ffe89694ae0cfc553cb49d1d8b643239e353351531532',
|
raw: '0xf868808502d20cff33830e57e09400a289b43e1e4825dbedf2a78ba60a640634dc40830fffff801ca034c333b0b91cd832a3414d628e3fea29a00055cebf5ba59f7038c188404c0cf3a0524fd9b35be170439b5ffe89694ae0cfc553cb49d1d8b643239e353351531532',
|
||||||
@ -626,7 +626,7 @@ export default {
|
|||||||
condition: {
|
condition: {
|
||||||
block: 1
|
block: 1
|
||||||
},
|
},
|
||||||
networkId: 1,
|
chainId: 1,
|
||||||
nonce: '0x5',
|
nonce: '0x5',
|
||||||
publicKey: '0x96157302dade55a1178581333e57d60ffe6fdf5a99607890456a578b4e6b60e335037d61ed58aa4180f9fd747dc50d44a7924aa026acbfb988b5062b629d6c36',
|
publicKey: '0x96157302dade55a1178581333e57d60ffe6fdf5a99607890456a578b4e6b60e335037d61ed58aa4180f9fd747dc50d44a7924aa026acbfb988b5062b629d6c36',
|
||||||
r: '0x92e8beb19af2bad0511d516a86e77fa73004c0811b2173657a55797bdf8558e1',
|
r: '0x92e8beb19af2bad0511d516a86e77fa73004c0811b2173657a55797bdf8558e1',
|
||||||
@ -688,7 +688,7 @@ export default {
|
|||||||
condition: {
|
condition: {
|
||||||
block: 1
|
block: 1
|
||||||
},
|
},
|
||||||
networkId: 1,
|
chainId: 1,
|
||||||
nonce: '0x5',
|
nonce: '0x5',
|
||||||
publicKey: '0x96157302dade55a1178581333e57d60ffe6fdf5a99607890456a578b4e6b60e335037d61ed58aa4180f9fd747dc50d44a7924aa026acbfb988b5062b629d6c36',
|
publicKey: '0x96157302dade55a1178581333e57d60ffe6fdf5a99607890456a578b4e6b60e335037d61ed58aa4180f9fd747dc50d44a7924aa026acbfb988b5062b629d6c36',
|
||||||
r: '0x92e8beb19af2bad0511d516a86e77fa73004c0811b2173657a55797bdf8558e1',
|
r: '0x92e8beb19af2bad0511d516a86e77fa73004c0811b2173657a55797bdf8558e1',
|
||||||
@ -980,7 +980,7 @@ export default {
|
|||||||
creates: null,
|
creates: null,
|
||||||
raw: '0xf86c018504a817c80082520894f5d405530dabfbd0c1cab7a5812f008aa5559adf882efc004ac03a49968025a0b40c6967a7e8bbdfd99a25fd306b9ef23b80e719514aeb7ddd19e2303d6fc139a06bf770ab08119e67dc29817e1412a0e3086f43da308c314db1b3bca9fb6d32bd',
|
raw: '0xf86c018504a817c80082520894f5d405530dabfbd0c1cab7a5812f008aa5559adf882efc004ac03a49968025a0b40c6967a7e8bbdfd99a25fd306b9ef23b80e719514aeb7ddd19e2303d6fc139a06bf770ab08119e67dc29817e1412a0e3086f43da308c314db1b3bca9fb6d32bd',
|
||||||
publicKey: '0xeba33fd74f06236e17475bc5b6d1bac718eac048350d77d3fc8fbcbd85782a57c821255623c4fd1ebc9d555d07df453b2579ee557b7203fc256ca3b3401e4027',
|
publicKey: '0xeba33fd74f06236e17475bc5b6d1bac718eac048350d77d3fc8fbcbd85782a57c821255623c4fd1ebc9d555d07df453b2579ee557b7203fc256ca3b3401e4027',
|
||||||
networkId: 1,
|
chainId: 1,
|
||||||
standardV: '0x0',
|
standardV: '0x0',
|
||||||
v: '0x25',
|
v: '0x25',
|
||||||
r: '0xb40c6967a7e8bbdfd99a25fd306b9ef23b80e719514aeb7ddd19e2303d6fc139',
|
r: '0xb40c6967a7e8bbdfd99a25fd306b9ef23b80e719514aeb7ddd19e2303d6fc139',
|
||||||
|
@ -173,9 +173,9 @@ export class TransactionResponse {
|
|||||||
type: Data,
|
type: Data,
|
||||||
desc: 'Public key of the signer.'
|
desc: 'Public key of the signer.'
|
||||||
},
|
},
|
||||||
networkId: {
|
chainId: {
|
||||||
type: Quantity,
|
type: Quantity,
|
||||||
desc: 'The network id of the transaction, if any.'
|
desc: 'The chain id of the transaction, if any.'
|
||||||
},
|
},
|
||||||
standardV: {
|
standardV: {
|
||||||
type: Quantity,
|
type: Quantity,
|
||||||
|
@ -133,7 +133,7 @@ impl<C: MiningBlockChainClient, M: MinerService> Dispatcher for FullDispatcher<C
|
|||||||
-> BoxFuture<WithToken<SignedTransaction>, Error>
|
-> BoxFuture<WithToken<SignedTransaction>, Error>
|
||||||
{
|
{
|
||||||
let (client, miner) = (self.client.clone(), self.miner.clone());
|
let (client, miner) = (self.client.clone(), self.miner.clone());
|
||||||
let network_id = client.signing_network_id();
|
let chain_id = client.signing_chain_id();
|
||||||
let address = filled.from;
|
let address = filled.from;
|
||||||
future::done({
|
future::done({
|
||||||
let t = Transaction {
|
let t = Transaction {
|
||||||
@ -146,12 +146,12 @@ impl<C: MiningBlockChainClient, M: MinerService> Dispatcher for FullDispatcher<C
|
|||||||
};
|
};
|
||||||
|
|
||||||
if accounts.is_hardware_address(address) {
|
if accounts.is_hardware_address(address) {
|
||||||
hardware_signature(&*accounts, address, t, network_id).map(WithToken::No)
|
hardware_signature(&*accounts, address, t, chain_id).map(WithToken::No)
|
||||||
} else {
|
} else {
|
||||||
let hash = t.hash(network_id);
|
let hash = t.hash(chain_id);
|
||||||
let signature = try_bf!(signature(&*accounts, address, hash, password));
|
let signature = try_bf!(signature(&*accounts, address, hash, password));
|
||||||
Ok(signature.map(|sig| {
|
Ok(signature.map(|sig| {
|
||||||
SignedTransaction::new(t.with_signature(sig, network_id))
|
SignedTransaction::new(t.with_signature(sig, chain_id))
|
||||||
.expect("Transaction was signed by AccountsProvider; it never produces invalid signatures; qed")
|
.expect("Transaction was signed by AccountsProvider; it never produces invalid signatures; qed")
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -358,7 +358,7 @@ impl Dispatcher for LightDispatcher {
|
|||||||
fn sign(&self, accounts: Arc<AccountProvider>, filled: FilledTransactionRequest, password: SignWith)
|
fn sign(&self, accounts: Arc<AccountProvider>, filled: FilledTransactionRequest, password: SignWith)
|
||||||
-> BoxFuture<WithToken<SignedTransaction>, Error>
|
-> BoxFuture<WithToken<SignedTransaction>, Error>
|
||||||
{
|
{
|
||||||
let network_id = self.client.signing_network_id();
|
let chain_id = self.client.signing_chain_id();
|
||||||
let address = filled.from;
|
let address = filled.from;
|
||||||
|
|
||||||
let with_nonce = move |filled: FilledTransactionRequest, nonce| {
|
let with_nonce = move |filled: FilledTransactionRequest, nonce| {
|
||||||
@ -372,14 +372,14 @@ impl Dispatcher for LightDispatcher {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if accounts.is_hardware_address(address) {
|
if accounts.is_hardware_address(address) {
|
||||||
return hardware_signature(&*accounts, address, t, network_id).map(WithToken::No)
|
return hardware_signature(&*accounts, address, t, chain_id).map(WithToken::No)
|
||||||
}
|
}
|
||||||
|
|
||||||
let hash = t.hash(network_id);
|
let hash = t.hash(chain_id);
|
||||||
let signature = signature(&*accounts, address, hash, password)?;
|
let signature = signature(&*accounts, address, hash, password)?;
|
||||||
|
|
||||||
Ok(signature.map(|sig| {
|
Ok(signature.map(|sig| {
|
||||||
SignedTransaction::new(t.with_signature(sig, network_id))
|
SignedTransaction::new(t.with_signature(sig, chain_id))
|
||||||
.expect("Transaction was signed by AccountsProvider; it never produces invalid signatures; qed")
|
.expect("Transaction was signed by AccountsProvider; it never produces invalid signatures; qed")
|
||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
@ -552,20 +552,20 @@ fn signature(accounts: &AccountProvider, address: Address, hash: H256, password:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// obtain a hardware signature from the given account.
|
// obtain a hardware signature from the given account.
|
||||||
fn hardware_signature(accounts: &AccountProvider, address: Address, t: Transaction, network_id: Option<u64>)
|
fn hardware_signature(accounts: &AccountProvider, address: Address, t: Transaction, chain_id: Option<u64>)
|
||||||
-> Result<SignedTransaction, Error>
|
-> Result<SignedTransaction, Error>
|
||||||
{
|
{
|
||||||
debug_assert!(accounts.is_hardware_address(address));
|
debug_assert!(accounts.is_hardware_address(address));
|
||||||
|
|
||||||
let mut stream = rlp::RlpStream::new();
|
let mut stream = rlp::RlpStream::new();
|
||||||
t.rlp_append_unsigned_transaction(&mut stream, network_id);
|
t.rlp_append_unsigned_transaction(&mut stream, chain_id);
|
||||||
let signature = accounts.sign_with_hardware(address, &stream.as_raw())
|
let signature = accounts.sign_with_hardware(address, &stream.as_raw())
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
debug!(target: "miner", "Error signing transaction with hardware wallet: {}", e);
|
debug!(target: "miner", "Error signing transaction with hardware wallet: {}", e);
|
||||||
errors::account("Error signing transaction with hardware wallet", e)
|
errors::account("Error signing transaction with hardware wallet", e)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
SignedTransaction::new(t.with_signature(signature, network_id))
|
SignedTransaction::new(t.with_signature(signature, chain_id))
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
debug!(target: "miner", "Hardware wallet has produced invalid signature: {}", e);
|
debug!(target: "miner", "Hardware wallet has produced invalid signature: {}", e);
|
||||||
errors::account("Invalid signature generated", e)
|
errors::account("Invalid signature generated", e)
|
||||||
|
@ -310,7 +310,7 @@ pub fn transaction_message(error: TransactionError) -> String {
|
|||||||
GasLimitExceeded { limit, got } => {
|
GasLimitExceeded { limit, got } => {
|
||||||
format!("Transaction cost exceeds current gas limit. Limit: {}, got: {}. Try decreasing supplied gas.", limit, got)
|
format!("Transaction cost exceeds current gas limit. Limit: {}, got: {}. Try decreasing supplied gas.", limit, got)
|
||||||
},
|
},
|
||||||
InvalidNetworkId => "Invalid network id.".into(),
|
InvalidChainId => "Invalid chain id.".into(),
|
||||||
InvalidGasLimit(_) => "Supplied gas is beyond limit.".into(),
|
InvalidGasLimit(_) => "Supplied gas is beyond limit.".into(),
|
||||||
SenderBanned => "Sender is banned in local queue.".into(),
|
SenderBanned => "Sender is banned in local queue.".into(),
|
||||||
RecipientBanned => "Recipient is banned in local queue.".into(),
|
RecipientBanned => "Recipient is banned in local queue.".into(),
|
||||||
|
@ -124,9 +124,9 @@ impl<D: Dispatcher + 'static> Personal for PersonalClient<D> {
|
|||||||
.map(move |tx| (tx, dispatcher))
|
.map(move |tx| (tx, dispatcher))
|
||||||
})
|
})
|
||||||
.and_then(|(pending_tx, dispatcher)| {
|
.and_then(|(pending_tx, dispatcher)| {
|
||||||
let network_id = pending_tx.network_id();
|
let chain_id = pending_tx.chain_id();
|
||||||
trace!(target: "miner", "send_transaction: dispatching tx: {} for network ID {:?}",
|
trace!(target: "miner", "send_transaction: dispatching tx: {} for chain ID {:?}",
|
||||||
::rlp::encode(&*pending_tx).into_vec().pretty(), network_id);
|
::rlp::encode(&*pending_tx).into_vec().pretty(), chain_id);
|
||||||
|
|
||||||
dispatcher.dispatch_transaction(pending_tx).map(Into::into)
|
dispatcher.dispatch_transaction(pending_tx).map(Into::into)
|
||||||
})
|
})
|
||||||
|
@ -544,7 +544,7 @@ fn rpc_eth_pending_transaction_by_hash() {
|
|||||||
tester.miner.pending_transactions.lock().insert(H256::zero(), tx);
|
tester.miner.pending_transactions.lock().insert(H256::zero(), tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"condition":null,"creates":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x1","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","networkId":null,"nonce":"0x0","publicKey":"0x7ae46da747962c2ee46825839c1ef9298e3bd2e70ca2938495c3693a485ec3eaa8f196327881090ff64cf4fbb0a48485d4f83098e189ed3b7a87d5941b59f789","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","raw":"0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","standardV":"0x0","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"v":"0x1b","value":"0xa"},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"chainId":null,"condition":null,"creates":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x1","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","nonce":"0x0","publicKey":"0x7ae46da747962c2ee46825839c1ef9298e3bd2e70ca2938495c3693a485ec3eaa8f196327881090ff64cf4fbb0a48485d4f83098e189ed3b7a87d5941b59f789","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","raw":"0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","standardV":"0x0","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"v":"0x1b","value":"0xa"},"id":1}"#;
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "eth_getTransactionByHash",
|
"method": "eth_getTransactionByHash",
|
||||||
@ -860,12 +860,13 @@ fn rpc_eth_sign_transaction() {
|
|||||||
let response = r#"{"jsonrpc":"2.0","result":{"#.to_owned() +
|
let response = r#"{"jsonrpc":"2.0","result":{"#.to_owned() +
|
||||||
r#""raw":"0x"# + &rlp.to_hex() + r#"","# +
|
r#""raw":"0x"# + &rlp.to_hex() + r#"","# +
|
||||||
r#""tx":{"# +
|
r#""tx":{"# +
|
||||||
r#""blockHash":null,"blockNumber":null,"condition":null,"creates":null,"# +
|
r#""blockHash":null,"blockNumber":null,"# +
|
||||||
|
&format!("\"chainId\":{},", t.chain_id().map_or("null".to_owned(), |n| format!("{}", n))) +
|
||||||
|
r#""condition":null,"creates":null,"# +
|
||||||
&format!("\"from\":\"0x{:?}\",", &address) +
|
&format!("\"from\":\"0x{:?}\",", &address) +
|
||||||
r#""gas":"0x76c0","gasPrice":"0x9184e72a000","# +
|
r#""gas":"0x76c0","gasPrice":"0x9184e72a000","# +
|
||||||
&format!("\"hash\":\"0x{:?}\",", t.hash()) +
|
&format!("\"hash\":\"0x{:?}\",", t.hash()) +
|
||||||
r#""input":"0x","# +
|
r#""input":"0x","# +
|
||||||
&format!("\"networkId\":{},", t.network_id().map_or("null".to_owned(), |n| format!("{}", n))) +
|
|
||||||
r#""nonce":"0x1","# +
|
r#""nonce":"0x1","# +
|
||||||
&format!("\"publicKey\":\"0x{:?}\",", t.recover_public().unwrap()) +
|
&format!("\"publicKey\":\"0x{:?}\",", t.recover_public().unwrap()) +
|
||||||
&format!("\"r\":\"0x{}\",", U256::from(signature.r()).to_hex()) +
|
&format!("\"r\":\"0x{}\",", U256::from(signature.r()).to_hex()) +
|
||||||
|
@ -233,7 +233,7 @@ fn rpc_parity_remove_transaction() {
|
|||||||
let hash = signed.hash();
|
let hash = signed.hash();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_removeTransaction", "params":[""#.to_owned() + &format!("0x{:?}", hash) + r#""], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_removeTransaction", "params":[""#.to_owned() + &format!("0x{:?}", hash) + r#""], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"condition":null,"creates":null,"from":"0x0000000000000000000000000000000000000002","gas":"0x76c0","gasPrice":"0x9184e72a000","hash":"0xa2e0da8a8064e0b9f93e95a53c2db6d01280efb8ac72a708d25487e67dd0f8fc","input":"0x","networkId":null,"nonce":"0x1","publicKey":null,"r":"0x1","raw":"0xe9018609184e72a0008276c0940000000000000000000000000000000000000005849184e72a80800101","s":"0x1","standardV":"0x4","to":"0x0000000000000000000000000000000000000005","transactionIndex":null,"v":"0x0","value":"0x9184e72a"},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"chainId":null,"condition":null,"creates":null,"from":"0x0000000000000000000000000000000000000002","gas":"0x76c0","gasPrice":"0x9184e72a000","hash":"0xa2e0da8a8064e0b9f93e95a53c2db6d01280efb8ac72a708d25487e67dd0f8fc","input":"0x","nonce":"0x1","publicKey":null,"r":"0x1","raw":"0xe9018609184e72a0008276c0940000000000000000000000000000000000000005849184e72a80800101","s":"0x1","standardV":"0x4","to":"0x0000000000000000000000000000000000000005","transactionIndex":null,"v":"0x0","value":"0x9184e72a"},"id":1}"#;
|
||||||
|
|
||||||
miner.pending_transactions.lock().insert(hash, signed);
|
miner.pending_transactions.lock().insert(hash, signed);
|
||||||
assert_eq!(io.handle_request_sync(&request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(&request), Some(response.to_owned()));
|
||||||
|
@ -454,12 +454,13 @@ fn should_confirm_sign_transaction_with_rlp() {
|
|||||||
let response = r#"{"jsonrpc":"2.0","result":{"#.to_owned() +
|
let response = r#"{"jsonrpc":"2.0","result":{"#.to_owned() +
|
||||||
r#""raw":"0x"# + &rlp.to_hex() + r#"","# +
|
r#""raw":"0x"# + &rlp.to_hex() + r#"","# +
|
||||||
r#""tx":{"# +
|
r#""tx":{"# +
|
||||||
r#""blockHash":null,"blockNumber":null,"condition":null,"creates":null,"# +
|
r#""blockHash":null,"blockNumber":null,"# +
|
||||||
|
&format!("\"chainId\":{},", t.chain_id().map_or("null".to_owned(), |n| format!("{}", n))) +
|
||||||
|
r#""condition":null,"creates":null,"# +
|
||||||
&format!("\"from\":\"0x{:?}\",", &address) +
|
&format!("\"from\":\"0x{:?}\",", &address) +
|
||||||
r#""gas":"0x989680","gasPrice":"0x1000","# +
|
r#""gas":"0x989680","gasPrice":"0x1000","# +
|
||||||
&format!("\"hash\":\"0x{:?}\",", t.hash()) +
|
&format!("\"hash\":\"0x{:?}\",", t.hash()) +
|
||||||
r#""input":"0x","# +
|
r#""input":"0x","# +
|
||||||
&format!("\"networkId\":{},", t.network_id().map_or("null".to_owned(), |n| format!("{}", n))) +
|
|
||||||
r#""nonce":"0x0","# +
|
r#""nonce":"0x0","# +
|
||||||
&format!("\"publicKey\":\"0x{:?}\",", t.public_key().unwrap()) +
|
&format!("\"publicKey\":\"0x{:?}\",", t.public_key().unwrap()) +
|
||||||
&format!("\"r\":\"0x{}\",", U256::from(signature.r()).to_hex()) +
|
&format!("\"r\":\"0x{}\",", U256::from(signature.r()).to_hex()) +
|
||||||
|
@ -297,12 +297,13 @@ fn should_add_sign_transaction_to_the_queue() {
|
|||||||
let response = r#"{"jsonrpc":"2.0","result":{"#.to_owned() +
|
let response = r#"{"jsonrpc":"2.0","result":{"#.to_owned() +
|
||||||
r#""raw":"0x"# + &rlp.to_hex() + r#"","# +
|
r#""raw":"0x"# + &rlp.to_hex() + r#"","# +
|
||||||
r#""tx":{"# +
|
r#""tx":{"# +
|
||||||
r#""blockHash":null,"blockNumber":null,"condition":null,"creates":null,"# +
|
r#""blockHash":null,"blockNumber":null,"# +
|
||||||
|
&format!("\"chainId\":{},", t.chain_id().map_or("null".to_owned(), |n| format!("{}", n))) +
|
||||||
|
r#""condition":null,"creates":null,"# +
|
||||||
&format!("\"from\":\"0x{:?}\",", &address) +
|
&format!("\"from\":\"0x{:?}\",", &address) +
|
||||||
r#""gas":"0x76c0","gasPrice":"0x9184e72a000","# +
|
r#""gas":"0x76c0","gasPrice":"0x9184e72a000","# +
|
||||||
&format!("\"hash\":\"0x{:?}\",", t.hash()) +
|
&format!("\"hash\":\"0x{:?}\",", t.hash()) +
|
||||||
r#""input":"0x","# +
|
r#""input":"0x","# +
|
||||||
&format!("\"networkId\":{},", t.network_id().map_or("null".to_owned(), |n| format!("{}", n))) +
|
|
||||||
r#""nonce":"0x1","# +
|
r#""nonce":"0x1","# +
|
||||||
&format!("\"publicKey\":\"0x{:?}\",", t.public_key().unwrap()) +
|
&format!("\"publicKey\":\"0x{:?}\",", t.public_key().unwrap()) +
|
||||||
&format!("\"r\":\"0x{}\",", U256::from(signature.r()).to_hex()) +
|
&format!("\"r\":\"0x{}\",", U256::from(signature.r()).to_hex()) +
|
||||||
|
@ -230,7 +230,7 @@ mod tests {
|
|||||||
fn test_serialize_block_transactions() {
|
fn test_serialize_block_transactions() {
|
||||||
let t = BlockTransactions::Full(vec![Transaction::default()]);
|
let t = BlockTransactions::Full(vec![Transaction::default()]);
|
||||||
let serialized = serde_json::to_string(&t).unwrap();
|
let serialized = serde_json::to_string(&t).unwrap();
|
||||||
assert_eq!(serialized, r#"[{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null,"networkId":null,"standardV":"0x0","v":"0x0","r":"0x0","s":"0x0","condition":null}]"#);
|
assert_eq!(serialized, r#"[{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null,"chainId":null,"standardV":"0x0","v":"0x0","r":"0x0","s":"0x0","condition":null}]"#);
|
||||||
|
|
||||||
let t = BlockTransactions::Hashes(vec![H256::default().into()]);
|
let t = BlockTransactions::Hashes(vec![H256::default().into()]);
|
||||||
let serialized = serde_json::to_string(&t).unwrap();
|
let serialized = serde_json::to_string(&t).unwrap();
|
||||||
|
@ -59,8 +59,8 @@ pub struct Transaction {
|
|||||||
#[serde(rename="publicKey")]
|
#[serde(rename="publicKey")]
|
||||||
pub public_key: Option<H512>,
|
pub public_key: Option<H512>,
|
||||||
/// The network id of the transaction, if any.
|
/// The network id of the transaction, if any.
|
||||||
#[serde(rename="networkId")]
|
#[serde(rename="chainId")]
|
||||||
pub network_id: Option<u64>,
|
pub chain_id: Option<u64>,
|
||||||
/// The standardised V field of the signature (0 or 1).
|
/// The standardised V field of the signature (0 or 1).
|
||||||
#[serde(rename="standardV")]
|
#[serde(rename="standardV")]
|
||||||
pub standard_v: U256,
|
pub standard_v: U256,
|
||||||
@ -196,7 +196,7 @@ impl Transaction {
|
|||||||
},
|
},
|
||||||
raw: ::rlp::encode(&t.signed).into_vec().into(),
|
raw: ::rlp::encode(&t.signed).into_vec().into(),
|
||||||
public_key: t.recover_public().ok().map(Into::into),
|
public_key: t.recover_public().ok().map(Into::into),
|
||||||
network_id: t.network_id(),
|
chain_id: t.chain_id(),
|
||||||
standard_v: t.standard_v().into(),
|
standard_v: t.standard_v().into(),
|
||||||
v: t.original_v().into(),
|
v: t.original_v().into(),
|
||||||
r: signature.r().into(),
|
r: signature.r().into(),
|
||||||
@ -230,7 +230,7 @@ impl Transaction {
|
|||||||
},
|
},
|
||||||
raw: ::rlp::encode(&t).into_vec().into(),
|
raw: ::rlp::encode(&t).into_vec().into(),
|
||||||
public_key: t.public_key().map(Into::into),
|
public_key: t.public_key().map(Into::into),
|
||||||
network_id: t.network_id(),
|
chain_id: t.chain_id(),
|
||||||
standard_v: t.standard_v().into(),
|
standard_v: t.standard_v().into(),
|
||||||
v: t.original_v().into(),
|
v: t.original_v().into(),
|
||||||
r: signature.r().into(),
|
r: signature.r().into(),
|
||||||
@ -273,7 +273,7 @@ mod tests {
|
|||||||
fn test_transaction_serialize() {
|
fn test_transaction_serialize() {
|
||||||
let t = Transaction::default();
|
let t = Transaction::default();
|
||||||
let serialized = serde_json::to_string(&t).unwrap();
|
let serialized = serde_json::to_string(&t).unwrap();
|
||||||
assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null,"networkId":null,"standardV":"0x0","v":"0x0","r":"0x0","s":"0x0","condition":null}"#);
|
assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null,"chainId":null,"standardV":"0x0","v":"0x0","r":"0x0","s":"0x0","condition":null}"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -42,7 +42,7 @@ impl IoHandler<ClientIoMessage> for TestIoHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_tx(secret: &Secret, nonce: U256, network_id: u64) -> PendingTransaction {
|
fn new_tx(secret: &Secret, nonce: U256, chain_id: u64) -> PendingTransaction {
|
||||||
let signed = Transaction {
|
let signed = Transaction {
|
||||||
nonce: nonce.into(),
|
nonce: nonce.into(),
|
||||||
gas_price: 0.into(),
|
gas_price: 0.into(),
|
||||||
@ -50,7 +50,7 @@ fn new_tx(secret: &Secret, nonce: U256, network_id: u64) -> PendingTransaction {
|
|||||||
action: Action::Call(Address::default()),
|
action: Action::Call(Address::default()),
|
||||||
value: 0.into(),
|
value: 0.into(),
|
||||||
data: Vec::new(),
|
data: Vec::new(),
|
||||||
}.sign(secret, Some(network_id));
|
}.sign(secret, Some(chain_id));
|
||||||
PendingTransaction::new(signed, None)
|
PendingTransaction::new(signed, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ fn authority_round() {
|
|||||||
ap.insert_account(s0.secret().clone(), "").unwrap();
|
ap.insert_account(s0.secret().clone(), "").unwrap();
|
||||||
ap.insert_account(s1.secret().clone(), "").unwrap();
|
ap.insert_account(s1.secret().clone(), "").unwrap();
|
||||||
|
|
||||||
let network_id = Spec::new_test_round().network_id();
|
let chain_id = Spec::new_test_round().chain_id();
|
||||||
let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), Spec::new_test_round, Some(ap));
|
let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), Spec::new_test_round, Some(ap));
|
||||||
let io_handler0: Arc<IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler { client: net.peer(0).chain.clone() });
|
let io_handler0: Arc<IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler { client: net.peer(0).chain.clone() });
|
||||||
let io_handler1: Arc<IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler { client: net.peer(1).chain.clone() });
|
let io_handler1: Arc<IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler { client: net.peer(1).chain.clone() });
|
||||||
@ -76,15 +76,15 @@ fn authority_round() {
|
|||||||
// exchange statuses
|
// exchange statuses
|
||||||
net.sync();
|
net.sync();
|
||||||
// Trigger block proposal
|
// Trigger block proposal
|
||||||
net.peer(0).chain.miner().import_own_transaction(&*net.peer(0).chain, new_tx(s0.secret(), 0.into(), network_id)).unwrap();
|
net.peer(0).chain.miner().import_own_transaction(&*net.peer(0).chain, new_tx(s0.secret(), 0.into(), chain_id)).unwrap();
|
||||||
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 0.into(), network_id)).unwrap();
|
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 0.into(), chain_id)).unwrap();
|
||||||
// Sync a block
|
// Sync a block
|
||||||
net.sync();
|
net.sync();
|
||||||
assert_eq!(net.peer(0).chain.chain_info().best_block_number, 1);
|
assert_eq!(net.peer(0).chain.chain_info().best_block_number, 1);
|
||||||
assert_eq!(net.peer(1).chain.chain_info().best_block_number, 1);
|
assert_eq!(net.peer(1).chain.chain_info().best_block_number, 1);
|
||||||
|
|
||||||
net.peer(0).chain.miner().import_own_transaction(&*net.peer(0).chain, new_tx(s0.secret(), 1.into(), network_id)).unwrap();
|
net.peer(0).chain.miner().import_own_transaction(&*net.peer(0).chain, new_tx(s0.secret(), 1.into(), chain_id)).unwrap();
|
||||||
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 1.into(), network_id)).unwrap();
|
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 1.into(), chain_id)).unwrap();
|
||||||
// Move to next proposer step.
|
// Move to next proposer step.
|
||||||
net.peer(0).chain.engine().step();
|
net.peer(0).chain.engine().step();
|
||||||
net.peer(1).chain.engine().step();
|
net.peer(1).chain.engine().step();
|
||||||
@ -93,8 +93,8 @@ fn authority_round() {
|
|||||||
assert_eq!(net.peer(1).chain.chain_info().best_block_number, 2);
|
assert_eq!(net.peer(1).chain.chain_info().best_block_number, 2);
|
||||||
|
|
||||||
// Fork the network with equal height.
|
// Fork the network with equal height.
|
||||||
net.peer(0).chain.miner().import_own_transaction(&*net.peer(0).chain, new_tx(s0.secret(), 2.into(), network_id)).unwrap();
|
net.peer(0).chain.miner().import_own_transaction(&*net.peer(0).chain, new_tx(s0.secret(), 2.into(), chain_id)).unwrap();
|
||||||
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 2.into(), network_id)).unwrap();
|
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 2.into(), chain_id)).unwrap();
|
||||||
// Let both nodes build one block.
|
// Let both nodes build one block.
|
||||||
net.peer(0).chain.engine().step();
|
net.peer(0).chain.engine().step();
|
||||||
let early_hash = net.peer(0).chain.chain_info().best_block_hash;
|
let early_hash = net.peer(0).chain.chain_info().best_block_hash;
|
||||||
@ -116,8 +116,8 @@ fn authority_round() {
|
|||||||
assert_eq!(ci1.best_block_hash, early_hash);
|
assert_eq!(ci1.best_block_hash, early_hash);
|
||||||
|
|
||||||
// Selfish miner
|
// Selfish miner
|
||||||
net.peer(0).chain.miner().import_own_transaction(&*net.peer(0).chain, new_tx(s0.secret(), 3.into(), network_id)).unwrap();
|
net.peer(0).chain.miner().import_own_transaction(&*net.peer(0).chain, new_tx(s0.secret(), 3.into(), chain_id)).unwrap();
|
||||||
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 3.into(), network_id)).unwrap();
|
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 3.into(), chain_id)).unwrap();
|
||||||
// Node 0 is an earlier primary.
|
// Node 0 is an earlier primary.
|
||||||
net.peer(0).chain.engine().step();
|
net.peer(0).chain.engine().step();
|
||||||
assert_eq!(net.peer(0).chain.chain_info().best_block_number, 4);
|
assert_eq!(net.peer(0).chain.chain_info().best_block_number, 4);
|
||||||
@ -128,7 +128,7 @@ fn authority_round() {
|
|||||||
// Node 1 makes 2 blocks, but is a later primary on the first one.
|
// Node 1 makes 2 blocks, but is a later primary on the first one.
|
||||||
net.peer(1).chain.engine().step();
|
net.peer(1).chain.engine().step();
|
||||||
net.peer(1).chain.engine().step();
|
net.peer(1).chain.engine().step();
|
||||||
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 4.into(), network_id)).unwrap();
|
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 4.into(), chain_id)).unwrap();
|
||||||
net.peer(1).chain.engine().step();
|
net.peer(1).chain.engine().step();
|
||||||
net.peer(1).chain.engine().step();
|
net.peer(1).chain.engine().step();
|
||||||
assert_eq!(net.peer(1).chain.chain_info().best_block_number, 5);
|
assert_eq!(net.peer(1).chain.chain_info().best_block_number, 5);
|
||||||
@ -149,7 +149,7 @@ fn tendermint() {
|
|||||||
ap.insert_account(s0.secret().clone(), "").unwrap();
|
ap.insert_account(s0.secret().clone(), "").unwrap();
|
||||||
ap.insert_account(s1.secret().clone(), "").unwrap();
|
ap.insert_account(s1.secret().clone(), "").unwrap();
|
||||||
|
|
||||||
let network_id = Spec::new_test_tendermint().network_id();
|
let chain_id = Spec::new_test_tendermint().chain_id();
|
||||||
let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), Spec::new_test_tendermint, Some(ap));
|
let mut net = TestNet::with_spec_and_accounts(2, SyncConfig::default(), Spec::new_test_tendermint, Some(ap));
|
||||||
let io_handler0: Arc<IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler { client: net.peer(0).chain.clone() });
|
let io_handler0: Arc<IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler { client: net.peer(0).chain.clone() });
|
||||||
let io_handler1: Arc<IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler { client: net.peer(1).chain.clone() });
|
let io_handler1: Arc<IoHandler<ClientIoMessage>> = Arc::new(TestIoHandler { client: net.peer(1).chain.clone() });
|
||||||
@ -165,7 +165,7 @@ fn tendermint() {
|
|||||||
// Exhange statuses
|
// Exhange statuses
|
||||||
net.sync();
|
net.sync();
|
||||||
// Propose
|
// Propose
|
||||||
net.peer(0).chain.miner().import_own_transaction(&*net.peer(0).chain, new_tx(s0.secret(), 0.into(), network_id)).unwrap();
|
net.peer(0).chain.miner().import_own_transaction(&*net.peer(0).chain, new_tx(s0.secret(), 0.into(), chain_id)).unwrap();
|
||||||
net.sync();
|
net.sync();
|
||||||
// Propose timeout, synchronous for now
|
// Propose timeout, synchronous for now
|
||||||
net.peer(0).chain.engine().step();
|
net.peer(0).chain.engine().step();
|
||||||
@ -176,7 +176,7 @@ fn tendermint() {
|
|||||||
assert_eq!(net.peer(0).chain.chain_info().best_block_number, 1);
|
assert_eq!(net.peer(0).chain.chain_info().best_block_number, 1);
|
||||||
assert_eq!(net.peer(1).chain.chain_info().best_block_number, 1);
|
assert_eq!(net.peer(1).chain.chain_info().best_block_number, 1);
|
||||||
|
|
||||||
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 0.into(), network_id)).unwrap();
|
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 0.into(), chain_id)).unwrap();
|
||||||
// Commit timeout
|
// Commit timeout
|
||||||
net.peer(0).chain.engine().step();
|
net.peer(0).chain.engine().step();
|
||||||
net.peer(1).chain.engine().step();
|
net.peer(1).chain.engine().step();
|
||||||
@ -190,8 +190,8 @@ fn tendermint() {
|
|||||||
assert_eq!(net.peer(0).chain.chain_info().best_block_number, 2);
|
assert_eq!(net.peer(0).chain.chain_info().best_block_number, 2);
|
||||||
assert_eq!(net.peer(1).chain.chain_info().best_block_number, 2);
|
assert_eq!(net.peer(1).chain.chain_info().best_block_number, 2);
|
||||||
|
|
||||||
net.peer(0).chain.miner().import_own_transaction(&*net.peer(0).chain, new_tx(s0.secret(), 1.into(), network_id)).unwrap();
|
net.peer(0).chain.miner().import_own_transaction(&*net.peer(0).chain, new_tx(s0.secret(), 1.into(), chain_id)).unwrap();
|
||||||
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 1.into(), network_id)).unwrap();
|
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 1.into(), chain_id)).unwrap();
|
||||||
// Peers get disconnected.
|
// Peers get disconnected.
|
||||||
// Commit
|
// Commit
|
||||||
net.peer(0).chain.engine().step();
|
net.peer(0).chain.engine().step();
|
||||||
@ -199,8 +199,8 @@ fn tendermint() {
|
|||||||
// Propose
|
// Propose
|
||||||
net.peer(0).chain.engine().step();
|
net.peer(0).chain.engine().step();
|
||||||
net.peer(1).chain.engine().step();
|
net.peer(1).chain.engine().step();
|
||||||
net.peer(0).chain.miner().import_own_transaction(&*net.peer(0).chain, new_tx(s0.secret(), 2.into(), network_id)).unwrap();
|
net.peer(0).chain.miner().import_own_transaction(&*net.peer(0).chain, new_tx(s0.secret(), 2.into(), chain_id)).unwrap();
|
||||||
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 2.into(), network_id)).unwrap();
|
net.peer(1).chain.miner().import_own_transaction(&*net.peer(1).chain, new_tx(s1.secret(), 2.into(), chain_id)).unwrap();
|
||||||
// Send different prevotes
|
// Send different prevotes
|
||||||
net.sync();
|
net.sync();
|
||||||
// Prevote timeout
|
// Prevote timeout
|
||||||
|
Loading…
Reference in New Issue
Block a user