From 5196e021a895e34331053fbd1dc33a35f87be043 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Fri, 30 Aug 2019 16:42:40 +0900 Subject: [PATCH 001/105] Bump the version to 2.0.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 16493560c4..577e0e23fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -226,7 +226,7 @@ dependencies = [ [[package]] name = "codechain" -version = "0.0.0" +version = "2.0.0" dependencies = [ "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cidr 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 9cf79b8a1a..04bd8583cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "codechain" -version = "0.0.0" +version = "2.0.0" license = "AGPL-3.0" authors = ["CodeChain Team "] exclude = [ From 33a4ecbaf308aa63416624c2c5d2a1fea908f7a0 Mon Sep 17 00:00:00 2001 From: Joonmo Yang Date: Mon, 2 Sep 2019 12:37:56 +0900 Subject: [PATCH 002/105] Turn on lto for the release build --- Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 04bd8583cb..b4c9410bcf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,6 +58,9 @@ vergen = "2" path = "codechain/main.rs" name = "codechain" +[profile.release] +lto = true + [workspace] members = [ "core", From 4a8af17e47d1b3467af4356a740a5241f0d0d797 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Thu, 5 Sep 2019 18:53:55 +0900 Subject: [PATCH 003/105] Update genesis block of the Beagle network --- core/res/beagle.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/res/beagle.json b/core/res/beagle.json index cd7c986db1..4e1419ff8c 100644 --- a/core/res/beagle.json +++ b/core/res/beagle.json @@ -73,7 +73,7 @@ }, "score": "0x20000", "author": "bccq8m5rgjw60rcxvsruydafsze6tdhkm8hsu7rpm56", - "timestamp": "0x00", + "timestamp": "0x01", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "0x" }, From e9b3f3186cb8f96a70ca7b80d94015c7e8e79e52 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Thu, 5 Sep 2019 14:48:39 +0900 Subject: [PATCH 004/105] Update the best block when best proposal header is updated In Tendermint best block needs precommits in the next header. Currently, the best block is updated when the best proposal header's previous block is imported. However, the best block is not updated when a proposal block's next header is imported. This commit updates best block when the next header is imported. --- core/src/client/importer.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/core/src/client/importer.rs b/core/src/client/importer.rs index b010b5e06b..beb7f99243 100644 --- a/core/src/client/importer.rs +++ b/core/src/client/importer.rs @@ -318,6 +318,7 @@ impl Importer { _importer_lock: &MutexGuard<()>, ) -> usize { let prev_best_proposal_header_hash = client.block_chain().best_proposal_header().hash(); + let prev_best_block_hash = client.block_chain().best_block_hash(); let mut bad = HashSet::new(); let mut imported = Vec::new(); @@ -350,7 +351,8 @@ impl Importer { self.header_queue.mark_as_bad(&bad.drain().collect::>()); let (enacted, retracted) = self.calculate_enacted_retracted(&routes); - let new_best_proposal_header_hash = client.block_chain().best_proposal_header().hash(); + let new_best_proposal_header = client.block_chain().best_proposal_header(); + let new_best_proposal_header_hash = new_best_proposal_header.hash(); let best_proposal_header_changed = if prev_best_proposal_header_hash != new_best_proposal_header_hash { Some(new_best_proposal_header_hash) } else { @@ -367,6 +369,14 @@ impl Importer { best_proposal_header_changed, ); + let maybe_new_best_block_hash = new_best_proposal_header.parent_hash(); + if best_proposal_header_changed.is_some() + && prev_best_block_hash != maybe_new_best_block_hash + && client.block(&BlockId::Hash(maybe_new_best_block_hash)).is_some() + { + client.update_best_as_committed(maybe_new_best_block_hash); + } + client.db().flush().expect("DB flush failed."); imported.len() From 98261726da0997e90932e20b1dbb7c72c0bc90f0 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Thu, 5 Sep 2019 22:00:19 +0900 Subject: [PATCH 005/105] Revert "Update the best block when best proposal header is updated" This reverts commit e6c6f959bb8cff8cdde87b2e876f8d2f796bc5ea. --- core/src/client/importer.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/core/src/client/importer.rs b/core/src/client/importer.rs index beb7f99243..b010b5e06b 100644 --- a/core/src/client/importer.rs +++ b/core/src/client/importer.rs @@ -318,7 +318,6 @@ impl Importer { _importer_lock: &MutexGuard<()>, ) -> usize { let prev_best_proposal_header_hash = client.block_chain().best_proposal_header().hash(); - let prev_best_block_hash = client.block_chain().best_block_hash(); let mut bad = HashSet::new(); let mut imported = Vec::new(); @@ -351,8 +350,7 @@ impl Importer { self.header_queue.mark_as_bad(&bad.drain().collect::>()); let (enacted, retracted) = self.calculate_enacted_retracted(&routes); - let new_best_proposal_header = client.block_chain().best_proposal_header(); - let new_best_proposal_header_hash = new_best_proposal_header.hash(); + let new_best_proposal_header_hash = client.block_chain().best_proposal_header().hash(); let best_proposal_header_changed = if prev_best_proposal_header_hash != new_best_proposal_header_hash { Some(new_best_proposal_header_hash) } else { @@ -369,14 +367,6 @@ impl Importer { best_proposal_header_changed, ); - let maybe_new_best_block_hash = new_best_proposal_header.parent_hash(); - if best_proposal_header_changed.is_some() - && prev_best_block_hash != maybe_new_best_block_hash - && client.block(&BlockId::Hash(maybe_new_best_block_hash)).is_some() - { - client.update_best_as_committed(maybe_new_best_block_hash); - } - client.db().flush().expect("DB flush failed."); imported.len() From e463c9c80afe936c253373dd0ed57c97fea5188e Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Tue, 10 Sep 2019 14:54:43 +0900 Subject: [PATCH 006/105] Use TendermintState instead of Step in some places Since TendermintState has more information than Step, using TendermintState is better. Also, if TendermintState::Commit has block_hash as a field, Step -> TendermintState conversion will be broken. --- core/src/consensus/tendermint/types.rs | 11 ----- core/src/consensus/tendermint/worker.rs | 60 +++++++++++++------------ 2 files changed, 31 insertions(+), 40 deletions(-) diff --git a/core/src/consensus/tendermint/types.rs b/core/src/consensus/tendermint/types.rs index 70cef83807..c92d656013 100644 --- a/core/src/consensus/tendermint/types.rs +++ b/core/src/consensus/tendermint/types.rs @@ -102,17 +102,6 @@ impl fmt::Debug for TendermintState { } } -impl From for TendermintState { - fn from(s: Step) -> Self { - match s { - Step::Propose => TendermintState::Propose, - Step::Prevote => TendermintState::Prevote, - Step::Precommit => TendermintState::Precommit, - Step::Commit => TendermintState::Commit, - } - } -} - #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] pub enum Step { Propose, diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index d0ef5f4ae5..f9d59b6494 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -592,8 +592,8 @@ impl Worker { self.votes_received = BitSet::new(); } - fn move_to_step(&mut self, step: Step, is_restoring: bool) { - let prev_step = mem::replace(&mut self.step, step.into()); + fn move_to_step(&mut self, state: TendermintState, is_restoring: bool) { + let prev_step = mem::replace(&mut self.step, state.clone()); if !is_restoring { self.backup(); } @@ -602,18 +602,18 @@ impl Worker { self.timeout_token_nonce += 1; self.extension .send(network::Event::SetTimerStep { - step, + step: state.to_step(), view: self.view, expired_token_nonce, }) .unwrap(); - let vote_step = VoteStep::new(self.height, self.view, step); + let vote_step = VoteStep::new(self.height, self.view, state.to_step()); // If there are not enough pre-votes or pre-commits, // move_to_step can be called with the same step // Also, when moving to the commit step, // keep `votes_received` for gossiping. - if prev_step.to_step() != step && step != Step::Commit { + if prev_step.to_step() != state.to_step() && !state.is_commit() { self.votes_received = BitSet::new(); } @@ -624,13 +624,13 @@ impl Worker { self.last_two_thirds_majority.view(), self.votes_received, ); - match step { + match state.to_step() { Step::Propose => { cinfo!(ENGINE, "move_to_step: Propose."); if let Some(hash) = self.votes.get_block_hashes(&vote_step).first() { if self.client().block(&BlockId::Hash(*hash)).is_some() { self.proposal = Proposal::new_imported(*hash); - self.move_to_step(Step::Prevote, is_restoring); + self.move_to_step(TendermintState::Prevote, is_restoring); } else { cwarn!(ENGINE, "Proposal is received but not imported"); // Proposal is received but is not verified yet. @@ -822,7 +822,7 @@ impl Worker { let next_step = match self.step { TendermintState::Precommit if message.on.block_hash.is_none() && has_enough_aligned_votes => { self.increment_view(1); - Some(Step::Propose) + Some(TendermintState::Propose) } TendermintState::Precommit if has_enough_aligned_votes => { let bh = message.on.block_hash.expect("previous guard ensures is_some; qed"); @@ -832,16 +832,16 @@ impl Worker { // Update the best block hash as the hash of the committed block self.client().update_best_as_committed(bh); - Some(Step::Commit) + Some(TendermintState::Commit) } else { cwarn!(ENGINE, "Cannot find a proposal which committed"); self.increment_view(1); - Some(Step::Propose) + Some(TendermintState::Propose) } } // Avoid counting votes twice. - TendermintState::Prevote if lock_change => Some(Step::Precommit), - TendermintState::Prevote if has_enough_aligned_votes => Some(Step::Precommit), + TendermintState::Prevote if lock_change => Some(TendermintState::Precommit), + TendermintState::Prevote if has_enough_aligned_votes => Some(TendermintState::Precommit), _ => None, }; @@ -856,7 +856,7 @@ impl Worker { { let height = self.height; self.move_to_height(height + 1); - self.move_to_step(Step::Propose, is_restoring); + self.move_to_step(TendermintState::Propose, is_restoring); return } @@ -904,7 +904,7 @@ impl Worker { let current_step = self.step.clone(); match current_step { TendermintState::Propose => { - self.move_to_step(Step::Prevote, false); + self.move_to_step(TendermintState::Prevote, false); } TendermintState::ProposeWaitImported { block, @@ -944,13 +944,13 @@ impl Worker { if proposal_at_view_0 == Some(proposal.hash()) { self.proposal = Proposal::new_imported(proposal.hash()) } - self.move_to_step(Step::Prevote, false); + self.move_to_step(TendermintState::Prevote, false); } } fn submit_proposal_block(&mut self, sealed_block: &SealedBlock) { cinfo!(ENGINE, "Submitting proposal block {}", sealed_block.header().hash()); - self.move_to_step(Step::Prevote, false); + self.move_to_step(TendermintState::Prevote, false); self.broadcast_proposal_block(self.view, encoded::Block::new(sealed_block.rlp_bytes())); } @@ -968,14 +968,16 @@ impl Worker { let client = self.client(); let backup = restore(client.get_kvdb().as_ref()); if let Some(backup) = backup { - let backup_step = if backup.step == Step::Commit { + let backup_step = match backup.step { + Step::Propose => TendermintState::Propose, + Step::Prevote => TendermintState::Prevote, + Step::Precommit => TendermintState::Precommit, // If the backuped step is `Commit`, we should start at `Precommit` to update the // chain's best block safely. - Step::Precommit - } else { - backup.step + Step::Commit => TendermintState::Precommit, }; - self.step = backup_step.into(); + + self.step = backup_step; self.height = backup.height; self.view = backup.view; self.last_confirmed_view = backup.last_confirmed_view; @@ -1188,7 +1190,7 @@ impl Worker { let next_step = match self.step { TendermintState::Propose => { cinfo!(ENGINE, "Propose timeout."); - Step::Prevote + TendermintState::Prevote } TendermintState::ProposeWaitBlockGeneration { .. @@ -1210,20 +1212,20 @@ impl Worker { } TendermintState::Prevote if self.has_enough_any_votes() => { cinfo!(ENGINE, "Prevote timeout."); - Step::Precommit + TendermintState::Precommit } TendermintState::Prevote => { cinfo!(ENGINE, "Prevote timeout without enough votes."); - Step::Prevote + TendermintState::Prevote } TendermintState::Precommit if self.has_enough_any_votes() => { cinfo!(ENGINE, "Precommit timeout."); self.increment_view(1); - Step::Propose + TendermintState::Propose } TendermintState::Precommit => { cinfo!(ENGINE, "Precommit timeout without enough votes."); - Step::Precommit + TendermintState::Precommit } TendermintState::Commit => { cinfo!(ENGINE, "Commit timeout."); @@ -1234,7 +1236,7 @@ impl Worker { } let height = self.height; self.move_to_height(height + 1); - Step::Propose + TendermintState::Propose } TendermintState::CommitTimedout => unreachable!(), }; @@ -1457,14 +1459,14 @@ impl Worker { } } if height_changed { - self.move_to_step(Step::Propose, false); + self.move_to_step(TendermintState::Propose, false); return } } if !enacted.is_empty() && self.can_move_from_commit_to_propose() { let new_height = self.height + 1; self.move_to_height(new_height); - self.move_to_step(Step::Propose, false) + self.move_to_step(TendermintState::Propose, false) } } From 93e35d29e6999aa556051c01d62619fa6cbde302 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Tue, 10 Sep 2019 15:49:33 +0900 Subject: [PATCH 007/105] Move "Transition to {state}" log in the move_to_step function --- core/src/consensus/tendermint/worker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index f9d59b6494..0252140c90 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -593,6 +593,7 @@ impl Worker { } fn move_to_step(&mut self, state: TendermintState, is_restoring: bool) { + ctrace!(ENGINE, "Transition to {:?} triggered.", state); let prev_step = mem::replace(&mut self.step, state.clone()); if !is_restoring { self.backup(); @@ -846,7 +847,6 @@ impl Worker { }; if let Some(step) = next_step { - ctrace!(ENGINE, "Transition to {:?} triggered.", step); self.move_to_step(step, is_restoring); return } From fafccc760bebbb31f2b5a9dbe7ae77859f871b7e Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 11 Sep 2019 15:51:20 +0900 Subject: [PATCH 008/105] Move to Commit state if enough precommits are collected --- core/src/consensus/tendermint/types.rs | 66 ++++++++++-- core/src/consensus/tendermint/worker.rs | 136 ++++++++++++++++++------ 2 files changed, 161 insertions(+), 41 deletions(-) diff --git a/core/src/consensus/tendermint/types.rs b/core/src/consensus/tendermint/types.rs index c92d656013..91c63f242b 100644 --- a/core/src/consensus/tendermint/types.rs +++ b/core/src/consensus/tendermint/types.rs @@ -23,6 +23,7 @@ use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; use super::super::BitSet; use super::message::VoteStep; use crate::block::{IsBlock, SealedBlock}; +use consensus::tendermint::BlockHash; pub type Height = u64; pub type View = u64; @@ -41,8 +42,14 @@ pub enum TendermintState { }, Prevote, Precommit, - Commit, - CommitTimedout, + Commit { + view: View, + block_hash: H256, + }, + CommitTimedout { + view: View, + block_hash: H256, + }, } impl TendermintState { @@ -60,25 +67,60 @@ impl TendermintState { } => Step::Propose, TendermintState::Prevote => Step::Prevote, TendermintState::Precommit => Step::Precommit, - TendermintState::Commit => Step::Commit, - TendermintState::CommitTimedout => Step::Commit, + TendermintState::Commit { + .. + } => Step::Commit, + TendermintState::CommitTimedout { + .. + } => Step::Commit, } } pub fn is_commit(&self) -> bool { match self { - TendermintState::Commit => true, - TendermintState::CommitTimedout => true, + TendermintState::Commit { + .. + } => true, + TendermintState::CommitTimedout { + .. + } => true, _ => false, } } pub fn is_commit_timedout(&self) -> bool { match self { - TendermintState::CommitTimedout => true, + TendermintState::CommitTimedout { + .. + } => true, _ => false, } } + + pub fn committed(&self) -> Option<(View, BlockHash)> { + match self { + TendermintState::Commit { + block_hash, + view, + } => Some((*view, *block_hash)), + TendermintState::CommitTimedout { + block_hash, + view, + } => Some((*view, *block_hash)), + TendermintState::Propose => None, + TendermintState::ProposeWaitBlockGeneration { + .. + } => None, + TendermintState::ProposeWaitImported { + .. + } => None, + TendermintState::ProposeWaitEmptyBlockTimer { + .. + } => None, + TendermintState::Prevote => None, + TendermintState::Precommit => None, + } + } } impl fmt::Debug for TendermintState { @@ -96,8 +138,14 @@ impl fmt::Debug for TendermintState { } => write!(f, "TendermintState::ProposeWaitEmptyBlockTimer({})", block.header().hash()), TendermintState::Prevote => write!(f, "TendermintState::Prevote"), TendermintState::Precommit => write!(f, "TendermintState::Precommit"), - TendermintState::Commit => write!(f, "TendermintState::Commit"), - TendermintState::CommitTimedout => write!(f, "TendermintState::CommitTimedout"), + TendermintState::Commit { + block_hash, + view, + } => write!(f, "TendermintState::Commit({}, {})", block_hash, view), + TendermintState::CommitTimedout { + block_hash, + view, + } => write!(f, "TendermintState::CommitTimedout({}, {})", block_hash, view), } } } diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 0252140c90..d54d34b67e 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -405,6 +405,10 @@ impl Worker { /// Check Tendermint can move from the commit step to the propose step fn can_move_from_commit_to_propose(&self) -> bool { + if !self.step.is_commit() { + return false + } + let vote_step = VoteStep::new(self.height, self.last_confirmed_view, Step::Precommit); if self.step.is_commit_timedout() && self.check_current_block_exists() { cinfo!(ENGINE, "Transition to Propose because best block is changed after commit timeout"); @@ -442,6 +446,20 @@ impl Worker { Some((proposal.signature, proposal.signer_index, bytes)) } + fn is_proposal_received(&self, height: Height, view: View, block_hash: BlockHash) -> bool { + let all_votes = self.votes.get_all_votes_in_round(&VoteStep { + height, + view, + step: Step::Propose, + }); + + if let Some(proposal) = all_votes.first() { + proposal.on.block_hash.expect("Proposal message always include block hash") == block_hash + } else { + false + } + } + pub fn vote_step(&self) -> VoteStep { VoteStep { height: self.height, @@ -592,6 +610,7 @@ impl Worker { self.votes_received = BitSet::new(); } + #[allow(clippy::cognitive_complexity)] fn move_to_step(&mut self, state: TendermintState, is_restoring: bool) { ctrace!(ENGINE, "Transition to {:?} triggered.", state); let prev_step = mem::replace(&mut self.step, state.clone()); @@ -707,6 +726,34 @@ impl Worker { } Step::Commit => { cinfo!(ENGINE, "move_to_step: Commit."); + let (view, block_hash) = state.committed().expect("commit always has committed_view"); + self.save_last_confirmed_view(view); + + let proposal_received = self.is_proposal_received(self.height, view, block_hash); + let proposal_imported = self.client().block(&block_hash.into()).is_some(); + let best_block_header = self.client().best_block_header(); + if best_block_header.number() >= self.height { + cwarn!( + ENGINE, + "best_block_header.number() >= self.height ({} >= {}) in Commit state", + best_block_header.number(), + self.height + ); + return + } + + let should_update_best_block = best_block_header.hash() != block_hash; + + cdebug!( + ENGINE, + "commited, proposal_received: {}, proposal_imported: {}, should_update_best_block: {}", + proposal_received, + proposal_imported, + should_update_best_block + ); + if proposal_imported && should_update_best_block { + self.client().update_best_as_committed(block_hash); + } } } } @@ -818,6 +865,32 @@ impl Worker { self.last_two_thirds_majority = TwoThirdsMajority::from_message(message.on.step.view, message.on.block_hash); } + + if vote_step.step == Step::Precommit + && self.height == vote_step.height + && message.on.block_hash.is_some() + && has_enough_aligned_votes + { + if self.can_move_from_commit_to_propose() { + let height = self.height; + self.move_to_height(height + 1); + self.move_to_step(TendermintState::Propose, is_restoring); + return + } + + let block_hash = message.on.block_hash.expect("Upper if already checked block hash"); + if !self.step.is_commit() { + self.move_to_step( + TendermintState::Commit { + block_hash, + view: vote_step.view, + }, + is_restoring, + ); + return + } + } + // Check if it can affect the step transition. if self.is_step(message) { let next_step = match self.step { @@ -825,21 +898,6 @@ impl Worker { self.increment_view(1); Some(TendermintState::Propose) } - TendermintState::Precommit if has_enough_aligned_votes => { - let bh = message.on.block_hash.expect("previous guard ensures is_some; qed"); - if self.client().block(&BlockId::Hash(bh)).is_some() { - // Commit the block, and update the last confirmed view - self.save_last_confirmed_view(message.on.step.view); - - // Update the best block hash as the hash of the committed block - self.client().update_best_as_committed(bh); - Some(TendermintState::Commit) - } else { - cwarn!(ENGINE, "Cannot find a proposal which committed"); - self.increment_view(1); - Some(TendermintState::Propose) - } - } // Avoid counting votes twice. TendermintState::Prevote if lock_change => Some(TendermintState::Precommit), TendermintState::Prevote if has_enough_aligned_votes => Some(TendermintState::Precommit), @@ -850,14 +908,6 @@ impl Worker { self.move_to_step(step, is_restoring); return } - } else if vote_step.step == Step::Precommit - && self.height == vote_step.height - && self.can_move_from_commit_to_propose() - { - let height = self.height; - self.move_to_height(height + 1); - self.move_to_step(TendermintState::Propose, is_restoring); - return } // self.move_to_step() calls self.broadcast_state() @@ -1227,18 +1277,27 @@ impl Worker { cinfo!(ENGINE, "Precommit timeout without enough votes."); TendermintState::Precommit } - TendermintState::Commit => { + TendermintState::Commit { + block_hash, + view, + } => { cinfo!(ENGINE, "Commit timeout."); - if !self.check_current_block_exists() { + if self.client().block(&block_hash.into()).is_none() { cwarn!(ENGINE, "Best chain is not updated yet, wait until imported"); - self.step = TendermintState::CommitTimedout; + self.step = TendermintState::CommitTimedout { + block_hash, + view, + }; return } + let height = self.height; self.move_to_height(height + 1); TendermintState::Propose } - TendermintState::CommitTimedout => unreachable!(), + TendermintState::CommitTimedout { + .. + } => unreachable!(), }; self.move_to_step(next_step, false); @@ -1439,6 +1498,24 @@ impl Worker { } }; + if self.step.is_commit() && (imported.len() + enacted.len() == 1) { + let (_, committed_block_hash) = self.step.committed().expect("Commit state always has block_hash"); + if imported.first() == Some(&committed_block_hash) { + cdebug!(ENGINE, "Committed block {} is committed_block_hash", committed_block_hash); + self.client().update_best_as_committed(committed_block_hash); + return + } + if enacted.first() == Some(&committed_block_hash) { + cdebug!(ENGINE, "Committed block {} is now the best block", committed_block_hash); + if self.can_move_from_commit_to_propose() { + let new_height = self.height + 1; + self.move_to_height(new_height); + self.move_to_step(TendermintState::Propose, false); + return + } + } + } + if !imported.is_empty() { let mut height_changed = false; for hash in imported { @@ -1463,11 +1540,6 @@ impl Worker { return } } - if !enacted.is_empty() && self.can_move_from_commit_to_propose() { - let new_height = self.height + 1; - self.move_to_height(new_height); - self.move_to_step(TendermintState::Propose, false) - } } fn send_proposal_block( From 297dcd4be0d98927997b99b0ff6b452ea53d8889 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Wed, 11 Sep 2019 12:08:23 +0900 Subject: [PATCH 009/105] Fix a step regression bug in Tendermint::worker::new_blocks A regression in the step can cause a node double-vote. --- core/src/consensus/tendermint/worker.rs | 29 ++++++++++++++++--------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index d54d34b67e..5e105dd23c 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -1516,17 +1516,24 @@ impl Worker { } } - if !imported.is_empty() { - let mut height_changed = false; + if let Some((last, rest)) = imported.split_last() { + let (imported, last_proposal_header) = { + let header = + c.block_header(&last.clone().into()).expect("ChainNotify is called after the block is imported"); + let full_header = header.decode(); + if self.is_proposal(full_header.number(), full_header.hash()) { + (rest, Some(full_header)) + } else { + (imported.as_slice(), None) + } + }; + let height_at_begin = self.height; for hash in imported { // New Commit received, skip to next height. - let header = c.block_header(&hash.into()).expect("ChainNotify is called after the block is imported"); - + let header = + c.block_header(&hash.clone().into()).expect("ChainNotify is called after the block is imported"); let full_header = header.decode(); - if self.is_proposal(full_header.number(), full_header.hash()) { - self.on_imported_proposal(&full_header); - } else if self.height < header.number() { - height_changed = true; + if self.height < header.number() { cinfo!(ENGINE, "Received a commit: {:?}.", header.number()); let prev_block_view = TendermintSealView::new(full_header.seal()) .previous_block_view() @@ -1535,9 +1542,11 @@ impl Worker { self.save_last_confirmed_view(prev_block_view); } } - if height_changed { + if height_at_begin != self.height { self.move_to_step(TendermintState::Propose, false); - return + } + if let Some(last_proposal_header) = last_proposal_header { + self.on_imported_proposal(&last_proposal_header); } } } From 5a1019527df71295132fa8ba184b6ea685ec50b5 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 11 Sep 2019 12:17:33 +0900 Subject: [PATCH 010/105] Add Commit message in Tendermint Before this commit, Tendermint extension only requests current height and view's votes. Handling only the current view's message makes code simple. However, there may be a commit before the current view. This creates a liveness problem. After this commit, a node requests a Commit message if some of its peer's height is higher than the node. The commit message is not related to the node's current view. The Commit message fixes the liveness problem. --- core/src/consensus/tendermint/message.rs | 89 ++++++++ core/src/consensus/tendermint/network.rs | 37 ++++ core/src/consensus/tendermint/worker.rs | 255 +++++++++++++++++++++++ 3 files changed, 381 insertions(+) diff --git a/core/src/consensus/tendermint/message.rs b/core/src/consensus/tendermint/message.rs index a0dd9b65ad..6e24147fc3 100644 --- a/core/src/consensus/tendermint/message.rs +++ b/core/src/consensus/tendermint/message.rs @@ -79,6 +79,8 @@ const MESSAGE_ID_PROPOSAL_BLOCK: u8 = 0x02; const MESSAGE_ID_STEP_STATE: u8 = 0x03; const MESSAGE_ID_REQUEST_MESSAGE: u8 = 0x04; const MESSAGE_ID_REQUEST_PROPOSAL: u8 = 0x05; +const MESSAGE_ID_REQUEST_COMMIT: u8 = 0x06; +const MESSAGE_ID_COMMIT: u8 = 0x07; #[derive(Debug, PartialEq)] pub enum TendermintMessage { @@ -102,6 +104,13 @@ pub enum TendermintMessage { height: Height, view: View, }, + RequestCommit { + height: Height, + }, + Commit { + block: Bytes, + votes: Vec, + }, } impl Encodable for TendermintMessage { @@ -160,6 +169,22 @@ impl Encodable for TendermintMessage { s.append(height); s.append(view); } + TendermintMessage::RequestCommit { + height, + } => { + s.begin_list(2); + s.append(&MESSAGE_ID_REQUEST_COMMIT); + s.append(height); + } + TendermintMessage::Commit { + block, + votes, + } => { + s.begin_list(3); + s.append(&MESSAGE_ID_COMMIT); + s.append(block); + s.append_list(votes); + } } } } @@ -253,6 +278,34 @@ impl Decodable for TendermintMessage { view, } } + MESSAGE_ID_REQUEST_COMMIT => { + let item_count = rlp.item_count()?; + if item_count != 2 { + return Err(DecoderError::RlpIncorrectListLen { + got: item_count, + expected: 2, + }) + } + let height = rlp.at(1)?.as_val()?; + TendermintMessage::RequestCommit { + height, + } + } + MESSAGE_ID_COMMIT => { + let item_count = rlp.item_count()?; + if item_count != 3 { + return Err(DecoderError::RlpIncorrectListLen { + got: item_count, + expected: 3, + }) + } + let block = rlp.at(1)?.as_val()?; + let votes = rlp.at(2)?.as_list()?; + TendermintMessage::Commit { + block, + votes, + } + } _ => return Err(DecoderError::Custom("Unknown message id detected")), }) } @@ -408,6 +461,42 @@ mod tests { }); } + #[test] + fn encode_and_decode_tendermint_message_6() { + rlp_encode_and_decode_test!(TendermintMessage::RequestCommit { + height: 3, + }); + } + + #[test] + fn encode_and_decode_tendermint_message_7() { + rlp_encode_and_decode_test!(TendermintMessage::Commit { + block: vec![1u8, 2u8], + votes: vec![ + ConsensusMessage { + signature: SchnorrSignature::random(), + signer_index: 0x1234, + on: VoteOn { + step: VoteStep::new(2, 3, Step::Commit), + block_hash: Some(H256::from( + "07feab4c39250abf60b77d7589a5b61fdf409bd837e936376381d19db1e1f050" + )), + }, + }, + ConsensusMessage { + signature: SchnorrSignature::random(), + signer_index: 0x1235, + on: VoteOn { + step: VoteStep::new(2, 3, Step::Commit), + block_hash: Some(H256::from( + "07feab4c39250abf60b77d7589a5b61fdf409bd837e936376381d19db1e1f050" + )), + }, + } + ] + }); + } + #[test] fn encode_and_decode_consensus_message_1() { let message = ConsensusMessage::default(); diff --git a/core/src/consensus/tendermint/network.rs b/core/src/consensus/tendermint/network.rs index 9d90702b28..05175fd636 100644 --- a/core/src/consensus/tendermint/network.rs +++ b/core/src/consensus/tendermint/network.rs @@ -352,6 +352,43 @@ impl NetworkExtension for TendermintExtension { self.send_votes(token, votes); } } + Ok(TendermintMessage::RequestCommit { + height, + }) => { + ctrace!(ENGINE, "Received RequestCommit for {} from {:?}", height, token); + let (result, receiver) = crossbeam::bounded(1); + self.inner + .send(worker::Event::RequestCommit { + height, + result, + }) + .unwrap(); + + if let Ok(message) = receiver.recv() { + ctrace!(ENGINE, "Send commit for {} to {:?}", height, token); + self.api.send(token, Arc::new(message)); + } + } + Ok(TendermintMessage::Commit { + block, + votes, + }) => { + ctrace!(ENGINE, "Received Commit from {:?}", token); + let (result, receiver) = crossbeam::bounded(1); + self.inner + .send(worker::Event::GetCommit { + block: block.clone(), + votes, + result, + }) + .unwrap(); + + if let Some(c) = receiver.recv().unwrap() { + if let Err(e) = c.import_block(block) { + cinfo!(ENGINE, "Failed to import committed block {:?}", e); + } + } + } _ => cinfo!(ENGINE, "Invalid message from peer {}", token), } } diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 5e105dd23c..3ac78a8c92 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -163,6 +163,15 @@ pub enum Event { requested: BitSet, result: crossbeam::Sender, }, + RequestCommit { + height: Height, + result: crossbeam::Sender, + }, + GetCommit { + block: Bytes, + votes: Vec, + result: crossbeam::Sender>>, + }, } impl Worker { @@ -342,6 +351,20 @@ impl Worker { }) => { inner.get_all_votes_and_authors(&vote_step, &requested, result); } + Ok(Event::RequestCommit { + height, + result + }) => { + inner.on_request_commit_message(height, result); + } + Ok(Event::GetCommit { + block, + votes, + result + }) => { + let client = inner.on_commit_message(block, votes); + result.send(client).unwrap(); + } Err(crossbeam::RecvError) => { cerror!(ENGINE, "The event channel for tendermint thread had been closed."); break @@ -1596,6 +1619,25 @@ impl Worker { result.send(message).unwrap(); } + fn send_request_commit(&self, token: &NodeId, height: Height, result: &crossbeam::Sender) { + ctrace!(ENGINE, "Request commit {} to {:?}", height, token); + let message = TendermintMessage::RequestCommit { + height, + } + .rlp_bytes() + .into_vec(); + result.send(message).unwrap(); + } + + fn send_commit(&self, block: encoded::Block, votes: Vec, result: &crossbeam::Sender) { + let message = TendermintMessage::Commit { + block: block.into_inner(), + votes, + }; + + result.send(message.rlp_bytes().into_vec()).unwrap(); + } + fn on_proposal_message( &mut self, signature: SchnorrSignature, @@ -1745,6 +1787,10 @@ impl Worker { return } + if self.height < peer_vote_step.height && !self.step.is_commit() { + self.send_request_commit(token, self.height, &result); + } + let peer_has_proposal = (self.view == peer_vote_step.view && peer_proposal.is_some()) || self.view < peer_vote_step.view || self.height < peer_vote_step.height; @@ -1851,6 +1897,215 @@ impl Worker { } } } + + fn on_request_commit_message(&self, height: Height, result: crossbeam::Sender) { + if height >= self.height { + return + } + + if height == self.height - 1 { + let block = self.client().block(&height.into()).expect("Parent block should exist"); + let block_hash = block.hash(); + let seal = block.seal(); + let view = TendermintSealView::new(&seal).consensus_view().expect("Block is already verified and imported"); + + let votes = self + .votes + .get_all_votes_in_round(&VoteStep { + height, + view, + step: Step::Precommit, + }) + .into_iter() + .filter(|vote| vote.on.block_hash == Some(block_hash)) + .collect(); + + self.send_commit(block, votes, &result); + } else if height < self.height - 1 { + let block = self.client().block(&height.into()).expect("Parent block should exist"); + let child_block = self.client().block(&(height + 1).into()).expect("Parent block should exist"); + let child_block_header_seal = child_block.header().seal(); + let child_block_seal_view = TendermintSealView::new(&child_block_header_seal); + let view = child_block_seal_view.previous_block_view().expect("Verified block"); + let on = VoteOn { + step: VoteStep::new(height, view, Step::Precommit), + block_hash: Some(block.hash()), + }; + let mut votes = Vec::new(); + for (index, signature) in child_block_seal_view.signatures().expect("The block is verified") { + let message = ConsensusMessage { + signature, + signer_index: index, + on: on.clone(), + }; + votes.push(message); + } + + self.send_commit(block, votes, &result); + } + } + + #[allow(clippy::cognitive_complexity)] + fn on_commit_message(&mut self, block: Bytes, votes: Vec) -> Option> { + if self.step.is_commit() { + return None + } + let block_hash = { + let block_view = BlockView::new(&block); + block_view.hash() + }; + + if votes.is_empty() { + cwarn!(ENGINE, "Invalid commit message received: precommits are empty",); + return None + } + + let first_vote = &votes[0]; + let commit_vote_on = first_vote.on.clone(); + let commit_height = first_vote.height(); + let commit_view = first_vote.on.step.view; + let commit_block_hash = match &first_vote.on.block_hash { + Some(block_hash) => *block_hash, + None => { + cwarn!(ENGINE, "Invalid commit message-{} received: precommit nil", commit_height); + return None + } + }; + + if commit_block_hash != block_hash { + cwarn!( + ENGINE, + "Invalid commit message-{} received: block_hash {} is different from precommit's block_hash {}", + commit_height, + block_hash, + commit_block_hash, + ); + return None + } + + if commit_height < self.height { + cdebug!( + ENGINE, + "Received commit message is old. Current height is {} but commit messages is for height {}", + self.height, + commit_height, + ); + return None + } else if commit_height > self.height { + cwarn!( + ENGINE, + "Invalid commit message received: precommit on height {} but current height is {}", + commit_height, + self.height + ); + return None + } + + let prev_block_hash = self + .client() + .block_header(&(self.height - 1).into()) + .expect("self.height - 1 == the best block number") + .hash(); + + if commit_vote_on.step.step != Step::Precommit { + cwarn!( + ENGINE, + "Invalid commit message-{} received: vote is not precommit but {:?}", + commit_height, + commit_vote_on.step.step + ); + return None + } + + let mut vote_bitset = BitSet::new(); + + for vote in &votes { + let signer_index = vote.signer_index; + + if vote.on != commit_vote_on { + cwarn!( + ENGINE, + "Invalid commit message received: One precommit on {:?}, other precommit on {:?}", + commit_vote_on, + vote.on + ); + return None + } + + if signer_index >= self.validators.count(&prev_block_hash) { + cwarn!( + ENGINE, + "Invalid commit message-{} received: invalid signer index {}", + commit_height, + signer_index + ); + return None + } + + let sender_public = self.validators.get(&prev_block_hash, signer_index); + + match vote.verify(&sender_public) { + Err(err) => { + cwarn!( + ENGINE, + "Invalid commit message-{} received: invalid signature signer_index: {} address: {} internal error: {:?}", + commit_height, + signer_index, + public_to_address(&sender_public), + err + ); + return None + } + Ok(false) => { + cwarn!( + ENGINE, + "Invalid commit message-{} received: invalid signature signer_index: {} address: {}", + commit_height, + signer_index, + public_to_address(&sender_public) + ); + return None + } + Ok(true) => {} + } + vote_bitset.set(signer_index); + } + + if let Err(err) = self.validators.check_enough_votes(&prev_block_hash, &vote_bitset) { + cwarn!(ENGINE, "Invalid commit message-{} received: check_enough_votes failed: {:?}", commit_height, err); + return None + } + + cdebug!(ENGINE, "Commit message-{} is verified", commit_height); + for vote in votes { + if !self.votes.is_old_or_known(&vote) { + self.votes.vote(vote); + } + } + + // Since we don't have proposal vote, set proposal = None + self.proposal = Proposal::None; + self.view = commit_view; + self.votes_received = vote_bitset; + self.last_two_thirds_majority = TwoThirdsMajority::Empty; + + self.move_to_step( + TendermintState::Commit { + block_hash, + view: commit_view, + }, + false, + ); + + if self.client().block(&BlockId::Hash(block_hash)).is_some() { + cdebug!(ENGINE, "Committed block is already imported {}", block_hash); + None + } else { + cdebug!(ENGINE, "Committed block is not imported yet {}", block_hash); + let c = self.client.upgrade()?; + Some(c) + } + } } fn calculate_score(height: Height, view: View) -> U256 { From ba6f3bca3f64b076735b00a23b8073d67d69e29f Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 11 Sep 2019 12:19:32 +0900 Subject: [PATCH 011/105] Do not request proposal to peers if the current state is Commit --- core/src/consensus/tendermint/worker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 3ac78a8c92..a9daf5ee85 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -492,7 +492,7 @@ impl Worker { } pub fn need_proposal(&self) -> bool { - self.proposal.is_none() + self.proposal.is_none() && !self.step.is_commit() } pub fn get_all_votes_and_authors( From f8e236d0ebba9d8717bf52c09de1d739fd5bf663 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 11 Sep 2019 12:20:03 +0900 Subject: [PATCH 012/105] Make step transition log verbose --- core/src/consensus/tendermint/worker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index a9daf5ee85..78df782f68 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -635,7 +635,7 @@ impl Worker { #[allow(clippy::cognitive_complexity)] fn move_to_step(&mut self, state: TendermintState, is_restoring: bool) { - ctrace!(ENGINE, "Transition to {:?} triggered.", state); + ctrace!(ENGINE, "Transition to {:?} triggered from {:?}.", state, self.step); let prev_step = mem::replace(&mut self.step, state.clone()); if !is_restoring { self.backup(); From 8193aebfe8824e9b52017816b8842a56f82f2ba6 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Thu, 12 Sep 2019 04:24:48 +0900 Subject: [PATCH 013/105] Fix possible regression issue caused by `ProposeWaitEmptyBlockTimer` Possible scenario: * Schedule timeout for `ProposeWaitEmptyBlockTimer` on height: n * On timeout, timer loop queues a call to `Tendermint::on_timeout` on the timer worker * Blocks are imported at the same time with the timeout. * Block importer holds lock for Tendermint, calls `new_blocks` * The worker checks whether it is cancelled, but it is not cancelled yet. * The worker waits for the lock. * several `move_to_height`, `move_to_step` are called by new_blocks * height is not n anymore. * `move_to_step` clears timer, but the check is already passed and the worker waits for the lock. * It finally releases the lock. * The waiting worker calls Tendermint::on_timeout and the timeout for `ProposeWaitEmptyBlockTimer` calls `move_to_step(Prevote)` * The timeout was set for the height n, but the code in the timeout reads changed height. --- core/src/consensus/tendermint/worker.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 78df782f68..a71b069ac0 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -1232,8 +1232,15 @@ impl Worker { TendermintState::ProposeWaitEmptyBlockTimer { block, } => { - cdebug!(ENGINE, "Empty proposal timer is finished, go to the prevote step and broadcast the block"); - self.submit_proposal_block(block.as_ref()); + if self.height == block.header().number() { + cdebug!( + ENGINE, + "Empty proposal timer is finished, go to the prevote step and broadcast the block" + ); + self.submit_proposal_block(block.as_ref()); + } else { + cwarn!(ENGINE, "Empty proposal timer was for previous height."); + } } _ => { cwarn!(ENGINE, "Empty proposal timer was not cleared."); From 110e2de9479aa63ce9775e93f435081f6c99c935 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Mon, 23 Sep 2019 12:20:23 +0900 Subject: [PATCH 014/105] Remove compose and decompose transaction --- core/src/codechain_machine.rs | 6 - rpc/src/v1/impls/chain.rs | 2 - rpc/src/v1/types/action.rs | 127 ------- state/src/impls/shard_level.rs | 578 +----------------------------- state/src/impls/test_helper.rs | 25 -- state/src/impls/top_level.rs | 8 - test/src/e2e/verification.test.ts | 4 - test/src/helper/spawn.ts | 7 +- types/src/common_params.rs | 7 +- types/src/errors/runtime_error.rs | 77 +--- types/src/errors/syntax_error.rs | 58 +-- types/src/transaction/action.rs | 209 +---------- types/src/transaction/shard.rs | 221 +----------- 13 files changed, 28 insertions(+), 1301 deletions(-) diff --git a/core/src/codechain_machine.rs b/core/src/codechain_machine.rs index 751ec92d9c..d75ccf3361 100644 --- a/core/src/codechain_machine.rs +++ b/core/src/codechain_machine.rs @@ -203,12 +203,6 @@ impl CodeChainMachine { Action::IncreaseAssetSupply { .. } => params.min_asset_supply_increase_cost(), - Action::ComposeAsset { - .. - } => params.min_asset_compose_cost(), - Action::DecomposeAsset { - .. - } => params.min_asset_decompose_cost(), Action::UnwrapCCC { .. } => params.min_asset_unwrap_ccc_cost(), diff --git a/rpc/src/v1/impls/chain.rs b/rpc/src/v1/impls/chain.rs index 4d0001fbb8..addac3d980 100644 --- a/rpc/src/v1/impls/chain.rs +++ b/rpc/src/v1/impls/chain.rs @@ -288,8 +288,6 @@ where "store" => Some(common_parameters.min_store_transaction_cost()), "remove" => Some(common_parameters.min_remove_transaction_cost()), "custom" => Some(common_parameters.min_custom_transaction_cost()), - "composeAsset" => Some(common_parameters.min_asset_compose_cost()), - "decomposeAsset" => Some(common_parameters.min_asset_decompose_cost()), _ => None, }) diff --git a/rpc/src/v1/types/action.rs b/rpc/src/v1/types/action.rs index cc1dc075f4..4552c2a448 100644 --- a/rpc/src/v1/types/action.rs +++ b/rpc/src/v1/types/action.rs @@ -78,27 +78,6 @@ pub enum Action { approvals: Vec, }, #[serde(rename_all = "camelCase")] - ComposeAsset { - network_id: NetworkId, - shard_id: ShardId, - metadata: String, - approver: Option, - registrar: Option, - allowed_script_hashes: Vec, - inputs: Vec, - output: Box, - - approvals: Vec, - }, - #[serde(rename_all = "camelCase")] - DecomposeAsset { - network_id: NetworkId, - input: Box, - outputs: Vec, - - approvals: Vec, - }, - #[serde(rename_all = "camelCase")] UnwrapCCC { network_id: NetworkId, burn: AssetTransferInput, @@ -207,31 +186,7 @@ pub enum ActionWithTracker { tracker: H256, }, - #[serde(rename_all = "camelCase")] - ComposeAsset { - network_id: NetworkId, - shard_id: ShardId, - metadata: String, - approver: Option, - registrar: Option, - allowed_script_hashes: Vec, - inputs: Vec, - output: Box, - approvals: Vec, - - tracker: H256, - }, - #[serde(rename_all = "camelCase")] - DecomposeAsset { - network_id: NetworkId, - input: Box, - outputs: Vec, - - approvals: Vec, - - tracker: H256, - }, #[serde(rename_all = "camelCase")] UnwrapCCC { network_id: NetworkId, @@ -367,40 +322,6 @@ impl ActionWithTracker { approvals, tracker: tracker.unwrap(), }, - ActionType::ComposeAsset { - network_id, - shard_id, - metadata, - approver, - registrar, - allowed_script_hashes, - inputs, - output, - approvals, - } => ActionWithTracker::ComposeAsset { - network_id, - shard_id, - metadata, - approver: approver.map(|approver| PlatformAddress::new_v1(network_id, approver)), - registrar: registrar.map(|registrar| PlatformAddress::new_v1(network_id, registrar)), - allowed_script_hashes, - inputs: inputs.into_iter().map(From::from).collect(), - output: Box::new((*output).into()), - approvals, - tracker: tracker.unwrap(), - }, - ActionType::DecomposeAsset { - network_id, - input, - outputs, - approvals, - } => ActionWithTracker::DecomposeAsset { - network_id, - input: Box::new(input.into()), - outputs: outputs.into_iter().map(From::from).collect(), - approvals, - tracker: tracker.unwrap(), - }, ActionType::UnwrapCCC { network_id, burn, @@ -597,54 +518,6 @@ impl TryFrom for ActionType { approvals, } } - Action::ComposeAsset { - network_id, - shard_id, - metadata, - approver, - registrar, - allowed_script_hashes, - inputs, - output, - - approvals, - } => { - let approver = match approver { - Some(approver) => Some(approver.try_into_address()?), - None => None, - }; - let registrar = match registrar { - Some(registrar) => Some(registrar.try_into_address()?), - None => None, - }; - let output_content = AssetMintOutputType::try_from(*output)?; - ActionType::ComposeAsset { - network_id, - shard_id, - metadata, - approver, - registrar, - allowed_script_hashes, - inputs: inputs.into_iter().map(From::from).collect(), - output: Box::new(output_content), - approvals, - } - } - Action::DecomposeAsset { - network_id, - input, - outputs, - - approvals, - } => { - let outputs = outputs.into_iter().map(TryFrom::try_from).collect::>()?; - ActionType::DecomposeAsset { - network_id, - input: (*input).into(), - outputs, - approvals, - } - } Action::UnwrapCCC { network_id, burn, diff --git a/state/src/impls/shard_level.rs b/state/src/impls/shard_level.rs index 6d2cab86de..48da78ff47 100644 --- a/state/src/impls/shard_level.rs +++ b/state/src/impls/shard_level.rs @@ -15,7 +15,7 @@ // along with this program. If not, see . use std::cell::{RefCell, RefMut}; -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; use std::iter::{once, FromIterator}; use ccrypto::{Blake, BLAKE_NULL_RLP}; @@ -186,45 +186,6 @@ impl<'db> ShardLevelState<'db> { assert_eq!(*shard_id, self.shard_id); self.increase_asset_supply(transaction.tracker(), *seq, sender, approvers, asset_type, output) } - ShardTransaction::ComposeAsset { - metadata, - approver, - registrar, - allowed_script_hashes, - inputs, - output, - shard_id, - .. - } => self.compose_asset( - &transaction, - metadata, - approver, - registrar, - allowed_script_hashes, - inputs, - output, - sender, - approvers, - shard_users, - *shard_id, - client, - parent_block_number, - parent_block_timestamp, - ), - ShardTransaction::DecomposeAsset { - input, - outputs, - .. - } => self.decompose_asset( - &transaction, - input, - outputs, - sender, - approvers, - client, - parent_block_number, - parent_block_timestamp, - ), ShardTransaction::UnwrapCCC { burn, .. @@ -699,201 +660,6 @@ impl<'db> ShardLevelState<'db> { }) } - // FIXME: Remove this clippy config - #[cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))] - fn compose_asset( - &mut self, - transaction: &ShardTransaction, - metadata: &str, - approver: &Option
, - registrar: &Option
, - allowed_script_hashes: &[H160], - inputs: &[AssetTransferInput], - output: &AssetMintOutput, - sender: &Address, - approvers: &[Address], - shard_users: &[Address], - output_shard_id: ShardId, - client: &C, - parent_block_number: BlockNumber, - parent_block_timestamp: u64, - ) -> StateResult<()> { - let mut sum: HashMap<(H160, ShardId), u64> = HashMap::new(); - - let mut deleted_assets = Vec::with_capacity(inputs.len()); - for input in inputs.iter() { - if input.prev_out.shard_id != self.shard_id { - continue - } - self.check_and_run_input_script( - input, - transaction, - None, - false, - sender, - approvers, - client, - parent_block_number, - parent_block_timestamp, - )?; - - assert_eq!(self.shard_id, input.prev_out.shard_id); - let shard_asset_type = (input.prev_out.asset_type, input.prev_out.shard_id); - let asset_scheme = - self.asset_scheme(shard_asset_type.0)?.ok_or_else(|| RuntimeError::AssetSchemeNotFound { - shard_id: input.prev_out.shard_id, - asset_type: input.prev_out.asset_type, - })?; - if asset_scheme.is_regulated() { - return Err(RuntimeError::CannotComposeRegulatedAsset.into()) - } - - self.kill_asset(input.prev_out.tracker, input.prev_out.index); - deleted_assets.push((input.prev_out.tracker, input.prev_out.index, input.prev_out.quantity)); - - *sum.entry(shard_asset_type).or_insert_with(Default::default) += input.prev_out.quantity; - } - ctrace!(TX, "Deleted assets {:?}", deleted_assets); - - let pool = sum.into_iter().map(|((asset_type, _), quantity)| Asset::new(asset_type, quantity)).collect(); - - if output_shard_id == self.shard_id { - self.mint_asset( - transaction.tracker(), - metadata, - output, - approver, - approvers, - registrar, - allowed_script_hashes, - sender, - shard_users, - pool, - )?; - } - Ok(()) - } - - fn decompose_asset( - &mut self, - transaction: &ShardTransaction, - input: &AssetTransferInput, - outputs: &[AssetTransferOutput], - sender: &Address, - approvers: &[Address], - client: &C, - parent_block_number: BlockNumber, - parent_block_timestamp: u64, - ) -> StateResult<()> { - let AssetOutPoint { - asset_type, - shard_id, - quantity, - .. - } = input.prev_out; - if self.shard_id == input.prev_out.shard_id { - let asset_scheme = self.asset_scheme(asset_type)?.ok_or_else(|| RuntimeError::AssetSchemeNotFound { - shard_id, - asset_type, - })?; - // The input asset should be composed asset - if asset_scheme.pool().is_empty() { - return Err(RuntimeError::InvalidDecomposedInput { - asset_type, - shard_id, - got: 0, - } - .into()) - } - - // Check that the outputs are match with pool - let mut sum: HashMap = HashMap::new(); - for output in outputs { - let output_type = output.asset_type; - - *sum.entry(output_type).or_insert_with(Default::default) += output.quantity; - } - for asset in asset_scheme.pool() { - let asset_type = asset.asset_type(); - match sum.remove(asset_type) { - None => { - return Err(RuntimeError::InvalidDecomposedOutput { - asset_type: *asset_type, - shard_id: self.shard_id, - expected: asset.quantity(), - got: 0, - } - .into()) - } - Some(value) => { - if value != asset.quantity() { - return Err(RuntimeError::InvalidDecomposedOutput { - asset_type: *asset_type, - shard_id: self.shard_id, - expected: asset.quantity(), - got: value, - } - .into()) - } - } - } - } - if !sum.is_empty() { - let mut invalid_assets: Vec = - sum.into_iter().map(|(asset_type, quantity)| Asset::new(asset_type, quantity)).collect(); - let invalid_asset = invalid_assets.pop().unwrap(); - return Err(RuntimeError::InvalidDecomposedOutput { - asset_type: *invalid_asset.asset_type(), - shard_id: self.shard_id, - expected: 0, - got: invalid_asset.quantity(), - } - .into()) - } - - self.check_and_run_input_script( - input, - transaction, - None, - false, - sender, - approvers, - client, - parent_block_number, - parent_block_timestamp, - )?; - - self.kill_asset(input.prev_out.tracker, input.prev_out.index); - - let mut asset_scheme = self.get_asset_scheme_mut(self.shard_id, asset_type)?; - let previous_supply = asset_scheme.reduce_supply(quantity); - - ctrace!(TX, "Deleted assets {:?} {:?}", asset_type, quantity); - ctrace!(TX, "Reduced asset supply {:?} {:?} {:?}", asset_type, previous_supply, quantity); - } - - // Put asset into DB - let transaction_tracker = transaction.tracker(); - for (index, output) in outputs.iter().enumerate() { - if output.shard_id != self.shard_id { - continue - } - self.check_output_script_hash(output, sender, approvers)?; - self.create_asset( - transaction_tracker, - index, - output.asset_type, - output.lock_script_hash, - output.parameters.clone(), - output.quantity, - None, - )?; - } - ctrace!(TX, "Created assets {}:{}:(0..{})", self.shard_id, transaction_tracker, outputs.len()); - - Ok(()) - } - fn wrap_ccc( &mut self, tx_hash: &H256, @@ -1772,348 +1538,6 @@ mod tests { ]); } - #[test] - fn mint_and_compose() { - let mut state_db = RefCell::new(get_temp_state_db()); - let mut shard_cache = ShardCache::default(); - let mut state = get_temp_shard_state(&mut state_db, SHARD_ID, &mut shard_cache); - let sender = address(); - - let metadata = "metadata".to_string(); - let lock_script_hash = H160::from("0xb042ad154a3359d276835c903587ebafefea22af"); - let amount = 30; - let mint = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata.clone()); - let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); - assert_eq!(Ok(()), state.apply(&mint, &sender, &[], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0) => { asset_type: asset_type, quantity: amount }) - ]); - - let random_lock_script_hash = H160::random(); - let compose = asset_compose!( - "composed".to_string(), - asset_transfer_inputs![(asset_out_point!(mint_tracker, 0, asset_type, 30), vec![0x30, 0x01])], - asset_mint_output!(random_lock_script_hash, supply: 1) - ); - let compose_tracker = compose.tracker(); - let composed_asset_type = Blake::blake(compose_tracker); - - assert_eq!(Ok(()), state.apply(&compose, &sender, &[], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0)), - (scheme: (composed_asset_type) => { metadata: "composed".to_string(), supply: 1, pool: [Asset::new(asset_type, amount)] }), - (asset: (compose_tracker, 0) => { asset_type: composed_asset_type, quantity: 1 }) - ]); - } - - #[test] - fn mint_and_compose_and_decompose() { - let mut state_db = RefCell::new(get_temp_state_db()); - let mut shard_cache = ShardCache::default(); - let mut state = get_temp_shard_state(&mut state_db, SHARD_ID, &mut shard_cache); - let sender = address(); - - let metadata = "metadata".to_string(); - let lock_script_hash = H160::from("0xb042ad154a3359d276835c903587ebafefea22af"); - let amount = 30; - let mint = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata.clone()); - let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); - assert_eq!(Ok(()), state.apply(&mint, &sender, &[], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0) => { asset_type: asset_type, quantity: amount }) - ]); - - let compose = asset_compose!( - "composed".to_string(), - asset_transfer_inputs![(asset_out_point!(mint_tracker, 0, asset_type, amount), vec![0x30, 0x01])], - asset_mint_output!(lock_script_hash, supply: 1) - ); - let compose_tracker = compose.tracker(); - let composed_asset_type = Blake::blake(compose_tracker); - - assert_eq!(Ok(()), state.apply(&compose, &sender, &[], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0)), - (scheme: (composed_asset_type) => { metadata: "composed".to_string(), supply: 1, pool: [Asset::new(asset_type, amount)] }), - (asset: (compose_tracker, 0) => { asset_type: composed_asset_type, quantity: 1 }) - ]); - - let random_lock_script_hash = H160::random(); - let decompose = asset_decompose!( - asset_transfer_input!(asset_out_point!(compose_tracker, 0, composed_asset_type, 1), vec![0x30, 0x01]), - asset_transfer_outputs![(random_lock_script_hash, asset_type, amount)] - ); - let decompose_tracker = decompose.tracker(); - - assert_eq!(Ok(()), state.apply(&decompose, &sender, &[], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0)), - (scheme: (composed_asset_type) => { metadata: "composed".to_string(), supply: 0, pool: [Asset::new(asset_type, amount)] }), - (asset: (compose_tracker, 0)), - (asset: (decompose_tracker, 0) => { asset_type: asset_type, quantity: amount }) - ]); - } - - #[test] - #[allow(clippy::cognitive_complexity)] - fn decompose_fail_invalid_input_different_asset_type() { - let mut state_db = RefCell::new(get_temp_state_db()); - let mut shard_cache = ShardCache::default(); - let mut state = get_temp_shard_state(&mut state_db, SHARD_ID, &mut shard_cache); - let sender = address(); - - let metadata = "metadata".to_string(); - let lock_script_hash = H160::from("0xb042ad154a3359d276835c903587ebafefea22af"); - let amount = 30; - let mint = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata.clone()); - let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); - - assert_eq!(Ok(()), state.apply(&mint, &sender, &[], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0) => { asset_type: asset_type, quantity: amount }) - ]); - - let mint2 = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), "invalid_asset".to_string()); - let mint2_tracker = mint2.tracker(); - let asset_type2 = Blake::blake(mint2_tracker); - - assert_eq!(Ok(()), state.apply(&mint2, &sender, &[], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0) => { asset_type: asset_type, quantity: amount }), - (scheme: (asset_type2) => { metadata: "invalid_asset".to_string(), supply: amount }), - (asset: (mint2_tracker, 0) => { asset_type: asset_type2, quantity: amount }) - ]); - - let compose = asset_compose!( - "composed".to_string(), - asset_transfer_inputs![(asset_out_point!(mint_tracker, 0, asset_type, amount), vec![0x30, 0x01])], - asset_mint_output!(lock_script_hash, supply: 1) - ); - let compose_tracker = compose.tracker(); - let composed_asset_type = Blake::blake(compose_tracker); - - assert_eq!(Ok(()), state.apply(&compose, &sender, &[], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0)), - (scheme: (asset_type2) => { metadata: "invalid_asset".to_string(), supply: amount }), - (asset: (mint2_tracker, 0) => { asset_type: asset_type2, quantity: amount }), - (scheme: (composed_asset_type) => { metadata: "composed".to_string(), supply: 1, pool: [Asset::new(asset_type, amount)] }), - (asset: (compose_tracker, 0) => { asset_type: composed_asset_type, quantity: 1 }) - ]); - - let random_lock_script_hash = H160::random(); - let decompose = asset_decompose!( - asset_transfer_input!(asset_out_point!(mint2_tracker, 0, asset_type2, 1), vec![0x30, 0x01]), - asset_transfer_outputs![(random_lock_script_hash, asset_type, amount)] - ); - - assert_eq!( - Err(StateError::Runtime(RuntimeError::InvalidDecomposedInput { - asset_type: asset_type2, - shard_id: SHARD_ID, - got: 0, - })), - state.apply(&decompose, &sender, &[], &[], &get_test_client(), 0, 0) - ); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0) ), - (scheme: (asset_type2) => { metadata: "invalid_asset".to_string(), supply: amount }), - (asset: (mint2_tracker, 0) => { asset_type: asset_type2, quantity: amount }), - (scheme: (composed_asset_type) => { metadata: "composed".to_string(), supply: 1, pool: [Asset::new(asset_type, amount)] }), - (asset: (compose_tracker, 0) => { asset_type: composed_asset_type, quantity: 1 }) - ]); - } - - #[test] - #[allow(clippy::cognitive_complexity)] - fn decompose_fail_invalid_output_insufficient_output() { - let mut state_db = RefCell::new(get_temp_state_db()); - let mut shard_cache = ShardCache::default(); - let mut state = get_temp_shard_state(&mut state_db, SHARD_ID, &mut shard_cache); - let sender = address(); - - let metadata = "metadata".to_string(); - let lock_script_hash = H160::from("0xb042ad154a3359d276835c903587ebafefea22af"); - let amount = 30; - let mint = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata.clone()); - let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); - - assert_eq!(Ok(()), state.apply(&mint, &sender, &[], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0) => { asset_type: asset_type, quantity: amount }) - ]); - - let mint2 = asset_mint!(asset_mint_output!(lock_script_hash, supply: 1), "invalid_asset".to_string()); - let mint2_tracker = mint2.tracker(); - let asset_type2 = Blake::blake(mint2_tracker); - - assert_eq!(Ok(()), state.apply(&mint2, &sender, &[], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0) => { asset_type: asset_type, quantity: amount }), - (scheme: (asset_type2) => { metadata: "invalid_asset".to_string(), supply: 1 }), - (asset: (mint2_tracker, 0) => { asset_type: asset_type2, quantity: 1 }) - ]); - - let compose = asset_compose!( - "composed".to_string(), - asset_transfer_inputs![ - (asset_out_point!(mint_tracker, 0, asset_type, amount), vec![0x30, 0x01]), - (asset_out_point!(mint2_tracker, 0, asset_type2, 1), vec![0x30, 0x01]), - ], - asset_mint_output!(lock_script_hash, supply: 1) - ); - let compose_tracker = compose.tracker(); - let composed_asset_type = Blake::blake(compose_tracker); - - assert_eq!(Ok(()), state.apply(&compose, &sender, &[], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0)), - (scheme: (asset_type2) => { metadata: "invalid_asset".to_string(), supply: 1 }), - (asset: (mint2_tracker, 0)), - (scheme: (composed_asset_type) => { metadata: "composed".to_string(), supply: 1 }), - (asset: (compose_tracker, 0) => { asset_type: composed_asset_type, quantity: 1 }) - ]); - - let random_lock_script_hash = H160::random(); - let decompose = asset_decompose!( - asset_transfer_input!(asset_out_point!(compose_tracker, 0, composed_asset_type, 1), vec![0x30, 0x01]), - asset_transfer_outputs![(random_lock_script_hash, asset_type, amount)] - ); - - assert_eq!( - Err(StateError::Runtime(RuntimeError::InvalidDecomposedOutput { - asset_type: asset_type2, - shard_id: SHARD_ID, - expected: 1, - got: 0, - })), - state.apply(&decompose, &sender, &[], &[], &get_test_client(), 0, 0) - ); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0)), - (scheme: (asset_type2) => { metadata: "invalid_asset".to_string(), supply: 1 }), - (asset: (mint2_tracker, 0)), - (scheme: (composed_asset_type) => { metadata: "composed".to_string(), supply: 1 }), - (asset: (compose_tracker, 0) => { asset_type: composed_asset_type, quantity: 1 }) - ]); - } - - - #[test] - #[allow(clippy::cognitive_complexity)] - fn decompose_fail_invalid_output_insufficient_amount() { - let mut state_db = RefCell::new(get_temp_state_db()); - let mut shard_cache = ShardCache::default(); - let mut state = get_temp_shard_state(&mut state_db, SHARD_ID, &mut shard_cache); - let sender = address(); - - let metadata = "metadata".to_string(); - let lock_script_hash = H160::from("0xb042ad154a3359d276835c903587ebafefea22af"); - let amount = 30; - let mint = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata.clone()); - let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); - - assert_eq!(Ok(()), state.apply(&mint, &sender, &[], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0) => { asset_type: asset_type, quantity: amount }) - ]); - - let mint2 = asset_mint!(asset_mint_output!(lock_script_hash, supply: 1), "invalid_asset".to_string()); - let mint2_tracker = mint2.tracker(); - let asset_type2 = Blake::blake(mint2_tracker); - assert_eq!(Ok(()), state.apply(&mint2, &sender, &[], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0) => { asset_type: asset_type, quantity: amount }), - (scheme: (asset_type2) => { metadata: "invalid_asset".to_string(), supply: 1 }), - (asset: (mint2_tracker, 0) => { asset_type: asset_type2, quantity: 1 }) - ]); - - let compose = asset_compose!( - "composed".to_string(), - asset_transfer_inputs![ - (asset_out_point!(mint_tracker, 0, asset_type, amount), vec![0x30, 0x01]), - (asset_out_point!(mint2_tracker, 0, asset_type2, 1), vec![0x30, 0x01]), - ], - asset_mint_output!(lock_script_hash, supply: 1) - ); - let compose_tracker = compose.tracker(); - let composed_asset_type = Blake::blake(compose_tracker); - - assert_eq!(Ok(()), state.apply(&compose, &sender, &[], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0)), - (scheme: (asset_type2) => { metadata: "invalid_asset".to_string(), supply: 1 }), - (asset: (mint2_tracker, 0)), - (scheme: (composed_asset_type) => { metadata: "composed".to_string(), supply: 1 }), - (asset: (compose_tracker, 0) => { asset_type: composed_asset_type, quantity: 1 }) - ]); - - let random_lock_script_hash = H160::random(); - let decompose = asset_decompose!( - asset_transfer_input!(asset_out_point!(compose_tracker, 0, composed_asset_type, 1), vec![0x30, 0x01]), - asset_transfer_outputs![ - (random_lock_script_hash, asset_type, 10), - (random_lock_script_hash, asset_type2, 1), - ] - ); - - assert_eq!( - Err(StateError::Runtime(RuntimeError::InvalidDecomposedOutput { - asset_type, - shard_id: SHARD_ID, - expected: 30, - got: 10, - })), - state.apply(&decompose, &sender, &[], &[], &get_test_client(), 0, 0) - ); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0)), - (scheme: (asset_type2) => { metadata: "invalid_asset".to_string(), supply: 1 }), - (asset: (mint2_tracker, 0)), - (scheme: (composed_asset_type) => { metadata: "composed".to_string(), supply: 1 }), - (asset: (compose_tracker, 0) => { asset_type: composed_asset_type, quantity: 1 }) - ]); - } - #[test] fn wrap_and_unwrap_ccc() { let sender = address(); diff --git a/state/src/impls/test_helper.rs b/state/src/impls/test_helper.rs index a1e2990183..cfe4999226 100644 --- a/state/src/impls/test_helper.rs +++ b/state/src/impls/test_helper.rs @@ -324,31 +324,6 @@ macro_rules! order_on_transfer { } } -macro_rules! asset_compose { - ($metadata:expr, $inputs:expr, $outputs:expr) => { - $crate::ctypes::transaction::ShardTransaction::ComposeAsset { - network_id: $crate::impls::test_helper::NETWORK_ID.into(), - shard_id: $crate::impls::test_helper::SHARD_ID, - metadata: $metadata, - approver: None, - registrar: None, - allowed_script_hashes: vec![], - inputs: $inputs, - output: $outputs, - } - }; -} - -macro_rules! asset_decompose { - ($input:expr, $outputs:expr) => { - $crate::ctypes::transaction::ShardTransaction::DecomposeAsset { - network_id: $crate::impls::test_helper::NETWORK_ID.into(), - input: $input, - outputs: $outputs, - } - }; -} - macro_rules! asset_wrap_ccc_output { ($lock_script_hash:expr, $quantity:expr) => { $crate::ctypes::transaction::AssetWrapCCCOutput { diff --git a/state/src/impls/top_level.rs b/state/src/impls/top_level.rs index 725c290645..53c46cd04a 100644 --- a/state/src/impls/top_level.rs +++ b/state/src/impls/top_level.rs @@ -430,14 +430,6 @@ impl TopLevelState { Action::TransferAsset { approvals, .. - } - | Action::ComposeAsset { - approvals, - .. - } - | Action::DecomposeAsset { - approvals, - .. } => { let transaction = Option::::from(action.clone()).expect("It's a shard transaction"); debug_assert_eq!(network_id, transaction.network_id()); diff --git a/test/src/e2e/verification.test.ts b/test/src/e2e/verification.test.ts index 349d90f59b..8e78b9a00a 100644 --- a/test/src/e2e/verification.test.ts +++ b/test/src/e2e/verification.test.ts @@ -150,10 +150,6 @@ describe("solo - 1 node", function() { { actionType: 0x14, actionLength: 10 }, { actionType: 0x15, actionLength: 9 }, // ChangeAssetScheme { actionType: 0x15, actionLength: 11 }, - { actionType: 0x16, actionLength: 11 }, // ComposeAsset - { actionType: 0x16, actionLength: 13 }, - { actionType: 0x17, actionLength: 4 }, // DecomposeAsset - { actionType: 0x17, actionLength: 6 }, { actionType: 0x18, actionLength: 8 }, // IncreaseAssetSupply { actionType: 0x18, actionLength: 10 } ].forEach(function(params: { diff --git a/test/src/helper/spawn.ts b/test/src/helper/spawn.ts index a3e2ff2d03..a2919bb290 100644 --- a/test/src/helper/spawn.ts +++ b/test/src/helper/spawn.ts @@ -21,8 +21,6 @@ import { Asset, AssetAddress, AssetTransferInput, - ComposeAsset, - DecomposeAsset, H256, PlatformAddress, SignedTransaction, @@ -612,10 +610,7 @@ export default class CodeChain { return tx.getMintedAsset(); } - public async signTransactionInput( - tx: TransferAsset | ComposeAsset | DecomposeAsset, - index: number - ) { + public async signTransactionInput(tx: TransferAsset, index: number) { const keyStore = await this.sdk.key.createLocalKeyStore( this.localKeyStorePath ); diff --git a/types/src/common_params.rs b/types/src/common_params.rs index a1cba07c97..06e787483e 100644 --- a/types/src/common_params.rs +++ b/types/src/common_params.rs @@ -45,7 +45,9 @@ pub struct CommonParams { min_asset_transfer_cost: u64, min_asset_scheme_change_cost: u64, min_asset_supply_increase_cost: u64, + /// Deprecated min_asset_compose_cost: u64, + /// Deprecated min_asset_decompose_cost: u64, min_asset_unwrap_ccc_cost: u64, /// Maximum size of block body. @@ -122,9 +124,11 @@ impl CommonParams { pub fn min_asset_supply_increase_cost(&self) -> u64 { self.min_asset_supply_increase_cost } + #[deprecated] pub fn min_asset_compose_cost(&self) -> u64 { self.min_asset_compose_cost } + #[deprecated] pub fn min_asset_decompose_cost(&self) -> u64 { self.min_asset_decompose_cost } @@ -261,7 +265,8 @@ impl From for CommonParams { impl From for Params { fn from(p: CommonParams) -> Params { - let mut result = Params { + #[allow(deprecated)] + let mut result: Params = Params { max_extra_data_size: p.max_extra_data_size().into(), max_asset_scheme_metadata_size: p.max_asset_scheme_metadata_size().into(), max_transfer_metadata_size: p.max_transfer_metadata_size().into(), diff --git a/types/src/errors/runtime_error.rs b/types/src/errors/runtime_error.rs index 5ba8a1dd17..056fc464d9 100644 --- a/types/src/errors/runtime_error.rs +++ b/types/src/errors/runtime_error.rs @@ -50,7 +50,6 @@ pub enum Error { }, AssetSupplyOverflow, CannotBurnRegulatedAsset, - CannotComposeRegulatedAsset, FailedToHandleCustomAction(String), /// Script execution result is `Fail` FailedToUnlock { @@ -80,17 +79,6 @@ pub enum Error { index: usize, mismatch: Mismatch, }, - InvalidDecomposedInput { - asset_type: H160, - shard_id: ShardId, - got: u64, - }, - InvalidDecomposedOutput { - asset_type: H160, - shard_id: ShardId, - expected: u64, - got: u64, - }, /// Errors on orders: origin_outputs of order is not satisfied. InvalidOriginOutputs(H256), /// Failed to decode script. @@ -127,15 +115,18 @@ const ERROR_ID_ASSET_NOT_FOUND: u8 = 1; const ERROR_ID_ASSET_SCHEME_DUPLICATED: u8 = 2; const ERROR_ID_ASSET_SCHEME_NOT_FOUND: u8 = 3; const ERROR_ID_CANNOT_BURN_REGULATED_ASSET: u8 = 4; -const ERROR_ID_CANNOT_COMPOSE_REGULATED_ASSET: u8 = 5; +/// Deprecated +//const ERROR_ID_CANNOT_COMPOSE_REGULATED_ASSET: u8 = 5; const ERROR_ID_FAILED_TO_UNLOCK: u8 = 6; const ERROR_ID_INVALID_SEQ_OF_ASSET_SCHEME: u8 = 7; const ERROR_ID_INSUFFICIENT_BALANCE: u8 = 8; const ERROR_ID_INSUFFICIENT_PERMISSION: u8 = 9; const ERROR_ID_INVALID_ASSET_QUANTITY: u8 = 10; const ERROR_ID_UNEXPECTED_ASSET_TYPE: u8 = 11; -const ERROR_ID_INVALID_DECOMPOSED_INPUT: u8 = 13; -const ERROR_ID_INVALID_DECOMPOSED_OUTPUT: u8 = 14; +/// Deprecated +//const ERROR_ID_INVALID_DECOMPOSED_INPUT: u8 = 13; +/// Deprecated +//const ERROR_ID_INVALID_DECOMPOSED_OUTPUT: u8 = 14; const ERROR_ID_INVALID_SHARD_ID: u8 = 15; const ERROR_ID_INVALID_TRANSFER_DESTINATION: u8 = 16; const ERROR_ID_NEW_OWNERS_MUST_CONTAIN_SENDER: u8 = 17; @@ -169,15 +160,12 @@ impl TaggedRlp for RlpHelper { ERROR_ID_INVALID_SEQ_OF_ASSET_SCHEME => 5, ERROR_ID_ASSET_SUPPLY_OVERFLOW => 1, ERROR_ID_CANNOT_BURN_REGULATED_ASSET => 1, - ERROR_ID_CANNOT_COMPOSE_REGULATED_ASSET => 1, ERROR_ID_FAILED_TO_HANDLE_CUSTOM_ACTION => 2, ERROR_ID_FAILED_TO_UNLOCK => 5, ERROR_ID_INSUFFICIENT_BALANCE => 4, ERROR_ID_INSUFFICIENT_PERMISSION => 1, ERROR_ID_INVALID_ASSET_QUANTITY => 6, ERROR_ID_UNEXPECTED_ASSET_TYPE => 3, - ERROR_ID_INVALID_DECOMPOSED_INPUT => 4, - ERROR_ID_INVALID_DECOMPOSED_OUTPUT => 5, ERROR_ID_INVALID_ORIGIN_OUTPUTS => 2, ERROR_ID_INVALID_SCRIPT => 1, ERROR_ID_INVALID_SEQ => 2, @@ -229,9 +217,6 @@ impl Encodable for Error { .append(actual), Error::AssetSupplyOverflow => RlpHelper::new_tagged_list(s, ERROR_ID_ASSET_SUPPLY_OVERFLOW), Error::CannotBurnRegulatedAsset => RlpHelper::new_tagged_list(s, ERROR_ID_CANNOT_BURN_REGULATED_ASSET), - Error::CannotComposeRegulatedAsset => { - RlpHelper::new_tagged_list(s, ERROR_ID_CANNOT_COMPOSE_REGULATED_ASSET) - } Error::FailedToHandleCustomAction(detail) => { RlpHelper::new_tagged_list(s, ERROR_ID_FAILED_TO_HANDLE_CUSTOM_ACTION).append(detail) } @@ -270,24 +255,6 @@ impl Encodable for Error { index, mismatch, } => RlpHelper::new_tagged_list(s, ERROR_ID_UNEXPECTED_ASSET_TYPE).append(index).append(mismatch), - Error::InvalidDecomposedInput { - asset_type, - shard_id, - got, - } => RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_DECOMPOSED_INPUT) - .append(asset_type) - .append(shard_id) - .append(got), - Error::InvalidDecomposedOutput { - asset_type, - shard_id, - expected, - got, - } => RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_DECOMPOSED_OUTPUT) - .append(asset_type) - .append(shard_id) - .append(expected) - .append(got), Error::InvalidOriginOutputs(addr) => { RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_ORIGIN_OUTPUTS).append(addr) } @@ -356,7 +323,6 @@ impl Decodable for Error { }, ERROR_ID_ASSET_SUPPLY_OVERFLOW => Error::AssetSupplyOverflow, ERROR_ID_CANNOT_BURN_REGULATED_ASSET => Error::CannotBurnRegulatedAsset, - ERROR_ID_CANNOT_COMPOSE_REGULATED_ASSET => Error::CannotComposeRegulatedAsset, ERROR_ID_FAILED_TO_HANDLE_CUSTOM_ACTION => Error::FailedToHandleCustomAction(rlp.val_at(1)?), ERROR_ID_FAILED_TO_UNLOCK => Error::FailedToUnlock { shard_id: rlp.val_at(1)?, @@ -381,17 +347,6 @@ impl Decodable for Error { index: rlp.val_at(1)?, mismatch: rlp.val_at(2)?, }, - ERROR_ID_INVALID_DECOMPOSED_INPUT => Error::InvalidDecomposedInput { - asset_type: rlp.val_at(1)?, - shard_id: rlp.val_at(2)?, - got: rlp.val_at(3)?, - }, - ERROR_ID_INVALID_DECOMPOSED_OUTPUT => Error::InvalidDecomposedOutput { - asset_type: rlp.val_at(1)?, - shard_id: rlp.val_at(2)?, - expected: rlp.val_at(3)?, - got: rlp.val_at(4)?, - }, ERROR_ID_INVALID_ORIGIN_OUTPUTS => Error::InvalidOriginOutputs(rlp.val_at(1)?), ERROR_ID_INVALID_SCRIPT => Error::InvalidScript, ERROR_ID_INVALID_SEQ => Error::InvalidSeq(rlp.val_at(1)?), @@ -443,7 +398,6 @@ impl Display for Error { } => write!(f, "Already used seq of asset scheme {}:{}. expected: {}, actual: {}", asset_type, shard_id, expected, actual), Error::AssetSupplyOverflow => write!(f, "Asset supply should not be overflowed"), Error::CannotBurnRegulatedAsset => write!(f, "Cannot burn the regulated asset"), - Error::CannotComposeRegulatedAsset => write!(f, "Cannot compose the regulated asset"), Error::FailedToHandleCustomAction(detail) => write!(f, "Cannot handle custom action: {}", detail), Error::FailedToUnlock { shard_id, @@ -469,25 +423,6 @@ impl Display for Error { shard_id, tracker, index, expected, got ), Error::UnexpectedAssetType{index, mismatch} => write!(f, "{}th input has an unexpected asset type: {}", index, mismatch), - Error::InvalidDecomposedInput { - asset_type, - shard_id, - got, - } => write!( - f, - "The inputs are not valid. The quantity of asset({}, shard #{}) input must be 1, but {}.", - asset_type, shard_id, got - ), - Error::InvalidDecomposedOutput { - asset_type, - shard_id, - expected, - got, - } => write!( - f, - "The decomposed output is not balid. The quantity of asset({}, shard #{}) must be {}, but {}.", - asset_type, shard_id, expected, got - ), Error::InvalidOriginOutputs(addr) => write!(f, "origin_outputs of order({}) is not satisfied", addr), Error::InvalidScript => write!(f, "Failed to decode script"), Error::InvalidSeq(mismatch) => write!(f, "Invalid transaction seq {}", mismatch), diff --git a/types/src/errors/syntax_error.rs b/types/src/errors/syntax_error.rs index 0a3163db4e..9d9ba40a70 100644 --- a/types/src/errors/syntax_error.rs +++ b/types/src/errors/syntax_error.rs @@ -32,9 +32,6 @@ pub enum Error { tracker: H256, index: usize, }, - /// AssetCompose requires at least 1 input. - EmptyInput, - EmptyOutput, EmptyShardOwners(ShardId), /// Returned when the sum of the transaction's inputs is different from the sum of outputs. InconsistentTransactionInOut, @@ -49,15 +46,7 @@ pub enum Error { }, /// AssetType format error InvalidAssetType(H160), - InvalidComposedOutputAmount { - got: u64, - }, InvalidCustomAction(String), - InvalidDecomposedInputAmount { - asset_type: H160, - shard_id: ShardId, - got: u64, - }, /// Invalid network ID given. InvalidNetworkId(NetworkId), /// invalid asset_quantity_from, asset_quantity_to because of ratio @@ -106,15 +95,17 @@ pub enum Error { } const ERORR_ID_DUPLICATED_PREVIOUS_OUTPUT: u8 = 1; -const ERROR_ID_EMPTY_INPUT: u8 = 2; -const ERROR_ID_EMPTY_OUTPUT: u8 = 3; +/// Deprecated +//const ERROR_ID_EMPTY_INPUT: u8 = 2; +//const ERROR_ID_EMPTY_OUTPUT: u8 = 3; const ERROR_ID_EMPTY_SHARD_OWNERS: u8 = 4; const ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT: u8 = 5; const ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT_WITH_ORDERS: u8 = 6; const ERROR_ID_INSUFFICIENT_FEE: u8 = 7; const ERROR_ID_INVALID_ASSET_TYPE: u8 = 8; -const ERROR_ID_INVALID_COMPOSED_OUTPUT_AMOUNT: u8 = 9; -const ERROR_ID_INVALID_DECOMPOSED_INPUT_AMOUNT: u8 = 10; +/// Deprecated +//const ERROR_ID_INVALID_COMPOSED_OUTPUT_AMOUNT: u8 = 9; +//const ERROR_ID_INVALID_DECOMPOSED_INPUT_AMOUNT: u8 = 10; const ERROR_ID_INVALID_NETWORK_ID: u8 = 11; const ERROR_ID_INVALID_ORDER_ASSET_QUANTITIES: u8 = 12; const ERROR_ID_INVALID_ORDER_ASSET_TYPES: u8 = 13; @@ -144,16 +135,12 @@ impl TaggedRlp for RlpHelper { fn length_of(tag: u8) -> Result { Ok(match tag { ERORR_ID_DUPLICATED_PREVIOUS_OUTPUT => 3, - ERROR_ID_EMPTY_INPUT => 1, - ERROR_ID_EMPTY_OUTPUT => 1, ERROR_ID_EMPTY_SHARD_OWNERS => 2, ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT => 1, ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT_WITH_ORDERS => 1, ERROR_ID_INSUFFICIENT_FEE => 3, ERROR_ID_INVALID_ASSET_TYPE => 2, - ERROR_ID_INVALID_COMPOSED_OUTPUT_AMOUNT => 2, ERROR_ID_INVALID_CUSTOM_ACTION => 2, - ERROR_ID_INVALID_DECOMPOSED_INPUT_AMOUNT => 4, ERROR_ID_INVALID_NETWORK_ID => 2, ERROR_ID_INVALID_ORDER_ASSET_QUANTITIES => 4, ERROR_ID_INVALID_ORDER_ASSET_TYPES => 1, @@ -186,8 +173,6 @@ impl Encodable for Error { tracker, index, } => RlpHelper::new_tagged_list(s, ERORR_ID_DUPLICATED_PREVIOUS_OUTPUT).append(tracker).append(index), - Error::EmptyInput => RlpHelper::new_tagged_list(s, ERROR_ID_EMPTY_INPUT), - Error::EmptyOutput => RlpHelper::new_tagged_list(s, ERROR_ID_EMPTY_OUTPUT), Error::EmptyShardOwners(shard_id) => { RlpHelper::new_tagged_list(s, ERROR_ID_EMPTY_SHARD_OWNERS).append(shard_id) } @@ -202,20 +187,9 @@ impl Encodable for Error { got, } => RlpHelper::new_tagged_list(s, ERROR_ID_INSUFFICIENT_FEE).append(minimal).append(got), Error::InvalidAssetType(addr) => RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_ASSET_TYPE).append(addr), - Error::InvalidComposedOutputAmount { - got, - } => RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_COMPOSED_OUTPUT_AMOUNT).append(got), Error::InvalidCustomAction(err) => { RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_CUSTOM_ACTION).append(err) } - Error::InvalidDecomposedInputAmount { - asset_type, - shard_id, - got, - } => RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_DECOMPOSED_INPUT_AMOUNT) - .append(asset_type) - .append(shard_id) - .append(got), Error::InvalidNetworkId(network_id) => { RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_NETWORK_ID).append(network_id) } @@ -276,8 +250,6 @@ impl Decodable for Error { tracker: rlp.val_at(1)?, index: rlp.val_at(2)?, }, - ERROR_ID_EMPTY_INPUT => Error::EmptyInput, - ERROR_ID_EMPTY_OUTPUT => Error::EmptyOutput, ERROR_ID_EMPTY_SHARD_OWNERS => Error::EmptyShardOwners(rlp.val_at(1)?), ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT => Error::InconsistentTransactionInOut, ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT_WITH_ORDERS => Error::InconsistentTransactionInOutWithOrders, @@ -286,15 +258,7 @@ impl Decodable for Error { got: rlp.val_at(2)?, }, ERROR_ID_INVALID_ASSET_TYPE => Error::InvalidAssetType(rlp.val_at(1)?), - ERROR_ID_INVALID_COMPOSED_OUTPUT_AMOUNT => Error::InvalidComposedOutputAmount { - got: rlp.val_at(1)?, - }, ERROR_ID_INVALID_CUSTOM_ACTION => Error::InvalidCustomAction(rlp.val_at(1)?), - ERROR_ID_INVALID_DECOMPOSED_INPUT_AMOUNT => Error::InvalidDecomposedInputAmount { - asset_type: rlp.val_at(1)?, - shard_id: rlp.val_at(2)?, - got: rlp.val_at(3)?, - }, ERROR_ID_INVALID_NETWORK_ID => Error::InvalidNetworkId(rlp.val_at(1)?), ERROR_ID_INVALID_ORDER_ASSET_QUANTITIES => Error::InvalidOrderAssetQuantities { from: rlp.val_at(1)?, @@ -343,8 +307,6 @@ impl Display for Error { tracker, index, } => write!(f, "The previous output of inputs/burns are duplicated: ({}, {})", tracker, index), - Error::EmptyInput => write!(f, "The input is empty"), - Error::EmptyOutput => writeln!(f, "The output is empty"), Error::EmptyShardOwners (shard_id) => write!(f, "Shard({}) must have at least one owner", shard_id), Error::InconsistentTransactionInOut => write!(f, "The sum of the transaction's inputs is different from the sum of the transaction's outputs"), Error::InconsistentTransactionInOutWithOrders => write!(f, "The transaction's input and output do not follow its orders"), @@ -353,15 +315,7 @@ impl Display for Error { got, } => write!(f, "Insufficient fee. Min={}, Given={}", minimal, got), Error::InvalidAssetType (addr) => write!(f, "Asset type is invalid: {}", addr), - Error::InvalidComposedOutputAmount { - got, - } => write!(f, "The composed output is note valid. The supply must be 1, but {}.", got), Error::InvalidCustomAction(err) => write!(f, "Invalid custom action: {}", err), - Error::InvalidDecomposedInputAmount { - asset_type, - shard_id, - got, - } => write!(f, "The inputs are not valid. The quantity of asset({}, shard #{}) input must be 1, but {}.", asset_type, shard_id, got), Error::InvalidNetworkId (network_id) => write!(f, "{} is an invalid network id", network_id), Error::InvalidOrderAssetQuantities { from, diff --git a/types/src/transaction/action.rs b/types/src/transaction/action.rs index 46de0e6e4a..7199859ea5 100644 --- a/types/src/transaction/action.rs +++ b/types/src/transaction/action.rs @@ -37,8 +37,10 @@ const UNWRAP_CCC: u8 = 0x11; const MINT_ASSET: u8 = 0x13; const TRANSFER_ASSET: u8 = 0x14; const CHANGE_ASSET_SCHEME: u8 = 0x15; -const COMPOSE_ASSET: u8 = 0x16; -const DECOMPOSE_ASSET: u8 = 0x17; +// Derepcated +//const COMPOSE_ASSET: u8 = 0x16; +// Derepcated +//const DECOMPOSE_ASSET: u8 = 0x17; const INCREASE_ASSET_SUPPLY: u8 = 0x18; const CUSTOM: u8 = 0xFF; @@ -84,23 +86,6 @@ pub enum Action { output: Box, approvals: Vec, }, - ComposeAsset { - network_id: NetworkId, - shard_id: ShardId, - metadata: String, - approver: Option
, - registrar: Option
, - allowed_script_hashes: Vec, - inputs: Vec, - output: Box, - approvals: Vec, - }, - DecomposeAsset { - network_id: NetworkId, - input: AssetTransferInput, - outputs: Vec, - approvals: Vec, - }, UnwrapCCC { network_id: NetworkId, burn: AssetTransferInput, @@ -167,12 +152,6 @@ impl Action { | Action::IncreaseAssetSupply { .. } - | Action::ComposeAsset { - .. - } - | Action::DecomposeAsset { - .. - } | Action::UnwrapCCC { .. } => self.clone().into(), @@ -244,51 +223,6 @@ impl Action { return Err(SyntaxError::CannotChangeWcccAssetScheme) } } - Action::ComposeAsset { - inputs, - output, - .. - } => { - let disable_compose_asset = true; - if disable_compose_asset { - return Err(SyntaxError::DisabledTransaction) - } - if inputs.is_empty() { - return Err(SyntaxError::EmptyInput) - } - if inputs.iter().any(|input| input.prev_out.quantity == 0) { - return Err(SyntaxError::ZeroQuantity) - } - check_duplication_in_prev_out(&[], inputs)?; - if output.supply != 1 { - return Err(SyntaxError::InvalidComposedOutputAmount { - got: output.supply, - }) - } - } - Action::DecomposeAsset { - input, - outputs, - .. - } => { - let disable_decompose_asset = true; - if disable_decompose_asset { - return Err(SyntaxError::DisabledTransaction) - } - if input.prev_out.quantity != 1 { - return Err(SyntaxError::InvalidDecomposedInputAmount { - asset_type: input.prev_out.asset_type, - shard_id: input.prev_out.shard_id, - got: input.prev_out.quantity, - }) - } - if outputs.is_empty() { - return Err(SyntaxError::EmptyOutput) - } - if outputs.iter().any(|output| output.quantity == 0) { - return Err(SyntaxError::ZeroQuantity) - } - } Action::UnwrapCCC { burn, .. @@ -360,18 +294,6 @@ impl Action { Action::IncreaseAssetSupply { .. } => {} - Action::ComposeAsset { - metadata, - .. - } => { - let max_asset_scheme_metadata_size = common_params.max_asset_scheme_metadata_size(); - if metadata.len() > max_asset_scheme_metadata_size { - return Err(SyntaxError::MetadataTooBig) - } - } - Action::DecomposeAsset { - .. - } => {} Action::UnwrapCCC { .. } => {} @@ -429,14 +351,6 @@ impl Action { | Action::IncreaseAssetSupply { approvals, .. - } - | Action::ComposeAsset { - approvals, - .. - } - | Action::DecomposeAsset { - approvals, - .. } => Some(approvals), _ => None, } @@ -460,14 +374,6 @@ impl Action { network_id, .. } - | Action::ComposeAsset { - network_id, - .. - } - | Action::DecomposeAsset { - network_id, - .. - } | Action::UnwrapCCC { network_id, .. @@ -546,36 +452,6 @@ impl From for Option { seq, output: *output, }), - Action::ComposeAsset { - network_id, - shard_id, - metadata, - approver, - registrar, - allowed_script_hashes, - inputs, - output, - .. - } => Some(ShardTransaction::ComposeAsset { - network_id, - shard_id, - metadata, - approver, - registrar, - allowed_script_hashes, - inputs, - output: *output, - }), - Action::DecomposeAsset { - network_id, - input, - outputs, - .. - } => Some(ShardTransaction::DecomposeAsset { - network_id, - input, - outputs, - }), Action::UnwrapCCC { network_id, burn, @@ -679,44 +555,6 @@ impl Encodable for Action { .append(&output.supply) .append_list(approvals); } - Action::ComposeAsset { - network_id, - shard_id, - metadata, - approver, - registrar, - allowed_script_hashes, - inputs, - output, - approvals, - } => { - s.begin_list(12) - .append(&COMPOSE_ASSET) - .append(network_id) - .append(shard_id) - .append(metadata) - .append(approver) - .append(registrar) - .append_list(allowed_script_hashes) - .append_list(inputs) - .append(&output.lock_script_hash) - .append(&output.parameters) - .append(&output.supply) - .append_list(approvals); - } - Action::DecomposeAsset { - network_id, - input, - outputs, - approvals, - } => { - s.begin_list(5) - .append(&DECOMPOSE_ASSET) - .append(network_id) - .append(input) - .append_list(outputs) - .append_list(approvals); - } Action::UnwrapCCC { network_id, burn, @@ -899,45 +737,6 @@ impl Decodable for Action { approvals: rlp.list_at(8)?, }) } - COMPOSE_ASSET => { - let item_count = rlp.item_count()?; - if item_count != 12 { - return Err(DecoderError::RlpIncorrectListLen { - got: item_count, - expected: 12, - }) - } - Ok(Action::ComposeAsset { - network_id: rlp.val_at(1)?, - shard_id: rlp.val_at(2)?, - metadata: rlp.val_at(3)?, - approver: rlp.val_at(4)?, - registrar: rlp.val_at(5)?, - allowed_script_hashes: rlp.list_at(6)?, - inputs: rlp.list_at(7)?, - output: Box::new(AssetMintOutput { - lock_script_hash: rlp.val_at(8)?, - parameters: rlp.list_at(9)?, - supply: rlp.val_at(10)?, - }), - approvals: rlp.list_at(11)?, - }) - } - DECOMPOSE_ASSET => { - let item_count = rlp.item_count()?; - if item_count != 5 { - return Err(DecoderError::RlpIncorrectListLen { - got: item_count, - expected: 5, - }) - } - Ok(Action::DecomposeAsset { - network_id: rlp.val_at(1)?, - input: rlp.val_at(2)?, - outputs: rlp.list_at(3)?, - approvals: rlp.list_at(4)?, - }) - } UNWRAP_CCC => { let item_count = rlp.item_count()?; if item_count != 4 { diff --git a/types/src/transaction/shard.rs b/types/src/transaction/shard.rs index 1e9f919d58..32c705b348 100644 --- a/types/src/transaction/shard.rs +++ b/types/src/transaction/shard.rs @@ -62,21 +62,6 @@ pub enum ShardTransaction { seq: usize, output: AssetMintOutput, }, - ComposeAsset { - network_id: NetworkId, - shard_id: ShardId, - metadata: String, - approver: Option
, - registrar: Option
, - allowed_script_hashes: Vec, - inputs: Vec, - output: AssetMintOutput, - }, - DecomposeAsset { - network_id: NetworkId, - input: AssetTransferInput, - outputs: Vec, - }, UnwrapCCC { network_id: NetworkId, burn: AssetTransferInput, @@ -123,18 +108,10 @@ impl ShardTransaction { network_id, .. } - | ShardTransaction::ComposeAsset { - network_id, - .. - } | ShardTransaction::ChangeAssetScheme { network_id, .. } - | ShardTransaction::DecomposeAsset { - network_id, - .. - } | ShardTransaction::UnwrapCCC { network_id, .. @@ -174,26 +151,6 @@ impl ShardTransaction { shard_id, .. } => vec![*shard_id], - ShardTransaction::ComposeAsset { - inputs, - shard_id, - .. - } => { - let mut shards: Vec = inputs.iter().map(|v| v.prev_out.shard_id).collect(); - shards.push(*shard_id); - shards.sort_unstable(); - shards.dedup(); - shards - } - ShardTransaction::DecomposeAsset { - outputs, - .. - } => { - let mut shards: Vec = outputs.iter().map(|v| v.shard_id).collect(); - shards.sort_unstable(); - shards.dedup(); - shards - } ShardTransaction::UnwrapCCC { burn, .. @@ -220,13 +177,6 @@ impl ShardTransaction { ShardTransaction::ChangeAssetScheme { .. } => false, - ShardTransaction::ComposeAsset { - .. - } => index == 0, - ShardTransaction::DecomposeAsset { - outputs, - .. - } => index < outputs.len(), ShardTransaction::UnwrapCCC { .. } => false, @@ -256,14 +206,6 @@ impl ShardTransaction { ShardTransaction::ChangeAssetScheme { .. } => unreachable!("AssetSchemeChange doesn't have a valid index"), - ShardTransaction::ComposeAsset { - shard_id, - .. - } => &id == shard_id, - ShardTransaction::DecomposeAsset { - outputs, - .. - } => id == outputs[index].shard_id, ShardTransaction::UnwrapCCC { .. } => unreachable!("UnwrapCCC doesn't have a valid index"), @@ -366,69 +308,6 @@ impl PartialHashing for ShardTransaction { &blake128(tag.get_tag()), )) } - ShardTransaction::ComposeAsset { - network_id, - shard_id, - metadata, - approver, - registrar, - allowed_script_hashes, - inputs, - output, - } => { - if tag.filter_len != 0 { - return Err(HashingError::InvalidFilter) - } - - let new_inputs = apply_input_scheme(inputs, tag.sign_all_inputs, !is_burn, cur); - - let new_output = if tag.sign_all_outputs { - output.clone() - } else { - AssetMintOutput::default() - }; - - Ok(blake256_with_key( - &ShardTransaction::ComposeAsset { - network_id: *network_id, - shard_id: *shard_id, - metadata: metadata.to_string(), - approver: *approver, - registrar: *registrar, - allowed_script_hashes: allowed_script_hashes.to_vec(), - inputs: new_inputs, - output: new_output, - } - .rlp_bytes(), - &blake128(tag.get_tag()), - )) - } - ShardTransaction::DecomposeAsset { - network_id, - input, - outputs, - } => { - let new_outputs = if tag.sign_all_outputs { - outputs.clone() - } else { - apply_bitmask_to_output(tag.filter.clone(), &outputs, Vec::new())? - }; - - Ok(blake256_with_key( - &ShardTransaction::DecomposeAsset { - network_id: *network_id, - input: AssetTransferInput { - prev_out: input.prev_out.clone(), - timelock: input.timelock, - lock_script: Vec::new(), - unlock_script: Vec::new(), - }, - outputs: new_outputs, - } - .rlp_bytes(), - &blake128(tag.get_tag()), - )) - } ShardTransaction::UnwrapCCC { network_id, burn, @@ -478,8 +357,10 @@ const ASSET_UNWRAP_CCC_ID: TransactionId = 0x11; const ASSET_MINT_ID: TransactionId = 0x13; const ASSET_TRANSFER_ID: TransactionId = 0x14; const ASSET_SCHEME_CHANGE_ID: TransactionId = 0x15; -const ASSET_COMPOSE_ID: TransactionId = 0x16; -const ASSET_DECOMPOSE_ID: TransactionId = 0x17; +/// Deprecated +//const ASSET_COMPOSE_ID: TransactionId = 0x16; +/// Deprecated +//const ASSET_DECOMPOSE_ID: TransactionId = 0x17; const ASSET_INCREASE_SUPPLY_ID: TransactionId = 0x18; impl Decodable for ShardTransaction { @@ -562,43 +443,6 @@ impl Decodable for ShardTransaction { }, }) } - ASSET_COMPOSE_ID => { - let item_count = d.item_count()?; - if item_count != 11 { - return Err(DecoderError::RlpIncorrectListLen { - got: item_count, - expected: 11, - }) - } - Ok(ShardTransaction::ComposeAsset { - network_id: d.val_at(1)?, - shard_id: d.val_at(2)?, - metadata: d.val_at(3)?, - approver: d.val_at(4)?, - registrar: d.val_at(5)?, - allowed_script_hashes: d.list_at(6)?, - inputs: d.list_at(7)?, - output: AssetMintOutput { - lock_script_hash: d.val_at(8)?, - parameters: d.val_at(9)?, - supply: d.val_at(10)?, - }, - }) - } - ASSET_DECOMPOSE_ID => { - let item_count = d.item_count()?; - if item_count != 4 { - return Err(DecoderError::RlpIncorrectListLen { - got: item_count, - expected: 4, - }) - } - Ok(ShardTransaction::DecomposeAsset { - network_id: d.val_at(1)?, - input: d.val_at(2)?, - outputs: d.list_at(3)?, - }) - } ASSET_UNWRAP_CCC_ID => { let item_count = d.item_count()?; if item_count != 4 { @@ -705,41 +549,6 @@ impl Encodable for ShardTransaction { .append(parameters) .append(supply); } - ShardTransaction::ComposeAsset { - network_id, - shard_id, - metadata, - approver, - registrar, - allowed_script_hashes, - inputs, - output: - AssetMintOutput { - lock_script_hash, - parameters, - supply, - }, - } => { - s.begin_list(11) - .append(&ASSET_COMPOSE_ID) - .append(network_id) - .append(shard_id) - .append(metadata) - .append(approver) - .append(registrar) - .append_list(allowed_script_hashes) - .append_list(inputs) - .append(lock_script_hash) - .append(parameters) - .append(supply); - } - ShardTransaction::DecomposeAsset { - network_id, - input, - outputs, - } => { - s.begin_list(4).append(&ASSET_DECOMPOSE_ID).append(network_id).append(input).append_list(outputs); - } ShardTransaction::UnwrapCCC { network_id, burn, @@ -1009,28 +818,6 @@ mod tests { )); } - - #[test] - fn encode_and_decode_decompose_transaction() { - let tx = ShardTransaction::DecomposeAsset { - network_id: NetworkId::default(), - input: AssetTransferInput { - prev_out: AssetOutPoint { - tracker: Default::default(), - index: 0, - asset_type: H160::default(), - shard_id: 0, - quantity: 30, - }, - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - outputs: Vec::new(), - }; - rlp_encode_and_decode_test!(tx); - } - #[test] fn encode_and_decode_unwrapccc_transaction() { let tx = ShardTransaction::UnwrapCCC { From a6f7c230095674b7156da9a36dc9786816a6102c Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Mon, 23 Sep 2019 12:13:56 +0900 Subject: [PATCH 015/105] Import following downloaded blocks if the preceding block is already queued Before this commit, following blocks were dropped and this behavior was causing "parent not found" errors in Block Sync. --- sync/src/block/extension.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sync/src/block/extension.rs b/sync/src/block/extension.rs index 01cdb59852..d865a56fd2 100644 --- a/sync/src/block/extension.rs +++ b/sync/src/block/extension.rs @@ -728,6 +728,9 @@ impl Extension { Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { cwarn!(SYNC, "Downloaded already existing block({})", hash) } + Err(BlockImportError::Import(ImportError::AlreadyQueued)) => { + cwarn!(SYNC, "Downloaded already queued in the verification queue({})", hash) + } Err(err) => { // FIXME: handle import errors cwarn!(SYNC, "Cannot import block({}): {:?}", hash, err); From 16bb07527268b850fba4ac084e1a531dbd44e18e Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Mon, 23 Sep 2019 18:26:38 +0900 Subject: [PATCH 016/105] If best block is not changed don't move to the next height --- core/src/consensus/tendermint/worker.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index a71b069ac0..2593031fef 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -1312,7 +1312,11 @@ impl Worker { view, } => { cinfo!(ENGINE, "Commit timeout."); - if self.client().block(&block_hash.into()).is_none() { + + let proposal_imported = self.client().block(&block_hash.into()).is_some(); + let best_block_header = self.client().best_block_header(); + + if !proposal_imported || best_block_header.hash() != block_hash { cwarn!(ENGINE, "Best chain is not updated yet, wait until imported"); self.step = TendermintState::CommitTimedout { block_hash, From 8e142eb2f6cb30caf11ca7fba8ed7e7ef45747f9 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Mon, 23 Sep 2019 18:30:36 +0900 Subject: [PATCH 017/105] Call new_blocks even though block verification queue is not empty new_blocks was called when the block verification queue is empty. The purpose of the behavior is not clear. Maybe it was used to backpressure for block sync extension. Since we have another block sync flow control and tendermint assumes that new_blocks is always called, this commit changed the behavior of new_blocks to be always called. --- core/src/client/importer.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/client/importer.rs b/core/src/client/importer.rs index b010b5e06b..d039b36e22 100644 --- a/core/src/client/importer.rs +++ b/core/src/client/importer.rs @@ -144,7 +144,10 @@ impl Importer { }; { - if !imported_blocks.is_empty() && is_empty { + if !imported_blocks.is_empty() { + if !is_empty { + ctrace!(CLIENT, "Call new_blocks even though block verification queue is not empty"); + } let (enacted, retracted) = self.calculate_enacted_retracted(&import_results); self.miner.chain_new_blocks(client, &imported_blocks, &invalid_blocks, &enacted, &retracted); client.new_blocks(&imported_blocks, &invalid_blocks, &enacted, &retracted, &[], duration); From 8248af2d0be7649f5e2d5962bf204e2ecdd22cd1 Mon Sep 17 00:00:00 2001 From: Joonmo Yang Date: Mon, 23 Sep 2019 18:10:34 +0900 Subject: [PATCH 018/105] Fill the missing fields in the Transaction spec --- spec/Transaction.md | 48 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/spec/Transaction.md b/spec/Transaction.md index cf688beec4..f084846eca 100644 --- a/spec/Transaction.md +++ b/spec/Transaction.md @@ -22,6 +22,7 @@ enum Action { MintAsset { ..., }, TransferAsset { ..., }, ChangeAssetScheme { ..., }, + IncreaseAssetSupply { ..., }, Pay { ..., }, SetRegularKey { ..., }, WrapCCC { ..., }, @@ -43,6 +44,10 @@ This kind of asset needs permission to be transferred. A regulated asset is an asset that has an registrar. The registrar can change the asset scheme and transfer the asset arbitrarily. +If the `allowed_script_hashes` is specified, this asset can be only locked with +the lock script hashes in the list. If the list is empty, any lock script hashes +can be used. + ```rust MintAsset { network_id: NetworkId, @@ -50,6 +55,7 @@ MintAsset { metadata: String, approver: Option, registrar: Option, + allowed_script_hashes: Vec, output: AssetMintOutput, @@ -136,23 +142,42 @@ Only the registrar of the asset can use it. ```rust ChangeAssetScheme { network_id: NetworkId, - asset_type: H256, + shard_id: ShardId, + asset_type: H160, + seq: usize, metadata: String, approver: Option, registrar: Option, + allowed_script_hashes: Vec, approvals: Vec, } ``` +## IncreaseAssetSupply + +It increases the total supply of the asset. +Only the registrar of the asset can use it. + +```rust +IncreaseAssetSupply { + network_id: NetworkId, + shard_id: ShardId, + asset_type: H160, + seq: usize, + output: AssetMintOutput, + approvals: Vec, +} +``` + ## Pay -`Pay` sends `value` amount of CCC to the `receiver`. +`Pay` sends `quantity` amount of CCC to the `receiver`. ```rust Pay { receiver: Address, - amount: u64, + quantity: u64, } ``` @@ -176,7 +201,8 @@ WrapCCC { shard_id: ShardId, lock_script_hash: H160, parameters: Vec, - amount: u64, + quantity: u64, + payer: Address, } ``` @@ -193,13 +219,6 @@ UnwrapCCC { } ``` -```rust -Custom { - handler_id: u64, - bytes: Bytes, -} -``` - ## Store This is a special kind of transaction that allows a user to upload text onto the blockchain. @@ -227,3 +246,10 @@ Remove { `Custom` is a special transaction. The types of transactions that may exist depends on the consensus engine. + +```rust +Custom { + handler_id: u64, + bytes: Bytes, +} +``` From 91f6389b570c2ba66c5da288dacc37c3a6eeff3d Mon Sep 17 00:00:00 2001 From: JinGyeong Jeong Date: Fri, 20 Sep 2019 20:59:07 +0900 Subject: [PATCH 019/105] Remove order --- core/src/codechain_machine.rs | 34 +- core/src/miner/mem_pool.rs | 1 - core/src/transaction.rs | 4 +- rpc/src/v1/impls/devel.rs | 1 - rpc/src/v1/types/action.rs | 13 +- rpc/src/v1/types/asset.rs | 4 +- rpc/src/v1/types/mod.rs | 4 +- rpc/src/v1/types/order.rs | 144 -- spec/Asset-Exchange-Protocol.md | 75 - spec/JSON-RPC.md | 26 +- spec/Transaction.md | 6 - state/src/impls/shard_level.rs | 187 +- state/src/impls/test_helper.rs | 58 +- state/src/impls/top_level.rs | 3 +- state/src/item/asset.rs | 24 +- test/src/e2e.long/orders.test.ts | 2988 --------------------- test/src/e2e.long/ordersDisabled.test.ts | 3019 ---------------------- test/src/helper/error.ts | 45 - types/src/errors/history_error.rs | 18 - types/src/errors/runtime_error.rs | 9 - types/src/errors/syntax_error.rs | 167 +- types/src/transaction/action.rs | 975 +------ types/src/transaction/mod.rs | 2 - types/src/transaction/order.rs | 453 ---- types/src/transaction/shard.rs | 72 +- vm/tests/chk_multi_sig.rs | 82 - vm/tests/chk_sig.rs | 16 - vm/tests/executor.rs | 13 - 28 files changed, 61 insertions(+), 8382 deletions(-) delete mode 100644 rpc/src/v1/types/order.rs delete mode 100644 spec/Asset-Exchange-Protocol.md delete mode 100644 test/src/e2e.long/orders.test.ts delete mode 100644 test/src/e2e.long/ordersDisabled.test.ts delete mode 100644 types/src/transaction/order.rs diff --git a/core/src/codechain_machine.rs b/core/src/codechain_machine.rs index d75ccf3361..9d10dcf0aa 100644 --- a/core/src/codechain_machine.rs +++ b/core/src/codechain_machine.rs @@ -18,7 +18,7 @@ use ckey::Address; use cstate::{StateError, TopState, TopStateView}; use ctypes::errors::{HistoryError, SyntaxError}; -use ctypes::transaction::{Action, AssetTransferInput, OrderOnTransfer, Timelock}; +use ctypes::transaction::{Action, AssetTransferInput, Timelock}; use ctypes::{CommonParams, Header}; use crate::block::{ExecutedBlock, IsBlock}; @@ -28,14 +28,12 @@ use crate::transaction::{SignedTransaction, UnverifiedTransaction}; pub struct CodeChainMachine { params: CommonParams, - is_order_disabled: bool, } impl CodeChainMachine { pub fn new(params: CommonParams) -> Self { CodeChainMachine { params, - is_order_disabled: is_order_disabled(), } } @@ -58,7 +56,7 @@ impl CodeChainMachine { } .into()) } - tx.verify_with_params(common_params, self.is_order_disabled)?; + tx.verify_with_params(common_params)?; Ok(()) } @@ -79,7 +77,6 @@ impl CodeChainMachine { ) -> Result<(), Error> { if let Action::TransferAsset { inputs, - orders, expiration, .. } = &tx.action @@ -88,7 +85,6 @@ impl CodeChainMachine { if verify_timelock { Self::verify_transfer_timelock(inputs, header, client)?; } - Self::verify_transfer_order_expired(orders, header)?; } // FIXME: Filter transactions. Ok(()) @@ -176,19 +172,6 @@ impl CodeChainMachine { Ok(()) } - fn verify_transfer_order_expired(orders: &[OrderOnTransfer], header: &Header) -> Result<(), Error> { - for order_tx in orders { - if order_tx.order.expiration < header.timestamp() { - return Err(HistoryError::OrderExpired { - expiration: order_tx.order.expiration, - timestamp: header.timestamp(), - } - .into()) - } - } - Ok(()) - } - pub fn min_cost(params: &CommonParams, action: &Action) -> u64 { match action { Action::MintAsset { @@ -250,16 +233,3 @@ impl CodeChainMachine { Ok(()) } } - -fn is_order_disabled() -> bool { - #[cfg(test)] - const DEFAULT_ORDER_DISABLED: bool = false; - #[cfg(not(test))] - const DEFAULT_ORDER_DISABLED: bool = true; - let var = std::env::var("ENABLE_ORDER"); - match var.as_ref().map(|x| x.trim()) { - Ok(value) => !value.parse::().unwrap(), - Err(std::env::VarError::NotPresent) => DEFAULT_ORDER_DISABLED, - Err(err) => unreachable!("{:?}", err), - } -} diff --git a/core/src/miner/mem_pool.rs b/core/src/miner/mem_pool.rs index cd0d8d5d18..0ceb45dd02 100644 --- a/core/src/miner/mem_pool.rs +++ b/core/src/miner/mem_pool.rs @@ -1273,7 +1273,6 @@ pub mod test { burns: vec![], inputs: vec![], outputs: vec![], - orders: vec![], metadata: "".into(), approvals: vec![], expiration: None, diff --git a/core/src/transaction.rs b/core/src/transaction.rs index 0521e7ac5a..5820a3ff5f 100644 --- a/core/src/transaction.rs +++ b/core/src/transaction.rs @@ -137,7 +137,7 @@ impl UnverifiedTransaction { } /// Verify transactiosn with the common params. Does not attempt signer recovery. - pub fn verify_with_params(&self, params: &CommonParams, is_order_disabled: bool) -> Result<(), SyntaxError> { + pub fn verify_with_params(&self, params: &CommonParams) -> Result<(), SyntaxError> { if self.network_id != params.network_id() { return Err(SyntaxError::InvalidNetworkId(self.network_id)) } @@ -145,7 +145,7 @@ impl UnverifiedTransaction { if byte_size >= params.max_body_size() { return Err(SyntaxError::TransactionIsTooBig) } - self.action.verify_with_params(params, is_order_disabled) + self.action.verify_with_params(params) } } diff --git a/rpc/src/v1/impls/devel.rs b/rpc/src/v1/impls/devel.rs index 042923600b..e916b8ec56 100644 --- a/rpc/src/v1/impls/devel.rs +++ b/rpc/src/v1/impls/devel.rs @@ -174,7 +174,6 @@ where burns: vec![], inputs: $inputs, outputs: $outputs, - orders: vec![], metadata: "".to_string(), approvals: vec![], expiration: None, diff --git a/rpc/src/v1/types/action.rs b/rpc/src/v1/types/action.rs index 4552c2a448..02160c57d5 100644 --- a/rpc/src/v1/types/action.rs +++ b/rpc/src/v1/types/action.rs @@ -24,7 +24,7 @@ use primitives::{Bytes, H160, H256}; use rustc_serialize::hex::{FromHex, ToHex}; use super::super::errors::ConversionError; -use super::{AssetMintOutput, AssetTransferInput, AssetTransferOutput, OrderOnTransfer}; +use super::{AssetMintOutput, AssetTransferInput, AssetTransferOutput}; #[derive(Debug, Deserialize, PartialEq)] #[serde(rename_all = "camelCase", tag = "type")] @@ -48,7 +48,6 @@ pub enum Action { burns: Vec, inputs: Vec, outputs: Vec, - orders: Vec, metadata: String, approvals: Vec, @@ -151,7 +150,9 @@ pub enum ActionWithTracker { burns: Vec, inputs: Vec, outputs: Vec, - orders: Vec, + // NOTE: The orders field is removed in the core but it remains to + // support the old version of the SDK + orders: Vec<()>, metadata: String, approvals: Vec, @@ -269,7 +270,6 @@ impl ActionWithTracker { burns, inputs, outputs, - orders, metadata, approvals, expiration, @@ -278,7 +278,7 @@ impl ActionWithTracker { burns: burns.into_iter().map(From::from).collect(), inputs: inputs.into_iter().map(From::from).collect(), outputs: outputs.into_iter().map(From::from).collect(), - orders: orders.into_iter().map(From::from).collect(), + orders: vec![], metadata, approvals, expiration: expiration.map(From::from), @@ -449,20 +449,17 @@ impl TryFrom for ActionType { burns, inputs, outputs, - orders, metadata, approvals, expiration, } => { let outputs = outputs.into_iter().map(TryFrom::try_from).collect::>()?; - let orders = orders.into_iter().map(TryFrom::try_from).collect::>()?; ActionType::TransferAsset { network_id, burns: burns.into_iter().map(From::from).collect(), inputs: inputs.into_iter().map(From::from).collect(), outputs, - orders, metadata, approvals, expiration: expiration.map(From::from), diff --git a/rpc/src/v1/types/asset.rs b/rpc/src/v1/types/asset.rs index cff4fd085e..bba19e06e9 100644 --- a/rpc/src/v1/types/asset.rs +++ b/rpc/src/v1/types/asset.rs @@ -18,7 +18,7 @@ use std::ops::Deref; use cjson::uint::Uint; use cstate::{Asset as AssetType, OwnedAsset as OwnedAssetType}; -use primitives::{H160, H256}; +use primitives::H160; use rustc_serialize::hex::ToHex; #[derive(Clone, Debug, PartialEq, Serialize)] @@ -35,7 +35,6 @@ pub struct OwnedAsset { asset: Asset, lock_script_hash: H160, parameters: Vec, - order_hash: Option, } impl From for Asset { @@ -55,7 +54,6 @@ impl From for OwnedAsset { quantity: asset.quantity().into(), }, lock_script_hash: *asset.lock_script_hash(), - order_hash: *asset.order_hash(), parameters: asset.parameters().iter().map(Deref::deref).map(<[u8]>::to_hex).collect(), } } diff --git a/rpc/src/v1/types/mod.rs b/rpc/src/v1/types/mod.rs index a11dec6110..59ab24ad1c 100644 --- a/rpc/src/v1/types/mod.rs +++ b/rpc/src/v1/types/mod.rs @@ -20,7 +20,6 @@ mod asset_input; mod asset_output; mod asset_scheme; mod block; -mod order; mod text; mod transaction; mod unsigned_transaction; @@ -29,9 +28,8 @@ mod work; use primitives::H256; use self::asset::Asset; -use self::asset_input::{AssetOutPoint, AssetTransferInput}; +use self::asset_input::AssetTransferInput; use self::asset_output::{AssetMintOutput, AssetTransferOutput}; -use self::order::OrderOnTransfer; pub use self::action::{Action, ActionWithTracker}; pub use self::asset::OwnedAsset; diff --git a/rpc/src/v1/types/order.rs b/rpc/src/v1/types/order.rs deleted file mode 100644 index c9396ff20d..0000000000 --- a/rpc/src/v1/types/order.rs +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2018-2019 Kodebox, Inc. -// This file is part of CodeChain. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -use std::convert::{TryFrom, TryInto}; - -use cjson::uint::Uint; -use ctypes::transaction::{Order as OrderType, OrderOnTransfer as OrderOnTransferType}; -use ctypes::ShardId; -use primitives::H160; -use rustc_serialize::hex::{FromHex, FromHexError, ToHex}; - -use super::AssetOutPoint; - -#[derive(Debug, Deserialize, PartialEq, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct Order { - pub asset_type_from: H160, - pub asset_type_to: H160, - pub asset_type_fee: H160, - pub shard_id_from: ShardId, - pub shard_id_to: ShardId, - pub shard_id_fee: ShardId, - pub asset_quantity_from: Uint, - pub asset_quantity_to: Uint, - pub asset_quantity_fee: Uint, - pub origin_outputs: Vec, - pub expiration: Uint, - pub lock_script_hash_from: H160, - pub parameters_from: Vec, - pub lock_script_hash_fee: H160, - pub parameters_fee: Vec, -} - -impl From for Order { - fn from(from: OrderType) -> Self { - Order { - asset_type_from: from.asset_type_from, - asset_type_to: from.asset_type_to, - asset_type_fee: from.asset_type_fee, - shard_id_from: from.shard_id_from, - shard_id_to: from.shard_id_to, - shard_id_fee: from.shard_id_fee, - asset_quantity_from: from.asset_quantity_from.into(), - asset_quantity_to: from.asset_quantity_to.into(), - asset_quantity_fee: from.asset_quantity_fee.into(), - origin_outputs: from.origin_outputs.into_iter().map(From::from).collect(), - expiration: from.expiration.into(), - lock_script_hash_from: from.lock_script_hash_from, - parameters_from: from.parameters_from.into_iter().map(|param| param.to_hex()).collect(), - lock_script_hash_fee: from.lock_script_hash_fee, - parameters_fee: from.parameters_fee.into_iter().map(|param| param.to_hex()).collect(), - } - } -} - -impl TryFrom for OrderType { - type Error = FromHexError; - fn try_from(from: Order) -> Result { - let parameters_from = - from.parameters_from.into_iter().map(|param| param.from_hex()).collect::>()?; - let parameters_fee = from.parameters_fee.into_iter().map(|param| param.from_hex()).collect::>()?; - Ok(OrderType { - asset_type_from: from.asset_type_from, - asset_type_to: from.asset_type_to, - asset_type_fee: from.asset_type_fee, - shard_id_from: from.shard_id_from, - shard_id_to: from.shard_id_to, - shard_id_fee: from.shard_id_fee, - asset_quantity_from: from.asset_quantity_from.into(), - asset_quantity_to: from.asset_quantity_to.into(), - asset_quantity_fee: from.asset_quantity_fee.into(), - origin_outputs: from.origin_outputs.into_iter().map(From::from).collect(), - expiration: from.expiration.into(), - lock_script_hash_from: from.lock_script_hash_from, - parameters_from, - lock_script_hash_fee: from.lock_script_hash_fee, - parameters_fee, - }) - } -} - -#[derive(Debug, Deserialize, PartialEq, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct OrderOnTransfer { - pub order: Order, - /// Spent quantity of asset_type_from - pub spent_quantity: Uint, - // Indices of asset_type_from - pub input_from_indices: Vec, - // Indices of asset_type_fee - pub input_fee_indices: Vec, - // Indices of remain asset_type_from - pub output_from_indices: Vec, - // Indices of asset_type_to - pub output_to_indices: Vec, - // Indices of ramain asset_type_fee - pub output_owned_fee_indices: Vec, - // Indices of paid asset_type_fee - pub output_transferred_fee_indices: Vec, -} - -impl From for OrderOnTransfer { - fn from(from: OrderOnTransferType) -> Self { - OrderOnTransfer { - order: from.order.into(), - spent_quantity: from.spent_quantity.into(), - input_from_indices: from.input_from_indices, - input_fee_indices: from.input_fee_indices, - output_from_indices: from.output_from_indices, - output_to_indices: from.output_to_indices, - output_owned_fee_indices: from.output_owned_fee_indices, - output_transferred_fee_indices: from.output_transferred_fee_indices, - } - } -} - -impl TryFrom for OrderOnTransferType { - type Error = FromHexError; - fn try_from(from: OrderOnTransfer) -> Result { - Ok(OrderOnTransferType { - order: from.order.try_into()?, - spent_quantity: from.spent_quantity.into(), - input_from_indices: from.input_from_indices, - input_fee_indices: from.input_fee_indices, - output_from_indices: from.output_from_indices, - output_to_indices: from.output_to_indices, - output_owned_fee_indices: from.output_owned_fee_indices, - output_transferred_fee_indices: from.output_transferred_fee_indices, - }) - } -} diff --git a/spec/Asset-Exchange-Protocol.md b/spec/Asset-Exchange-Protocol.md deleted file mode 100644 index 648cdfbc8d..0000000000 --- a/spec/Asset-Exchange-Protocol.md +++ /dev/null @@ -1,75 +0,0 @@ -CodeChain supports an on-chain order to support DEX(Decentralized Exchange). - -## Order - -An order can be either a _point-to-point order_ between a maker and a taker, or a _broadcast order_ between a maker, a relayer and takers. -Point-to-point orders allow two parties(makers and takers) to directly exchange assets between each other. -Broadcast orders are similar to point-to-point orders, but also allow relayers to take fee assets from makers and takers. Broadcast orders are usually used in decentralized exchange platforms. - -Orders on CodeChain are implemented on UTXO forms. -Basically, an order is like a tag on products in grocery stores. Orders can be put on inputs and outputs of transfer transactions. If an input/output has an order, it means that that specific input/output should be exchanged as its order says. Think about this situation: Let’s say we have an order to exchange 10 gold to 100 silver, and we've put that order on a 10-gold input. Then there should be a 100-silver output with the same order of 10 gold to 100 silver. If there isn’t enough gold, there would perhaps be a 5-gold output and a 50-silver output, both with the same order, or, whatever outputs with the same order while maintaining the order equilibrium. - -Assets with orders must be able to be spent by takers or relayers without any permission. But in the CodeChain UTXO form, those parties should provide a lock script and an unlock script to prove the ownership of the assets. In order to solve the problem, if there are orders on inputs, CodeChain runs VM on **orders**, not *transactions*, if there are orders on inputs. If there are no orders on inputs, CodeChain runs VM on transactions as usual. Partial signing is not allowed on transactions with orders. With this convention, takers and relayers can take the ownership of the assets with orders with unlock scripts which are provided by makers. - - -## Order format - -The format of `Order` is as shown below. - -| Name | Data Type | Description | -|--------------------|-----------------|-----------------------------------------------------------------------------------------------------------| -| assetTypeFrom | H160 | The type of the asset offered by maker | -| assetTypeTo | H160 | The type of the asset requested by maker | -| assetTypeFee | H160 | The type of the asset offered by maker to give as fees | -| shardIdFrom | ShardId | The shard ID of the asset offered by maker | -| shardIdTo | ShardId | The shard ID of the asset requested by maker | -| shardIdFee | ShardId | The shard ID of the asset offered by maker to give as fees | -| assetQuantityFrom | U64 | Total quantity of assets with the type assetTypeFrom | -| assetQuantityTo | U64 | Total quantity of assets with the type assetTypeTo | -| assetQuantityFee | U64 | Total quantity of assets with the type assetTypeFee | -| originOutputs | AssetOutPoint[] | The previous outputs composed of assetTypeFrom / assetTypeFee assets, which the order starts from | -| expiration | U64 | Time at which the order expires | -| lockScriptHashFrom | H160 | Lock script hash provided by maker, which should be written in every output with the order except fee | -| parametersFrom | Bytes[] | Parameters provided by maker, which should be written in every output with the order except fee | -| lockScriptHashFee | H160 | Lock script hash provided by relayer, which should be written in every fee output with the order | -| parametersFee | Bytes[] | Parameters provided by relayer, which should be written in every fee output with the order | - -To make a point-to-point order, put a zero on the `assetQuantityFee` field. -To write an order on a transfer transaction, the order should be wrapped once more, to `OrderOnTransfer`. - -## OrderOnTransfer format - -If there are inputs and outputs with the same order, it is wasteful to put the order in every input/output. Therefore, orders are wrapped into `OrderOnTransfer`. - -| Name | Data Type | Description | -| --------------------------- | --------- | -------------------------------------------------------------------------------- | -| order | Order | The order to write on the transfer transaction | -| spentQuantity | U64 | The spent quantity of `assetTypeFrom` of the order in the transfer transaction | -| inputFromIndices | Index[] | The indices of the transfer inputs that are protected by the order ( assetFrom) | -| inputFeeIndices | Index[] | The indices of the transfer inputs that are protected by the order (assetFee) | -| outputFromIndices | Index[] | The indices of the transfer outputs that are protected by the order (assetFrom) | -| outputToIndices | Index[] | The indices of the transfer outputs that are protected by the order (assetTo) | -| outputOwnedFeeIndices | Index[] | The indices of the transfer outputs that are protected by the order (assetFee) | -| outputTransferredFeeIndices | Index[] | The indices of the transfer outputs that are protected by the order (assetFee) | - -And the format of transfer transaction is as shown below. - -| Name | Data Type | -|---------------|-----------------------| -| networkId | NetworkId | -| burns | AssetTransferInput[] | -| inputs | AssetTransferInput[] | -| outputs | AssetTransferOutput[] | -| orders | OrderOnTransfer[] | - -## How to support partial fills? - -As described above in the 10-gold-to-100-silver order, it is possible to make a transfer transaction which has a 10-gold input that results in a 5-gold and 50-silver output, tagged with the same order. (Other inputs/outputs should be provided by a taker or a relayer). After this transaction, an asset contains the hash of the *consumed order*, which is a 5-gold-to-50-silver order, not a 10-gold-to-100-silver order. To use the 5-gold output, provide the 5-gold-to-50-silver order with the same information except for the `assetQuantityFrom` and the `assetQuantityTo` field. Neither a lock script nor an unlock script is needed for the 5-gold input. CodeChain will compare the order of an input and the order of the corresponding previous output, and will not run VM on the order if those orders are identical. - -## How to support cancellation? - -An order can be cancelled by the maker before it is completely filled. Let's use the described 10-gold-to-100-silver order example again. Suppose the maker wants to cancel the order after the 5-gold and 50-silver transaction is processed. Unlike the previous partial fill case, this time the maker has to prove the ownership of the remaining asset. Both a lock script and an unlock script is needed for the 5-gold input. Writing a new transaction with empty `orders` field with this input makes CodeChain cancel the remaining 5-gold and 50-silver order. - -## How to handle matched two orders with different exchange ratios? - -Suppose Alice and Bob want to exchange their own assets through a DEX platform. Alice offered a 10-gold-to-100-silver exchange ratio but Bob offered a 5-gold-to-100-silver exchange ratio, which has higher gold to silver ratio compared to the Alice's offer. For DEX platforms to satisfy both Alice and Bob, the minimum conditions are "Alice gets at least 100 silvers at the expense of 5 golds" and "Bob gets at least 5 golds at the expense of 100 silvers". Satisfying these conditions, there are extra 5 golds. Because CodeChain only checks the minimum conditions, DEX platforms have a freedom of how they dispose these extra assets. As long as the minimum conditions are satisfied, any possible choice of transaction could be accepted. \ No newline at end of file diff --git a/spec/JSON-RPC.md b/spec/JSON-RPC.md index 15a552e9ca..940676b59d 100644 --- a/spec/JSON-RPC.md +++ b/spec/JSON-RPC.md @@ -79,7 +79,6 @@ A string that starts with "(NetworkID)c", and Bech32 string follows. For example - burns: `AssetTransferInput[]` - inputs: `AssetTransferInput[]` - outputs: `AssetTransferOutput[]` - - orders: `OrderOnTransfer[]` - metadata: `string` - approvals: `Signature[]` - expiration: `Expiration time` | `null` @@ -215,29 +214,6 @@ When `Transaction` is included in any response, there will be an additional fiel - shardId: `number` - quantity: `U64` -### Order - - - assetTypeFrom: `H160` - - assetTypeTo: `H160` - - assetTypeFee: `H160` - - shardIdFrom: `number` - - shardIdTo: `number` - - shardIdFee: `number` - - assetQuantityFrom: `U64` - - assetQuantityTo: `U64` - - assetQuantityFee: `U64` - - originOutputs: `AssetOutPoint[]` - - expiration: `number` - - lockScriptHash: `H160` - - parameters: `string[]` - -### OrderOnTransfer - - - order: `Order` - - spentQuantity: `U64` - - inputIndices: `number[]` - - outputIndices: `number[]` - ## Signature `H520` for ECDSA signature | `H512` for Schnorr signature @@ -1578,7 +1554,7 @@ Errors: `Transfer Only` ``` curl \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc": "2.0", "method": "chain_executeVM", "params": [{"type":"assetTransfer","data":{"networkId":"tc","burns":[],"inputs":[{"prevOut":{"transactionHash":"0x56774a7e53abd17d70789af6d6f89b4ac23048c07430d1fbe7a8fe0688ecd250","index":0,"assetType":"0x53000000ec7f404207fc5f6bfaad91ed3bf4532b94f508fbea86223409eb189c","quantity":"0x64"},"timelock":null,"lockScript":[53,1,148,17,34,255,128],"unlockScript":[50,65,57,113,98,163,242,125,128,229,140,240,213,154,218,70,232,138,150,84,215,67,109,128,156,81,100,57,53,194,83,70,149,63,53,138,140,11,7,42,34,206,32,244,60,3,191,57,24,132,44,10,175,13,218,20,62,152,175,40,8,240,76,185,246,37,0,50,1,3,50,64,179,217,97,169,96,174,90,169,141,98,170,45,70,139,251,168,8,238,200,83,24,49,115,158,81,199,69,29,229,191,88,173,232,249,178,39,56,223,68,148,75,92,15,236,37,56,88,197,38,111,93,69,232,65,2,247,239,134,191,115,159,238,196,201]}],"outputs":[{"lockScriptHash":"0x5f5960a7bca6ceeeb0c97bc717562914e7a1de04","parameters":[[170,45,255,58,152,57,253,189,84,170,233,14,217,172,65,78,188,106,99,109]],"assetType":"0x53000000ec7f404207fc5f6bfaad91ed3bf4532b94f508fbea86223409eb189c","quantity":"0x64"}],"orders":[]}}, [[[123,110,101,117,85,125,64,83,80,25,37,104,84,81,160,50,198,212,89,125]]], [0]], "id": null}' \ + -d '{"jsonrpc": "2.0", "method": "chain_executeVM", "params": [{"type":"assetTransfer","data":{"networkId":"tc","burns":[],"inputs":[{"prevOut":{"transactionHash":"0x56774a7e53abd17d70789af6d6f89b4ac23048c07430d1fbe7a8fe0688ecd250","index":0,"assetType":"0x53000000ec7f404207fc5f6bfaad91ed3bf4532b94f508fbea86223409eb189c","quantity":"0x64"},"timelock":null,"lockScript":[53,1,148,17,34,255,128],"unlockScript":[50,65,57,113,98,163,242,125,128,229,140,240,213,154,218,70,232,138,150,84,215,67,109,128,156,81,100,57,53,194,83,70,149,63,53,138,140,11,7,42,34,206,32,244,60,3,191,57,24,132,44,10,175,13,218,20,62,152,175,40,8,240,76,185,246,37,0,50,1,3,50,64,179,217,97,169,96,174,90,169,141,98,170,45,70,139,251,168,8,238,200,83,24,49,115,158,81,199,69,29,229,191,88,173,232,249,178,39,56,223,68,148,75,92,15,236,37,56,88,197,38,111,93,69,232,65,2,247,239,134,191,115,159,238,196,201]}],"outputs":[{"lockScriptHash":"0x5f5960a7bca6ceeeb0c97bc717562914e7a1de04","parameters":[[170,45,255,58,152,57,253,189,84,170,233,14,217,172,65,78,188,106,99,109]],"assetType":"0x53000000ec7f404207fc5f6bfaad91ed3bf4532b94f508fbea86223409eb189c","quantity":"0x64"}]}}, [[[123,110,101,117,85,125,64,83,80,25,37,104,84,81,160,50,198,212,89,125]]], [0]], "id": null}' \ localhost:8080 ``` diff --git a/spec/Transaction.md b/spec/Transaction.md index f084846eca..354a7ee53e 100644 --- a/spec/Transaction.md +++ b/spec/Transaction.md @@ -80,7 +80,6 @@ TransferAsset { burns: Vec, inputs: Vec, outputs: Vec, - orders: Vec, metadata: String, approvals: Vec, @@ -129,11 +128,6 @@ enum Timelock { } ``` -### Order - -Order is used for the DEX. -Please see [this page](./Asset-Exchange-Protocol.md) for more information. - ## ChangeAssetScheme It changes the asset scheme. diff --git a/state/src/impls/shard_level.rs b/state/src/impls/shard_level.rs index 48da78ff47..0a079f1d7c 100644 --- a/state/src/impls/shard_level.rs +++ b/state/src/impls/shard_level.rs @@ -23,8 +23,8 @@ use ckey::Address; use cmerkle::{self, TrieError, TrieFactory}; use ctypes::errors::{RuntimeError, UnlockFailureReason}; use ctypes::transaction::{ - AssetMintOutput, AssetOutPoint, AssetTransferInput, AssetTransferOutput, AssetWrapCCCOutput, Order, - OrderOnTransfer, PartialHashing, ShardTransaction, + AssetMintOutput, AssetOutPoint, AssetTransferInput, AssetTransferOutput, AssetWrapCCCOutput, PartialHashing, + ShardTransaction, }; use ctypes::util::unexpected::Mismatch; use ctypes::{BlockNumber, ShardId}; @@ -137,7 +137,6 @@ impl<'db> ShardLevelState<'db> { burns, inputs, outputs, - orders, .. } => { debug_assert!(outputs.len() <= 512); @@ -148,7 +147,6 @@ impl<'db> ShardLevelState<'db> { burns, inputs, outputs, - orders, client, parent_block_number, parent_block_timestamp, @@ -261,7 +259,6 @@ impl<'db> ShardLevelState<'db> { output.lock_script_hash, output.parameters.clone(), output.supply, - None, )?; ctrace!(TX, "Created asset on {}:{}:{}", self.shard_id, transaction_tracker, 0); Ok(()) @@ -277,24 +274,14 @@ impl<'db> ShardLevelState<'db> { burns: &[AssetTransferInput], inputs: &[AssetTransferInput], outputs: &[AssetTransferOutput], - orders: &[OrderOnTransfer], client: &C, parent_block_number: BlockNumber, parent_block_timestamp: u64, ) -> StateResult<()> { - let mut values_to_hash = vec![None; inputs.len()]; - for order_tx in orders { - let order = &order_tx.order; - for input_idx in order_tx.input_from_indices.iter().chain(order_tx.input_fee_indices.iter()) { - values_to_hash[*input_idx] = Some(order); - } - } - - for (input, transaction, order, burn) in inputs + for (input, transaction, burn) in inputs .iter() - .enumerate() - .map(|(index, input)| (input, transaction, values_to_hash[index], false)) - .chain(burns.iter().map(|input| (input, transaction, None, true))) + .map(|input| (input, transaction, false)) + .chain(burns.iter().map(|input| (input, transaction, true))) { if input.prev_out.shard_id != self.shard_id { continue @@ -302,7 +289,6 @@ impl<'db> ShardLevelState<'db> { self.check_and_run_input_script( input, transaction, - order, burn, sender, approvers, @@ -312,21 +298,6 @@ impl<'db> ShardLevelState<'db> { )?; } - self.check_orders(orders, inputs)?; - let mut output_order_hashes = vec![None; outputs.len()]; - for order_tx in orders { - let order = &order_tx.order; - for output_idx in order_tx - .output_from_indices - .iter() - .chain(order_tx.output_to_indices.iter()) - .chain(order_tx.output_owned_fee_indices.iter()) - .chain(order_tx.output_transferred_fee_indices.iter()) - { - output_order_hashes[*output_idx] = Some(order.consume(order_tx.spent_quantity).hash()); - } - } - let mut deleted_asset = Vec::with_capacity(inputs.len() + burns.len()); for input in inputs.iter().chain(burns) { if input.prev_out.shard_id != self.shard_id { @@ -348,7 +319,6 @@ impl<'db> ShardLevelState<'db> { output.lock_script_hash, output.parameters.clone(), output.quantity, - output_order_hashes[index], )?; } let mut reduced_supplies = Vec::with_capacity(burns.len()); @@ -373,41 +343,6 @@ impl<'db> ShardLevelState<'db> { Ok(()) } - fn check_orders(&self, orders: &[OrderOnTransfer], inputs: &[AssetTransferInput]) -> StateResult<()> { - for order_tx in orders { - let order = &order_tx.order; - let mut counter: usize = 0; - for input_idx in order_tx.input_from_indices.iter().chain(order_tx.input_fee_indices.iter()) { - let input = &inputs[*input_idx]; - let tracker = input.prev_out.tracker; - let index = input.prev_out.index; - if input.prev_out.shard_id != self.shard_id { - continue - } - let asset = self.asset(tracker, index)?.ok_or_else(|| RuntimeError::AssetNotFound { - shard_id: self.shard_id, - tracker, - index, - })?; - - match &asset.order_hash() { - Some(order_hash) if *order_hash == order.hash() => {} - _ => { - if order.origin_outputs.contains(&input.prev_out) { - counter += 1; - } else { - return Err(RuntimeError::InvalidOriginOutputs(order.hash()).into()) - } - } - } - } - if counter > 0 && counter != order.origin_outputs.len() { - return Err(RuntimeError::InvalidOriginOutputs(order.hash()).into()) - } - } - Ok(()) - } - fn approved_by_registrar(&self, asset_type: H160, sender: &Address, approvers: &[Address]) -> StateResult { let asset_scheme = self.asset_scheme(asset_type)?.ok_or_else(|| RuntimeError::AssetSchemeNotFound { asset_type, @@ -493,7 +428,6 @@ impl<'db> ShardLevelState<'db> { output.lock_script_hash, output.parameters.clone(), output.supply, - None, )?; ctrace!(TX, "Increased asset supply {:?} {:?} => {:?}", asset_type, previous_supply, output.supply); ctrace!(TX, "Created asset on {}:{}", self.shard_id, transaction_tracker); @@ -588,7 +522,6 @@ impl<'db> ShardLevelState<'db> { &self, input: &AssetTransferInput, transaction: &PartialHashing, - order: Option<&Order>, burn: bool, sender: &Address, approvers: &[Address], @@ -596,25 +529,12 @@ impl<'db> ShardLevelState<'db> { parent_block_number: BlockNumber, parent_block_timestamp: u64, ) -> StateResult<()> { - debug_assert!(!burn || order.is_none()); - let (asset, from_regulator) = self.check_input_asset(input, sender, approvers)?; if from_regulator { return Ok(()) // Don't execute scripts when regulator sends the transaction. } - let to_hash: &PartialHashing = if let Some(order) = order { - if let Some(order_hash) = &asset.order_hash() { - if *order_hash == order.hash() { - // If an order on an input and an order on the corresponding prev_out(asset) is same, - // then skip checking lock script and running VM. - return Ok(()) - } - } - order - } else { - transaction - }; + let to_hash: &PartialHashing = transaction; if *asset.lock_script_hash() != Blake::blake(&input.lock_script) { return Err(RuntimeError::ScriptHashMismatch(Mismatch { @@ -685,7 +605,7 @@ impl<'db> ShardLevelState<'db> { let mut asset_scheme = self.get_asset_scheme_mut(self.shard_id, asset_type)?; asset_scheme.increase_supply(quantity)?; - self.create_asset(*tx_hash, 0, asset_type, *lock_script_hash, parameters.to_vec(), quantity, None)?; + self.create_asset(*tx_hash, 0, asset_type, *lock_script_hash, parameters.to_vec(), quantity)?; ctrace!(TX, "Created Wrapped CCC on {}:{}:{}", self.shard_id, tx_hash, 0); Ok(()) } @@ -704,7 +624,6 @@ impl<'db> ShardLevelState<'db> { self.check_and_run_input_script( burn, transaction, - None, true, sender, &approvers, @@ -762,10 +681,9 @@ impl<'db> ShardLevelState<'db> { lock_script_hash: H160, parameters: Vec, quantity: u64, - order_hash: Option, ) -> cmerkle::Result { self.cache.create_asset(&OwnedAssetAddress::new(tracker, index, self.shard_id), || { - OwnedAsset::new(asset_type, lock_script_hash, parameters, quantity, order_hash) + OwnedAsset::new(asset_type, lock_script_hash, parameters, quantity) }) } @@ -874,8 +792,6 @@ impl<'db> ShardStateView for ReadOnlyShardLevelState<'db> { #[cfg(test)] mod tests { - use ctypes::transaction::AssetOutPoint; - use super::super::super::StateError; use super::super::test_helper::SHARD_ID; use super::*; @@ -1090,7 +1006,6 @@ mod tests { assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); - check_shard_level_state!(state, [ (scheme: (asset_type) => { metadata: metadata, supply: amount, allowed_script_hashes: allowed_script_hashes}), (asset: (mint_tracker, 0) => { asset_type: asset_type, quantity: amount }) @@ -1139,6 +1054,7 @@ mod tests { assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); + check_shard_level_state!(state, [ (scheme: (asset_type) => { metadata: metadata, supply: amount, allowed_script_hashes: allowed_script_hashes}), (asset: (mint_tracker, 0) => { asset_type: asset_type, quantity: amount }) @@ -1453,91 +1369,6 @@ mod tests { ]); } - fn mint_for_transfer(state: &mut ShardLevelState, sender: Address, metadata: String, amount: u64) -> AssetOutPoint { - let lock_script_hash = H160::from("b042ad154a3359d276835c903587ebafefea22af"); - let mint = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata.clone()); - let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); - assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), - (asset: (mint_tracker, 0) => { asset_type: asset_type, quantity: amount }) - ]); - - asset_out_point!(mint_tracker, 0, asset_type, amount) - } - - #[test] - #[allow(clippy::cognitive_complexity)] - fn mint_three_times_and_transfer_with_order() { - let sender = address(); - let mut state_db = RefCell::new(get_temp_state_db()); - let mut shard_cache = ShardCache::default(); - let mut state = get_temp_shard_state(&mut state_db, SHARD_ID, &mut shard_cache); - - let mint_output_1 = mint_for_transfer(&mut state, sender, "metadata1".to_string(), 30); - let mint_output_2 = mint_for_transfer(&mut state, sender, "metadata2".to_string(), 30); - let mint_output_3 = mint_for_transfer(&mut state, sender, "metadata3".to_string(), 30); - let asset_type_1 = mint_output_1.asset_type; - let asset_type_2 = mint_output_2.asset_type; - let asset_type_3 = mint_output_3.asset_type; - - let lock_script_hash = H160::from("b042ad154a3359d276835c903587ebafefea22af"); - let order = order!(from: (asset_type_1, 20), to: (asset_type_2, 10), fee: (asset_type_3, 20), - [mint_output_1.clone(), mint_output_3.clone()], - 10, - lock_script_hash - ); - let order_consumed = order.consume(20); - let order_consumed_hash = order_consumed.hash(); - - let transfer = asset_transfer!( - inputs: - asset_transfer_inputs![ - (mint_output_1.clone(), vec![0x30, 0x01]), - (mint_output_2.clone(), vec![0x30, 0x01]), - (mint_output_3.clone(), vec![0x30, 0x01]), - ], - asset_transfer_outputs![ - (lock_script_hash, asset_type_1, 10), - (lock_script_hash, asset_type_2, 10), - (lock_script_hash, asset_type_3, 10), - (lock_script_hash, asset_type_1, 20), - (lock_script_hash, asset_type_2, 20), - (lock_script_hash, vec![vec![0x1]], asset_type_3, 20), - ], - vec![order_on_transfer! ( - order, - 20, - input_from_indices: [0], - input_fee_indices: [2], - output_from_indices: [0], - output_to_indices: [1], - output_owned_fee_indices: [2], - output_transferred_fee_indices: [5] - )] - ); - let transfer_tracker = transfer.tracker(); - - assert_eq!(Ok(()), state.apply(&transfer, &sender, &[sender], &[], &get_test_client(), 0, 0)); - - check_shard_level_state!(state, [ - (scheme: (asset_type_1) => { metadata: "metadata1".to_string(), supply: 30 }), - (scheme: (asset_type_2) => { metadata: "metadata2".to_string(), supply: 30 }), - (scheme: (asset_type_3) => { metadata: "metadata3".to_string(), supply: 30 }), - (asset: (mint_output_1.tracker, 0)), - (asset: (mint_output_2.tracker, 0)), - (asset: (mint_output_3.tracker, 0)), - (asset: (transfer_tracker, 0) => { asset_type: asset_type_1, quantity: 10, order: order_consumed_hash }), - (asset: (transfer_tracker, 1) => { asset_type: asset_type_2, quantity: 10, order: order_consumed_hash }), - (asset: (transfer_tracker, 2) => { asset_type: asset_type_3, quantity: 10, order: order_consumed_hash }), - (asset: (transfer_tracker, 3) => { asset_type: asset_type_1, quantity: 20, order }), - (asset: (transfer_tracker, 4) => { asset_type: asset_type_2, quantity: 20, order }), - (asset: (transfer_tracker, 5) => { asset_type: asset_type_3, quantity: 20, order: order_consumed_hash }) - ]); - } - #[test] fn wrap_and_unwrap_ccc() { let sender = address(); diff --git a/state/src/impls/test_helper.rs b/state/src/impls/test_helper.rs index cfe4999226..78544c9b71 100644 --- a/state/src/impls/test_helper.rs +++ b/state/src/impls/test_helper.rs @@ -211,7 +211,6 @@ macro_rules! transfer_asset { burns: Vec::new(), inputs: $inputs, outputs: $outputs, - orders: Vec::new(), metadata: "".into(), approvals: vec![], expiration: None, @@ -223,19 +222,17 @@ macro_rules! transfer_asset { burns: Vec::new(), inputs: $inputs, outputs: $outputs, - orders: Vec::new(), metadata: "".into(), approvals: $approvals, expiration: None, } }; - (inputs: $inputs:expr, $outputs:expr, $orders:expr) => { + (inputs: $inputs:expr, $outputs:expr) => { $crate::ctypes::transaction::Action::TransferAsset { network_id: $crate::impls::test_helper::NETWORK_ID.into(), burns: Vec::new(), inputs: $inputs, outputs: $outputs, - orders: $orders, metadata: "".into(), approvals: vec![], expiration: None, @@ -247,7 +244,6 @@ macro_rules! transfer_asset { burns: $burns, inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), metadata: "".into(), approvals: vec![], expiration: None, @@ -262,16 +258,14 @@ macro_rules! asset_transfer { burns: Vec::new(), inputs: $inputs, outputs: $outputs, - orders: Vec::new(), } }; - (inputs: $inputs:expr, $outputs:expr, $orders:expr) => { + (inputs: $inputs:expr, $outputs:expr) => { $crate::ctypes::transaction::ShardTransaction::TransferAsset { network_id: $crate::impls::test_helper::NETWORK_ID.into(), burns: Vec::new(), inputs: $inputs, outputs: $outputs, - orders: $orders, } }; (burns: $burns:expr) => { @@ -280,50 +274,10 @@ macro_rules! asset_transfer { burns: $burns, inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } }; } -macro_rules! order { - (from: ($from:expr, $from_quantity:expr), to: ($to:expr, $to_quantity:expr), fee: ($fee:expr, $fee_quantity:expr), [$($output:expr),*], $expiration:expr, $lock_script_hash:expr) => { - $crate::ctypes::transaction::Order { - asset_type_from: $from, - asset_type_to: $to, - asset_type_fee: $fee, - shard_id_from: $crate::impls::test_helper::SHARD_ID, - shard_id_to: $crate::impls::test_helper::SHARD_ID, - shard_id_fee: $crate::impls::test_helper::SHARD_ID, - asset_quantity_from: $from_quantity, - asset_quantity_to: $to_quantity, - asset_quantity_fee: $fee_quantity, - origin_outputs: vec![$($output,)*], - expiration: $expiration, - lock_script_hash_from: $lock_script_hash, - parameters_from: Vec::new(), - lock_script_hash_fee: $lock_script_hash, - parameters_fee: vec![vec![0x1]], - } - } -} - -macro_rules! order_on_transfer { - ($order:expr, $spent_quantity:expr, input_from_indices: [$($input_from:expr),*], input_fee_indices: [$($input_fee:expr),*], - output_from_indices: [$($output_from:expr),*], output_to_indices: [$($output_to:expr),*], output_owned_fee_indices: [$($output_owned:expr),*], - output_transferred_fee_indices: [$($output_transferred:expr),*]) => { - $crate::ctypes::transaction::OrderOnTransfer { - order: $order, - spent_quantity: $spent_quantity, - input_from_indices: vec![$($input_from,)*], - input_fee_indices: vec![$($input_fee,)*], - output_from_indices: vec![$($output_from,)*], - output_to_indices: vec![$($output_to,)*], - output_owned_fee_indices: vec![$($output_owned,)*], - output_transferred_fee_indices: vec![$($output_transferred,)*] - } - } -} - macro_rules! asset_wrap_ccc_output { ($lock_script_hash:expr, $quantity:expr) => { $crate::ctypes::transaction::AssetWrapCCCOutput { @@ -499,7 +453,7 @@ macro_rules! set_top_level_state { set_top_level_state!($state, [$($x),*]); }; ($state:expr, [(asset: ($shard:expr, $tx_hash:expr, $index:expr) => { asset_type: $asset_type: expr, quantity: $quantity:expr, lock_script_hash: $lock_script_hash:expr }) $(,$x:tt)*]) => { - assert_eq!(Ok((true)), $state.create_asset($shard, $tx_hash, $index, $asset_type, $lock_script_hash, Vec::new(), $quantity, None)); + assert_eq!(Ok((true)), $state.create_asset($shard, $tx_hash, $index, $asset_type, $lock_script_hash, Vec::new(), $quantity)); set_top_level_state!($state, [$($x),*]); }; @@ -696,23 +650,21 @@ macro_rules! check_shard_level_state { check_shard_level_state!($state, [$($x),*]); }; - ($state:expr, [(asset: ($tx_hash:expr, $index:expr) => { asset_type: $asset_type:expr, quantity: $quantity:expr, order: $order:expr }) $(,$x:tt)*]) => { + ($state:expr, [(asset: ($tx_hash:expr, $index:expr) => { asset_type: $asset_type:expr, quantity: $quantity:expr }) $(,$x:tt)*]) => { let asset = $state.asset($tx_hash, $index) .expect(&format!("Cannot read Asset from {}:{}:{}", $state.shard_id(), $tx_hash, $index)) .expect(&format!("Asset for {}:{}:{} not exist", $state.shard_id(), $tx_hash, $index)); assert_eq!(&$asset_type, asset.asset_type()); assert_eq!($quantity, asset.quantity()); - assert_eq!(Some(&$order), asset.order_hash().as_ref()); check_shard_level_state!($state, [$($x),*]); }; - ($state:expr, [(asset: ($tx_hash:expr, $index:expr) => { asset_type: $asset_type:expr, quantity: $quantity:expr, order }) $(,$x:tt)*]) => { + ($state:expr, [(asset: ($tx_hash:expr, $index:expr) => { asset_type: $asset_type:expr, quantity: $quantity:expr }) $(,$x:tt)*]) => { let asset = $state.asset($tx_hash, $index) .expect(&format!("Cannot read Asset from {}:{}:{}", $state.shard_id(), $tx_hash, $index)) .expect(&format!("Asset for {}:{}:{} not exist", $state.shard_id(), $tx_hash, $index)); assert_eq!(&$asset_type, asset.asset_type()); assert_eq!($quantity, asset.quantity()); - assert_eq!(&None, asset.order_hash()); check_shard_level_state!($state, [$($x),*]); }; diff --git a/state/src/impls/top_level.rs b/state/src/impls/top_level.rs index 53c46cd04a..ba4fe10b79 100644 --- a/state/src/impls/top_level.rs +++ b/state/src/impls/top_level.rs @@ -751,13 +751,12 @@ impl TopLevelState { lock_script_hash: H160, parameters: Vec, amount: u64, - order_hash: Option, ) -> TrieResult { match self.shard_root(shard_id)? { Some(shard_root) => { let mut shard_cache = self.shard_caches.entry(shard_id).or_default(); let state = ShardLevelState::from_existing(shard_id, &mut self.db, shard_root, &mut shard_cache)?; - state.create_asset(tx_hash, index, asset_type, lock_script_hash, parameters, amount, order_hash)?; + state.create_asset(tx_hash, index, asset_type, lock_script_hash, parameters, amount)?; Ok(true) } None => Ok(false), diff --git a/state/src/item/asset.rs b/state/src/item/asset.rs index 9a8619a2a8..70552d2805 100644 --- a/state/src/item/asset.rs +++ b/state/src/item/asset.rs @@ -48,17 +48,10 @@ pub struct OwnedAsset { asset: Asset, lock_script_hash: H160, parameters: Vec, - order_hash: Option, } impl OwnedAsset { - pub fn new( - asset_type: H160, - lock_script_hash: H160, - parameters: Vec, - quantity: u64, - order_hash: Option, - ) -> Self { + pub fn new(asset_type: H160, lock_script_hash: H160, parameters: Vec, quantity: u64) -> Self { Self { asset: Asset { asset_type, @@ -66,7 +59,6 @@ impl OwnedAsset { }, lock_script_hash, parameters, - order_hash, } } @@ -85,10 +77,6 @@ impl OwnedAsset { pub fn quantity(&self) -> u64 { self.asset.quantity() } - - pub fn order_hash(&self) -> &Option { - &self.order_hash - } } impl Default for OwnedAsset { @@ -100,7 +88,6 @@ impl Default for OwnedAsset { }, lock_script_hash: H160::zero(), parameters: vec![], - order_hash: None, } } } @@ -123,7 +110,8 @@ impl Encodable for OwnedAsset { .append(&self.asset.quantity()) .append(&self.lock_script_hash) .append(&self.parameters) - .append(&self.order_hash); + // NOTE: The order_hash field removed. + .append(&Option::::None); } } @@ -142,6 +130,11 @@ impl Decodable for OwnedAsset { cdebug!(STATE, "{} is not an expected prefix for asset", prefix); return Err(DecoderError::Custom("Unexpected prefix")) } + let order_hash = rlp.val_at::>(5)?; + if let Some(h) = order_hash { + cdebug!(STATE, "order_hash must be None but Some({}) is given", h); + return Err(DecoderError::Custom("order_hash must be None")) + } Ok(Self { asset: Asset { asset_type: rlp.val_at(1)?, @@ -149,7 +142,6 @@ impl Decodable for OwnedAsset { }, lock_script_hash: rlp.val_at(3)?, parameters: rlp.val_at(4)?, - order_hash: rlp.val_at(5)?, }) } } diff --git a/test/src/e2e.long/orders.test.ts b/test/src/e2e.long/orders.test.ts deleted file mode 100644 index e8ddabb26d..0000000000 --- a/test/src/e2e.long/orders.test.ts +++ /dev/null @@ -1,2988 +0,0 @@ -// Copyright 2018-2019 Kodebox, Inc. -// This file is part of CodeChain. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -import { expect } from "chai"; -import { Asset, AssetAddress, H160, U64 } from "codechain-sdk/lib/core/classes"; -import * as _ from "lodash"; -import "mocha"; -import { faucetAddress, faucetSecret } from "../helper/constants"; -import { ERROR } from "../helper/error"; -import CodeChain from "../helper/spawn"; - -describe("orders", function() { - let node: CodeChain; - - before(async function() { - node = new CodeChain({ - env: { - ENABLE_ORDER: "true" - } - }); - await node.start(); - }); - - describe("AssetTransfer with orders", function() { - describe("Mint one asset", function() { - let aliceAddress: AssetAddress; - - let gold: Asset; - - beforeEach(async function() { - aliceAddress = await node.createP2PKHAddress(); - gold = await node.mintAsset({ - supply: 10000, - recipient: aliceAddress - }); - }); - - it("Wrong order - originOutputs are wrong (asset type from/to is same)", async function() { - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(gold) - .addOutputs( - _.times(2, () => ({ - recipient: aliceAddress, - quantity: 5000, - assetType: gold.assetType, - shardId: 0 - })) - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitGolds = splitTx.getTransferredAssets(); - const splitGoldInputs = splitGolds.map((g: Asset) => - g.createTransferInput() - ); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: H160.zero(), // Fake asset type - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 5000, - assetQuantityTo: 5000, - expiration, - originOutputs: [splitGoldInputs[0].prevOut], - recipientFrom: aliceAddress - }); - - (order.assetTypeTo as any) = gold.assetType; - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(splitGoldInputs) - .addOutputs( - { - recipient: aliceAddress, - quantity: 5000, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 5000, - assetType: gold.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 5000, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.INVALID_ORDER_ASSET_TYPES); - } - }); - }); - - describe("Mint two assets", function() { - let aliceAddress: AssetAddress; - let bobAddress: AssetAddress; - - let gold: Asset; - let silver: Asset; - - beforeEach(async function() { - aliceAddress = await node.createP2PKHAddress(); - bobAddress = await node.createP2PKHAddress(); - gold = await node.mintAsset({ - supply: 10000, - recipient: aliceAddress - }); - silver = await node.mintAsset({ - supply: 10000, - recipient: bobAddress - }); - }); - - it("Correct order, correct transfer", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const hash = await node.sendAssetTransaction(transferTx); - expect(await node.sdk.rpc.chain.containsTransaction(hash)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null; - }); - - it("Correct order, correct transfer - Many originOutputs", async function() { - // Split minted gold asset to 10 assets - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(gold) - .addOutputs( - _.times(10, () => ({ - recipient: aliceAddress, - quantity: 1000, - assetType: gold.assetType, - shardId: 0 - })) - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitGolds = splitTx.getTransferredAssets(); - const splitGoldInputs = splitGolds.map(g => - g.createTransferInput() - ); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: splitGoldInputs.map(input => input.prevOut), - recipientFrom: aliceAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(splitGoldInputs) - .addInputs(silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: _.range(10), - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await Promise.all( - _.range((transferTx as any)._transaction.inputs.length).map( - i => node.signTransactionInput(transferTx, i) - ) - ); - - const hash = await node.sendAssetTransaction(transferTx); - expect(await node.sdk.rpc.chain.containsTransaction(hash)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null; - }).timeout(10_000); - - it("Correct order, correct transfer - Output(to) is empty", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 10000, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 10000, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 10000, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [], - outputToIndices: [0], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const hash = await node.sendAssetTransaction(transferTx); - expect(await node.sdk.rpc.chain.containsTransaction(hash)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null; - }); - - it("Correct order, correct transfer - Splitted output", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 1000, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 9000, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 1000, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 4500, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 4500, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 1000, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [1], - outputToIndices: [0], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const hash = await node.sendAssetTransaction(transferTx); - expect(await node.sdk.rpc.chain.containsTransaction(hash)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null; - }); - - it("Correct two orders, correct transfer - Ratio is same", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const aliceOrder = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - - const bobOrder = node.sdk.core.createOrder({ - assetTypeFrom: silver.assetType, - assetTypeTo: gold.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 1000, - assetQuantityTo: 100, - expiration, - originOutputs: [silverInput.prevOut], - recipientFrom: bobAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order: aliceOrder, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }) - .addOrder({ - order: bobOrder, - spentQuantity: 1000, - inputFromIndices: [1], - inputFeeIndices: [], - outputFromIndices: [3], - outputToIndices: [2], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const hash = await node.sendAssetTransaction(transferTx); - expect(await node.sdk.rpc.chain.containsTransaction(hash)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null; - }); - - it("Correct two orders, correct transfer - Ratio is different", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const aliceOrder = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - - const bobOrder = node.sdk.core.createOrder({ - assetTypeFrom: silver.assetType, - assetTypeTo: gold.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 1000, - assetQuantityTo: 50, - expiration, - originOutputs: [silverInput.prevOut], - recipientFrom: bobAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - // Bob gets more gold than he wanted. - // If there's a relayer, relayer may take it. - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order: aliceOrder, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }) - .addOrder({ - order: bobOrder, - spentQuantity: 1000, - inputFromIndices: [1], - inputFeeIndices: [], - outputFromIndices: [3], - outputToIndices: [2], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const hash = await node.sendAssetTransaction(transferTx); - expect(await node.sdk.rpc.chain.containsTransaction(hash)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null; - }); - - it("Correct order, correct transfer - Charlie get some of asset without order", async function() { - const charlieAddress = await node.createP2PKHAddress(); - // Split minted gold asset to 10 assets - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(gold) - .addOutputs( - _.times(10, () => ({ - recipient: aliceAddress, - quantity: 1000, - assetType: gold.assetType, - shardId: 0 - })) - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitGolds = splitTx.getTransferredAssets(); - const splitGoldInputs = splitGolds.map(g => - g.createTransferInput() - ); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 3000, - assetQuantityTo: 7500, - expiration, - originOutputs: [splitGoldInputs[0].prevOut], - recipientFrom: aliceAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs([...splitGoldInputs.slice(0, 3), silverInput]) - .addOutputs( - { - recipient: aliceAddress, - quantity: 2500, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 1000, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 7500, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 2000, - assetType: gold.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 1000, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [], - outputToIndices: [0], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - await node.signTransactionInput(transferTx, 2); - await node.signTransactionInput(transferTx, 3); - - const hash = await node.sendAssetTransaction(transferTx); - expect(await node.sdk.rpc.chain.containsTransaction(hash)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null; - }); - - it("Correct order, wrong transfer - Output(from) is empty", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 10000, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 10000, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 10000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 0, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo( - ERROR.INCONSISTENT_TRANSACTION_IN_OUT_WITH_ORDERS - ); - } - }); - - it("Correct order, wrong transfer - Spend too much", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9800, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 2000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 200, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 8000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 200, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.INVALID_SPENT_QUANTITY); - } - }); - - it("Correct order, wrong transfer - Ratio is wrong", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000 - 10, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000 + 10, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo( - ERROR.INCONSISTENT_TRANSACTION_IN_OUT_WITH_ORDERS - ); - } - }); - - it("Correct order, wrong transfer - Lock script hash of maker is wrong", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - - (transferTx.orders()[0].order - .lockScriptHashFrom as any) = new H160( - "0000000000000000000000000000000000000000" - ); - - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo( - ERROR.INVALID_ORDER_LOCK_SCRIPT_HASH - ); - } - }); - - it("Correct order, wrong transfer - Parameters of maker are wrong", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - - (transferTx.orders()[0].order.parametersFrom as any) = []; - - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.INVALID_ORDER_PARAMETERS); - } - }); - - it("Correct order, Correct transfer - many outputs (from)", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900 - 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0, 1], - outputToIndices: [2], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const hash = await node.sendAssetTransaction(transferTx); - expect(await node.sdk.rpc.chain.containsTransaction(hash)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null; - }); - - it("Correct order, Correct transfer - many outputs (to)", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000 - 100, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 100, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1, 2], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const hash = await node.sendAssetTransaction(transferTx); - expect(await node.sdk.rpc.chain.containsTransaction(hash)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null; - }); - - it("Correct order, Correct transfer - many outputs (both)", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900 - 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000 - 100, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 100, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0, 1], - outputToIndices: [2, 3], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const hash = await node.sendAssetTransaction(transferTx); - expect(await node.sdk.rpc.chain.containsTransaction(hash)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null; - }); - - it("Wrong order - originOutputs are wrong (empty)", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - (order.originOutputs as any) = []; - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.INVALID_ORIGIN_OUTPUTS); - } - }); - - it("Wrong order - originOutputs are wrong (prevOut does not match)", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [silverInput.prevOut], - recipientFrom: aliceAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.INVALID_ORIGIN_OUTPUTS); - } - }); - - it("Wrong order - originOutputs are wrong (Quantity is not enough)", async function() { - // Split minted gold asset to 10 assets - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(gold) - .addOutputs( - _.times(10, () => ({ - recipient: aliceAddress, - quantity: 1000, - assetType: gold.assetType, - shardId: 0 - })) - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitGolds = splitTx.getTransferredAssets(); - const splitGoldInputs = splitGolds.map(g => - g.createTransferInput() - ); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 3000, - assetQuantityTo: 7500, - expiration, - originOutputs: [splitGoldInputs[0].prevOut], - recipientFrom: aliceAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs([...splitGoldInputs.slice(0, 3), silverInput]) - .addOutputs( - { - recipient: aliceAddress, - quantity: 7500, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 3000, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 2500, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 3000, - inputFromIndices: [0, 1, 2], - inputFeeIndices: [], - outputFromIndices: [], - outputToIndices: [0], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 1); - - await node.sendAssetTransactionExpectedToFail(transferTx); - }).timeout(10_000); - - it("Wrong order - originOutputs are wrong (few outputs)", async function() { - // Split minted gold asset to 10 assets - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(gold) - .addOutputs( - _.times(10, () => ({ - recipient: aliceAddress, - quantity: 1000, - assetType: gold.assetType, - shardId: 0 - })) - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitGolds = splitTx.getTransferredAssets(); - const splitGoldInputs = splitGolds.map(g => - g.createTransferInput() - ); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: splitGoldInputs - .slice(0, 9) - .map(input => input.prevOut), - recipientFrom: aliceAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(splitGoldInputs) - .addInputs(silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: _.range(10), - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await Promise.all( - _.range((transferTx as any)._transaction.inputs.length).map( - i => node.signTransactionInput(transferTx, i) - ) - ); - - await node.sendAssetTransactionExpectedToFail(transferTx); - }).timeout(10_000); - - it("Wrong order - originOutputs are wrong (many outputs)", async function() { - // Split minted gold asset to 10 assets - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(gold) - .addOutputs( - _.times(10, () => ({ - recipient: aliceAddress, - quantity: 1000, - assetType: gold.assetType, - shardId: 0 - })) - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitGolds = splitTx.getTransferredAssets(); - const splitGoldInputs = splitGolds.map(g => - g.createTransferInput() - ); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: splitGoldInputs.map(input => input.prevOut), - recipientFrom: aliceAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(splitGoldInputs.slice(0, 9)) - .addInputs(silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 8900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: _.range(9), - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await Promise.all( - _.range((transferTx as any)._transaction.inputs.length).map( - i => node.signTransactionInput(transferTx, i) - ) - ); - - await node.sendAssetTransactionExpectedToFail(transferTx); - }).timeout(10_000); - - it("Wrong order - Ratio is wrong (from is zero)", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - (order.assetQuantityFrom as any) = new U64(0); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo( - ERROR.INVALID_ORDER_ASSET_QUANTITIES - ); - } - }); - - it("Wrong order - Ratio is wrong (to is zero)", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - (order.assetQuantityTo as any) = new U64(0); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo( - ERROR.INVALID_ORDER_ASSET_QUANTITIES - ); - } - }); - - it("Wrong order - Expiration is old", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = 0; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.ORDER_EXPIRED); - } - }); - - it("Successful partial fills", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - - const transferTx1 = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9950, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 500, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 50, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9500, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 50, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx1, 0); - await node.signTransactionInput(transferTx1, 1); - - const hash1 = await node.sendAssetTransaction(transferTx1); - expect(await node.sdk.rpc.chain.containsTransaction(hash1)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash1)).not.null; - - const orderConsumed = order.consume(50); - const transferTx2 = node.sdk.core - .createTransferAssetTransaction() - .addInputs( - transferTx1.getTransferredAsset(0), - transferTx1.getTransferredAsset(3) - ) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 500, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 50, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order: orderConsumed, - spentQuantity: 50, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - // Sign on input 0 is not needed - await node.signTransactionInput(transferTx2, 1); - - const hash2 = await node.sendAssetTransaction(transferTx2); - expect(await node.sdk.rpc.chain.containsTransaction(hash2)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash2)).not.null; - }).timeout(10_000); - - it("Successful mutual partial fills", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const aliceOrder = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const bobOrder = node.sdk.core.createOrder({ - assetTypeFrom: silver.assetType, - assetTypeTo: gold.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 1000, - assetQuantityTo: 50, - expiration, - originOutputs: [silverInput.prevOut], - recipientFrom: bobAddress - }); - - const transferTx1 = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9990, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 100, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 10, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9900, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order: aliceOrder, - spentQuantity: 10, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }) - .addOrder({ - order: bobOrder, - spentQuantity: 100, - inputFromIndices: [1], - inputFeeIndices: [], - outputFromIndices: [3], - outputToIndices: [2], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx1, 0); - await node.signTransactionInput(transferTx1, 1); - - const hash1 = await node.sendAssetTransaction(transferTx1); - expect(await node.sdk.rpc.chain.containsTransaction(hash1)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash1)).not.null; - - const aliceOrderConsumed = aliceOrder.consume(10); - const bobOrderConsumed = bobOrder.consume(100); - const transferTx2 = node.sdk.core - .createTransferAssetTransaction() - .addInputs( - transferTx1.getTransferredAsset(0), - transferTx1.getTransferredAsset(3) - ) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9990 - 50, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 500, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 50, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9900 - 500, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order: aliceOrderConsumed, - spentQuantity: 50, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }) - .addOrder({ - order: bobOrderConsumed, - spentQuantity: 500, - inputFromIndices: [1], - inputFeeIndices: [], - outputFromIndices: [3], - outputToIndices: [2], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - // Sign on both inputs 0, 1 are not needed - - const hash2 = await node.sendAssetTransaction(transferTx2); - expect(await node.sdk.rpc.chain.containsTransaction(hash2)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash2)).not.null; - }).timeout(10_000); - - it("Successful partial cancel", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx1 = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9950, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 500, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 50, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9500, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 50, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx1, 0); - await node.signTransactionInput(transferTx1, 1); - - const hash1 = await node.sendAssetTransaction(transferTx1); - expect(await node.sdk.rpc.chain.containsTransaction(hash1)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash1)).not.null; - - const transferTx2 = node.sdk.core - .createTransferAssetTransaction() - .addInputs( - transferTx1.getTransferredAsset(0), - transferTx1.getTransferredAsset(3) - ) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9500, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9950, - assetType: gold.assetType, - shardId: 0 - } - ); - await node.signTransactionInput(transferTx2, 0); - await node.signTransactionInput(transferTx2, 1); - - const hash2 = await node.sendAssetTransaction(transferTx2); - expect(await node.sdk.rpc.chain.containsTransaction(hash2)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash2)).not.null; - }); - }).timeout(10_000); - - describe("Mint three assets ", function() { - let aliceAddress: AssetAddress; - let bobAddress: AssetAddress; - let charlieAddress: AssetAddress; - - let gold: Asset; - let silver: Asset; - let bronze: Asset; - let feeAsset: Asset; - - beforeEach(async function() { - aliceAddress = await node.createP2PKHAddress(); - bobAddress = await node.createP2PKHAddress(); - charlieAddress = await node.createP2PKHAddress(); - const FeeOwnerAddress = await node.createP2PKHAddress(); - gold = await node.mintAsset({ - supply: 10000, - recipient: aliceAddress - }); - silver = await node.mintAsset({ - supply: 10000, - recipient: bobAddress - }); - bronze = await node.mintAsset({ - supply: 10000, - recipient: FeeOwnerAddress - }); - - const bronzeInput = bronze.createTransferInput(); - const transferTx1 = node.sdk.core - .createTransferAssetTransaction() - .addInputs(bronzeInput) - .addOutputs({ - recipient: aliceAddress, - quantity: 10000, - assetType: bronze.assetType, - shardId: 0 - }); - await node.signTransactionInput(transferTx1, 0); - await node.sendAssetTransaction(transferTx1); - feeAsset = transferTx1.getTransferredAsset(0); - }); - - it("Correct order - originOutputs fee is not enough but Ok", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - const feeInput = feeAsset.createTransferInput(); - - // Split minted gold asset to 10 assets - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(feeInput) - .addOutputs( - _.times(10, () => ({ - recipient: aliceAddress, - quantity: 1000, - assetType: bronze.assetType, - shardId: 0 - })) - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitFees = splitTx.getTransferredAssets(); - const splitFeeInputs = splitFees.map(g => - g.createTransferInput() - ); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - assetTypeFee: bronze.assetType, - shardIdFrom: 0, - shardIdTo: 0, - shardIdFee: 0, - assetQuantityFrom: 1000, - assetQuantityTo: 10000, - assetQuantityFee: 2000, - expiration, - originOutputs: [ - goldInput.prevOut, - splitFeeInputs[0].prevOut - ], - recipientFrom: aliceAddress, - recipientFee: charlieAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput, splitFeeInputs[0]) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 800, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 200, - assetType: bronze.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [2], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [2], - outputTransferredFeeIndices: [5] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - await node.signTransactionInput(transferTx, 2); - - const hash = await node.sendAssetTransaction(transferTx); - expect(await node.sdk.rpc.chain.containsTransaction(hash)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null; - }); - - it("Correct order, correct transfer", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - const feeInput = feeAsset.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - assetTypeFee: bronze.assetType, - shardIdFrom: 0, - shardIdTo: 0, - shardIdFee: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - assetQuantityFee: 200, - expiration, - originOutputs: [goldInput.prevOut, feeInput.prevOut], - recipientFrom: aliceAddress, - recipientFee: charlieAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput, feeInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 9800, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 200, - assetType: bronze.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [2], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [2], - outputTransferredFeeIndices: [5] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - await node.signTransactionInput(transferTx, 2); - - const hash = await node.sendAssetTransaction(transferTx); - expect(await node.sdk.rpc.chain.containsTransaction(hash)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null; - }); - - it("Correct two orders, correct transfer - Ratio is same", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - const feeInput = feeAsset.createTransferInput(); - - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(feeInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 5000, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 5000, - assetType: bronze.assetType, - shardId: 0 - } - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitFees = splitTx.getTransferredAssets(); - const aliceFeeInput = splitFees[0].createTransferInput(); - const bobFeeInput = splitFees[1].createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const aliceOrder = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - assetTypeFee: bronze.assetType, - shardIdFrom: 0, - shardIdTo: 0, - shardIdFee: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - assetQuantityFee: 200, - expiration, - originOutputs: [goldInput.prevOut, aliceFeeInput.prevOut], - recipientFrom: aliceAddress, - recipientFee: charlieAddress - }); - - const bobOrder = node.sdk.core.createOrder({ - assetTypeFrom: silver.assetType, - assetTypeTo: gold.assetType, - assetTypeFee: bronze.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 1000, - assetQuantityTo: 100, - assetQuantityFee: 2000, - expiration, - originOutputs: [silverInput.prevOut, bobFeeInput.prevOut], - recipientFrom: bobAddress, - recipientFee: charlieAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs( - goldInput, - aliceFeeInput, - silverInput, - bobFeeInput - ) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 5000 - 200, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 200, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 5000 - 2000, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 2000, - assetType: bronze.assetType, - shardId: 0 - } - ) - .addOrder({ - order: aliceOrder, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [1], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [2], - outputTransferredFeeIndices: [3] - }) - .addOrder({ - order: bobOrder, - spentQuantity: 1000, - inputFromIndices: [2], - inputFeeIndices: [3], - outputFromIndices: [5], - outputToIndices: [4], - outputOwnedFeeIndices: [6], - outputTransferredFeeIndices: [7] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - await node.signTransactionInput(transferTx, 2); - await node.signTransactionInput(transferTx, 3); - - const hash = await node.sendAssetTransaction(transferTx); - expect(await node.sdk.rpc.chain.containsTransaction(hash)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null; - }); - - it("Correct two orders, correct transfer - Ratio is different, fee Recipient intrecepts leftover", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - const feeInput = feeAsset.createTransferInput(); - - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(feeInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 5000, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 5000, - assetType: bronze.assetType, - shardId: 0 - } - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitFees = splitTx.getTransferredAssets(); - const aliceFeeInput = splitFees[0].createTransferInput(); - const bobFeeInput = splitFees[1].createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const aliceOrder = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - assetTypeFee: bronze.assetType, - shardIdFrom: 0, - shardIdTo: 0, - shardIdFee: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - assetQuantityFee: 200, - expiration, - originOutputs: [goldInput.prevOut, aliceFeeInput.prevOut], - recipientFrom: aliceAddress, - recipientFee: charlieAddress - }); - - const bobOrder = node.sdk.core.createOrder({ - assetTypeFrom: silver.assetType, - assetTypeTo: gold.assetType, - assetTypeFee: bronze.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 1000, - assetQuantityTo: 50, - assetQuantityFee: 2000, - expiration, - originOutputs: [silverInput.prevOut, bobFeeInput.prevOut], - recipientFrom: bobAddress, - recipientFee: charlieAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs( - goldInput, - aliceFeeInput, - silverInput, - bobFeeInput - ) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 5000 - 200, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 200, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 50, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 50, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 5000 - 2000, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 2000, - assetType: bronze.assetType, - shardId: 0 - } - ) - .addOrder({ - order: aliceOrder, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [1], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [2], - outputTransferredFeeIndices: [3] - }) - .addOrder({ - order: bobOrder, - spentQuantity: 1000, - inputFromIndices: [2], - inputFeeIndices: [3], - outputFromIndices: [6], - outputToIndices: [5], - outputOwnedFeeIndices: [7], - outputTransferredFeeIndices: [8] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - await node.signTransactionInput(transferTx, 2); - await node.signTransactionInput(transferTx, 3); - - const hash = await node.sendAssetTransaction(transferTx); - expect(await node.sdk.rpc.chain.containsTransaction(hash)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null; - }); - - it("Wrong order - feeInput Omitted in OriginOutputs", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - const feeInput = feeAsset.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - assetTypeFee: bronze.assetType, - shardIdFrom: 0, - shardIdTo: 0, - shardIdFee: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - assetQuantityFee: 200, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress, - recipientFee: charlieAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput, feeInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 9800, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 200, - assetType: bronze.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [2], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [2], - outputTransferredFeeIndices: [5] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - await node.signTransactionInput(transferTx, 2); - - await node.sendAssetTransactionExpectedToFail(transferTx); - }); - }); - - describe("Mint five assets", function() { - let addresses: AssetAddress[]; - let assets: Asset[]; - - beforeEach(async function() { - addresses = []; - assets = []; - for (let i = 0; i < 5; i++) { - const address = await node.createP2PKHAddress(); - const asset = await node.mintAsset({ - supply: 10000, - recipient: address - }); - addresses.push(address); - assets.push(asset); - } - }); - - it("Multiple orders", async function() { - const inputs = assets.map(asset => asset.createTransferInput()); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(inputs) - .addOutputs([ - ..._.range(5).map(i => ({ - recipient: addresses[i], - quantity: 50, - assetType: assets[(i + 1) % 5].assetType, - shardId: 0 - })), - ..._.range(5).map(i => ({ - recipient: addresses[i], - quantity: 9950, - assetType: assets[i].assetType, - shardId: 0 - })) - ]); - - for (let i = 0; i < 5; i++) { - const order = node.sdk.core.createOrder({ - assetTypeFrom: assets[i].assetType, - assetTypeTo: assets[(i + 1) % 5].assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 100, - expiration: U64.MAX_VALUE, - originOutputs: [inputs[i].prevOut], - recipientFrom: addresses[i] - }); - transferTx.addOrder({ - order, - spentQuantity: 50, - inputFromIndices: [i], - inputFeeIndices: [], - outputFromIndices: [i + 5], - outputToIndices: [i], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - } - - await Promise.all( - _.range((transferTx as any)._transaction.inputs.length).map( - i => node.signTransactionInput(transferTx, i) - ) - ); - - const hash = await node.sendAssetTransaction(transferTx); - expect(await node.sdk.rpc.chain.containsTransaction(hash)).be - .true; - expect(await node.sdk.rpc.chain.getTransaction(hash)).not.null; - }).timeout(10_000); - }); - }); - - afterEach(function() { - if (this.currentTest!.state === "failed") { - node.keepLogs(); - } - }); - - after(async function() { - await node.clean(); - }); -}); diff --git a/test/src/e2e.long/ordersDisabled.test.ts b/test/src/e2e.long/ordersDisabled.test.ts deleted file mode 100644 index a802e14362..0000000000 --- a/test/src/e2e.long/ordersDisabled.test.ts +++ /dev/null @@ -1,3019 +0,0 @@ -// Copyright 2018-2019 Kodebox, Inc. -// This file is part of CodeChain. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -import { expect } from "chai"; -import { Asset, AssetAddress, H160, U64 } from "codechain-sdk/lib/core/classes"; -import * as _ from "lodash"; -import "mocha"; -import { faucetAddress, faucetSecret } from "../helper/constants"; -import { ERROR } from "../helper/error"; -import CodeChain from "../helper/spawn"; - -describe("order is disabled", function() { - let node: CodeChain; - - before(async function() { - node = new CodeChain(); - await node.start(); - }); - - describe("AssetTransfer with orders", function() { - describe("Mint one asset", function() { - let aliceAddress: AssetAddress; - - let gold: Asset; - - beforeEach(async function() { - aliceAddress = await node.createP2PKHAddress(); - gold = await node.mintAsset({ - supply: 10000, - recipient: aliceAddress - }); - }); - - it("Wrong order - originOutputs are wrong (asset type from/to is same)", async function() { - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(gold) - .addOutputs( - _.times(2, () => ({ - recipient: aliceAddress, - quantity: 5000, - assetType: gold.assetType, - shardId: 0 - })) - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitGolds = splitTx.getTransferredAssets(); - const splitGoldInputs = splitGolds.map((g: Asset) => - g.createTransferInput() - ); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: H160.zero(), // Fake asset type - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 5000, - assetQuantityTo: 5000, - expiration, - originOutputs: [splitGoldInputs[0].prevOut], - recipientFrom: aliceAddress - }); - - (order.assetTypeTo as any) = gold.assetType; - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(splitGoldInputs) - .addOutputs( - { - recipient: aliceAddress, - quantity: 5000, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 5000, - assetType: gold.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 5000, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.INVALID_ORDER_ASSET_TYPES); - } - }); - }); - - describe("Mint two assets", function() { - let aliceAddress: AssetAddress; - let bobAddress: AssetAddress; - - let gold: Asset; - let silver: Asset; - - beforeEach(async function() { - aliceAddress = await node.createP2PKHAddress(); - bobAddress = await node.createP2PKHAddress(); - gold = await node.mintAsset({ - supply: 10000, - recipient: aliceAddress - }); - silver = await node.mintAsset({ - supply: 10000, - recipient: bobAddress - }); - }); - - it("Correct order, correct transfer", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - - it("Correct order, correct transfer - Many originOutputs", async function() { - // Split minted gold asset to 10 assets - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(gold) - .addOutputs( - _.times(10, () => ({ - recipient: aliceAddress, - quantity: 1000, - assetType: gold.assetType, - shardId: 0 - })) - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitGolds = splitTx.getTransferredAssets(); - const splitGoldInputs = splitGolds.map(g => - g.createTransferInput() - ); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: splitGoldInputs.map(input => input.prevOut), - recipientFrom: aliceAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(splitGoldInputs) - .addInputs(silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: _.range(10), - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await Promise.all( - _.range((transferTx as any)._transaction.inputs.length).map( - i => node.signTransactionInput(transferTx, i) - ) - ); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }).timeout(10_000); - - it("Correct order, correct transfer - Output(to) is empty", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 10000, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 10000, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 10000, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [], - outputToIndices: [0], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - - it("Correct order, correct transfer - Splitted output", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 1000, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 9000, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 1000, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 4500, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 4500, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 1000, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [1], - outputToIndices: [0], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - - it("Correct two orders, correct transfer - Ratio is same", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const aliceOrder = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - - const bobOrder = node.sdk.core.createOrder({ - assetTypeFrom: silver.assetType, - assetTypeTo: gold.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 1000, - assetQuantityTo: 100, - expiration, - originOutputs: [silverInput.prevOut], - recipientFrom: bobAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order: aliceOrder, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }) - .addOrder({ - order: bobOrder, - spentQuantity: 1000, - inputFromIndices: [1], - inputFeeIndices: [], - outputFromIndices: [3], - outputToIndices: [2], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - - it("Correct two orders, correct transfer - Ratio is different", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const aliceOrder = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - - const bobOrder = node.sdk.core.createOrder({ - assetTypeFrom: silver.assetType, - assetTypeTo: gold.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 1000, - assetQuantityTo: 50, - expiration, - originOutputs: [silverInput.prevOut], - recipientFrom: bobAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - // Bob gets more gold than he wanted. - // If there's a relayer, relayer may take it. - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order: aliceOrder, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }) - .addOrder({ - order: bobOrder, - spentQuantity: 1000, - inputFromIndices: [1], - inputFeeIndices: [], - outputFromIndices: [3], - outputToIndices: [2], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - - it("Correct order, correct transfer - Charlie get some of asset without order", async function() { - const charlieAddress = await node.createP2PKHAddress(); - // Split minted gold asset to 10 assets - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(gold) - .addOutputs( - _.times(10, () => ({ - recipient: aliceAddress, - quantity: 1000, - assetType: gold.assetType, - shardId: 0 - })) - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitGolds = splitTx.getTransferredAssets(); - const splitGoldInputs = splitGolds.map(g => - g.createTransferInput() - ); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 3000, - assetQuantityTo: 7500, - expiration, - originOutputs: [splitGoldInputs[0].prevOut], - recipientFrom: aliceAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs([...splitGoldInputs.slice(0, 3), silverInput]) - .addOutputs( - { - recipient: aliceAddress, - quantity: 2500, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 1000, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 7500, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 2000, - assetType: gold.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 1000, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [], - outputToIndices: [0], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - await node.signTransactionInput(transferTx, 2); - await node.signTransactionInput(transferTx, 3); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - - it("Correct order, wrong transfer - Output(from) is empty", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 10000, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 10000, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 10000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 0, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo( - ERROR.INCONSISTENT_TRANSACTION_IN_OUT_WITH_ORDERS - ); - } - }); - - it("Correct order, wrong transfer - Spend too much", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9800, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 2000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 200, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 8000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 200, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.INVALID_SPENT_QUANTITY); - } - }); - - it("Correct order, wrong transfer - Ratio is wrong", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000 - 10, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000 + 10, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo( - ERROR.INCONSISTENT_TRANSACTION_IN_OUT_WITH_ORDERS - ); - } - }); - - it("Correct order, wrong transfer - Lock script hash of maker is wrong", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - - (transferTx.orders()[0].order - .lockScriptHashFrom as any) = new H160( - "0000000000000000000000000000000000000000" - ); - - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo( - ERROR.INVALID_ORDER_LOCK_SCRIPT_HASH - ); - } - }); - - it("Correct order, wrong transfer - Parameters of maker are wrong", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - - (transferTx.orders()[0].order.parametersFrom as any) = []; - - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.INVALID_ORDER_PARAMETERS); - } - }); - - it("Correct order, wrong transfer - Too many outputs (from)", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900 - 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0, 1], - outputToIndices: [2], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - - it("Correct order, wrong transfer - Too many outputs (to)", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000 - 100, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 100, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1, 2], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - - it("Correct order, wrong transfer - Too many outputs (both)", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900 - 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000 - 100, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 100, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0, 1], - outputToIndices: [2, 3], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - - it("Wrong order - originOutputs are wrong (empty)", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - (order.originOutputs as any) = []; - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.INVALID_ORIGIN_OUTPUTS); - } - }); - - it("Wrong order - originOutputs are wrong (prevOut does not match)", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [silverInput.prevOut], - recipientFrom: aliceAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.INVALID_ORIGIN_OUTPUTS); - } - }); - - it("Wrong order - originOutputs are wrong (Quantity is not enough)", async function() { - // Split minted gold asset to 10 assets - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(gold) - .addOutputs( - _.times(10, () => ({ - recipient: aliceAddress, - quantity: 1000, - assetType: gold.assetType, - shardId: 0 - })) - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitGolds = splitTx.getTransferredAssets(); - const splitGoldInputs = splitGolds.map(g => - g.createTransferInput() - ); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 3000, - assetQuantityTo: 7500, - expiration, - originOutputs: [splitGoldInputs[0].prevOut], - recipientFrom: aliceAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs([...splitGoldInputs.slice(0, 3), silverInput]) - .addOutputs( - { - recipient: aliceAddress, - quantity: 7500, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 3000, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 2500, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 3000, - inputFromIndices: [0, 1, 2], - inputFeeIndices: [], - outputFromIndices: [], - outputToIndices: [0], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }).timeout(10_000); - - it("Wrong order - originOutputs are wrong (few outputs)", async function() { - // Split minted gold asset to 10 assets - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(gold) - .addOutputs( - _.times(10, () => ({ - recipient: aliceAddress, - quantity: 1000, - assetType: gold.assetType, - shardId: 0 - })) - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitGolds = splitTx.getTransferredAssets(); - const splitGoldInputs = splitGolds.map(g => - g.createTransferInput() - ); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: splitGoldInputs - .slice(0, 9) - .map(input => input.prevOut), - recipientFrom: aliceAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(splitGoldInputs) - .addInputs(silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: _.range(10), - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await Promise.all( - _.range((transferTx as any)._transaction.inputs.length).map( - i => node.signTransactionInput(transferTx, i) - ) - ); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }).timeout(10_000); - - it("Wrong order - originOutputs are wrong (many outputs)", async function() { - // Split minted gold asset to 10 assets - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(gold) - .addOutputs( - _.times(10, () => ({ - recipient: aliceAddress, - quantity: 1000, - assetType: gold.assetType, - shardId: 0 - })) - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitGolds = splitTx.getTransferredAssets(); - const splitGoldInputs = splitGolds.map(g => - g.createTransferInput() - ); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: splitGoldInputs.map(input => input.prevOut), - recipientFrom: aliceAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(splitGoldInputs.slice(0, 9)) - .addInputs(silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 8900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: _.range(9), - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await Promise.all( - _.range((transferTx as any)._transaction.inputs.length).map( - i => node.signTransactionInput(transferTx, i) - ) - ); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }).timeout(10_000); - - it("Wrong order - Ratio is wrong (from is zero)", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - (order.assetQuantityFrom as any) = new U64(0); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo( - ERROR.INVALID_ORDER_ASSET_QUANTITIES - ); - } - }); - - it("Wrong order - Ratio is wrong (to is zero)", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - (order.assetQuantityTo as any) = new U64(0); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo( - ERROR.INVALID_ORDER_ASSET_QUANTITIES - ); - } - }); - - it("Wrong order - Expiration is old", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = 0; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - - it("Successful partial fills", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - - const transferTx1 = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9950, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 500, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 50, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9500, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 50, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx1, 0); - await node.signTransactionInput(transferTx1, 1); - - const signed = transferTx1.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }).timeout(10_000); - - it("Successful mutual partial fills", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const aliceOrder = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const bobOrder = node.sdk.core.createOrder({ - assetTypeFrom: silver.assetType, - assetTypeTo: gold.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 1000, - assetQuantityTo: 50, - expiration, - originOutputs: [silverInput.prevOut], - recipientFrom: bobAddress - }); - - const transferTx1 = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9990, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 100, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 10, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9900, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order: aliceOrder, - spentQuantity: 10, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }) - .addOrder({ - order: bobOrder, - spentQuantity: 100, - inputFromIndices: [1], - inputFeeIndices: [], - outputFromIndices: [3], - outputToIndices: [2], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx1, 0); - await node.signTransactionInput(transferTx1, 1); - - const signed = transferTx1.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }).timeout(10_000); - - it("Successful partial cancel", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress - }); - const transferTx1 = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9950, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 500, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 50, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9500, - assetType: silver.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 50, - inputFromIndices: [0], - inputFeeIndices: [], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - await node.signTransactionInput(transferTx1, 0); - await node.signTransactionInput(transferTx1, 1); - - const signed = transferTx1.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - }).timeout(10_000); - - describe("Mint three assets ", function() { - let aliceAddress: AssetAddress; - let bobAddress: AssetAddress; - let charlieAddress: AssetAddress; - - let gold: Asset; - let silver: Asset; - let bronze: Asset; - let feeAsset: Asset; - - beforeEach(async function() { - aliceAddress = await node.createP2PKHAddress(); - bobAddress = await node.createP2PKHAddress(); - charlieAddress = await node.createP2PKHAddress(); - const FeeOwnerAddress = await node.createP2PKHAddress(); - gold = await node.mintAsset({ - supply: 10000, - recipient: aliceAddress - }); - silver = await node.mintAsset({ - supply: 10000, - recipient: bobAddress - }); - bronze = await node.mintAsset({ - supply: 10000, - recipient: FeeOwnerAddress - }); - - const bronzeInput = bronze.createTransferInput(); - const transferTx1 = node.sdk.core - .createTransferAssetTransaction() - .addInputs(bronzeInput) - .addOutputs({ - recipient: aliceAddress, - quantity: 10000, - assetType: bronze.assetType, - shardId: 0 - }); - await node.signTransactionInput(transferTx1, 0); - await node.sendAssetTransaction(transferTx1); - feeAsset = transferTx1.getTransferredAsset(0); - }); - - it("Correct order - originOutputs fee is not enough but Ok", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - const feeInput = feeAsset.createTransferInput(); - - // Split minted gold asset to 10 assets - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(feeInput) - .addOutputs( - _.times(10, () => ({ - recipient: aliceAddress, - quantity: 1000, - assetType: bronze.assetType, - shardId: 0 - })) - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitFees = splitTx.getTransferredAssets(); - const splitFeeInputs = splitFees.map(g => - g.createTransferInput() - ); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - assetTypeFee: bronze.assetType, - shardIdFrom: 0, - shardIdTo: 0, - shardIdFee: 0, - assetQuantityFrom: 1000, - assetQuantityTo: 10000, - assetQuantityFee: 2000, - expiration, - originOutputs: [ - goldInput.prevOut, - splitFeeInputs[0].prevOut - ], - recipientFrom: aliceAddress, - recipientFee: charlieAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput, splitFeeInputs[0]) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 800, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 200, - assetType: bronze.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [2], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [2], - outputTransferredFeeIndices: [5] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - await node.signTransactionInput(transferTx, 2); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - - it("Correct order, correct transfer", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - const feeInput = feeAsset.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - assetTypeFee: bronze.assetType, - shardIdFrom: 0, - shardIdTo: 0, - shardIdFee: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - assetQuantityFee: 200, - expiration, - originOutputs: [goldInput.prevOut, feeInput.prevOut], - recipientFrom: aliceAddress, - recipientFee: charlieAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput, feeInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 9800, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 200, - assetType: bronze.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [2], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [2], - outputTransferredFeeIndices: [5] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - await node.signTransactionInput(transferTx, 2); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - - it("Correct two orders, correct transfer - Ratio is same", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - const feeInput = feeAsset.createTransferInput(); - - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(feeInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 5000, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 5000, - assetType: bronze.assetType, - shardId: 0 - } - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitFees = splitTx.getTransferredAssets(); - const aliceFeeInput = splitFees[0].createTransferInput(); - const bobFeeInput = splitFees[1].createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const aliceOrder = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - assetTypeFee: bronze.assetType, - shardIdFrom: 0, - shardIdTo: 0, - shardIdFee: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - assetQuantityFee: 200, - expiration, - originOutputs: [goldInput.prevOut, aliceFeeInput.prevOut], - recipientFrom: aliceAddress, - recipientFee: charlieAddress - }); - - const bobOrder = node.sdk.core.createOrder({ - assetTypeFrom: silver.assetType, - assetTypeTo: gold.assetType, - assetTypeFee: bronze.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 1000, - assetQuantityTo: 100, - assetQuantityFee: 2000, - expiration, - originOutputs: [silverInput.prevOut, bobFeeInput.prevOut], - recipientFrom: bobAddress, - recipientFee: charlieAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs( - goldInput, - aliceFeeInput, - silverInput, - bobFeeInput - ) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 5000 - 200, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 200, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 5000 - 2000, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 2000, - assetType: bronze.assetType, - shardId: 0 - } - ) - .addOrder({ - order: aliceOrder, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [1], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [2], - outputTransferredFeeIndices: [3] - }) - .addOrder({ - order: bobOrder, - spentQuantity: 1000, - inputFromIndices: [2], - inputFeeIndices: [3], - outputFromIndices: [5], - outputToIndices: [4], - outputOwnedFeeIndices: [6], - outputTransferredFeeIndices: [7] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - await node.signTransactionInput(transferTx, 2); - await node.signTransactionInput(transferTx, 3); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - - it("Correct two orders, correct transfer - Ratio is different, fee Recipient intrecepts leftover", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - const feeInput = feeAsset.createTransferInput(); - - const splitTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(feeInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 5000, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 5000, - assetType: bronze.assetType, - shardId: 0 - } - ); - await node.signTransactionInput(splitTx, 0); - - const splitHash = await node.sendAssetTransaction(splitTx); - expect(await node.sdk.rpc.chain.containsTransaction(splitHash)) - .be.true; - expect(await node.sdk.rpc.chain.getTransaction(splitHash)).not - .null; - - const splitFees = splitTx.getTransferredAssets(); - const aliceFeeInput = splitFees[0].createTransferInput(); - const bobFeeInput = splitFees[1].createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const aliceOrder = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - assetTypeFee: bronze.assetType, - shardIdFrom: 0, - shardIdTo: 0, - shardIdFee: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - assetQuantityFee: 200, - expiration, - originOutputs: [goldInput.prevOut, aliceFeeInput.prevOut], - recipientFrom: aliceAddress, - recipientFee: charlieAddress - }); - - const bobOrder = node.sdk.core.createOrder({ - assetTypeFrom: silver.assetType, - assetTypeTo: gold.assetType, - assetTypeFee: bronze.assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 1000, - assetQuantityTo: 50, - assetQuantityFee: 2000, - expiration, - originOutputs: [silverInput.prevOut, bobFeeInput.prevOut], - recipientFrom: bobAddress, - recipientFee: charlieAddress - }); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs( - goldInput, - aliceFeeInput, - silverInput, - bobFeeInput - ) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 5000 - 200, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 200, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 50, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 50, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 5000 - 2000, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 2000, - assetType: bronze.assetType, - shardId: 0 - } - ) - .addOrder({ - order: aliceOrder, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [1], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [2], - outputTransferredFeeIndices: [3] - }) - .addOrder({ - order: bobOrder, - spentQuantity: 1000, - inputFromIndices: [2], - inputFeeIndices: [3], - outputFromIndices: [6], - outputToIndices: [5], - outputOwnedFeeIndices: [7], - outputTransferredFeeIndices: [8] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - await node.signTransactionInput(transferTx, 2); - await node.signTransactionInput(transferTx, 3); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - - it("Wrong order - feeInput Omitted in OriginOutputs", async function() { - const goldInput = gold.createTransferInput(); - const silverInput = silver.createTransferInput(); - const feeInput = feeAsset.createTransferInput(); - - const expiration = Math.round(Date.now() / 1000) + 120; - const order = node.sdk.core.createOrder({ - assetTypeFrom: gold.assetType, - assetTypeTo: silver.assetType, - assetTypeFee: bronze.assetType, - shardIdFrom: 0, - shardIdTo: 0, - shardIdFee: 0, - assetQuantityFrom: 100, - assetQuantityTo: 1000, - assetQuantityFee: 200, - expiration, - originOutputs: [goldInput.prevOut], - recipientFrom: aliceAddress, - recipientFee: charlieAddress - }); - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(goldInput, silverInput, feeInput) - .addOutputs( - { - recipient: aliceAddress, - quantity: 9900, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 1000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: aliceAddress, - quantity: 9800, - assetType: bronze.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 100, - assetType: gold.assetType, - shardId: 0 - }, - { - recipient: bobAddress, - quantity: 9000, - assetType: silver.assetType, - shardId: 0 - }, - { - recipient: charlieAddress, - quantity: 200, - assetType: bronze.assetType, - shardId: 0 - } - ) - .addOrder({ - order, - spentQuantity: 100, - inputFromIndices: [0], - inputFeeIndices: [2], - outputFromIndices: [0], - outputToIndices: [1], - outputOwnedFeeIndices: [2], - outputTransferredFeeIndices: [5] - }); - await node.signTransactionInput(transferTx, 0); - await node.signTransactionInput(transferTx, 1); - await node.signTransactionInput(transferTx, 2); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }); - }); - - describe("Mint five assets", function() { - let addresses: AssetAddress[]; - let assets: Asset[]; - - beforeEach(async function() { - addresses = []; - assets = []; - for (let i = 0; i < 5; i++) { - const address = await node.createP2PKHAddress(); - const asset = await node.mintAsset({ - supply: 10000, - recipient: address - }); - addresses.push(address); - assets.push(asset); - } - }); - - it("Multiple orders", async function() { - const inputs = assets.map(asset => asset.createTransferInput()); - - const transferTx = node.sdk.core - .createTransferAssetTransaction() - .addInputs(inputs) - .addOutputs([ - ..._.range(5).map(i => ({ - recipient: addresses[i], - quantity: 50, - assetType: assets[(i + 1) % 5].assetType, - shardId: 0 - })), - ..._.range(5).map(i => ({ - recipient: addresses[i], - quantity: 9950, - assetType: assets[i].assetType, - shardId: 0 - })) - ]); - - for (let i = 0; i < 5; i++) { - const order = node.sdk.core.createOrder({ - assetTypeFrom: assets[i].assetType, - assetTypeTo: assets[(i + 1) % 5].assetType, - shardIdFrom: 0, - shardIdTo: 0, - assetQuantityFrom: 100, - assetQuantityTo: 100, - expiration: U64.MAX_VALUE, - originOutputs: [inputs[i].prevOut], - recipientFrom: addresses[i] - }); - transferTx.addOrder({ - order, - spentQuantity: 50, - inputFromIndices: [i], - inputFeeIndices: [], - outputFromIndices: [i + 5], - outputToIndices: [i], - outputOwnedFeeIndices: [], - outputTransferredFeeIndices: [] - }); - } - - await Promise.all( - _.range((transferTx as any)._transaction.inputs.length).map( - i => node.signTransactionInput(transferTx, i) - ) - ); - - const signed = transferTx.sign({ - secret: faucetSecret, - fee: 10, - seq: await node.sdk.rpc.chain.getSeq(faucetAddress) - }); - try { - await node.sdk.rpc.chain.sendSignedTransaction(signed); - expect.fail(); - } catch (e) { - expect(e).is.similarTo(ERROR.DISABLED_TRANSACTION); - } - }).timeout(10_000); - }); - }); - - afterEach(function() { - if (this.currentTest!.state === "failed") { - node.keepLogs(); - } - }); - - after(async function() { - await node.clean(); - }); -}); diff --git a/test/src/helper/error.ts b/test/src/helper/error.ts index fd5daf85f6..e36d1741ad 100644 --- a/test/src/helper/error.ts +++ b/test/src/helper/error.ts @@ -109,56 +109,11 @@ export const ERROR = { data: $containsWord("Syntax(DuplicatedPreviousOutput"), message: $anything }, - ORDER_IS_NOT_EMPTY: { - code: -32099, - message: $anything, - data: $containsWord("OrderIsNotEmpty") - }, - INCONSISTENT_TRANSACTION_IN_OUT_WITH_ORDERS: { - code: -32099, - message: $anything, - data: $containsWord("InconsistentTransactionInOutWithOrders") - }, INVALID_ORIGIN_OUTPUTS: { code: -32099, message: $anything, data: $containsWord("InvalidOriginOutputs") }, - INVALID_ORDER_ASSET_QUANTITIES: { - code: -32099, - message: $anything, - data: $containsWord("InvalidOrderAssetQuantities") - }, - INVALID_ORDER_ASSET_TYPES: { - code: -32099, - message: $anything, - data: $containsWord("InvalidOrderAssetTypes") - }, - INVALID_ORDER_LOCK_SCRIPT_HASH: { - code: -32099, - message: $anything, - data: $containsWord("InvalidOrderLockScriptHash") - }, - INVALID_ORDER_PARAMETERS: { - code: -32099, - message: $anything, - data: $containsWord("InvalidOrderParameters") - }, - INVALID_OUTPUT_WITH_ORDER: { - code: -32099, - message: $anything, - data: $containsWord("InvalidOutputWithOrder") - }, - INVALID_SPENT_QUANTITY: { - code: -32099, - message: $anything, - data: $containsWord("InvalidSpentQuantity") - }, - ORDER_EXPIRED: { - code: -32099, - message: $anything, - data: $containsWord("OrderExpired") - }, DISABLED_TRANSACTION: { code: -32099, message: $anything, diff --git a/types/src/errors/history_error.rs b/types/src/errors/history_error.rs index deadf1074d..d43cfb0722 100644 --- a/types/src/errors/history_error.rs +++ b/types/src/errors/history_error.rs @@ -29,10 +29,6 @@ pub enum Error { LimitReached, /// Transaction is not valid anymore (state already has higher seq) Old, - OrderExpired { - expiration: u64, - timestamp: u64, - }, Timelocked { timelock: Timelock, remaining_time: u64, @@ -50,7 +46,6 @@ pub enum Error { const ERROR_ID_LIMIT_REACHED: u8 = 2; const ERROR_ID_OLD: u8 = 3; -const ERROR_ID_ORDER_EXPIRED: u8 = 4; const ERROR_ID_TIMELOCKED: u8 = 5; const ERROR_ID_TOO_CHEAP_TO_REPLACE: u8 = 6; const ERROR_ID_TX_ALREADY_IMPORTED: u8 = 7; @@ -64,7 +59,6 @@ impl TaggedRlp for RlpHelper { Ok(match tag { ERROR_ID_LIMIT_REACHED => 1, ERROR_ID_OLD => 1, - ERROR_ID_ORDER_EXPIRED => 3, ERROR_ID_TIMELOCKED => 3, ERROR_ID_TOO_CHEAP_TO_REPLACE => 1, ERROR_ID_TX_ALREADY_IMPORTED => 1, @@ -79,10 +73,6 @@ impl Encodable for Error { match self { Error::LimitReached => RlpHelper::new_tagged_list(s, ERROR_ID_LIMIT_REACHED), Error::Old => RlpHelper::new_tagged_list(s, ERROR_ID_OLD), - Error::OrderExpired { - expiration, - timestamp, - } => RlpHelper::new_tagged_list(s, ERROR_ID_ORDER_EXPIRED).append(expiration).append(timestamp), Error::Timelocked { timelock, remaining_time, @@ -103,10 +93,6 @@ impl Decodable for Error { let error = match tag { ERROR_ID_LIMIT_REACHED => Error::LimitReached, ERROR_ID_OLD => Error::Old, - ERROR_ID_ORDER_EXPIRED => Error::OrderExpired { - expiration: rlp.val_at(1)?, - timestamp: rlp.val_at(2)?, - }, ERROR_ID_TIMELOCKED => Error::Timelocked { timelock: rlp.val_at(1)?, remaining_time: rlp.val_at(2)?, @@ -129,10 +115,6 @@ impl Display for Error { match self { Error::LimitReached => write!(f, "Transaction limit reached"), Error::Old => write!(f, "No longer valid"), - Error::OrderExpired { - expiration, - timestamp, - } => write!(f, "The order is expired. Expiration: {}, Block timestamp: {}", expiration, timestamp), Error::Timelocked { timelock, remaining_time, diff --git a/types/src/errors/runtime_error.rs b/types/src/errors/runtime_error.rs index 056fc464d9..63d0fc34de 100644 --- a/types/src/errors/runtime_error.rs +++ b/types/src/errors/runtime_error.rs @@ -79,8 +79,6 @@ pub enum Error { index: usize, mismatch: Mismatch, }, - /// Errors on orders: origin_outputs of order is not satisfied. - InvalidOriginOutputs(H256), /// Failed to decode script. InvalidScript, /// Returned when transaction seq does not match state seq @@ -138,7 +136,6 @@ const ERROR_ID_SCRIPT_NOT_ALLOWED: u8 = 22; const ERROR_ID_TEXT_NOT_EXIST: u8 = 23; const ERROR_ID_TEXT_VERIFICATION_FAIL: u8 = 24; const ERROR_ID_CANNOT_USE_MASTER_KEY: u8 = 25; -const ERROR_ID_INVALID_ORIGIN_OUTPUTS: u8 = 26; const ERROR_ID_INVALID_SCRIPT: u8 = 27; const ERROR_ID_INVALID_SEQ: u8 = 28; const ERROR_ID_ASSET_SUPPLY_OVERFLOW: u8 = 29; @@ -166,7 +163,6 @@ impl TaggedRlp for RlpHelper { ERROR_ID_INSUFFICIENT_PERMISSION => 1, ERROR_ID_INVALID_ASSET_QUANTITY => 6, ERROR_ID_UNEXPECTED_ASSET_TYPE => 3, - ERROR_ID_INVALID_ORIGIN_OUTPUTS => 2, ERROR_ID_INVALID_SCRIPT => 1, ERROR_ID_INVALID_SEQ => 2, ERROR_ID_INVALID_SHARD_ID => 2, @@ -255,9 +251,6 @@ impl Encodable for Error { index, mismatch, } => RlpHelper::new_tagged_list(s, ERROR_ID_UNEXPECTED_ASSET_TYPE).append(index).append(mismatch), - Error::InvalidOriginOutputs(addr) => { - RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_ORIGIN_OUTPUTS).append(addr) - } Error::InvalidScript => RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_SCRIPT), Error::InvalidSeq(mismatch) => RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_SEQ).append(mismatch), Error::InvalidShardId(shard_id) => { @@ -347,7 +340,6 @@ impl Decodable for Error { index: rlp.val_at(1)?, mismatch: rlp.val_at(2)?, }, - ERROR_ID_INVALID_ORIGIN_OUTPUTS => Error::InvalidOriginOutputs(rlp.val_at(1)?), ERROR_ID_INVALID_SCRIPT => Error::InvalidScript, ERROR_ID_INVALID_SEQ => Error::InvalidSeq(rlp.val_at(1)?), ERROR_ID_INVALID_SHARD_ID => Error::InvalidShardId(rlp.val_at(1)?), @@ -423,7 +415,6 @@ impl Display for Error { shard_id, tracker, index, expected, got ), Error::UnexpectedAssetType{index, mismatch} => write!(f, "{}th input has an unexpected asset type: {}", index, mismatch), - Error::InvalidOriginOutputs(addr) => write!(f, "origin_outputs of order({}) is not satisfied", addr), Error::InvalidScript => write!(f, "Failed to decode script"), Error::InvalidSeq(mismatch) => write!(f, "Invalid transaction seq {}", mismatch), Error::InvalidShardId(shard_id) => write!(f, "{} is an invalid shard id", shard_id), diff --git a/types/src/errors/syntax_error.rs b/types/src/errors/syntax_error.rs index 9d9ba40a70..6f8c246f00 100644 --- a/types/src/errors/syntax_error.rs +++ b/types/src/errors/syntax_error.rs @@ -14,11 +14,10 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . - use std::fmt::{Display, Formatter, Result as FormatResult}; use ckey::NetworkId; -use primitives::{Bytes, H160, H256}; +use primitives::{H160, H256}; use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; use super::TaggedRlp; @@ -35,8 +34,6 @@ pub enum Error { EmptyShardOwners(ShardId), /// Returned when the sum of the transaction's inputs is different from the sum of outputs. InconsistentTransactionInOut, - /// the input and output of tx is not consistent with its orders - InconsistentTransactionInOutWithOrders, /// Transaction's fee is below currently set minimal fee requirement. InsufficientFee { /// Minimal expected fee @@ -49,37 +46,9 @@ pub enum Error { InvalidCustomAction(String), /// Invalid network ID given. InvalidNetworkId(NetworkId), - /// invalid asset_quantity_from, asset_quantity_to because of ratio - InvalidOrderAssetQuantities { - from: u64, - to: u64, - fee: u64, - }, - /// asset_type_from and asset_type_to are equal. - InvalidOrderAssetTypes, - /// The input/output indices of the order on transfer indicate assets of different type from the order. - InvalidAssetTypesWithOrder { - asset_type: String, - idx: usize, - }, - /// Owner of the assets indicated by the input/output indices of the order on transfer is not valid - InvalidAssetOwnerWithOrder { - asset_type: String, - idx: usize, - }, - /// The input/output indices of the order on transfer is not valid. - InvalidOrderInOutIndices, - /// the lock script hash of the order is different from the output - InvalidOrderLockScriptHash(H160), - /// the parameters of the order is different from the output - InvalidOrderParameters(Vec), - /// Errors on orders - /// origin_outputs of order is not satisfied. - InvalidOriginOutputs(H256), InvalidApproval(String), /// Max metadata size is exceeded. MetadataTooBig, - OrderRecipientsAreSame, TextContentTooBig, TooManyOutputs(usize), TransactionIsTooBig, @@ -88,10 +57,6 @@ pub enum Error { CannotChangeWcccAssetScheme, DisabledTransaction, InvalidSignerOfWrapCCC, - InvalidSpentQuantity { - asset_quantity_from: u64, - spent_quantity: u64, - }, } const ERORR_ID_DUPLICATED_PREVIOUS_OUTPUT: u8 = 1; @@ -100,24 +65,14 @@ const ERORR_ID_DUPLICATED_PREVIOUS_OUTPUT: u8 = 1; //const ERROR_ID_EMPTY_OUTPUT: u8 = 3; const ERROR_ID_EMPTY_SHARD_OWNERS: u8 = 4; const ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT: u8 = 5; -const ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT_WITH_ORDERS: u8 = 6; const ERROR_ID_INSUFFICIENT_FEE: u8 = 7; const ERROR_ID_INVALID_ASSET_TYPE: u8 = 8; /// Deprecated //const ERROR_ID_INVALID_COMPOSED_OUTPUT_AMOUNT: u8 = 9; //const ERROR_ID_INVALID_DECOMPOSED_INPUT_AMOUNT: u8 = 10; const ERROR_ID_INVALID_NETWORK_ID: u8 = 11; -const ERROR_ID_INVALID_ORDER_ASSET_QUANTITIES: u8 = 12; -const ERROR_ID_INVALID_ORDER_ASSET_TYPES: u8 = 13; -const ERROR_ID_INVALID_ASSET_TYPES_WITH_ORDER: u8 = 14; -const ERROR_ID_INVALID_ASSET_OWNER_WITH_ORDER: u8 = 15; -const ERROR_ID_INVALID_ORDER_IN_OUT_INDICES: u8 = 16; -const ERROR_ID_INVALID_ORDER_LOCK_SCRIPT_HASH: u8 = 17; -const ERROR_ID_INVALID_ORDER_PARAMETERS: u8 = 18; -const ERROR_ID_INVALID_ORIGIN_OUTPUTS: u8 = 19; const ERROR_ID_INVALID_APPROVAL: u8 = 21; const ERROR_ID_METADATA_TOO_BIG: u8 = 22; -const ERROR_ID_ORDER_RECIPIENTS_ARE_SAME: u8 = 23; const ERROR_ID_TEXT_CONTENT_TOO_BIG: u8 = 24; const ERROR_ID_TOO_MANY_OUTPUTS: u8 = 26; const ERROR_ID_TX_IS_TOO_BIG: u8 = 27; @@ -126,7 +81,6 @@ const ERROR_ID_CANNOT_CHANGE_WCCC_ASSET_SCHEME: u8 = 29; const ERROR_ID_DISABLED_TRANSACTION: u8 = 30; const ERROR_ID_INVALID_SIGNER_OF_WRAP_CCC: u8 = 31; const ERROR_ID_INVALID_CUSTOM_ACTION: u8 = 32; -const ERROR_ID_INVALID_SPENT_QUANTITY: u8 = 33; struct RlpHelper; impl TaggedRlp for RlpHelper { @@ -137,22 +91,12 @@ impl TaggedRlp for RlpHelper { ERORR_ID_DUPLICATED_PREVIOUS_OUTPUT => 3, ERROR_ID_EMPTY_SHARD_OWNERS => 2, ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT => 1, - ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT_WITH_ORDERS => 1, ERROR_ID_INSUFFICIENT_FEE => 3, ERROR_ID_INVALID_ASSET_TYPE => 2, ERROR_ID_INVALID_CUSTOM_ACTION => 2, ERROR_ID_INVALID_NETWORK_ID => 2, - ERROR_ID_INVALID_ORDER_ASSET_QUANTITIES => 4, - ERROR_ID_INVALID_ORDER_ASSET_TYPES => 1, - ERROR_ID_INVALID_ASSET_TYPES_WITH_ORDER => 3, - ERROR_ID_INVALID_ASSET_OWNER_WITH_ORDER => 3, - ERROR_ID_INVALID_ORDER_IN_OUT_INDICES => 1, - ERROR_ID_INVALID_ORDER_LOCK_SCRIPT_HASH => 2, - ERROR_ID_INVALID_ORDER_PARAMETERS => 2, - ERROR_ID_INVALID_ORIGIN_OUTPUTS => 2, ERROR_ID_INVALID_APPROVAL => 2, ERROR_ID_METADATA_TOO_BIG => 1, - ERROR_ID_ORDER_RECIPIENTS_ARE_SAME => 1, ERROR_ID_TEXT_CONTENT_TOO_BIG => 1, ERROR_ID_TOO_MANY_OUTPUTS => 2, ERROR_ID_TX_IS_TOO_BIG => 1, @@ -160,7 +104,6 @@ impl TaggedRlp for RlpHelper { ERROR_ID_CANNOT_CHANGE_WCCC_ASSET_SCHEME => 1, ERROR_ID_DISABLED_TRANSACTION => 1, ERROR_ID_INVALID_SIGNER_OF_WRAP_CCC => 1, - ERROR_ID_INVALID_SPENT_QUANTITY => 3, _ => return Err(DecoderError::Custom("Invalid SyntaxError")), }) } @@ -179,9 +122,6 @@ impl Encodable for Error { Error::InconsistentTransactionInOut => { RlpHelper::new_tagged_list(s, ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT) } - Error::InconsistentTransactionInOutWithOrders => { - RlpHelper::new_tagged_list(s, ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT_WITH_ORDERS) - } Error::InsufficientFee { minimal, got, @@ -193,36 +133,8 @@ impl Encodable for Error { Error::InvalidNetworkId(network_id) => { RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_NETWORK_ID).append(network_id) } - Error::InvalidOrderAssetQuantities { - from, - to, - fee, - } => RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_ORDER_ASSET_QUANTITIES) - .append(from) - .append(to) - .append(fee), - Error::InvalidOrderAssetTypes => RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_ORDER_ASSET_TYPES), - Error::InvalidAssetTypesWithOrder { - asset_type, - idx, - } => RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_ASSET_TYPES_WITH_ORDER).append(asset_type).append(idx), - Error::InvalidAssetOwnerWithOrder { - asset_type, - idx, - } => RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_ASSET_OWNER_WITH_ORDER).append(asset_type).append(idx), - Error::InvalidOrderInOutIndices => RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_ORDER_IN_OUT_INDICES), - Error::InvalidOrderLockScriptHash(lock_script_hash) => { - RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_ORDER_LOCK_SCRIPT_HASH).append(lock_script_hash) - } - Error::InvalidOrderParameters(parameters) => { - RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_ORDER_PARAMETERS).append(parameters) - } - Error::InvalidOriginOutputs(order_hash) => { - RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_ORIGIN_OUTPUTS).append(order_hash) - } Error::InvalidApproval(err) => RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_APPROVAL).append(err), Error::MetadataTooBig => RlpHelper::new_tagged_list(s, ERROR_ID_METADATA_TOO_BIG), - Error::OrderRecipientsAreSame => RlpHelper::new_tagged_list(s, ERROR_ID_ORDER_RECIPIENTS_ARE_SAME), Error::TextContentTooBig => RlpHelper::new_tagged_list(s, ERROR_ID_TEXT_CONTENT_TOO_BIG), Error::TooManyOutputs(num) => RlpHelper::new_tagged_list(s, ERROR_ID_TOO_MANY_OUTPUTS).append(num), Error::TransactionIsTooBig => RlpHelper::new_tagged_list(s, ERROR_ID_TX_IS_TOO_BIG), @@ -232,12 +144,6 @@ impl Encodable for Error { } Error::DisabledTransaction => RlpHelper::new_tagged_list(s, ERROR_ID_DISABLED_TRANSACTION), Error::InvalidSignerOfWrapCCC => RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_SIGNER_OF_WRAP_CCC), - Error::InvalidSpentQuantity { - asset_quantity_from, - spent_quantity, - } => RlpHelper::new_tagged_list(s, ERROR_ID_INVALID_SPENT_QUANTITY) - .append(asset_quantity_from) - .append(spent_quantity), }; } } @@ -252,7 +158,6 @@ impl Decodable for Error { }, ERROR_ID_EMPTY_SHARD_OWNERS => Error::EmptyShardOwners(rlp.val_at(1)?), ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT => Error::InconsistentTransactionInOut, - ERROR_ID_INCONSISTENT_TRANSACTION_IN_OUT_WITH_ORDERS => Error::InconsistentTransactionInOutWithOrders, ERROR_ID_INSUFFICIENT_FEE => Error::InsufficientFee { minimal: rlp.val_at(1)?, got: rlp.val_at(2)?, @@ -260,27 +165,8 @@ impl Decodable for Error { ERROR_ID_INVALID_ASSET_TYPE => Error::InvalidAssetType(rlp.val_at(1)?), ERROR_ID_INVALID_CUSTOM_ACTION => Error::InvalidCustomAction(rlp.val_at(1)?), ERROR_ID_INVALID_NETWORK_ID => Error::InvalidNetworkId(rlp.val_at(1)?), - ERROR_ID_INVALID_ORDER_ASSET_QUANTITIES => Error::InvalidOrderAssetQuantities { - from: rlp.val_at(1)?, - to: rlp.val_at(2)?, - fee: rlp.val_at(3)?, - }, - ERROR_ID_INVALID_ORDER_ASSET_TYPES => Error::InvalidOrderAssetTypes, - ERROR_ID_INVALID_ASSET_TYPES_WITH_ORDER => Error::InvalidAssetTypesWithOrder { - asset_type: rlp.val_at(1)?, - idx: rlp.val_at(2)?, - }, - ERROR_ID_INVALID_ASSET_OWNER_WITH_ORDER => Error::InvalidAssetOwnerWithOrder { - asset_type: rlp.val_at(1)?, - idx: rlp.val_at(2)?, - }, - ERROR_ID_INVALID_ORDER_IN_OUT_INDICES => Error::InvalidOrderInOutIndices, - ERROR_ID_INVALID_ORDER_LOCK_SCRIPT_HASH => Error::InvalidOrderLockScriptHash(rlp.val_at(1)?), - ERROR_ID_INVALID_ORDER_PARAMETERS => Error::InvalidOrderParameters(rlp.val_at(1)?), - ERROR_ID_INVALID_ORIGIN_OUTPUTS => Error::InvalidOriginOutputs(rlp.val_at(1)?), ERROR_ID_INVALID_APPROVAL => Error::InvalidApproval(rlp.val_at(1)?), ERROR_ID_METADATA_TOO_BIG => Error::MetadataTooBig, - ERROR_ID_ORDER_RECIPIENTS_ARE_SAME => Error::OrderRecipientsAreSame, ERROR_ID_TEXT_CONTENT_TOO_BIG => Error::TextContentTooBig, ERROR_ID_TOO_MANY_OUTPUTS => Error::TooManyOutputs(rlp.val_at(1)?), ERROR_ID_TX_IS_TOO_BIG => Error::TransactionIsTooBig, @@ -288,10 +174,6 @@ impl Decodable for Error { ERROR_ID_CANNOT_CHANGE_WCCC_ASSET_SCHEME => Error::CannotChangeWcccAssetScheme, ERROR_ID_DISABLED_TRANSACTION => Error::DisabledTransaction, ERROR_ID_INVALID_SIGNER_OF_WRAP_CCC => Error::InvalidSignerOfWrapCCC, - ERROR_ID_INVALID_SPENT_QUANTITY => Error::InvalidSpentQuantity { - asset_quantity_from: rlp.val_at(1)?, - spent_quantity: rlp.val_at(2)?, - }, _ => return Err(DecoderError::Custom("Invalid SyntaxError")), }; RlpHelper::check_size(rlp, tag)?; @@ -299,7 +181,6 @@ impl Decodable for Error { } } - impl Display for Error { fn fmt(&self, f: &mut Formatter) -> FormatResult { match self { @@ -307,50 +188,26 @@ impl Display for Error { tracker, index, } => write!(f, "The previous output of inputs/burns are duplicated: ({}, {})", tracker, index), - Error::EmptyShardOwners (shard_id) => write!(f, "Shard({}) must have at least one owner", shard_id), - Error::InconsistentTransactionInOut => write!(f, "The sum of the transaction's inputs is different from the sum of the transaction's outputs"), - Error::InconsistentTransactionInOutWithOrders => write!(f, "The transaction's input and output do not follow its orders"), + Error::EmptyShardOwners(shard_id) => write!(f, "Shard({}) must have at least one owner", shard_id), + Error::InconsistentTransactionInOut => { + write!(f, "The sum of the transaction's inputs is different from the sum of the transaction's outputs") + } Error::InsufficientFee { minimal, got, } => write!(f, "Insufficient fee. Min={}, Given={}", minimal, got), - Error::InvalidAssetType (addr) => write!(f, "Asset type is invalid: {}", addr), + Error::InvalidAssetType(addr) => write!(f, "Asset type is invalid: {}", addr), Error::InvalidCustomAction(err) => write!(f, "Invalid custom action: {}", err), - Error::InvalidNetworkId (network_id) => write!(f, "{} is an invalid network id", network_id), - Error::InvalidOrderAssetQuantities { - from, - to, - fee, - } => write!(f, "The asset exchange ratio of the order is invalid: from:to:fee = {}:{}:{}", from, to, fee), - Error::InvalidOrderAssetTypes => write!(f, "There are same shard asset types in the order"), - Error::InvalidAssetTypesWithOrder { - asset_type, - idx - } => write!(f, "{}th {} asset has a different type from the order", idx, asset_type), - Error::InvalidAssetOwnerWithOrder { - asset_type, - idx - } => write!(f, "Owner of the {}th {} assets is not valid", idx, asset_type), - Error::InvalidOrderInOutIndices => write!(f, "The order on transfer is invalid because its input/output indices are wrong or overlapped with other orders"), - Error::InvalidOrderLockScriptHash (lock_script_hash) => write!(f, "The lock script hash of the order is different from the output: {}", lock_script_hash), - Error::InvalidOrderParameters (parameters) => write!(f, "The parameters of the order is different from the output: {:?}", parameters), - Error::InvalidOriginOutputs (order_hash) => write!(f, "The order({}) is invalid because its origin outputs are wrong", order_hash), + Error::InvalidNetworkId(network_id) => write!(f, "{} is an invalid network id", network_id), Error::InvalidApproval(err) => write!(f, "Transaction has an invalid approval :{}", err), - Error::MetadataTooBig => write!(f, "Metadata size is too big."), - Error::OrderRecipientsAreSame => write!(f, "Both the lock script hash and parameters should not be same between maker and relayer"), - Error::TextContentTooBig => write!(f, "The content of the text is too big"), - Error::TooManyOutputs (num) => write!(f, "The number of outputs is {}. It should be 126 or less.", num), - Error::TransactionIsTooBig => write!(f, "Transaction size exceeded the body size limit"), - Error::ZeroQuantity => write!(f, "A quantity cannot be 0"), + Error::MetadataTooBig => write!(f, "Metadata size is too big."), + Error::TextContentTooBig => write!(f, "The content of the text is too big"), + Error::TooManyOutputs(num) => write!(f, "The number of outputs is {}. It should be 126 or less.", num), + Error::TransactionIsTooBig => write!(f, "Transaction size exceeded the body size limit"), + Error::ZeroQuantity => write!(f, "A quantity cannot be 0"), Error::CannotChangeWcccAssetScheme => write!(f, "Cannot change the asset scheme of WCCC"), Error::DisabledTransaction => write!(f, "Used the disabled transaction"), Error::InvalidSignerOfWrapCCC => write!(f, "The signer of WrapCCC must be matched"), - Error::InvalidSpentQuantity { - asset_quantity_from, - spent_quantity, - } => { - write!(f, "The spentQuantity value {} in an OrderOnTransfer cannot exceed the assetQuantityFrom value {}", spent_quantity, asset_quantity_from) - } } } } diff --git a/types/src/transaction/action.rs b/types/src/transaction/action.rs index 7199859ea5..22e321af63 100644 --- a/types/src/transaction/action.rs +++ b/types/src/transaction/action.rs @@ -22,7 +22,7 @@ use primitives::{Bytes, H160, H256}; use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; use crate::errors::SyntaxError; -use crate::transaction::{AssetMintOutput, AssetTransferInput, AssetTransferOutput, OrderOnTransfer, ShardTransaction}; +use crate::transaction::{AssetMintOutput, AssetTransferInput, AssetTransferOutput, ShardTransaction}; use crate::{CommonParams, ShardId}; const PAY: u8 = 0x02; @@ -62,7 +62,6 @@ pub enum Action { burns: Vec, inputs: Vec, outputs: Vec, - orders: Vec, metadata: String, approvals: Vec, expiration: Option, @@ -177,7 +176,6 @@ impl Action { burns, inputs, outputs, - orders, .. } => { if outputs.len() > 512 { @@ -197,11 +195,6 @@ impl Action { if outputs.iter().any(|output| output.quantity == 0) { return Err(SyntaxError::ZeroQuantity) } - for order in orders { - order.order.verify()?; - } - verify_order_indices(orders, inputs.len(), outputs.len())?; - verify_input_and_output_consistent_with_order(orders, inputs, outputs)?; } Action::ChangeAssetScheme { asset_type, @@ -250,7 +243,7 @@ impl Action { Ok(()) } - pub fn verify_with_params(&self, common_params: &CommonParams, is_order_disabled: bool) -> Result<(), SyntaxError> { + pub fn verify_with_params(&self, common_params: &CommonParams) -> Result<(), SyntaxError> { if let Some(network_id) = self.network_id() { let system_network_id = common_params.network_id(); if network_id != system_network_id { @@ -269,7 +262,6 @@ impl Action { } } Action::TransferAsset { - orders, metadata, .. } => { @@ -277,10 +269,6 @@ impl Action { if metadata.len() > max_transfer_metadata_size { return Err(SyntaxError::MetadataTooBig) } - - if is_order_disabled && !orders.is_empty() { - return Err(SyntaxError::DisabledTransaction) - } } Action::ChangeAssetScheme { metadata, @@ -409,14 +397,12 @@ impl From for Option { burns, inputs, outputs, - orders, .. } => Some(ShardTransaction::TransferAsset { network_id, burns, inputs, outputs, - orders, }), Action::ChangeAssetScheme { network_id, @@ -497,18 +483,19 @@ impl Encodable for Action { burns, inputs, outputs, - orders, metadata, approvals, expiration, } => { + let empty: Vec = vec![]; s.begin_list(9) .append(&TRANSFER_ASSET) .append(network_id) .append_list(burns) .append_list(inputs) .append_list(outputs) - .append_list(orders) + // NOTE: The orders field removed. + .append_list(&empty) .append(metadata) .append_list(approvals) .append(expiration); @@ -690,7 +677,6 @@ impl Decodable for Action { burns: rlp.list_at(2)?, inputs: rlp.list_at(3)?, outputs: rlp.list_at(4)?, - orders: rlp.list_at(5)?, metadata: rlp.val_at(6)?, approvals: rlp.list_at(7)?, expiration: rlp.val_at(8)?, @@ -918,205 +904,12 @@ fn check_duplication_in_prev_out( Ok(()) } -fn verify_order_indices(orders: &[OrderOnTransfer], input_len: usize, output_len: usize) -> Result<(), SyntaxError> { - let mut input_check = vec![false; input_len]; - let mut output_check = vec![false; output_len]; - - for order_info in orders { - for input_idx in order_info.input_from_indices.iter().chain(order_info.input_fee_indices.iter()) { - if *input_idx >= input_len || input_check[*input_idx] { - return Err(SyntaxError::InvalidOrderInOutIndices) - } - input_check[*input_idx] = true; - } - - for output_idx in order_info - .output_from_indices - .iter() - .chain(order_info.output_to_indices.iter()) - .chain(order_info.output_owned_fee_indices.iter()) - .chain(order_info.output_transferred_fee_indices.iter()) - { - if *output_idx >= output_len || output_check[*output_idx] { - return Err(SyntaxError::InvalidOrderInOutIndices) - } - output_check[*output_idx] = true; - } - } - Ok(()) -} - -fn verify_input_and_output_consistent_with_order( - orders: &[OrderOnTransfer], - inputs: &[AssetTransferInput], - outputs: &[AssetTransferOutput], -) -> Result<(), SyntaxError> { - for order_tx in orders { - let mut input_quantity_from: u64 = 0; - let mut input_quantity_fee: u64 = 0; - let mut output_quantity_from: u64 = 0; - let mut output_quantity_to: u64 = 0; - let mut output_quantity_fee_remaining: u64 = 0; - let mut output_quantity_fee_given: u64 = 0; - - let order = &order_tx.order; - - // Check if a valid amount is spent - if order_tx.spent_quantity > order.asset_quantity_from { - return Err(SyntaxError::InvalidSpentQuantity { - asset_quantity_from: order.asset_quantity_from, - spent_quantity: order_tx.spent_quantity, - }) - } - - // Check input indices and calculate input_quantity_from and input_quantity_fee - for idx in order_tx.input_from_indices.iter() { - let prev_out = &inputs[*idx].prev_out; - if prev_out.asset_type == order.asset_type_from && prev_out.shard_id == order.shard_id_from { - input_quantity_from += prev_out.quantity - } else { - return Err(SyntaxError::InvalidAssetTypesWithOrder { - asset_type: "INPUT FROM".to_string(), - idx: *idx, - }) - } - } - - for idx in order_tx.input_fee_indices.iter() { - let prev_out = &inputs[*idx].prev_out; - if prev_out.asset_type == order.asset_type_fee && prev_out.shard_id == order.shard_id_fee { - input_quantity_fee += prev_out.quantity - } else { - return Err(SyntaxError::InvalidAssetTypesWithOrder { - asset_type: "INPUT FEE".to_string(), - idx: *idx, - }) - } - } - - // Check output indices and calculate output_quantity_from, output_quantity_to, output_quantity_fee_remaining and output_quantity_fee_given - for idx in order_tx.output_from_indices.iter() { - let output = &outputs[*idx]; - let owned_by_maker = order.check_transfer_output(output)?; - if !owned_by_maker { - return Err(SyntaxError::InvalidAssetOwnerWithOrder { - asset_type: "OUTPUT FROM".to_string(), - idx: *idx, - }) - } - if output.asset_type == order.asset_type_from && output.shard_id == order.shard_id_from { - output_quantity_from += output.quantity - } else { - return Err(SyntaxError::InvalidAssetTypesWithOrder { - asset_type: "OUTPUT FROM".to_string(), - idx: *idx, - }) - } - } - - for idx in order_tx.output_to_indices.iter() { - let output = &outputs[*idx]; - let owned_by_maker = order.check_transfer_output(output)?; - if !owned_by_maker { - return Err(SyntaxError::InvalidAssetOwnerWithOrder { - asset_type: "OUTPUT TO".to_string(), - idx: *idx, - }) - } - if output.asset_type == order.asset_type_to && output.shard_id == order.shard_id_to { - output_quantity_to += output.quantity - } else { - return Err(SyntaxError::InvalidAssetTypesWithOrder { - asset_type: "OUTPUT TO".to_string(), - idx: *idx, - }) - } - } - - for idx in order_tx.output_owned_fee_indices.iter() { - let output = &outputs[*idx]; - let owned_by_maker = order.check_transfer_output(output)?; - if !owned_by_maker { - return Err(SyntaxError::InvalidAssetOwnerWithOrder { - asset_type: "OUTPUT OWNED FEE".to_string(), - idx: *idx, - }) - } - if output.asset_type == order.asset_type_fee && output.shard_id == order.shard_id_fee { - output_quantity_fee_remaining += output.quantity - } else { - return Err(SyntaxError::InvalidAssetTypesWithOrder { - asset_type: "OUTPUT OWNED FEE".to_string(), - idx: *idx, - }) - } - } - - for idx in order_tx.output_transferred_fee_indices.iter() { - let output = &outputs[*idx]; - let owned_by_maker = order.check_transfer_output(output)?; - if owned_by_maker { - return Err(SyntaxError::InvalidAssetOwnerWithOrder { - asset_type: "OUTPUT TRANSFERRED FEE".to_string(), - idx: *idx, - }) - } - if output.asset_type == order.asset_type_fee && output.shard_id == order.shard_id_fee { - output_quantity_fee_given += output.quantity - } else { - return Err(SyntaxError::InvalidAssetTypesWithOrder { - asset_type: "OUTPUT TRANSFERRED FEE".to_string(), - idx: *idx, - }) - } - } - - // NOTE: If input_quantity_from == output_quantity_from, it means the asset is not spent as the order. - // If it's allowed, everyone can move the asset from one to another without permission. - if input_quantity_from <= output_quantity_from - || input_quantity_from - output_quantity_from != order_tx.spent_quantity - { - return Err(SyntaxError::InconsistentTransactionInOutWithOrders) - } - if !is_ratio_greater_or_equal( - order.asset_quantity_from, - order.asset_quantity_to, - order_tx.spent_quantity, - output_quantity_to, - ) { - return Err(SyntaxError::InconsistentTransactionInOutWithOrders) - } - if input_quantity_fee < output_quantity_fee_remaining - || input_quantity_fee - output_quantity_fee_remaining != output_quantity_fee_given - || !is_ratio_equal( - order.asset_quantity_from, - order.asset_quantity_fee, - order_tx.spent_quantity, - output_quantity_fee_given, - ) - { - return Err(SyntaxError::InconsistentTransactionInOutWithOrders) - } - } - Ok(()) -} - -fn is_ratio_equal(from: u64, fee: u64, spent: u64, fee_given: u64) -> bool { - // from:fee = spent:fee_given - u128::from(from) * u128::from(fee_given) == u128::from(fee) * u128::from(spent) -} - -fn is_ratio_greater_or_equal(from: u64, to: u64, spent: u64, output: u64) -> bool { - // from:to <= spent:output - u128::from(from) * u128::from(output) >= u128::from(to) * u128::from(spent) -} - #[cfg(test)] mod tests { use rlp::rlp_encode_and_decode_test; use super::*; - use crate::transaction::{AssetOutPoint, Order}; + use crate::transaction::AssetOutPoint; #[test] fn encode_and_decode_mint_asset() { @@ -1195,7 +988,6 @@ mod tests { let burns = vec![]; let inputs = vec![]; let outputs = vec![]; - let orders = vec![]; let network_id = "tc".into(); let metadata = "".into(); rlp_encode_and_decode_test!(Action::TransferAsset { @@ -1203,7 +995,6 @@ mod tests { burns, inputs, outputs, - orders, metadata, approvals: vec![Signature::random(), Signature::random()], expiration: Some(10), @@ -1266,760 +1057,6 @@ mod tests { }); } - #[test] - fn verify_transfer_transaction_with_order() { - let asset_type_a = H160::random(); - let asset_type_b = H160::random(); - let lock_script_hash = H160::random(); - let parameters = vec![vec![1]]; - let origin_output = AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_a, - shard_id: 0, - quantity: 30, - }; - let order = Order { - asset_type_from: asset_type_a, - asset_type_to: asset_type_b, - asset_type_fee: H160::zero(), - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 30, - asset_quantity_to: 10, - asset_quantity_fee: 0, - origin_outputs: vec![origin_output.clone()], - expiration: 10, - lock_script_hash_from: lock_script_hash, - parameters_from: parameters.clone(), - lock_script_hash_fee: lock_script_hash, - parameters_fee: parameters.clone(), - }; - - let action = Action::TransferAsset { - network_id: NetworkId::default(), - burns: vec![], - inputs: vec![ - AssetTransferInput { - prev_out: origin_output, - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - AssetTransferInput { - prev_out: AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_b, - shard_id: 0, - quantity: 10, - }, - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - ], - outputs: vec![ - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_b, - shard_id: 0, - quantity: 10, - }, - AssetTransferOutput { - lock_script_hash, - parameters: vec![], - asset_type: asset_type_a, - shard_id: 0, - quantity: 30, - }, - ], - orders: vec![OrderOnTransfer { - order, - spent_quantity: 30, - input_from_indices: vec![0], - input_fee_indices: vec![], - output_from_indices: vec![], - output_to_indices: vec![0], - output_owned_fee_indices: vec![], - output_transferred_fee_indices: vec![], - }], - metadata: "".into(), - approvals: vec![], - expiration: None, - }; - assert_eq!(action.verify(), Ok(())); - let mut common_params = CommonParams::default_for_test(); - common_params.set_max_asset_scheme_metadata_size(1000); - common_params.set_max_transfer_metadata_size(1000); - common_params.set_max_text_content_size(1000); - assert_eq!(action.verify_with_params(&common_params, false), Ok(())); - } - - #[test] - fn verify_partial_fill_transfer_transaction_with_order() { - let asset_type_a = H160::random(); - let asset_type_b = H160::random(); - let asset_type_c = H160::random(); - let lock_script_hash = H160::random(); - let parameters1 = vec![vec![1]]; - let parameters2 = vec![vec![2]]; - - let origin_output_1 = AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_a, - shard_id: 0, - quantity: 40, - }; - let origin_output_2 = AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_c, - shard_id: 0, - quantity: 30, - }; - - let order = Order { - asset_type_from: asset_type_a, - asset_type_to: asset_type_b, - asset_type_fee: asset_type_c, - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 30, - asset_quantity_to: 20, - asset_quantity_fee: 30, - origin_outputs: vec![origin_output_1.clone(), origin_output_2.clone()], - expiration: 10, - lock_script_hash_from: lock_script_hash, - parameters_from: parameters1.clone(), - lock_script_hash_fee: lock_script_hash, - parameters_fee: parameters2.clone(), - }; - - let action = Action::TransferAsset { - network_id: NetworkId::default(), - burns: vec![], - inputs: vec![ - AssetTransferInput { - prev_out: origin_output_1, - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - AssetTransferInput { - prev_out: origin_output_2, - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - AssetTransferInput { - prev_out: AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_b, - shard_id: 0, - quantity: 10, - }, - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - ], - outputs: vec![ - AssetTransferOutput { - lock_script_hash, - parameters: parameters1.clone(), - asset_type: asset_type_a, - shard_id: 0, - quantity: 25, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters1.clone(), - asset_type: asset_type_b, - shard_id: 0, - quantity: 10, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters1.clone(), - asset_type: asset_type_c, - shard_id: 0, - quantity: 15, - }, - AssetTransferOutput { - lock_script_hash, - parameters: vec![], - asset_type: asset_type_a, - shard_id: 0, - quantity: 15, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters2.clone(), - asset_type: asset_type_c, - shard_id: 0, - quantity: 15, - }, - ], - orders: vec![OrderOnTransfer { - order, - spent_quantity: 15, - input_from_indices: vec![0], - input_fee_indices: vec![1], - output_from_indices: vec![0], - output_to_indices: vec![1], - output_owned_fee_indices: vec![2], - output_transferred_fee_indices: vec![4], - }], - metadata: "".into(), - approvals: vec![], - expiration: None, - }; - - assert_eq!(action.verify(), Ok(())); - let mut common_params = CommonParams::default_for_test(); - common_params.set_max_asset_scheme_metadata_size(1000); - common_params.set_max_transfer_metadata_size(1000); - common_params.set_max_text_content_size(1000); - assert_eq!(action.verify_with_params(&common_params, false), Ok(())); - } - - #[test] - fn verify_inconsistent_transfer_transaction_with_order() { - let asset_type_a = H160::random(); - let asset_type_b = H160::random(); - let asset_type_c = H160::random(); - let lock_script_hash = H160::random(); - let parameters = vec![vec![1]]; - let parameters_fee = vec![vec![2]]; - - // Case 1: ratio is wrong - let origin_output = AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_a, - shard_id: 0, - quantity: 30, - }; - let order = Order { - asset_type_from: asset_type_a, - asset_type_to: asset_type_b, - asset_type_fee: H160::zero(), - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 25, - asset_quantity_to: 10, - asset_quantity_fee: 0, - origin_outputs: vec![origin_output.clone()], - expiration: 10, - lock_script_hash_from: lock_script_hash, - parameters_from: parameters.clone(), - lock_script_hash_fee: lock_script_hash, - parameters_fee: parameters_fee.clone(), - }; - - let action = Action::TransferAsset { - network_id: NetworkId::default(), - burns: vec![], - inputs: vec![ - AssetTransferInput { - prev_out: origin_output, - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - AssetTransferInput { - prev_out: AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_b, - shard_id: 0, - quantity: 10, - }, - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - ], - outputs: vec![ - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_b, - shard_id: 0, - quantity: 10, - }, - AssetTransferOutput { - lock_script_hash, - parameters: vec![], - asset_type: asset_type_a, - shard_id: 0, - quantity: 30, - }, - ], - orders: vec![OrderOnTransfer { - order, - spent_quantity: 25, - input_from_indices: vec![0], - input_fee_indices: vec![], - output_from_indices: vec![], - output_to_indices: vec![0], - output_owned_fee_indices: vec![], - output_transferred_fee_indices: vec![], - }], - metadata: "".into(), - approvals: vec![], - expiration: None, - }; - assert_eq!(action.verify(), Err(SyntaxError::InconsistentTransactionInOutWithOrders)); - - // Case 2: multiple outputs with same order and asset_type - let origin_output_1 = AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_a, - shard_id: 0, - quantity: 40, - }; - let origin_output_2 = AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_c, - shard_id: 0, - quantity: 40, - }; - let order = Order { - asset_type_from: asset_type_a, - asset_type_to: asset_type_b, - asset_type_fee: asset_type_c, - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 30, - asset_quantity_to: 10, - asset_quantity_fee: 30, - origin_outputs: vec![origin_output_1.clone(), origin_output_2.clone()], - expiration: 10, - lock_script_hash_from: lock_script_hash, - parameters_from: parameters.clone(), - lock_script_hash_fee: lock_script_hash, - parameters_fee: parameters_fee.clone(), - }; - - // Case 2-1: asset_type_from - let action = Action::TransferAsset { - network_id: NetworkId::default(), - burns: vec![], - inputs: vec![ - AssetTransferInput { - prev_out: origin_output_1.clone(), - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - AssetTransferInput { - prev_out: origin_output_2.clone(), - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - AssetTransferInput { - prev_out: AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_b, - shard_id: 0, - quantity: 10, - }, - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - ], - outputs: vec![ - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_a, - shard_id: 0, - quantity: 5, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_a, - shard_id: 0, - quantity: 6, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_b, - shard_id: 0, - quantity: 10, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_c, - shard_id: 0, - quantity: 10, - }, - AssetTransferOutput { - lock_script_hash, - parameters: vec![], - asset_type: asset_type_a, - shard_id: 0, - quantity: 29, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters_fee.clone(), - asset_type: asset_type_c, - shard_id: 0, - quantity: 30, - }, - ], - orders: vec![OrderOnTransfer { - order: order.clone(), - spent_quantity: 30, - input_from_indices: vec![0], - input_fee_indices: vec![1], - output_from_indices: vec![0, 1], - output_to_indices: vec![2], - output_owned_fee_indices: vec![3], - output_transferred_fee_indices: vec![5], - }], - metadata: "".into(), - approvals: vec![], - expiration: None, - }; - assert_eq!(action.verify(), Err(SyntaxError::InconsistentTransactionInOutWithOrders)); - - // Case 2-2: asset_type_to - let action = Action::TransferAsset { - network_id: NetworkId::default(), - burns: vec![], - inputs: vec![ - AssetTransferInput { - prev_out: origin_output_1.clone(), - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - AssetTransferInput { - prev_out: origin_output_2.clone(), - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - AssetTransferInput { - prev_out: AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_b, - shard_id: 0, - quantity: 10, - }, - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - ], - outputs: vec![ - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_a, - shard_id: 0, - quantity: 10, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_b, - shard_id: 0, - quantity: 5, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_b, - shard_id: 0, - quantity: 4, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_c, - shard_id: 0, - quantity: 10, - }, - AssetTransferOutput { - lock_script_hash, - parameters: vec![], - asset_type: asset_type_a, - shard_id: 0, - quantity: 30, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters_fee.clone(), - asset_type: asset_type_c, - shard_id: 0, - quantity: 30, - }, - AssetTransferOutput { - lock_script_hash, - parameters: vec![], - asset_type: asset_type_b, - shard_id: 0, - quantity: 1, - }, - ], - orders: vec![OrderOnTransfer { - order: order.clone(), - spent_quantity: 30, - input_from_indices: vec![0], - input_fee_indices: vec![1], - output_from_indices: vec![0], - output_to_indices: vec![1, 2], - output_owned_fee_indices: vec![3], - output_transferred_fee_indices: vec![5], - }], - metadata: "".into(), - approvals: vec![], - expiration: None, - }; - assert_eq!(action.verify(), Err(SyntaxError::InconsistentTransactionInOutWithOrders)); - - // Case 2-3: asset_type_fee - let action = Action::TransferAsset { - network_id: NetworkId::default(), - burns: vec![], - inputs: vec![ - AssetTransferInput { - prev_out: origin_output_1.clone(), - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - AssetTransferInput { - prev_out: origin_output_2.clone(), - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - AssetTransferInput { - prev_out: AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_b, - shard_id: 0, - quantity: 10, - }, - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - ], - outputs: vec![ - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_a, - shard_id: 0, - quantity: 10, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_b, - shard_id: 0, - quantity: 10, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_c, - shard_id: 0, - quantity: 6, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_c, - shard_id: 0, - quantity: 5, - }, - AssetTransferOutput { - lock_script_hash, - parameters: vec![], - asset_type: asset_type_a, - shard_id: 0, - quantity: 30, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters_fee.clone(), - asset_type: asset_type_c, - shard_id: 0, - quantity: 29, - }, - ], - orders: vec![OrderOnTransfer { - order: order.clone(), - spent_quantity: 30, - input_from_indices: vec![0], - input_fee_indices: vec![1], - output_from_indices: vec![0], - output_to_indices: vec![1], - output_owned_fee_indices: vec![2, 3], - output_transferred_fee_indices: vec![5], - }], - metadata: "".into(), - approvals: vec![], - expiration: None, - }; - assert_eq!(action.verify(), Err(SyntaxError::InconsistentTransactionInOutWithOrders)); - } - - #[test] - fn verify_transfer_transaction_with_two_orders() { - let asset_type_a = H160::random(); - let asset_type_b = H160::random(); - let lock_script_hash = H160::random(); - let parameters = vec![vec![1]]; - let origin_output_1 = AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_a, - shard_id: 0, - quantity: 30, - }; - let origin_output_2 = AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_b, - shard_id: 0, - quantity: 10, - }; - - let order_1 = Order { - asset_type_from: asset_type_a, - asset_type_to: asset_type_b, - asset_type_fee: H160::zero(), - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 30, - asset_quantity_to: 10, - asset_quantity_fee: 0, - origin_outputs: vec![origin_output_1.clone()], - expiration: 10, - lock_script_hash_from: lock_script_hash, - parameters_from: parameters.clone(), - lock_script_hash_fee: lock_script_hash, - parameters_fee: parameters.clone(), - }; - let order_2 = Order { - asset_type_from: asset_type_b, - asset_type_to: asset_type_a, - asset_type_fee: H160::zero(), - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 10, - asset_quantity_to: 20, - asset_quantity_fee: 0, - origin_outputs: vec![origin_output_2.clone()], - expiration: 10, - lock_script_hash_from: lock_script_hash, - parameters_from: parameters.clone(), - lock_script_hash_fee: lock_script_hash, - parameters_fee: parameters.clone(), - }; - - let action = Action::TransferAsset { - network_id: NetworkId::default(), - burns: vec![], - inputs: vec![ - AssetTransferInput { - prev_out: origin_output_1, - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - AssetTransferInput { - prev_out: origin_output_2, - timelock: None, - lock_script: vec![0x30, 0x01], - unlock_script: vec![], - }, - ], - outputs: vec![ - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_b, - shard_id: 0, - quantity: 10, - }, - AssetTransferOutput { - lock_script_hash, - parameters: parameters.clone(), - asset_type: asset_type_a, - shard_id: 0, - quantity: 20, - }, - AssetTransferOutput { - lock_script_hash, - parameters: vec![], - asset_type: asset_type_a, - shard_id: 0, - quantity: 10, - }, - ], - orders: vec![ - OrderOnTransfer { - order: order_1, - spent_quantity: 30, - input_from_indices: vec![0], - input_fee_indices: vec![], - output_from_indices: vec![], - output_to_indices: vec![0], - output_owned_fee_indices: vec![], - output_transferred_fee_indices: vec![], - }, - OrderOnTransfer { - order: order_2, - spent_quantity: 10, - input_from_indices: vec![1], - input_fee_indices: vec![], - output_from_indices: vec![], - output_to_indices: vec![1], - output_owned_fee_indices: vec![], - output_transferred_fee_indices: vec![], - }, - ], - metadata: "".into(), - approvals: vec![], - expiration: None, - }; - assert_eq!(action.verify(), Ok(())); - let mut common_params = CommonParams::default_for_test(); - common_params.set_max_asset_scheme_metadata_size(1000); - common_params.set_max_transfer_metadata_size(1000); - common_params.set_max_text_content_size(1000); - assert_eq!(action.verify_with_params(&common_params, false), Ok(())); - } - #[test] fn verify_unwrap_ccc_transaction_should_fail() { let tx_zero_quantity = Action::UnwrapCCC { diff --git a/types/src/transaction/mod.rs b/types/src/transaction/mod.rs index a09a3339cf..acbbaa748d 100644 --- a/types/src/transaction/mod.rs +++ b/types/src/transaction/mod.rs @@ -18,7 +18,6 @@ mod action; mod asset_out_point; mod incomplete_transaction; mod input; -mod order; mod output; mod partial_hashing; mod shard; @@ -30,7 +29,6 @@ pub use self::action::Action; pub use self::asset_out_point::AssetOutPoint; pub use self::incomplete_transaction::IncompleteTransaction; pub use self::input::AssetTransferInput; -pub use self::order::{Order, OrderOnTransfer}; pub use self::output::{AssetMintOutput, AssetTransferOutput}; pub use self::partial_hashing::{HashingError, PartialHashing}; pub use self::shard::{AssetWrapCCCOutput, ShardTransaction}; diff --git a/types/src/transaction/order.rs b/types/src/transaction/order.rs deleted file mode 100644 index 5cae34bf93..0000000000 --- a/types/src/transaction/order.rs +++ /dev/null @@ -1,453 +0,0 @@ -// Copyright 2018-2019 Kodebox, Inc. -// This file is part of CodeChain. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -use primitives::{Bytes, H160}; - -use crate::ShardId; - -use super::{AssetOutPoint, AssetTransferOutput}; -use crate::errors::SyntaxError; - -#[derive(Debug, Clone, Eq, PartialEq, RlpDecodable, RlpEncodable)] -pub struct Order { - // Main order information - pub asset_type_from: H160, - pub asset_type_to: H160, - pub asset_type_fee: H160, - pub shard_id_from: ShardId, - pub shard_id_to: ShardId, - pub shard_id_fee: ShardId, - pub asset_quantity_from: u64, - pub asset_quantity_to: u64, - pub asset_quantity_fee: u64, - /// previous outputs that order is started - pub origin_outputs: Vec, - /// expiration time by second - pub expiration: u64, - pub lock_script_hash_from: H160, - pub parameters_from: Vec, - pub lock_script_hash_fee: H160, - pub parameters_fee: Vec, -} - -#[derive(Debug, Clone, Eq, PartialEq, RlpDecodable, RlpEncodable)] -pub struct OrderOnTransfer { - pub order: Order, - /// Spent quantity of asset_type_from - pub spent_quantity: u64, - // Indices of asset_type_from - pub input_from_indices: Vec, - // Indices of asset_type_fee - pub input_fee_indices: Vec, - // Indices of remain asset_type_from - pub output_from_indices: Vec, - // Indices of asset_type_to - pub output_to_indices: Vec, - // Indices of ramain asset_type_fee - pub output_owned_fee_indices: Vec, - // Indices of paid asset_type_fee - pub output_transferred_fee_indices: Vec, -} - -impl Order { - // FIXME: Remove this after the clippy nonminimal bool bug is fixed - // https://rust-lang.github.io/rust-clippy/v0.0.212/#nonminimal_bool - #![cfg_attr(feature = "cargo-clippy", allow(clippy::nonminimal_bool))] - pub fn verify(&self) -> Result<(), SyntaxError> { - // If asset_quantity_fee is zero, it means there's no fee to pay. - // asset_type_from and asset_type_to can be the same with asset_type_fee. - if self.asset_type_from == self.asset_type_to && self.shard_id_from == self.shard_id_to { - return Err(SyntaxError::InvalidOrderAssetTypes) - } - // Invalid asset exchange transaction. The case is naive transfer transaction if either of asset_quantity_from or asset_quantity_to is zero - if (self.asset_quantity_from == 0) ^ (self.asset_quantity_to == 0) { - return Err(SyntaxError::InvalidOrderAssetQuantities { - from: self.asset_quantity_from, - to: self.asset_quantity_to, - fee: self.asset_quantity_fee, - }) - } - // asset_quantity_fee should be mutiples of asset_quantity_from - if self.asset_quantity_from == 0 && self.asset_quantity_fee != 0 - || self.asset_quantity_from != 0 && self.asset_quantity_fee % self.asset_quantity_from != 0 - { - return Err(SyntaxError::InvalidOrderAssetQuantities { - from: self.asset_quantity_from, - to: self.asset_quantity_to, - fee: self.asset_quantity_fee, - }) - } - // fee recipient should not be the same with the one provided asset_type_from - if self.asset_quantity_fee != 0 - && self.lock_script_hash_fee == self.lock_script_hash_from - && self.parameters_fee == self.parameters_from - { - return Err(SyntaxError::OrderRecipientsAreSame) - } - if self.origin_outputs.is_empty() { - return Err(SyntaxError::InvalidOriginOutputs(self.hash())) - } - // Check if the origin_outputs include other types of asset except asset_type_from and asset_type_fee - for origin_output in self.origin_outputs.iter() { - if (origin_output.asset_type != self.asset_type_from || origin_output.shard_id != self.shard_id_from) - && (origin_output.asset_type != self.asset_type_fee || origin_output.shard_id != self.shard_id_fee) - { - return Err(SyntaxError::InvalidOriginOutputs(self.hash())) - } - } - Ok(()) - } - - // Check if an arbitrary output is involved in this order - pub fn check_transfer_output(&self, output: &AssetTransferOutput) -> Result { - if self.asset_quantity_fee != 0 - && self.asset_type_fee == output.asset_type - && self.shard_id_fee == output.shard_id - && self.lock_script_hash_fee == output.lock_script_hash - && self.parameters_fee == output.parameters - { - // owned by relayer - return Ok(false) - } - - if self.lock_script_hash_from != output.lock_script_hash { - return Err(SyntaxError::InvalidOrderLockScriptHash(self.lock_script_hash_from)) - } - if self.parameters_from != output.parameters { - return Err(SyntaxError::InvalidOrderParameters(self.parameters_from.to_vec())) - } - // owned by maker - Ok(true) - } - - pub fn consume(&self, quantity: u64) -> Order { - Order { - asset_type_from: self.asset_type_from, - asset_type_to: self.asset_type_to, - asset_type_fee: self.asset_type_fee, - shard_id_from: self.shard_id_from, - shard_id_to: self.shard_id_to, - shard_id_fee: self.shard_id_fee, - asset_quantity_from: self.asset_quantity_from - quantity, - asset_quantity_to: self.asset_quantity_to - - (u128::from(quantity) * u128::from(self.asset_quantity_to) / u128::from(self.asset_quantity_from)) - as u64, - asset_quantity_fee: self.asset_quantity_fee - - (u128::from(quantity) * u128::from(self.asset_quantity_fee) / u128::from(self.asset_quantity_from)) - as u64, - origin_outputs: self.origin_outputs.clone(), - expiration: self.expiration, - lock_script_hash_from: self.lock_script_hash_from, - parameters_from: self.parameters_from.clone(), - lock_script_hash_fee: self.lock_script_hash_fee, - parameters_fee: self.parameters_fee.clone(), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use primitives::H256; - - #[test] - fn verify_order_success() { - let asset_type_from = H160::random(); - let asset_type_to = H160::random(); - let asset_type_fee = H160::random(); - let order = Order { - asset_type_from, - asset_type_to, - asset_type_fee, - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 3, - asset_quantity_to: 2, - asset_quantity_fee: 3, - origin_outputs: vec![AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_from, - shard_id: 0, - quantity: 10, - }], - expiration: 10, - lock_script_hash_from: H160::random(), - parameters_from: vec![vec![1]], - lock_script_hash_fee: H160::random(), - parameters_fee: vec![vec![1]], - }; - assert_eq!(order.verify(), Ok(())); - - let order = Order { - asset_type_from, - asset_type_to, - asset_type_fee, - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 3, - asset_quantity_to: 2, - asset_quantity_fee: 0, - origin_outputs: vec![AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_from, - shard_id: 0, - quantity: 10, - }], - expiration: 10, - lock_script_hash_from: H160::random(), - parameters_from: vec![vec![1]], - lock_script_hash_fee: H160::random(), - parameters_fee: vec![vec![1]], - }; - assert_eq!(order.verify(), Ok(())); - - let order = Order { - asset_type_from, - asset_type_to, - asset_type_fee, - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 0, - asset_quantity_to: 0, - asset_quantity_fee: 0, - origin_outputs: vec![AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_from, - shard_id: 0, - quantity: 10, - }], - expiration: 10, - lock_script_hash_from: H160::random(), - parameters_from: vec![vec![1]], - lock_script_hash_fee: H160::random(), - parameters_fee: vec![vec![1]], - }; - assert_eq!(order.verify(), Ok(())); - } - - #[test] - fn verify_order_fail() { - // 1. origin outputs are invalid - let asset_type_from = H160::random(); - let asset_type_to = H160::random(); - let asset_type_fee = H160::random(); - let order = Order { - asset_type_from, - asset_type_to, - asset_type_fee, - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 3, - asset_quantity_to: 2, - asset_quantity_fee: 3, - origin_outputs: vec![AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: H160::random(), - shard_id: 0, - quantity: 10, - }], - expiration: 10, - lock_script_hash_from: H160::random(), - parameters_from: vec![vec![1]], - lock_script_hash_fee: H160::random(), - parameters_fee: vec![vec![1]], - }; - assert_eq!(order.verify(), Err(SyntaxError::InvalidOriginOutputs(order.hash()))); - - let order = Order { - asset_type_from, - asset_type_to, - asset_type_fee, - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 3, - asset_quantity_to: 2, - asset_quantity_fee: 3, - origin_outputs: vec![], - expiration: 10, - lock_script_hash_from: H160::random(), - parameters_from: vec![vec![1]], - lock_script_hash_fee: H160::random(), - parameters_fee: vec![vec![1]], - }; - assert_eq!(order.verify(), Err(SyntaxError::InvalidOriginOutputs(order.hash()))); - - // 2. asset quantitys are invalid - let order = Order { - asset_type_from, - asset_type_to, - asset_type_fee, - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 3, - asset_quantity_to: 0, - asset_quantity_fee: 3, - origin_outputs: vec![AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_from, - shard_id: 0, - quantity: 10, - }], - expiration: 10, - lock_script_hash_from: H160::random(), - parameters_from: vec![vec![1]], - lock_script_hash_fee: H160::random(), - parameters_fee: vec![vec![1]], - }; - assert_eq!( - order.verify(), - Err(SyntaxError::InvalidOrderAssetQuantities { - from: 3, - to: 0, - fee: 3, - }) - ); - - let order = Order { - asset_type_from, - asset_type_to, - asset_type_fee, - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 0, - asset_quantity_to: 2, - asset_quantity_fee: 3, - origin_outputs: vec![AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_from, - shard_id: 0, - quantity: 10, - }], - expiration: 10, - lock_script_hash_from: H160::random(), - parameters_from: vec![vec![1]], - lock_script_hash_fee: H160::random(), - parameters_fee: vec![vec![1]], - }; - assert_eq!( - order.verify(), - Err(SyntaxError::InvalidOrderAssetQuantities { - from: 0, - to: 2, - fee: 3, - }) - ); - - let order = Order { - asset_type_from, - asset_type_to, - asset_type_fee, - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 0, - asset_quantity_to: 0, - asset_quantity_fee: 3, - origin_outputs: vec![AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_from, - shard_id: 0, - quantity: 10, - }], - expiration: 10, - lock_script_hash_from: H160::random(), - parameters_from: vec![vec![1]], - lock_script_hash_fee: H160::random(), - parameters_fee: vec![vec![1]], - }; - assert_eq!( - order.verify(), - Err(SyntaxError::InvalidOrderAssetQuantities { - from: 0, - to: 0, - fee: 3, - }) - ); - - let order = Order { - asset_type_from, - asset_type_to, - asset_type_fee, - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 3, - asset_quantity_to: 2, - asset_quantity_fee: 2, - origin_outputs: vec![AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: asset_type_from, - shard_id: 0, - quantity: 10, - }], - expiration: 10, - lock_script_hash_from: H160::random(), - parameters_from: vec![vec![1]], - lock_script_hash_fee: H160::random(), - parameters_fee: vec![vec![1]], - }; - assert_eq!( - order.verify(), - Err(SyntaxError::InvalidOrderAssetQuantities { - from: 3, - to: 2, - fee: 2, - }) - ); - - // 3. asset types are same - let asset_type = H160::random(); - let order = Order { - asset_type_from: asset_type, - asset_type_to: asset_type, - asset_type_fee, - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 3, - asset_quantity_to: 2, - asset_quantity_fee: 3, - origin_outputs: vec![AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type, - shard_id: 0, - quantity: 10, - }], - expiration: 10, - lock_script_hash_from: H160::random(), - parameters_from: vec![vec![1]], - lock_script_hash_fee: H160::random(), - parameters_fee: vec![vec![1]], - }; - assert_eq!(order.verify(), Err(SyntaxError::InvalidOrderAssetTypes)); - } -} diff --git a/types/src/transaction/shard.rs b/types/src/transaction/shard.rs index 32c705b348..b417d49fe4 100644 --- a/types/src/transaction/shard.rs +++ b/types/src/transaction/shard.rs @@ -19,13 +19,10 @@ use ckey::{Address, NetworkId}; use primitives::{Bytes, H160, H256}; use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; -use super::{ - AssetMintOutput, AssetTransferInput, AssetTransferOutput, HashingError, Order, OrderOnTransfer, PartialHashing, -}; +use super::{AssetMintOutput, AssetTransferInput, AssetTransferOutput, HashingError, PartialHashing}; use crate::util::tag::Tag; use crate::ShardId; - /// Shard Transaction type. #[derive(Debug, Clone, PartialEq, Eq)] pub enum ShardTransaction { @@ -43,7 +40,6 @@ pub enum ShardTransaction { burns: Vec, inputs: Vec, outputs: Vec, - orders: Vec, }, ChangeAssetScheme { network_id: NetworkId, @@ -281,12 +277,7 @@ impl PartialHashing for ShardTransaction { burns, inputs, outputs, - orders, } => { - if !orders.is_empty() && (!tag.sign_all_inputs || !tag.sign_all_outputs) { - return Err(HashingError::InvalidFilter) - } - let new_burns = apply_input_scheme(burns, tag.sign_all_inputs, is_burn, cur); let new_inputs = apply_input_scheme(inputs, tag.sign_all_inputs, !is_burn, cur); @@ -302,7 +293,6 @@ impl PartialHashing for ShardTransaction { burns: new_burns, inputs: new_inputs, outputs: new_outputs, - orders: orders.to_vec(), } .rlp_bytes(), &blake128(tag.get_tag()), @@ -337,21 +327,6 @@ impl PartialHashing for ShardTransaction { } } -impl Order { - pub fn hash(&self) -> H256 { - blake256(&self.rlp_bytes()) - } -} - -impl PartialHashing for Order { - fn hash_partially(&self, tag: Tag, _cur: &AssetTransferInput, is_burn: bool) -> Result { - assert!(tag.sign_all_inputs); - assert!(tag.sign_all_outputs); - assert!(!is_burn); - Ok(self.hash()) - } -} - type TransactionId = u8; const ASSET_UNWRAP_CCC_ID: TransactionId = 0x11; const ASSET_MINT_ID: TransactionId = 0x13; @@ -396,12 +371,15 @@ impl Decodable for ShardTransaction { expected: 6, }) } + let orders = d.list_at::(5)?; + if !orders.is_empty() { + return Err(DecoderError::Custom("orders must be an empty list")) + } Ok(ShardTransaction::TransferAsset { network_id: d.val_at(1)?, burns: d.list_at(2)?, inputs: d.list_at(3)?, outputs: d.list_at(4)?, - orders: d.list_at(5)?, }) } ASSET_SCHEME_CHANGE_ID => { @@ -496,15 +474,16 @@ impl Encodable for ShardTransaction { burns, inputs, outputs, - orders, } => { + let empty: Vec = vec![]; s.begin_list(6) .append(&ASSET_TRANSFER_ID) .append(network_id) .append_list(burns) .append_list(inputs) .append_list(outputs) - .append_list(orders); + // NOTE: The orders field removed. + .append_list(&empty); } ShardTransaction::ChangeAssetScheme { network_id, @@ -863,38 +842,6 @@ mod tests { shard_id: 0, quantity: 30, }], - orders: vec![OrderOnTransfer { - order: Order { - asset_type_from: H160::random(), - asset_type_to: H160::random(), - asset_type_fee: H160::random(), - shard_id_from: 0, - shard_id_to: 0, - shard_id_fee: 0, - asset_quantity_from: 10, - asset_quantity_to: 10, - asset_quantity_fee: 0, - origin_outputs: vec![AssetOutPoint { - tracker: H256::random(), - index: 0, - asset_type: H160::random(), - shard_id: 0, - quantity: 30, - }], - expiration: 10, - lock_script_hash_from: H160::random(), - parameters_from: vec![vec![1]], - lock_script_hash_fee: H160::random(), - parameters_fee: vec![vec![1]], - }, - spent_quantity: 10, - input_from_indices: vec![0], - input_fee_indices: vec![], - output_from_indices: vec![], - output_to_indices: vec![0], - output_owned_fee_indices: vec![], - output_transferred_fee_indices: vec![], - }], }; rlp_encode_and_decode_test!(tx); } @@ -942,7 +889,6 @@ mod tests { burns: Vec::new(), inputs: inputs.clone(), outputs: outputs.clone(), - orders: vec![], }; let mut tag: Vec = vec![0b0000_1111 as u8]; for _i in 0..12 { @@ -961,7 +907,6 @@ mod tests { burns: Vec::new(), inputs: inputs.clone(), outputs: outputs.clone(), - orders: vec![], }; tag = vec![0b0000_0111 as u8]; for _i in 0..12 { @@ -980,7 +925,6 @@ mod tests { burns: Vec::new(), inputs, outputs, - orders: vec![], }; tag = vec![0b0000_0011 as u8]; for _i in 0..12 { diff --git a/vm/tests/chk_multi_sig.rs b/vm/tests/chk_multi_sig.rs index 6296bf54d7..29ba62be0a 100644 --- a/vm/tests/chk_multi_sig.rs +++ b/vm/tests/chk_multi_sig.rs @@ -44,7 +44,6 @@ fn valid_multi_sig_0_of_2() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let outpoint = AssetTransferInput { prev_out: AssetOutPoint { @@ -86,7 +85,6 @@ fn valid_multi_sig_1_of_2() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let outpoint = AssetTransferInput { prev_out: AssetOutPoint { @@ -110,7 +108,6 @@ fn valid_multi_sig_1_of_2() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -140,7 +137,6 @@ fn valid_multi_sig_2_of_2() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let outpoint = AssetTransferInput { prev_out: AssetOutPoint { @@ -164,7 +160,6 @@ fn valid_multi_sig_2_of_2() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -196,7 +191,6 @@ fn nvalid_multi_sig_2_of_2_duplicated() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let outpoint = AssetTransferInput { prev_out: AssetOutPoint { @@ -220,7 +214,6 @@ fn nvalid_multi_sig_2_of_2_duplicated() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -254,7 +247,6 @@ fn valid_multi_sig_2_of_3_110() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let outpoint = AssetTransferInput { prev_out: AssetOutPoint { @@ -280,7 +272,6 @@ fn valid_multi_sig_2_of_3_110() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -313,7 +304,6 @@ fn valid_multi_sig_2_of_3_101() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let outpoint = AssetTransferInput { prev_out: AssetOutPoint { @@ -339,7 +329,6 @@ fn valid_multi_sig_2_of_3_101() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -372,7 +361,6 @@ fn valid_multi_sig_2_of_3_011() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let outpoint = AssetTransferInput { prev_out: AssetOutPoint { @@ -398,7 +386,6 @@ fn valid_multi_sig_2_of_3_011() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -431,7 +418,6 @@ fn invalid_multi_sig_1_of_2() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let outpoint = AssetTransferInput { prev_out: AssetOutPoint { @@ -455,7 +441,6 @@ fn invalid_multi_sig_1_of_2() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -486,7 +471,6 @@ fn invalid_multi_sig_2_of_2() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let outpoint = AssetTransferInput { prev_out: AssetOutPoint { @@ -510,7 +494,6 @@ fn invalid_multi_sig_2_of_2() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -542,7 +525,6 @@ fn invalid_multi_sig_2_of_2_with_1_invalid_sig() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let outpoint = AssetTransferInput { prev_out: AssetOutPoint { @@ -566,7 +548,6 @@ fn invalid_multi_sig_2_of_2_with_1_invalid_sig() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -577,7 +558,6 @@ fn invalid_multi_sig_2_of_2_with_1_invalid_sig() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -601,62 +581,6 @@ fn invalid_multi_sig_2_of_2_with_1_invalid_sig() { ); } -#[test] -fn invalid_multi_sig_2_of_2_with_changed_order_sig() { - let client = TestClient::default(); - let transaction = ShardTransaction::TransferAsset { - network_id: NetworkId::default(), - burns: Vec::new(), - inputs: Vec::new(), - outputs: Vec::new(), - orders: Vec::new(), - }; - let outpoint = AssetTransferInput { - prev_out: AssetOutPoint { - tracker: Default::default(), - index: 0, - asset_type: H160::default(), - shard_id: 0, - quantity: 0, - }, - timelock: None, - lock_script: Vec::new(), - unlock_script: Vec::new(), - }; - let keypair1 = KeyPair::from_private(Private::from(ONE_KEY)).unwrap(); - let keypair2 = KeyPair::from_private(Private::from(MINUS_ONE_KEY)).unwrap(); - let pubkey1 = <&[u8]>::from(keypair1.public()).to_vec(); - let pubkey2 = <&[u8]>::from(keypair2.public()).to_vec(); - let message = blake256_with_key( - &ShardTransaction::TransferAsset { - network_id: NetworkId::default(), - burns: Vec::new(), - inputs: Vec::new(), - outputs: Vec::new(), - orders: Vec::new(), - } - .rlp_bytes(), - &blake128(&[0b11 as u8]), - ); - let signature1 = sign(keypair1.private(), &message).unwrap().to_vec(); - let signature2 = sign(keypair2.private(), &message).unwrap().to_vec(); - - let unlock_script = - vec![Instruction::PushB(vec![0b11 as u8]), Instruction::PushB(signature2), Instruction::PushB(signature1)]; - let lock_script = vec![ - Instruction::PushB(vec![2]), - Instruction::PushB(pubkey1), - Instruction::PushB(pubkey2), - Instruction::PushB(vec![2]), - Instruction::ChkMultiSig, - ]; - - assert_eq!( - execute(&unlock_script, &[], &lock_script, &transaction, VMConfig::default(), &outpoint, false, &client, 0, 0), - Ok(ScriptResult::Fail) - ); -} - #[test] fn invalid_multi_sig_with_less_sig_than_m() { let client = TestClient::default(); @@ -665,7 +589,6 @@ fn invalid_multi_sig_with_less_sig_than_m() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let outpoint = AssetTransferInput { prev_out: AssetOutPoint { @@ -689,7 +612,6 @@ fn invalid_multi_sig_with_less_sig_than_m() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -719,7 +641,6 @@ fn invalid_multi_sig_with_more_sig_than_m() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let outpoint = AssetTransferInput { prev_out: AssetOutPoint { @@ -743,7 +664,6 @@ fn invalid_multi_sig_with_more_sig_than_m() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -775,7 +695,6 @@ fn invalid_multi_sig_with_too_many_arg() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let outpoint = AssetTransferInput { prev_out: AssetOutPoint { @@ -797,7 +716,6 @@ fn invalid_multi_sig_with_too_many_arg() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), diff --git a/vm/tests/chk_sig.rs b/vm/tests/chk_sig.rs index c77bade884..dae1a07757 100644 --- a/vm/tests/chk_sig.rs +++ b/vm/tests/chk_sig.rs @@ -44,7 +44,6 @@ fn valid_pay_to_public_key() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let input = AssetTransferInput { prev_out: AssetOutPoint { @@ -66,7 +65,6 @@ fn valid_pay_to_public_key() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -89,7 +87,6 @@ fn invalid_pay_to_public_key() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let input = AssetTransferInput { prev_out: AssetOutPoint { @@ -111,7 +108,6 @@ fn invalid_pay_to_public_key() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -180,7 +176,6 @@ fn sign_all_input_all_output() { burns: Vec::new(), inputs: vec![input0.clone(), input1.clone()], outputs: vec![output0.clone(), output1.clone()], - orders: Vec::new(), }; // Execute sciprt in input0 @@ -192,7 +187,6 @@ fn sign_all_input_all_output() { burns: Vec::new(), inputs: vec![input0.clone(), input1], outputs: vec![output0, output1], - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -260,7 +254,6 @@ fn sign_single_input_all_output() { burns: Vec::new(), inputs: vec![input0.clone(), input1.clone()], outputs: vec![output0.clone(), output1.clone()], - orders: Vec::new(), }; // Execute sciprt in input0 @@ -272,7 +265,6 @@ fn sign_single_input_all_output() { burns: Vec::new(), inputs: vec![input0.clone()], outputs: vec![output0, output1], - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b10 as u8]), @@ -339,7 +331,6 @@ fn sign_all_input_partial_output() { burns: Vec::new(), inputs: vec![input0.clone(), input1.clone()], outputs: vec![output0.clone(), output1.clone()], - orders: Vec::new(), }; // Execute sciprt in input0 @@ -351,7 +342,6 @@ fn sign_all_input_partial_output() { burns: Vec::new(), inputs: vec![input0.clone(), input1], outputs: vec![output0], - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b1, 0b0000_0101 as u8]), @@ -418,7 +408,6 @@ fn sign_single_input_partial_output() { burns: Vec::new(), inputs: vec![input0.clone(), input1.clone()], outputs: vec![output0.clone(), output1.clone()], - orders: Vec::new(), }; // Execute sciprt in input0 @@ -430,7 +419,6 @@ fn sign_single_input_partial_output() { burns: Vec::new(), inputs: vec![input0.clone()], outputs: vec![output0], - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b1, 0b0000_0100 as u8]), @@ -475,7 +463,6 @@ fn distinguish_sign_single_input_with_sign_all() { burns: Vec::new(), inputs: vec![input0.clone()], outputs: vec![output0.clone()], - orders: Vec::new(), }; // Execute sciprt in input0 @@ -487,7 +474,6 @@ fn distinguish_sign_single_input_with_sign_all() { burns: Vec::new(), inputs: vec![input0.clone()], outputs: vec![output0], - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), @@ -533,7 +519,6 @@ fn distinguish_sign_single_output_with_sign_all() { burns: Vec::new(), inputs: vec![input0.clone()], outputs: vec![output0.clone()], - orders: Vec::new(), }; // Execute sciprt in input0 @@ -545,7 +530,6 @@ fn distinguish_sign_single_output_with_sign_all() { burns: Vec::new(), inputs: vec![input0.clone()], outputs: vec![output0], - orders: Vec::new(), } .rlp_bytes(), &blake128(&[0b11 as u8]), diff --git a/vm/tests/executor.rs b/vm/tests/executor.rs index 52ec106358..9ff0a9fa35 100644 --- a/vm/tests/executor.rs +++ b/vm/tests/executor.rs @@ -39,7 +39,6 @@ fn simple_success() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let input = AssetTransferInput { prev_out: AssetOutPoint { @@ -72,7 +71,6 @@ fn simple_failure() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let input = AssetTransferInput { prev_out: AssetOutPoint { @@ -104,7 +102,6 @@ fn simple_burn() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let input = AssetTransferInput { prev_out: AssetOutPoint { @@ -132,7 +129,6 @@ fn underflow() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let input = AssetTransferInput { prev_out: AssetOutPoint { @@ -160,7 +156,6 @@ fn out_of_memory() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let input = AssetTransferInput { prev_out: AssetOutPoint { @@ -202,7 +197,6 @@ fn invalid_unlock_script() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let input = AssetTransferInput { prev_out: AssetOutPoint { @@ -230,7 +224,6 @@ fn conditional_burn() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let input = AssetTransferInput { prev_out: AssetOutPoint { @@ -285,7 +278,6 @@ fn _blake256() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let input = AssetTransferInput { prev_out: AssetOutPoint { @@ -370,7 +362,6 @@ fn _ripemd160() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let input = AssetTransferInput { prev_out: AssetOutPoint { @@ -463,7 +454,6 @@ fn _sha256() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let input = AssetTransferInput { prev_out: AssetOutPoint { @@ -556,7 +546,6 @@ fn _keccak256() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let input = AssetTransferInput { prev_out: AssetOutPoint { @@ -648,7 +637,6 @@ fn dummy_tx() -> ShardTransaction { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), } } @@ -916,7 +904,6 @@ fn copy_stack_underflow() { burns: Vec::new(), inputs: Vec::new(), outputs: Vec::new(), - orders: Vec::new(), }; let input = AssetTransferInput { prev_out: AssetOutPoint { From d243fc461b239233b092ca682f49c3391094a4ef Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Fri, 20 Sep 2019 11:52:57 +0900 Subject: [PATCH 020/105] Do not convert to Bytes until it is necessary --- core/src/consensus/tendermint/worker.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 2593031fef..a3b22f4cba 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -571,7 +571,8 @@ impl Worker { self.validators.check_enough_votes(&self.prev_block_hash(), &votes).is_ok() } - fn broadcast_message(&self, message: Bytes) { + fn broadcast_message(&self, message: ConsensusMessage) { + let message = message.rlp_bytes().to_vec(); self.extension .send(network::Event::BroadcastMessage { message, @@ -831,7 +832,7 @@ impl Worker { } } - fn generate_message(&mut self, block_hash: Option, is_restoring: bool) -> Option { + fn generate_message(&mut self, block_hash: Option, is_restoring: bool) -> Option { let height = self.height; let r = self.view; let on = VoteOn { @@ -860,7 +861,7 @@ impl Worker { cinfo!(ENGINE, "Generated {:?} as {}th validator.", message, signer_index); self.handle_valid_message(&message, is_restoring); - Some(message.rlp_bytes().into_vec()) + Some(message) } fn handle_valid_message(&mut self, message: &ConsensusMessage, is_restoring: bool) { From 60f0e35f41a3a358718ee6d7fc74db0347da630c Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Fri, 20 Sep 2019 21:01:02 +0900 Subject: [PATCH 021/105] Remove vote_collector::Message trait ConsensusMessage is the only implementation. --- core/src/consensus/mod.rs | 1 - core/src/consensus/solo/mod.rs | 55 +-------- core/src/consensus/stake/actions.rs | 28 ++--- core/src/consensus/stake/mod.rs | 151 +++++++++++------------ core/src/consensus/tendermint/message.rs | 21 +--- core/src/consensus/tendermint/mod.rs | 4 +- core/src/consensus/tendermint/types.rs | 7 -- core/src/consensus/tendermint/worker.rs | 7 +- core/src/consensus/vote_collector.rs | 79 +++++------- core/src/lib.rs | 2 +- 10 files changed, 132 insertions(+), 223 deletions(-) diff --git a/core/src/consensus/mod.rs b/core/src/consensus/mod.rs index 465fb2f2d1..418587af36 100644 --- a/core/src/consensus/mod.rs +++ b/core/src/consensus/mod.rs @@ -37,7 +37,6 @@ pub use self::tendermint::{ }; pub use self::validator_set::validator_list::RoundRobinValidator; pub use self::validator_set::{DynamicValidator, ValidatorSet}; -pub use self::vote_collector::Message; use std::fmt; use std::sync::{Arc, Weak}; diff --git a/core/src/consensus/solo/mod.rs b/core/src/consensus/solo/mod.rs index a6711fcc2b..b8c9bfd155 100644 --- a/core/src/consensus/solo/mod.rs +++ b/core/src/consensus/solo/mod.rs @@ -18,18 +18,16 @@ mod params; use std::sync::Arc; -use ckey::{Address, Error as KeyError, Public, SchnorrSignature}; +use ckey::Address; use cstate::{ActionHandler, HitHandler}; use ctypes::{CommonParams, Header}; -use primitives::H256; -use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; use self::params::SoloParams; use super::stake; use super::{ConsensusEngine, Seal}; use crate::block::{ExecutedBlock, IsBlock}; use crate::codechain_machine::CodeChainMachine; -use crate::consensus::{EngineError, EngineType, Message}; +use crate::consensus::{EngineError, EngineType}; use crate::error::Error; /// A consensus engine which does not provide any consensus mechanism. @@ -39,53 +37,6 @@ pub struct Solo { action_handlers: Vec>, } -#[derive(Debug, PartialEq, Eq, Clone, Hash, Default)] -pub struct SoloMessage {} - -impl Encodable for SoloMessage { - fn rlp_append(&self, s: &mut RlpStream) { - s.append_empty_data(); - } -} - -impl Decodable for SoloMessage { - fn decode(_rlp: &UntrustedRlp) -> Result { - Ok(SoloMessage {}) - } -} - -impl Message for SoloMessage { - type Round = bool; - - fn signature(&self) -> SchnorrSignature { - SchnorrSignature::random() - } - - fn signer_index(&self) -> usize { - Default::default() - } - - fn block_hash(&self) -> Option { - None - } - - fn round(&self) -> &bool { - &false - } - - fn height(&self) -> u64 { - 0 - } - - fn is_broadcastable(&self) -> bool { - false - } - - fn verify(&self, _signer_public: &Public) -> Result { - Ok(true) - } -} - impl Solo { /// Returns new instance of Solo over the given state machine. pub fn new(params: SoloParams, machine: CodeChainMachine) -> Self { @@ -93,7 +44,7 @@ impl Solo { if params.enable_hit_handler { action_handlers.push(Arc::new(HitHandler::new())); } - action_handlers.push(Arc::new(stake::Stake::::new(params.genesis_stakes.clone()))); + action_handlers.push(Arc::new(stake::Stake::new(params.genesis_stakes.clone()))); Solo { params, diff --git a/core/src/consensus/stake/actions.rs b/core/src/consensus/stake/actions.rs index 38dd4549fc..68dcc01e38 100644 --- a/core/src/consensus/stake/actions.rs +++ b/core/src/consensus/stake/actions.rs @@ -19,13 +19,13 @@ use std::sync::Arc; use ccrypto::Blake; use ckey::{recover, Address, Signature}; use client::ConsensusClient; -use consensus::vote_collector::Message; -use consensus::ValidatorSet; use ctypes::errors::SyntaxError; use ctypes::CommonParams; use primitives::{Bytes, H256}; use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; +use crate::consensus::{ConsensusMessage, ValidatorSet}; + const ACTION_TAG_TRANSFER_CCS: u8 = 1; const ACTION_TAG_DELEGATE_CCS: u8 = 2; const ACTION_TAG_REVOKE: u8 = 3; @@ -35,7 +35,7 @@ const ACTION_TAG_REDELEGATE: u8 = 6; const ACTION_TAG_CHANGE_PARAMS: u8 = 0xFF; #[derive(Debug, PartialEq)] -pub enum Action { +pub enum Action { TransferCCS { address: Address, quantity: u64, @@ -62,13 +62,14 @@ pub enum Action { params: Box, signatures: Vec, }, + // TODO: ConsensusMessage is tied to the Tendermint ReportDoubleVote { - message1: M, - message2: M, + message1: ConsensusMessage, + message2: ConsensusMessage, }, } -impl Action { +impl Action { pub fn verify( &self, current_params: &CommonParams, @@ -113,7 +114,7 @@ impl Action { ))) } params.verify().map_err(SyntaxError::InvalidCustomAction)?; - let action = Action::::ChangeParams { + let action = Action::ChangeParams { metadata_seq: *metadata_seq, params: params.clone(), signatures: vec![], @@ -183,7 +184,7 @@ impl Action { } } -impl Encodable for Action { +impl Encodable for Action { fn rlp_append(&self, s: &mut RlpStream) { match self { Action::TransferCCS { @@ -244,7 +245,7 @@ impl Encodable for Action { } } -impl Decodable for Action { +impl Decodable for Action { fn decode(rlp: &UntrustedRlp) -> Result { let tag = rlp.val_at(0)?; match tag { @@ -357,13 +358,12 @@ mod tests { use ccrypto::blake256; use ckey::sign_schnorr; use client::TestBlockChainClient; - use consensus::solo::SoloMessage; use consensus::{message_info_rlp, ConsensusMessage, DynamicValidator, Step, VoteOn, VoteStep}; use rlp::rlp_encode_and_decode_test; #[test] fn decode_fail_if_change_params_have_no_signatures() { - let action = Action::::ChangeParams { + let action = Action::ChangeParams { metadata_seq: 3, params: CommonParams::default_for_test().into(), signatures: vec![], @@ -373,13 +373,13 @@ mod tests { expected: 4, got: 3, }), - UntrustedRlp::new(&rlp::encode(&action)).as_val::>() + UntrustedRlp::new(&rlp::encode(&action)).as_val::() ); } #[test] fn rlp_of_change_params() { - rlp_encode_and_decode_test!(Action::::ChangeParams { + rlp_encode_and_decode_test!(Action::ChangeParams { metadata_seq: 3, params: CommonParams::default_for_test().into(), signatures: vec![Signature::random(), Signature::random()], @@ -448,7 +448,7 @@ mod tests { create_consensus_message(message_info1, &test_client, vote_step_twister, block_hash_twister); let consensus_message2 = create_consensus_message(message_info2, &test_client, vote_step_twister, block_hash_twister); - let action = Action::::ReportDoubleVote { + let action = Action::ReportDoubleVote { message1: consensus_message1, message2: consensus_message2, }; diff --git a/core/src/consensus/stake/mod.rs b/core/src/consensus/stake/mod.rs index c5b4bae6e7..8bd8d6d5b2 100644 --- a/core/src/consensus/stake/mod.rs +++ b/core/src/consensus/stake/mod.rs @@ -20,13 +20,11 @@ mod distribute; use std::collections::btree_map::BTreeMap; use std::collections::HashMap; -use std::marker::PhantomData; use std::sync::{Arc, Weak}; use crate::client::ConsensusClient; use ccrypto::Blake; use ckey::{public_to_address, recover, Address, Public, Signature}; -use consensus::vote_collector::Message; use cstate::{ActionHandler, StateResult, TopLevelState, TopState, TopStateView}; use ctypes::errors::{RuntimeError, SyntaxError}; use ctypes::util::unexpected::Mismatch; @@ -43,18 +41,16 @@ use super::ValidatorSet; pub const CUSTOM_ACTION_HANDLER_ID: u64 = 2; -pub struct Stake { +pub struct Stake { genesis_stakes: HashMap, client: RwLock>>, validators: RwLock>>, - phantom: PhantomData, } -impl Stake { - pub fn new(genesis_stakes: HashMap) -> Stake { +impl Stake { + pub fn new(genesis_stakes: HashMap) -> Stake { Stake { genesis_stakes, - phantom: PhantomData, client: Default::default(), validators: Default::default(), } @@ -65,7 +61,7 @@ impl Stake { } } -impl ActionHandler for Stake { +impl ActionHandler for Stake { fn name(&self) -> &'static str { "stake handler" } @@ -95,7 +91,7 @@ impl ActionHandler for Stake { fee_payer: &Address, sender_public: &Public, ) -> StateResult<()> { - let action = Action::::decode(&UntrustedRlp::new(bytes)).expect("Verification passed"); + let action = Action::decode(&UntrustedRlp::new(bytes)).expect("Verification passed"); match action { Action::TransferCCS { address, @@ -135,7 +131,7 @@ impl ActionHandler for Stake { metadata_seq, params, signatures, - } => change_params::(state, metadata_seq, *params, &signatures), + } => change_params(state, metadata_seq, *params, &signatures), Action::ReportDoubleVote { message1, .. @@ -153,7 +149,7 @@ impl ActionHandler for Stake { } fn verify(&self, bytes: &[u8], current_params: &CommonParams) -> Result<(), SyntaxError> { - let action = Action::::decode(&UntrustedRlp::new(bytes)) + let action = Action::decode(&UntrustedRlp::new(bytes)) .map_err(|err| SyntaxError::InvalidCustomAction(err.to_string()))?; let client: Option> = self.client.read().as_ref().and_then(Weak::upgrade); let validators: Option> = self.validators.read().as_ref().and_then(Weak::upgrade); @@ -357,7 +353,7 @@ pub fn update_validator_weights(state: &mut TopLevelState, block_author: &Addres validators.save_to_state(state) } -fn change_params( +fn change_params( state: &mut TopLevelState, metadata_seq: u64, params: CommonParams, @@ -366,7 +362,7 @@ fn change_params( // Update state first because the signature validation is more expensive. state.update_params(metadata_seq, params)?; - let action = Action::::ChangeParams { + let action = Action::ChangeParams { metadata_seq, params: params.into(), signatures: vec![], @@ -551,7 +547,6 @@ mod tests { use super::action_data::get_account_key; use super::*; - use consensus::solo::SoloMessage; use consensus::stake::action_data::{get_delegation_key, Candidate, Prisoner}; use cstate::tests::helpers; use cstate::TopStateView; @@ -575,7 +570,7 @@ mod tests { let stake = { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(address1, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); @@ -600,7 +595,7 @@ mod tests { let stake = { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(address1, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); @@ -628,7 +623,7 @@ mod tests { let stake = { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(address1, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); @@ -660,12 +655,12 @@ mod tests { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegatee, 100); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: delegatee, quantity: 40, }; @@ -703,12 +698,12 @@ mod tests { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegatee, 100); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: delegatee, quantity: 100, }; @@ -747,11 +742,11 @@ mod tests { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegatee, 100); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: delegatee, quantity: 40, }; @@ -771,12 +766,12 @@ mod tests { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegatee, 100); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: delegatee, quantity: 200, }; @@ -796,18 +791,18 @@ mod tests { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegatee, 100); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: delegatee, quantity: 50, }; stake.execute(&action.rlp_bytes(), &mut state, &delegator, &delegator_pubkey).unwrap(); - let action = Action::::TransferCCS { + let action = Action::TransferCCS { address: delegatee, quantity: 50, }; @@ -827,18 +822,18 @@ mod tests { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegatee, 100); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: delegatee, quantity: 50, }; stake.execute(&action.rlp_bytes(), &mut state, &delegator, &delegator_pubkey).unwrap(); - let action = Action::::TransferCCS { + let action = Action::TransferCCS { address: delegatee, quantity: 100, }; @@ -858,19 +853,19 @@ mod tests { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegatee, 100); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: delegatee, quantity: 50, }; let result = stake.execute(&action.rlp_bytes(), &mut state, &delegator, &delegator_pubkey); assert!(result.is_ok()); - let action = Action::::Revoke { + let action = Action::Revoke { address: delegatee, quantity: 20, }; @@ -896,19 +891,19 @@ mod tests { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegatee, 100); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: delegatee, quantity: 50, }; let result = stake.execute(&action.rlp_bytes(), &mut state, &delegator, &delegator_pubkey); assert!(result.is_ok()); - let action = Action::::Revoke { + let action = Action::Revoke { address: delegatee, quantity: 70, }; @@ -934,19 +929,19 @@ mod tests { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegatee, 100); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: delegatee, quantity: 50, }; let result = stake.execute(&action.rlp_bytes(), &mut state, &delegator, &delegator_pubkey); assert!(result.is_ok()); - let action = Action::::Revoke { + let action = Action::Revoke { address: delegatee, quantity: 50, }; @@ -971,20 +966,20 @@ mod tests { let stake = { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); self_nominate(&mut state, &prev_delegatee, &prev_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); self_nominate(&mut state, &next_delegatee, &next_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: prev_delegatee, quantity: 50, }; let result = stake.execute(&action.rlp_bytes(), &mut state, &delegator, &delegator_pubkey); assert!(result.is_ok()); - let action = Action::::Redelegate { + let action = Action::Redelegate { prev_delegatee, next_delegatee, quantity: 20, @@ -1013,20 +1008,20 @@ mod tests { let stake = { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); self_nominate(&mut state, &prev_delegatee, &prev_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); self_nominate(&mut state, &next_delegatee, &next_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: prev_delegatee, quantity: 50, }; let result = stake.execute(&action.rlp_bytes(), &mut state, &delegator, &delegator_pubkey); assert!(result.is_ok()); - let action = Action::::Redelegate { + let action = Action::Redelegate { prev_delegatee, next_delegatee, quantity: 70, @@ -1055,20 +1050,20 @@ mod tests { let stake = { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); self_nominate(&mut state, &prev_delegatee, &prev_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); self_nominate(&mut state, &next_delegatee, &next_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: prev_delegatee, quantity: 50, }; let result = stake.execute(&action.rlp_bytes(), &mut state, &delegator, &delegator_pubkey); assert!(result.is_ok()); - let action = Action::::Redelegate { + let action = Action::Redelegate { prev_delegatee, next_delegatee, quantity: 50, @@ -1097,20 +1092,20 @@ mod tests { let stake = { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); self_nominate(&mut state, &prev_delegatee, &prev_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: prev_delegatee, quantity: 40, }; let result = stake.execute(&action.rlp_bytes(), &mut state, &delegator, &delegator_pubkey); assert!(result.is_ok()); - let action = Action::::Redelegate { + let action = Action::Redelegate { prev_delegatee, next_delegatee, quantity: 50, @@ -1135,18 +1130,18 @@ mod tests { let stake = { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); self_nominate(&mut state, &prev_delegatee, &prev_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); self_nominate(&mut state, &criminal, &criminal_pubkey, 100, 0, 10, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: criminal, quantity: 40, }; stake.execute(&action.rlp_bytes(), &mut state, &delegator, &delegator_pubkey).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: prev_delegatee, quantity: 40, }; @@ -1163,7 +1158,7 @@ mod tests { let candidates = Candidates::load_from_state(&state).unwrap(); assert_eq!(candidates.len(), 1); - let action = Action::::Redelegate { + let action = Action::Redelegate { prev_delegatee, next_delegatee: criminal, quantity: 40, @@ -1187,7 +1182,7 @@ mod tests { let stake = { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); self_nominate(&mut state, &prev_delegatee, &prev_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); @@ -1195,7 +1190,7 @@ mod tests { let deposit = 200; self_nominate(&mut state, &jail_address, &jail_pubkey, deposit, 0, 5, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: prev_delegatee, quantity: 40, }; @@ -1212,7 +1207,7 @@ mod tests { let candidates = Candidates::load_from_state(&state).unwrap(); assert_eq!(candidates.len(), 1); - let action = Action::::Redelegate { + let action = Action::Redelegate { prev_delegatee, next_delegatee: jail_address, quantity: 40, @@ -1229,7 +1224,7 @@ mod tests { let mut state = helpers::get_temp_state(); state.add_balance(&address, 1000).unwrap(); - let stake = Stake::::new(HashMap::new()); + let stake = Stake::new(HashMap::new()); stake.init(&mut state).unwrap(); // TODO: change with stake.execute() @@ -1289,7 +1284,7 @@ mod tests { let mut state = helpers::get_temp_state(); state.add_balance(&address, 1000).unwrap(); - let stake = Stake::::new(HashMap::new()); + let stake = Stake::new(HashMap::new()); stake.init(&mut state).unwrap(); // TODO: change with stake.execute() @@ -1314,7 +1309,7 @@ mod tests { increase_term_id_until(&mut state, 29); state.add_balance(&address, 1000).unwrap(); - let stake = Stake::::new(HashMap::new()); + let stake = Stake::new(HashMap::new()); stake.init(&mut state).unwrap(); // TODO: change with stake.execute() @@ -1358,14 +1353,14 @@ mod tests { let stake = { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); // TODO: change with stake.execute() self_nominate(&mut state, &address, &address_pubkey, 0, 0, 30, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address, quantity: 40, }; @@ -1396,7 +1391,7 @@ mod tests { let mut state = helpers::get_temp_state(); state.add_balance(&address, 1000).unwrap(); - let stake = Stake::::new(HashMap::new()); + let stake = Stake::new(HashMap::new()); stake.init(&mut state).unwrap(); // TODO: change with stake.execute() @@ -1434,7 +1429,7 @@ mod tests { let mut state = metadata_for_election(); state.add_balance(&address, 1000).unwrap(); - let stake = Stake::::new(HashMap::new()); + let stake = Stake::new(HashMap::new()); stake.init(&mut state).unwrap(); // TODO: change with stake.execute() @@ -1473,7 +1468,7 @@ mod tests { let mut state = metadata_for_election(); state.add_balance(&address, 1000).unwrap(); - let stake = Stake::::new(HashMap::new()); + let stake = Stake::new(HashMap::new()); stake.init(&mut state).unwrap(); // TODO: change with stake.execute() @@ -1527,7 +1522,7 @@ mod tests { let mut state = metadata_for_election(); state.add_balance(&address, 1000).unwrap(); - let stake = Stake::::new(HashMap::new()); + let stake = Stake::new(HashMap::new()); stake.init(&mut state).unwrap(); // TODO: change with stake.execute() @@ -1572,7 +1567,7 @@ mod tests { let stake = { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); @@ -1585,7 +1580,7 @@ mod tests { jail(&mut state, &[address], custody_until, released_at).unwrap(); for current_term in 0..=released_at { - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address, quantity: 1, }; @@ -1595,7 +1590,7 @@ mod tests { on_term_close(&mut state, pseudo_term_to_block_num_calculator(current_term), &[]).unwrap(); } - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address, quantity: 1, }; @@ -1616,7 +1611,7 @@ mod tests { let stake = { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); @@ -1627,7 +1622,7 @@ mod tests { let released_at = 20; self_nominate(&mut state, &address, &address_pubkey, deposit, 0, nominate_expire, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address, quantity: 40, }; @@ -1659,7 +1654,7 @@ mod tests { let stake = { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); @@ -1669,7 +1664,7 @@ mod tests { let released_at = 20; self_nominate(&mut state, &address, &address_pubkey, 0, 0, nominate_expire, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address, quantity: 40, }; @@ -1714,13 +1709,13 @@ mod tests { let stake = { let mut genesis_stakes = HashMap::new(); genesis_stakes.insert(delegator, 100); - Stake::::new(genesis_stakes) + Stake::new(genesis_stakes) }; stake.init(&mut state).unwrap(); let deposit = 100; self_nominate(&mut state, &criminal, &criminal_pubkey, deposit, 0, 10, b"".to_vec()).unwrap(); - let action = Action::::DelegateCCS { + let action = Action::DelegateCCS { address: criminal, quantity: 40, }; @@ -1750,7 +1745,7 @@ mod tests { let criminal = public_to_address(&criminal_pubkey); let mut state = helpers::get_temp_state(); - let stake = Stake::::new(HashMap::new()); + let stake = Stake::new(HashMap::new()); stake.init(&mut state).unwrap(); assert_eq!(Ok(()), state.add_balance(&criminal, 100)); diff --git a/core/src/consensus/tendermint/message.rs b/core/src/consensus/tendermint/message.rs index 6e24147fc3..8ed70543c5 100644 --- a/core/src/consensus/tendermint/message.rs +++ b/core/src/consensus/tendermint/message.rs @@ -24,7 +24,6 @@ use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; use snap; use super::super::validator_set::DynamicValidator; -use super::super::vote_collector::Message; use super::super::BitSet; use super::{BlockHash, Height, Step, View}; @@ -347,36 +346,28 @@ impl ConsensusMessage { }, }) } -} - -impl Message for ConsensusMessage { - type Round = VoteStep; - fn signature(&self) -> SchnorrSignature { + pub fn signature(&self) -> SchnorrSignature { self.signature } - fn signer_index(&self) -> usize { + pub fn signer_index(&self) -> usize { self.signer_index } - fn block_hash(&self) -> Option { + pub fn block_hash(&self) -> Option { self.on.block_hash } - fn round(&self) -> &VoteStep { + pub fn round(&self) -> &VoteStep { &self.on.step } - fn height(&self) -> u64 { + pub fn height(&self) -> u64 { self.on.step.height } - fn is_broadcastable(&self) -> bool { - self.on.step.step.is_pre() - } - - fn verify(&self, signer_public: &Public) -> Result { + pub fn verify(&self, signer_public: &Public) -> Result { let vote_info = message_info_rlp(self.on.step, self.on.block_hash); verify_schnorr(signer_public, &self.signature, &blake256(vote_info)) } diff --git a/core/src/consensus/tendermint/mod.rs b/core/src/consensus/tendermint/mod.rs index 8c324429cd..98966c9269 100644 --- a/core/src/consensus/tendermint/mod.rs +++ b/core/src/consensus/tendermint/mod.rs @@ -71,7 +71,7 @@ pub struct Tendermint { /// Action handlers for this consensus method action_handlers: Vec>, /// stake object to register client data later - stake: Arc>, + stake: Arc, /// Chain notify chain_notify: Arc, has_signer: AtomicBool, @@ -90,7 +90,7 @@ impl Tendermint { /// Create a new instance of Tendermint engine pub fn new(our_params: TendermintParams, machine: CodeChainMachine) -> Arc { let validators = Arc::clone(&our_params.validators); - let stake = Arc::new(stake::Stake::::new(our_params.genesis_stakes)); + let stake = Arc::new(stake::Stake::new(our_params.genesis_stakes)); let timeouts = our_params.timeouts; let machine = Arc::new(machine); diff --git a/core/src/consensus/tendermint/types.rs b/core/src/consensus/tendermint/types.rs index 91c63f242b..bdacb40906 100644 --- a/core/src/consensus/tendermint/types.rs +++ b/core/src/consensus/tendermint/types.rs @@ -159,13 +159,6 @@ pub enum Step { } impl Step { - pub fn is_pre(self) -> bool { - match self { - Step::Prevote | Step::Precommit => true, - _ => false, - } - } - pub fn number(self) -> u8 { match self { Step::Propose => 0, diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index a3b22f4cba..35c3b7c6b9 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -30,7 +30,6 @@ use ctypes::{BlockNumber, Header}; use primitives::{u256_from_u128, Bytes, H256, U256}; use rlp::{Encodable, UntrustedRlp}; -use super::super::vote_collector::DoubleVote; use super::super::BitSet; use super::backup::{backup, restore, BackupView}; use super::message::*; @@ -47,7 +46,7 @@ use crate::block::*; use crate::client::ConsensusClient; use crate::consensus::signer::EngineSigner; use crate::consensus::validator_set::{DynamicValidator, ValidatorSet}; -use crate::consensus::vote_collector::{Message, VoteCollector}; +use crate::consensus::vote_collector::{DoubleVote, VoteCollector}; use crate::consensus::{EngineError, Seal}; use crate::encoded; use crate::error::{BlockError, Error}; @@ -80,7 +79,7 @@ struct Worker { /// The votes_received field is changed after last state broadcast. votes_received_changed: bool, /// Vote accumulator. - votes: VoteCollector, + votes: VoteCollector, /// Used to sign messages and proposals. signer: EngineSigner, /// Last majority @@ -1421,7 +1420,7 @@ impl Worker { Ok(()) } - fn report_double_vote(&self, double: &DoubleVote) { + fn report_double_vote(&self, double: &DoubleVote) { let network_id = self.client().common_params(BlockId::Latest).unwrap().network_id(); let seq = match self.signer.address() { Some(address) => self.client().latest_seq(address), diff --git a/core/src/consensus/vote_collector.rs b/core/src/consensus/vote_collector.rs index ff104fd763..9522e3e7a1 100644 --- a/core/src/consensus/vote_collector.rs +++ b/core/src/consensus/vote_collector.rs @@ -15,58 +15,39 @@ // along with this program. If not, see . use std::collections::{BTreeMap, HashMap, HashSet}; -use std::fmt::Debug; -use std::hash::Hash; use std::iter::Iterator; -use ckey::{Error as KeyError, Public, SchnorrSignature}; +use ckey::SchnorrSignature; use parking_lot::RwLock; use primitives::H256; -use rlp::{Decodable, Encodable, RlpStream}; +use rlp::{Encodable, RlpStream}; use super::stake::Action; use super::BitSet; - -pub trait Message: Clone + PartialEq + Eq + Hash + Encodable + Decodable + Debug + Sync + Send { - type Round: Clone + Copy + PartialEq + Eq + Hash + Default + Debug + Ord; - - fn height(&self) -> u64; - - fn signature(&self) -> SchnorrSignature; - - fn signer_index(&self) -> usize; - - fn block_hash(&self) -> Option; - - fn round(&self) -> &Self::Round; - - fn is_broadcastable(&self) -> bool; - - fn verify(&self, signer_public: &Public) -> Result; -} +use super::{ConsensusMessage, VoteStep}; /// Storing all Proposals, Prevotes and Precommits. #[derive(Debug)] -pub struct VoteCollector { - votes: RwLock>>, +pub struct VoteCollector { + votes: RwLock>, } #[derive(Debug, Default)] -struct StepCollector { - voted: HashMap, +struct StepCollector { + voted: HashMap, block_votes: HashMap, BTreeMap>, - messages: HashSet, + messages: HashSet, } #[derive(Debug)] -pub struct DoubleVote { +pub struct DoubleVote { author_index: usize, - vote_one: M, - vote_two: M, + vote_one: ConsensusMessage, + vote_two: ConsensusMessage, } -impl DoubleVote { - pub fn to_action(&self) -> Action { +impl DoubleVote { + pub fn to_action(&self) -> Action { Action::ReportDoubleVote { message1: self.vote_one.clone(), message2: self.vote_two.clone(), @@ -74,15 +55,15 @@ impl DoubleVote { } } -impl Encodable for DoubleVote { +impl Encodable for DoubleVote { fn rlp_append(&self, s: &mut RlpStream) { s.begin_list(2).append(&self.vote_one).append(&self.vote_two); } } -impl StepCollector { +impl StepCollector { /// Returns Some(&Address) when validator is double voting. - fn insert(&mut self, message: M) -> Option> { + fn insert(&mut self, message: ConsensusMessage) -> Option { // Do nothing when message was seen. if self.messages.insert(message.clone()) { if let Some(previous) = self.voted.insert(message.signer_index(), message.clone()) { @@ -126,7 +107,7 @@ impl StepCollector { } } -impl Default for VoteCollector { +impl Default for VoteCollector { fn default() -> Self { let mut collector = BTreeMap::new(); // Insert dummy entry to fulfill invariant: "only messages newer than the oldest are inserted". @@ -137,14 +118,14 @@ impl Default for VoteCollector { } } -impl VoteCollector { +impl VoteCollector { /// Insert vote if it is newer than the oldest one. - pub fn vote(&self, message: M) -> Option> { + pub fn vote(&self, message: ConsensusMessage) -> Option { self.votes.write().entry(*message.round()).or_insert_with(Default::default).insert(message) } /// Checks if the message should be ignored. - pub fn is_old_or_known(&self, message: &M) -> bool { + pub fn is_old_or_known(&self, message: &ConsensusMessage) -> bool { let read_guard = self.votes.read(); let is_known = read_guard.get(&message.round()).map_or(false, |c| c.messages.contains(message)); @@ -164,7 +145,7 @@ impl VoteCollector { } /// Throws out messages older than message, leaves message as marker for the oldest. - pub fn throw_out_old(&self, vote_round: &M::Round) { + pub fn throw_out_old(&self, vote_round: &VoteStep) { let mut guard = self.votes.write(); let new_collector = guard.split_off(vote_round); assert!(!new_collector.is_empty()); @@ -175,7 +156,7 @@ impl VoteCollector { /// Returning indices is in ascending order, and signature and indices are matched with another. pub fn round_signatures_and_indices( &self, - round: &M::Round, + round: &VoteStep, block_hash: &H256, ) -> (Vec, Vec) { let guard = self.votes.read(); @@ -191,7 +172,7 @@ impl VoteCollector { /// Returns the first signature and the index of its signer for a given round and hash if exists. - pub fn round_signature(&self, round: &M::Round, block_hash: &H256) -> Option { + pub fn round_signature(&self, round: &VoteStep, block_hash: &H256) -> Option { let guard = self.votes.read(); guard .get(round) @@ -200,7 +181,7 @@ impl VoteCollector { } /// Count votes which agree with the given message. - pub fn aligned_votes(&self, message: &M) -> BitSet { + pub fn aligned_votes(&self, message: &ConsensusMessage) -> BitSet { if let Some(votes) = self.votes.read().get(&message.round()) { votes.count_block(&message.block_hash()) } else { @@ -208,7 +189,7 @@ impl VoteCollector { } } - pub fn block_round_votes(&self, round: &M::Round, block_hash: &Option) -> BitSet { + pub fn block_round_votes(&self, round: &VoteStep, block_hash: &Option) -> BitSet { if let Some(votes) = self.votes.read().get(round) { votes.count_block(block_hash) } else { @@ -217,7 +198,7 @@ impl VoteCollector { } /// Count all votes collected for a given round. - pub fn round_votes(&self, vote_round: &M::Round) -> BitSet { + pub fn round_votes(&self, vote_round: &VoteStep) -> BitSet { if let Some(votes) = self.votes.read().get(vote_round) { votes.count() } else { @@ -225,22 +206,22 @@ impl VoteCollector { } } - pub fn get_block_hashes(&self, round: &M::Round) -> Vec { + pub fn get_block_hashes(&self, round: &VoteStep) -> Vec { let guard = self.votes.read(); guard.get(round).map(|c| c.block_votes.keys().cloned().filter_map(|x| x).collect()).unwrap_or_else(Vec::new) } - pub fn get_all(&self) -> Vec { + pub fn get_all(&self) -> Vec { self.votes.read().iter().flat_map(|(_round, collector)| collector.messages.iter()).cloned().collect() } - pub fn get_all_votes_in_round(&self, round: &M::Round) -> Vec { + pub fn get_all_votes_in_round(&self, round: &VoteStep) -> Vec { let guard = self.votes.read(); let c = guard.get(round); c.map(|c| c.messages.iter().cloned().collect()).unwrap_or_default() } - pub fn get_all_votes_and_indices_in_round(&self, round: &M::Round) -> Vec<(usize, M)> { + pub fn get_all_votes_and_indices_in_round(&self, round: &VoteStep) -> Vec<(usize, ConsensusMessage)> { let guard = self.votes.read(); guard.get(round).map(|c| c.voted.iter().map(|(k, v)| (*k, v.clone())).collect()).unwrap_or_default() } diff --git a/core/src/lib.rs b/core/src/lib.rs index 4de7795106..8c28839bdd 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -89,7 +89,7 @@ pub use crate::client::{ EngineClient, EngineInfo, ExecuteClient, ImportBlock, MiningBlockChainClient, Shard, StateInfo, TermInfo, TestBlockChainClient, TextClient, }; -pub use crate::consensus::{EngineType, Message, TimeGapParams}; +pub use crate::consensus::{EngineType, TimeGapParams}; pub use crate::db::{COL_STATE, NUM_COLUMNS}; pub use crate::error::{BlockImportError, Error, ImportError}; pub use crate::miner::{Miner, MinerOptions, MinerService, Stratum, StratumConfig, StratumError}; From 43d1a9988fea2731ab791fbb272190ff598781a2 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Fri, 20 Sep 2019 21:04:33 +0900 Subject: [PATCH 022/105] Move VoteCollector into Tendermint --- core/src/consensus/mod.rs | 1 - core/src/consensus/tendermint/mod.rs | 1 + core/src/consensus/{ => tendermint}/vote_collector.rs | 2 +- core/src/consensus/tendermint/worker.rs | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename core/src/consensus/{ => tendermint}/vote_collector.rs (99%) diff --git a/core/src/consensus/mod.rs b/core/src/consensus/mod.rs index 418587af36..bf92051d3b 100644 --- a/core/src/consensus/mod.rs +++ b/core/src/consensus/mod.rs @@ -24,7 +24,6 @@ mod solo; pub mod stake; mod tendermint; mod validator_set; -pub mod vote_collector; pub use self::blake_pow::BlakePoW; pub use self::cuckoo::Cuckoo; diff --git a/core/src/consensus/tendermint/mod.rs b/core/src/consensus/tendermint/mod.rs index 98966c9269..59d39c11f3 100644 --- a/core/src/consensus/tendermint/mod.rs +++ b/core/src/consensus/tendermint/mod.rs @@ -21,6 +21,7 @@ mod message; mod network; mod params; pub mod types; +pub mod vote_collector; mod worker; use std::sync::atomic::AtomicBool; diff --git a/core/src/consensus/vote_collector.rs b/core/src/consensus/tendermint/vote_collector.rs similarity index 99% rename from core/src/consensus/vote_collector.rs rename to core/src/consensus/tendermint/vote_collector.rs index 9522e3e7a1..e50f12da9c 100644 --- a/core/src/consensus/vote_collector.rs +++ b/core/src/consensus/tendermint/vote_collector.rs @@ -23,8 +23,8 @@ use primitives::H256; use rlp::{Encodable, RlpStream}; use super::stake::Action; -use super::BitSet; use super::{ConsensusMessage, VoteStep}; +use crate::consensus::BitSet; /// Storing all Proposals, Prevotes and Precommits. #[derive(Debug)] diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 35c3b7c6b9..ea6c94a361 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -37,6 +37,7 @@ use super::network; use super::params::TimeGapParams; use super::stake::CUSTOM_ACTION_HANDLER_ID; use super::types::{Height, Proposal, Step, TendermintSealView, TendermintState, TwoThirdsMajority, View}; +use super::vote_collector::{DoubleVote, VoteCollector}; use super::{ BlockHash, ENGINE_TIMEOUT_BROADCAST_STEP_STATE, ENGINE_TIMEOUT_EMPTY_PROPOSAL, ENGINE_TIMEOUT_TOKEN_NONCE_BASE, SEAL_FIELDS, @@ -46,7 +47,6 @@ use crate::block::*; use crate::client::ConsensusClient; use crate::consensus::signer::EngineSigner; use crate::consensus::validator_set::{DynamicValidator, ValidatorSet}; -use crate::consensus::vote_collector::{DoubleVote, VoteCollector}; use crate::consensus::{EngineError, Seal}; use crate::encoded; use crate::error::{BlockError, Error}; From 0f2f6f83714fab366a74208960a3f021144e4ff1 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Wed, 25 Sep 2019 16:17:41 +0900 Subject: [PATCH 023/105] Box ConsensusMesasage in stake::Action::ReportDoubleVote ConsensusMessage is a large struct, therefore it bloats the enum --- core/src/consensus/stake/actions.rs | 17 ++++++++++------- core/src/consensus/tendermint/vote_collector.rs | 4 ++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/core/src/consensus/stake/actions.rs b/core/src/consensus/stake/actions.rs index 68dcc01e38..a41199c5ea 100644 --- a/core/src/consensus/stake/actions.rs +++ b/core/src/consensus/stake/actions.rs @@ -64,8 +64,8 @@ pub enum Action { }, // TODO: ConsensusMessage is tied to the Tendermint ReportDoubleVote { - message1: ConsensusMessage, - message2: ConsensusMessage, + message1: Box, + message2: Box, }, } @@ -239,7 +239,10 @@ impl Encodable for Action { message1, message2, } => { - s.begin_list(3).append(&ACTION_TAG_REPORT_DOUBLE_VOTE).append(message1).append(message2); + s.begin_list(3) + .append(&ACTION_TAG_REPORT_DOUBLE_VOTE) + .append(message1.as_ref()) + .append(message2.as_ref()); } }; } @@ -340,8 +343,8 @@ impl Decodable for Action { got: item_count, }) } - let message1 = rlp.val_at(1)?; - let message2 = rlp.val_at(2)?; + let message1 = Box::new(rlp.val_at(1)?); + let message2 = Box::new(rlp.val_at(2)?); Ok(Action::ReportDoubleVote { message1, message2, @@ -449,8 +452,8 @@ mod tests { let consensus_message2 = create_consensus_message(message_info2, &test_client, vote_step_twister, block_hash_twister); let action = Action::ReportDoubleVote { - message1: consensus_message1, - message2: consensus_message2, + message1: Box::new(consensus_message1), + message2: Box::new(consensus_message2), }; let arced_client: Arc = Arc::new(test_client); validator_set.register_client(Arc::downgrade(&arced_client)); diff --git a/core/src/consensus/tendermint/vote_collector.rs b/core/src/consensus/tendermint/vote_collector.rs index e50f12da9c..35f0c1b4c3 100644 --- a/core/src/consensus/tendermint/vote_collector.rs +++ b/core/src/consensus/tendermint/vote_collector.rs @@ -49,8 +49,8 @@ pub struct DoubleVote { impl DoubleVote { pub fn to_action(&self) -> Action { Action::ReportDoubleVote { - message1: self.vote_one.clone(), - message2: self.vote_two.clone(), + message1: Box::new(self.vote_one.clone()), + message2: Box::new(self.vote_two.clone()), } } } From fded2e003b4e785e072da1944a9725e8e7381909 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Wed, 25 Sep 2019 19:25:48 +0900 Subject: [PATCH 024/105] Remove lock in VoteCollector --- .../consensus/tendermint/vote_collector.rs | 49 ++++++++----------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/core/src/consensus/tendermint/vote_collector.rs b/core/src/consensus/tendermint/vote_collector.rs index 35f0c1b4c3..d1d8e09f4c 100644 --- a/core/src/consensus/tendermint/vote_collector.rs +++ b/core/src/consensus/tendermint/vote_collector.rs @@ -18,7 +18,6 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use std::iter::Iterator; use ckey::SchnorrSignature; -use parking_lot::RwLock; use primitives::H256; use rlp::{Encodable, RlpStream}; @@ -29,7 +28,7 @@ use crate::consensus::BitSet; /// Storing all Proposals, Prevotes and Precommits. #[derive(Debug)] pub struct VoteCollector { - votes: RwLock>, + votes: BTreeMap, } #[derive(Debug, Default)] @@ -113,29 +112,27 @@ impl Default for VoteCollector { // Insert dummy entry to fulfill invariant: "only messages newer than the oldest are inserted". collector.insert(Default::default(), Default::default()); VoteCollector { - votes: RwLock::new(collector), + votes: collector, } } } impl VoteCollector { /// Insert vote if it is newer than the oldest one. - pub fn vote(&self, message: ConsensusMessage) -> Option { - self.votes.write().entry(*message.round()).or_insert_with(Default::default).insert(message) + pub fn vote(&mut self, message: ConsensusMessage) -> Option { + self.votes.entry(*message.round()).or_insert_with(Default::default).insert(message) } /// Checks if the message should be ignored. pub fn is_old_or_known(&self, message: &ConsensusMessage) -> bool { - let read_guard = self.votes.read(); - - let is_known = read_guard.get(&message.round()).map_or(false, |c| c.messages.contains(message)); + let is_known = self.votes.get(&message.round()).map_or(false, |c| c.messages.contains(message)); if is_known { cdebug!(ENGINE, "Known message: {:?}.", message); return true } // The reason not using `message.round() <= oldest` is to allow precommit messages on Commit step. - let is_old = read_guard.keys().next().map_or(true, |oldest| message.round() < oldest); + let is_old = self.votes.keys().next().map_or(true, |oldest| message.round() < oldest); if is_old { cdebug!(ENGINE, "Old message {:?}.", message); return true @@ -145,11 +142,10 @@ impl VoteCollector { } /// Throws out messages older than message, leaves message as marker for the oldest. - pub fn throw_out_old(&self, vote_round: &VoteStep) { - let mut guard = self.votes.write(); - let new_collector = guard.split_off(vote_round); + pub fn throw_out_old(&mut self, vote_round: &VoteStep) { + let new_collector = self.votes.split_off(vote_round); assert!(!new_collector.is_empty()); - *guard = new_collector; + self.votes = new_collector; } /// Collects the signatures and the indices for the given round and hash. @@ -159,8 +155,7 @@ impl VoteCollector { round: &VoteStep, block_hash: &H256, ) -> (Vec, Vec) { - let guard = self.votes.read(); - guard + self.votes .get(round) .and_then(|c| c.block_votes.get(&Some(*block_hash))) .map(|votes| { @@ -173,8 +168,7 @@ impl VoteCollector { /// Returns the first signature and the index of its signer for a given round and hash if exists. pub fn round_signature(&self, round: &VoteStep, block_hash: &H256) -> Option { - let guard = self.votes.read(); - guard + self.votes .get(round) .and_then(|c| c.block_votes.get(&Some(*block_hash))) .and_then(|votes| votes.values().next().cloned()) @@ -182,7 +176,7 @@ impl VoteCollector { /// Count votes which agree with the given message. pub fn aligned_votes(&self, message: &ConsensusMessage) -> BitSet { - if let Some(votes) = self.votes.read().get(&message.round()) { + if let Some(votes) = self.votes.get(&message.round()) { votes.count_block(&message.block_hash()) } else { Default::default() @@ -190,7 +184,7 @@ impl VoteCollector { } pub fn block_round_votes(&self, round: &VoteStep, block_hash: &Option) -> BitSet { - if let Some(votes) = self.votes.read().get(round) { + if let Some(votes) = self.votes.get(round) { votes.count_block(block_hash) } else { Default::default() @@ -199,7 +193,7 @@ impl VoteCollector { /// Count all votes collected for a given round. pub fn round_votes(&self, vote_round: &VoteStep) -> BitSet { - if let Some(votes) = self.votes.read().get(vote_round) { + if let Some(votes) = self.votes.get(vote_round) { votes.count() } else { Default::default() @@ -207,22 +201,21 @@ impl VoteCollector { } pub fn get_block_hashes(&self, round: &VoteStep) -> Vec { - let guard = self.votes.read(); - guard.get(round).map(|c| c.block_votes.keys().cloned().filter_map(|x| x).collect()).unwrap_or_else(Vec::new) + self.votes + .get(round) + .map(|c| c.block_votes.keys().cloned().filter_map(|x| x).collect()) + .unwrap_or_else(Vec::new) } pub fn get_all(&self) -> Vec { - self.votes.read().iter().flat_map(|(_round, collector)| collector.messages.iter()).cloned().collect() + self.votes.iter().flat_map(|(_round, collector)| collector.messages.iter()).cloned().collect() } pub fn get_all_votes_in_round(&self, round: &VoteStep) -> Vec { - let guard = self.votes.read(); - let c = guard.get(round); - c.map(|c| c.messages.iter().cloned().collect()).unwrap_or_default() + self.votes.get(round).map(|c| c.messages.iter().cloned().collect()).unwrap_or_default() } pub fn get_all_votes_and_indices_in_round(&self, round: &VoteStep) -> Vec<(usize, ConsensusMessage)> { - let guard = self.votes.read(); - guard.get(round).map(|c| c.voted.iter().map(|(k, v)| (*k, v.clone())).collect()).unwrap_or_default() + self.votes.get(round).map(|c| c.voted.iter().map(|(k, v)| (*k, v.clone())).collect()).unwrap_or_default() } } From 932bb711c7066d9c4586000b5737382d3c6d2101 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 25 Sep 2019 16:12:54 +0900 Subject: [PATCH 025/105] Stop generating block if consensus cannot make a seal If Tendermint consensus received an outdated block request, it returns empty seal. Miner should stop the block generation if the seal is empty. --- core/src/miner/miner.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index e9c784c8ec..6e6de60521 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -451,7 +451,7 @@ impl Miner { &self, parent_block_id: BlockId, chain: &C, - ) -> Result<(ClosedBlock, Option), Error> { + ) -> Result)>, Error> { let (transactions, mut open_block, original_work_hash, block_number) = { let sealing_work = self.sealing_work.lock(); @@ -491,7 +491,7 @@ impl Miner { if let Some(seal_bytes) = seal.seal_fields() { open_block.seal(self.engine.borrow(), seal_bytes).expect("Sealing always success"); } else { - panic!("Seal should not be none") + return Ok(None) } } @@ -576,7 +576,7 @@ impl Miner { chain.chain_info().best_block_timestamp, ); } - Ok((block, original_work_hash)) + Ok(Some((block, original_work_hash))) } /// Attempts to perform internal sealing (one that does not require work) and handles the result depending on the type of Seal. @@ -798,9 +798,12 @@ impl MinerService for Miner { // | Make sure to release the locks before calling that method. | // -------------------------------------------------------------------------- match self.prepare_block(BlockId::Latest, client) { - Ok((block, original_work_hash)) => { + Ok(Some((block, original_work_hash))) => { self.prepare_work(block, original_work_hash); } + Ok(None) => { + ctrace!(MINER, "prepare_work_sealing: cannot prepare block"); + } Err(err) => { ctrace!(MINER, "prepare_work_sealing: cannot prepare block: {:?}", err); } @@ -837,13 +840,17 @@ impl MinerService for Miner { let parent_block_number = chain.block_header(&parent_block).expect("Parent is always exist").number(); if self.requires_reseal(parent_block_number) { let (block, original_work_hash) = match self.prepare_block(parent_block, chain) { - Ok((block, original_work_hash)) => { + Ok(Some((block, original_work_hash))) => { if !allow_empty_block && block.block().transactions().is_empty() { ctrace!(MINER, "update_sealing: block is empty, and allow_empty_block is false"); return } (block, original_work_hash) } + Ok(None) => { + ctrace!(MINER, "update_sealing: cannot prepare block"); + return + } Err(err) => { ctrace!(MINER, "update_sealing: cannot prepare block: {:?}", err); return From 7b3905149b034c89804d12fac7fffb253484389e Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Thu, 26 Sep 2019 14:17:56 +0900 Subject: [PATCH 026/105] Handle multiple proposals in a view correctly in Tendermint Previous code assumes that there is only one proposal in a view. Tendermint was always using the first proposal even though there are many proposals in a view. This commit makes Tendermint find proper proposal in the situation. --- .../consensus/tendermint/vote_collector.rs | 9 ++++ core/src/consensus/tendermint/worker.rs | 46 +++++++++---------- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/core/src/consensus/tendermint/vote_collector.rs b/core/src/consensus/tendermint/vote_collector.rs index d1d8e09f4c..3002839ae6 100644 --- a/core/src/consensus/tendermint/vote_collector.rs +++ b/core/src/consensus/tendermint/vote_collector.rs @@ -207,6 +207,15 @@ impl VoteCollector { .unwrap_or_else(Vec::new) } + pub fn has_votes_for(&self, round: &VoteStep, block_hash: H256) -> bool { + let votes = self + .votes + .get(round) + .map(|c| c.block_votes.keys().cloned().filter_map(|x| x).collect()) + .unwrap_or_else(Vec::new); + votes.into_iter().any(|vote_block_hash| vote_block_hash == block_hash) + } + pub fn get_all(&self) -> Vec { self.votes.iter().flat_map(|(_round, collector)| collector.messages.iter()).cloned().collect() } diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index ea6c94a361..63d12abd3c 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -453,7 +453,7 @@ impl Worker { self.validators.next_block_proposer(prev_block_hash, view) } - pub fn proposal_at(&self, height: Height, view: View) -> Option<(SchnorrSignature, usize, Bytes)> { + pub fn first_proposal_at(&self, height: Height, view: View) -> Option<(SchnorrSignature, usize, Bytes)> { let vote_step = VoteStep { height, view, @@ -475,11 +475,9 @@ impl Worker { step: Step::Propose, }); - if let Some(proposal) = all_votes.first() { - proposal.on.block_hash.expect("Proposal message always include block hash") == block_hash - } else { - false - } + all_votes + .into_iter() + .any(|proposal| proposal.on.block_hash.expect("Proposal message always include block hash") == block_hash) } pub fn vote_step(&self) -> VoteStep { @@ -670,6 +668,7 @@ impl Worker { match state.to_step() { Step::Propose => { cinfo!(ENGINE, "move_to_step: Propose."); + // If there are multiple proposals, use the first proposal. if let Some(hash) = self.votes.get_block_hashes(&vote_step).first() { if self.client().block(&BlockId::Hash(*hash)).is_some() { self.proposal = Proposal::new_imported(*hash); @@ -683,9 +682,9 @@ impl Worker { } else { let parent_block_hash = self.prev_block_hash(); if self.is_signer_proposer(&parent_block_hash) { - if let TwoThirdsMajority::Lock(lock_view, _) = self.last_two_thirds_majority { + if let TwoThirdsMajority::Lock(lock_view, locked_block_hash) = self.last_two_thirds_majority { cinfo!(ENGINE, "I am a proposer, I'll re-propose a locked block"); - match self.locked_proposal_block(lock_view) { + match self.locked_proposal_block(lock_view, locked_block_hash) { Ok(block) => self.repropose_block(block), Err(error_msg) => cwarn!(ENGINE, "{}", error_msg), } @@ -796,14 +795,14 @@ impl Worker { } } - fn locked_proposal_block(&self, locked_view: View) -> Result { + fn locked_proposal_block(&self, locked_view: View, locked_proposal_hash: H256) -> Result { let vote_step = VoteStep::new(self.height, locked_view, Step::Propose); - let locked_proposal_hash = self.votes.get_block_hashes(&vote_step).first().cloned(); + let received_locked_block = self.votes.has_votes_for(&vote_step, locked_proposal_hash); - let locked_proposal_hash = locked_proposal_hash.ok_or_else(|| { + if !received_locked_block { self.request_proposal_to_any(self.height, locked_view); - format!("Have a lock on {}-{}, but do not received a locked proposal", self.height, locked_view) - })?; + return Err(format!("Have a lock on {}-{}, but do not received a locked proposal", self.height, locked_view)) + } let locked_proposal_block = self.client().block(&BlockId::Hash(locked_proposal_hash)).ok_or_else(|| { format!( @@ -970,9 +969,9 @@ impl Worker { }); let current_height = self.height; - let vote_step = VoteStep::new(self.height, self.view, self.step.to_step()); - let proposal_at_current_view = self.votes.get_block_hashes(&vote_step).first().cloned(); - if proposal_at_current_view == Some(proposal.hash()) { + let current_vote_step = VoteStep::new(self.height, self.view, self.step.to_step()); + let proposal_is_for_current = self.votes.has_votes_for(¤t_vote_step, proposal.hash()); + if proposal_is_for_current { self.proposal = Proposal::new_imported(proposal.hash()); let current_step = self.step.clone(); match current_step { @@ -1005,16 +1004,15 @@ impl Worker { self.move_to_height(height); let prev_block_view = TendermintSealView::new(proposal.seal()).previous_block_view().unwrap(); self.save_last_confirmed_view(prev_block_view); - let proposal_at_view_0 = self - .votes - .get_block_hashes(&VoteStep { + let proposal_is_for_view0 = self.votes.has_votes_for( + &VoteStep { height, view: 0, step: Step::Propose, - }) - .first() - .cloned(); - if proposal_at_view_0 == Some(proposal.hash()) { + }, + proposal.hash(), + ); + if proposal_is_for_view0 { self.proposal = Proposal::new_imported(proposal.hash()) } self.move_to_step(TendermintState::Prevote, false); @@ -1896,7 +1894,7 @@ impl Worker { return } - if let Some((signature, _signer_index, block)) = self.proposal_at(request_height, request_view) { + if let Some((signature, _signer_index, block)) = self.first_proposal_at(request_height, request_view) { ctrace!(ENGINE, "Send proposal {}-{} to {:?}", request_height, request_view, token); self.send_proposal_block(signature, request_view, block, result); return From 626ac14fe0d0043a07cbd268805bac6445f0fe34 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Thu, 26 Sep 2019 15:29:35 +0900 Subject: [PATCH 027/105] Make the order of votes consistent When there are multiple proposals, we want to use the first proposal consistently. To do that the order or votes should be consistent. --- core/src/consensus/tendermint/vote_collector.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/src/consensus/tendermint/vote_collector.rs b/core/src/consensus/tendermint/vote_collector.rs index 3002839ae6..ad5391ec8c 100644 --- a/core/src/consensus/tendermint/vote_collector.rs +++ b/core/src/consensus/tendermint/vote_collector.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use std::collections::{BTreeMap, HashMap, HashSet}; +use std::collections::{BTreeMap, HashMap}; use std::iter::Iterator; use ckey::SchnorrSignature; @@ -35,7 +35,7 @@ pub struct VoteCollector { struct StepCollector { voted: HashMap, block_votes: HashMap, BTreeMap>, - messages: HashSet, + messages: Vec, } #[derive(Debug)] @@ -64,7 +64,8 @@ impl StepCollector { /// Returns Some(&Address) when validator is double voting. fn insert(&mut self, message: ConsensusMessage) -> Option { // Do nothing when message was seen. - if self.messages.insert(message.clone()) { + if !self.messages.contains(&message) { + self.messages.push(message.clone()); if let Some(previous) = self.voted.insert(message.signer_index(), message.clone()) { // Bad validator sent a different message. return Some(DoubleVote { @@ -217,11 +218,11 @@ impl VoteCollector { } pub fn get_all(&self) -> Vec { - self.votes.iter().flat_map(|(_round, collector)| collector.messages.iter()).cloned().collect() + self.votes.iter().flat_map(|(_round, collector)| collector.messages.clone()).collect() } pub fn get_all_votes_in_round(&self, round: &VoteStep) -> Vec { - self.votes.get(round).map(|c| c.messages.iter().cloned().collect()).unwrap_or_default() + self.votes.get(round).map(|c| c.messages.clone()).unwrap_or_default() } pub fn get_all_votes_and_indices_in_round(&self, round: &VoteStep) -> Vec<(usize, ConsensusMessage)> { From b41b482f6eb9d96f51003f84a6a8a2d228750852 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Sun, 22 Sep 2019 05:12:25 +0900 Subject: [PATCH 028/105] Relplace message_info_rlp, message_hash with VoteOn::hash --- core/src/consensus/mod.rs | 3 +-- core/src/consensus/stake/actions.rs | 11 ++++++----- core/src/consensus/tendermint/message.rs | 25 +++++++----------------- core/src/consensus/tendermint/mod.rs | 24 ++++++++++++++--------- core/src/consensus/tendermint/worker.rs | 24 ++++++++++++++--------- 5 files changed, 44 insertions(+), 43 deletions(-) diff --git a/core/src/consensus/mod.rs b/core/src/consensus/mod.rs index bf92051d3b..513270d71a 100644 --- a/core/src/consensus/mod.rs +++ b/core/src/consensus/mod.rs @@ -31,8 +31,7 @@ pub use self::null_engine::NullEngine; pub use self::simple_poa::SimplePoA; pub use self::solo::Solo; pub use self::tendermint::{ - message_info_rlp, ConsensusMessage, Height, Step, Tendermint, TendermintParams, TimeGapParams, View, VoteOn, - VoteStep, + ConsensusMessage, Height, Step, Tendermint, TendermintParams, TimeGapParams, View, VoteOn, VoteStep, }; pub use self::validator_set::validator_list::RoundRobinValidator; pub use self::validator_set::{DynamicValidator, ValidatorSet}; diff --git a/core/src/consensus/stake/actions.rs b/core/src/consensus/stake/actions.rs index a41199c5ea..f96fd4d26d 100644 --- a/core/src/consensus/stake/actions.rs +++ b/core/src/consensus/stake/actions.rs @@ -358,10 +358,9 @@ impl Decodable for Action { #[cfg(test)] mod tests { use super::*; - use ccrypto::blake256; use ckey::sign_schnorr; use client::TestBlockChainClient; - use consensus::{message_info_rlp, ConsensusMessage, DynamicValidator, Step, VoteOn, VoteStep}; + use consensus::{ConsensusMessage, DynamicValidator, Step, VoteOn, VoteStep}; use rlp::rlp_encode_and_decode_test; #[test] @@ -418,12 +417,14 @@ mod tests { step: vote_step, block_hash, }; - let message_for_signature = - blake256(message_info_rlp(vote_step_twister(vote_step), block_hash_twister(block_hash))); + let twisted = VoteOn { + step: vote_step_twister(vote_step), + block_hash: block_hash_twister(block_hash), + }; let reversed_idx = client.get_validators().len() - 1 - signer_index; let pubkey = *client.get_validators().get(reversed_idx).unwrap().pubkey(); let privkey = *client.validator_keys.read().get(&pubkey).unwrap(); - let signature = sign_schnorr(&privkey, &message_for_signature).unwrap(); + let signature = sign_schnorr(&privkey, &twisted.hash()).unwrap(); ConsensusMessage { signature, diff --git a/core/src/consensus/tendermint/message.rs b/core/src/consensus/tendermint/message.rs index 8ed70543c5..a811e98da1 100644 --- a/core/src/consensus/tendermint/message.rs +++ b/core/src/consensus/tendermint/message.rs @@ -316,6 +316,12 @@ pub struct VoteOn { pub block_hash: Option, } +impl VoteOn { + pub fn hash(&self) -> H256 { + blake256(&self.rlp_bytes()) + } +} + /// Message transmitted between consensus participants. #[derive(Debug, PartialEq, Eq, Clone, Hash, Default, RlpDecodable, RlpEncodable)] pub struct ConsensusMessage { @@ -368,27 +374,10 @@ impl ConsensusMessage { } pub fn verify(&self, signer_public: &Public) -> Result { - let vote_info = message_info_rlp(self.on.step, self.on.block_hash); - verify_schnorr(signer_public, &self.signature, &blake256(vote_info)) + verify_schnorr(signer_public, &self.signature, &self.on.hash()) } } -pub fn message_info_rlp(step: VoteStep, block_hash: Option) -> Bytes { - let vote_on = VoteOn { - step, - block_hash, - }; - vote_on.rlp_bytes().into_vec() -} - -pub fn message_hash(step: VoteStep, block_hash: H256) -> H256 { - let vote_on = VoteOn { - step, - block_hash: Some(block_hash), - }; - blake256(&vote_on.rlp_bytes()) -} - #[cfg(test)] mod tests { use rlp::{self, rlp_encode_and_decode_test}; diff --git a/core/src/consensus/tendermint/mod.rs b/core/src/consensus/tendermint/mod.rs index 59d39c11f3..997e80cc78 100644 --- a/core/src/consensus/tendermint/mod.rs +++ b/core/src/consensus/tendermint/mod.rs @@ -35,7 +35,7 @@ use parking_lot::RwLock; use primitives::H256; use self::chain_notify::TendermintChainNotify; -pub use self::message::{message_info_rlp, ConsensusMessage, VoteOn, VoteStep}; +pub use self::message::{ConsensusMessage, VoteOn, VoteStep}; pub use self::params::{TendermintParams, TimeGapParams, TimeoutParams}; pub use self::types::{Height, Step, View}; use super::{stake, ValidatorSet}; @@ -129,7 +129,7 @@ mod tests { use primitives::Bytes; use super::super::BitSet; - use super::message::{message_info_rlp, VoteStep}; + use super::message::VoteStep; use crate::account_provider::AccountProvider; use crate::block::{ClosedBlock, OpenBlock}; use crate::client::TestBlockChainClient; @@ -231,8 +231,11 @@ mod tests { header.set_author(proposer); header.set_parent_hash(Default::default()); - let vote_info = message_info_rlp(VoteStep::new(3, 0, Step::Precommit), Some(*header.parent_hash())); - let signature2 = tap.get_account(&proposer, None).unwrap().sign_schnorr(&blake256(&vote_info)).unwrap(); + let vote_on = VoteOn { + step: VoteStep::new(3, 0, Step::Precommit), + block_hash: Some(*header.parent_hash()), + }; + let signature2 = tap.get_account(&proposer, None).unwrap().sign_schnorr(&vote_on.hash()).unwrap(); let seal = Seal::Tendermint { prev_view: 0, @@ -267,8 +270,11 @@ mod tests { header.set_author(proposer); header.set_parent_hash(block1_hash); - let vote_info = message_info_rlp(VoteStep::new(1, 0, Step::Precommit), Some(*header.parent_hash())); - let signature2 = tap.get_account(&proposer, None).unwrap().sign_schnorr(&blake256(&vote_info)).unwrap(); + let vote_info = VoteOn { + step: VoteStep::new(1, 0, Step::Precommit), + block_hash: Some(*header.parent_hash()), + }; + let signature2 = tap.get_account(&proposer, None).unwrap().sign_schnorr(&vote_info.hash()).unwrap(); let seal = Seal::Tendermint { prev_view: 0, @@ -287,9 +293,9 @@ mod tests { } let voter = validator3; - let signature3 = tap.get_account(&voter, None).unwrap().sign_schnorr(&blake256(&vote_info)).unwrap(); + let signature3 = tap.get_account(&voter, None).unwrap().sign_schnorr(&vote_info.hash()).unwrap(); let voter = validator0; - let signature0 = tap.get_account(&voter, None).unwrap().sign_schnorr(&blake256(&vote_info)).unwrap(); + let signature0 = tap.get_account(&voter, None).unwrap().sign_schnorr(&vote_info.hash()).unwrap(); let seal = Seal::Tendermint { prev_view: 0, @@ -304,7 +310,7 @@ mod tests { assert!(engine.verify_block_external(&header).is_ok()); let bad_voter = insert_and_unlock(&tap, "101"); - let bad_signature = tap.get_account(&bad_voter, None).unwrap().sign_schnorr(&blake256(vote_info)).unwrap(); + let bad_signature = tap.get_account(&bad_voter, None).unwrap().sign_schnorr(&vote_info.hash()).unwrap(); let seal = Seal::Tendermint { prev_view: 0, diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 63d12abd3c..728cd73d93 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -1120,9 +1120,11 @@ impl Worker { debug_assert_eq!(Ok(self.view), TendermintSealView::new(header.seal()).consensus_view()); - let vote_step = VoteStep::new(header.number() as Height, self.view, Step::Propose); - let vote_info = message_info_rlp(vote_step, Some(hash)); - let signature = self.sign(blake256(&vote_info)).expect("I am proposer"); + let vote_on = VoteOn { + step: VoteStep::new(header.number() as Height, self.view, Step::Propose), + block_hash: Some(hash), + }; + let signature = self.sign(vote_on.hash()).expect("I am proposer"); self.votes.vote( ConsensusMessage::new_proposal(signature, &*self.validators, header, self.view, prev_proposer_idx) .expect("I am proposer"), @@ -1191,8 +1193,10 @@ impl Worker { } let previous_block_view = TendermintSealView::new(header.seal()).previous_block_view()?; - let step = VoteStep::new(header.number() - 1, previous_block_view, Step::Precommit); - let precommit_hash = message_hash(step, *header.parent_hash()); + let precommit_vote_on = VoteOn { + step: VoteStep::new(header.number() - 1, previous_block_view, Step::Precommit), + block_hash: Some(*header.parent_hash()), + }; let mut voted_validators = BitSet::new(); let grand_parent_hash = self @@ -1202,7 +1206,7 @@ impl Worker { .parent_hash(); for (bitset_index, signature) in seal_view.signatures()? { let public = self.validators.get(&grand_parent_hash, bitset_index); - if !verify_schnorr(&public, &signature, &precommit_hash)? { + if !verify_schnorr(&public, &signature, &precommit_vote_on.hash())? { let address = public_to_address(&public); return Err(EngineError::BlockNotAuthorized(address.to_owned()).into()) } @@ -1474,11 +1478,13 @@ impl Worker { fn repropose_block(&mut self, block: encoded::Block) { let header = block.decode_header(); - let vote_step = VoteStep::new(header.number() as Height, self.view, Step::Propose); - let vote_info = message_info_rlp(vote_step, Some(header.hash())); + let vote_on = VoteOn { + step: VoteStep::new(header.number() as Height, self.view, Step::Propose), + block_hash: Some(header.hash()), + }; let parent_hash = header.parent_hash(); let prev_proposer_idx = self.block_proposer_idx(*parent_hash).expect("Prev block must exists"); - let signature = self.sign(blake256(&vote_info)).expect("I am proposer"); + let signature = self.sign(vote_on.hash()).expect("I am proposer"); self.votes.vote( ConsensusMessage::new_proposal(signature, &*self.validators, &header, self.view, prev_proposer_idx) .expect("I am proposer"), From 38971d5c6ddf08d9ce310de875d3d65b143ae057 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Sun, 22 Sep 2019 05:19:38 +0900 Subject: [PATCH 029/105] Make sign function hash argument by itself --- core/src/consensus/tendermint/worker.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 728cd73d93..c6e7f5c571 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -20,7 +20,6 @@ use std::sync::{Arc, Weak}; use std::thread::{Builder, JoinHandle}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use ccrypto::blake256; use ckey::{public_to_address, verify_schnorr, Address, SchnorrSignature}; use cnetwork::{EventSender, NodeId}; use crossbeam_channel as crossbeam; @@ -837,13 +836,12 @@ impl Worker { step: VoteStep::new(height, r, self.step.to_step()), block_hash, }; - let vote_info = on.rlp_bytes(); let signer_index = self.signer_index().or_else(|| { ctrace!(ENGINE, "No message, since there is no engine signer."); None })?; let signature = self - .sign(blake256(&vote_info)) + .sign(&on) .map_err(|error| { ctrace!(ENGINE, "{}th validator could not sign the message {}", signer_index, error); error @@ -1124,7 +1122,7 @@ impl Worker { step: VoteStep::new(header.number() as Height, self.view, Step::Propose), block_hash: Some(hash), }; - let signature = self.sign(vote_on.hash()).expect("I am proposer"); + let signature = self.sign(&vote_on).expect("I am proposer"); self.votes.vote( ConsensusMessage::new_proposal(signature, &*self.validators, header, self.view, prev_proposer_idx) .expect("I am proposer"), @@ -1484,7 +1482,7 @@ impl Worker { }; let parent_hash = header.parent_hash(); let prev_proposer_idx = self.block_proposer_idx(*parent_hash).expect("Prev block must exists"); - let signature = self.sign(vote_on.hash()).expect("I am proposer"); + let signature = self.sign(&vote_on).expect("I am proposer"); self.votes.vote( ConsensusMessage::new_proposal(signature, &*self.validators, &header, self.view, prev_proposer_idx) .expect("I am proposer"), @@ -1517,8 +1515,8 @@ impl Worker { self.signer.set_to_keep_decrypted_account(ap, address); } - fn sign(&self, hash: H256) -> Result { - self.signer.sign(hash).map_err(Into::into) + fn sign(&self, vote_on: &VoteOn) -> Result { + self.signer.sign(vote_on.hash()).map_err(Into::into) } fn signer_index(&self) -> Option { From b01b14dddef84be4fe64d6df2211cc7becdc6501 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 25 Sep 2019 12:13:38 +0900 Subject: [PATCH 030/105] Remove unused `on_verified_proposal` in consensus --- core/src/client/importer.rs | 5 ----- core/src/consensus/mod.rs | 5 ----- 2 files changed, 10 deletions(-) diff --git a/core/src/client/importer.rs b/core/src/client/importer.rs index d039b36e22..b00e992e8f 100644 --- a/core/src/client/importer.rs +++ b/core/src/client/importer.rs @@ -30,7 +30,6 @@ use super::{BlockChainTrait, Client, ClientConfig}; use crate::block::{enact, IsBlock, LockedBlock}; use crate::blockchain::{BodyProvider, HeaderProvider, ImportRoute}; use crate::consensus::CodeChainEngine; -use crate::encoded; use crate::error::Error; use crate::miner::{Miner, MinerService}; use crate::service::ClientIoMessage; @@ -117,10 +116,6 @@ impl Importer { continue } if let Ok(closed_block) = self.check_and_close_block(&block, client) { - if self.engine.is_proposal(&block.header) { - self.engine.on_verified_proposal(encoded::Block::new(block.bytes.clone())) - } - imported_blocks.push(header.hash()); let route = self.commit_block(&closed_block, &header, &block.bytes, client); import_results.push(route); diff --git a/core/src/consensus/mod.rs b/core/src/consensus/mod.rs index 513270d71a..9647203d52 100644 --- a/core/src/consensus/mod.rs +++ b/core/src/consensus/mod.rs @@ -53,7 +53,6 @@ use crate::account_provider::AccountProvider; use crate::block::{ExecutedBlock, SealedBlock}; use crate::client::ConsensusClient; use crate::codechain_machine::CodeChainMachine; -use crate::encoded; use crate::error::Error; use crate::transaction::UnverifiedTransaction; use crate::views::HeaderView; @@ -242,10 +241,6 @@ pub trait ConsensusEngine: Sync + Send { false } - /// Called when proposal block is verified. - /// Consensus many hold the verified proposal block until it should be imported. - fn on_verified_proposal(&self, _verified_block_data: encoded::Block) {} - /// Register an account which signs consensus messages. fn set_signer(&self, _ap: Arc, _address: Address) {} From c03b699943c568cd67e27497d0e2e8c23a75e010 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Thu, 26 Sep 2019 15:39:41 +0900 Subject: [PATCH 031/105] Do not panic when height, view or step is changed while creating a block --- core/src/consensus/tendermint/worker.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index c6e7f5c571..0b714b576e 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -1098,6 +1098,24 @@ impl Worker { } fn proposal_generated(&mut self, sealed_block: &SealedBlock) { + let proposal_height = sealed_block.header().number(); + let proposal_seal = sealed_block.header().seal(); + let proposal_view = TendermintSealView::new(proposal_seal) + .consensus_view() + .expect("Generated proposal should have a valid seal"); + assert!(proposal_height <= self.height, "A proposal cannot be generated on the future height"); + if proposal_height < self.height || (proposal_height == self.height && proposal_view != self.view) { + ctrace!( + ENGINE, + "Proposal is generated on the height {} and view {}. Current height is {} and view is {}", + proposal_height, + proposal_view, + self.height, + self.view, + ); + return + } + let header = sealed_block.header(); let hash = header.hash(); let parent_hash = header.parent_hash(); @@ -1112,7 +1130,12 @@ impl Worker { parent_hash, expected_parent_hash ); } else { - panic!("Block is generated at unexpected step {:?}", self.step); + ctrace!( + ENGINE, + "Proposal is generated after step is changed. Expected step is ProposeWaitBlockGeneration but current step is {:?}", + self.step, + ); + return } let prev_proposer_idx = self.block_proposer_idx(*parent_hash).expect("Prev block must exists"); From 9f3abffbeefecd1ebcadf26f7665a8e70069c02b Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 2 Oct 2019 15:48:48 +0900 Subject: [PATCH 032/105] Bump the version 2.1.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 577e0e23fc..3c49355157 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -226,7 +226,7 @@ dependencies = [ [[package]] name = "codechain" -version = "2.0.0" +version = "2.1.0" dependencies = [ "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cidr 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index b4c9410bcf..e1627acdb8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "codechain" -version = "2.0.0" +version = "2.1.0" license = "AGPL-3.0" authors = ["CodeChain Team "] exclude = [ From b01a75965b5c24c864762fa092a120ca75f0b0cf Mon Sep 17 00:00:00 2001 From: Joonmo Yang Date: Thu, 26 Sep 2019 14:05:09 +0900 Subject: [PATCH 033/105] Try to unlock account only when it is imported --- codechain/run_node.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/codechain/run_node.rs b/codechain/run_node.rs index 6d5cb5d5a1..b3003f8938 100644 --- a/codechain/run_node.rs +++ b/codechain/run_node.rs @@ -193,8 +193,13 @@ fn load_password_file(path: &Option) -> Result { fn unlock_accounts(ap: &AccountProvider, pf: &PasswordFile) -> Result<(), String> { for entry in pf.entries() { let entry_address = entry.address.into_address(); - ap.unlock_account_permanently(entry_address, entry.password.clone()) - .map_err(|e| format!("Failed to unlock account {}: {}", entry_address, e))?; + let has_account = ap + .has_account(&entry_address) + .map_err(|e| format!("Unexpected error while querying account {}: {}", entry_address, e))?; + if has_account { + ap.unlock_account_permanently(entry_address, entry.password.clone()) + .map_err(|e| format!("Failed to unlock account {}: {}", entry_address, e))?; + } } Ok(()) } From 525042f29ea474bfac7036831d6ebeff8fa53ef7 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Thu, 26 Sep 2019 16:40:39 +0900 Subject: [PATCH 034/105] Check mutation of votes_received automatially --- core/src/consensus/tendermint/worker.rs | 84 ++++++++++++++++++------- 1 file changed, 62 insertions(+), 22 deletions(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 0b714b576e..c2dd143da0 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -52,6 +52,7 @@ use crate::error::{BlockError, Error}; use crate::transaction::{SignedTransaction, UnverifiedTransaction}; use crate::views::BlockView; use crate::BlockId; +use std::cell::Cell; type SpawnResult = ( JoinHandle<()>, @@ -74,9 +75,7 @@ struct Worker { /// Consensus step. step: TendermintState, /// Record current round's received votes as bit set - votes_received: BitSet, - /// The votes_received field is changed after last state broadcast. - votes_received_changed: bool, + votes_received: MutTrigger, /// Vote accumulator. votes: VoteCollector, /// Used to sign messages and proposals. @@ -192,8 +191,7 @@ impl Worker { last_confirmed_view: 0, validators, extension, - votes_received: BitSet::new(), - votes_received_changed: false, + votes_received: MutTrigger::new(BitSet::new()), time_gap_params, timeout_token_nonce: ENGINE_TIMEOUT_TOKEN_NONCE_BASE, } @@ -576,13 +574,13 @@ impl Worker { .unwrap(); } - fn broadcast_state(&self, vote_step: VoteStep, proposal: Option, lock_view: Option, votes: BitSet) { + fn broadcast_state(&self, vote_step: VoteStep, proposal: Option, lock_view: Option, votes: &BitSet) { self.extension .send(network::Event::BroadcastState { vote_step, proposal, lock_view, - votes, + votes: *votes, }) .unwrap(); } @@ -617,7 +615,7 @@ impl Worker { cinfo!(ENGINE, "increment_view: New view."); self.view += n; self.proposal = Proposal::None; - self.votes_received = BitSet::new(); + self.votes_received = MutTrigger::new(BitSet::new()); } fn move_to_height(&mut self, height: Height) { @@ -627,7 +625,7 @@ impl Worker { self.height = height; self.view = 0; self.proposal = Proposal::None; - self.votes_received = BitSet::new(); + self.votes_received = MutTrigger::new(BitSet::new()); } #[allow(clippy::cognitive_complexity)] @@ -654,7 +652,7 @@ impl Worker { // Also, when moving to the commit step, // keep `votes_received` for gossiping. if prev_step.to_step() != state.to_step() && !state.is_commit() { - self.votes_received = BitSet::new(); + self.votes_received = MutTrigger::new(BitSet::new()); } // need to reset vote @@ -662,7 +660,7 @@ impl Worker { vote_step, self.proposal.block_hash(), self.last_two_thirds_majority.view(), - self.votes_received, + self.votes_received.borrow_anyway(), ); match state.to_step() { Step::Propose => { @@ -929,10 +927,6 @@ impl Worker { return } } - - // self.move_to_step() calls self.broadcast_state() - // If self.move_to_step() is not called, call self.broadcast_state() in here. - self.votes_received_changed = true; } pub fn on_imported_proposal(&mut self, proposal: &Header) { @@ -1273,13 +1267,12 @@ impl Worker { } if token == ENGINE_TIMEOUT_BROADCAST_STEP_STATE { - if self.votes_received_changed { - self.votes_received_changed = false; + if let Some(votes_received) = self.votes_received.borrow_if_mutated() { self.broadcast_state( self.vote_step(), self.proposal.block_hash(), self.last_two_thirds_majority.view(), - self.votes_received, + votes_received, ); } return @@ -1776,7 +1769,7 @@ impl Worker { VoteStep::new(self.height, self.view, self.step.to_step()), self.proposal.block_hash(), self.last_two_thirds_majority.view(), - self.votes_received, + self.votes_received.borrow_anyway(), ); } @@ -1851,8 +1844,7 @@ impl Worker { BitSet::new() }; - let current_votes = self.votes_received; - let difference = &peer_known_votes - ¤t_votes; + let difference = &peer_known_votes - &self.votes_received; if !difference.is_empty() { self.send_request_messages(token, current_vote_step, difference, &result); } @@ -2122,7 +2114,7 @@ impl Worker { // Since we don't have proposal vote, set proposal = None self.proposal = Proposal::None; self.view = commit_view; - self.votes_received = vote_bitset; + self.votes_received = MutTrigger::new(vote_bitset); self.last_two_thirds_majority = TwoThirdsMajority::Empty; self.move_to_step( @@ -2148,3 +2140,51 @@ fn calculate_score(height: Height, view: View) -> U256 { let height = U256::from(height); u256_from_u128(std::u128::MAX) * height - view } + +/// Sets internal trigger on deref_mut (taking mutable reference to internal value) +/// trigger is reset on borrowing +struct MutTrigger { + target: T, + deref_mut_triggered: Cell, +} + +impl MutTrigger { + fn new(target: T) -> Self { + Self { + target, + deref_mut_triggered: Cell::new(true), + } + } + + /// Get the reference if triggered (mutable reference is taken after last borrowing) + /// When it is not triggered, returns None + fn borrow_if_mutated(&self) -> Option<&T> { + if self.deref_mut_triggered.get() { + self.deref_mut_triggered.set(false); + Some(&self.target) + } else { + None + } + } + + /// Reset the trigger and take a reference + fn borrow_anyway(&self) -> &T { + self.deref_mut_triggered.set(false); + &self.target + } +} + +impl std::ops::Deref for MutTrigger { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.target + } +} + +impl std::ops::DerefMut for MutTrigger { + fn deref_mut(&mut self) -> &mut Self::Target { + self.deref_mut_triggered.set(true); + &mut self.target + } +} From 4908cc10cb6699c017920d7e3024b4d603d2e99e Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Thu, 26 Sep 2019 16:23:39 +0900 Subject: [PATCH 035/105] Cleanup vote functions --- core/src/consensus/tendermint/message.rs | 24 ---- core/src/consensus/tendermint/worker.rs | 149 ++++++++++++----------- 2 files changed, 76 insertions(+), 97 deletions(-) diff --git a/core/src/consensus/tendermint/message.rs b/core/src/consensus/tendermint/message.rs index a811e98da1..65cd5dfbcc 100644 --- a/core/src/consensus/tendermint/message.rs +++ b/core/src/consensus/tendermint/message.rs @@ -18,12 +18,10 @@ use std::cmp; use ccrypto::blake256; use ckey::{verify_schnorr, Error as KeyError, Public, SchnorrSignature}; -use ctypes::Header; use primitives::{Bytes, H256}; use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; use snap; -use super::super::validator_set::DynamicValidator; use super::super::BitSet; use super::{BlockHash, Height, Step, View}; @@ -331,28 +329,6 @@ pub struct ConsensusMessage { } impl ConsensusMessage { - /// If a locked node re-proposes locked proposal, the proposed_view is different from the header's view. - pub fn new_proposal( - signature: SchnorrSignature, - validators: &DynamicValidator, - proposal_header: &Header, - proposed_view: View, - prev_proposer_idx: usize, - ) -> Result { - let height = proposal_header.number() as Height; - let signer_index = - validators.proposer_index(*proposal_header.parent_hash(), prev_proposer_idx, proposed_view as usize); - - Ok(ConsensusMessage { - signature, - signer_index, - on: VoteOn { - step: VoteStep::new(height, proposed_view, Step::Propose), - block_hash: Some(proposal_header.hash()), - }, - }) - } - pub fn signature(&self) -> SchnorrSignature { self.signature } diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index c2dd143da0..7fd285fd01 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -819,7 +819,8 @@ impl Worker { } fn generate_and_broadcast_message(&mut self, block_hash: Option, is_restoring: bool) { - if let Some(message) = self.generate_message(block_hash, is_restoring) { + if let Some(message) = self.vote_on_block_hash(block_hash).expect("Error while vote") { + self.handle_valid_message(&message, is_restoring); if !is_restoring { self.backup(); } @@ -827,37 +828,6 @@ impl Worker { } } - fn generate_message(&mut self, block_hash: Option, is_restoring: bool) -> Option { - let height = self.height; - let r = self.view; - let on = VoteOn { - step: VoteStep::new(height, r, self.step.to_step()), - block_hash, - }; - let signer_index = self.signer_index().or_else(|| { - ctrace!(ENGINE, "No message, since there is no engine signer."); - None - })?; - let signature = self - .sign(&on) - .map_err(|error| { - ctrace!(ENGINE, "{}th validator could not sign the message {}", signer_index, error); - error - }) - .ok()?; - let message = ConsensusMessage { - signature, - signer_index, - on, - }; - self.votes_received.set(signer_index); - self.votes.vote(message.clone()); - cinfo!(ENGINE, "Generated {:?} as {}th validator.", message, signer_index); - self.handle_valid_message(&message, is_restoring); - - Some(message) - } - fn handle_valid_message(&mut self, message: &ConsensusMessage, is_restoring: bool) { let vote_step = &message.on.step; let is_newer_than_lock = match self.last_two_thirds_majority.view() { @@ -1111,7 +1081,6 @@ impl Worker { } let header = sealed_block.header(); - let hash = header.hash(); let parent_hash = header.parent_hash(); if let TendermintState::ProposeWaitBlockGeneration { @@ -1131,19 +1100,9 @@ impl Worker { ); return } - let prev_proposer_idx = self.block_proposer_idx(*parent_hash).expect("Prev block must exists"); - debug_assert_eq!(Ok(self.view), TendermintSealView::new(header.seal()).consensus_view()); - let vote_on = VoteOn { - step: VoteStep::new(header.number() as Height, self.view, Step::Propose), - block_hash: Some(hash), - }; - let signature = self.sign(&vote_on).expect("I am proposer"); - self.votes.vote( - ConsensusMessage::new_proposal(signature, &*self.validators, header, self.view, prev_proposer_idx) - .expect("I am proposer"), - ); + self.vote_on_header_for_proposal(&header).expect("I'm a proposer"); self.step = TendermintState::ProposeWaitImported { block: Box::new(sealed_block.clone()), @@ -1492,18 +1451,7 @@ impl Worker { fn repropose_block(&mut self, block: encoded::Block) { let header = block.decode_header(); - let vote_on = VoteOn { - step: VoteStep::new(header.number() as Height, self.view, Step::Propose), - block_hash: Some(header.hash()), - }; - let parent_hash = header.parent_hash(); - let prev_proposer_idx = self.block_proposer_idx(*parent_hash).expect("Prev block must exists"); - let signature = self.sign(&vote_on).expect("I am proposer"); - self.votes.vote( - ConsensusMessage::new_proposal(signature, &*self.validators, &header, self.view, prev_proposer_idx) - .expect("I am proposer"), - ); - + self.vote_on_header_for_proposal(&header).expect("I am proposer"); self.proposal = Proposal::new_imported(header.hash()); self.broadcast_proposal_block(self.view, block); } @@ -1531,8 +1479,76 @@ impl Worker { self.signer.set_to_keep_decrypted_account(ap, address); } - fn sign(&self, vote_on: &VoteOn) -> Result { - self.signer.sign(vote_on.hash()).map_err(Into::into) + fn vote_on_block_hash(&mut self, block_hash: Option) -> Result, Error> { + let signer_index = if let Some(signer_index) = self.signer_index() { + signer_index + } else { + ctrace!(ENGINE, "No message, since there is no engine signer."); + return Ok(None) + }; + + let on = VoteOn { + step: VoteStep::new(self.height, self.view, self.step.to_step()), + block_hash, + }; + let signature = self.signer.sign(on.hash())?; + + let vote = ConsensusMessage { + signature, + signer_index, + on, + }; + + self.votes_received.set(vote.signer_index); + self.votes.vote(vote.clone()); + cinfo!(ENGINE, "Voted {:?} as {}th validator.", vote, signer_index); + Ok(Some(vote)) + } + + fn vote_on_header_for_proposal(&mut self, header: &Header) -> Result { + assert!(header.number() == self.height); + + let parent_hash = header.parent_hash(); + let prev_proposer_idx = self.block_proposer_idx(*parent_hash).expect("Prev block must exists"); + let signer_index = self.validators.proposer_index(*parent_hash, prev_proposer_idx, self.view as usize); + + let on = VoteOn { + step: VoteStep::new(self.height, self.view, Step::Propose), + block_hash: Some(header.hash()), + }; + let signature = self.signer.sign(on.hash())?; + + let vote = ConsensusMessage { + signature, + signer_index, + on, + }; + + self.votes.vote(vote.clone()); + cinfo!(ENGINE, "Voted {:?} as {}th proposer.", vote, signer_index); + Ok(vote) + } + + fn recover_proposal_vote( + &self, + header: &Header, + proposed_view: View, + signature: SchnorrSignature, + ) -> Option { + let prev_proposer_idx = self.block_proposer_idx(*header.parent_hash())?; + let signer_index = + self.validators.proposer_index(*header.parent_hash(), prev_proposer_idx, proposed_view as usize); + + let on = VoteOn { + step: VoteStep::new(header.number(), proposed_view, Step::Propose), + block_hash: Some(header.hash()), + }; + + Some(ConsensusMessage { + signature, + signer_index, + on, + }) } fn signer_index(&self) -> Option { @@ -1696,27 +1712,14 @@ impl Worker { return None } } - - let prev_proposer_idx = match self.block_proposer_idx(*parent_hash) { - Some(idx) => idx, + let message = match self.recover_proposal_vote(&header_view, proposed_view, signature) { + Some(vote) => vote, None => { cwarn!(ENGINE, "Prev block proposer does not exist for height {}", number); return None } }; - let message = ConsensusMessage::new_proposal( - signature, - &*self.validators, - &header_view, - proposed_view, - prev_proposer_idx, - ) - .map_err(|err| { - cwarn!(ENGINE, "Invalid proposal received: {:?}", err); - }) - .ok()?; - // If the proposal's height is current height + 1 and the proposal has valid precommits, // we should import it and increase height if number > (self.height + 1) as u64 { From 39bea393bb854f652491c3f121993bee981b9e80 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Thu, 26 Sep 2019 16:24:12 +0900 Subject: [PATCH 036/105] Add VoteRegressionChecker --- core/src/consensus/tendermint/mod.rs | 1 + .../tendermint/vote_regression_checker.rs | 189 ++++++++++++++++++ core/src/consensus/tendermint/worker.rs | 9 +- 3 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 core/src/consensus/tendermint/vote_regression_checker.rs diff --git a/core/src/consensus/tendermint/mod.rs b/core/src/consensus/tendermint/mod.rs index 997e80cc78..8366faf1ae 100644 --- a/core/src/consensus/tendermint/mod.rs +++ b/core/src/consensus/tendermint/mod.rs @@ -22,6 +22,7 @@ mod network; mod params; pub mod types; pub mod vote_collector; +mod vote_regression_checker; mod worker; use std::sync::atomic::AtomicBool; diff --git a/core/src/consensus/tendermint/vote_regression_checker.rs b/core/src/consensus/tendermint/vote_regression_checker.rs new file mode 100644 index 0000000000..fc37907afa --- /dev/null +++ b/core/src/consensus/tendermint/vote_regression_checker.rs @@ -0,0 +1,189 @@ +use consensus::{Step, VoteOn}; +use std::cmp::Ordering; + +pub struct VoteRegressionChecker { + last_vote: Option, +} + +impl VoteRegressionChecker { + pub fn new() -> VoteRegressionChecker { + VoteRegressionChecker { + last_vote: None, + } + } + + pub fn check(&mut self, vote_on: &VoteOn) -> bool { + assert!(match vote_on.step.step { + Step::Propose | Step::Prevote | Step::Precommit => true, + _ => false, + }); + + let monotonic = if let Some(last_vote) = &self.last_vote { + match last_vote.step.cmp(&vote_on.step) { + Ordering::Less => true, + Ordering::Greater => false, + Ordering::Equal => last_vote.block_hash == vote_on.block_hash, + } + } else { + true + }; + + if monotonic { + self.last_vote = Some(vote_on.clone()); + } + monotonic + } +} + +#[cfg(test)] +mod tests { + use super::*; + use consensus::VoteStep; + use primitives::H256; + + #[test] + fn test_initial_set() { + let mut checker = VoteRegressionChecker::new(); + + let random_step = VoteStep::new(100, 10, Step::Prevote); + let random_hash = Some(H256::random()); + assert!(checker.check(&VoteOn { + step: random_step, + block_hash: random_hash + })) + } + + #[test] + #[should_panic] + fn test_disallow_commit() { + let mut checker = VoteRegressionChecker::new(); + + let random_commit_step = VoteStep::new(100, 10, Step::Commit); + let random_hash = Some(H256::random()); + assert!(checker.check(&VoteOn { + step: random_commit_step, + block_hash: random_hash + })) + } + + #[test] + fn test_allow_height_increase() { + let mut checker = VoteRegressionChecker::new(); + + checker.check(&VoteOn { + step: VoteStep::new(100, 10, Step::Prevote), + block_hash: Some(H256::from(1)), + }); + + assert!(checker.check(&VoteOn { + step: VoteStep::new(101, 10, Step::Prevote), + block_hash: Some(H256::from(2)) + })) + } + + #[test] + fn test_disallow_height_decrease() { + let mut checker = VoteRegressionChecker::new(); + + checker.check(&VoteOn { + step: VoteStep::new(100, 10, Step::Prevote), + block_hash: Some(H256::from(1)), + }); + + assert!(!checker.check(&VoteOn { + step: VoteStep::new(99, 10, Step::Prevote), + block_hash: Some(H256::from(2)) + })) + } + + #[test] + fn test_allow_view_increase() { + let mut checker = VoteRegressionChecker::new(); + + checker.check(&VoteOn { + step: VoteStep::new(100, 10, Step::Prevote), + block_hash: Some(H256::from(1)), + }); + + assert!(checker.check(&VoteOn { + step: VoteStep::new(100, 11, Step::Prevote), + block_hash: Some(H256::from(2)) + })) + } + + #[test] + fn test_disallow_view_decrease() { + let mut checker = VoteRegressionChecker::new(); + + checker.check(&VoteOn { + step: VoteStep::new(100, 10, Step::Prevote), + block_hash: Some(H256::from(1)), + }); + + assert!(!checker.check(&VoteOn { + step: VoteStep::new(100, 9, Step::Prevote), + block_hash: Some(H256::from(2)) + })) + } + + #[test] + fn test_allow_step_increased() { + let mut checker = VoteRegressionChecker::new(); + + checker.check(&VoteOn { + step: VoteStep::new(100, 10, Step::Prevote), + block_hash: Some(H256::from(1)), + }); + + assert!(checker.check(&VoteOn { + step: VoteStep::new(100, 10, Step::Precommit), + block_hash: Some(H256::from(2)) + })) + } + + #[test] + fn test_disallow_step_decreased() { + let mut checker = VoteRegressionChecker::new(); + + checker.check(&VoteOn { + step: VoteStep::new(100, 10, Step::Prevote), + block_hash: Some(H256::from(1)), + }); + + assert!(!checker.check(&VoteOn { + step: VoteStep::new(100, 10, Step::Propose), + block_hash: Some(H256::from(2)) + })) + } + + #[test] + fn test_allow_same_hash() { + let mut checker = VoteRegressionChecker::new(); + + let block_hash = Some(H256::random()); + checker.check(&VoteOn { + step: VoteStep::new(100, 10, Step::Prevote), + block_hash, + }); + + assert!(checker.check(&VoteOn { + step: VoteStep::new(100, 10, Step::Prevote), + block_hash, + })) + } + + #[test] + fn test_disallow_hash_change() { + let mut checker = VoteRegressionChecker::new(); + + checker.check(&VoteOn { + step: VoteStep::new(100, 10, Step::Prevote), + block_hash: Some(H256::from(1)), + }); + + assert!(!checker.check(&VoteOn { + step: VoteStep::new(100, 10, Step::Prevote), + block_hash: Some(H256::from(2)) + })) + } +} diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 7fd285fd01..4fb93ec546 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -37,6 +37,7 @@ use super::params::TimeGapParams; use super::stake::CUSTOM_ACTION_HANDLER_ID; use super::types::{Height, Proposal, Step, TendermintSealView, TendermintState, TwoThirdsMajority, View}; use super::vote_collector::{DoubleVote, VoteCollector}; +use super::vote_regression_checker::VoteRegressionChecker; use super::{ BlockHash, ENGINE_TIMEOUT_BROADCAST_STEP_STATE, ENGINE_TIMEOUT_EMPTY_PROPOSAL, ENGINE_TIMEOUT_TOKEN_NONCE_BASE, SEAL_FIELDS, @@ -92,6 +93,7 @@ struct Worker { extension: EventSender, time_gap_params: TimeGapParams, timeout_token_nonce: usize, + vote_regression_checker: VoteRegressionChecker, } pub enum Event { @@ -194,6 +196,7 @@ impl Worker { votes_received: MutTrigger::new(BitSet::new()), time_gap_params, timeout_token_nonce: ENGINE_TIMEOUT_TOKEN_NONCE_BASE, + vote_regression_checker: VoteRegressionChecker::new(), } } @@ -1081,12 +1084,12 @@ impl Worker { } let header = sealed_block.header(); - let parent_hash = header.parent_hash(); if let TendermintState::ProposeWaitBlockGeneration { parent_hash: expected_parent_hash, } = self.step { + let parent_hash = header.parent_hash(); assert_eq!( *parent_hash, expected_parent_hash, "Generated hash({:?}) is different from expected({:?})", @@ -1491,6 +1494,8 @@ impl Worker { step: VoteStep::new(self.height, self.view, self.step.to_step()), block_hash, }; + assert!(self.vote_regression_checker.check(&on), "Vote should not regress"); + let signature = self.signer.sign(on.hash())?; let vote = ConsensusMessage { @@ -1516,6 +1521,8 @@ impl Worker { step: VoteStep::new(self.height, self.view, Step::Propose), block_hash: Some(header.hash()), }; + assert!(self.vote_regression_checker.check(&on), "Vote should not regress"); + let signature = self.signer.sign(on.hash())?; let vote = ConsensusMessage { From 463c484917bcba1020310be32c8a32332e2df38b Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Thu, 26 Sep 2019 16:43:52 +0900 Subject: [PATCH 037/105] Rename VoteCollector::vote to collect --- core/src/consensus/tendermint/vote_collector.rs | 2 +- core/src/consensus/tendermint/worker.rs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/consensus/tendermint/vote_collector.rs b/core/src/consensus/tendermint/vote_collector.rs index ad5391ec8c..ea3cef1572 100644 --- a/core/src/consensus/tendermint/vote_collector.rs +++ b/core/src/consensus/tendermint/vote_collector.rs @@ -120,7 +120,7 @@ impl Default for VoteCollector { impl VoteCollector { /// Insert vote if it is newer than the oldest one. - pub fn vote(&mut self, message: ConsensusMessage) -> Option { + pub fn collect(&mut self, message: ConsensusMessage) -> Option { self.votes.entry(*message.round()).or_insert_with(Default::default).insert(message) } diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 4fb93ec546..82c4b84244 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -921,7 +921,7 @@ impl Worker { on: on.clone(), }; if !self.votes.is_old_or_known(&message) { - self.votes.vote(message); + self.votes.collect(message); } } @@ -1387,7 +1387,7 @@ impl Worker { self.votes_received.set(vote_index); } - if let Some(double) = self.votes.vote(message.clone()) { + if let Some(double) = self.votes.collect(message.clone()) { cerror!(ENGINE, "Double vote found {:?}", double); self.report_double_vote(&double); return Err(EngineError::DoubleVote(sender)) @@ -1505,7 +1505,7 @@ impl Worker { }; self.votes_received.set(vote.signer_index); - self.votes.vote(vote.clone()); + self.votes.collect(vote.clone()); cinfo!(ENGINE, "Voted {:?} as {}th validator.", vote, signer_index); Ok(Some(vote)) } @@ -1531,7 +1531,7 @@ impl Worker { on, }; - self.votes.vote(vote.clone()); + self.votes.collect(vote.clone()); cinfo!(ENGINE, "Voted {:?} as {}th proposer.", vote, signer_index); Ok(vote) } @@ -1783,7 +1783,7 @@ impl Worker { ); } - if let Some(double) = self.votes.vote(message.clone()) { + if let Some(double) = self.votes.collect(message.clone()) { cerror!(ENGINE, "Double Vote found {:?}", double); self.report_double_vote(&double); return None @@ -2117,7 +2117,7 @@ impl Worker { cdebug!(ENGINE, "Commit message-{} is verified", commit_height); for vote in votes { if !self.votes.is_old_or_known(&vote) { - self.votes.vote(vote); + self.votes.collect(vote); } } From 3ab64a805b354f3c260e2c6c213116a143d5745d Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Thu, 26 Sep 2019 17:27:12 +0900 Subject: [PATCH 038/105] Fix to use Err(DoubleVote) from VoteCollector VoteCollector is changed to return Result. Rust compiler will force you to check whether there was a double vote. --- .../consensus/tendermint/vote_collector.rs | 41 ++++++++++--------- core/src/consensus/tendermint/worker.rs | 16 +++++--- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/core/src/consensus/tendermint/vote_collector.rs b/core/src/consensus/tendermint/vote_collector.rs index ea3cef1572..d93fef2e86 100644 --- a/core/src/consensus/tendermint/vote_collector.rs +++ b/core/src/consensus/tendermint/vote_collector.rs @@ -61,26 +61,29 @@ impl Encodable for DoubleVote { } impl StepCollector { - /// Returns Some(&Address) when validator is double voting. - fn insert(&mut self, message: ConsensusMessage) -> Option { + /// Some(true): a message is new + /// Some(false): a message is duplicated + /// Err(DoubleVote): a double vote + fn insert(&mut self, message: ConsensusMessage) -> Result { // Do nothing when message was seen. - if !self.messages.contains(&message) { - self.messages.push(message.clone()); - if let Some(previous) = self.voted.insert(message.signer_index(), message.clone()) { - // Bad validator sent a different message. - return Some(DoubleVote { - author_index: message.signer_index(), - vote_one: previous, - vote_two: message, - }) - } else { - self.block_votes - .entry(message.block_hash()) - .or_default() - .insert(message.signer_index(), message.signature()); - } + if self.messages.contains(&message) { + return Ok(false) + } + self.messages.push(message.clone()); + if let Some(previous) = self.voted.insert(message.signer_index(), message.clone()) { + // Bad validator sent a different message. + Err(DoubleVote { + author_index: message.signer_index(), + vote_one: previous, + vote_two: message, + }) + } else { + self.block_votes + .entry(message.block_hash()) + .or_default() + .insert(message.signer_index(), message.signature()); + Ok(true) } - None } /// Count all votes for the given block hash at this round. @@ -120,7 +123,7 @@ impl Default for VoteCollector { impl VoteCollector { /// Insert vote if it is newer than the oldest one. - pub fn collect(&mut self, message: ConsensusMessage) -> Option { + pub fn collect(&mut self, message: ConsensusMessage) -> Result { self.votes.entry(*message.round()).or_insert_with(Default::default).insert(message) } diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 82c4b84244..ed23a1fdb0 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -921,7 +921,9 @@ impl Worker { on: on.clone(), }; if !self.votes.is_old_or_known(&message) { - self.votes.collect(message); + if let Err(double_vote) = self.votes.collect(message) { + cerror!(ENGINE, "Double vote found on_commit_message: {:?}", double_vote); + } } } @@ -1387,7 +1389,7 @@ impl Worker { self.votes_received.set(vote_index); } - if let Some(double) = self.votes.collect(message.clone()) { + if let Err(double) = self.votes.collect(message.clone()) { cerror!(ENGINE, "Double vote found {:?}", double); self.report_double_vote(&double); return Err(EngineError::DoubleVote(sender)) @@ -1505,7 +1507,7 @@ impl Worker { }; self.votes_received.set(vote.signer_index); - self.votes.collect(vote.clone()); + self.votes.collect(vote.clone()).expect("Must not attempt double vote"); cinfo!(ENGINE, "Voted {:?} as {}th validator.", vote, signer_index); Ok(Some(vote)) } @@ -1531,7 +1533,7 @@ impl Worker { on, }; - self.votes.collect(vote.clone()); + self.votes.collect(vote.clone()).expect("Must not attempt double vote on proposal");; cinfo!(ENGINE, "Voted {:?} as {}th proposer.", vote, signer_index); Ok(vote) } @@ -1783,7 +1785,7 @@ impl Worker { ); } - if let Some(double) = self.votes.collect(message.clone()) { + if let Err(double) = self.votes.collect(message.clone()) { cerror!(ENGINE, "Double Vote found {:?}", double); self.report_double_vote(&double); return None @@ -2117,7 +2119,9 @@ impl Worker { cdebug!(ENGINE, "Commit message-{} is verified", commit_height); for vote in votes { if !self.votes.is_old_or_known(&vote) { - self.votes.collect(vote); + if let Err(double_vote) = self.votes.collect(vote) { + cerror!(ENGINE, "Double vote found on_commit_message: {:?}", double_vote); + } } } From c113048700b06b3cea73e27ccd39d4f602e94c8c Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Mon, 30 Sep 2019 19:07:32 +0900 Subject: [PATCH 039/105] Fix assertions to clarify the intention --- .../tendermint/vote_regression_checker.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/core/src/consensus/tendermint/vote_regression_checker.rs b/core/src/consensus/tendermint/vote_regression_checker.rs index fc37907afa..5538c9ea45 100644 --- a/core/src/consensus/tendermint/vote_regression_checker.rs +++ b/core/src/consensus/tendermint/vote_regression_checker.rs @@ -13,10 +13,13 @@ impl VoteRegressionChecker { } pub fn check(&mut self, vote_on: &VoteOn) -> bool { - assert!(match vote_on.step.step { - Step::Propose | Step::Prevote | Step::Precommit => true, - _ => false, - }); + assert!( + match vote_on.step.step { + Step::Propose | Step::Prevote | Step::Precommit => true, + _ => false, + }, + "We don't vote on Commit. Check your code" + ); let monotonic = if let Some(last_vote) = &self.last_vote { match last_vote.step.cmp(&vote_on.step) { @@ -55,15 +58,15 @@ mod tests { #[test] #[should_panic] - fn test_disallow_commit() { + fn test_panic_on_commit() { let mut checker = VoteRegressionChecker::new(); let random_commit_step = VoteStep::new(100, 10, Step::Commit); let random_hash = Some(H256::random()); - assert!(checker.check(&VoteOn { + checker.check(&VoteOn { step: random_commit_step, - block_hash: random_hash - })) + block_hash: random_hash, + }); } #[test] From 7a879360e416cb82924ac572b7bcf0213d5cb6f6 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 2 Oct 2019 19:31:44 +0900 Subject: [PATCH 040/105] Enable IPC in production build --- codechain/config/presets/config.prod.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codechain/config/presets/config.prod.toml b/codechain/config/presets/config.prod.toml index cccebbf7b9..b67e2746bb 100644 --- a/codechain/config/presets/config.prod.toml +++ b/codechain/config/presets/config.prod.toml @@ -40,7 +40,7 @@ interface = "127.0.0.1" port = 8080 [ipc] -disable = true +disable = false path = "/tmp/jsonrpc.ipc" [ws] From 8d04a9116e1a65f7bc11e1a719e0f681172bc5da Mon Sep 17 00:00:00 2001 From: Seulgi Kim Date: Mon, 7 Oct 2019 13:42:04 +0900 Subject: [PATCH 041/105] Merge pull request #1803 from sgkim126/crypto Extract the crypto module to a new repository --- Cargo.lock | 32 +++--- Cargo.toml | 2 +- core/Cargo.toml | 2 +- crypto/Cargo.toml | 13 --- crypto/src/aes.rs | 148 ------------------------ crypto/src/blake.rs | 186 ------------------------------- crypto/src/error.rs | 83 -------------- crypto/src/hash.rs | 99 ---------------- crypto/src/lib.rs | 63 ----------- crypto/src/password.rs | 27 ----- crypto/src/pbkdf2.rs | 30 ----- crypto/src/scrypt.rs | 40 ------- discovery/Cargo.toml | 2 +- key/Cargo.toml | 2 +- keystore/Cargo.toml | 2 +- network/Cargo.toml | 2 +- rpc/Cargo.toml | 2 +- state/Cargo.toml | 2 +- stratum/Cargo.toml | 2 +- types/Cargo.toml | 2 +- util/journaldb/Cargo.toml | 2 +- util/memorydb/Cargo.toml | 2 +- util/merkle/Cargo.toml | 2 +- util/trie-standardmap/Cargo.toml | 2 +- vm/Cargo.toml | 2 +- 25 files changed, 32 insertions(+), 719 deletions(-) delete mode 100644 crypto/Cargo.toml delete mode 100644 crypto/src/aes.rs delete mode 100644 crypto/src/blake.rs delete mode 100644 crypto/src/error.rs delete mode 100644 crypto/src/hash.rs delete mode 100644 crypto/src/lib.rs delete mode 100644 crypto/src/password.rs delete mode 100644 crypto/src/pbkdf2.rs delete mode 100644 crypto/src/scrypt.rs diff --git a/Cargo.lock b/Cargo.lock index 3c49355157..2de29f4633 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -232,6 +232,7 @@ dependencies = [ "cidr 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "codechain-core 0.1.0", + "codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)", "codechain-discovery 0.1.0", "codechain-key 0.1.0", "codechain-keystore 0.1.0", @@ -271,7 +272,7 @@ dependencies = [ name = "codechain-core" version = "0.1.0" dependencies = [ - "codechain-crypto 0.1.0", + "codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)", "codechain-io 1.9.0", "codechain-json 0.1.0", "codechain-key 0.1.0", @@ -312,10 +313,10 @@ dependencies = [ [[package]] name = "codechain-crypto" version = "0.1.0" +source = "git+https://github.com/CodeChain-io/rust-codechain-crypto.git#2857470de2f5480b7d61ff57fb652f9d9fc5585b" dependencies = [ "primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -324,7 +325,7 @@ dependencies = [ name = "codechain-discovery" version = "0.1.0" dependencies = [ - "codechain-crypto 0.1.0", + "codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)", "codechain-key 0.1.0", "codechain-logger 0.1.0", "codechain-network 0.1.0", @@ -367,7 +368,7 @@ name = "codechain-key" version = "0.1.0" dependencies = [ "bech32 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "codechain-crypto 0.1.0", + "codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "never-type 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -387,7 +388,7 @@ dependencies = [ name = "codechain-keystore" version = "0.1.0" dependencies = [ - "codechain-crypto 0.1.0", + "codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)", "codechain-json 0.1.0", "codechain-key 0.1.0", "codechain-types 0.1.0", @@ -427,7 +428,7 @@ dependencies = [ name = "codechain-merkle" version = "0.1.0" dependencies = [ - "codechain-crypto 0.1.0", + "codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)", "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1", "memorydb 0.1.1", @@ -442,7 +443,7 @@ name = "codechain-network" version = "0.1.0" dependencies = [ "cidr 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "codechain-crypto 0.1.0", + "codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)", "codechain-io 1.9.0", "codechain-key 0.1.0", "codechain-logger 0.1.0", @@ -469,7 +470,7 @@ version = "0.1.0" dependencies = [ "cidr 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "codechain-core 0.1.0", - "codechain-crypto 0.1.0", + "codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)", "codechain-json 0.1.0", "codechain-key 0.1.0", "codechain-keystore 0.1.0", @@ -505,7 +506,7 @@ dependencies = [ name = "codechain-state" version = "0.1.0" dependencies = [ - "codechain-crypto 0.1.0", + "codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)", "codechain-key 0.1.0", "codechain-logger 0.1.0", "codechain-merkle 0.1.0", @@ -529,7 +530,7 @@ dependencies = [ name = "codechain-stratum" version = "1.11.0" dependencies = [ - "codechain-crypto 0.1.0", + "codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)", "codechain-json 0.1.0", "codechain-logger 0.1.0", "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -586,7 +587,7 @@ dependencies = [ name = "codechain-types" version = "0.1.0" dependencies = [ - "codechain-crypto 0.1.0", + "codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)", "codechain-json 0.1.0", "codechain-key 0.1.0", "primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)", @@ -601,7 +602,7 @@ dependencies = [ name = "codechain-vm" version = "0.1.0" dependencies = [ - "codechain-crypto 0.1.0", + "codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)", "codechain-key 0.1.0", "codechain-types 0.1.0", "primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)", @@ -1227,7 +1228,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "journaldb" version = "0.1.0" dependencies = [ - "codechain-crypto 0.1.0", + "codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)", "hashdb 0.1.1", "kvdb 0.1.0", "kvdb-memorydb 0.1.0", @@ -1501,7 +1502,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "memorydb" version = "0.1.1" dependencies = [ - "codechain-crypto 0.1.0", + "codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)", "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1", "plain_hasher 0.1.0", @@ -2814,7 +2815,7 @@ dependencies = [ name = "trie-standardmap" version = "0.1.0" dependencies = [ - "codechain-crypto 0.1.0", + "codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)", "primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)", "rlp 0.2.1", ] @@ -3097,6 +3098,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum clippy 0.0.198 (registry+https://github.com/rust-lang/crates.io-index)" = "da3a62431bbcebe5250a1235e022cc61bcc2f32405d8dc08da4011d223c6a4ba" "checksum clippy_lints 0.0.198 (registry+https://github.com/rust-lang/crates.io-index)" = "9517a4eee5daa6eaf318a5bd7a4db0bcd5d92e8d8f22c3e341e60cf1746c73a4" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)" = "" "checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc" "checksum cookie 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d53b80dde876f47f03cda35303e368a79b91c70b0d65ecba5fd5280944a08591" "checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" diff --git a/Cargo.toml b/Cargo.toml index e1627acdb8..29d41a3ed9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ exclude = [ app_dirs = "^1.2.1" clap = { version = "2", features = ["yaml"] } codechain-core = { path = "core" } +codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" } codechain-discovery = { path = "discovery" } codechain-logger = { path = "util/logger" } codechain-key = { path = "key" } @@ -64,7 +65,6 @@ lto = true [workspace] members = [ "core", - "crypto", "discovery", "json", "key", diff --git a/core/Cargo.toml b/core/Cargo.toml index cfcff63a5a..00988ddb10 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" authors = ["CodeChain Team "] [dependencies] -codechain-crypto = { path = "../crypto" } +codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" } codechain-io = { path = "../util/io" } codechain-json = { path = "../json" } codechain-key = { path = "../key" } diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml deleted file mode 100644 index d16761d96c..0000000000 --- a/crypto/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "codechain-crypto" -version = "0.1.0" -authors = ["CodeChain Team "] - -[dependencies] -ring = "0.14.6" -quick-error = "1.2" -rust-crypto = "0.2.36" -primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.git", version = "0.4" } - -[dev-dependencies] -rand = "0.6.1" diff --git a/crypto/src/aes.rs b/crypto/src/aes.rs deleted file mode 100644 index ac74b16b7a..0000000000 --- a/crypto/src/aes.rs +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2018-2019 Kodebox, Inc. -// This file is part of CodeChain. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -use error::SymmError; -use primitives::H256; -use rcrypto::aes::KeySize::KeySize256; -use rcrypto::aes::{cbc_decryptor, cbc_encryptor}; -use rcrypto::aessafe::AesSafe128Encryptor; -use rcrypto::blockmodes::{CtrMode, PkcsPadding}; -use rcrypto::buffer::{BufferResult, ReadBuffer, RefReadBuffer, RefWriteBuffer, WriteBuffer}; -pub use rcrypto::symmetriccipher::SymmetricCipherError; -use rcrypto::symmetriccipher::{Decryptor, Encryptor}; - -fn is_underflow(result: BufferResult) -> bool { - match result { - BufferResult::BufferUnderflow => true, - BufferResult::BufferOverflow => false, - } -} - -// AES-256/CBC/Pkcs encryption. -pub fn encrypt(data: &[u8], key: &H256, iv: &u128) -> Result, SymmetricCipherError> { - let mut encryptor = cbc_encryptor(KeySize256, key, &iv.to_be_bytes(), PkcsPadding); - - let mut final_result = Vec::::new(); - let mut read_buffer = RefReadBuffer::new(data); - let mut buffer = [0; 4096]; - let mut write_buffer = RefWriteBuffer::new(&mut buffer); - - - let mut finish = false; - while !finish { - finish = is_underflow(encryptor.encrypt(&mut read_buffer, &mut write_buffer, true)?); - final_result.extend(write_buffer.take_read_buffer().take_remaining().iter().cloned()); - } - - Ok(final_result) -} - -// AES-256/CBC/Pkcs decryption. -pub fn decrypt(encrypted_data: &[u8], key: &H256, iv: &u128) -> Result, SymmetricCipherError> { - let mut decryptor = cbc_decryptor(KeySize256, key, &iv.to_be_bytes(), PkcsPadding); - - let mut final_result = Vec::::new(); - let mut read_buffer = RefReadBuffer::new(encrypted_data); - let mut buffer = [0; 4096]; - let mut write_buffer = RefWriteBuffer::new(&mut buffer); - - let mut finish = false; - while !finish { - finish = is_underflow(decryptor.decrypt(&mut read_buffer, &mut write_buffer, true)?); - final_result.extend(write_buffer.take_read_buffer().take_remaining().iter().cloned()); - } - - Ok(final_result) -} - -/// Encrypt a message (CTR mode). -/// -/// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each. -/// An error is returned if the input lengths are invalid. -pub fn encrypt_128_ctr(k: &[u8], iv: &[u8], plain: &[u8], dest: &mut [u8]) -> Result<(), SymmError> { - let mut encryptor = CtrMode::new(AesSafe128Encryptor::new(k), iv.to_vec()); - encryptor.encrypt(&mut RefReadBuffer::new(plain), &mut RefWriteBuffer::new(dest), true)?; - Ok(()) -} - -/// Decrypt a message (CTR mode). -/// -/// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each. -/// An error is returned if the input lengths are invalid. -pub fn decrypt_128_ctr(k: &[u8], iv: &[u8], encrypted: &[u8], dest: &mut [u8]) -> Result<(), SymmError> { - let mut encryptor = CtrMode::new(AesSafe128Encryptor::new(k), iv.to_vec()); - encryptor.decrypt(&mut RefReadBuffer::new(encrypted), &mut RefWriteBuffer::new(dest), true)?; - Ok(()) -} - -#[cfg(test)] -mod tests { - use super::*; - - use rand::rngs::OsRng; - use rand::Rng; - use rand::RngCore; - - #[test] - fn aes256_with_random_key_and_iv() { - let message = "0123456789abcdefghijklmnopqrstubewxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\ - 0123456789abcdefghijklmnopqrstubewxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\ - 0123456789abcdefghijklmnopqrstubewxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\ - 0123456789abcdefghijklmnopqrstubewxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\ - 0123456789abcdefghijklmnopqrstubewxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\ - 0123456789abcdefghijklmnopqrstubewxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\ - 0123456789abcdefghijklmnopqrstubewxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\ - 0123456789abcdefghijklmnopqrstubewxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\ - 0123456789abcdefghijklmnopqrstubewxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\ - 0123456789abcdefghijklmnopqrstubewxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\ - 0123456789abcdefghijklmnopqrstubewxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\ - 0123456789abcdefghijklmnopqrstubewxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\ - 0123456789abcdefghijklmnopqrstubewxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\ - 0123456789abcdefghijklmnopqrstubewxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - let mut key = H256([0; 32]); - - // In a real program, the key and iv may be determined - // using some other mechanism. If a password is to be used - // as a key, an algorithm like PBKDF2, Bcrypt, or Scrypt (all - // supported by Rust-Crypto!) would be a good choice to derive - // a password. For the purposes of this example, the key and - // iv are just random values. - let mut rng = OsRng::new().ok().unwrap(); - rng.fill_bytes(&mut key); - let iv = rng.gen(); - - let encrypted_data = encrypt(message.as_bytes(), &key, &iv).ok().unwrap(); - let decrypted_data = decrypt(&encrypted_data[..], &key, &iv).ok().unwrap(); - - assert_eq!(message.as_bytes(), &decrypted_data[..]); - } - - #[test] - fn short_input() { - let input = vec![130, 39, 16]; - - let mut key = H256([0; 32]); - - let mut rng = OsRng::new().unwrap(); - rng.fill_bytes(&mut key); - let iv = rng.gen(); - - let encrypted = encrypt(&input, &key, &iv).unwrap(); - let decrypted = decrypt(&encrypted, &key, &iv).unwrap(); - assert_eq!(input, decrypted); - } -} diff --git a/crypto/src/blake.rs b/crypto/src/blake.rs deleted file mode 100644 index 27324fc455..0000000000 --- a/crypto/src/blake.rs +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2018 Kodebox, Inc. -// This file is part of CodeChain. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -use primitives::{H128, H160, H256, H512}; -use rcrypto::blake2b::Blake2b; -use rcrypto::digest::Digest; - -/// BLAKE128 -pub fn blake128>(s: T) -> H128 { - H128::blake(s) -} - -pub fn blake128_with_key>(s: T, key: &[u8]) -> H128 { - H128::blake_with_key(s, key) -} - -/// BLAKE256 -pub fn blake256>(s: T) -> H256 { - H256::blake(s) -} - -pub fn blake256_with_key>(s: T, key: &[u8]) -> H256 { - H256::blake_with_key(s, key) -} - -/// BLAKE512 -pub fn blake512>(s: T) -> H512 { - H512::blake(s) -} - -pub fn blake512_with_key>(s: T, key: &[u8]) -> H512 { - H512::blake_with_key(s, key) -} - -pub trait Blake { - fn blake>(s: T) -> Self; - fn blake_with_key>(s: T, key: &[u8]) -> Self; -} - -macro_rules! implement_blake { - ($self:ident) => { - impl Blake for $self { - fn blake>(s: T) -> Self { - let input = s.as_ref(); - let mut result = Self::default(); - let mut hasher = Blake2b::new(result.len()); - hasher.input(input); - hasher.result(&mut *result); - result - } - fn blake_with_key>(s: T, key: &[u8]) -> Self { - let input = s.as_ref(); - let mut result = Self::default(); - let mut hasher = Blake2b::new_keyed(result.len(), &key); - hasher.input(input); - hasher.result(&mut *result); - result - } - } - }; -} - -implement_blake!(H128); -implement_blake!(H160); -implement_blake!(H256); -implement_blake!(H512); - -/// Get the 256-bits BLAKE2b hash of the empty bytes string. -pub const BLAKE_EMPTY: H256 = H256([ - 0x0e, 0x57, 0x51, 0xc0, 0x26, 0xe5, 0x43, 0xb2, 0xe8, 0xab, 0x2e, 0xb0, 0x60, 0x99, 0xda, 0xa1, 0xd1, 0xe5, 0xdf, - 0x47, 0x77, 0x8f, 0x77, 0x87, 0xfa, 0xab, 0x45, 0xcd, 0xf1, 0x2f, 0xe3, 0xa8, -]); - -/// Get the 256-bits BLAKE2b hash of the RLP encoding of empty data. -pub const BLAKE_NULL_RLP: H256 = H256([ - 0x45, 0xb0, 0xcf, 0xc2, 0x20, 0xce, 0xec, 0x5b, 0x7c, 0x1c, 0x62, 0xc4, 0xd4, 0x19, 0x3d, 0x38, 0xe4, 0xeb, 0xa4, - 0x8e, 0x88, 0x15, 0x72, 0x9c, 0xe7, 0x5f, 0x9c, 0x0a, 0xb0, 0xe4, 0xc1, 0xc0, -]); - -/// Get the 256-bits BLAKE2b hash of the RLP encoding of empty list. -pub const BLAKE_EMPTY_LIST_RLP: H256 = H256([ - 0xda, 0x22, 0x3b, 0x09, 0x96, 0x7c, 0x5b, 0xd2, 0x11, 0x07, 0x43, 0x30, 0x7e, 0x0a, 0xf6, 0xd3, 0x9f, 0x61, 0x72, - 0x0a, 0xa7, 0x21, 0x8a, 0x64, 0x0a, 0x08, 0xee, 0xd1, 0x2d, 0xd5, 0x75, 0xc7, -]); - -#[cfg(test)] -mod tests { - use std::panic::catch_unwind; - - use super::*; - - #[test] - fn _blake128() { - let result = H128::blake(b"hello"); - assert_eq!(H128::from("46fb7408d4f285228f4af516ea25851b"), result); - } - - #[test] - fn _blake256() { - let expected = "324dcf027dd4a30a932c441f365a25e86b173defa4b8e58948253471b81b72cf".into(); - let result = blake256(b"hello"); - assert_eq!(result, expected); - } - - #[test] - fn _blake512() { - let expected = "e4cfa39a3d37be31c59609e807970799caa68a19bfaa15135f165085e01d41a65ba1e1b146aeb6bd0092b49eac214c103ccfa3a365954bbbe52f74a2b3620c94".into(); - let result = blake512(b"hello"); - assert_eq!(result, expected); - } - - #[test] - fn blake_empty() { - let expected = BLAKE_EMPTY; - let result = blake256([0u8; 0]); - assert_eq!(result, expected); - } - - #[test] - fn blake_null_rlp() { - let expected = BLAKE_NULL_RLP; - let result = blake256([0x80]); - assert_eq!(result, expected); - } - - #[test] - fn blake_empty_list_rlp() { - let expected = BLAKE_EMPTY_LIST_RLP; - let result = blake256([0xc0]); - assert_eq!(result, expected); - } - - #[test] - fn maximum_length_of_blake256_key_is_512() { - let _ = blake256_with_key([0u8; 0], &[0; 64]); - let must_not_fail = catch_unwind(|| blake256_with_key([0u8; 0], &[0; 64])); - assert!(must_not_fail.is_ok()); - let must_fail = catch_unwind(|| blake256_with_key([0u8; 0], &[0; 65])); - assert!(must_fail.is_err()); - } - - #[test] - fn maximum_length_of_blake512_key_is_512() { - let _ = blake256_with_key([0u8; 0], &[0; 64]); - let must_not_fail = catch_unwind(|| blake512_with_key([0u8; 0], &[0; 64])); - assert!(must_not_fail.is_ok()); - let must_fail = catch_unwind(|| blake512_with_key([0u8; 0], &[0; 65])); - assert!(must_fail.is_err()); - } - - #[test] - fn blake256_output_changes_when_key_changes() { - let r1 = blake256_with_key([0u8; 0], &[0; 64]); - let r2 = blake256_with_key([0u8; 0], &[1; 64]); - assert_ne!(r1, r2); - } - - #[test] - fn blake_trait_with_h256() { - let input = b"hello world"; - let hash_result = blake256(&input); - let trait_result = H256::blake(&input); - assert_eq!(hash_result, trait_result); - } - - #[test] - fn blake_trait_with_h512() { - let input = b"hello world"; - let hash_result = blake512(&input); - let trait_result = H512::blake(&input); - assert_eq!(hash_result, trait_result); - } -} diff --git a/crypto/src/error.rs b/crypto/src/error.rs deleted file mode 100644 index 6677c1b6da..0000000000 --- a/crypto/src/error.rs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -quick_error! { - #[derive(Debug)] - pub enum Error { - Scrypt(e: ScryptError) { - cause(e) - from() - } - Symm(e: SymmError) { - cause(e) - from() - } - ZeroIterations { - description("Iterations' value should not be zero") - } - } -} - -quick_error! { - #[derive(Debug)] - pub enum ScryptError { - // log(N) < r / 16 - InvalidN { - display("Invalid N argument of the scrypt encryption") - } - // p <= (2^31-1 * 32)/(128 * r) - InvalidP { - display("Invalid p argument of the scrypt encryption") - } - } -} - -#[allow(deprecated)] -mod errors { - use rcrypto; - use ring; - - quick_error! { - #[derive(Debug)] - pub enum SymmError wraps PrivSymmErr { - RustCrypto(e: rcrypto::symmetriccipher::SymmetricCipherError) { - display("symmetric crypto error") - from() - } - Ring(e: ring::error::Unspecified) { - display("symmetric crypto error") - cause(e) - from() - } - Offset(x: usize) { - display("offset {} greater than slice length", x) - } - } - } - - impl From for SymmError { - fn from(e: ring::error::Unspecified) -> SymmError { - SymmError(PrivSymmErr::Ring(e)) - } - } - - impl From for SymmError { - fn from(e: rcrypto::symmetriccipher::SymmetricCipherError) -> SymmError { - SymmError(PrivSymmErr::RustCrypto(e)) - } - } -} -pub use self::errors::SymmError; diff --git a/crypto/src/hash.rs b/crypto/src/hash.rs deleted file mode 100644 index f258d3db5e..0000000000 --- a/crypto/src/hash.rs +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2018 Kodebox, Inc. -// This file is part of CodeChain. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -use primitives::{H160, H256}; -use rcrypto::digest::Digest; -use rcrypto::ripemd160::Ripemd160; -use rcrypto::sha1::Sha1; -use rcrypto::sha2::Sha256; -use rcrypto::sha3::Sha3; - -/// RIPEMD160 -#[inline] -pub fn ripemd160>(s: T) -> H160 { - let input = s.as_ref(); - let mut result = H160::default(); - let mut hasher = Ripemd160::new(); - hasher.input(input); - hasher.result(&mut *result); - result -} - -/// SHA-1 -#[inline] -pub fn sha1>(s: T) -> H160 { - let input = s.as_ref(); - let mut result = H160::default(); - let mut hasher = Sha1::new(); - hasher.input(input); - hasher.result(&mut *result); - result -} - -/// SHA-256 -#[inline] -pub fn sha256>(s: T) -> H256 { - let input = s.as_ref(); - let mut result = H256::default(); - let mut hasher = Sha256::new(); - hasher.input(input); - hasher.result(&mut *result); - result -} - -/// KECCAK256 -#[inline] -pub fn keccak256>(s: T) -> H256 { - let input = s.as_ref(); - let mut result = H256::default(); - let mut hasher = Sha3::keccak256(); - hasher.input(input); - hasher.result(&mut result); - result -} - -#[cfg(test)] -mod tests { - use super::{keccak256, ripemd160, sha1, sha256}; - - #[test] - fn _ripemd160() { - let expected = "108f07b8382412612c048d07d13f814118445acd".into(); - let result = ripemd160(b"hello"); - assert_eq!(result, expected); - } - - #[test] - fn _sha1() { - let expected = "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d".into(); - let result = sha1(b"hello"); - assert_eq!(result, expected); - } - - #[test] - fn _sha256() { - let expected = "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824".into(); - let result = sha256(b"hello"); - assert_eq!(result, expected); - } - - #[test] - fn _keccak256() { - let expected = "1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8".into(); - let result = keccak256(b"hello"); - assert_eq!(result, expected); - } -} diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs deleted file mode 100644 index cc2be3158c..0000000000 --- a/crypto/src/lib.rs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2018-2019 Kodebox, Inc. -// This file is part of CodeChain. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -extern crate crypto as rcrypto; -extern crate primitives; -#[macro_use] -extern crate quick_error; -#[cfg(test)] -extern crate rand; -extern crate ring; - -pub mod aes; -mod blake; -pub mod error; -mod hash; -mod password; -pub mod pbkdf2; -pub mod scrypt; - -use std::num::NonZeroU32; - -pub use crate::error::Error; - -pub const KEY_LENGTH: usize = 32; -pub const KEY_ITERATIONS: usize = 10240; -pub const KEY_LENGTH_AES: usize = KEY_LENGTH / 2; - -pub use crate::blake::*; -pub use crate::hash::{keccak256, ripemd160, sha1, sha256}; -pub use crate::password::Password; - -// Do not move Password. It will make debugger print the password. -pub fn derive_key_iterations(password: &Password, salt: &[u8; 32], c: NonZeroU32) -> (Vec, Vec) { - let mut derived_key = [0u8; KEY_LENGTH]; - pbkdf2::sha256(c, &pbkdf2::Salt(salt), &pbkdf2::Secret(password.as_bytes()), &mut derived_key); - let derived_right_bits = &derived_key[0..KEY_LENGTH_AES]; - let derived_left_bits = &derived_key[KEY_LENGTH_AES..KEY_LENGTH]; - (derived_right_bits.to_vec(), derived_left_bits.to_vec()) -} - -pub fn derive_mac(derived_left_bits: &[u8], cipher_text: &[u8]) -> Vec { - let mut mac = vec![0u8; KEY_LENGTH_AES + cipher_text.len()]; - mac[0..KEY_LENGTH_AES].copy_from_slice(derived_left_bits); - mac[KEY_LENGTH_AES..cipher_text.len() + KEY_LENGTH_AES].copy_from_slice(cipher_text); - mac -} - -pub fn is_equal(a: &[u8], b: &[u8]) -> bool { - ring::constant_time::verify_slices_are_equal(a, b).is_ok() -} diff --git a/crypto/src/password.rs b/crypto/src/password.rs deleted file mode 100644 index b20d37a63a..0000000000 --- a/crypto/src/password.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2019 Kodebox, Inc. -// This file is part of CodeChain. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -use std::ops::Deref; - -pub struct Password<'a>(pub &'a str); - -impl<'a> Deref for Password<'a> { - type Target = str; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} diff --git a/crypto/src/pbkdf2.rs b/crypto/src/pbkdf2.rs deleted file mode 100644 index 71b1aec277..0000000000 --- a/crypto/src/pbkdf2.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -use std::num::NonZeroU32; - -use ring; - -pub struct Salt<'a>(pub &'a [u8]); -pub struct Secret<'a>(pub &'a [u8]); - -pub fn sha256(iter: NonZeroU32, salt: &Salt, sec: &Secret, out: &mut [u8; 32]) { - ring::pbkdf2::derive(&ring::digest::SHA256, iter, salt.0, sec.0, &mut out[..]) -} - -pub fn sha512(iter: NonZeroU32, salt: &Salt, sec: &Secret, out: &mut [u8; 64]) { - ring::pbkdf2::derive(&ring::digest::SHA512, iter, salt.0, sec.0, &mut out[..]) -} diff --git a/crypto/src/scrypt.rs b/crypto/src/scrypt.rs deleted file mode 100644 index 333f8b4c41..0000000000 --- a/crypto/src/scrypt.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -use rcrypto::scrypt::{scrypt, ScryptParams}; - -use crate::error::ScryptError; -use crate::{Password, KEY_LENGTH, KEY_LENGTH_AES}; - -// Do not move Password. It will make debugger print the password. -pub fn derive_key(pass: &Password, salt: &[u8; 32], n: u32, p: u32, r: u32) -> Result<(Vec, Vec), ScryptError> { - // sanity checks - let log_n = (32 - n.leading_zeros() - 1) as u8; - if u32::from(log_n) >= r * 16 { - return Err(ScryptError::InvalidN) - } - - if u64::from(p) > ((u64::from(u32::max_value()) - 1) * 32) / (128 * u64::from(r)) { - return Err(ScryptError::InvalidP) - } - - let mut derived_key = vec![0u8; KEY_LENGTH]; - let scrypt_params = ScryptParams::new(log_n, r, p); - scrypt(pass.as_bytes(), salt, &scrypt_params, &mut derived_key); - let derived_right_bits = &derived_key[0..KEY_LENGTH_AES]; - let derived_left_bits = &derived_key[KEY_LENGTH_AES..KEY_LENGTH]; - Ok((derived_right_bits.to_vec(), derived_left_bits.to_vec())) -} diff --git a/discovery/Cargo.toml b/discovery/Cargo.toml index 3c02527478..75152d0445 100644 --- a/discovery/Cargo.toml +++ b/discovery/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" authors = ["CodeChain Team "] [dependencies] -codechain-crypto = { path = "../crypto" } +codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" } codechain-key = { path = "../key" } codechain-logger = { path = "../util/logger" } codechain-network = { path = "../network" } diff --git a/key/Cargo.toml b/key/Cargo.toml index a4a5f8d216..9ee276691f 100644 --- a/key/Cargo.toml +++ b/key/Cargo.toml @@ -9,7 +9,7 @@ rustc-hex = "1.0" rustc-serialize = "0.3" lazy_static = "1.2" bech32 = "0.2.2" -codechain-crypto = { path = "../crypto" } +codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" } never-type = "0.1.0" parking_lot = "0.6.0" primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.git", version = "0.4" } diff --git a/keystore/Cargo.toml b/keystore/Cargo.toml index 5ffe2db17d..20aa62ae9a 100644 --- a/keystore/Cargo.toml +++ b/keystore/Cargo.toml @@ -16,7 +16,7 @@ serde_derive = "1.0" rustc-hex = "1.0" time = "0.1.34" parking_lot = "0.6.0" -codechain-crypto = { path = "../crypto" } +codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" } smallvec = "0.4" tempdir = "0.3" diff --git a/network/Cargo.toml b/network/Cargo.toml index 8bcd319e56..9e6ff4308b 100644 --- a/network/Cargo.toml +++ b/network/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" authors = ["CodeChain Team "] [dependencies] -codechain-crypto = { path = "../crypto" } +codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" } codechain-io = { path = "../util/io" } codechain-key = { path = "../key" } codechain-logger = { path = "../util/logger" } diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index b48638f844..181aaddd46 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -8,7 +8,7 @@ authors = ["CodeChain Team "] [dependencies] cidr = "0.0.4" codechain-core = { path = "../core" } -codechain-crypto = { path = "../crypto" } +codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" } codechain-json = { path = "../json" } codechain-key = { path = "../key" } codechain-keystore = { path = "../keystore" } diff --git a/state/Cargo.toml b/state/Cargo.toml index 483efd1285..3ba24b3a17 100644 --- a/state/Cargo.toml +++ b/state/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" authors = ["CodeChain Team "] [dependencies] -codechain-crypto = { path = "../crypto" } +codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" } codechain-logger = { path = "../util/logger" } codechain-merkle = { path = "../util/merkle" } codechain-key = { path = "../key" } diff --git a/stratum/Cargo.toml b/stratum/Cargo.toml index 93e6feb582..7840f2cabb 100644 --- a/stratum/Cargo.toml +++ b/stratum/Cargo.toml @@ -6,7 +6,7 @@ license = "GPL-3.0" authors = ["Parity Technologies ", "CodeChain Team "] [dependencies] -codechain-crypto = { path = "../crypto" } +codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" } codechain-logger = { path = "../util/logger" } codechain-json = { path = "../json" } jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } diff --git a/types/Cargo.toml b/types/Cargo.toml index 911c3d0fe0..379558ca39 100644 --- a/types/Cargo.toml +++ b/types/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" authors = ["CodeChain Team "] [dependencies] -codechain-crypto = { path = "../crypto" } +codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" } codechain-json = { path = "../json" } codechain-key = { path = "../key" } primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.git", version = "0.4" } diff --git a/util/journaldb/Cargo.toml b/util/journaldb/Cargo.toml index 563e7756aa..1b4ac31d4f 100644 --- a/util/journaldb/Cargo.toml +++ b/util/journaldb/Cargo.toml @@ -14,5 +14,5 @@ rlp = { path = "../rlp" } util-error = { path = "../error" } [dev-dependencies] -codechain-crypto = { path = "../../crypto" } +codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" } kvdb-memorydb = { path = "../kvdb-memorydb" } diff --git a/util/memorydb/Cargo.toml b/util/memorydb/Cargo.toml index 457813e6bf..ea800266c2 100644 --- a/util/memorydb/Cargo.toml +++ b/util/memorydb/Cargo.toml @@ -7,7 +7,7 @@ license = "GPL-3.0" [dependencies] elastic-array = "0.10" -codechain-crypto = { version = "0.1.0", path = "../../crypto" } +codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" } hashdb = { version = "0.1.1", path = "../hashdb" } plain_hasher = { path = "../plain_hasher" } primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.git", version = "0.4" } diff --git a/util/merkle/Cargo.toml b/util/merkle/Cargo.toml index 112658681c..4cf53e157a 100644 --- a/util/merkle/Cargo.toml +++ b/util/merkle/Cargo.toml @@ -7,7 +7,7 @@ authors = ["CodeChain Team "] elastic-array = "0.10" rand = "0.6.1" hashdb = {path = "../hashdb" } -codechain-crypto = { path = "../../crypto" } +codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" } primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.git", version = "0.4" } rlp = {path = "../rlp" } diff --git a/util/trie-standardmap/Cargo.toml b/util/trie-standardmap/Cargo.toml index c3d2cb0e39..495f7fc6b4 100644 --- a/util/trie-standardmap/Cargo.toml +++ b/util/trie-standardmap/Cargo.toml @@ -5,6 +5,6 @@ authors = ["debris ", "CodeChain Team "] [lib] [dependencies] -codechain-crypto = { path = "../crypto" } +codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" } codechain-key = { path = "../key" } codechain-types = { path = "../types" } primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.git", version = "0.4" } From c617d862ba1bb79df88d64c0f605751b91a2d0e8 Mon Sep 17 00:00:00 2001 From: Seulgi Kim Date: Mon, 7 Oct 2019 10:20:16 +0900 Subject: [PATCH 042/105] Use rust 1.37.0 --- .travis.yml | 2 +- rust-toolchain | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 89ecc447c1..e377307b98 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: rust rust: - - 1.36.0 + - 1.37.0 stages: - name: test if: branch != docker-build diff --git a/rust-toolchain b/rust-toolchain index 39fc130ef8..bf50e910e6 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.36.0 +1.37.0 From 31a7d522f65b02b208a35c0e1484145ae9d3d968 Mon Sep 17 00:00:00 2001 From: Seulgi Kim Date: Mon, 7 Oct 2019 11:07:11 +0900 Subject: [PATCH 043/105] trait objects without an explicit `dyn` are deprecated --- codechain/rpc_apis.rs | 2 +- codechain/run_node.rs | 12 ++++----- core/src/block.rs | 18 ++++++++----- core/src/blockchain/blockchain.rs | 8 +++--- core/src/blockchain/body_db.rs | 8 +++--- core/src/blockchain/headerchain.rs | 10 +++---- core/src/blockchain/invoice_db.rs | 4 +-- core/src/blockchain/route.rs | 2 +- core/src/client/client.rs | 26 +++++++++---------- core/src/client/importer.rs | 6 ++--- core/src/client/mod.rs | 12 ++++----- core/src/client/test_client.rs | 4 +-- core/src/consensus/mod.rs | 8 +++--- core/src/consensus/simple_poa/mod.rs | 6 ++--- core/src/consensus/solo/mod.rs | 6 ++--- core/src/consensus/stake/actions.rs | 6 ++--- core/src/consensus/stake/mod.rs | 10 +++---- core/src/consensus/tendermint/backup.rs | 4 +-- core/src/consensus/tendermint/engine.rs | 12 ++++----- core/src/consensus/tendermint/mod.rs | 14 +++++----- core/src/consensus/tendermint/network.rs | 4 +-- core/src/consensus/tendermint/worker.rs | 16 ++++++------ .../validator_set/dynamic_validator.rs | 8 +++--- core/src/consensus/validator_set/mod.rs | 2 +- .../consensus/validator_set/validator_list.rs | 6 ++--- core/src/db.rs | 22 ++++++++-------- core/src/miner/backup.rs | 2 +- core/src/miner/mem_pool.rs | 4 +-- core/src/miner/miner.rs | 20 +++++++------- core/src/scheme/scheme.rs | 6 ++--- core/src/service.rs | 2 +- core/src/verification/canon_verifier.rs | 4 +-- core/src/verification/mod.rs | 2 +- core/src/verification/noop_verifier.rs | 4 +-- core/src/verification/queue/kind.rs | 20 +++++++++----- core/src/verification/queue/mod.rs | 6 ++--- core/src/verification/verification.rs | 10 +++---- core/src/verification/verifier.rs | 4 +-- discovery/src/extension.rs | 4 +-- keystore/src/import.rs | 4 +-- keystore/src/keystore.rs | 12 ++++----- keystore/src/secret_store.rs | 2 +- network/src/client.rs | 2 +- network/src/p2p/handler.rs | 4 +-- network/src/service.rs | 6 ++--- rpc/src/v1/impls/devel.rs | 2 +- rpc/src/v1/impls/net.rs | 4 +-- state/src/action_handler/mod.rs | 2 +- state/src/cache/shard_cache.rs | 2 +- state/src/cache/top_cache.rs | 2 +- state/src/cache/write_back.rs | 2 +- state/src/db/state_db.rs | 8 +++--- state/src/impls/shard_level.rs | 4 +-- state/src/impls/top_level.rs | 4 +-- state/src/tests.rs | 2 +- state/src/traits.rs | 2 +- stratum/src/lib.rs | 4 +-- sync/src/block/downloader/header.rs | 4 +-- sync/src/block/extension.rs | 4 +-- sync/src/snapshot/snapshot.rs | 18 ++++++------- sync/src/transaction/extension.rs | 6 ++--- util/hashdb/src/lib.rs | 14 +++++----- util/io/src/service.rs | 4 +-- util/io/src/worker.rs | 2 +- util/journaldb/src/archivedb.rs | 8 +++--- util/journaldb/src/lib.rs | 2 +- util/journaldb/src/traits.rs | 4 +-- util/kvdb/src/lib.rs | 2 +- util/merkle/src/lib.rs | 6 ++--- util/merkle/src/triedb.rs | 6 ++--- util/merkle/src/triedbmut.rs | 8 +++--- util/rlp_compress/src/lib.rs | 4 +-- util/secp256k1/src/lib.rs | 2 +- util/timer/src/timer.rs | 6 ++--- vm/src/executor.rs | 2 +- 75 files changed, 253 insertions(+), 241 deletions(-) diff --git a/codechain/rpc_apis.rs b/codechain/rpc_apis.rs index ab8eec6ad5..3f4d3c016a 100644 --- a/codechain/rpc_apis.rs +++ b/codechain/rpc_apis.rs @@ -25,7 +25,7 @@ use csync::BlockSyncEvent; pub struct ApiDependencies { pub client: Arc, pub miner: Arc, - pub network_control: Arc, + pub network_control: Arc, pub account_provider: Arc, pub block_sync: Option>, } diff --git a/codechain/run_node.rs b/codechain/run_node.rs index b3003f8938..5ec7eb7c02 100644 --- a/codechain/run_node.rs +++ b/codechain/run_node.rs @@ -91,7 +91,7 @@ fn discovery_start( fn client_start( client_config: &ClientConfig, timer_loop: &TimerLoop, - db: Arc, + db: Arc, scheme: &Scheme, miner: Arc, ) -> Result { @@ -122,7 +122,7 @@ fn new_miner( config: &config::Config, scheme: &Scheme, ap: Arc, - db: Arc, + db: Arc, ) -> Result, String> { let miner = Miner::new(config.miner_options()?, scheme, Some(ap), db); @@ -204,7 +204,7 @@ fn unlock_accounts(ap: &AccountProvider, pf: &PasswordFile) -> Result<(), String Ok(()) } -pub fn open_db(cfg: &config::Operating, client_config: &ClientConfig) -> Result, String> { +pub fn open_db(cfg: &config::Operating, client_config: &ClientConfig) -> Result, String> { let base_path = cfg.base_path.as_ref().unwrap().clone(); let db_path = cfg.db_path.as_ref().map(String::clone).unwrap_or_else(|| base_path + "/" + DEFAULT_DB_PATH); let client_path = Path::new(&db_path); @@ -282,7 +282,7 @@ pub fn run_node(matches: &ArgMatches) -> Result<(), String> { scheme.engine.register_chain_notify(client.client().as_ref()); - let network_service: Arc = { + let network_service: Arc = { if !config.network.disable.unwrap() { let network_config = config.network_config()?; // XXX: What should we do if the network id has been changed. @@ -303,7 +303,7 @@ pub fn run_node(matches: &ArgMatches) -> Result<(), String> { service.register_extension(move |api| BlockSyncExtension::new(client, api)) }; let sync = Arc::new(BlockSyncSender::from(sync_sender.clone())); - client.client().add_notify(Arc::downgrade(&sync) as Weak); + client.client().add_notify(Arc::downgrade(&sync) as Weak); _maybe_sync = Some(sync); // Hold sync to ensure it not to be destroyed. maybe_sync_sender = Some(sync_sender); } @@ -362,7 +362,7 @@ pub fn run_node(matches: &ArgMatches) -> Result<(), String> { let client = client.client(); let snapshot_period = client.common_params(BlockId::Latest).unwrap().snapshot_period(); let service = SnapshotService::new(Arc::clone(&client), config.snapshot.path.unwrap(), snapshot_period); - client.add_notify(Arc::downgrade(&service) as Weak); + client.add_notify(Arc::downgrade(&service) as Weak); Some(service) } else { None diff --git a/core/src/block.rs b/core/src/block.rs index 1261d075f2..6b9e218aa5 100644 --- a/core/src/block.rs +++ b/core/src/block.rs @@ -121,13 +121,13 @@ impl ExecutedBlock { /// Block that is ready for transactions to be added. pub struct OpenBlock<'x> { block: ExecutedBlock, - engine: &'x CodeChainEngine, + engine: &'x dyn CodeChainEngine, } impl<'x> OpenBlock<'x> { /// Create a new `OpenBlock` ready for transaction pushing. pub fn try_new( - engine: &'x CodeChainEngine, + engine: &'x dyn CodeChainEngine, db: StateDB, parent: &Header, author: Address, @@ -311,7 +311,7 @@ impl<'x> OpenBlock<'x> { /// Provide a valid seal /// /// NOTE: This does not check the validity of `seal` with the engine. - pub fn seal(&mut self, engine: &CodeChainEngine, seal: Vec) -> Result<(), BlockError> { + pub fn seal(&mut self, engine: &dyn CodeChainEngine, seal: Vec) -> Result<(), BlockError> { let expected_seal_fields = engine.seal_fields(self.header()); if seal.len() != expected_seal_fields { return Err(BlockError::InvalidSealArity(Mismatch { @@ -347,7 +347,7 @@ impl ClosedBlock { } /// Given an engine reference, reopen the `ClosedBlock` into an `OpenBlock`. - pub fn reopen(self, engine: &CodeChainEngine) -> OpenBlock { + pub fn reopen(self, engine: &dyn CodeChainEngine) -> OpenBlock { // revert rewards (i.e. set state back at last transaction's state). let mut block = self.block; block.state = self.unclosed_state; @@ -367,7 +367,7 @@ impl LockedBlock { /// Provide a valid seal in order to turn this into a `SealedBlock`. /// /// NOTE: This does not check the validity of `seal` with the engine. - pub fn seal(mut self, engine: &CodeChainEngine, seal: Vec) -> Result { + pub fn seal(mut self, engine: &dyn CodeChainEngine, seal: Vec) -> Result { let expected_seal_fields = engine.seal_fields(self.header()); if seal.len() != expected_seal_fields { return Err(BlockError::InvalidSealArity(Mismatch { @@ -384,7 +384,11 @@ impl LockedBlock { /// Provide a valid seal in order to turn this into a `SealedBlock`. /// This does check the validity of `seal` with the engine. /// Returns the `ClosedBlock` back again if the seal is no good. - pub fn try_seal(mut self, engine: &CodeChainEngine, seal: Vec) -> Result { + pub fn try_seal( + mut self, + engine: &dyn CodeChainEngine, + seal: Vec, + ) -> Result { self.block.header.set_seal(seal); // TODO: passing state context to avoid engines owning it? @@ -489,7 +493,7 @@ impl IsBlock for SealedBlock { pub fn enact( header: &Header, transactions: &[SignedTransaction], - engine: &CodeChainEngine, + engine: &dyn CodeChainEngine, client: &C, db: StateDB, parent: &Header, diff --git a/core/src/blockchain/blockchain.rs b/core/src/blockchain/blockchain.rs index abec2d35d9..3b55954fb3 100644 --- a/core/src/blockchain/blockchain.rs +++ b/core/src/blockchain/blockchain.rs @@ -58,7 +58,7 @@ pub struct BlockChain { impl BlockChain { /// Create new instance of blockchain from given Genesis. - pub fn new(genesis: &[u8], db: Arc) -> Self { + pub fn new(genesis: &[u8], db: Arc) -> Self { let genesis_block = BlockView::new(genesis); // load best block @@ -102,7 +102,7 @@ impl BlockChain { &self, batch: &mut DBTransaction, header: &HeaderView, - engine: &CodeChainEngine, + engine: &dyn CodeChainEngine, ) -> ImportRoute { match self.headerchain.insert_header(batch, header, engine) { Some(c) => ImportRoute::new_from_best_header_changed(header.hash(), &c), @@ -118,7 +118,7 @@ impl BlockChain { batch: &mut DBTransaction, bytes: &[u8], invoices: Vec, - engine: &CodeChainEngine, + engine: &dyn CodeChainEngine, ) -> ImportRoute { // create views onto rlp let new_block = BlockView::new(bytes); @@ -180,7 +180,7 @@ impl BlockChain { } /// Calculate how best block is changed - fn best_block_changed(&self, new_block: &BlockView, engine: &CodeChainEngine) -> BestBlockChanged { + fn best_block_changed(&self, new_block: &BlockView, engine: &dyn CodeChainEngine) -> BestBlockChanged { let new_header = new_block.header_view(); let parent_hash_of_new_block = new_header.parent_hash(); let parent_details_of_new_block = self.block_details(&parent_hash_of_new_block).expect("Invalid parent hash"); diff --git a/core/src/blockchain/body_db.rs b/core/src/blockchain/body_db.rs index 547c4c4b43..a97a591989 100644 --- a/core/src/blockchain/body_db.rs +++ b/core/src/blockchain/body_db.rs @@ -42,14 +42,14 @@ pub struct BodyDB { transaction_address_cache: Mutex>, pending_transaction_addresses: Mutex>>, - db: Arc, + db: Arc, } type TransactionHashAndAddress = (H256, TransactionAddresses); impl BodyDB { /// Create new instance of blockchain from given Genesis. - pub fn new(genesis: &BlockView, db: Arc) -> Self { + pub fn new(genesis: &BlockView, db: Arc) -> Self { let bdb = Self { body_cache: Mutex::new(LruCache::new(BODY_CACHE_SIZE)), parcel_address_cache: RwLock::new(HashMap::new()), @@ -196,8 +196,8 @@ impl BodyDB { }; let (removed, added): ( - Box>, - Box>, + Box>, + Box>, ) = match best_block_changed { BestBlockChanged::CanonChainAppended { .. diff --git a/core/src/blockchain/headerchain.rs b/core/src/blockchain/headerchain.rs index c3d78fc20e..490510f556 100644 --- a/core/src/blockchain/headerchain.rs +++ b/core/src/blockchain/headerchain.rs @@ -53,7 +53,7 @@ pub struct HeaderChain { detail_cache: RwLock>, hash_cache: Mutex>, - db: Arc, + db: Arc, pending_best_header_hash: RwLock>, pending_best_proposal_block_hash: RwLock>, @@ -63,7 +63,7 @@ pub struct HeaderChain { impl HeaderChain { /// Create new instance of blockchain from given Genesis. - pub fn new(genesis: &HeaderView, db: Arc) -> Self { + pub fn new(genesis: &HeaderView, db: Arc) -> Self { // load best header let best_header_hash = match db.get(db::COL_EXTRA, BEST_HEADER_KEY).unwrap() { Some(hash) => H256::from_slice(&hash), @@ -122,7 +122,7 @@ impl HeaderChain { &self, batch: &mut DBTransaction, header: &HeaderView, - engine: &CodeChainEngine, + engine: &dyn CodeChainEngine, ) -> Option { let hash = header.hash(); @@ -239,7 +239,7 @@ impl HeaderChain { } /// Calculate how best block is changed - fn best_header_changed(&self, new_header: &HeaderView, engine: &CodeChainEngine) -> BestHeaderChanged { + fn best_header_changed(&self, new_header: &HeaderView, engine: &dyn CodeChainEngine) -> BestHeaderChanged { let parent_hash_of_new_header = new_header.parent_hash(); let parent_details_of_new_header = self.block_details(&parent_hash_of_new_header).expect("Invalid parent hash"); let is_new_best = parent_details_of_new_header.total_score + new_header.score() @@ -403,7 +403,7 @@ impl HeaderProvider for HeaderChain { } /// Get block header data -fn block_header_data(hash: &H256, header_cache: &Mutex>, db: &KeyValueDB) -> Option> { +fn block_header_data(hash: &H256, header_cache: &Mutex>, db: &dyn KeyValueDB) -> Option> { // Check cache first { let mut lock = header_cache.lock(); diff --git a/core/src/blockchain/invoice_db.rs b/core/src/blockchain/invoice_db.rs index 9bd5a58c2e..8c14499d90 100644 --- a/core/src/blockchain/invoice_db.rs +++ b/core/src/blockchain/invoice_db.rs @@ -34,12 +34,12 @@ pub struct InvoiceDB { // transaction hash -> error hint hash_cache: RwLock>>, - db: Arc, + db: Arc, } impl InvoiceDB { /// Create new instance of blockchain from given Genesis. - pub fn new(db: Arc) -> Self { + pub fn new(db: Arc) -> Self { Self { tracker_cache: Default::default(), hash_cache: Default::default(), diff --git a/core/src/blockchain/route.rs b/core/src/blockchain/route.rs index be8cb2d63e..553680bb60 100644 --- a/core/src/blockchain/route.rs +++ b/core/src/blockchain/route.rs @@ -71,7 +71,7 @@ pub struct TreeRoute { /// /// If the tree route verges into pruned or unknown blocks, /// `None` is returned. -pub fn tree_route(db: &HeaderProvider, from: H256, to: H256) -> Option { +pub fn tree_route(db: &dyn HeaderProvider, from: H256, to: H256) -> Option { let mut retracted = vec![]; let mut enacted = vec![]; diff --git a/core/src/client/client.rs b/core/src/client/client.rs index 4c39949f3d..3117abd55f 100644 --- a/core/src/client/client.rs +++ b/core/src/client/client.rs @@ -58,19 +58,19 @@ use crate::types::{BlockId, BlockStatus, TransactionId, VerificationQueueInfo as const MAX_MEM_POOL_SIZE: usize = 4096; pub struct Client { - engine: Arc, + engine: Arc, io_channel: Mutex>, chain: RwLock, /// Client uses this to store blocks, traces, etc. - db: Arc, + db: Arc, state_db: RwLock, /// List of actors to be notified on certain chain events - notify: RwLock>>, + notify: RwLock>>, /// Count of pending transactions in the queue queue_transactions: AtomicUsize, @@ -87,7 +87,7 @@ impl Client { pub fn try_new( config: &ClientConfig, scheme: &Scheme, - db: Arc, + db: Arc, miner: Arc, message_channel: IoChannel, reseal_timer: TimerApi, @@ -133,12 +133,12 @@ impl Client { } /// Returns engine reference. - pub fn engine(&self) -> &CodeChainEngine { + pub fn engine(&self) -> &dyn CodeChainEngine { &*self.engine } /// Adds an actor to be notified on certain events - pub fn add_notify(&self, target: Weak) { + pub fn add_notify(&self, target: Weak) { self.notify.write().push(target); } @@ -194,7 +194,7 @@ impl Client { fn notify(&self, f: F) where - F: Fn(&ChainNotify), { + F: Fn(&dyn ChainNotify), { for np in self.notify.read().iter() { if let Some(n) = np.upgrade() { f(&*n); @@ -305,7 +305,7 @@ impl Client { } } - fn state_info(&self, state: StateOrBlock) -> Option> { + fn state_info(&self, state: StateOrBlock) -> Option> { Some(match state { StateOrBlock::State(state) => state, StateOrBlock::Block(id) => Box::new(self.state_at(id)?), @@ -320,7 +320,7 @@ impl Client { self.chain.read() } - pub fn db(&self) -> &Arc { + pub fn db(&self) -> &Arc { &self.db } } @@ -352,7 +352,7 @@ impl TimeoutHandler for Client { } impl DatabaseClient for Client { - fn database(&self) -> Arc { + fn database(&self) -> Arc { Arc::clone(&self.db()) } } @@ -440,7 +440,7 @@ impl ExecuteClient for Client { fn execute_vm( &self, - tx: &PartialHashing, + tx: &dyn PartialHashing, inputs: &[AssetTransferInput], params: &[Vec], indices: &[usize], @@ -581,7 +581,7 @@ impl EngineClient for Client { } } - fn get_kvdb(&self) -> Arc { + fn get_kvdb(&self) -> Arc { self.db.clone() } } @@ -905,7 +905,7 @@ impl ChainTimeInfo for Client { } impl FindActionHandler for Client { - fn find_action_handler_for(&self, id: u64) -> Option<&ActionHandler> { + fn find_action_handler_for(&self, id: u64) -> Option<&dyn ActionHandler> { self.engine.find_action_handler_for(id) } } diff --git a/core/src/client/importer.rs b/core/src/client/importer.rs index b00e992e8f..e2cca86c7a 100644 --- a/core/src/client/importer.rs +++ b/core/src/client/importer.rs @@ -44,7 +44,7 @@ pub struct Importer { pub import_lock: Mutex<()>, // FIXME Maybe wrap the whole `Importer` instead? /// Used to verify blocks - pub verifier: Box>, + pub verifier: Box>, /// Queue containing pending blocks pub block_queue: BlockQueue, @@ -56,13 +56,13 @@ pub struct Importer { pub miner: Arc, /// CodeChain engine to be used during import - pub engine: Arc, + pub engine: Arc, } impl Importer { pub fn try_new( config: &ClientConfig, - engine: Arc, + engine: Arc, message_channel: IoChannel, miner: Arc, ) -> Result { diff --git a/core/src/client/mod.rs b/core/src/client/mod.rs index 10ee58c47e..33594dcf4a 100644 --- a/core/src/client/mod.rs +++ b/core/src/client/mod.rs @@ -111,7 +111,7 @@ pub trait EngineClient: Sync + Send + BlockChainTrait + ImportBlock { /// Used in Tendermint, when going to the commit step. fn update_best_as_committed(&self, block_hash: H256); - fn get_kvdb(&self) -> Arc; + fn get_kvdb(&self) -> Arc; } pub trait ConsensusClient: BlockChainClient + EngineClient + EngineInfo + TermInfo + StateInfo {} @@ -164,14 +164,14 @@ pub trait AccountData { /// State information to be used during client query pub enum StateOrBlock { /// State to be used, may be pending - State(Box), + State(Box), /// Id of an existing block from a chain to get state from Block(BlockId), } -impl From> for StateOrBlock { - fn from(info: Box) -> StateOrBlock { +impl From> for StateOrBlock { + fn from(info: Box) -> StateOrBlock { StateOrBlock::State(info) } } @@ -275,7 +275,7 @@ pub trait MiningBlockChainClient: BlockChainClient + BlockProducer + FindActionH /// Provides methods to access database. pub trait DatabaseClient { - fn database(&self) -> Arc; + fn database(&self) -> Arc; } /// Provides methods to access asset @@ -303,7 +303,7 @@ pub trait ExecuteClient: ChainTimeInfo { fn execute_vm( &self, - tx: &PartialHashing, + tx: &dyn PartialHashing, inputs: &[AssetTransferInput], params: &[Vec], indices: &[usize], diff --git a/core/src/client/test_client.rs b/core/src/client/test_client.rs index c922de1856..f823758c79 100644 --- a/core/src/client/test_client.rs +++ b/core/src/client/test_client.rs @@ -136,7 +136,7 @@ impl TestBlockChainClient { } /// Create test client with custom scheme and extra data. - pub fn new_with_scheme_and_extra(scheme: Scheme, extra_data: Bytes, db: Arc) -> Self { + pub fn new_with_scheme_and_extra(scheme: Scheme, extra_data: Bytes, db: Arc) -> Self { let genesis_block = scheme.genesis_block(); let genesis_header = scheme.genesis_header(); let genesis_hash = genesis_header.hash(); @@ -614,7 +614,7 @@ impl super::EngineClient for TestBlockChainClient { fn update_best_as_committed(&self, _block_hash: H256) {} - fn get_kvdb(&self) -> Arc { + fn get_kvdb(&self) -> Arc { let db = kvdb_memorydb::create(NUM_COLUMNS.unwrap_or(0)); Arc::new(db) } diff --git a/core/src/consensus/mod.rs b/core/src/consensus/mod.rs index 9647203d52..7be9fdce92 100644 --- a/core/src/consensus/mod.rs +++ b/core/src/consensus/mod.rs @@ -233,7 +233,7 @@ pub trait ConsensusEngine: Sync + Send { } /// Add Client which can be used for sealing, potentially querying the state and sending messages. - fn register_client(&self, _client: Weak) {} + fn register_client(&self, _client: Weak) {} /// Find out if the block is a proposal block and should not be inserted into the DB. /// Takes a header of a fully verified block. @@ -254,7 +254,7 @@ pub trait ConsensusEngine: Sync + Send { fn block_reward(&self, block_number: u64) -> u64; - fn block_fee(&self, transactions: Box>) -> u64 { + fn block_fee(&self, transactions: Box>) -> u64 { transactions.map(|tx| tx.fee).sum() } @@ -270,11 +270,11 @@ pub trait ConsensusEngine: Sync + Send { true } - fn action_handlers(&self) -> &[Arc] { + fn action_handlers(&self) -> &[Arc] { &[] } - fn find_action_handler_for(&self, id: u64) -> Option<&ActionHandler> { + fn find_action_handler_for(&self, id: u64) -> Option<&dyn ActionHandler> { self.action_handlers().iter().find(|handler| handler.handler_id() == id).map(AsRef::as_ref) } diff --git a/core/src/consensus/simple_poa/mod.rs b/core/src/consensus/simple_poa/mod.rs index 6a410dbb11..d2a2633ef8 100644 --- a/core/src/consensus/simple_poa/mod.rs +++ b/core/src/consensus/simple_poa/mod.rs @@ -37,7 +37,7 @@ use crate::error::{BlockError, Error}; pub struct SimplePoA { machine: CodeChainMachine, signer: RwLock, - validators: Box, + validators: Box, /// Reward per block, in base units. block_reward: u64, } @@ -55,7 +55,7 @@ impl SimplePoA { } } -fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Error> { +fn verify_external(header: &Header, validators: &dyn ValidatorSet) -> Result<(), Error> { use rlp::UntrustedRlp; // Check if the signature belongs to a validator, can depend on parent state. @@ -130,7 +130,7 @@ impl ConsensusEngine for SimplePoA { self.machine.add_balance(block, &author, total_reward) } - fn register_client(&self, client: Weak) { + fn register_client(&self, client: Weak) { self.validators.register_client(client); } diff --git a/core/src/consensus/solo/mod.rs b/core/src/consensus/solo/mod.rs index b8c9bfd155..915e6485f9 100644 --- a/core/src/consensus/solo/mod.rs +++ b/core/src/consensus/solo/mod.rs @@ -34,13 +34,13 @@ use crate::error::Error; pub struct Solo { params: SoloParams, machine: CodeChainMachine, - action_handlers: Vec>, + action_handlers: Vec>, } impl Solo { /// Returns new instance of Solo over the given state machine. pub fn new(params: SoloParams, machine: CodeChainMachine) -> Self { - let mut action_handlers: Vec> = Vec::new(); + let mut action_handlers: Vec> = Vec::new(); if params.enable_hit_handler { action_handlers.push(Arc::new(HitHandler::new())); } @@ -135,7 +135,7 @@ impl ConsensusEngine for Solo { 1 } - fn action_handlers(&self) -> &[Arc] { + fn action_handlers(&self) -> &[Arc] { &self.action_handlers } diff --git a/core/src/consensus/stake/actions.rs b/core/src/consensus/stake/actions.rs index f96fd4d26d..013bda7180 100644 --- a/core/src/consensus/stake/actions.rs +++ b/core/src/consensus/stake/actions.rs @@ -73,8 +73,8 @@ impl Action { pub fn verify( &self, current_params: &CommonParams, - client: Option>, - validators: Option>, + client: Option>, + validators: Option>, ) -> Result<(), SyntaxError> { match self { Action::TransferCCS { @@ -456,7 +456,7 @@ mod tests { message1: Box::new(consensus_message1), message2: Box::new(consensus_message2), }; - let arced_client: Arc = Arc::new(test_client); + let arced_client: Arc = Arc::new(test_client); validator_set.register_client(Arc::downgrade(&arced_client)); action.verify(&CommonParams::default_for_test(), Some(Arc::clone(&arced_client)), Some(Arc::new(validator_set))) } diff --git a/core/src/consensus/stake/mod.rs b/core/src/consensus/stake/mod.rs index 8bd8d6d5b2..d6bb44885c 100644 --- a/core/src/consensus/stake/mod.rs +++ b/core/src/consensus/stake/mod.rs @@ -43,8 +43,8 @@ pub const CUSTOM_ACTION_HANDLER_ID: u64 = 2; pub struct Stake { genesis_stakes: HashMap, - client: RwLock>>, - validators: RwLock>>, + client: RwLock>>, + validators: RwLock>>, } impl Stake { @@ -55,7 +55,7 @@ impl Stake { validators: Default::default(), } } - pub fn register_resources(&self, client: Weak, validators: Weak) { + pub fn register_resources(&self, client: Weak, validators: Weak) { *self.client.write() = Some(Weak::clone(&client)); *self.validators.write() = Some(Weak::clone(&validators)); } @@ -151,8 +151,8 @@ impl ActionHandler for Stake { fn verify(&self, bytes: &[u8], current_params: &CommonParams) -> Result<(), SyntaxError> { let action = Action::decode(&UntrustedRlp::new(bytes)) .map_err(|err| SyntaxError::InvalidCustomAction(err.to_string()))?; - let client: Option> = self.client.read().as_ref().and_then(Weak::upgrade); - let validators: Option> = self.validators.read().as_ref().and_then(Weak::upgrade); + let client: Option> = self.client.read().as_ref().and_then(Weak::upgrade); + let validators: Option> = self.validators.read().as_ref().and_then(Weak::upgrade); action.verify(current_params, client, validators) } diff --git a/core/src/consensus/tendermint/backup.rs b/core/src/consensus/tendermint/backup.rs index 83f88973a4..bc22a664f1 100644 --- a/core/src/consensus/tendermint/backup.rs +++ b/core/src/consensus/tendermint/backup.rs @@ -40,7 +40,7 @@ pub struct BackupData { pub last_confirmed_view: View, } -pub fn backup(db: &KeyValueDB, backup_data: BackupView) { +pub fn backup(db: &dyn KeyValueDB, backup_data: BackupView) { let BackupView { height, view, @@ -58,7 +58,7 @@ pub fn backup(db: &KeyValueDB, backup_data: BackupView) { db.write(batch).expect("Low level database error. Some issue with disk?"); } -pub fn restore(db: &KeyValueDB) -> Option { +pub fn restore(db: &dyn KeyValueDB) -> Option { let value = db.get(db::COL_EXTRA, BACKUP_KEY).expect("Low level database error. Some issue with disk?"); let (height, view, step, votes, last_confirmed_view) = value.map(|bytes| { let bytes = bytes.into_vec(); diff --git a/core/src/consensus/tendermint/engine.rs b/core/src/consensus/tendermint/engine.rs index 3f13e6d693..1805caef4b 100644 --- a/core/src/consensus/tendermint/engine.rs +++ b/core/src/consensus/tendermint/engine.rs @@ -248,7 +248,7 @@ impl ConsensusEngine for Tendermint { Ok(()) } - fn register_client(&self, client: Weak) { + fn register_client(&self, client: Weak) { *self.client.write() = Some(Weak::clone(&client)); self.stake.register_resources(client, Arc::downgrade(&self.validators)); } @@ -301,7 +301,7 @@ impl ConsensusEngine for Tendermint { } fn register_chain_notify(&self, client: &Client) { - client.add_notify(Arc::downgrade(&self.chain_notify) as Weak); + client.add_notify(Arc::downgrade(&self.chain_notify) as Weak); } fn get_best_block_from_best_proposal_header(&self, header: &HeaderView) -> H256 { @@ -319,7 +319,7 @@ impl ConsensusEngine for Tendermint { header.number() >= allowed_height } - fn action_handlers(&self) -> &[Arc] { + fn action_handlers(&self) -> &[Arc] { &self.action_handlers } @@ -363,7 +363,7 @@ fn block_number_if_term_changed( } fn inactive_validators( - client: &ConsensusClient, + client: &dyn ConsensusClient, start_of_the_current_term: u64, current_block: &Header, mut validators: HashSet
, @@ -380,8 +380,8 @@ fn inactive_validators( } fn calculate_pending_rewards_of_the_previous_term( - chain: &ConsensusClient, - validators: &ValidatorSet, + chain: &dyn ConsensusClient, + validators: &dyn ValidatorSet, rewards: BTreeMap, start_of_the_current_term: u64, start_of_the_current_term_header: encoded::Header, diff --git a/core/src/consensus/tendermint/mod.rs b/core/src/consensus/tendermint/mod.rs index 8366faf1ae..a5ca75668d 100644 --- a/core/src/consensus/tendermint/mod.rs +++ b/core/src/consensus/tendermint/mod.rs @@ -58,20 +58,20 @@ pub type BlockHash = H256; /// ConsensusEngine using `Tendermint` consensus algorithm pub struct Tendermint { - client: RwLock>>, + client: RwLock>>, external_params_initializer: crossbeam::Sender, - extension_initializer: crossbeam::Sender<(crossbeam::Sender, Weak)>, + extension_initializer: crossbeam::Sender<(crossbeam::Sender, Weak)>, timeouts: TimeoutParams, join: Option>, quit_tendermint: crossbeam::Sender<()>, inner: crossbeam::Sender, - validators: Arc, + validators: Arc, /// Reward per block, in base units. block_reward: u64, /// codechain machine descriptor machine: Arc, /// Action handlers for this consensus method - action_handlers: Vec>, + action_handlers: Vec>, /// stake object to register client data later stake: Arc, /// Chain notify @@ -98,7 +98,7 @@ impl Tendermint { let (join, external_params_initializer, extension_initializer, inner, quit_tendermint) = worker::spawn(our_params.validators); - let action_handlers: Vec> = vec![stake.clone()]; + let action_handlers: Vec> = vec![stake.clone()]; let chain_notify = Arc::new(TendermintChainNotify::new(inner.clone())); Arc::new(Tendermint { @@ -149,7 +149,7 @@ mod tests { let test = TestBlockChainClient::new_with_scheme(Scheme::new_test_tendermint()); let test_client: Arc = Arc::new(test); - let consensus_client = Arc::clone(&test_client) as Arc; + let consensus_client = Arc::clone(&test_client) as Arc; scheme.engine.register_client(Arc::downgrade(&consensus_client)); (scheme, tap, test_client) } @@ -172,7 +172,7 @@ mod tests { addr } - fn insert_and_register(tap: &Arc, engine: &CodeChainEngine, acc: &str) -> Address { + fn insert_and_register(tap: &Arc, engine: &dyn CodeChainEngine, acc: &str) -> Address { let addr = insert_and_unlock(tap, acc); engine.set_signer(tap.clone(), addr); addr diff --git a/core/src/consensus/tendermint/network.rs b/core/src/consensus/tendermint/network.rs index 05175fd636..d1746d51fa 100644 --- a/core/src/consensus/tendermint/network.rs +++ b/core/src/consensus/tendermint/network.rs @@ -44,7 +44,7 @@ use super::{ pub struct TendermintExtension { inner: crossbeam::Sender, peers: HashMap, - api: Box, + api: Box, timeouts: TimeoutParams, } @@ -52,7 +52,7 @@ const MIN_PEERS_PROPAGATION: usize = 4; const MAX_PEERS_PROPAGATION: usize = 128; impl TendermintExtension { - pub fn new(inner: crossbeam::Sender, timeouts: TimeoutParams, api: Box) -> Self { + pub fn new(inner: crossbeam::Sender, timeouts: TimeoutParams, api: Box) -> Self { let initial = timeouts.initial(); ctrace!(ENGINE, "Setting the initial timeout to {:?}.", initial); api.set_timer_once(ENGINE_TIMEOUT_TOKEN_NONCE_BASE, initial).expect("Timer set succeeds"); diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index ed23a1fdb0..86f6344af2 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -58,7 +58,7 @@ use std::cell::Cell; type SpawnResult = ( JoinHandle<()>, crossbeam::Sender, - crossbeam::Sender<(crossbeam::Sender, Weak)>, + crossbeam::Sender<(crossbeam::Sender, Weak)>, crossbeam::Sender, crossbeam::Sender<()>, ); @@ -68,7 +68,7 @@ pub fn spawn(validators: Arc) -> SpawnResult { } struct Worker { - client: Weak, + client: Weak, /// Blockchain height. height: Height, /// Consensus view. @@ -141,7 +141,7 @@ pub enum Event { signature: SchnorrSignature, view: View, message: Bytes, - result: crossbeam::Sender>>, + result: crossbeam::Sender>>, }, StepState { token: NodeId, @@ -169,7 +169,7 @@ pub enum Event { GetCommit { block: Bytes, votes: Vec, - result: crossbeam::Sender>>, + result: crossbeam::Sender>>, }, } @@ -178,7 +178,7 @@ impl Worker { fn new( validators: Arc, extension: EventSender, - client: Weak, + client: Weak, time_gap_params: TimeGapParams, ) -> Self { Worker { @@ -387,7 +387,7 @@ impl Worker { } /// The client is a thread-safe struct. Using it in multi-threads is safe. - fn client(&self) -> Arc { + fn client(&self) -> Arc { self.client.upgrade().expect("Client lives longer than consensus") } @@ -1697,7 +1697,7 @@ impl Worker { signature: SchnorrSignature, proposed_view: View, bytes: Bytes, - ) -> Option> { + ) -> Option> { let c = self.client.upgrade()?; // This block borrows bytes @@ -1986,7 +1986,7 @@ impl Worker { } #[allow(clippy::cognitive_complexity)] - fn on_commit_message(&mut self, block: Bytes, votes: Vec) -> Option> { + fn on_commit_message(&mut self, block: Bytes, votes: Vec) -> Option> { if self.step.is_commit() { return None } diff --git a/core/src/consensus/validator_set/dynamic_validator.rs b/core/src/consensus/validator_set/dynamic_validator.rs index bb4e12496d..b9b95a09c4 100644 --- a/core/src/consensus/validator_set/dynamic_validator.rs +++ b/core/src/consensus/validator_set/dynamic_validator.rs @@ -30,7 +30,7 @@ use crate::consensus::EngineError; /// Validator set containing a known set of public keys. pub struct DynamicValidator { initial_list: RoundRobinValidator, - client: RwLock>>, + client: RwLock>>, } impl DynamicValidator { @@ -42,7 +42,7 @@ impl DynamicValidator { } fn validators(&self, parent: H256) -> Option> { - let client: Arc = + let client: Arc = self.client.read().as_ref().and_then(Weak::upgrade).expect("Client is not initialized"); let block_id = parent.into(); let term_id = client.current_term_id(block_id).expect( @@ -174,7 +174,7 @@ impl ValidatorSet for DynamicValidator { } /// Allows blockchain state access. - fn register_client(&self, client: Weak) { + fn register_client(&self, client: Weak) { self.initial_list.register_client(Weak::clone(&client)); let mut client_lock = self.client.write(); assert!(client_lock.is_none()); @@ -207,7 +207,7 @@ mod tests { let a1 = Public::from_str("34959b60d54703e9dfe36afb1e9950a4abe34d666cbb64c92969013bc9cc74063f9e4680d9d48c4597ee623bd4b507a1b2f43a9c5766a06463f85b73a94c51d1").unwrap(); let a2 = Public::from_str("8c5a25bfafceea03073e2775cfb233a46648a088c12a1ca18a5865534887ccf60e1670be65b5f8e29643f463fdf84b1cbadd6027e71d8d04496570cb6b04885d").unwrap(); let set = DynamicValidator::new(vec![a1, a2]); - let test_client: Arc = Arc::new({ + let test_client: Arc = Arc::new({ let mut client = TestBlockChainClient::new(); client.term_id = Some(1); client diff --git a/core/src/consensus/validator_set/mod.rs b/core/src/consensus/validator_set/mod.rs index 4c84777c5e..b86f8d9d14 100644 --- a/core/src/consensus/validator_set/mod.rs +++ b/core/src/consensus/validator_set/mod.rs @@ -55,7 +55,7 @@ pub trait ValidatorSet: Send + Sync { fn check_enough_votes(&self, parent: &H256, votes: &BitSet) -> Result<(), EngineError>; /// Allows blockchain state access. - fn register_client(&self, _client: Weak) {} + fn register_client(&self, _client: Weak) {} fn addresses(&self, _parent: &H256) -> Vec
; } diff --git a/core/src/consensus/validator_set/validator_list.rs b/core/src/consensus/validator_set/validator_list.rs index a568ea435f..cdec5664e5 100644 --- a/core/src/consensus/validator_set/validator_list.rs +++ b/core/src/consensus/validator_set/validator_list.rs @@ -32,7 +32,7 @@ use crate::types::BlockId; pub struct RoundRobinValidator { validators: Vec, addresses: HashSet
, - client: RwLock>>, + client: RwLock>>, } impl RoundRobinValidator { @@ -70,7 +70,7 @@ impl ValidatorSet for RoundRobinValidator { } fn next_block_proposer(&self, parent: &H256, view: u64) -> Option
{ - let client: Arc = self.client.read().as_ref().and_then(Weak::upgrade)?; + let client: Arc = self.client.read().as_ref().and_then(Weak::upgrade)?; client.block_header(&BlockId::from(*parent)).map(|header| { let proposer = header.author(); let grand_parent = header.parent_hash(); @@ -101,7 +101,7 @@ impl ValidatorSet for RoundRobinValidator { } } - fn register_client(&self, client: Weak) { + fn register_client(&self, client: Weak) { *self.client.write() = Some(client); } diff --git a/core/src/db.rs b/core/src/db.rs index 115994fa6b..ec15ac4deb 100644 --- a/core/src/db.rs +++ b/core/src/db.rs @@ -88,13 +88,13 @@ pub trait Key { /// Should be used to write value into database. pub trait Writable { /// Writes the value into the database. - fn write(&mut self, col: Option, key: &Key, value: &T) + fn write(&mut self, col: Option, key: &dyn Key, value: &T) where T: rlp::Encodable, R: Deref; /// Deletes key from the databse. - fn delete(&mut self, col: Option, key: &Key) + fn delete(&mut self, col: Option, key: &dyn Key) where T: rlp::Encodable, R: Deref; @@ -103,7 +103,7 @@ pub trait Writable { fn write_with_cache( &mut self, col: Option, - cache: &mut Cache, + cache: &mut dyn Cache, key: K, value: T, policy: CacheUpdatePolicy, @@ -126,7 +126,7 @@ pub trait Writable { fn extend_with_cache( &mut self, col: Option, - cache: &mut Cache, + cache: &mut dyn Cache, values: HashMap, policy: CacheUpdatePolicy, ) where @@ -153,7 +153,7 @@ pub trait Writable { fn extend_with_option_cache( &mut self, col: Option, - cache: &mut Cache>, + cache: &mut dyn Cache>, values: HashMap>, policy: CacheUpdatePolicy, ) where @@ -186,7 +186,7 @@ pub trait Writable { /// Should be used to read values from database. pub trait Readable { /// Returns value for given key. - fn read(&self, col: Option, key: &Key) -> Option + fn read(&self, col: Option, key: &dyn Key) -> Option where T: rlp::Decodable, R: Deref; @@ -210,7 +210,7 @@ pub trait Readable { } /// Returns true if given value exists. - fn exists(&self, col: Option, key: &Key) -> bool + fn exists(&self, col: Option, key: &dyn Key) -> bool where R: Deref; @@ -232,14 +232,14 @@ pub trait Readable { } impl Writable for DBTransaction { - fn write(&mut self, col: Option, key: &Key, value: &T) + fn write(&mut self, col: Option, key: &dyn Key, value: &T) where T: rlp::Encodable, R: Deref, { self.put(col, &key.key(), &rlp::encode(value)); } - fn delete(&mut self, col: Option, key: &Key) + fn delete(&mut self, col: Option, key: &dyn Key) where T: rlp::Encodable, R: Deref, { @@ -248,7 +248,7 @@ impl Writable for DBTransaction { } impl Readable for KVDB { - fn read(&self, col: Option, key: &Key) -> Option + fn read(&self, col: Option, key: &dyn Key) -> Option where T: rlp::Decodable, R: Deref, { @@ -262,7 +262,7 @@ impl Readable for KVDB { } } - fn exists(&self, col: Option, key: &Key) -> bool + fn exists(&self, col: Option, key: &dyn Key) -> bool where R: Deref, { let result = self.get(col, &key.key()); diff --git a/core/src/miner/backup.rs b/core/src/miner/backup.rs index f355424eff..7ba35afc43 100644 --- a/core/src/miner/backup.rs +++ b/core/src/miner/backup.rs @@ -42,7 +42,7 @@ pub fn remove_item(batch: &mut DBTransaction, key: &H256) { batch.delete(dblib::COL_MEMPOOL, db_key.as_ref()); } -pub fn recover_to_data(db: &KeyValueDB) -> HashMap { +pub fn recover_to_data(db: &dyn KeyValueDB) -> HashMap { let mut by_hash = HashMap::new(); for (key, value) in db.iter(dblib::COL_MEMPOOL) { diff --git a/core/src/miner/mem_pool.rs b/core/src/miner/mem_pool.rs index 0ceb45dd02..d95627f55a 100644 --- a/core/src/miner/mem_pool.rs +++ b/core/src/miner/mem_pool.rs @@ -110,12 +110,12 @@ pub struct MemPool { /// Next id that should be assigned to a transaction imported to the pool next_transaction_id: u64, /// Arc of KeyValueDB in which the backup information is stored. - db: Arc, + db: Arc, } impl MemPool { /// Create new instance of this Queue with specified limits - pub fn with_limits(limit: usize, memory_limit: usize, fee_bump_shift: usize, db: Arc) -> Self { + pub fn with_limits(limit: usize, memory_limit: usize, fee_bump_shift: usize, db: Arc) -> Self { MemPool { minimal_fee: 0, fee_bump_shift, diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index 6e6de60521..43f1e00dbf 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -110,7 +110,7 @@ struct SealingWork { enabled: bool, } -type TransactionListener = Box; +type TransactionListener = Box; pub struct Miner { mem_pool: Arc>, @@ -120,18 +120,18 @@ pub struct Miner { sealing_block_last_request: Mutex, sealing_work: Mutex, params: RwLock, - engine: Arc, + engine: Arc, options: MinerOptions, sealing_enabled: AtomicBool, accounts: Option>, - notifiers: RwLock>>, + notifiers: RwLock>>, } impl Miner { /// Push listener that will handle new jobs - pub fn add_work_listener(&self, notifier: Box) { + pub fn add_work_listener(&self, notifier: Box) { self.notifiers.write().push(notifier); } @@ -139,12 +139,12 @@ impl Miner { options: MinerOptions, scheme: &Scheme, accounts: Option>, - db: Arc, + db: Arc, ) -> Arc { Arc::new(Self::new_raw(options, scheme, accounts, db)) } - pub fn with_scheme(scheme: &Scheme, db: Arc) -> Self { + pub fn with_scheme(scheme: &Scheme, db: Arc) -> Self { Self::new_raw(Default::default(), scheme, None, db) } @@ -152,7 +152,7 @@ impl Miner { options: MinerOptions, scheme: &Scheme, accounts: Option>, - db: Arc, + db: Arc, ) -> Self { let mem_limit = options.mem_pool_memory_limit.unwrap_or_else(usize::max_value); let mem_pool = Arc::new(RwLock::new(MemPool::with_limits( @@ -162,7 +162,7 @@ impl Miner { db, ))); - let notifiers: Vec> = if options.new_work_notify.is_empty() { + let notifiers: Vec> = if options.new_work_notify.is_empty() { Vec::new() } else { vec![Box::new(WorkPoster::new(&options.new_work_notify))] @@ -192,7 +192,7 @@ impl Miner { } /// Set a callback to be notified about imported transactions' hashes. - pub fn add_transactions_listener(&self, f: Box) { + pub fn add_transactions_listener(&self, f: Box) { self.transaction_listener.write().push(f); } @@ -1143,7 +1143,7 @@ pub mod test { miner.add_transactions_to_pool(client.as_ref(), transactions, TxOrigin::Local, &mut mem_pool); } - fn generate_test_client(db: Arc, miner: Arc, scheme: &Scheme) -> Result, Error> { + fn generate_test_client(db: Arc, miner: Arc, scheme: &Scheme) -> Result, Error> { let timer_loop = TimerLoop::new(2); let client_config: ClientConfig = Default::default(); diff --git a/core/src/scheme/scheme.rs b/core/src/scheme/scheme.rs index fd1ad38cb6..69a425a5a5 100644 --- a/core/src/scheme/scheme.rs +++ b/core/src/scheme/scheme.rs @@ -44,7 +44,7 @@ pub struct Scheme { /// User friendly scheme name pub name: String, /// What engine are we using for this? - pub engine: Arc, + pub engine: Arc, /// Name of the subdir inside the main data dir to use for chain data and settings. pub data_dir: String, @@ -97,7 +97,7 @@ impl Scheme { /// Convert engine scheme into a arc'd Engine of the right underlying type. /// TODO avoid this hard-coded nastiness - use dynamic-linked plugin framework instead. - fn engine(engine_scheme: cjson::scheme::Engine, params: CommonParams) -> Arc { + fn engine(engine_scheme: cjson::scheme::Engine, params: CommonParams) -> Arc { let machine = Self::machine(&engine_scheme, params); match engine_scheme { @@ -182,7 +182,7 @@ impl Scheme { Ok(top_level.commit_and_into_db()?) } - pub fn check_genesis_root(&self, db: &HashDB) -> bool { + pub fn check_genesis_root(&self, db: &dyn HashDB) -> bool { if db.is_empty() { return true } diff --git a/core/src/service.rs b/core/src/service.rs index 9744bbe3ec..78e3a1e4ef 100644 --- a/core/src/service.rs +++ b/core/src/service.rs @@ -38,7 +38,7 @@ impl ClientService { pub fn start( config: &ClientConfig, scheme: &Scheme, - db: Arc, + db: Arc, miner: Arc, reseal_timer: TimerApi, ) -> Result { diff --git a/core/src/verification/canon_verifier.rs b/core/src/verification/canon_verifier.rs index b481242c6b..295ed45769 100644 --- a/core/src/verification/canon_verifier.rs +++ b/core/src/verification/canon_verifier.rs @@ -31,7 +31,7 @@ impl Verifier for CanonVerifier { block: &[u8], header: &Header, parent: &Header, - engine: &CodeChainEngine, + engine: &dyn CodeChainEngine, do_full: Option>, common_params: &CommonParams, ) -> Result<(), Error> { @@ -42,7 +42,7 @@ impl Verifier for CanonVerifier { verification::verify_block_final(expected, got) } - fn verify_block_external(&self, header: &Header, engine: &CodeChainEngine) -> Result<(), Error> { + fn verify_block_external(&self, header: &Header, engine: &dyn CodeChainEngine) -> Result<(), Error> { engine.verify_block_external(header) } } diff --git a/core/src/verification/mod.rs b/core/src/verification/mod.rs index 67174c5b9f..a13cb4a00e 100644 --- a/core/src/verification/mod.rs +++ b/core/src/verification/mod.rs @@ -58,7 +58,7 @@ impl Default for VerifierType { } /// Create a new verifier based on type. -pub fn new(v: VerifierType) -> Box> { +pub fn new(v: VerifierType) -> Box> { match v { VerifierType::Canon | VerifierType::CanonNoSeal => Box::new(CanonVerifier), VerifierType::Noop => Box::new(NoopVerifier), diff --git a/core/src/verification/noop_verifier.rs b/core/src/verification/noop_verifier.rs index 9d771d07d5..8c93d2e1a9 100644 --- a/core/src/verification/noop_verifier.rs +++ b/core/src/verification/noop_verifier.rs @@ -30,7 +30,7 @@ impl Verifier for NoopVerifier { _block: &[u8], _: &Header, _t: &Header, - _: &CodeChainEngine, + _: &dyn CodeChainEngine, _: Option>, _common_params: &CommonParams, ) -> Result<(), Error> { @@ -41,7 +41,7 @@ impl Verifier for NoopVerifier { Ok(()) } - fn verify_block_external(&self, _header: &Header, _engine: &CodeChainEngine) -> Result<(), Error> { + fn verify_block_external(&self, _header: &Header, _engine: &dyn CodeChainEngine) -> Result<(), Error> { Ok(()) } } diff --git a/core/src/verification/queue/kind.rs b/core/src/verification/queue/kind.rs index f1755ca2b0..7140d38a5b 100644 --- a/core/src/verification/queue/kind.rs +++ b/core/src/verification/queue/kind.rs @@ -70,12 +70,12 @@ pub trait Kind: 'static + Sized + Send + Sync { fn name() -> &'static str; /// Attempt to create the `Unverified` item from the input. - fn create(input: Self::Input, engine: &CodeChainEngine) -> Result; + fn create(input: Self::Input, engine: &dyn CodeChainEngine) -> Result; /// Attempt to verify the `Unverified` item using the given engine. fn verify( unverified: Self::Unverified, - engine: &CodeChainEngine, + engine: &dyn CodeChainEngine, check_seal: bool, ) -> Result; @@ -120,14 +120,18 @@ pub mod headers { "Headers" } - fn create(input: Self::Input, engine: &CodeChainEngine) -> Result { + fn create(input: Self::Input, engine: &dyn CodeChainEngine) -> Result { // FIXME: this doesn't seem to match with full block verification verify_header_basic(&input)?; verify_header_with_engine(&input, engine)?; Ok(input) } - fn verify(un: Self::Unverified, engine: &CodeChainEngine, check_seal: bool) -> Result { + fn verify( + un: Self::Unverified, + engine: &dyn CodeChainEngine, + check_seal: bool, + ) -> Result { if check_seal { engine.verify_block_seal(&un).map(|_| un) } else { @@ -166,7 +170,7 @@ pub mod blocks { "Blocks" } - fn create(input: Self::Input, engine: &CodeChainEngine) -> Result { + fn create(input: Self::Input, engine: &dyn CodeChainEngine) -> Result { match verify_block_basic(&input.header, &input.bytes) .and_then(|_| verify_header_with_engine(&input.header, engine)) { @@ -178,7 +182,11 @@ pub mod blocks { } } - fn verify(un: Self::Unverified, engine: &CodeChainEngine, check_seal: bool) -> Result { + fn verify( + un: Self::Unverified, + engine: &dyn CodeChainEngine, + check_seal: bool, + ) -> Result { let hash = un.hash(); match verify_block_seal(un.header, un.bytes, engine, check_seal) { Ok(verified) => Ok(verified), diff --git a/core/src/verification/queue/mod.rs b/core/src/verification/queue/mod.rs index 2521d41820..451c51c787 100644 --- a/core/src/verification/queue/mod.rs +++ b/core/src/verification/queue/mod.rs @@ -63,7 +63,7 @@ impl Default for Config { } pub struct VerificationQueue { - engine: Arc, + engine: Arc, verification: Arc>, processing: RwLock>, // hash to score deleting: Arc, @@ -121,7 +121,7 @@ impl QueueSignal { impl VerificationQueue { pub fn new( config: &Config, - engine: Arc, + engine: Arc, message_channel: IoChannel, check_seal: bool, ) -> Self { @@ -193,7 +193,7 @@ impl VerificationQueue { fn verify( verification: &Verification, - engine: &CodeChainEngine, + engine: &dyn CodeChainEngine, ready_signal: &QueueSignal, empty: &SCondvar, more_to_verify: &SCondvar, diff --git a/core/src/verification/verification.rs b/core/src/verification/verification.rs index c98d831846..7e7c88c61e 100644 --- a/core/src/verification/verification.rs +++ b/core/src/verification/verification.rs @@ -52,7 +52,7 @@ pub fn verify_block_basic(header: &Header, bytes: &[u8]) -> Result<(), Error> { Ok(()) } -pub fn verify_header_with_engine(header: &Header, engine: &CodeChainEngine) -> Result<(), Error> { +pub fn verify_header_with_engine(header: &Header, engine: &dyn CodeChainEngine) -> Result<(), Error> { engine.verify_header_basic(&header)?; let expected_seal_fields = engine.seal_fields(header); @@ -68,7 +68,7 @@ pub fn verify_header_with_engine(header: &Header, engine: &CodeChainEngine) -> R pub fn verify_block_with_params( header: &Header, bytes: &[u8], - engine: &CodeChainEngine, + engine: &dyn CodeChainEngine, common_params: &CommonParams, ) -> Result<(), Error> { verify_header_with_params(&header, common_params)?; @@ -157,7 +157,7 @@ fn verify_transactions_root( pub fn verify_block_seal( header: Header, bytes: Bytes, - engine: &CodeChainEngine, + engine: &dyn CodeChainEngine, check_seal: bool, ) -> Result { if check_seal { @@ -188,7 +188,7 @@ pub struct FullFamilyParams<'a, C: BlockChainTrait + 'a> { pub transactions: &'a [SignedTransaction], /// Block provider to use during verification - pub block_provider: &'a BlockProvider, + pub block_provider: &'a dyn BlockProvider, /// Engine client to use during verification pub client: &'a C, @@ -199,7 +199,7 @@ pub fn verify_block_family( block: &[u8], header: &Header, parent: &Header, - engine: &CodeChainEngine, + engine: &dyn CodeChainEngine, do_full: Option>, common_params: &CommonParams, ) -> Result<(), Error> { diff --git a/core/src/verification/verifier.rs b/core/src/verification/verifier.rs index e272d5b246..6917d0e4cb 100644 --- a/core/src/verification/verifier.rs +++ b/core/src/verification/verifier.rs @@ -31,7 +31,7 @@ where block: &[u8], header: &Header, parent: &Header, - engine: &CodeChainEngine, + engine: &dyn CodeChainEngine, do_full: Option>, common_params: &CommonParams, ) -> Result<(), Error>; @@ -39,5 +39,5 @@ where /// Do a final verification check for an enacted header vs its expected counterpart. fn verify_block_final(&self, expected: &Header, got: &Header) -> Result<(), Error>; /// Verify a block, inspecing external state. - fn verify_block_external(&self, header: &Header, engine: &CodeChainEngine) -> Result<(), Error>; + fn verify_block_external(&self, header: &Header, engine: &dyn CodeChainEngine) -> Result<(), Error>; } diff --git a/discovery/src/extension.rs b/discovery/src/extension.rs index a8d595ba80..16444a1128 100644 --- a/discovery/src/extension.rs +++ b/discovery/src/extension.rs @@ -32,13 +32,13 @@ use super::Config; pub struct Extension { config: Config, routing_table: Arc, - api: Box, + api: Box, nodes: HashSet, // FIXME: Find the optimized data structure for it use_kademlia: bool, } impl Extension { - pub fn new(routing_table: Arc, config: Config, api: Box, use_kademlia: bool) -> Self { + pub fn new(routing_table: Arc, config: Config, api: Box, use_kademlia: bool) -> Self { if use_kademlia { cinfo!(DISCOVERY, "Discovery starts with kademlia option"); } else { diff --git a/keystore/src/import.rs b/keystore/src/import.rs index d7e55cfd68..2a0130c1da 100644 --- a/keystore/src/import.rs +++ b/keystore/src/import.rs @@ -25,7 +25,7 @@ use crate::accounts_dir::{DiskKeyFileManager, KeyDirectory, KeyFileManager}; use crate::Error; /// Import an account from a file. -pub fn import_account(path: &Path, dst: &KeyDirectory) -> Result { +pub fn import_account(path: &Path, dst: &dyn KeyDirectory) -> Result { let key_manager = DiskKeyFileManager; let existing_accounts = dst.load()?.into_iter().map(|a| a.address).collect::>(); let filename = path.file_name().and_then(OsStr::to_str).map(ToOwned::to_owned); @@ -39,7 +39,7 @@ pub fn import_account(path: &Path, dst: &KeyDirectory) -> Result } /// Import all accounts from one directory to the other. -pub fn import_accounts(src: &KeyDirectory, dst: &KeyDirectory) -> Result, Error> { +pub fn import_accounts(src: &dyn KeyDirectory, dst: &dyn KeyDirectory) -> Result, Error> { let accounts = src.load()?; let existing_accounts = dst.load()?.into_iter().map(|a| a.address).collect::>(); diff --git a/keystore/src/keystore.rs b/keystore/src/keystore.rs index 8cd8a23f14..bc46604b7c 100644 --- a/keystore/src/keystore.rs +++ b/keystore/src/keystore.rs @@ -36,12 +36,12 @@ pub struct KeyStore { impl KeyStore { /// Open a new accounts store with given key directory backend. - pub fn open(directory: Box) -> Result { + pub fn open(directory: Box) -> Result { Self::open_with_iterations(directory, KEY_ITERATIONS as u32) } /// Open a new account store with given key directory backend and custom number of iterations. - pub fn open_with_iterations(directory: Box, iterations: u32) -> Result { + pub fn open_with_iterations(directory: Box, iterations: u32) -> Result { Ok(KeyStore { store: KeyMultiStore::open_with_iterations(directory, iterations)?, }) @@ -123,7 +123,7 @@ impl SecretStore for KeyStore { fn copy_account( &self, - new_store: &SimpleSecretStore, + new_store: &dyn SimpleSecretStore, account: &Address, password: &Password, new_password: &Password, @@ -159,7 +159,7 @@ impl SecretStore for KeyStore { /// Similar to `KeyStore` but may store many accounts (with different passwords) for the same `Address` pub struct KeyMultiStore { - dir: Box, + dir: Box, iterations: u32, // order lock: cache cache: RwLock>>, @@ -174,12 +174,12 @@ struct Timestamp { impl KeyMultiStore { /// Open new multi-accounts store with given key directory backend. - pub fn open(directory: Box) -> Result { + pub fn open(directory: Box) -> Result { Self::open_with_iterations(directory, KEY_ITERATIONS as u32) } /// Open new multi-accounts store with given key directory backend and custom number of iterations for new keys. - pub fn open_with_iterations(directory: Box, iterations: u32) -> Result { + pub fn open_with_iterations(directory: Box, iterations: u32) -> Result { let store = KeyMultiStore { dir: directory, iterations, diff --git a/keystore/src/secret_store.rs b/keystore/src/secret_store.rs index 51cb3ced53..fa00667dd3 100644 --- a/keystore/src/secret_store.rs +++ b/keystore/src/secret_store.rs @@ -68,7 +68,7 @@ pub trait SecretStore: SimpleSecretStore { /// Copies account between stores. fn copy_account( &self, - new_store: &SimpleSecretStore, + new_store: &dyn SimpleSecretStore, account: &Address, password: &Password, new_password: &Password, diff --git a/network/src/client.rs b/network/src/client.rs index 06bcc80601..8d94fb15a5 100644 --- a/network/src/client.rs +++ b/network/src/client.rs @@ -112,7 +112,7 @@ impl Client { where T: 'static + Sized + NetworkExtension, E: 'static + Sized + Send, - F: 'static + FnOnce(Box) -> T + Send, { + F: 'static + FnOnce(Box) -> T + Send, { let mut extensions = self.extensions.write(); let name = T::name(); let timer = self.timer_loop.new_timer_with_name(name); diff --git a/network/src/p2p/handler.rs b/network/src/p2p/handler.rs index 0a108d0f3e..6cc7a0193e 100644 --- a/network/src/p2p/handler.rs +++ b/network/src/p2p/handler.rs @@ -102,7 +102,7 @@ pub struct Handler { establishing_outgoing_session: Mutex>, routing_table: Arc, - filters: Arc, + filters: Arc, remote_node_ids: RwLock>, remote_node_ids_reverse: RwLock>, @@ -126,7 +126,7 @@ impl Handler { socket_address: SocketAddr, client: Arc, routing_table: Arc, - filters: Arc, + filters: Arc, bootstrap_addresses: Vec, min_peers: usize, max_peers: usize, diff --git a/network/src/service.rs b/network/src/service.rs index 62f64bd596..93b5449d42 100644 --- a/network/src/service.rs +++ b/network/src/service.rs @@ -35,7 +35,7 @@ pub struct Service { client: Arc, routing_table: Arc, p2p_handler: Arc, - filters_control: Arc, + filters_control: Arc, } impl Service { @@ -46,7 +46,7 @@ impl Service { bootstrap_addresses: Vec, min_peers: usize, max_peers: usize, - filters_control: Arc, + filters_control: Arc, routing_table: Arc, ) -> Result, Error> { let p2p = IoService::start("P2P")?; @@ -79,7 +79,7 @@ impl Service { where T: 'static + Sized + NetworkExtension, E: 'static + Sized + Send, - F: 'static + FnOnce(Box) -> T + Send, { + F: 'static + FnOnce(Box) -> T + Send, { self.client.register_extension(factory) } diff --git a/rpc/src/v1/impls/devel.rs b/rpc/src/v1/impls/devel.rs index e916b8ec56..51e96aa71d 100644 --- a/rpc/src/v1/impls/devel.rs +++ b/rpc/src/v1/impls/devel.rs @@ -47,7 +47,7 @@ use super::super::types::{TPSTestOption, TPSTestSetting}; pub struct DevelClient { client: Arc, - db: Arc, + db: Arc, miner: Arc, block_sync: Option>, } diff --git a/rpc/src/v1/impls/net.rs b/rpc/src/v1/impls/net.rs index d76bdb9d74..7d2c50b282 100644 --- a/rpc/src/v1/impls/net.rs +++ b/rpc/src/v1/impls/net.rs @@ -28,11 +28,11 @@ use super::super::traits::Net; use super::super::types::FilterStatus; pub struct NetClient { - network_control: Arc, + network_control: Arc, } impl NetClient { - pub fn new(network_control: Arc) -> Self { + pub fn new(network_control: Arc) -> Self { Self { network_control, } diff --git a/state/src/action_handler/mod.rs b/state/src/action_handler/mod.rs index 55bd45a250..519f8e62df 100644 --- a/state/src/action_handler/mod.rs +++ b/state/src/action_handler/mod.rs @@ -57,7 +57,7 @@ pub trait ActionHandler: Send + Sync { } pub trait FindActionHandler { - fn find_action_handler_for(&self, _id: u64) -> Option<&ActionHandler> { + fn find_action_handler_for(&self, _id: u64) -> Option<&dyn ActionHandler> { None } } diff --git a/state/src/cache/shard_cache.rs b/state/src/cache/shard_cache.rs index 1d19bc8b9e..b028036758 100644 --- a/state/src/cache/shard_cache.rs +++ b/state/src/cache/shard_cache.rs @@ -52,7 +52,7 @@ impl ShardCache { self.asset.revert_to_checkpoint(); } - pub fn commit(&mut self, trie: &mut TrieMut) -> TrieResult<()> { + pub fn commit(&mut self, trie: &mut dyn TrieMut) -> TrieResult<()> { self.asset_scheme.commit(trie)?; self.asset.commit(trie)?; Ok(()) diff --git a/state/src/cache/top_cache.rs b/state/src/cache/top_cache.rs index 6c9bb78e37..91c442078b 100644 --- a/state/src/cache/top_cache.rs +++ b/state/src/cache/top_cache.rs @@ -80,7 +80,7 @@ impl TopCache { self.action_data.revert_to_checkpoint(); } - pub fn commit<'db>(&mut self, trie: &mut (TrieMut + 'db)) -> TrieResult<()> { + pub fn commit<'db>(&mut self, trie: &mut (dyn TrieMut + 'db)) -> TrieResult<()> { self.account.commit(trie)?; self.regular_account.commit(trie)?; self.metadata.commit(trie)?; diff --git a/state/src/cache/write_back.rs b/state/src/cache/write_back.rs index 46a68e542e..f2323ec4d1 100644 --- a/state/src/cache/write_back.rs +++ b/state/src/cache/write_back.rs @@ -176,7 +176,7 @@ where } } - pub fn commit<'db>(&mut self, trie: &mut (TrieMut + 'db)) -> TrieResult<()> { + pub fn commit<'db>(&mut self, trie: &mut (dyn TrieMut + 'db)) -> TrieResult<()> { let mut cache = self.cache.borrow_mut(); for (address, ref mut a) in cache.iter_mut().filter(|&(_, ref a)| a.is_dirty) { a.is_dirty = false; diff --git a/state/src/db/state_db.rs b/state/src/db/state_db.rs index 3035482f84..ed129bb013 100644 --- a/state/src/db/state_db.rs +++ b/state/src/db/state_db.rs @@ -47,14 +47,14 @@ use crate::impls::TopLevelState; /// State database abstraction. pub struct StateDB { /// Backing database. - db: Box, + db: Box, cache: GlobalCache, current_hash: Option, } impl StateDB { /// Create a new instance wrapping `JournalDB` - pub fn new(db: Box) -> StateDB { + pub fn new(db: Box) -> StateDB { StateDB { db, cache: Default::default(), @@ -130,12 +130,12 @@ impl StateDB { impl AsHashDB for StateDB { /// Conversion method to interpret self as `HashDB` reference - fn as_hashdb(&self) -> &HashDB { + fn as_hashdb(&self) -> &dyn HashDB { self.db.as_hashdb() } /// Conversion method to interpret self as mutable `HashDB` reference - fn as_hashdb_mut(&mut self) -> &mut HashDB { + fn as_hashdb_mut(&mut self) -> &mut dyn HashDB { self.db.as_hashdb_mut() } } diff --git a/state/src/impls/shard_level.rs b/state/src/impls/shard_level.rs index 0a079f1d7c..07a9333445 100644 --- a/state/src/impls/shard_level.rs +++ b/state/src/impls/shard_level.rs @@ -521,7 +521,7 @@ impl<'db> ShardLevelState<'db> { fn check_and_run_input_script( &self, input: &AssetTransferInput, - transaction: &PartialHashing, + transaction: &dyn PartialHashing, burn: bool, sender: &Address, approvers: &[Address], @@ -534,7 +534,7 @@ impl<'db> ShardLevelState<'db> { return Ok(()) // Don't execute scripts when regulator sends the transaction. } - let to_hash: &PartialHashing = transaction; + let to_hash: &dyn PartialHashing = transaction; if *asset.lock_script_hash() != Blake::blake(&input.lock_script) { return Err(RuntimeError::ScriptHashMismatch(Mismatch { diff --git a/state/src/impls/top_level.rs b/state/src/impls/top_level.rs index ba4fe10b79..55cf04cc22 100644 --- a/state/src/impls/top_level.rs +++ b/state/src/impls/top_level.rs @@ -127,7 +127,7 @@ impl TopStateView for TopLevelState { self.top_cache.shard(&shard_address, &trie) } - fn shard_state<'db>(&'db self, shard_id: ShardId) -> TrieResult>> { + fn shard_state<'db>(&'db self, shard_id: ShardId) -> TrieResult>> { match self.shard_root(shard_id)? { // FIXME: Find a way to use stored cache. Some(shard_root) => { @@ -999,7 +999,7 @@ impl TopState for TopLevelState { } } -fn is_active_account(state: &TopStateView, address: &Address) -> TrieResult { +fn is_active_account(state: &dyn TopStateView, address: &Address) -> TrieResult { match &state.account(address)? { Some(account) if account.is_active() => Ok(true), _ => Ok(false), diff --git a/state/src/tests.rs b/state/src/tests.rs index ce41af4a02..3de024e8e2 100644 --- a/state/src/tests.rs +++ b/state/src/tests.rs @@ -44,7 +44,7 @@ pub mod helpers { impl FindActionHandler for TestClient {} - pub fn get_memory_db() -> Arc { + pub fn get_memory_db() -> Arc { Arc::new(kvdb_memorydb::create(1)) } diff --git a/state/src/traits.rs b/state/src/traits.rs index 0828b9ffad..164e2e53fa 100644 --- a/state/src/traits.rs +++ b/state/src/traits.rs @@ -93,7 +93,7 @@ pub trait TopStateView { } fn shard(&self, shard_id: ShardId) -> TrieResult>; - fn shard_state<'db>(&'db self, shard_id: ShardId) -> TrieResult>>; + fn shard_state<'db>(&'db self, shard_id: ShardId) -> TrieResult>>; fn shard_root(&self, shard_id: ShardId) -> TrieResult> { Ok(self.shard(shard_id)?.map(|shard| *shard.root())) diff --git a/stratum/src/lib.rs b/stratum/src/lib.rs index a92088c0ca..2a38335fff 100644 --- a/stratum/src/lib.rs +++ b/stratum/src/lib.rs @@ -76,7 +76,7 @@ pub struct Stratum { impl Stratum { pub fn start( addr: &SocketAddr, - dispatcher: Arc, + dispatcher: Arc, secret: Option, ) -> Result, Error> { let implementation = Arc::new(StratumImpl { @@ -135,7 +135,7 @@ struct StratumImpl { /// List of workers supposed to receive job update job_que: RwLock>, /// Payload manager - dispatcher: Arc, + dispatcher: Arc, /// Authorized workers (socket - worker_id) workers: Arc>>, /// Secret if any diff --git a/sync/src/block/downloader/header.rs b/sync/src/block/downloader/header.rs index 141998c988..d05a40074f 100644 --- a/sync/src/block/downloader/header.rs +++ b/sync/src/block/downloader/header.rs @@ -38,7 +38,7 @@ struct Pivot { #[derive(Clone)] pub struct HeaderDownloader { // NOTE: Use this member as minimum as possible. - client: Arc, + client: Arc, total_score: U256, best_hash: H256, @@ -55,7 +55,7 @@ impl HeaderDownloader { self.total_score } - pub fn new(client: Arc, total_score: U256, best_hash: H256) -> Self { + pub fn new(client: Arc, total_score: U256, best_hash: H256) -> Self { let best_header_hash = client.best_block_header().hash(); let best_score = client.block_total_score(&BlockId::Latest).expect("Best block always exist"); diff --git a/sync/src/block/extension.rs b/sync/src/block/extension.rs index d865a56fd2..1038e2c4b6 100644 --- a/sync/src/block/extension.rs +++ b/sync/src/block/extension.rs @@ -64,12 +64,12 @@ pub struct Extension { tokens_info: HashMap, token_generator: TokenGenerator, client: Arc, - api: Box, + api: Box, last_request: u64, } impl Extension { - pub fn new(client: Arc, api: Box) -> Extension { + pub fn new(client: Arc, api: Box) -> Extension { api.set_timer(SYNC_TIMER_TOKEN, Duration::from_millis(SYNC_TIMER_INTERVAL)).expect("Timer set succeeds"); let mut header = client.best_header(); diff --git a/sync/src/snapshot/snapshot.rs b/sync/src/snapshot/snapshot.rs index d0759e9494..d0e03eed00 100644 --- a/sync/src/snapshot/snapshot.rs +++ b/sync/src/snapshot/snapshot.rs @@ -71,7 +71,7 @@ impl Snapshot { Ok(()) } - fn read_chunk(&self, backing: Arc, root: &H256) -> Result { + fn read_chunk(&self, backing: Arc, root: &H256) -> Result { let file = File::open(self.file_for(root))?; let mut buf = Vec::new(); let mut snappy = snap::Reader::new(file); @@ -123,7 +123,7 @@ impl Snapshot { } struct Chunk { - journal: Box, + journal: Box, never_referenced_keys: Vec, } @@ -185,15 +185,15 @@ impl Chunk { } pub trait WriteSnapshot { - fn write_snapshot(&self, db: &KeyValueDB, root: &H256) -> Result<(), Error>; + fn write_snapshot(&self, db: &dyn KeyValueDB, root: &H256) -> Result<(), Error>; } pub trait ReadSnapshot { - fn read_snapshot(&self, db: Arc, root: &H256) -> Result<(), Error>; + fn read_snapshot(&self, db: Arc, root: &H256) -> Result<(), Error>; } impl WriteSnapshot for Snapshot { - fn write_snapshot(&self, db: &KeyValueDB, root: &H256) -> Result<(), Error> { + fn write_snapshot(&self, db: &dyn KeyValueDB, root: &H256) -> Result<(), Error> { let root_val = match db.get(COL_STATE, root) { Ok(Some(value)) => value.to_vec(), Ok(None) => return Err(Error::SyncError("Invalid state root, or the database is empty".to_string())), @@ -217,7 +217,7 @@ impl WriteSnapshot for Snapshot { } impl ReadSnapshot for Snapshot { - fn read_snapshot(&self, db: Arc, root: &H256) -> Result<(), Error> { + fn read_snapshot(&self, db: Arc, root: &H256) -> Result<(), Error> { let head = { let mut head = self.read_chunk(db.clone(), root)?; if head.purge() { @@ -253,7 +253,7 @@ impl ReadSnapshot for Snapshot { } } -fn get_node(db: &KeyValueDB, key: &H256) -> Result, Error> { +fn get_node(db: &dyn KeyValueDB, key: &H256) -> Result, Error> { match db.get(COL_STATE, key) { Ok(Some(value)) => Ok(value.to_vec()), Ok(None) => Err(Error::NodeNotFound(*key)), @@ -261,7 +261,7 @@ fn get_node(db: &KeyValueDB, key: &H256) -> Result, Error> { } } -fn children_of(db: &KeyValueDB, node: &[u8]) -> Result)>, Error> { +fn children_of(db: &dyn KeyValueDB, node: &[u8]) -> Result)>, Error> { let keys = match Node::decoded(node) { None => Vec::new(), Some(Node::Leaf(..)) => Vec::new(), @@ -275,7 +275,7 @@ fn children_of(db: &KeyValueDB, node: &[u8]) -> Result)>, Err Ok(result) } -fn enumerate_subtree(db: &KeyValueDB, root: &H256) -> Result)>, Error> { +fn enumerate_subtree(db: &dyn KeyValueDB, root: &H256) -> Result)>, Error> { let node = get_node(db, root)?; let children = match Node::decoded(&node) { None => Vec::new(), diff --git a/sync/src/transaction/extension.rs b/sync/src/transaction/extension.rs index ea24368749..4eb1aa912c 100644 --- a/sync/src/transaction/extension.rs +++ b/sync/src/transaction/extension.rs @@ -55,12 +55,12 @@ impl KnownTxs { pub struct Extension { known_txs: KnownTxs, peers: HashMap, - client: Arc, - api: Box, + client: Arc, + api: Box, } impl Extension { - pub fn new(client: Arc, api: Box) -> Self { + pub fn new(client: Arc, api: Box) -> Self { api.set_timer(BROADCAST_TIMER_TOKEN, Duration::from_millis(BROADCAST_TIMER_INTERVAL)) .expect("Timer set succeeds"); Extension { diff --git a/util/hashdb/src/lib.rs b/util/hashdb/src/lib.rs index 801928b4e7..3550d0619b 100644 --- a/util/hashdb/src/lib.rs +++ b/util/hashdb/src/lib.rs @@ -56,26 +56,26 @@ pub trait HashDB: AsHashDB + Send + Sync { /// Upcast trait. pub trait AsHashDB { /// Perform upcast to HashDB for anything that derives from HashDB. - fn as_hashdb(&self) -> &HashDB; + fn as_hashdb(&self) -> &dyn HashDB; /// Perform mutable upcast to HashDB for anything that derives from HashDB. - fn as_hashdb_mut(&mut self) -> &mut HashDB; + fn as_hashdb_mut(&mut self) -> &mut dyn HashDB; } impl AsHashDB for T { - fn as_hashdb(&self) -> &HashDB { + fn as_hashdb(&self) -> &dyn HashDB { self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { + fn as_hashdb_mut(&mut self) -> &mut dyn HashDB { self } } -impl<'a> AsHashDB for &'a mut HashDB { - fn as_hashdb(&self) -> &HashDB { +impl<'a> AsHashDB for &'a mut dyn HashDB { + fn as_hashdb(&self) -> &dyn HashDB { &**self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { + fn as_hashdb_mut(&mut self) -> &mut dyn HashDB { &mut **self } } diff --git a/util/io/src/service.rs b/util/io/src/service.rs index 65a8a7c016..91d564b333 100644 --- a/util/io/src/service.rs +++ b/util/io/src/service.rs @@ -176,7 +176,7 @@ struct UserTimer { once: bool, } -type HandlerType = RwLock>>>; +type HandlerType = RwLock>>>; /// Root IO handler. Manages user handler, messages and IO timers. pub struct IoManager @@ -479,7 +479,7 @@ where } /// Register an IO handler with the event loop. - pub fn register_handler(&self, handler: Arc + Send>) -> Result<(), IoError> { + pub fn register_handler(&self, handler: Arc + Send>) -> Result<(), IoError> { let h = Arc::clone(&handler); assert!(self.handler.read().is_none()); *self.handler.write() = Some(handler); diff --git a/util/io/src/worker.rs b/util/io/src/worker.rs index 841ec10455..ba292abf50 100644 --- a/util/io/src/worker.rs +++ b/util/io/src/worker.rs @@ -44,7 +44,7 @@ pub enum WorkType { pub struct Work { pub work_type: WorkType, pub token: usize, - pub handler: Arc>, + pub handler: Arc>, } /// An IO worker thread diff --git a/util/journaldb/src/archivedb.rs b/util/journaldb/src/archivedb.rs index 3859e5e9c4..62e5729780 100644 --- a/util/journaldb/src/archivedb.rs +++ b/util/journaldb/src/archivedb.rs @@ -37,14 +37,14 @@ use traits::JournalDB; /// that the states of any block the node has ever processed will be accessible. pub struct ArchiveDB { overlay: MemoryDB, - backing: Arc, + backing: Arc, latest_era: Option, column: Option, } impl ArchiveDB { /// Create a new instance from a key-value db. - pub fn new(backing: Arc, col: Option) -> ArchiveDB { + pub fn new(backing: Arc, col: Option) -> ArchiveDB { let latest_era = backing.get(col, &LATEST_ERA_KEY).expect("Low-level database error.").map(|val| decode::(&val)); ArchiveDB { @@ -109,7 +109,7 @@ impl HashDB for ArchiveDB { } impl JournalDB for ArchiveDB { - fn boxed_clone(&self) -> Box { + fn boxed_clone(&self) -> Box { Box::new(ArchiveDB { overlay: self.overlay.clone(), backing: self.backing.clone(), @@ -189,7 +189,7 @@ impl JournalDB for ArchiveDB { false } - fn backing(&self) -> &Arc { + fn backing(&self) -> &Arc { &self.backing } diff --git a/util/journaldb/src/lib.rs b/util/journaldb/src/lib.rs index 3ae7da9679..4614077fa0 100644 --- a/util/journaldb/src/lib.rs +++ b/util/journaldb/src/lib.rs @@ -85,7 +85,7 @@ impl fmt::Display for Algorithm { } /// Create a new `JournalDB` trait object over a generic key-value database. -pub fn new(backing: Arc<::kvdb::KeyValueDB>, algorithm: Algorithm, col: Option) -> Box { +pub fn new(backing: Arc, algorithm: Algorithm, col: Option) -> Box { match algorithm { Algorithm::Archive => Box::new(archivedb::ArchiveDB::new(backing, col)), } diff --git a/util/journaldb/src/traits.rs b/util/journaldb/src/traits.rs index 5bb39486c0..64fb31e54e 100644 --- a/util/journaldb/src/traits.rs +++ b/util/journaldb/src/traits.rs @@ -26,7 +26,7 @@ use std::sync::Arc; /// exclusive actions. pub trait JournalDB: HashDB { /// Return a copy of ourself, in a box. - fn boxed_clone(&self) -> Box; + fn boxed_clone(&self) -> Box; /// Returns the size of journalled state in memory. /// This function has a considerable speed requirement -- @@ -68,7 +68,7 @@ pub trait JournalDB: HashDB { } /// Get backing database. - fn backing(&self) -> &Arc; + fn backing(&self) -> &Arc; /// Clear internal strucutres. This should called after changes have been written /// to the backing strage diff --git a/util/kvdb/src/lib.rs b/util/kvdb/src/lib.rs index f430e4d46d..cdee56678f 100644 --- a/util/kvdb/src/lib.rs +++ b/util/kvdb/src/lib.rs @@ -183,4 +183,4 @@ pub trait KeyValueDB: Sync + Send { fn restore(&self, new_db: &str) -> Result<()>; } -pub type KeyValueDBIterator<'a> = Box, Box<[u8]>)> + 'a>; +pub type KeyValueDBIterator<'a> = Box, Box<[u8]>)> + 'a>; diff --git a/util/merkle/src/lib.rs b/util/merkle/src/lib.rs index dca921debe..63f7b708f7 100644 --- a/util/merkle/src/lib.rs +++ b/util/merkle/src/lib.rs @@ -140,17 +140,17 @@ pub enum TrieFactory {} impl TrieFactory { /// Create new immutable instance of Trie. - pub fn readonly<'db>(db: &'db HashDB, root: &'db H256) -> Result> { + pub fn readonly<'db>(db: &'db dyn HashDB, root: &'db H256) -> Result> { Ok(TrieDB::try_new(db, root)?) } /// Create new mutable instance of Trie. - pub fn create<'db>(db: &'db mut HashDB, root: &'db mut H256) -> Box { + pub fn create<'db>(db: &'db mut dyn HashDB, root: &'db mut H256) -> Box { Box::new(TrieDBMut::new(db, root)) } /// Create new mutable instance of trie and check for errors. - pub fn from_existing<'db>(db: &'db mut HashDB, root: &'db mut H256) -> Result> { + pub fn from_existing<'db>(db: &'db mut dyn HashDB, root: &'db mut H256) -> Result> { Ok(Box::new(TrieDBMut::from_existing(db, root)?)) } } diff --git a/util/merkle/src/triedb.rs b/util/merkle/src/triedb.rs index b377a1a74a..7ef72e31bb 100644 --- a/util/merkle/src/triedb.rs +++ b/util/merkle/src/triedb.rs @@ -48,14 +48,14 @@ use crate::{Query, Trie, TrieError}; /// } /// ``` pub struct TrieDB<'db> { - db: &'db HashDB, + db: &'db dyn HashDB, root: &'db H256, } impl<'db> TrieDB<'db> { /// Create a new trie with the backing database `db` and `root` /// Returns an error if `root` does not exist - pub fn try_new(db: &'db HashDB, root: &'db H256) -> crate::Result { + pub fn try_new(db: &'db dyn HashDB, root: &'db H256) -> crate::Result { if !db.contains(root) { Err(TrieError::InvalidStateRoot(*root)) } else { @@ -67,7 +67,7 @@ impl<'db> TrieDB<'db> { } /// Get the backing database. - pub fn db(&self) -> &HashDB { + pub fn db(&self) -> &dyn HashDB { self.db } diff --git a/util/merkle/src/triedbmut.rs b/util/merkle/src/triedbmut.rs index 456628d9fb..17b2a23da6 100644 --- a/util/merkle/src/triedbmut.rs +++ b/util/merkle/src/triedbmut.rs @@ -31,14 +31,14 @@ fn empty_children() -> [Option; 16] { } pub struct TrieDBMut<'a> { - db: &'a mut HashDB, + db: &'a mut dyn HashDB, // When Trie is empty, root has None. root: &'a mut H256, } impl<'a> TrieDBMut<'a> { /// Create a new trie with backing database `db` and empty `root`. - pub fn new(db: &'a mut HashDB, root: &'a mut H256) -> Self { + pub fn new(db: &'a mut dyn HashDB, root: &'a mut H256) -> Self { *root = BLAKE_NULL_RLP; TrieDBMut { @@ -49,7 +49,7 @@ impl<'a> TrieDBMut<'a> { /// Create a new trie with the backing database `db` and `root. /// Returns an error if `root` does not exist. - pub fn from_existing(db: &'a mut HashDB, root: &'a mut H256) -> crate::Result { + pub fn from_existing(db: &'a mut dyn HashDB, root: &'a mut H256) -> crate::Result { if !db.contains(root) { return Err(TrieError::InvalidStateRoot(*root)) } @@ -348,7 +348,7 @@ mod tests { use super::*; - fn populate_trie<'db>(db: &'db mut HashDB, root: &'db mut H256, v: &[(Vec, Vec)]) -> TrieDBMut<'db> { + fn populate_trie<'db>(db: &'db mut dyn HashDB, root: &'db mut H256, v: &[(Vec, Vec)]) -> TrieDBMut<'db> { let mut t = TrieDBMut::new(db, root); for (key, val) in v { t.insert(key, val).unwrap(); diff --git a/util/rlp_compress/src/lib.rs b/util/rlp_compress/src/lib.rs index 25c1fa7d82..2b0c1fe642 100644 --- a/util/rlp_compress/src/lib.rs +++ b/util/rlp_compress/src/lib.rs @@ -40,7 +40,7 @@ pub trait Decompressor { } /// Call this function to compress rlp. -pub fn compress(c: &[u8], swapper: &Compressor) -> ElasticArray1024 { +pub fn compress(c: &[u8], swapper: &dyn Compressor) -> ElasticArray1024 { let rlp = UntrustedRlp::new(c); if rlp.is_data() { ElasticArray1024::from_slice(swapper.compressed(rlp.as_raw()).unwrap_or_else(|| rlp.as_raw())) @@ -50,7 +50,7 @@ pub fn compress(c: &[u8], swapper: &Compressor) -> ElasticArray1024 { } /// Call this function to decompress rlp. -pub fn decompress(c: &[u8], swapper: &Decompressor) -> ElasticArray1024 { +pub fn decompress(c: &[u8], swapper: &dyn Decompressor) -> ElasticArray1024 { let rlp = UntrustedRlp::new(c); if rlp.is_data() { ElasticArray1024::from_slice(swapper.decompressed(rlp.as_raw()).unwrap_or_else(|| rlp.as_raw())) diff --git a/util/secp256k1/src/lib.rs b/util/secp256k1/src/lib.rs index 0bfb6dc16b..21b37dc0d4 100644 --- a/util/secp256k1/src/lib.rs +++ b/util/secp256k1/src/lib.rs @@ -333,7 +333,7 @@ impl fmt::Display for Error { } impl error::Error for Error { - fn cause(&self) -> Option<&error::Error> { + fn cause(&self) -> Option<&dyn error::Error> { None } diff --git a/util/timer/src/timer.rs b/util/timer/src/timer.rs index c0e4990a81..565685ae2b 100644 --- a/util/timer/src/timer.rs +++ b/util/timer/src/timer.rs @@ -106,7 +106,7 @@ type TimerId = usize; pub struct TimerApi { timer_id: TimerId, timer_name: Arc>>, - handler: Arc>>>, + handler: Arc>>>, scheduler: Weak, } @@ -533,7 +533,7 @@ struct Schedule { schedule_id: ScheduleId, repeat: Option, state_control: Arc, - handler: Weak, + handler: Weak, timer_name: TimerName, } @@ -569,7 +569,7 @@ struct Callback { schedule_id: ScheduleId, from_oneshot_schedule: bool, state_control: Arc, - handler: Arc, + handler: Arc, timer_name: TimerName, } diff --git a/vm/src/executor.rs b/vm/src/executor.rs index f5dbd8843a..ab03140cd7 100644 --- a/vm/src/executor.rs +++ b/vm/src/executor.rs @@ -164,7 +164,7 @@ pub fn execute( unlock: &[Instruction], params: &[Vec], lock: &[Instruction], - tx: &PartialHashing, + tx: &dyn PartialHashing, config: Config, cur: &AssetTransferInput, burn: bool, From cc1b9ba72506024d591eabce3bf9f4206bfe6123 Mon Sep 17 00:00:00 2001 From: Seulgi Kim Date: Mon, 7 Oct 2019 11:14:57 +0900 Subject: [PATCH 044/105] `...` range patterns are deprecated --- network/src/p2p/handler.rs | 58 +++++++++++++++++------------------ sync/src/block/extension.rs | 2 +- util/rlp/src/stream.rs | 4 +-- util/rlp/src/untrusted_rlp.rs | 22 ++++++------- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/network/src/p2p/handler.rs b/network/src/p2p/handler.rs index 6cc7a0193e..ce46872384 100644 --- a/network/src/p2p/handler.rs +++ b/network/src/p2p/handler.rs @@ -363,15 +363,15 @@ impl IoHandler for Handler { const CHECK_BOOTSTRAP_INTERVAL: Duration = Duration::from_secs(15); io.register_timer_once(CONNECT_TO_BOOTSTRAP, CHECK_BOOTSTRAP_INTERVAL); } - FIRST_WAIT_SYNC...LAST_WAIT_SYNC => { + FIRST_WAIT_SYNC..=LAST_WAIT_SYNC => { cwarn!(NETWORK, "No sync message from {}", timer); io.deregister_stream(wait_sync_stream(timer)); } - FIRST_WAIT_ACK...LAST_WAIT_ACK => { + FIRST_WAIT_ACK..=LAST_WAIT_ACK => { cwarn!(NETWORK, "No ack message from {}", timer); io.deregister_stream(wait_ack_stream(timer)); } - FIRST_TRY_SYNC...LAST_TRY_SYNC => { + FIRST_TRY_SYNC..=LAST_TRY_SYNC => { let stream = retry_sync_stream(timer); let mut outgoing_connections = self.outgoing_connections.write(); if let Some(con) = outgoing_connections.get_mut(&stream) { @@ -430,7 +430,7 @@ impl IoHandler for Handler { let stream = *self.remote_node_ids_reverse.read().get(&node_id).ok_or_else(|| Error::InvalidNode(node_id))?; let (network_message_size, peer_addr) = match stream { - FIRST_OUTBOUND...LAST_OUTBOUND => { + FIRST_OUTBOUND..=LAST_OUTBOUND => { let mut outbound_connections = self.outbound_connections.write(); if let Some(con) = outbound_connections.get_mut(&stream) { let _f = finally(|| { @@ -445,7 +445,7 @@ impl IoHandler for Handler { return Err(format!("{} is an invalid stream", stream).into()) } } - FIRST_INBOUND...LAST_INBOUND => { + FIRST_INBOUND..=LAST_INBOUND => { let mut inbound_connections = self.inbound_connections.write(); if let Some(con) = inbound_connections.get_mut(&stream) { let _f = finally(|| { @@ -577,19 +577,19 @@ impl IoHandler for Handler { fn stream_hup(&self, io: &IoContext, stream: StreamToken) -> IoHandlerResult<()> { match stream { - FIRST_INBOUND...LAST_INBOUND => { + FIRST_INBOUND..=LAST_INBOUND => { cinfo!(NETWORK, "Hang-up inbound stream({})", stream); io.deregister_stream(stream); } - FIRST_OUTBOUND...LAST_OUTBOUND => { + FIRST_OUTBOUND..=LAST_OUTBOUND => { cinfo!(NETWORK, "Hang-up outbound stream({})", stream); io.deregister_stream(stream); } - FIRST_INCOMING...LAST_INCOMING => { + FIRST_INCOMING..=LAST_INCOMING => { cinfo!(NETWORK, "Hang-up incoming stream({})", stream); io.deregister_stream(stream); } - FIRST_OUTGOING...LAST_OUTGOING => { + FIRST_OUTGOING..=LAST_OUTGOING => { cinfo!(NETWORK, "Hang-up outgoing stream({})", stream); io.deregister_stream(stream); } @@ -647,7 +647,7 @@ impl IoHandler for Handler { io.register_timer_once(wait_sync_timer(token), WAIT_SYNC); } } - FIRST_INBOUND...LAST_INBOUND => { + FIRST_INBOUND..=LAST_INBOUND => { let mut inbound_connections = self.inbound_connections.write(); if let Some(con) = inbound_connections.get_mut(&stream_token) { let should_update = AtomicBool::new(true); @@ -716,7 +716,7 @@ impl IoHandler for Handler { cdebug!(NETWORK, "Invalid inbound token({}) on read", stream_token); } } - FIRST_OUTBOUND...LAST_OUTBOUND => { + FIRST_OUTBOUND..=LAST_OUTBOUND => { let mut outbound_connections = self.outbound_connections.write(); if let Some(con) = outbound_connections.get_mut(&stream_token) { let should_update = AtomicBool::new(true); @@ -761,7 +761,7 @@ impl IoHandler for Handler { cdebug!(NETWORK, "Invalid outbound token({}) on read", stream_token); } } - FIRST_INCOMING...LAST_INCOMING => { + FIRST_INCOMING..=LAST_INCOMING => { let mut incoming_connections = self.incoming_connections.write(); if let Some(con) = incoming_connections.get_mut(&stream_token) { let should_update = AtomicBool::new(true); @@ -855,7 +855,7 @@ impl IoHandler for Handler { cdebug!(NETWORK, "Invalid incoming token({}) on read", stream_token); } } - FIRST_OUTGOING...LAST_OUTGOING => { + FIRST_OUTGOING..=LAST_OUTGOING => { let mut outgoing_connections = self.outgoing_connections.write(); if let Some(con) = outgoing_connections.get_mut(&stream_token) { let should_update = AtomicBool::new(true); @@ -904,28 +904,28 @@ impl IoHandler for Handler { fn stream_writable(&self, _io: &IoContext, stream: StreamToken) -> IoHandlerResult<()> { match stream { - FIRST_INBOUND...LAST_INBOUND => { + FIRST_INBOUND..=LAST_INBOUND => { if let Some(con) = self.inbound_connections.write().get_mut(&stream) { con.flush()?; } else { cdebug!(NETWORK, "Invalid inbound token({}) on write", stream); } } - FIRST_OUTBOUND...LAST_OUTBOUND => { + FIRST_OUTBOUND..=LAST_OUTBOUND => { if let Some(con) = self.outbound_connections.write().get_mut(&stream) { con.flush()?; } else { cdebug!(NETWORK, "Invalid outbound token({}) on write", stream); } } - FIRST_INCOMING...LAST_INCOMING => { + FIRST_INCOMING..=LAST_INCOMING => { if let Some(con) = self.incoming_connections.write().get_mut(&stream) { con.flush()?; } else { cdebug!(NETWORK, "Invalid incoming token({}) on write", stream); } } - FIRST_OUTGOING...LAST_OUTGOING => { + FIRST_OUTGOING..=LAST_OUTGOING => { if let Some(con) = self.outgoing_connections.write().get_mut(&stream) { con.flush()?; } else { @@ -948,7 +948,7 @@ impl IoHandler for Handler { event_loop.register(&self.listener, reg, Ready::readable(), PollOpt::edge())?; ctrace!(NETWORK, "TCP connection starts for {}", self.socket_address); } - FIRST_INBOUND...LAST_INBOUND => { + FIRST_INBOUND..=LAST_INBOUND => { if let Some(con) = self.inbound_connections.read().get(&stream) { con.register(reg, event_loop)?; ctrace!(NETWORK, "Inbound connect({}) registered", stream); @@ -956,7 +956,7 @@ impl IoHandler for Handler { cdebug!(NETWORK, "Invalid inbound token({}) on register", stream); } } - FIRST_OUTBOUND...LAST_OUTBOUND => { + FIRST_OUTBOUND..=LAST_OUTBOUND => { if let Some(con) = self.outbound_connections.read().get(&stream) { con.register(reg, event_loop)?; ctrace!(NETWORK, "Outbound connect({}) registered", stream); @@ -964,7 +964,7 @@ impl IoHandler for Handler { cdebug!(NETWORK, "Invalid outbound token({}) on register", stream); } } - FIRST_INCOMING...LAST_INCOMING => { + FIRST_INCOMING..=LAST_INCOMING => { if let Some(con) = self.incoming_connections.read().get(&stream) { con.register(reg, event_loop)?; ctrace!(NETWORK, "Incoming connect({}) registered", stream); @@ -972,7 +972,7 @@ impl IoHandler for Handler { cdebug!(NETWORK, "Invalid incoming token({}) on register", stream); } } - FIRST_OUTGOING...LAST_OUTGOING => { + FIRST_OUTGOING..=LAST_OUTGOING => { if let Some(con) = self.outgoing_connections.read().get(&stream) { con.register(reg, event_loop)?; ctrace!(NETWORK, "Outgoing connect({}) registered", stream); @@ -1000,7 +1000,7 @@ impl IoHandler for Handler { ACCEPT => { event_loop.reregister(&self.listener, reg, Ready::readable(), PollOpt::edge())?; } - FIRST_INBOUND...LAST_INBOUND => { + FIRST_INBOUND..=LAST_INBOUND => { if let Some(con) = self.inbound_connections.read().get(&stream) { con.reregister(reg, event_loop)?; ctrace!(NETWORK, "Inbound connect({}) updated", stream); @@ -1008,7 +1008,7 @@ impl IoHandler for Handler { cdebug!(NETWORK, "Invalid inbound token({}) on update", stream); } } - FIRST_OUTBOUND...LAST_OUTBOUND => { + FIRST_OUTBOUND..=LAST_OUTBOUND => { if let Some(con) = self.outbound_connections.read().get(&stream) { con.reregister(reg, event_loop)?; ctrace!(NETWORK, "Outbound connect({}) updated", stream); @@ -1016,7 +1016,7 @@ impl IoHandler for Handler { cdebug!(NETWORK, "Invalid outbound token({}) on update", stream); } } - FIRST_INCOMING...LAST_INCOMING => { + FIRST_INCOMING..=LAST_INCOMING => { if let Some(con) = self.incoming_connections.read().get(&stream) { con.reregister(reg, event_loop)?; ctrace!(NETWORK, "Incoming connect({}) updated", stream); @@ -1024,7 +1024,7 @@ impl IoHandler for Handler { cdebug!(NETWORK, "Invalid incoming token({}) on update", stream); } } - FIRST_OUTGOING...LAST_OUTGOING => { + FIRST_OUTGOING..=LAST_OUTGOING => { if let Some(con) = self.outgoing_connections.read().get(&stream) { con.reregister(reg, event_loop)?; ctrace!(NETWORK, "Outgoing connect({}) updated", stream); @@ -1044,7 +1044,7 @@ impl IoHandler for Handler { ) -> IoHandlerResult<()> { self.channel.send(Message::StartConnect)?; match stream { - FIRST_INBOUND...LAST_INBOUND => { + FIRST_INBOUND..=LAST_INBOUND => { let mut inbound_connections = self.inbound_connections.write(); if let Some(con) = inbound_connections.remove(&stream) { if let Some(node_id) = self.remote_node_ids.write().remove(&stream) { @@ -1061,7 +1061,7 @@ impl IoHandler for Handler { cdebug!(NETWORK, "Invalid inbound token({}) on deregister", stream); } } - FIRST_OUTBOUND...LAST_OUTBOUND => { + FIRST_OUTBOUND..=LAST_OUTBOUND => { let mut outbound_connections = self.outbound_connections.write(); if let Some(con) = outbound_connections.remove(&stream) { if let Some(node_id) = self.remote_node_ids.write().remove(&stream) { @@ -1078,7 +1078,7 @@ impl IoHandler for Handler { cdebug!(NETWORK, "Invalid outbound token({}) on deregister", stream); } } - FIRST_INCOMING...LAST_INCOMING => { + FIRST_INCOMING..=LAST_INCOMING => { let mut incoming_connections = self.incoming_connections.write(); if let Some(con) = incoming_connections.remove(&stream) { con.deregister(event_loop)?; @@ -1107,7 +1107,7 @@ impl IoHandler for Handler { cdebug!(NETWORK, "Invalid incoming token({}) on deregister", stream); } } - FIRST_OUTGOING...LAST_OUTGOING => { + FIRST_OUTGOING..=LAST_OUTGOING => { let mut outgoing_connections = self.outgoing_connections.write(); if let Some(con) = outgoing_connections.remove(&stream) { con.deregister(event_loop)?; diff --git a/sync/src/block/extension.rs b/sync/src/block/extension.rs index 1038e2c4b6..32927c4fab 100644 --- a/sync/src/block/extension.rs +++ b/sync/src/block/extension.rs @@ -311,7 +311,7 @@ impl NetworkExtension for Extension { } } } - SYNC_EXPIRE_TOKEN_BEGIN...SYNC_EXPIRE_TOKEN_END => { + SYNC_EXPIRE_TOKEN_BEGIN..=SYNC_EXPIRE_TOKEN_END => { self.check_sync_variable(); let (id, request_id) = { let token_info = match self.tokens_info.get_mut(&token) { diff --git a/util/rlp/src/stream.rs b/util/rlp/src/stream.rs index 34c2b35da3..2e00952433 100644 --- a/util/rlp/src/stream.rs +++ b/util/rlp/src/stream.rs @@ -352,7 +352,7 @@ impl<'a> BasicEncoder<'a> { fn insert_list_payload(&mut self, len: usize, pos: usize) { // 1 byte was already reserved for payload earlier match len { - 0...55 => { + 0..=55 => { self.buffer[pos - 1] = 0xc0u8 + len as u8; } _ => { @@ -370,7 +370,7 @@ impl<'a> BasicEncoder<'a> { // byte is its own encoding if < 0x80 1 if value[0] < 0x80 => self.buffer.push(value[0]), // (prefix + length), followed by the string - len @ 1...55 => { + len @ 1..=55 => { self.buffer.push(0x80u8 + len as u8); self.buffer.append_slice(value); } diff --git a/util/rlp/src/untrusted_rlp.rs b/util/rlp/src/untrusted_rlp.rs index 161d771bba..79944565c4 100644 --- a/util/rlp/src/untrusted_rlp.rs +++ b/util/rlp/src/untrusted_rlp.rs @@ -89,14 +89,14 @@ impl PayloadInfo { expected: 1, got: 0, }), - Some(0...0x7f) => Ok(PayloadInfo::new(0, 1)), - Some(l @ 0x80...0xb7) => Ok(PayloadInfo::new(1, l as usize - 0x80)), - Some(l @ 0xb8...0xbf) => { + Some(0..=0x7f) => Ok(PayloadInfo::new(0, 1)), + Some(l @ 0x80..=0xb7) => Ok(PayloadInfo::new(1, l as usize - 0x80)), + Some(l @ 0xb8..=0xbf) => { let len_of_len = l as usize - 0xb7; calculate_payload_info(header_bytes, len_of_len) } - Some(l @ 0xc0...0xf7) => Ok(PayloadInfo::new(1, l as usize - 0xc0)), - Some(l @ 0xf8...0xff) => { + Some(l @ 0xc0..=0xf7) => Ok(PayloadInfo::new(1, l as usize - 0xc0)), + Some(l @ 0xf8..=0xff) => { let len_of_len = l as usize - 0xf7; calculate_payload_info(header_bytes, len_of_len) } @@ -263,9 +263,9 @@ where } match self.bytes[0] { - 0...0x80 => true, - 0x81...0xb7 => self.bytes[1] != 0, - b @ 0xb8...0xbf => self.bytes[1 + b as usize - 0xb7] != 0, + 0..=0x80 => true, + 0x81..=0xb7 => self.bytes[1] != 0, + b @ 0xb8..=0xbf => self.bytes[1 + b as usize - 0xb7] != 0, _ => false, } } @@ -402,9 +402,9 @@ impl<'a> BasicDecoder<'a> { got: 0, }), // Single byte value. - Some(l @ 0...0x7f) => Ok(f(&[l])?), + Some(l @ 0..=0x7f) => Ok(f(&[l])?), // 0-55 bytes - Some(l @ 0x80...0xb7) => { + Some(l @ 0x80..=0xb7) => { let last_index_of = 1 + l as usize - 0x80; if bytes.len() < last_index_of { return Err(DecoderError::RlpInconsistentLengthAndData { @@ -419,7 +419,7 @@ impl<'a> BasicDecoder<'a> { Ok(f(d)?) } // Longer than 55 bytes. - Some(l @ 0xb8...0xbf) => { + Some(l @ 0xb8..=0xbf) => { let len_of_len = l as usize - 0xb7; let begin_of_value = 1 as usize + len_of_len; if bytes.len() < begin_of_value { From e6f83c77e1158eb2994132b0f125681d46111506 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Mon, 7 Oct 2019 17:41:06 +0900 Subject: [PATCH 045/105] Do not generate a seal if the block is generated from a past view If generating a block takes too much time, the view could be changed before the miner module requests the signature. If the Tendermint module receives a signature request of an old view, it should ignore the message. Before this commit, the Tendermint module was crashing when it gets a signature request from an old view. --- core/src/consensus/tendermint/worker.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 86f6344af2..45ceb5ad6b 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -1044,7 +1044,13 @@ impl Worker { return Seal::None } - assert!(self.is_signer_proposer(&parent_hash)); + // We don't know at which view the node starts generating a block. + // If this node's signer is not proposer at the current view, return none. + if !self.is_signer_proposer(&parent_hash) { + cwarn!(ENGINE, "Seal request for an old view"); + return Seal::None + } + assert_eq!(Proposal::None, self.proposal); assert_eq!(height, self.height); From 46433fbaaa8a9f2272b8688fea4df143e4bf67e1 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Mon, 7 Oct 2019 15:47:30 +0900 Subject: [PATCH 046/105] Recover TendermintState when empty proposal timer is fired in a wrong time The Tendermint module was changing its step to 'Propose' when the "engine timeout empty proposal" timer is fired. If the timer is called in the wrong time the step should not be changed. This commit makes the step change when it is needed. --- core/src/consensus/tendermint/types.rs | 9 +++++++ core/src/consensus/tendermint/worker.rs | 36 +++++++++++++------------ 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/core/src/consensus/tendermint/types.rs b/core/src/consensus/tendermint/types.rs index bdacb40906..7cf582ebfe 100644 --- a/core/src/consensus/tendermint/types.rs +++ b/core/src/consensus/tendermint/types.rs @@ -76,6 +76,15 @@ impl TendermintState { } } + pub fn is_propose_wait_empty_block_timer(&self) -> bool { + match self { + TendermintState::ProposeWaitEmptyBlockTimer { + .. + } => true, + _ => false, + } + } + pub fn is_commit(&self) -> bool { match self { TendermintState::Commit { diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 45ceb5ad6b..c617eb3786 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -1214,25 +1214,27 @@ impl Worker { fn on_timeout(&mut self, token: usize) { // Timeout from empty block generation if token == ENGINE_TIMEOUT_EMPTY_PROPOSAL { - let prev_step = mem::replace(&mut self.step, TendermintState::Propose); - match prev_step { - TendermintState::ProposeWaitEmptyBlockTimer { - block, - } => { - if self.height == block.header().number() { - cdebug!( - ENGINE, - "Empty proposal timer is finished, go to the prevote step and broadcast the block" - ); - self.submit_proposal_block(block.as_ref()); - } else { - cwarn!(ENGINE, "Empty proposal timer was for previous height."); - } - } - _ => { - cwarn!(ENGINE, "Empty proposal timer was not cleared."); + let block = if self.step.is_propose_wait_empty_block_timer() { + let previous = mem::replace(&mut self.step, TendermintState::Propose); + match previous { + TendermintState::ProposeWaitEmptyBlockTimer { + block, + } => block, + _ => unreachable!(), } + } else { + cwarn!(ENGINE, "Empty proposal timer was not cleared."); + return + }; + + if self.height == block.header().number() { + cdebug!(ENGINE, "Empty proposal timer is finished, go to the prevote step and broadcast the block"); + self.submit_proposal_block(block.as_ref()); + } else { + self.move_to_step(TendermintState::Prevote, false); + cwarn!(ENGINE, "Empty proposal timer was for previous height."); } + return } From 2a9bc90e6e78cc1cdda0a45b56af5dfca81e8e6a Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Mon, 7 Oct 2019 16:46:08 +0900 Subject: [PATCH 047/105] Inline submit_proposal_block function in Tendermint It is hard to know whether submit_proposal_block changes step or not. Since submit_proposal_block has only two lines of code, it doesn't remove code duplication. To clarify step transition, inline the submit_proposal_block function. --- core/src/consensus/tendermint/worker.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index c617eb3786..04df0942bd 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -949,7 +949,9 @@ impl Worker { block, } => { if !block.transactions().is_empty() { - self.submit_proposal_block(&block); + cinfo!(ENGINE, "Submitting proposal block {}", block.header().hash()); + self.move_to_step(TendermintState::Prevote, false); + self.broadcast_proposal_block(self.view, encoded::Block::new(block.rlp_bytes())); } else { ctrace!(ENGINE, "Empty proposal is generated, set timer"); self.step = TendermintState::ProposeWaitEmptyBlockTimer { @@ -986,12 +988,6 @@ impl Worker { } } - fn submit_proposal_block(&mut self, sealed_block: &SealedBlock) { - cinfo!(ENGINE, "Submitting proposal block {}", sealed_block.header().hash()); - self.move_to_step(TendermintState::Prevote, false); - self.broadcast_proposal_block(self.view, encoded::Block::new(sealed_block.rlp_bytes())); - } - fn backup(&self) { backup(self.client().get_kvdb().as_ref(), BackupView { height: &self.height, @@ -1227,11 +1223,14 @@ impl Worker { return }; + // When self.height != block.header().number() && "propose timeout" is already called, + // the state is stuck and can't move to Prevote. We should change the step to Prevote. + self.move_to_step(TendermintState::Prevote, false); if self.height == block.header().number() { cdebug!(ENGINE, "Empty proposal timer is finished, go to the prevote step and broadcast the block"); - self.submit_proposal_block(block.as_ref()); + cinfo!(ENGINE, "Submitting proposal block {}", block.header().hash()); + self.broadcast_proposal_block(self.view, encoded::Block::new(block.rlp_bytes())); } else { - self.move_to_step(TendermintState::Prevote, false); cwarn!(ENGINE, "Empty proposal timer was for previous height."); } From fb752803e9aa8ebed39357a7d4f2e93f282fcd3f Mon Sep 17 00:00:00 2001 From: Seulgi Kim Date: Mon, 7 Oct 2019 15:59:08 +0900 Subject: [PATCH 048/105] Extract secp256k1 --- Cargo.lock | 103 +- key/Cargo.toml | 2 +- util/secp256k1/.gitignore | 4 - util/secp256k1/.travis.yml | 23 - util/secp256k1/Cargo.toml | 33 - util/secp256k1/LICENSE | 122 - util/secp256k1/Makefile | 6 - util/secp256k1/README.md | 15 - util/secp256k1/build.rs | 102 - util/secp256k1/depend/secp256k1/.gitignore | 49 - util/secp256k1/depend/secp256k1/.travis.yml | 70 - util/secp256k1/depend/secp256k1/COPYING | 19 - util/secp256k1/depend/secp256k1/Makefile.am | 181 - util/secp256k1/depend/secp256k1/README.md | 61 - util/secp256k1/depend/secp256k1/TODO | 3 - util/secp256k1/depend/secp256k1/autogen.sh | 3 - .../build-aux/m4/ax_jni_include_dir.m4 | 140 - .../build-aux/m4/ax_prog_cc_for_build.m4 | 125 - .../secp256k1/build-aux/m4/bitcoin_secp.m4 | 69 - util/secp256k1/depend/secp256k1/configure.ac | 511 -- .../secp256k1/contrib/lax_der_parsing.c | 150 - .../secp256k1/contrib/lax_der_parsing.h | 91 - .../contrib/lax_der_privatekey_parsing.c | 113 - .../contrib/lax_der_privatekey_parsing.h | 90 - .../depend/secp256k1/include/secp256k1.h | 621 --- .../depend/secp256k1/include/secp256k1_ecdh.h | 31 - .../secp256k1/include/secp256k1_recovery.h | 110 - .../secp256k1/include/secp256k1_schnorr.h | 173 - .../depend/secp256k1/libsecp256k1.pc.in | 13 - .../secp256k1/depend/secp256k1/obj/.gitignore | 0 .../depend/secp256k1/sage/group_prover.sage | 322 -- .../depend/secp256k1/sage/secp256k1.sage | 306 -- .../secp256k1/sage/weierstrass_prover.sage | 264 - .../secp256k1/src/asm/field_10x26_arm.s | 919 ---- .../depend/secp256k1/src/basic-config.h | 33 - util/secp256k1/depend/secp256k1/src/bench.h | 66 - .../depend/secp256k1/src/bench_ecdh.c | 54 - .../depend/secp256k1/src/bench_internal.c | 382 -- .../depend/secp256k1/src/bench_recover.c | 60 - .../secp256k1/src/bench_schnorr_verify.c | 73 - .../depend/secp256k1/src/bench_sign.c | 56 - .../depend/secp256k1/src/bench_verify.c | 112 - util/secp256k1/depend/secp256k1/src/ecdsa.h | 21 - .../depend/secp256k1/src/ecdsa_impl.h | 313 -- util/secp256k1/depend/secp256k1/src/eckey.h | 25 - .../depend/secp256k1/src/eckey_impl.h | 100 - util/secp256k1/depend/secp256k1/src/ecmult.h | 31 - .../depend/secp256k1/src/ecmult_const.h | 15 - .../depend/secp256k1/src/ecmult_const_impl.h | 240 - .../depend/secp256k1/src/ecmult_gen.h | 43 - .../depend/secp256k1/src/ecmult_gen_impl.h | 210 - .../depend/secp256k1/src/ecmult_impl.h | 406 -- util/secp256k1/depend/secp256k1/src/ext.c | 60 - util/secp256k1/depend/secp256k1/src/field.h | 132 - .../depend/secp256k1/src/field_10x26.h | 48 - .../depend/secp256k1/src/field_10x26_impl.h | 1161 ----- .../depend/secp256k1/src/field_5x52.h | 47 - .../secp256k1/src/field_5x52_asm_impl.h | 502 -- .../depend/secp256k1/src/field_5x52_impl.h | 496 -- .../secp256k1/src/field_5x52_int128_impl.h | 277 - .../depend/secp256k1/src/field_impl.h | 315 -- .../depend/secp256k1/src/gen_context.c | 74 - util/secp256k1/depend/secp256k1/src/group.h | 144 - .../depend/secp256k1/src/group_impl.h | 700 --- util/secp256k1/depend/secp256k1/src/hash.h | 41 - .../depend/secp256k1/src/hash_impl.h | 281 - .../src/java/org/bitcoin/NativeSecp256k1.java | 478 -- .../java/org/bitcoin/NativeSecp256k1Test.java | 226 - .../java/org/bitcoin/NativeSecp256k1Util.java | 45 - .../java/org/bitcoin/Secp256k1Context.java | 51 - .../src/java/org_bitcoin_NativeSecp256k1.c | 411 -- .../src/java/org_bitcoin_NativeSecp256k1.h | 127 - .../src/java/org_bitcoin_Secp256k1Context.c | 15 - .../src/java/org_bitcoin_Secp256k1Context.h | 22 - .../src/modules/ecdh/Makefile.am.include | 8 - .../secp256k1/src/modules/ecdh/main_impl.h | 54 - .../secp256k1/src/modules/ecdh/tests_impl.h | 105 - .../src/modules/recovery/Makefile.am.include | 8 - .../src/modules/recovery/main_impl.h | 193 - .../src/modules/recovery/tests_impl.h | 393 -- .../src/modules/schnorr/Makefile.am.include | 10 - .../secp256k1/src/modules/schnorr/main_impl.h | 164 - .../secp256k1/src/modules/schnorr/schnorr.h | 20 - .../src/modules/schnorr/schnorr_impl.h | 207 - .../src/modules/schnorr/tests_impl.h | 175 - util/secp256k1/depend/secp256k1/src/num.h | 74 - util/secp256k1/depend/secp256k1/src/num_gmp.h | 20 - .../depend/secp256k1/src/num_gmp_impl.h | 288 -- .../secp256k1/depend/secp256k1/src/num_impl.h | 24 - util/secp256k1/depend/secp256k1/src/scalar.h | 106 - .../depend/secp256k1/src/scalar_4x64.h | 19 - .../depend/secp256k1/src/scalar_4x64_impl.h | 949 ---- .../depend/secp256k1/src/scalar_8x32.h | 19 - .../depend/secp256k1/src/scalar_8x32_impl.h | 721 --- .../depend/secp256k1/src/scalar_impl.h | 333 -- .../depend/secp256k1/src/scalar_low.h | 15 - .../depend/secp256k1/src/scalar_low_impl.h | 114 - .../depend/secp256k1/src/secp256k1.c | 588 --- .../secp256k1/depend/secp256k1/src/testrand.h | 38 - .../depend/secp256k1/src/testrand_impl.h | 110 - util/secp256k1/depend/secp256k1/src/tests.c | 4545 ----------------- .../depend/secp256k1/src/tests_exhaustive.c | 470 -- util/secp256k1/depend/secp256k1/src/util.h | 113 - util/secp256k1/src/constants.rs | 60 - util/secp256k1/src/ecdh.rs | 144 - util/secp256k1/src/ffi.rs | 337 -- util/secp256k1/src/key.rs | 635 --- util/secp256k1/src/lib.rs | 964 ---- util/secp256k1/src/macros.rs | 148 - util/secp256k1/src/schnorr.rs | 182 - vm/Cargo.toml | 2 +- 111 files changed, 8 insertions(+), 25084 deletions(-) delete mode 100644 util/secp256k1/.gitignore delete mode 100644 util/secp256k1/.travis.yml delete mode 100644 util/secp256k1/Cargo.toml delete mode 100644 util/secp256k1/LICENSE delete mode 100644 util/secp256k1/Makefile delete mode 100644 util/secp256k1/README.md delete mode 100644 util/secp256k1/build.rs delete mode 100644 util/secp256k1/depend/secp256k1/.gitignore delete mode 100644 util/secp256k1/depend/secp256k1/.travis.yml delete mode 100644 util/secp256k1/depend/secp256k1/COPYING delete mode 100644 util/secp256k1/depend/secp256k1/Makefile.am delete mode 100644 util/secp256k1/depend/secp256k1/README.md delete mode 100644 util/secp256k1/depend/secp256k1/TODO delete mode 100755 util/secp256k1/depend/secp256k1/autogen.sh delete mode 100644 util/secp256k1/depend/secp256k1/build-aux/m4/ax_jni_include_dir.m4 delete mode 100644 util/secp256k1/depend/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 delete mode 100644 util/secp256k1/depend/secp256k1/build-aux/m4/bitcoin_secp.m4 delete mode 100644 util/secp256k1/depend/secp256k1/configure.ac delete mode 100644 util/secp256k1/depend/secp256k1/contrib/lax_der_parsing.c delete mode 100644 util/secp256k1/depend/secp256k1/contrib/lax_der_parsing.h delete mode 100644 util/secp256k1/depend/secp256k1/contrib/lax_der_privatekey_parsing.c delete mode 100644 util/secp256k1/depend/secp256k1/contrib/lax_der_privatekey_parsing.h delete mode 100644 util/secp256k1/depend/secp256k1/include/secp256k1.h delete mode 100644 util/secp256k1/depend/secp256k1/include/secp256k1_ecdh.h delete mode 100644 util/secp256k1/depend/secp256k1/include/secp256k1_recovery.h delete mode 100644 util/secp256k1/depend/secp256k1/include/secp256k1_schnorr.h delete mode 100644 util/secp256k1/depend/secp256k1/libsecp256k1.pc.in delete mode 100644 util/secp256k1/depend/secp256k1/obj/.gitignore delete mode 100644 util/secp256k1/depend/secp256k1/sage/group_prover.sage delete mode 100644 util/secp256k1/depend/secp256k1/sage/secp256k1.sage delete mode 100644 util/secp256k1/depend/secp256k1/sage/weierstrass_prover.sage delete mode 100644 util/secp256k1/depend/secp256k1/src/asm/field_10x26_arm.s delete mode 100644 util/secp256k1/depend/secp256k1/src/basic-config.h delete mode 100644 util/secp256k1/depend/secp256k1/src/bench.h delete mode 100644 util/secp256k1/depend/secp256k1/src/bench_ecdh.c delete mode 100644 util/secp256k1/depend/secp256k1/src/bench_internal.c delete mode 100644 util/secp256k1/depend/secp256k1/src/bench_recover.c delete mode 100644 util/secp256k1/depend/secp256k1/src/bench_schnorr_verify.c delete mode 100644 util/secp256k1/depend/secp256k1/src/bench_sign.c delete mode 100644 util/secp256k1/depend/secp256k1/src/bench_verify.c delete mode 100644 util/secp256k1/depend/secp256k1/src/ecdsa.h delete mode 100644 util/secp256k1/depend/secp256k1/src/ecdsa_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/eckey.h delete mode 100644 util/secp256k1/depend/secp256k1/src/eckey_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/ecmult.h delete mode 100644 util/secp256k1/depend/secp256k1/src/ecmult_const.h delete mode 100644 util/secp256k1/depend/secp256k1/src/ecmult_const_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/ecmult_gen.h delete mode 100644 util/secp256k1/depend/secp256k1/src/ecmult_gen_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/ecmult_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/ext.c delete mode 100644 util/secp256k1/depend/secp256k1/src/field.h delete mode 100644 util/secp256k1/depend/secp256k1/src/field_10x26.h delete mode 100644 util/secp256k1/depend/secp256k1/src/field_10x26_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/field_5x52.h delete mode 100644 util/secp256k1/depend/secp256k1/src/field_5x52_asm_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/field_5x52_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/field_5x52_int128_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/field_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/gen_context.c delete mode 100644 util/secp256k1/depend/secp256k1/src/group.h delete mode 100644 util/secp256k1/depend/secp256k1/src/group_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/hash.h delete mode 100644 util/secp256k1/depend/secp256k1/src/hash_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java delete mode 100644 util/secp256k1/depend/secp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java delete mode 100644 util/secp256k1/depend/secp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java delete mode 100644 util/secp256k1/depend/secp256k1/src/java/org/bitcoin/Secp256k1Context.java delete mode 100644 util/secp256k1/depend/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c delete mode 100644 util/secp256k1/depend/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h delete mode 100644 util/secp256k1/depend/secp256k1/src/java/org_bitcoin_Secp256k1Context.c delete mode 100644 util/secp256k1/depend/secp256k1/src/java/org_bitcoin_Secp256k1Context.h delete mode 100644 util/secp256k1/depend/secp256k1/src/modules/ecdh/Makefile.am.include delete mode 100644 util/secp256k1/depend/secp256k1/src/modules/ecdh/main_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/modules/ecdh/tests_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/modules/recovery/Makefile.am.include delete mode 100644 util/secp256k1/depend/secp256k1/src/modules/recovery/main_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/modules/recovery/tests_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/modules/schnorr/Makefile.am.include delete mode 100644 util/secp256k1/depend/secp256k1/src/modules/schnorr/main_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/modules/schnorr/schnorr.h delete mode 100644 util/secp256k1/depend/secp256k1/src/modules/schnorr/schnorr_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/modules/schnorr/tests_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/num.h delete mode 100644 util/secp256k1/depend/secp256k1/src/num_gmp.h delete mode 100644 util/secp256k1/depend/secp256k1/src/num_gmp_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/num_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/scalar.h delete mode 100644 util/secp256k1/depend/secp256k1/src/scalar_4x64.h delete mode 100644 util/secp256k1/depend/secp256k1/src/scalar_4x64_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/scalar_8x32.h delete mode 100644 util/secp256k1/depend/secp256k1/src/scalar_8x32_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/scalar_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/scalar_low.h delete mode 100644 util/secp256k1/depend/secp256k1/src/scalar_low_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/secp256k1.c delete mode 100644 util/secp256k1/depend/secp256k1/src/testrand.h delete mode 100644 util/secp256k1/depend/secp256k1/src/testrand_impl.h delete mode 100644 util/secp256k1/depend/secp256k1/src/tests.c delete mode 100644 util/secp256k1/depend/secp256k1/src/tests_exhaustive.c delete mode 100644 util/secp256k1/depend/secp256k1/src/util.h delete mode 100644 util/secp256k1/src/constants.rs delete mode 100644 util/secp256k1/src/ecdh.rs delete mode 100644 util/secp256k1/src/ffi.rs delete mode 100644 util/secp256k1/src/key.rs delete mode 100644 util/secp256k1/src/lib.rs delete mode 100644 util/secp256k1/src/macros.rs delete mode 100644 util/secp256k1/src/schnorr.rs diff --git a/Cargo.lock b/Cargo.lock index 2de29f4633..65cf759da9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,11 +90,6 @@ name = "bech32" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "bitflags" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "bitflags" version = "1.0.3" @@ -124,18 +119,6 @@ name = "c_linked_list" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "cargo_metadata" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "cc" version = "1.0.29" @@ -183,39 +166,6 @@ dependencies = [ "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "clippy" -version = "0.0.198" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy_lints 0.0.198 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "clippy_lints" -version = "0.0.198" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "cloudabi" version = "0.0.3" @@ -378,7 +328,7 @@ dependencies = [ "rlp 0.2.1", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "secp256k1 0.5.7", + "secp256k1 0.6.0 (git+https://github.com/CodeChain-io/rust-secp256k1.git)", "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -607,7 +557,7 @@ dependencies = [ "codechain-types 0.1.0", "primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)", "rlp 0.2.1", - "secp256k1 0.5.7", + "secp256k1 0.6.0 (git+https://github.com/CodeChain-io/rust-secp256k1.git)", ] [[package]] @@ -1067,11 +1017,6 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "hex" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "http" version = "0.1.17" @@ -1187,11 +1132,6 @@ dependencies = [ "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "if_chain" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "indexmap" version = "1.0.2" @@ -1211,14 +1151,6 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "itertools" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "itoa" version = "0.4.1" @@ -1862,25 +1794,11 @@ dependencies = [ "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "pulldown-cmark" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "quick-error" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "quine-mc_cluskey" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "quote" version = "0.3.15" @@ -2273,12 +2191,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "secp256k1" -version = "0.5.7" +version = "0.6.0" +source = "git+https://github.com/CodeChain-io/rust-secp256k1.git#7da4cfd232735b59060f9ce23b50e6c5632a5ae0" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy 0.0.198 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2307,7 +2225,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3083,20 +3000,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" "checksum base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9263aa6a38da271eec5c91a83ce1e800f093c8535788d403d626d8d5c3f8f007" "checksum bech32 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1955ebdd52d5c5f1fb4f94e97aa241c2ce5729d200b3c34fc71ac6ff7a7cc556" -"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" "checksum bitstring 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3e54f7b7a46d7b183eb41e2d82965261fa8a1597c68b50aced268ee1fc70272d" "checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" "checksum bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1d50c876fb7545f5f289cd8b2aee3f359d073ae819eed5d6373638e2c61e59" "checksum c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" -"checksum cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ebd6272a2ca4fd39dbabbd6611eb03df45c2259b3b80b39a9ff8fbdcf42a4b3" "checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e" "checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18" "checksum chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e48d85528df61dc964aa43c5f6ca681a19cfa74939b2348d204bd08a981f2fb0" "checksum cidr 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0bf7340fd56c8198b28f1115fb6e8482538727ec1526d57334b444af578b1193" "checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" -"checksum clippy 0.0.198 (registry+https://github.com/rust-lang/crates.io-index)" = "da3a62431bbcebe5250a1235e022cc61bcc2f32405d8dc08da4011d223c6a4ba" -"checksum clippy_lints 0.0.198 (registry+https://github.com/rust-lang/crates.io-index)" = "9517a4eee5daa6eaf318a5bd7a4db0bcd5d92e8d8f22c3e341e60cf1746c73a4" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum codechain-crypto 0.1.0 (git+https://github.com/CodeChain-io/rust-codechain-crypto.git)" = "" "checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc" @@ -3149,7 +3062,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum globset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "464627f948c3190ae3d04b1bc6d7dca2f785bda0ac01278e6db129ad383dbeb6" "checksum h2 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "2b53def7bb0253af7718036fe9338c15defd209136819464384f3a553e07481b" "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" -"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" "checksum http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "eed324f0f0daf6ec10c474f150505af2c143f251722bf9dbd1261bd1f2ee2c1a" "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" @@ -3158,11 +3070,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)" = "f1ebec079129e43af5e234ef36ee3d7e6085687d145b7ea653b262d16c6b65f1" "checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" -"checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8" "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" -"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450" "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" "checksum jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)" = "" "checksum jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)" = "" @@ -3226,9 +3136,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07" -"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" -"checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" "checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" @@ -3269,6 +3177,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339" "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum secp256k1 0.6.0 (git+https://github.com/CodeChain-io/rust-secp256k1.git)" = "" "checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2" "checksum security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" diff --git a/key/Cargo.toml b/key/Cargo.toml index 9ee276691f..c52f636761 100644 --- a/key/Cargo.toml +++ b/key/Cargo.toml @@ -15,7 +15,7 @@ parking_lot = "0.6.0" primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.git", version = "0.4" } rand_xorshift = "0.1.0" rlp = { path = "../util/rlp" } -secp256k1 = { path = "../util/secp256k1" } +secp256k1 = { git = "https://github.com/CodeChain-io/rust-secp256k1.git", version = "0.6" } serde = "1.0" serde_derive = "1.0" serde_json = "1.0" diff --git a/util/secp256k1/.gitignore b/util/secp256k1/.gitignore deleted file mode 100644 index ea771e380d..0000000000 --- a/util/secp256k1/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -target/ -*.swp -Cargo.lock -.idea \ No newline at end of file diff --git a/util/secp256k1/.travis.yml b/util/secp256k1/.travis.yml deleted file mode 100644 index 3f1e0a43de..0000000000 --- a/util/secp256k1/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: rust -sudo: false - -matrix: - include: - - rust: stable - - rust: beta - - rust: nightly - -install: - - | - pip install 'travis-cargo<0.2' --user && - export PATH=$HOME/.local/bin:$PATH - -script: - - | - travis-cargo build && - travis-cargo build -- --release && - travis-cargo test && - travis-cargo test -- --release && - travis-cargo bench && - travis-cargo --only stable doc - diff --git a/util/secp256k1/Cargo.toml b/util/secp256k1/Cargo.toml deleted file mode 100644 index 71a5cef64e..0000000000 --- a/util/secp256k1/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "secp256k1" -version = "0.5.7" -authors = [ "Dawid Ciężarkiewicz ", - "Andrew Poelstra " ] -license = "CC0-1.0" -homepage = "https://github.com/paritytech/rust-secp256k1/" -repository = "https://github.com/paritytech/rust-secp256k1/" -documentation = "https://www.wpsoftware.net/rustdoc/secp256k1/" -description = "Fork of Rust bindings for Pieter Wuille's `libsecp256k1` library. Implements ECDSA for the SECG elliptic curve group secp256k1 and related utilities." -keywords = [ "crypto", "ECDSA", "secp256k1", "libsecp256k1", "bitcoin" ] -readme = "README.md" - -build = "build.rs" -[build-dependencies] -cc = "1.0" - -[lib] -name = "secp256k1" -path = "src/lib.rs" - -[features] -unstable = [] -default = [] -dev = ["clippy"] - -[dependencies] -arrayvec = "0.4" -clippy = {version = "0.0", optional = true} -rand = "0.6.1" - -[dev-dependencies] -hex = "0.3.1" diff --git a/util/secp256k1/LICENSE b/util/secp256k1/LICENSE deleted file mode 100644 index 6ca207ef00..0000000000 --- a/util/secp256k1/LICENSE +++ /dev/null @@ -1,122 +0,0 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. - diff --git a/util/secp256k1/Makefile b/util/secp256k1/Makefile deleted file mode 100644 index 287952bbdb..0000000000 --- a/util/secp256k1/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -test: - cargo test - -build: - cargo build - diff --git a/util/secp256k1/README.md b/util/secp256k1/README.md deleted file mode 100644 index 1665fb6db7..0000000000 --- a/util/secp256k1/README.md +++ /dev/null @@ -1,15 +0,0 @@ -[![Build Status](https://travis-ci.org/apoelstra/rust-secp256k1.png?branch=master)](https://travis-ci.org/apoelstra/rust-secp256k1) - -### rust-secp256k1 - -`rust-secp256k1` is a wrapper around ![libsecp256k1](https://github.com/bitcoin/secp256k1), -a C library by Peter Wuille for producing ECDSA signatures using the SECG curve -`secp256k1`. This library -* exposes type-safe Rust bindings for all `libsecp256k1` functions -* implements key generation -* implements deterministic nonce generation via RFC6979 -* implements many unit tests, adding to those already present in `libsecp256k1` -* makes no allocations (except in unit tests) for efficiency and use in freestanding implementations - -[Full documentation](https://www.wpsoftware.net/rustdoc/secp256k1/) - diff --git a/util/secp256k1/build.rs b/util/secp256k1/build.rs deleted file mode 100644 index b5ef4bdd7e..0000000000 --- a/util/secp256k1/build.rs +++ /dev/null @@ -1,102 +0,0 @@ -// Bitcoin secp256k1 bindings -// Written in 2015 by -// Andrew Poelstra -// -// To the extent possible under law, the author(s) have dedicated all -// copyright and related and neighboring rights to this software to -// the public domain worldwide. This software is distributed without -// any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication -// along with this software. -// If not, see . -// - -//! # Build script - -// Coding conventions -#![deny(non_upper_case_globals)] -#![deny(non_camel_case_types)] -#![deny(non_snake_case)] -#![deny(unused_mut)] -#![warn(missing_docs)] - -extern crate cc; - -use std::env; -use std::ffi::OsString; -use std::path::PathBuf; - -#[cfg(target_os = "macos")] -const OS: &'static str = "darwin"; -#[cfg(target_os = "linux")] -const OS: &'static str = "linux"; -#[cfg(target_os = "windows")] -const OS: &'static str = "windows"; - -const ANDROID_INCLUDE: &'static str = "platforms/android-21/arch-arm64/usr/include"; - -fn android_aarch_compiler() -> String { - "toolchains/aarch64-linux-android-4.9/prebuilt/".to_string() + OS + "-x86_64/bin" -} - -fn android_arm_compiler() -> String { - "toolchains/arm-linux-androideabi-4.9/prebuilt/".to_string() + OS + "-x86_64/bin" -} - -fn android_i686_compiler() -> String { - "toolchains/x86-4.9/prebuilt/".to_string() + OS + "-x86_64/bin" -} - -fn concat_paths(first: &str, second: &str) -> PathBuf { - let mut path = PathBuf::from(first); - path.push(second); - path -} - -fn setup_android(config: &mut cc::Build) { - let path = env::var_os("PATH").unwrap_or_else(OsString::new); - let ndk_home = env::var("NDK_HOME").expect("NDK_HOME is not set"); - let mut paths = env::split_paths(&path).collect::>(); - paths.push(concat_paths(&ndk_home, &android_aarch_compiler())); - paths.push(concat_paths(&ndk_home, &android_arm_compiler())); - paths.push(concat_paths(&ndk_home, &android_i686_compiler())); - - let new_path = env::join_paths(paths).expect("all paths were created using PathBuf's; qed"); - env::set_var("PATH", new_path); - - config.include(&concat_paths(&ndk_home, ANDROID_INCLUDE)); -} - -fn main() { - let mut base_config = cc::Build::new(); - base_config.include("depend/secp256k1/").include("depend/secp256k1/include").include("depend/secp256k1/src"); - - let target = env::var("TARGET").expect("TARGET env variable is set by cargo; qed"); - if target.contains("android") { - setup_android(&mut base_config); - } - - base_config.flag("-g") - // TODO these three should be changed to use libgmp, at least until secp PR 290 is merged - .define("USE_NUM_NONE", Some("1")) - .define("USE_FIELD_INV_BUILTIN", Some("1")) - .define("USE_SCALAR_INV_BUILTIN", Some("1")) - // TODO these should use 64-bit variants on 64-bit systems - .define("USE_FIELD_10X26", Some("1")) - .define("USE_SCALAR_8X32", Some("1")) - .define("USE_ENDOMORPHISM", Some("1")) - // These all are OK. - .define("ENABLE_MODULE_ECDH", Some("1")) - .define("ENABLE_MODULE_SCHNORR", Some("1")) - .define("ENABLE_MODULE_RECOVERY", Some("1")); - - base_config.flag("-Wno-unused-function"); - base_config.flag_if_supported("-Wno-nonnull-compare"); - - // secp256k1 - base_config - .file("depend/secp256k1/contrib/lax_der_parsing.c") - .file("depend/secp256k1/src/ext.c") - .compile("libsecp256k1.a"); -} diff --git a/util/secp256k1/depend/secp256k1/.gitignore b/util/secp256k1/depend/secp256k1/.gitignore deleted file mode 100644 index 87fea161ba..0000000000 --- a/util/secp256k1/depend/secp256k1/.gitignore +++ /dev/null @@ -1,49 +0,0 @@ -bench_inv -bench_ecdh -bench_sign -bench_verify -bench_schnorr_verify -bench_recover -bench_internal -tests -exhaustive_tests -gen_context -*.exe -*.so -*.a -!.gitignore - -Makefile -configure -.libs/ -Makefile.in -aclocal.m4 -autom4te.cache/ -config.log -config.status -*.tar.gz -*.la -libtool -.deps/ -.dirstamp -*.lo -*.o -*~ -src/libsecp256k1-config.h -src/libsecp256k1-config.h.in -src/ecmult_static_context.h -build-aux/config.guess -build-aux/config.sub -build-aux/depcomp -build-aux/install-sh -build-aux/ltmain.sh -build-aux/m4/libtool.m4 -build-aux/m4/lt~obsolete.m4 -build-aux/m4/ltoptions.m4 -build-aux/m4/ltsugar.m4 -build-aux/m4/ltversion.m4 -build-aux/missing -build-aux/compile -build-aux/test-driver -src/stamp-h1 -libsecp256k1.pc diff --git a/util/secp256k1/depend/secp256k1/.travis.yml b/util/secp256k1/depend/secp256k1/.travis.yml deleted file mode 100644 index 65f3e2a1b8..0000000000 --- a/util/secp256k1/depend/secp256k1/.travis.yml +++ /dev/null @@ -1,70 +0,0 @@ -language: c -sudo: false -addons: - apt: - packages: libgmp-dev -compiler: - - clang - - gcc -cache: - directories: - - src/java/guava/ -env: - global: - - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no RECOVERY=no EXPERIMENTAL=no - - GUAVA_URL=https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar GUAVA_JAR=src/java/guava/guava-18.0.jar - matrix: - - SCALAR=32bit RECOVERY=yes - - SCALAR=32bit FIELD=32bit ECDH=yes EXPERIMENTAL=yes - - SCALAR=64bit - - FIELD=64bit RECOVERY=yes - - FIELD=64bit ENDOMORPHISM=yes - - FIELD=64bit ENDOMORPHISM=yes ECDH=yes EXPERIMENTAL=yes - - FIELD=64bit ASM=x86_64 - - FIELD=64bit ENDOMORPHISM=yes ASM=x86_64 - - FIELD=32bit SCHNORR=yes EXPERIMENTAL=yes - - FIELD=32bit ENDOMORPHISM=yes - - BIGNUM=no - - BIGNUM=no ENDOMORPHISM=yes SCHNORR=yes RECOVERY=yes EXPERIMENTAL=yes - - BIGNUM=no STATICPRECOMPUTATION=no - - BUILD=distcheck - - EXTRAFLAGS=CPPFLAGS=-DDETERMINISTIC - - EXTRAFLAGS=CFLAGS=-O0 - - BUILD=check-java ECDH=yes EXPERIMENTAL=yes -matrix: - fast_finish: true - include: - - compiler: clang - env: HOST=i686-linux-gnu ENDOMORPHISM=yes - addons: - apt: - packages: - - gcc-multilib - - libgmp-dev:i386 - - compiler: clang - env: HOST=i686-linux-gnu - addons: - apt: - packages: - - gcc-multilib - - compiler: gcc - env: HOST=i686-linux-gnu ENDOMORPHISM=yes - addons: - apt: - packages: - - gcc-multilib - - compiler: gcc - env: HOST=i686-linux-gnu - addons: - apt: - packages: - - gcc-multilib - - libgmp-dev:i386 -before_install: mkdir -p `dirname $GUAVA_JAR` -install: if [ ! -f $GUAVA_JAR ]; then wget $GUAVA_URL -O $GUAVA_JAR; fi -before_script: ./autogen.sh -script: - - if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi - - if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi - - ./configure --enable-experimental=$EXPERIMENTAL --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-schnorr=$SCHNORR --enable-module-recovery=$RECOVERY $EXTRAFLAGS $USE_HOST && make -j2 $BUILD -os: linux diff --git a/util/secp256k1/depend/secp256k1/COPYING b/util/secp256k1/depend/secp256k1/COPYING deleted file mode 100644 index 4522a5990e..0000000000 --- a/util/secp256k1/depend/secp256k1/COPYING +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2013 Pieter Wuille - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/util/secp256k1/depend/secp256k1/Makefile.am b/util/secp256k1/depend/secp256k1/Makefile.am deleted file mode 100644 index af46341523..0000000000 --- a/util/secp256k1/depend/secp256k1/Makefile.am +++ /dev/null @@ -1,181 +0,0 @@ -ACLOCAL_AMFLAGS = -I build-aux/m4 - -lib_LTLIBRARIES = libsecp256k1.la -if USE_JNI -JNI_LIB = libsecp256k1_jni.la -noinst_LTLIBRARIES = $(JNI_LIB) -else -JNI_LIB = -endif -include_HEADERS = include/secp256k1.h -noinst_HEADERS = -noinst_HEADERS += src/scalar.h -noinst_HEADERS += src/scalar_4x64.h -noinst_HEADERS += src/scalar_8x32.h -noinst_HEADERS += src/scalar_low.h -noinst_HEADERS += src/scalar_impl.h -noinst_HEADERS += src/scalar_4x64_impl.h -noinst_HEADERS += src/scalar_8x32_impl.h -noinst_HEADERS += src/scalar_low_impl.h -noinst_HEADERS += src/group.h -noinst_HEADERS += src/group_impl.h -noinst_HEADERS += src/num_gmp.h -noinst_HEADERS += src/num_gmp_impl.h -noinst_HEADERS += src/ecdsa.h -noinst_HEADERS += src/ecdsa_impl.h -noinst_HEADERS += src/eckey.h -noinst_HEADERS += src/eckey_impl.h -noinst_HEADERS += src/ecmult.h -noinst_HEADERS += src/ecmult_impl.h -noinst_HEADERS += src/ecmult_const.h -noinst_HEADERS += src/ecmult_const_impl.h -noinst_HEADERS += src/ecmult_gen.h -noinst_HEADERS += src/ecmult_gen_impl.h -noinst_HEADERS += src/num.h -noinst_HEADERS += src/num_impl.h -noinst_HEADERS += src/field_10x26.h -noinst_HEADERS += src/field_10x26_impl.h -noinst_HEADERS += src/field_5x52.h -noinst_HEADERS += src/field_5x52_impl.h -noinst_HEADERS += src/field_5x52_int128_impl.h -noinst_HEADERS += src/field_5x52_asm_impl.h -noinst_HEADERS += src/java/org_bitcoin_NativeSecp256k1.h -noinst_HEADERS += src/java/org_bitcoin_Secp256k1Context.h -noinst_HEADERS += src/util.h -noinst_HEADERS += src/testrand.h -noinst_HEADERS += src/testrand_impl.h -noinst_HEADERS += src/hash.h -noinst_HEADERS += src/hash_impl.h -noinst_HEADERS += src/field.h -noinst_HEADERS += src/field_impl.h -noinst_HEADERS += src/bench.h -noinst_HEADERS += contrib/lax_der_parsing.h -noinst_HEADERS += contrib/lax_der_parsing.c -noinst_HEADERS += contrib/lax_der_privatekey_parsing.h -noinst_HEADERS += contrib/lax_der_privatekey_parsing.c - -if USE_EXTERNAL_ASM -COMMON_LIB = libsecp256k1_common.la -noinst_LTLIBRARIES = $(COMMON_LIB) -else -COMMON_LIB = -endif - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = libsecp256k1.pc - -if USE_EXTERNAL_ASM -if USE_ASM_ARM -libsecp256k1_common_la_SOURCES = src/asm/field_10x26_arm.s -endif -endif - -libsecp256k1_la_SOURCES = src/secp256k1.c -libsecp256k1_la_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES) -libsecp256k1_la_LIBADD = $(JNI_LIB) $(SECP_LIBS) $(COMMON_LIB) - -libsecp256k1_jni_la_SOURCES = src/java/org_bitcoin_NativeSecp256k1.c src/java/org_bitcoin_Secp256k1Context.c -libsecp256k1_jni_la_CPPFLAGS = -DSECP256K1_BUILD $(JNI_INCLUDES) - -noinst_PROGRAMS = -if USE_BENCHMARK -noinst_PROGRAMS += bench_verify bench_sign bench_internal -bench_verify_SOURCES = src/bench_verify.c -bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) -bench_sign_SOURCES = src/bench_sign.c -bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) -bench_internal_SOURCES = src/bench_internal.c -bench_internal_LDADD = $(SECP_LIBS) $(COMMON_LIB) -bench_internal_CPPFLAGS = -DSECP256K1_BUILD $(SECP_INCLUDES) -endif - -TESTS = -if USE_TESTS -noinst_PROGRAMS += tests -tests_SOURCES = src/tests.c -tests_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src -I$(top_srcdir)/include $(SECP_INCLUDES) $(SECP_TEST_INCLUDES) -if !ENABLE_COVERAGE -tests_CPPFLAGS += -DVERIFY -endif -tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) -tests_LDFLAGS = -static -TESTS += tests -endif - -if USE_EXHAUSTIVE_TESTS -noinst_PROGRAMS += exhaustive_tests -exhaustive_tests_SOURCES = src/tests_exhaustive.c -exhaustive_tests_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src $(SECP_INCLUDES) -if !ENABLE_COVERAGE -exhaustive_tests_CPPFLAGS += -DVERIFY -endif -exhaustive_tests_LDADD = $(SECP_LIBS) -exhaustive_tests_LDFLAGS = -static -TESTS += exhaustive_tests -endif - -JAVAROOT=src/java -JAVAORG=org/bitcoin -JAVA_GUAVA=$(srcdir)/$(JAVAROOT)/guava/guava-18.0.jar -CLASSPATH_ENV=CLASSPATH=$(JAVA_GUAVA) -JAVA_FILES= \ - $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1.java \ - $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1Test.java \ - $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1Util.java \ - $(JAVAROOT)/$(JAVAORG)/Secp256k1Context.java - -if USE_JNI - -$(JAVA_GUAVA): - @echo Guava is missing. Fetch it via: \ - wget https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar -O $(@) - @false - -.stamp-java: $(JAVA_FILES) - @echo Compiling $^ - $(AM_V_at)$(CLASSPATH_ENV) javac $^ - @touch $@ - -if USE_TESTS - -check-java: libsecp256k1.la $(JAVA_GUAVA) .stamp-java - $(AM_V_at)java -Djava.library.path="./:./src:./src/.libs:.libs/" -cp "$(JAVA_GUAVA):$(JAVAROOT)" $(JAVAORG)/NativeSecp256k1Test - -endif -endif - -if USE_ECMULT_STATIC_PRECOMPUTATION -CPPFLAGS_FOR_BUILD +=-I$(top_srcdir) -CFLAGS_FOR_BUILD += -Wall -Wextra -Wno-unused-function - -gen_context_OBJECTS = gen_context.o -gen_context_BIN = gen_context$(BUILD_EXEEXT) -gen_%.o: src/gen_%.c - $(CC_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -c $< -o $@ - -$(gen_context_BIN): $(gen_context_OBJECTS) - $(CC_FOR_BUILD) $^ -o $@ - -$(libsecp256k1_la_OBJECTS): src/ecmult_static_context.h -$(tests_OBJECTS): src/ecmult_static_context.h -$(bench_internal_OBJECTS): src/ecmult_static_context.h - -src/ecmult_static_context.h: $(gen_context_BIN) - ./$(gen_context_BIN) - -CLEANFILES = $(gen_context_BIN) src/ecmult_static_context.h $(JAVAROOT)/$(JAVAORG)/*.class .stamp-java -endif - -EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h $(JAVA_FILES) - -if ENABLE_MODULE_ECDH -include src/modules/ecdh/Makefile.am.include -endif - -if ENABLE_MODULE_SCHNORR -include src/modules/schnorr/Makefile.am.include -endif - -if ENABLE_MODULE_RECOVERY -include src/modules/recovery/Makefile.am.include -endif diff --git a/util/secp256k1/depend/secp256k1/README.md b/util/secp256k1/depend/secp256k1/README.md deleted file mode 100644 index 8cd344ea81..0000000000 --- a/util/secp256k1/depend/secp256k1/README.md +++ /dev/null @@ -1,61 +0,0 @@ -libsecp256k1 -============ - -[![Build Status](https://travis-ci.org/bitcoin-core/secp256k1.svg?branch=master)](https://travis-ci.org/bitcoin-core/secp256k1) - -Optimized C library for EC operations on curve secp256k1. - -This library is a work in progress and is being used to research best practices. Use at your own risk. - -Features: -* secp256k1 ECDSA signing/verification and key generation. -* Adding/multiplying private/public keys. -* Serialization/parsing of private keys, public keys, signatures. -* Constant time, constant memory access signing and pubkey generation. -* Derandomized DSA (via RFC6979 or with a caller provided function.) -* Very efficient implementation. - -Implementation details ----------------------- - -* General - * No runtime heap allocation. - * Extensive testing infrastructure. - * Structured to facilitate review and analysis. - * Intended to be portable to any system with a C89 compiler and uint64_t support. - * Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.") -* Field operations - * Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1). - * Using 5 52-bit limbs (including hand-optimized assembly for x86_64, by Diederik Huys). - * Using 10 26-bit limbs. - * Field inverses and square roots using a sliding window over blocks of 1s (by Peter Dettman). -* Scalar operations - * Optimized implementation without data-dependent branches of arithmetic modulo the curve's order. - * Using 4 64-bit limbs (relying on __int128 support in the compiler). - * Using 8 32-bit limbs. -* Group operations - * Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7). - * Use addition between points in Jacobian and affine coordinates where possible. - * Use a unified addition/doubling formula where necessary to avoid data-dependent branches. - * Point/x comparison without a field inversion by comparison in the Jacobian coordinate space. -* Point multiplication for verification (a*P + b*G). - * Use wNAF notation for point multiplicands. - * Use a much larger window for multiples of G, using precomputed multiples. - * Use Shamir's trick to do the multiplication with the public key and the generator simultaneously. - * Optionally (off by default) use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones. -* Point multiplication for signing - * Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions. - * Access the table with branch-free conditional moves so memory access is uniform. - * No data-dependent branches - * The precomputed tables add and eventually subtract points for which no known scalar (private key) is known, preventing even an attacker with control over the private key used to control the data internally. - -Build steps ------------ - -libsecp256k1 is built using autotools: - - $ ./autogen.sh - $ ./configure - $ make - $ ./tests - $ sudo make install # optional diff --git a/util/secp256k1/depend/secp256k1/TODO b/util/secp256k1/depend/secp256k1/TODO deleted file mode 100644 index a300e1c5eb..0000000000 --- a/util/secp256k1/depend/secp256k1/TODO +++ /dev/null @@ -1,3 +0,0 @@ -* Unit tests for fieldelem/groupelem, including ones intended to - trigger fieldelem's boundary cases. -* Complete constant-time operations for signing/keygen diff --git a/util/secp256k1/depend/secp256k1/autogen.sh b/util/secp256k1/depend/secp256k1/autogen.sh deleted file mode 100755 index 65286b9353..0000000000 --- a/util/secp256k1/depend/secp256k1/autogen.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -set -e -autoreconf -if --warnings=all diff --git a/util/secp256k1/depend/secp256k1/build-aux/m4/ax_jni_include_dir.m4 b/util/secp256k1/depend/secp256k1/build-aux/m4/ax_jni_include_dir.m4 deleted file mode 100644 index 1fc3627614..0000000000 --- a/util/secp256k1/depend/secp256k1/build-aux/m4/ax_jni_include_dir.m4 +++ /dev/null @@ -1,140 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_jni_include_dir.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_JNI_INCLUDE_DIR -# -# DESCRIPTION -# -# AX_JNI_INCLUDE_DIR finds include directories needed for compiling -# programs using the JNI interface. -# -# JNI include directories are usually in the Java distribution. This is -# deduced from the value of $JAVA_HOME, $JAVAC, or the path to "javac", in -# that order. When this macro completes, a list of directories is left in -# the variable JNI_INCLUDE_DIRS. -# -# Example usage follows: -# -# AX_JNI_INCLUDE_DIR -# -# for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS -# do -# CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR" -# done -# -# If you want to force a specific compiler: -# -# - at the configure.in level, set JAVAC=yourcompiler before calling -# AX_JNI_INCLUDE_DIR -# -# - at the configure level, setenv JAVAC -# -# Note: This macro can work with the autoconf M4 macros for Java programs. -# This particular macro is not part of the original set of macros. -# -# LICENSE -# -# Copyright (c) 2008 Don Anderson -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 10 - -AU_ALIAS([AC_JNI_INCLUDE_DIR], [AX_JNI_INCLUDE_DIR]) -AC_DEFUN([AX_JNI_INCLUDE_DIR],[ - -JNI_INCLUDE_DIRS="" - -if test "x$JAVA_HOME" != x; then - _JTOPDIR="$JAVA_HOME" -else - if test "x$JAVAC" = x; then - JAVAC=javac - fi - AC_PATH_PROG([_ACJNI_JAVAC], [$JAVAC], [no]) - if test "x$_ACJNI_JAVAC" = xno; then - AC_MSG_WARN([cannot find JDK; try setting \$JAVAC or \$JAVA_HOME]) - fi - _ACJNI_FOLLOW_SYMLINKS("$_ACJNI_JAVAC") - _JTOPDIR=`echo "$_ACJNI_FOLLOWED" | sed -e 's://*:/:g' -e 's:/[[^/]]*$::'` -fi - -case "$host_os" in - darwin*) _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'` - _JINC="$_JTOPDIR/Headers";; - *) _JINC="$_JTOPDIR/include";; -esac -_AS_ECHO_LOG([_JTOPDIR=$_JTOPDIR]) -_AS_ECHO_LOG([_JINC=$_JINC]) - -# On Mac OS X 10.6.4, jni.h is a symlink: -# /System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers/jni.h -# -> ../../CurrentJDK/Headers/jni.h. - -AC_CACHE_CHECK(jni headers, ac_cv_jni_header_path, -[ -if test -f "$_JINC/jni.h"; then - ac_cv_jni_header_path="$_JINC" - JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $ac_cv_jni_header_path" -else - _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'` - if test -f "$_JTOPDIR/include/jni.h"; then - ac_cv_jni_header_path="$_JTOPDIR/include" - JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $ac_cv_jni_header_path" - else - ac_cv_jni_header_path=none - fi -fi -]) - - - -# get the likely subdirectories for system specific java includes -case "$host_os" in -bsdi*) _JNI_INC_SUBDIRS="bsdos";; -darwin*) _JNI_INC_SUBDIRS="darwin";; -freebsd*) _JNI_INC_SUBDIRS="freebsd";; -linux*) _JNI_INC_SUBDIRS="linux genunix";; -osf*) _JNI_INC_SUBDIRS="alpha";; -solaris*) _JNI_INC_SUBDIRS="solaris";; -mingw*) _JNI_INC_SUBDIRS="win32";; -cygwin*) _JNI_INC_SUBDIRS="win32";; -*) _JNI_INC_SUBDIRS="genunix";; -esac - -if test "x$ac_cv_jni_header_path" != "xnone"; then - # add any subdirectories that are present - for JINCSUBDIR in $_JNI_INC_SUBDIRS - do - if test -d "$_JTOPDIR/include/$JINCSUBDIR"; then - JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include/$JINCSUBDIR" - fi - done -fi -]) - -# _ACJNI_FOLLOW_SYMLINKS -# Follows symbolic links on , -# finally setting variable _ACJNI_FOLLOWED -# ---------------------------------------- -AC_DEFUN([_ACJNI_FOLLOW_SYMLINKS],[ -# find the include directory relative to the javac executable -_cur="$1" -while ls -ld "$_cur" 2>/dev/null | grep " -> " >/dev/null; do - AC_MSG_CHECKING([symlink for $_cur]) - _slink=`ls -ld "$_cur" | sed 's/.* -> //'` - case "$_slink" in - /*) _cur="$_slink";; - # 'X' avoids triggering unwanted echo options. - *) _cur=`echo "X$_cur" | sed -e 's/^X//' -e 's:[[^/]]*$::'`"$_slink";; - esac - AC_MSG_RESULT([$_cur]) -done -_ACJNI_FOLLOWED="$_cur" -])# _ACJNI diff --git a/util/secp256k1/depend/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 b/util/secp256k1/depend/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 deleted file mode 100644 index 77fd346a79..0000000000 --- a/util/secp256k1/depend/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 +++ /dev/null @@ -1,125 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_PROG_CC_FOR_BUILD -# -# DESCRIPTION -# -# This macro searches for a C compiler that generates native executables, -# that is a C compiler that surely is not a cross-compiler. This can be -# useful if you have to generate source code at compile-time like for -# example GCC does. -# -# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything -# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD). -# The value of these variables can be overridden by the user by specifying -# a compiler with an environment variable (like you do for standard CC). -# -# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object -# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if -# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are -# substituted in the Makefile. -# -# LICENSE -# -# Copyright (c) 2008 Paolo Bonzini -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 8 - -AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD]) -AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_CPP])dnl -AC_REQUIRE([AC_EXEEXT])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl - -dnl Use the standard macros, but make them use other variable names -dnl -pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl -pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl -pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl -pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl -pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl -pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl -pushdef([ac_cv_objext], ac_cv_build_objext)dnl -pushdef([ac_exeext], ac_build_exeext)dnl -pushdef([ac_objext], ac_build_objext)dnl -pushdef([CC], CC_FOR_BUILD)dnl -pushdef([CPP], CPP_FOR_BUILD)dnl -pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl -pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl -pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl -pushdef([host], build)dnl -pushdef([host_alias], build_alias)dnl -pushdef([host_cpu], build_cpu)dnl -pushdef([host_vendor], build_vendor)dnl -pushdef([host_os], build_os)dnl -pushdef([ac_cv_host], ac_cv_build)dnl -pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl -pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl -pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl -pushdef([ac_cv_host_os], ac_cv_build_os)dnl -pushdef([ac_cpp], ac_build_cpp)dnl -pushdef([ac_compile], ac_build_compile)dnl -pushdef([ac_link], ac_build_link)dnl - -save_cross_compiling=$cross_compiling -save_ac_tool_prefix=$ac_tool_prefix -cross_compiling=no -ac_tool_prefix= - -AC_PROG_CC -AC_PROG_CPP -AC_EXEEXT - -ac_tool_prefix=$save_ac_tool_prefix -cross_compiling=$save_cross_compiling - -dnl Restore the old definitions -dnl -popdef([ac_link])dnl -popdef([ac_compile])dnl -popdef([ac_cpp])dnl -popdef([ac_cv_host_os])dnl -popdef([ac_cv_host_vendor])dnl -popdef([ac_cv_host_cpu])dnl -popdef([ac_cv_host_alias])dnl -popdef([ac_cv_host])dnl -popdef([host_os])dnl -popdef([host_vendor])dnl -popdef([host_cpu])dnl -popdef([host_alias])dnl -popdef([host])dnl -popdef([LDFLAGS])dnl -popdef([CPPFLAGS])dnl -popdef([CFLAGS])dnl -popdef([CPP])dnl -popdef([CC])dnl -popdef([ac_objext])dnl -popdef([ac_exeext])dnl -popdef([ac_cv_objext])dnl -popdef([ac_cv_exeext])dnl -popdef([ac_cv_prog_cc_g])dnl -popdef([ac_cv_prog_cc_cross])dnl -popdef([ac_cv_prog_cc_works])dnl -popdef([ac_cv_prog_gcc])dnl -popdef([ac_cv_prog_CPP])dnl - -dnl Finally, set Makefile variables -dnl -BUILD_EXEEXT=$ac_build_exeext -BUILD_OBJEXT=$ac_build_objext -AC_SUBST(BUILD_EXEEXT)dnl -AC_SUBST(BUILD_OBJEXT)dnl -AC_SUBST([CFLAGS_FOR_BUILD])dnl -AC_SUBST([CPPFLAGS_FOR_BUILD])dnl -AC_SUBST([LDFLAGS_FOR_BUILD])dnl -]) diff --git a/util/secp256k1/depend/secp256k1/build-aux/m4/bitcoin_secp.m4 b/util/secp256k1/depend/secp256k1/build-aux/m4/bitcoin_secp.m4 deleted file mode 100644 index b74acb8c13..0000000000 --- a/util/secp256k1/depend/secp256k1/build-aux/m4/bitcoin_secp.m4 +++ /dev/null @@ -1,69 +0,0 @@ -dnl libsecp25k1 helper checks -AC_DEFUN([SECP_INT128_CHECK],[ -has_int128=$ac_cv_type___int128 -]) - -dnl escape "$0x" below using the m4 quadrigaph @S|@, and escape it again with a \ for the shell. -AC_DEFUN([SECP_64BIT_ASM_CHECK],[ -AC_MSG_CHECKING(for x86_64 assembly availability) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include ]],[[ - uint64_t a = 11, tmp; - __asm__ __volatile__("movq \@S|@0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx"); - ]])],[has_64bit_asm=yes],[has_64bit_asm=no]) -AC_MSG_RESULT([$has_64bit_asm]) -]) - -dnl -AC_DEFUN([SECP_OPENSSL_CHECK],[ - has_libcrypto=no - m4_ifdef([PKG_CHECK_MODULES],[ - PKG_CHECK_MODULES([CRYPTO], [libcrypto], [has_libcrypto=yes],[has_libcrypto=no]) - if test x"$has_libcrypto" = x"yes"; then - TEMP_LIBS="$LIBS" - LIBS="$LIBS $CRYPTO_LIBS" - AC_CHECK_LIB(crypto, main,[AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])],[has_libcrypto=no]) - LIBS="$TEMP_LIBS" - fi - ]) - if test x$has_libcrypto = xno; then - AC_CHECK_HEADER(openssl/crypto.h,[ - AC_CHECK_LIB(crypto, main,[ - has_libcrypto=yes - CRYPTO_LIBS=-lcrypto - AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed]) - ]) - ]) - LIBS= - fi -if test x"$has_libcrypto" = x"yes" && test x"$has_openssl_ec" = x; then - AC_MSG_CHECKING(for EC functions in libcrypto) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #include - #include ]],[[ - EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_secp256k1); - ECDSA_sign(0, NULL, 0, NULL, NULL, eckey); - ECDSA_verify(0, NULL, 0, NULL, 0, eckey); - EC_KEY_free(eckey); - ECDSA_SIG *sig_openssl; - sig_openssl = ECDSA_SIG_new(); - (void)sig_openssl->r; - ECDSA_SIG_free(sig_openssl); - ]])],[has_openssl_ec=yes],[has_openssl_ec=no]) - AC_MSG_RESULT([$has_openssl_ec]) -fi -]) - -dnl -AC_DEFUN([SECP_GMP_CHECK],[ -if test x"$has_gmp" != x"yes"; then - CPPFLAGS_TEMP="$CPPFLAGS" - CPPFLAGS="$GMP_CPPFLAGS $CPPFLAGS" - LIBS_TEMP="$LIBS" - LIBS="$GMP_LIBS $LIBS" - AC_CHECK_HEADER(gmp.h,[AC_CHECK_LIB(gmp, __gmpz_init,[has_gmp=yes; GMP_LIBS="$GMP_LIBS -lgmp"; AC_DEFINE(HAVE_LIBGMP,1,[Define this symbol if libgmp is installed])])]) - CPPFLAGS="$CPPFLAGS_TEMP" - LIBS="$LIBS_TEMP" -fi -]) diff --git a/util/secp256k1/depend/secp256k1/configure.ac b/util/secp256k1/depend/secp256k1/configure.ac deleted file mode 100644 index b2c559e45f..0000000000 --- a/util/secp256k1/depend/secp256k1/configure.ac +++ /dev/null @@ -1,511 +0,0 @@ -AC_PREREQ([2.60]) -AC_INIT([libsecp256k1],[0.1]) -AC_CONFIG_AUX_DIR([build-aux]) -AC_CONFIG_MACRO_DIR([build-aux/m4]) -AC_CANONICAL_HOST -AH_TOP([#ifndef LIBSECP256K1_CONFIG_H]) -AH_TOP([#define LIBSECP256K1_CONFIG_H]) -AH_BOTTOM([#endif /*LIBSECP256K1_CONFIG_H*/]) -AM_INIT_AUTOMAKE([foreign subdir-objects]) -LT_INIT - -dnl make the compilation flags quiet unless V=1 is used -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - -PKG_PROG_PKG_CONFIG - -AC_PATH_TOOL(AR, ar) -AC_PATH_TOOL(RANLIB, ranlib) -AC_PATH_TOOL(STRIP, strip) -AX_PROG_CC_FOR_BUILD - -if test "x$CFLAGS" = "x"; then - CFLAGS="-g" -fi - -AM_PROG_CC_C_O - -AC_PROG_CC_C89 -if test x"$ac_cv_prog_cc_c89" = x"no"; then - AC_MSG_ERROR([c89 compiler support required]) -fi -AM_PROG_AS - -case $host_os in - *darwin*) - if test x$cross_compiling != xyes; then - AC_PATH_PROG([BREW],brew,) - if test x$BREW != x; then - dnl These Homebrew packages may be keg-only, meaning that they won't be found - dnl in expected paths because they may conflict with system files. Ask - dnl Homebrew where each one is located, then adjust paths accordingly. - - openssl_prefix=`$BREW --prefix openssl 2>/dev/null` - gmp_prefix=`$BREW --prefix gmp 2>/dev/null` - if test x$openssl_prefix != x; then - PKG_CONFIG_PATH="$openssl_prefix/lib/pkgconfig:$PKG_CONFIG_PATH" - export PKG_CONFIG_PATH - fi - if test x$gmp_prefix != x; then - GMP_CPPFLAGS="-I$gmp_prefix/include" - GMP_LIBS="-L$gmp_prefix/lib" - fi - else - AC_PATH_PROG([PORT],port,) - dnl if homebrew isn't installed and macports is, add the macports default paths - dnl as a last resort. - if test x$PORT != x; then - CPPFLAGS="$CPPFLAGS -isystem /opt/local/include" - LDFLAGS="$LDFLAGS -L/opt/local/lib" - fi - fi - fi - ;; -esac - -CFLAGS="$CFLAGS -W" - -warn_CFLAGS="-std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings" -saved_CFLAGS="$CFLAGS" -CFLAGS="$CFLAGS $warn_CFLAGS" -AC_MSG_CHECKING([if ${CC} supports ${warn_CFLAGS}]) -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], - [ AC_MSG_RESULT([yes]) ], - [ AC_MSG_RESULT([no]) - CFLAGS="$saved_CFLAGS" - ]) - -saved_CFLAGS="$CFLAGS" -CFLAGS="$CFLAGS -fvisibility=hidden" -AC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden]) -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], - [ AC_MSG_RESULT([yes]) ], - [ AC_MSG_RESULT([no]) - CFLAGS="$saved_CFLAGS" - ]) - -AC_ARG_ENABLE(benchmark, - AS_HELP_STRING([--enable-benchmark],[compile benchmark (default is no)]), - [use_benchmark=$enableval], - [use_benchmark=no]) - -AC_ARG_ENABLE(coverage, - AS_HELP_STRING([--enable-coverage],[enable compiler flags to support kcov coverage analysis]), - [enable_coverage=$enableval], - [enable_coverage=no]) - -AC_ARG_ENABLE(tests, - AS_HELP_STRING([--enable-tests],[compile tests (default is yes)]), - [use_tests=$enableval], - [use_tests=yes]) - -AC_ARG_ENABLE(openssl_tests, - AS_HELP_STRING([--enable-openssl-tests],[enable OpenSSL tests, if OpenSSL is available (default is auto)]), - [enable_openssl_tests=$enableval], - [enable_openssl_tests=auto]) - -AC_ARG_ENABLE(experimental, - AS_HELP_STRING([--enable-experimental],[allow experimental configure options (default is no)]), - [use_experimental=$enableval], - [use_experimental=no]) - -AC_ARG_ENABLE(exhaustive_tests, - AS_HELP_STRING([--enable-exhaustive-tests],[compile exhaustive tests (default is yes)]), - [use_exhaustive_tests=$enableval], - [use_exhaustive_tests=yes]) - -AC_ARG_ENABLE(endomorphism, - AS_HELP_STRING([--enable-endomorphism],[enable endomorphism (default is no)]), - [use_endomorphism=$enableval], - [use_endomorphism=no]) - -AC_ARG_ENABLE(ecmult_static_precomputation, - AS_HELP_STRING([--enable-ecmult-static-precomputation],[enable precomputed ecmult table for signing (default is yes)]), - [use_ecmult_static_precomputation=$enableval], - [use_ecmult_static_precomputation=auto]) - -AC_ARG_ENABLE(module_ecdh, - AS_HELP_STRING([--enable-module-ecdh],[enable ECDH shared secret computation (experimental)]), - [enable_module_ecdh=$enableval], - [enable_module_ecdh=no]) - -AC_ARG_ENABLE(module_schnorr, - AS_HELP_STRING([--enable-module-schnorr],[enable Schnorr signature module (experimental)]), - [enable_module_schnorr=$enableval], - [enable_module_schnorr=no]) - -AC_ARG_ENABLE(module_recovery, - AS_HELP_STRING([--enable-module-recovery],[enable ECDSA pubkey recovery module (default is no)]), - [enable_module_recovery=$enableval], - [enable_module_recovery=no]) - -AC_ARG_ENABLE(jni, - AS_HELP_STRING([--enable-jni],[enable libsecp256k1_jni (default is auto)]), - [use_jni=$enableval], - [use_jni=auto]) - -AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=64bit|32bit|auto], -[Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto]) - -AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|no|auto], -[Specify Bignum Implementation. Default is auto])],[req_bignum=$withval], [req_bignum=auto]) - -AC_ARG_WITH([scalar], [AS_HELP_STRING([--with-scalar=64bit|32bit|auto], -[Specify scalar implementation. Default is auto])],[req_scalar=$withval], [req_scalar=auto]) - -AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm|no|auto] -[Specify assembly optimizations to use. Default is auto (experimental: arm)])],[req_asm=$withval], [req_asm=auto]) - -AC_CHECK_TYPES([__int128]) - -AC_MSG_CHECKING([for __builtin_expect]) -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_expect(0,0);}]])], - [ AC_MSG_RESULT([yes]);AC_DEFINE(HAVE_BUILTIN_EXPECT,1,[Define this symbol if __builtin_expect is available]) ], - [ AC_MSG_RESULT([no]) - ]) - -if test x"$enable_coverage" = x"yes"; then - AC_DEFINE(COVERAGE, 1, [Define this symbol to compile out all VERIFY code]) - CFLAGS="$CFLAGS -O0 --coverage" - LDFLAGS="--coverage" -else - CFLAGS="$CFLAGS -O3" -fi - -if test x"$use_ecmult_static_precomputation" != x"no"; then - save_cross_compiling=$cross_compiling - cross_compiling=no - TEMP_CC="$CC" - CC="$CC_FOR_BUILD" - AC_MSG_CHECKING([native compiler: ${CC_FOR_BUILD}]) - AC_RUN_IFELSE( - [AC_LANG_PROGRAM([], [return 0])], - [working_native_cc=yes], - [working_native_cc=no],[dnl]) - CC="$TEMP_CC" - cross_compiling=$save_cross_compiling - - if test x"$working_native_cc" = x"no"; then - set_precomp=no - if test x"$use_ecmult_static_precomputation" = x"yes"; then - AC_MSG_ERROR([${CC_FOR_BUILD} does not produce working binaries. Please set CC_FOR_BUILD]) - else - AC_MSG_RESULT([${CC_FOR_BUILD} does not produce working binaries. Please set CC_FOR_BUILD]) - fi - else - AC_MSG_RESULT([ok]) - set_precomp=yes - fi -else - set_precomp=no -fi - -if test x"$req_asm" = x"auto"; then - SECP_64BIT_ASM_CHECK - if test x"$has_64bit_asm" = x"yes"; then - set_asm=x86_64 - fi - if test x"$set_asm" = x; then - set_asm=no - fi -else - set_asm=$req_asm - case $set_asm in - x86_64) - SECP_64BIT_ASM_CHECK - if test x"$has_64bit_asm" != x"yes"; then - AC_MSG_ERROR([x86_64 assembly optimization requested but not available]) - fi - ;; - arm) - ;; - no) - ;; - *) - AC_MSG_ERROR([invalid assembly optimization selection]) - ;; - esac -fi - -if test x"$req_field" = x"auto"; then - if test x"set_asm" = x"x86_64"; then - set_field=64bit - fi - if test x"$set_field" = x; then - SECP_INT128_CHECK - if test x"$has_int128" = x"yes"; then - set_field=64bit - fi - fi - if test x"$set_field" = x; then - set_field=32bit - fi -else - set_field=$req_field - case $set_field in - 64bit) - if test x"$set_asm" != x"x86_64"; then - SECP_INT128_CHECK - if test x"$has_int128" != x"yes"; then - AC_MSG_ERROR([64bit field explicitly requested but neither __int128 support or x86_64 assembly available]) - fi - fi - ;; - 32bit) - ;; - *) - AC_MSG_ERROR([invalid field implementation selection]) - ;; - esac -fi - -if test x"$req_scalar" = x"auto"; then - SECP_INT128_CHECK - if test x"$has_int128" = x"yes"; then - set_scalar=64bit - fi - if test x"$set_scalar" = x; then - set_scalar=32bit - fi -else - set_scalar=$req_scalar - case $set_scalar in - 64bit) - SECP_INT128_CHECK - if test x"$has_int128" != x"yes"; then - AC_MSG_ERROR([64bit scalar explicitly requested but __int128 support not available]) - fi - ;; - 32bit) - ;; - *) - AC_MSG_ERROR([invalid scalar implementation selected]) - ;; - esac -fi - -if test x"$req_bignum" = x"auto"; then - SECP_GMP_CHECK - if test x"$has_gmp" = x"yes"; then - set_bignum=gmp - fi - - if test x"$set_bignum" = x; then - set_bignum=no - fi -else - set_bignum=$req_bignum - case $set_bignum in - gmp) - SECP_GMP_CHECK - if test x"$has_gmp" != x"yes"; then - AC_MSG_ERROR([gmp bignum explicitly requested but libgmp not available]) - fi - ;; - no) - ;; - *) - AC_MSG_ERROR([invalid bignum implementation selection]) - ;; - esac -fi - -# select assembly optimization -use_external_asm=no - -case $set_asm in -x86_64) - AC_DEFINE(USE_ASM_X86_64, 1, [Define this symbol to enable x86_64 assembly optimizations]) - ;; -arm) - use_external_asm=yes - ;; -no) - ;; -*) - AC_MSG_ERROR([invalid assembly optimizations]) - ;; -esac - -# select field implementation -case $set_field in -64bit) - AC_DEFINE(USE_FIELD_5X52, 1, [Define this symbol to use the FIELD_5X52 implementation]) - ;; -32bit) - AC_DEFINE(USE_FIELD_10X26, 1, [Define this symbol to use the FIELD_10X26 implementation]) - ;; -*) - AC_MSG_ERROR([invalid field implementation]) - ;; -esac - -# select bignum implementation -case $set_bignum in -gmp) - AC_DEFINE(HAVE_LIBGMP, 1, [Define this symbol if libgmp is installed]) - AC_DEFINE(USE_NUM_GMP, 1, [Define this symbol to use the gmp implementation for num]) - AC_DEFINE(USE_FIELD_INV_NUM, 1, [Define this symbol to use the num-based field inverse implementation]) - AC_DEFINE(USE_SCALAR_INV_NUM, 1, [Define this symbol to use the num-based scalar inverse implementation]) - ;; -no) - AC_DEFINE(USE_NUM_NONE, 1, [Define this symbol to use no num implementation]) - AC_DEFINE(USE_FIELD_INV_BUILTIN, 1, [Define this symbol to use the native field inverse implementation]) - AC_DEFINE(USE_SCALAR_INV_BUILTIN, 1, [Define this symbol to use the native scalar inverse implementation]) - ;; -*) - AC_MSG_ERROR([invalid bignum implementation]) - ;; -esac - -#select scalar implementation -case $set_scalar in -64bit) - AC_DEFINE(USE_SCALAR_4X64, 1, [Define this symbol to use the 4x64 scalar implementation]) - ;; -32bit) - AC_DEFINE(USE_SCALAR_8X32, 1, [Define this symbol to use the 8x32 scalar implementation]) - ;; -*) - AC_MSG_ERROR([invalid scalar implementation]) - ;; -esac - -if test x"$use_tests" = x"yes"; then - SECP_OPENSSL_CHECK - if test x"$has_openssl_ec" = x"yes"; then - if test x"$enable_openssl_tests" != x"no"; then - AC_DEFINE(ENABLE_OPENSSL_TESTS, 1, [Define this symbol if OpenSSL EC functions are available]) - SECP_TEST_INCLUDES="$SSL_CFLAGS $CRYPTO_CFLAGS" - SECP_TEST_LIBS="$CRYPTO_LIBS" - - case $host in - *mingw*) - SECP_TEST_LIBS="$SECP_TEST_LIBS -lgdi32" - ;; - esac - fi - else - if test x"$enable_openssl_tests" = x"yes"; then - AC_MSG_ERROR([OpenSSL tests requested but OpenSSL with EC support is not available]) - fi - fi -else - if test x"$enable_openssl_tests" = x"yes"; then - AC_MSG_ERROR([OpenSSL tests requested but tests are not enabled]) - fi -fi - -if test x"$use_jni" != x"no"; then - AX_JNI_INCLUDE_DIR - have_jni_dependencies=yes - if test x"$enable_module_schnorr" = x"no"; then - have_jni_dependencies=no - fi - if test x"$enable_module_ecdh" = x"no"; then - have_jni_dependencies=no - fi - if test "x$JNI_INCLUDE_DIRS" = "x"; then - have_jni_dependencies=no - fi - if test "x$have_jni_dependencies" = "xno"; then - if test x"$use_jni" = x"yes"; then - AC_MSG_ERROR([jni support explicitly requested but headers/dependencies were not found. Enable ECDH and Schnorr and try again.]) - fi - AC_MSG_WARN([jni headers/dependencies not found. jni support disabled]) - use_jni=no - else - use_jni=yes - for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS; do - JNI_INCLUDES="$JNI_INCLUDES -I$JNI_INCLUDE_DIR" - done - fi -fi - -if test x"$set_bignum" = x"gmp"; then - SECP_LIBS="$SECP_LIBS $GMP_LIBS" - SECP_INCLUDES="$SECP_INCLUDES $GMP_CPPFLAGS" -fi - -if test x"$use_endomorphism" = x"yes"; then - AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism optimization]) -fi - -if test x"$set_precomp" = x"yes"; then - AC_DEFINE(USE_ECMULT_STATIC_PRECOMPUTATION, 1, [Define this symbol to use a statically generated ecmult table]) -fi - -if test x"$enable_module_ecdh" = x"yes"; then - AC_DEFINE(ENABLE_MODULE_ECDH, 1, [Define this symbol to enable the ECDH module]) -fi - -if test x"$enable_module_schnorr" = x"yes"; then - AC_DEFINE(ENABLE_MODULE_SCHNORR, 1, [Define this symbol to enable the Schnorr signature module]) -fi - -if test x"$enable_module_recovery" = x"yes"; then - AC_DEFINE(ENABLE_MODULE_RECOVERY, 1, [Define this symbol to enable the ECDSA pubkey recovery module]) -fi - -AC_C_BIGENDIAN() - -if test x"$use_external_asm" = x"yes"; then - AC_DEFINE(USE_EXTERNAL_ASM, 1, [Define this symbol if an external (non-inline) assembly implementation is used]) -fi - -AC_MSG_NOTICE([Using static precomputation: $set_precomp]) -AC_MSG_NOTICE([Using assembly optimizations: $set_asm]) -AC_MSG_NOTICE([Using field implementation: $set_field]) -AC_MSG_NOTICE([Using bignum implementation: $set_bignum]) -AC_MSG_NOTICE([Using scalar implementation: $set_scalar]) -AC_MSG_NOTICE([Using endomorphism optimizations: $use_endomorphism]) -AC_MSG_NOTICE([Building for coverage analysis: $enable_coverage]) -AC_MSG_NOTICE([Building ECDH module: $enable_module_ecdh]) -AC_MSG_NOTICE([Building Schnorr signatures module: $enable_module_schnorr]) -AC_MSG_NOTICE([Building ECDSA pubkey recovery module: $enable_module_recovery]) -AC_MSG_NOTICE([Using jni: $use_jni]) - -if test x"$enable_experimental" = x"yes"; then - AC_MSG_NOTICE([******]) - AC_MSG_NOTICE([WARNING: experimental build]) - AC_MSG_NOTICE([Experimental features do not have stable APIs or properties, and may not be safe for production use.]) - AC_MSG_NOTICE([Building ECDH module: $enable_module_ecdh]) - AC_MSG_NOTICE([Building Schnorr signatures module: $enable_module_schnorr]) - AC_MSG_NOTICE([******]) -else - if test x"$enable_module_schnorr" = x"yes"; then - AC_MSG_ERROR([Schnorr signature module is experimental. Use --enable-experimental to allow.]) - fi - if test x"$enable_module_ecdh" = x"yes"; then - AC_MSG_ERROR([ECDH module is experimental. Use --enable-experimental to allow.]) - fi - if test x"$set_asm" = x"arm"; then - AC_MSG_ERROR([ARM assembly optimization is experimental. Use --enable-experimental to allow.]) - fi -fi - -AC_CONFIG_HEADERS([src/libsecp256k1-config.h]) -AC_CONFIG_FILES([Makefile libsecp256k1.pc]) -AC_SUBST(JNI_INCLUDES) -AC_SUBST(SECP_INCLUDES) -AC_SUBST(SECP_LIBS) -AC_SUBST(SECP_TEST_LIBS) -AC_SUBST(SECP_TEST_INCLUDES) -AM_CONDITIONAL([ENABLE_COVERAGE], [test x"$enable_coverage" = x"yes"]) -AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"]) -AM_CONDITIONAL([USE_EXHAUSTIVE_TESTS], [test x"$use_exhaustive_tests" != x"no"]) -AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" = x"yes"]) -AM_CONDITIONAL([USE_ECMULT_STATIC_PRECOMPUTATION], [test x"$set_precomp" = x"yes"]) -AM_CONDITIONAL([ENABLE_MODULE_ECDH], [test x"$enable_module_ecdh" = x"yes"]) -AM_CONDITIONAL([ENABLE_MODULE_SCHNORR], [test x"$enable_module_schnorr" = x"yes"]) -AM_CONDITIONAL([ENABLE_MODULE_RECOVERY], [test x"$enable_module_recovery" = x"yes"]) -AM_CONDITIONAL([USE_JNI], [test x"$use_jni" == x"yes"]) -AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$use_external_asm" = x"yes"]) -AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm"]) - -dnl make sure nothing new is exported so that we don't break the cache -PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH" -unset PKG_CONFIG_PATH -PKG_CONFIG_PATH="$PKGCONFIG_PATH_TEMP" - -AC_OUTPUT diff --git a/util/secp256k1/depend/secp256k1/contrib/lax_der_parsing.c b/util/secp256k1/depend/secp256k1/contrib/lax_der_parsing.c deleted file mode 100644 index 5b141a9948..0000000000 --- a/util/secp256k1/depend/secp256k1/contrib/lax_der_parsing.c +++ /dev/null @@ -1,150 +0,0 @@ -/********************************************************************** - * Copyright (c) 2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#include -#include - -#include "lax_der_parsing.h" - -int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { - size_t rpos, rlen, spos, slen; - size_t pos = 0; - size_t lenbyte; - unsigned char tmpsig[64] = {0}; - int overflow = 0; - - /* Hack to initialize sig with a correctly-parsed but invalid signature. */ - secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); - - /* Sequence tag byte */ - if (pos == inputlen || input[pos] != 0x30) { - return 0; - } - pos++; - - /* Sequence length bytes */ - if (pos == inputlen) { - return 0; - } - lenbyte = input[pos++]; - if (lenbyte & 0x80) { - lenbyte -= 0x80; - if (pos + lenbyte > inputlen) { - return 0; - } - pos += lenbyte; - } - - /* Integer tag byte for R */ - if (pos == inputlen || input[pos] != 0x02) { - return 0; - } - pos++; - - /* Integer length for R */ - if (pos == inputlen) { - return 0; - } - lenbyte = input[pos++]; - if (lenbyte & 0x80) { - lenbyte -= 0x80; - if (pos + lenbyte > inputlen) { - return 0; - } - while (lenbyte > 0 && input[pos] == 0) { - pos++; - lenbyte--; - } - if (lenbyte >= sizeof(size_t)) { - return 0; - } - rlen = 0; - while (lenbyte > 0) { - rlen = (rlen << 8) + input[pos]; - pos++; - lenbyte--; - } - } else { - rlen = lenbyte; - } - if (rlen > inputlen - pos) { - return 0; - } - rpos = pos; - pos += rlen; - - /* Integer tag byte for S */ - if (pos == inputlen || input[pos] != 0x02) { - return 0; - } - pos++; - - /* Integer length for S */ - if (pos == inputlen) { - return 0; - } - lenbyte = input[pos++]; - if (lenbyte & 0x80) { - lenbyte -= 0x80; - if (pos + lenbyte > inputlen) { - return 0; - } - while (lenbyte > 0 && input[pos] == 0) { - pos++; - lenbyte--; - } - if (lenbyte >= sizeof(size_t)) { - return 0; - } - slen = 0; - while (lenbyte > 0) { - slen = (slen << 8) + input[pos]; - pos++; - lenbyte--; - } - } else { - slen = lenbyte; - } - if (slen > inputlen - pos) { - return 0; - } - spos = pos; - pos += slen; - - /* Ignore leading zeroes in R */ - while (rlen > 0 && input[rpos] == 0) { - rlen--; - rpos++; - } - /* Copy R value */ - if (rlen > 32) { - overflow = 1; - } else { - memcpy(tmpsig + 32 - rlen, input + rpos, rlen); - } - - /* Ignore leading zeroes in S */ - while (slen > 0 && input[spos] == 0) { - slen--; - spos++; - } - /* Copy S value */ - if (slen > 32) { - overflow = 1; - } else { - memcpy(tmpsig + 64 - slen, input + spos, slen); - } - - if (!overflow) { - overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); - } - if (overflow) { - memset(tmpsig, 0, 64); - secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); - } - return 1; -} - diff --git a/util/secp256k1/depend/secp256k1/contrib/lax_der_parsing.h b/util/secp256k1/depend/secp256k1/contrib/lax_der_parsing.h deleted file mode 100644 index 7eaf63bf6a..0000000000 --- a/util/secp256k1/depend/secp256k1/contrib/lax_der_parsing.h +++ /dev/null @@ -1,91 +0,0 @@ -/********************************************************************** - * Copyright (c) 2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -/**** - * Please do not link this file directly. It is not part of the libsecp256k1 - * project and does not promise any stability in its API, functionality or - * presence. Projects which use this code should instead copy this header - * and its accompanying .c file directly into their codebase. - ****/ - -/* This file defines a function that parses DER with various errors and - * violations. This is not a part of the library itself, because the allowed - * violations are chosen arbitrarily and do not follow or establish any - * standard. - * - * In many places it matters that different implementations do not only accept - * the same set of valid signatures, but also reject the same set of signatures. - * The only means to accomplish that is by strictly obeying a standard, and not - * accepting anything else. - * - * Nonetheless, sometimes there is a need for compatibility with systems that - * use signatures which do not strictly obey DER. The snippet below shows how - * certain violations are easily supported. You may need to adapt it. - * - * Do not use this for new systems. Use well-defined DER or compact signatures - * instead if you have the choice (see secp256k1_ecdsa_signature_parse_der and - * secp256k1_ecdsa_signature_parse_compact). - * - * The supported violations are: - * - All numbers are parsed as nonnegative integers, even though X.609-0207 - * section 8.3.3 specifies that integers are always encoded as two's - * complement. - * - Integers can have length 0, even though section 8.3.1 says they can't. - * - Integers with overly long padding are accepted, violation section - * 8.3.2. - * - 127-byte long length descriptors are accepted, even though section - * 8.1.3.5.c says that they are not. - * - Trailing garbage data inside or after the signature is ignored. - * - The length descriptor of the sequence is ignored. - * - * Compared to for example OpenSSL, many violations are NOT supported: - * - Using overly long tag descriptors for the sequence or integers inside, - * violating section 8.1.2.2. - * - Encoding primitive integers as constructed values, violating section - * 8.3.1. - */ - -#ifndef SECP256K1_CONTRIB_LAX_DER_PARSING_H -#define SECP256K1_CONTRIB_LAX_DER_PARSING_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Parse a signature in "lax DER" format - * - * Returns: 1 when the signature could be parsed, 0 otherwise. - * Args: ctx: a secp256k1 context object - * Out: sig: a pointer to a signature object - * In: input: a pointer to the signature to be parsed - * inputlen: the length of the array pointed to be input - * - * This function will accept any valid DER encoded signature, even if the - * encoded numbers are out of range. In addition, it will accept signatures - * which violate the DER spec in various ways. Its purpose is to allow - * validation of the Bitcoin blockchain, which includes non-DER signatures - * from before the network rules were updated to enforce DER. Note that - * the set of supported violations is a strict subset of what OpenSSL will - * accept. - * - * After the call, sig will always be initialized. If parsing failed or the - * encoded numbers are out of range, signature validation with it is - * guaranteed to fail for every message and public key. - */ -int ecdsa_signature_parse_der_lax( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature* sig, - const unsigned char *input, - size_t inputlen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -#ifdef __cplusplus -} -#endif - -#endif /* SECP256K1_CONTRIB_LAX_DER_PARSING_H */ diff --git a/util/secp256k1/depend/secp256k1/contrib/lax_der_privatekey_parsing.c b/util/secp256k1/depend/secp256k1/contrib/lax_der_privatekey_parsing.c deleted file mode 100644 index c2e63b4b8d..0000000000 --- a/util/secp256k1/depend/secp256k1/contrib/lax_der_privatekey_parsing.c +++ /dev/null @@ -1,113 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014, 2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#include -#include - -#include "lax_der_privatekey_parsing.h" - -int ec_privkey_import_der(const secp256k1_context* ctx, unsigned char *out32, const unsigned char *privkey, size_t privkeylen) { - const unsigned char *end = privkey + privkeylen; - int lenb = 0; - int len = 0; - memset(out32, 0, 32); - /* sequence header */ - if (end < privkey+1 || *privkey != 0x30) { - return 0; - } - privkey++; - /* sequence length constructor */ - if (end < privkey+1 || !(*privkey & 0x80)) { - return 0; - } - lenb = *privkey & ~0x80; privkey++; - if (lenb < 1 || lenb > 2) { - return 0; - } - if (end < privkey+lenb) { - return 0; - } - /* sequence length */ - len = privkey[lenb-1] | (lenb > 1 ? privkey[lenb-2] << 8 : 0); - privkey += lenb; - if (end < privkey+len) { - return 0; - } - /* sequence element 0: version number (=1) */ - if (end < privkey+3 || privkey[0] != 0x02 || privkey[1] != 0x01 || privkey[2] != 0x01) { - return 0; - } - privkey += 3; - /* sequence element 1: octet string, up to 32 bytes */ - if (end < privkey+2 || privkey[0] != 0x04 || privkey[1] > 0x20 || end < privkey+2+privkey[1]) { - return 0; - } - memcpy(out32 + 32 - privkey[1], privkey + 2, privkey[1]); - if (!secp256k1_ec_seckey_verify(ctx, out32)) { - memset(out32, 0, 32); - return 0; - } - return 1; -} - -int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, int compressed) { - secp256k1_pubkey pubkey; - size_t pubkeylen = 0; - if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) { - *privkeylen = 0; - return 0; - } - if (compressed) { - static const unsigned char begin[] = { - 0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20 - }; - static const unsigned char middle[] = { - 0xA0,0x81,0x85,0x30,0x81,0x82,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, - 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, - 0x21,0x02,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, - 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, - 0x17,0x98,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, - 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x24,0x03,0x22,0x00 - }; - unsigned char *ptr = privkey; - memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); - memcpy(ptr, key32, 32); ptr += 32; - memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); - pubkeylen = 33; - secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED); - ptr += pubkeylen; - *privkeylen = ptr - privkey; - } else { - static const unsigned char begin[] = { - 0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20 - }; - static const unsigned char middle[] = { - 0xA0,0x81,0xA5,0x30,0x81,0xA2,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, - 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, - 0x41,0x04,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, - 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, - 0x17,0x98,0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65,0x5D,0xA4,0xFB,0xFC,0x0E,0x11, - 0x08,0xA8,0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,0x9C,0x47,0xD0,0x8F,0xFB,0x10, - 0xD4,0xB8,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, - 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x44,0x03,0x42,0x00 - }; - unsigned char *ptr = privkey; - memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); - memcpy(ptr, key32, 32); ptr += 32; - memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); - pubkeylen = 65; - secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED); - ptr += pubkeylen; - *privkeylen = ptr - privkey; - } - return 1; -} diff --git a/util/secp256k1/depend/secp256k1/contrib/lax_der_privatekey_parsing.h b/util/secp256k1/depend/secp256k1/contrib/lax_der_privatekey_parsing.h deleted file mode 100644 index fece261fb9..0000000000 --- a/util/secp256k1/depend/secp256k1/contrib/lax_der_privatekey_parsing.h +++ /dev/null @@ -1,90 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014, 2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -/**** - * Please do not link this file directly. It is not part of the libsecp256k1 - * project and does not promise any stability in its API, functionality or - * presence. Projects which use this code should instead copy this header - * and its accompanying .c file directly into their codebase. - ****/ - -/* This file contains code snippets that parse DER private keys with - * various errors and violations. This is not a part of the library - * itself, because the allowed violations are chosen arbitrarily and - * do not follow or establish any standard. - * - * It also contains code to serialize private keys in a compatible - * manner. - * - * These functions are meant for compatibility with applications - * that require BER encoded keys. When working with secp256k1-specific - * code, the simple 32-byte private keys normally used by the - * library are sufficient. - */ - -#ifndef SECP256K1_CONTRIB_BER_PRIVATEKEY_H -#define SECP256K1_CONTRIB_BER_PRIVATEKEY_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Export a private key in DER format. - * - * Returns: 1 if the private key was valid. - * Args: ctx: pointer to a context object, initialized for signing (cannot - * be NULL) - * Out: privkey: pointer to an array for storing the private key in BER. - * Should have space for 279 bytes, and cannot be NULL. - * privkeylen: Pointer to an int where the length of the private key in - * privkey will be stored. - * In: seckey: pointer to a 32-byte secret key to export. - * compressed: 1 if the key should be exported in - * compressed format, 0 otherwise - * - * This function is purely meant for compatibility with applications that - * require BER encoded keys. When working with secp256k1-specific code, the - * simple 32-byte private keys are sufficient. - * - * Note that this function does not guarantee correct DER output. It is - * guaranteed to be parsable by secp256k1_ec_privkey_import_der - */ -SECP256K1_WARN_UNUSED_RESULT int ec_privkey_export_der( - const secp256k1_context* ctx, - unsigned char *privkey, - size_t *privkeylen, - const unsigned char *seckey, - int compressed -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Import a private key in DER format. - * Returns: 1 if a private key was extracted. - * Args: ctx: pointer to a context object (cannot be NULL). - * Out: seckey: pointer to a 32-byte array for storing the private key. - * (cannot be NULL). - * In: privkey: pointer to a private key in DER format (cannot be NULL). - * privkeylen: length of the DER private key pointed to be privkey. - * - * This function will accept more than just strict DER, and even allow some BER - * violations. The public key stored inside the DER-encoded private key is not - * verified for correctness, nor are the curve parameters. Use this function - * only if you know in advance it is supposed to contain a secp256k1 private - * key. - */ -SECP256K1_WARN_UNUSED_RESULT int ec_privkey_import_der( - const secp256k1_context* ctx, - unsigned char *seckey, - const unsigned char *privkey, - size_t privkeylen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -#ifdef __cplusplus -} -#endif - -#endif /* SECP256K1_CONTRIB_BER_PRIVATEKEY_H */ diff --git a/util/secp256k1/depend/secp256k1/include/secp256k1.h b/util/secp256k1/depend/secp256k1/include/secp256k1.h deleted file mode 100644 index 3e9c098d19..0000000000 --- a/util/secp256k1/depend/secp256k1/include/secp256k1.h +++ /dev/null @@ -1,621 +0,0 @@ -#ifndef SECP256K1_H -#define SECP256K1_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* These rules specify the order of arguments in API calls: - * - * 1. Context pointers go first, followed by output arguments, combined - * output/input arguments, and finally input-only arguments. - * 2. Array lengths always immediately the follow the argument whose length - * they describe, even if this violates rule 1. - * 3. Within the OUT/OUTIN/IN groups, pointers to data that is typically generated - * later go first. This means: signatures, public nonces, private nonces, - * messages, public keys, secret keys, tweaks. - * 4. Arguments that are not data pointers go last, from more complex to less - * complex: function pointers, algorithm names, messages, void pointers, - * counts, flags, booleans. - * 5. Opaque data pointers follow the function pointer they are to be passed to. - */ - -/** Opaque data structure that holds context information (precomputed tables etc.). - * - * The purpose of context structures is to cache large precomputed data tables - * that are expensive to construct, and also to maintain the randomization data - * for blinding. - * - * Do not create a new context object for each operation, as construction is - * far slower than all other API calls (~100 times slower than an ECDSA - * verification). - * - * A constructed context can safely be used from multiple threads - * simultaneously, but API call that take a non-const pointer to a context - * need exclusive access to it. In particular this is the case for - * secp256k1_context_destroy and secp256k1_context_randomize. - * - * Regarding randomization, either do it once at creation time (in which case - * you do not need any locking for the other calls), or use a read-write lock. - */ -typedef struct secp256k1_context_struct secp256k1_context; - -/** Opaque data structure that holds a parsed and valid public key. - * - * The exact representation of data inside is implementation defined and not - * guaranteed to be portable between different platforms or versions. It is - * however guaranteed to be 64 bytes in size, and can be safely copied/moved. - * If you need to convert to a format suitable for storage, transmission, or - * comparison, use secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse. - */ -typedef struct { - unsigned char data[64]; -} secp256k1_pubkey; - -/** Opaque data structured that holds a parsed ECDSA signature. - * - * The exact representation of data inside is implementation defined and not - * guaranteed to be portable between different platforms or versions. It is - * however guaranteed to be 64 bytes in size, and can be safely copied/moved. - * If you need to convert to a format suitable for storage, transmission, or - * comparison, use the secp256k1_ecdsa_signature_serialize_* and - * secp256k1_ecdsa_signature_parse_* functions. - */ -typedef struct { - unsigned char data[64]; -} secp256k1_ecdsa_signature; - -/** A pointer to a function to deterministically generate a nonce. - * - * Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail. - * Out: nonce32: pointer to a 32-byte array to be filled by the function. - * In: msg32: the 32-byte message hash being verified (will not be NULL) - * key32: pointer to a 32-byte secret key (will not be NULL) - * algo16: pointer to a 16-byte array describing the signature - * algorithm (will be NULL for ECDSA for compatibility). - * data: Arbitrary data pointer that is passed through. - * attempt: how many iterations we have tried to find a nonce. - * This will almost always be 0, but different attempt values - * are required to result in a different nonce. - * - * Except for test cases, this function should compute some cryptographic hash of - * the message, the algorithm, the key and the attempt. - */ -typedef int (*secp256k1_nonce_function)( - unsigned char *nonce32, - const unsigned char *msg32, - const unsigned char *key32, - const unsigned char *algo16, - void *data, - unsigned int attempt -); - -# if !defined(SECP256K1_GNUC_PREREQ) -# if defined(__GNUC__)&&defined(__GNUC_MINOR__) -# define SECP256K1_GNUC_PREREQ(_maj,_min) \ - ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) -# else -# define SECP256K1_GNUC_PREREQ(_maj,_min) 0 -# endif -# endif - -# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) -# if SECP256K1_GNUC_PREREQ(2,7) -# define SECP256K1_INLINE __inline__ -# elif (defined(_MSC_VER)) -# define SECP256K1_INLINE __inline -# else -# define SECP256K1_INLINE -# endif -# else -# define SECP256K1_INLINE inline -# endif - -#ifndef SECP256K1_API -# if defined(_WIN32) -# ifdef SECP256K1_BUILD -# define SECP256K1_API __declspec(dllexport) -# else -# define SECP256K1_API -# endif -# elif defined(__GNUC__) && defined(SECP256K1_BUILD) -# define SECP256K1_API __attribute__ ((visibility ("default"))) -# else -# define SECP256K1_API -# endif -#endif - -/**Warning attributes - * NONNULL is not used if SECP256K1_BUILD is set to avoid the compiler optimizing out - * some paranoid null checks. */ -# if defined(__GNUC__) && SECP256K1_GNUC_PREREQ(3, 4) -# define SECP256K1_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) -# else -# define SECP256K1_WARN_UNUSED_RESULT -# endif -# if !defined(SECP256K1_BUILD) && defined(__GNUC__) && SECP256K1_GNUC_PREREQ(3, 4) -# define SECP256K1_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x))) -# else -# define SECP256K1_ARG_NONNULL(_x) -# endif - -/** All flags' lower 8 bits indicate what they're for. Do not use directly. */ -#define SECP256K1_FLAGS_TYPE_MASK ((1 << 8) - 1) -#define SECP256K1_FLAGS_TYPE_CONTEXT (1 << 0) -#define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1) -/** The higher bits contain the actual data. Do not use directly. */ -#define SECP256K1_FLAGS_BIT_CONTEXT_VERIFY (1 << 8) -#define SECP256K1_FLAGS_BIT_CONTEXT_SIGN (1 << 9) -#define SECP256K1_FLAGS_BIT_COMPRESSION (1 << 8) - -/** Flags to pass to secp256k1_context_create. */ -#define SECP256K1_CONTEXT_VERIFY (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) -#define SECP256K1_CONTEXT_SIGN (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_SIGN) -#define SECP256K1_CONTEXT_NONE (SECP256K1_FLAGS_TYPE_CONTEXT) - -/** Flag to pass to secp256k1_ec_pubkey_serialize and secp256k1_ec_privkey_export. */ -#define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION) -#define SECP256K1_EC_UNCOMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION) - -/** Prefix byte used to tag various encoded curvepoints for specific purposes */ -#define SECP256K1_TAG_PUBKEY_EVEN 0x02 -#define SECP256K1_TAG_PUBKEY_ODD 0x03 -#define SECP256K1_TAG_PUBKEY_UNCOMPRESSED 0x04 -#define SECP256K1_TAG_PUBKEY_HYBRID_EVEN 0x06 -#define SECP256K1_TAG_PUBKEY_HYBRID_ODD 0x07 - -/** Create a secp256k1 context object. - * - * Returns: a newly created context object. - * In: flags: which parts of the context to initialize. - * - * See also secp256k1_context_randomize. - */ -SECP256K1_API secp256k1_context* secp256k1_context_create( - unsigned int flags -) SECP256K1_WARN_UNUSED_RESULT; - -/** Copies a secp256k1 context object. - * - * Returns: a newly created context object. - * Args: ctx: an existing context to copy (cannot be NULL) - */ -SECP256K1_API secp256k1_context* secp256k1_context_clone( - const secp256k1_context* ctx -) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT; - -/** Destroy a secp256k1 context object. - * - * The context pointer may not be used afterwards. - * Args: ctx: an existing context to destroy (cannot be NULL) - */ -SECP256K1_API void secp256k1_context_destroy( - secp256k1_context* ctx -); - -/** Set a callback function to be called when an illegal argument is passed to - * an API call. It will only trigger for violations that are mentioned - * explicitly in the header. - * - * The philosophy is that these shouldn't be dealt with through a - * specific return value, as calling code should not have branches to deal with - * the case that this code itself is broken. - * - * On the other hand, during debug stage, one would want to be informed about - * such mistakes, and the default (crashing) may be inadvisable. - * When this callback is triggered, the API function called is guaranteed not - * to cause a crash, though its return value and output arguments are - * undefined. - * - * Args: ctx: an existing context object (cannot be NULL) - * In: fun: a pointer to a function to call when an illegal argument is - * passed to the API, taking a message and an opaque pointer - * (NULL restores a default handler that calls abort). - * data: the opaque pointer to pass to fun above. - */ -SECP256K1_API void secp256k1_context_set_illegal_callback( - secp256k1_context* ctx, - void (*fun)(const char* message, void* data), - const void* data -) SECP256K1_ARG_NONNULL(1); - -/** Set a callback function to be called when an internal consistency check - * fails. The default is crashing. - * - * This can only trigger in case of a hardware failure, miscompilation, - * memory corruption, serious bug in the library, or other error would can - * otherwise result in undefined behaviour. It will not trigger due to mere - * incorrect usage of the API (see secp256k1_context_set_illegal_callback - * for that). After this callback returns, anything may happen, including - * crashing. - * - * Args: ctx: an existing context object (cannot be NULL) - * In: fun: a pointer to a function to call when an internal error occurs, - * taking a message and an opaque pointer (NULL restores a default - * handler that calls abort). - * data: the opaque pointer to pass to fun above. - */ -SECP256K1_API void secp256k1_context_set_error_callback( - secp256k1_context* ctx, - void (*fun)(const char* message, void* data), - const void* data -) SECP256K1_ARG_NONNULL(1); - -/** Parse a variable-length public key into the pubkey object. - * - * Returns: 1 if the public key was fully valid. - * 0 if the public key could not be parsed or is invalid. - * Args: ctx: a secp256k1 context object. - * Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a - * parsed version of input. If not, its value is undefined. - * In: input: pointer to a serialized public key - * inputlen: length of the array pointed to by input - * - * This function supports parsing compressed (33 bytes, header byte 0x02 or - * 0x03), uncompressed (65 bytes, header byte 0x04), or hybrid (65 bytes, header - * byte 0x06 or 0x07) format public keys. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse( - const secp256k1_context* ctx, - secp256k1_pubkey* pubkey, - const unsigned char *input, - size_t inputlen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Serialize a pubkey object into a serialized byte sequence. - * - * Returns: 1 always. - * Args: ctx: a secp256k1 context object. - * Out: output: a pointer to a 65-byte (if compressed==0) or 33-byte (if - * compressed==1) byte array to place the serialized key - * in. - * In/Out: outputlen: a pointer to an integer which is initially set to the - * size of output, and is overwritten with the written - * size. - * In: pubkey: a pointer to a secp256k1_pubkey containing an - * initialized public key. - * flags: SECP256K1_EC_COMPRESSED if serialization should be in - * compressed format, otherwise SECP256K1_EC_UNCOMPRESSED. - */ -SECP256K1_API int secp256k1_ec_pubkey_serialize( - const secp256k1_context* ctx, - unsigned char *output, - size_t *outputlen, - const secp256k1_pubkey* pubkey, - unsigned int flags -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Parse an ECDSA signature in compact (64 bytes) format. - * - * Returns: 1 when the signature could be parsed, 0 otherwise. - * Args: ctx: a secp256k1 context object - * Out: sig: a pointer to a signature object - * In: input64: a pointer to the 64-byte array to parse - * - * The signature must consist of a 32-byte big endian R value, followed by a - * 32-byte big endian S value. If R or S fall outside of [0..order-1], the - * encoding is invalid. R and S with value 0 are allowed in the encoding. - * - * After the call, sig will always be initialized. If parsing failed or R or - * S are zero, the resulting sig value is guaranteed to fail validation for any - * message and public key. - */ -SECP256K1_API int secp256k1_ecdsa_signature_parse_compact( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature* sig, - const unsigned char *input64 -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Parse a DER ECDSA signature. - * - * Returns: 1 when the signature could be parsed, 0 otherwise. - * Args: ctx: a secp256k1 context object - * Out: sig: a pointer to a signature object - * In: input: a pointer to the signature to be parsed - * inputlen: the length of the array pointed to be input - * - * This function will accept any valid DER encoded signature, even if the - * encoded numbers are out of range. - * - * After the call, sig will always be initialized. If parsing failed or the - * encoded numbers are out of range, signature validation with it is - * guaranteed to fail for every message and public key. - */ -SECP256K1_API int secp256k1_ecdsa_signature_parse_der( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature* sig, - const unsigned char *input, - size_t inputlen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Serialize an ECDSA signature in DER format. - * - * Returns: 1 if enough space was available to serialize, 0 otherwise - * Args: ctx: a secp256k1 context object - * Out: output: a pointer to an array to store the DER serialization - * In/Out: outputlen: a pointer to a length integer. Initially, this integer - * should be set to the length of output. After the call - * it will be set to the length of the serialization (even - * if 0 was returned). - * In: sig: a pointer to an initialized signature object - */ -SECP256K1_API int secp256k1_ecdsa_signature_serialize_der( - const secp256k1_context* ctx, - unsigned char *output, - size_t *outputlen, - const secp256k1_ecdsa_signature* sig -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Serialize an ECDSA signature in compact (64 byte) format. - * - * Returns: 1 - * Args: ctx: a secp256k1 context object - * Out: output64: a pointer to a 64-byte array to store the compact serialization - * In: sig: a pointer to an initialized signature object - * - * See secp256k1_ecdsa_signature_parse_compact for details about the encoding. - */ -SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact( - const secp256k1_context* ctx, - unsigned char *output64, - const secp256k1_ecdsa_signature* sig -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Verify an ECDSA signature. - * - * Returns: 1: correct signature - * 0: incorrect or unparseable signature - * Args: ctx: a secp256k1 context object, initialized for verification. - * In: sig: the signature being verified (cannot be NULL) - * msg32: the 32-byte message hash being verified (cannot be NULL) - * pubkey: pointer to an initialized public key to verify with (cannot be NULL) - * - * To avoid accepting malleable signatures, only ECDSA signatures in lower-S - * form are accepted. - * - * If you need to accept ECDSA signatures from sources that do not obey this - * rule, apply secp256k1_ecdsa_signature_normalize to the signature prior to - * validation, but be aware that doing so results in malleable signatures. - * - * For details, see the comments for that function. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( - const secp256k1_context* ctx, - const secp256k1_ecdsa_signature *sig, - const unsigned char *msg32, - const secp256k1_pubkey *pubkey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Convert a signature to a normalized lower-S form. - * - * Returns: 1 if sigin was not normalized, 0 if it already was. - * Args: ctx: a secp256k1 context object - * Out: sigout: a pointer to a signature to fill with the normalized form, - * or copy if the input was already normalized. (can be NULL if - * you're only interested in whether the input was already - * normalized). - * In: sigin: a pointer to a signature to check/normalize (cannot be NULL, - * can be identical to sigout) - * - * With ECDSA a third-party can forge a second distinct signature of the same - * message, given a single initial signature, but without knowing the key. This - * is done by negating the S value modulo the order of the curve, 'flipping' - * the sign of the random point R which is not included in the signature. - * - * Forgery of the same message isn't universally problematic, but in systems - * where message malleability or uniqueness of signatures is important this can - * cause issues. This forgery can be blocked by all verifiers forcing signers - * to use a normalized form. - * - * The lower-S form reduces the size of signatures slightly on average when - * variable length encodings (such as DER) are used and is cheap to verify, - * making it a good choice. Security of always using lower-S is assured because - * anyone can trivially modify a signature after the fact to enforce this - * property anyway. - * - * The lower S value is always between 0x1 and - * 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, - * inclusive. - * - * No other forms of ECDSA malleability are known and none seem likely, but - * there is no formal proof that ECDSA, even with this additional restriction, - * is free of other malleability. Commonly used serialization schemes will also - * accept various non-unique encodings, so care should be taken when this - * property is required for an application. - * - * The secp256k1_ecdsa_sign function will by default create signatures in the - * lower-S form, and secp256k1_ecdsa_verify will not accept others. In case - * signatures come from a system that cannot enforce this property, - * secp256k1_ecdsa_signature_normalize must be called before verification. - */ -SECP256K1_API int secp256k1_ecdsa_signature_normalize( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature *sigout, - const secp256k1_ecdsa_signature *sigin -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3); - -/** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function. - * If a data pointer is passed, it is assumed to be a pointer to 32 bytes of - * extra entropy. - */ -SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; - -/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */ -SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_default; - -/** Create an ECDSA signature. - * - * Returns: 1: signature created - * 0: the nonce generation function failed, or the private key was invalid. - * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) - * In: msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) - * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used - * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) - * - * The created signature is always in lower-S form. See - * secp256k1_ecdsa_signature_normalize for more details. - */ -SECP256K1_API int secp256k1_ecdsa_sign( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature *sig, - const unsigned char *msg32, - const unsigned char *seckey, - secp256k1_nonce_function noncefp, - const void *ndata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Verify an ECDSA secret key. - * - * Returns: 1: secret key is valid - * 0: secret key is invalid - * Args: ctx: pointer to a context object (cannot be NULL) - * In: seckey: pointer to a 32-byte secret key (cannot be NULL) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify( - const secp256k1_context* ctx, - const unsigned char *seckey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); - -/** Compute the public key for a secret key. - * - * Returns: 1: secret was valid, public key stores - * 0: secret was invalid, try again - * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * Out: pubkey: pointer to the created public key (cannot be NULL) - * In: seckey: pointer to a 32-byte private key (cannot be NULL) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const unsigned char *seckey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Negates a private key in place. - * - * Returns: 1 always - * Args: ctx: pointer to a context object - * In/Out: pubkey: pointer to the public key to be negated (cannot be NULL) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate( - const secp256k1_context* ctx, - unsigned char *seckey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); - -/** Negates a public key in place. - * - * Returns: 1 always - * Args: ctx: pointer to a context object - * In/Out: pubkey: pointer to the public key to be negated (cannot be NULL) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); - -/** Tweak a private key by adding tweak to it. - * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for - * uniformly random 32-byte arrays, or if the resulting private key - * would be invalid (only when the tweak is the complement of the - * private key). 1 otherwise. - * Args: ctx: pointer to a context object (cannot be NULL). - * In/Out: seckey: pointer to a 32-byte private key. - * In: tweak: pointer to a 32-byte tweak. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add( - const secp256k1_context* ctx, - unsigned char *seckey, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Tweak a public key by adding tweak times the generator to it. - * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for - * uniformly random 32-byte arrays, or if the resulting public key - * would be invalid (only when the tweak is the complement of the - * corresponding private key). 1 otherwise. - * Args: ctx: pointer to a context object initialized for validation - * (cannot be NULL). - * In/Out: pubkey: pointer to a public key object. - * In: tweak: pointer to a 32-byte tweak. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Tweak a private key by multiplying it by a tweak. - * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for - * uniformly random 32-byte arrays, or equal to zero. 1 otherwise. - * Args: ctx: pointer to a context object (cannot be NULL). - * In/Out: seckey: pointer to a 32-byte private key. - * In: tweak: pointer to a 32-byte tweak. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul( - const secp256k1_context* ctx, - unsigned char *seckey, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Tweak a public key by multiplying it by a tweak value. - * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for - * uniformly random 32-byte arrays, or equal to zero. 1 otherwise. - * Args: ctx: pointer to a context object initialized for validation - * (cannot be NULL). - * In/Out: pubkey: pointer to a public key obkect. - * In: tweak: pointer to a 32-byte tweak. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Updates the context randomization to protect against side-channel leakage. - * Returns: 1: randomization successfully updated - * 0: error - * Args: ctx: pointer to a context object (cannot be NULL) - * In: seed32: pointer to a 32-byte random seed (NULL resets to initial state) - * - * While secp256k1 code is written to be constant-time no matter what secret - * values are, it's possible that a future compiler may output code which isn't, - * and also that the CPU may not emit the same radio frequencies or draw the same - * amount power for all values. - * - * This function provides a seed which is combined into the blinding value: that - * blinding value is added before each multiplication (and removed afterwards) so - * that it does not affect function results, but shields against attacks which - * rely on any input-dependent behaviour. - * - * You should call this after secp256k1_context_create or - * secp256k1_context_clone, and may call this repeatedly afterwards. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize( - secp256k1_context* ctx, - const unsigned char *seed32 -) SECP256K1_ARG_NONNULL(1); - -/** Add a number of public keys together. - * Returns: 1: the sum of the public keys is valid. - * 0: the sum of the public keys is not valid. - * Args: ctx: pointer to a context object - * Out: out: pointer to a public key object for placing the resulting public key - * (cannot be NULL) - * In: ins: pointer to array of pointers to public keys (cannot be NULL) - * n: the number of public keys to add together (must be at least 1) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine( - const secp256k1_context* ctx, - secp256k1_pubkey *out, - const secp256k1_pubkey * const * ins, - size_t n -) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -#ifdef __cplusplus -} -#endif - -#endif /* SECP256K1_H */ diff --git a/util/secp256k1/depend/secp256k1/include/secp256k1_ecdh.h b/util/secp256k1/depend/secp256k1/include/secp256k1_ecdh.h deleted file mode 100644 index 88492dc1a4..0000000000 --- a/util/secp256k1/depend/secp256k1/include/secp256k1_ecdh.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef SECP256K1_ECDH_H -#define SECP256K1_ECDH_H - -#include "secp256k1.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Compute an EC Diffie-Hellman secret in constant time - * Returns: 1: exponentiation was successful - * 0: scalar was invalid (zero or overflow) - * Args: ctx: pointer to a context object (cannot be NULL) - * Out: result: a 32-byte array which will be populated by an ECDH - * secret computed from the point and scalar - * In: pubkey: a pointer to a secp256k1_pubkey containing an - * initialized public key - * privkey: a 32-byte scalar with which to multiply the point - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh( - const secp256k1_context* ctx, - unsigned char *result, - const secp256k1_pubkey *pubkey, - const unsigned char *privkey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -#ifdef __cplusplus -} -#endif - -#endif /* SECP256K1_ECDH_H */ diff --git a/util/secp256k1/depend/secp256k1/include/secp256k1_recovery.h b/util/secp256k1/depend/secp256k1/include/secp256k1_recovery.h deleted file mode 100644 index cf6c5ed7f5..0000000000 --- a/util/secp256k1/depend/secp256k1/include/secp256k1_recovery.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef SECP256K1_RECOVERY_H -#define SECP256K1_RECOVERY_H - -#include "secp256k1.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Opaque data structured that holds a parsed ECDSA signature, - * supporting pubkey recovery. - * - * The exact representation of data inside is implementation defined and not - * guaranteed to be portable between different platforms or versions. It is - * however guaranteed to be 65 bytes in size, and can be safely copied/moved. - * If you need to convert to a format suitable for storage or transmission, use - * the secp256k1_ecdsa_signature_serialize_* and - * secp256k1_ecdsa_signature_parse_* functions. - * - * Furthermore, it is guaranteed that identical signatures (including their - * recoverability) will have identical representation, so they can be - * memcmp'ed. - */ -typedef struct { - unsigned char data[65]; -} secp256k1_ecdsa_recoverable_signature; - -/** Parse a compact ECDSA signature (64 bytes + recovery id). - * - * Returns: 1 when the signature could be parsed, 0 otherwise - * Args: ctx: a secp256k1 context object - * Out: sig: a pointer to a signature object - * In: input64: a pointer to a 64-byte compact signature - * recid: the recovery id (0, 1, 2 or 3) - */ -SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact( - const secp256k1_context* ctx, - secp256k1_ecdsa_recoverable_signature* sig, - const unsigned char *input64, - int recid -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Convert a recoverable signature into a normal signature. - * - * Returns: 1 - * Out: sig: a pointer to a normal signature (cannot be NULL). - * In: sigin: a pointer to a recoverable signature (cannot be NULL). - */ -SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature* sig, - const secp256k1_ecdsa_recoverable_signature* sigin -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Serialize an ECDSA signature in compact format (64 bytes + recovery id). - * - * Returns: 1 - * Args: ctx: a secp256k1 context object - * Out: output64: a pointer to a 64-byte array of the compact signature (cannot be NULL) - * recid: a pointer to an integer to hold the recovery id (can be NULL). - * In: sig: a pointer to an initialized signature object (cannot be NULL) - */ -SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact( - const secp256k1_context* ctx, - unsigned char *output64, - int *recid, - const secp256k1_ecdsa_recoverable_signature* sig -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Create a recoverable ECDSA signature. - * - * Returns: 1: signature created - * 0: the nonce generation function failed, or the private key was invalid. - * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) - * In: msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) - * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used - * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) - */ -SECP256K1_API int secp256k1_ecdsa_sign_recoverable( - const secp256k1_context* ctx, - secp256k1_ecdsa_recoverable_signature *sig, - const unsigned char *msg32, - const unsigned char *seckey, - secp256k1_nonce_function noncefp, - const void *ndata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Recover an ECDSA public key from a signature. - * - * Returns: 1: public key successfully recovered (which guarantees a correct signature). - * 0: otherwise. - * Args: ctx: pointer to a context object, initialized for verification (cannot be NULL) - * Out: pubkey: pointer to the recovered public key (cannot be NULL) - * In: sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL) - * msg32: the 32-byte message hash assumed to be signed (cannot be NULL) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const secp256k1_ecdsa_recoverable_signature *sig, - const unsigned char *msg32 -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -#ifdef __cplusplus -} -#endif - -#endif /* SECP256K1_RECOVERY_H */ diff --git a/util/secp256k1/depend/secp256k1/include/secp256k1_schnorr.h b/util/secp256k1/depend/secp256k1/include/secp256k1_schnorr.h deleted file mode 100644 index dc32fec1ea..0000000000 --- a/util/secp256k1/depend/secp256k1/include/secp256k1_schnorr.h +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef _SECP256K1_SCHNORR_ -# define _SECP256K1_SCHNORR_ - -# include "secp256k1.h" - -# ifdef __cplusplus -extern "C" { -# endif - -/** Create a signature using a custom EC-Schnorr-SHA256 construction. It - * produces non-malleable 64-byte signatures which support public key recovery - * batch validation, and multiparty signing. - * Returns: 1: signature created - * 0: the nonce generation function failed, or the private key was - * invalid. - * Args: ctx: pointer to a context object, initialized for signing - * (cannot be NULL) - * Out: sig64: pointer to a 64-byte array where the signature will be - * placed (cannot be NULL) - * In: msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) - * noncefp:pointer to a nonce generation function. If NULL, - * secp256k1_nonce_function_default is used - * ndata: pointer to arbitrary data used by the nonce generation - * function (can be NULL) - */ -SECP256K1_API int secp256k1_schnorr_sign( - const secp256k1_context* ctx, - unsigned char *sig64, - const unsigned char *msg32, - const unsigned char *seckey, - secp256k1_nonce_function noncefp, - const void *ndata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Verify a signature created by secp256k1_schnorr_sign. - * Returns: 1: correct signature - * 0: incorrect signature - * Args: ctx: a secp256k1 context object, initialized for verification. - * In: sig64: the 64-byte signature being verified (cannot be NULL) - * msg32: the 32-byte message hash being verified (cannot be NULL) - * pubkey: the public key to verify with (cannot be NULL) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_verify( - const secp256k1_context* ctx, - const unsigned char *sig64, - const unsigned char *msg32, - const secp256k1_pubkey *pubkey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Recover an EC public key from a Schnorr signature created using - * secp256k1_schnorr_sign. - * Returns: 1: public key successfully recovered (which guarantees a correct - * signature). - * 0: otherwise. - * Args: ctx: pointer to a context object, initialized for - * verification (cannot be NULL) - * Out: pubkey: pointer to a pubkey to set to the recovered public key - * (cannot be NULL). - * In: sig64: signature as 64 byte array (cannot be NULL) - * msg32: the 32-byte message hash assumed to be signed (cannot - * be NULL) - */ -SECP256K1_API int secp256k1_schnorr_recover( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const unsigned char *sig64, - const unsigned char *msg32 -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Generate a nonce pair deterministically for use with - * secp256k1_schnorr_partial_sign. - * Returns: 1: valid nonce pair was generated. - * 0: otherwise (nonce generation function failed) - * Args: ctx: pointer to a context object, initialized for signing - * (cannot be NULL) - * Out: pubnonce: public side of the nonce (cannot be NULL) - * privnonce32: private side of the nonce (32 byte) (cannot be NULL) - * In: msg32: the 32-byte message hash assumed to be signed (cannot - * be NULL) - * sec32: the 32-byte private key (cannot be NULL) - * noncefp: pointer to a nonce generation function. If NULL, - * secp256k1_nonce_function_default is used - * noncedata: pointer to arbitrary data used by the nonce generation - * function (can be NULL) - * - * Do not use the output as a private/public key pair for signing/validation. - */ -SECP256K1_API int secp256k1_schnorr_generate_nonce_pair( - const secp256k1_context* ctx, - secp256k1_pubkey *pubnonce, - unsigned char *privnonce32, - const unsigned char *msg32, - const unsigned char *sec32, - secp256k1_nonce_function noncefp, - const void* noncedata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Produce a partial Schnorr signature, which can be combined using - * secp256k1_schnorr_partial_combine, to end up with a full signature that is - * verifiable using secp256k1_schnorr_verify. - * Returns: 1: signature created successfully. - * 0: no valid signature exists with this combination of keys, nonces - * and message (chance around 1 in 2^128) - * -1: invalid private key, nonce, or public nonces. - * Args: ctx: pointer to context object, initialized for signing (cannot - * be NULL) - * Out: sig64: pointer to 64-byte array to put partial signature in - * In: msg32: pointer to 32-byte message to sign - * sec32: pointer to 32-byte private key - * pubnonce_others: pointer to pubkey containing the sum of the other's - * nonces (see secp256k1_ec_pubkey_combine) - * secnonce32: pointer to 32-byte array containing our nonce - * - * The intended procedure for creating a multiparty signature is: - * - Each signer S[i] with private key x[i] and public key Q[i] runs - * secp256k1_schnorr_generate_nonce_pair to produce a pair (k[i],R[i]) of - * private/public nonces. - * - All signers communicate their public nonces to each other (revealing your - * private nonce can lead to discovery of your private key, so it should be - * considered secret). - * - All signers combine all the public nonces they received (excluding their - * own) using secp256k1_ec_pubkey_combine to obtain an - * Rall[i] = sum(R[0..i-1,i+1..n]). - * - All signers produce a partial signature using - * secp256k1_schnorr_partial_sign, passing in their own private key x[i], - * their own private nonce k[i], and the sum of the others' public nonces - * Rall[i]. - * - All signers communicate their partial signatures to each other. - * - Someone combines all partial signatures using - * secp256k1_schnorr_partial_combine, to obtain a full signature. - * - The resulting signature is validatable using secp256k1_schnorr_verify, with - * public key equal to the result of secp256k1_ec_pubkey_combine of the - * signers' public keys (sum(Q[0..n])). - * - * Note that secp256k1_schnorr_partial_combine and secp256k1_ec_pubkey_combine - * function take their arguments in any order, and it is possible to - * pre-combine several inputs already with one call, and add more inputs later - * by calling the function again (they are commutative and associative). - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_sign( - const secp256k1_context* ctx, - unsigned char *sig64, - const unsigned char *msg32, - const unsigned char *sec32, - const secp256k1_pubkey *pubnonce_others, - const unsigned char *secnonce32 -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6); - -/** Combine multiple Schnorr partial signatures. - * Returns: 1: the passed signatures were successfully combined. - * 0: the resulting signature is not valid (chance of 1 in 2^256) - * -1: some inputs were invalid, or the signatures were not created - * using the same set of nonces - * Args: ctx: pointer to a context object - * Out: sig64: pointer to a 64-byte array to place the combined signature - * (cannot be NULL) - * In: sig64sin: pointer to an array of n pointers to 64-byte input - * signatures - * n: the number of signatures to combine (at least 1) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_combine( - const secp256k1_context* ctx, - unsigned char *sig64, - const unsigned char * const * sig64sin, - size_t n -) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -# ifdef __cplusplus -} -# endif - -#endif diff --git a/util/secp256k1/depend/secp256k1/libsecp256k1.pc.in b/util/secp256k1/depend/secp256k1/libsecp256k1.pc.in deleted file mode 100644 index a0d006f113..0000000000 --- a/util/secp256k1/depend/secp256k1/libsecp256k1.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libsecp256k1 -Description: Optimized C library for EC operations on curve secp256k1 -URL: https://github.com/bitcoin-core/secp256k1 -Version: @PACKAGE_VERSION@ -Cflags: -I${includedir} -Libs.private: @SECP_LIBS@ -Libs: -L${libdir} -lsecp256k1 - diff --git a/util/secp256k1/depend/secp256k1/obj/.gitignore b/util/secp256k1/depend/secp256k1/obj/.gitignore deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/util/secp256k1/depend/secp256k1/sage/group_prover.sage b/util/secp256k1/depend/secp256k1/sage/group_prover.sage deleted file mode 100644 index 8521f07999..0000000000 --- a/util/secp256k1/depend/secp256k1/sage/group_prover.sage +++ /dev/null @@ -1,322 +0,0 @@ -# This code supports verifying group implementations which have branches -# or conditional statements (like cmovs), by allowing each execution path -# to independently set assumptions on input or intermediary variables. -# -# The general approach is: -# * A constraint is a tuple of two sets of symbolic expressions: -# the first of which are required to evaluate to zero, the second of which -# are required to evaluate to nonzero. -# - A constraint is said to be conflicting if any of its nonzero expressions -# is in the ideal with basis the zero expressions (in other words: when the -# zero expressions imply that one of the nonzero expressions are zero). -# * There is a list of laws that describe the intended behaviour, including -# laws for addition and doubling. Each law is called with the symbolic point -# coordinates as arguments, and returns: -# - A constraint describing the assumptions under which it is applicable, -# called "assumeLaw" -# - A constraint describing the requirements of the law, called "require" -# * Implementations are transliterated into functions that operate as well on -# algebraic input points, and are called once per combination of branches -# executed. Each execution returns: -# - A constraint describing the assumptions this implementation requires -# (such as Z1=1), called "assumeFormula" -# - A constraint describing the assumptions this specific branch requires, -# but which is by construction guaranteed to cover the entire space by -# merging the results from all branches, called "assumeBranch" -# - The result of the computation -# * All combinations of laws with implementation branches are tried, and: -# - If the combination of assumeLaw, assumeFormula, and assumeBranch results -# in a conflict, it means this law does not apply to this branch, and it is -# skipped. -# - For others, we try to prove the require constraints hold, assuming the -# information in assumeLaw + assumeFormula + assumeBranch, and if this does -# not succeed, we fail. -# + To prove an expression is zero, we check whether it belongs to the -# ideal with the assumed zero expressions as basis. This test is exact. -# + To prove an expression is nonzero, we check whether each of its -# factors is contained in the set of nonzero assumptions' factors. -# This test is not exact, so various combinations of original and -# reduced expressions' factors are tried. -# - If we succeed, we print out the assumptions from assumeFormula that -# weren't implied by assumeLaw already. Those from assumeBranch are skipped, -# as we assume that all constraints in it are complementary with each other. -# -# Based on the sage verification scripts used in the Explicit-Formulas Database -# by Tanja Lange and others, see http://hyperelliptic.org/EFD - -class fastfrac: - """Fractions over rings.""" - - def __init__(self,R,top,bot=1): - """Construct a fractional, given a ring, a numerator, and denominator.""" - self.R = R - if parent(top) == ZZ or parent(top) == R: - self.top = R(top) - self.bot = R(bot) - elif top.__class__ == fastfrac: - self.top = top.top - self.bot = top.bot * bot - else: - self.top = R(numerator(top)) - self.bot = R(denominator(top)) * bot - - def iszero(self,I): - """Return whether this fraction is zero given an ideal.""" - return self.top in I and self.bot not in I - - def reduce(self,assumeZero): - zero = self.R.ideal(map(numerator, assumeZero)) - return fastfrac(self.R, zero.reduce(self.top)) / fastfrac(self.R, zero.reduce(self.bot)) - - def __add__(self,other): - """Add two fractions.""" - if parent(other) == ZZ: - return fastfrac(self.R,self.top + self.bot * other,self.bot) - if other.__class__ == fastfrac: - return fastfrac(self.R,self.top * other.bot + self.bot * other.top,self.bot * other.bot) - return NotImplemented - - def __sub__(self,other): - """Subtract two fractions.""" - if parent(other) == ZZ: - return fastfrac(self.R,self.top - self.bot * other,self.bot) - if other.__class__ == fastfrac: - return fastfrac(self.R,self.top * other.bot - self.bot * other.top,self.bot * other.bot) - return NotImplemented - - def __neg__(self): - """Return the negation of a fraction.""" - return fastfrac(self.R,-self.top,self.bot) - - def __mul__(self,other): - """Multiply two fractions.""" - if parent(other) == ZZ: - return fastfrac(self.R,self.top * other,self.bot) - if other.__class__ == fastfrac: - return fastfrac(self.R,self.top * other.top,self.bot * other.bot) - return NotImplemented - - def __rmul__(self,other): - """Multiply something else with a fraction.""" - return self.__mul__(other) - - def __div__(self,other): - """Divide two fractions.""" - if parent(other) == ZZ: - return fastfrac(self.R,self.top,self.bot * other) - if other.__class__ == fastfrac: - return fastfrac(self.R,self.top * other.bot,self.bot * other.top) - return NotImplemented - - def __pow__(self,other): - """Compute a power of a fraction.""" - if parent(other) == ZZ: - if other < 0: - # Negative powers require flipping top and bottom - return fastfrac(self.R,self.bot ^ (-other),self.top ^ (-other)) - else: - return fastfrac(self.R,self.top ^ other,self.bot ^ other) - return NotImplemented - - def __str__(self): - return "fastfrac((" + str(self.top) + ") / (" + str(self.bot) + "))" - def __repr__(self): - return "%s" % self - - def numerator(self): - return self.top - -class constraints: - """A set of constraints, consisting of zero and nonzero expressions. - - Constraints can either be used to express knowledge or a requirement. - - Both the fields zero and nonzero are maps from expressions to description - strings. The expressions that are the keys in zero are required to be zero, - and the expressions that are the keys in nonzero are required to be nonzero. - - Note that (a != 0) and (b != 0) is the same as (a*b != 0), so all keys in - nonzero could be multiplied into a single key. This is often much less - efficient to work with though, so we keep them separate inside the - constraints. This allows higher-level code to do fast checks on the individual - nonzero elements, or combine them if needed for stronger checks. - - We can't multiply the different zero elements, as it would suffice for one of - the factors to be zero, instead of all of them. Instead, the zero elements are - typically combined into an ideal first. - """ - - def __init__(self, **kwargs): - if 'zero' in kwargs: - self.zero = dict(kwargs['zero']) - else: - self.zero = dict() - if 'nonzero' in kwargs: - self.nonzero = dict(kwargs['nonzero']) - else: - self.nonzero = dict() - - def negate(self): - return constraints(zero=self.nonzero, nonzero=self.zero) - - def __add__(self, other): - zero = self.zero.copy() - zero.update(other.zero) - nonzero = self.nonzero.copy() - nonzero.update(other.nonzero) - return constraints(zero=zero, nonzero=nonzero) - - def __str__(self): - return "constraints(zero=%s,nonzero=%s)" % (self.zero, self.nonzero) - - def __repr__(self): - return "%s" % self - - -def conflicts(R, con): - """Check whether any of the passed non-zero assumptions is implied by the zero assumptions""" - zero = R.ideal(map(numerator, con.zero)) - if 1 in zero: - return True - # First a cheap check whether any of the individual nonzero terms conflict on - # their own. - for nonzero in con.nonzero: - if nonzero.iszero(zero): - return True - # It can be the case that entries in the nonzero set do not individually - # conflict with the zero set, but their combination does. For example, knowing - # that either x or y is zero is equivalent to having x*y in the zero set. - # Having x or y individually in the nonzero set is not a conflict, but both - # simultaneously is, so that is the right thing to check for. - if reduce(lambda a,b: a * b, con.nonzero, fastfrac(R, 1)).iszero(zero): - return True - return False - - -def get_nonzero_set(R, assume): - """Calculate a simple set of nonzero expressions""" - zero = R.ideal(map(numerator, assume.zero)) - nonzero = set() - for nz in map(numerator, assume.nonzero): - for (f,n) in nz.factor(): - nonzero.add(f) - rnz = zero.reduce(nz) - for (f,n) in rnz.factor(): - nonzero.add(f) - return nonzero - - -def prove_nonzero(R, exprs, assume): - """Check whether an expression is provably nonzero, given assumptions""" - zero = R.ideal(map(numerator, assume.zero)) - nonzero = get_nonzero_set(R, assume) - expl = set() - ok = True - for expr in exprs: - if numerator(expr) in zero: - return (False, [exprs[expr]]) - allexprs = reduce(lambda a,b: numerator(a)*numerator(b), exprs, 1) - for (f, n) in allexprs.factor(): - if f not in nonzero: - ok = False - if ok: - return (True, None) - ok = True - for (f, n) in zero.reduce(numerator(allexprs)).factor(): - if f not in nonzero: - ok = False - if ok: - return (True, None) - ok = True - for expr in exprs: - for (f,n) in numerator(expr).factor(): - if f not in nonzero: - ok = False - if ok: - return (True, None) - ok = True - for expr in exprs: - for (f,n) in zero.reduce(numerator(expr)).factor(): - if f not in nonzero: - expl.add(exprs[expr]) - if expl: - return (False, list(expl)) - else: - return (True, None) - - -def prove_zero(R, exprs, assume): - """Check whether all of the passed expressions are provably zero, given assumptions""" - r, e = prove_nonzero(R, dict(map(lambda x: (fastfrac(R, x.bot, 1), exprs[x]), exprs)), assume) - if not r: - return (False, map(lambda x: "Possibly zero denominator: %s" % x, e)) - zero = R.ideal(map(numerator, assume.zero)) - nonzero = prod(x for x in assume.nonzero) - expl = [] - for expr in exprs: - if not expr.iszero(zero): - expl.append(exprs[expr]) - if not expl: - return (True, None) - return (False, expl) - - -def describe_extra(R, assume, assumeExtra): - """Describe what assumptions are added, given existing assumptions""" - zerox = assume.zero.copy() - zerox.update(assumeExtra.zero) - zero = R.ideal(map(numerator, assume.zero)) - zeroextra = R.ideal(map(numerator, zerox)) - nonzero = get_nonzero_set(R, assume) - ret = set() - # Iterate over the extra zero expressions - for base in assumeExtra.zero: - if base not in zero: - add = [] - for (f, n) in numerator(base).factor(): - if f not in nonzero: - add += ["%s" % f] - if add: - ret.add((" * ".join(add)) + " = 0 [%s]" % assumeExtra.zero[base]) - # Iterate over the extra nonzero expressions - for nz in assumeExtra.nonzero: - nzr = zeroextra.reduce(numerator(nz)) - if nzr not in zeroextra: - for (f,n) in nzr.factor(): - if zeroextra.reduce(f) not in nonzero: - ret.add("%s != 0" % zeroextra.reduce(f)) - return ", ".join(x for x in ret) - - -def check_symbolic(R, assumeLaw, assumeAssert, assumeBranch, require): - """Check a set of zero and nonzero requirements, given a set of zero and nonzero assumptions""" - assume = assumeLaw + assumeAssert + assumeBranch - - if conflicts(R, assume): - # This formula does not apply - return None - - describe = describe_extra(R, assumeLaw + assumeBranch, assumeAssert) - - ok, msg = prove_zero(R, require.zero, assume) - if not ok: - return "FAIL, %s fails (assuming %s)" % (str(msg), describe) - - res, expl = prove_nonzero(R, require.nonzero, assume) - if not res: - return "FAIL, %s fails (assuming %s)" % (str(expl), describe) - - if describe != "": - return "OK (assuming %s)" % describe - else: - return "OK" - - -def concrete_verify(c): - for k in c.zero: - if k != 0: - return (False, c.zero[k]) - for k in c.nonzero: - if k == 0: - return (False, c.nonzero[k]) - return (True, None) diff --git a/util/secp256k1/depend/secp256k1/sage/secp256k1.sage b/util/secp256k1/depend/secp256k1/sage/secp256k1.sage deleted file mode 100644 index a97e732f7f..0000000000 --- a/util/secp256k1/depend/secp256k1/sage/secp256k1.sage +++ /dev/null @@ -1,306 +0,0 @@ -# Test libsecp256k1' group operation implementations using prover.sage - -import sys - -load("group_prover.sage") -load("weierstrass_prover.sage") - -def formula_secp256k1_gej_double_var(a): - """libsecp256k1's secp256k1_gej_double_var, used by various addition functions""" - rz = a.Z * a.Y - rz = rz * 2 - t1 = a.X^2 - t1 = t1 * 3 - t2 = t1^2 - t3 = a.Y^2 - t3 = t3 * 2 - t4 = t3^2 - t4 = t4 * 2 - t3 = t3 * a.X - rx = t3 - rx = rx * 4 - rx = -rx - rx = rx + t2 - t2 = -t2 - t3 = t3 * 6 - t3 = t3 + t2 - ry = t1 * t3 - t2 = -t4 - ry = ry + t2 - return jacobianpoint(rx, ry, rz) - -def formula_secp256k1_gej_add_var(branch, a, b): - """libsecp256k1's secp256k1_gej_add_var""" - if branch == 0: - return (constraints(), constraints(nonzero={a.Infinity : 'a_infinite'}), b) - if branch == 1: - return (constraints(), constraints(zero={a.Infinity : 'a_finite'}, nonzero={b.Infinity : 'b_infinite'}), a) - z22 = b.Z^2 - z12 = a.Z^2 - u1 = a.X * z22 - u2 = b.X * z12 - s1 = a.Y * z22 - s1 = s1 * b.Z - s2 = b.Y * z12 - s2 = s2 * a.Z - h = -u1 - h = h + u2 - i = -s1 - i = i + s2 - if branch == 2: - r = formula_secp256k1_gej_double_var(a) - return (constraints(), constraints(zero={h : 'h=0', i : 'i=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}), r) - if branch == 3: - return (constraints(), constraints(zero={h : 'h=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={i : 'i!=0'}), point_at_infinity()) - i2 = i^2 - h2 = h^2 - h3 = h2 * h - h = h * b.Z - rz = a.Z * h - t = u1 * h2 - rx = t - rx = rx * 2 - rx = rx + h3 - rx = -rx - rx = rx + i2 - ry = -rx - ry = ry + t - ry = ry * i - h3 = h3 * s1 - h3 = -h3 - ry = ry + h3 - return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz)) - -def formula_secp256k1_gej_add_ge_var(branch, a, b): - """libsecp256k1's secp256k1_gej_add_ge_var, which assume bz==1""" - if branch == 0: - return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(nonzero={a.Infinity : 'a_infinite'}), b) - if branch == 1: - return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite'}, nonzero={b.Infinity : 'b_infinite'}), a) - z12 = a.Z^2 - u1 = a.X - u2 = b.X * z12 - s1 = a.Y - s2 = b.Y * z12 - s2 = s2 * a.Z - h = -u1 - h = h + u2 - i = -s1 - i = i + s2 - if (branch == 2): - r = formula_secp256k1_gej_double_var(a) - return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r) - if (branch == 3): - return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity()) - i2 = i^2 - h2 = h^2 - h3 = h * h2 - rz = a.Z * h - t = u1 * h2 - rx = t - rx = rx * 2 - rx = rx + h3 - rx = -rx - rx = rx + i2 - ry = -rx - ry = ry + t - ry = ry * i - h3 = h3 * s1 - h3 = -h3 - ry = ry + h3 - return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz)) - -def formula_secp256k1_gej_add_zinv_var(branch, a, b): - """libsecp256k1's secp256k1_gej_add_zinv_var""" - bzinv = b.Z^(-1) - if branch == 0: - return (constraints(), constraints(nonzero={b.Infinity : 'b_infinite'}), a) - if branch == 1: - bzinv2 = bzinv^2 - bzinv3 = bzinv2 * bzinv - rx = b.X * bzinv2 - ry = b.Y * bzinv3 - rz = 1 - return (constraints(), constraints(zero={b.Infinity : 'b_finite'}, nonzero={a.Infinity : 'a_infinite'}), jacobianpoint(rx, ry, rz)) - azz = a.Z * bzinv - z12 = azz^2 - u1 = a.X - u2 = b.X * z12 - s1 = a.Y - s2 = b.Y * z12 - s2 = s2 * azz - h = -u1 - h = h + u2 - i = -s1 - i = i + s2 - if branch == 2: - r = formula_secp256k1_gej_double_var(a) - return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r) - if branch == 3: - return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity()) - i2 = i^2 - h2 = h^2 - h3 = h * h2 - rz = a.Z - rz = rz * h - t = u1 * h2 - rx = t - rx = rx * 2 - rx = rx + h3 - rx = -rx - rx = rx + i2 - ry = -rx - ry = ry + t - ry = ry * i - h3 = h3 * s1 - h3 = -h3 - ry = ry + h3 - return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz)) - -def formula_secp256k1_gej_add_ge(branch, a, b): - """libsecp256k1's secp256k1_gej_add_ge""" - zeroes = {} - nonzeroes = {} - a_infinity = False - if (branch & 4) != 0: - nonzeroes.update({a.Infinity : 'a_infinite'}) - a_infinity = True - else: - zeroes.update({a.Infinity : 'a_finite'}) - zz = a.Z^2 - u1 = a.X - u2 = b.X * zz - s1 = a.Y - s2 = b.Y * zz - s2 = s2 * a.Z - t = u1 - t = t + u2 - m = s1 - m = m + s2 - rr = t^2 - m_alt = -u2 - tt = u1 * m_alt - rr = rr + tt - degenerate = (branch & 3) == 3 - if (branch & 1) != 0: - zeroes.update({m : 'm_zero'}) - else: - nonzeroes.update({m : 'm_nonzero'}) - if (branch & 2) != 0: - zeroes.update({rr : 'rr_zero'}) - else: - nonzeroes.update({rr : 'rr_nonzero'}) - rr_alt = s1 - rr_alt = rr_alt * 2 - m_alt = m_alt + u1 - if not degenerate: - rr_alt = rr - m_alt = m - n = m_alt^2 - q = n * t - n = n^2 - if degenerate: - n = m - t = rr_alt^2 - rz = a.Z * m_alt - infinity = False - if (branch & 8) != 0: - if not a_infinity: - infinity = True - zeroes.update({rz : 'r.z=0'}) - else: - nonzeroes.update({rz : 'r.z!=0'}) - rz = rz * 2 - q = -q - t = t + q - rx = t - t = t * 2 - t = t + q - t = t * rr_alt - t = t + n - ry = -t - rx = rx * 4 - ry = ry * 4 - if a_infinity: - rx = b.X - ry = b.Y - rz = 1 - if infinity: - return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), point_at_infinity()) - return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), jacobianpoint(rx, ry, rz)) - -def formula_secp256k1_gej_add_ge_old(branch, a, b): - """libsecp256k1's old secp256k1_gej_add_ge, which fails when ay+by=0 but ax!=bx""" - a_infinity = (branch & 1) != 0 - zero = {} - nonzero = {} - if a_infinity: - nonzero.update({a.Infinity : 'a_infinite'}) - else: - zero.update({a.Infinity : 'a_finite'}) - zz = a.Z^2 - u1 = a.X - u2 = b.X * zz - s1 = a.Y - s2 = b.Y * zz - s2 = s2 * a.Z - z = a.Z - t = u1 - t = t + u2 - m = s1 - m = m + s2 - n = m^2 - q = n * t - n = n^2 - rr = t^2 - t = u1 * u2 - t = -t - rr = rr + t - t = rr^2 - rz = m * z - infinity = False - if (branch & 2) != 0: - if not a_infinity: - infinity = True - else: - return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(nonzero={z : 'conflict_a'}, zero={z : 'conflict_b'}), point_at_infinity()) - zero.update({rz : 'r.z=0'}) - else: - nonzero.update({rz : 'r.z!=0'}) - rz = rz * (0 if a_infinity else 2) - rx = t - q = -q - rx = rx + q - q = q * 3 - t = t * 2 - t = t + q - t = t * rr - t = t + n - ry = -t - rx = rx * (0 if a_infinity else 4) - ry = ry * (0 if a_infinity else 4) - t = b.X - t = t * (1 if a_infinity else 0) - rx = rx + t - t = b.Y - t = t * (1 if a_infinity else 0) - ry = ry + t - t = (1 if a_infinity else 0) - rz = rz + t - if infinity: - return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zero, nonzero=nonzero), point_at_infinity()) - return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zero, nonzero=nonzero), jacobianpoint(rx, ry, rz)) - -if __name__ == "__main__": - check_symbolic_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var) - check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var) - check_symbolic_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var) - check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge) - check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old) - - if len(sys.argv) >= 2 and sys.argv[1] == "--exhaustive": - check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var, 43) - check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var, 43) - check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var, 43) - check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge, 43) - check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old, 43) diff --git a/util/secp256k1/depend/secp256k1/sage/weierstrass_prover.sage b/util/secp256k1/depend/secp256k1/sage/weierstrass_prover.sage deleted file mode 100644 index 03ef2ec901..0000000000 --- a/util/secp256k1/depend/secp256k1/sage/weierstrass_prover.sage +++ /dev/null @@ -1,264 +0,0 @@ -# Prover implementation for Weierstrass curves of the form -# y^2 = x^3 + A * x + B, specifically with a = 0 and b = 7, with group laws -# operating on affine and Jacobian coordinates, including the point at infinity -# represented by a 4th variable in coordinates. - -load("group_prover.sage") - - -class affinepoint: - def __init__(self, x, y, infinity=0): - self.x = x - self.y = y - self.infinity = infinity - def __str__(self): - return "affinepoint(x=%s,y=%s,inf=%s)" % (self.x, self.y, self.infinity) - - -class jacobianpoint: - def __init__(self, x, y, z, infinity=0): - self.X = x - self.Y = y - self.Z = z - self.Infinity = infinity - def __str__(self): - return "jacobianpoint(X=%s,Y=%s,Z=%s,inf=%s)" % (self.X, self.Y, self.Z, self.Infinity) - - -def point_at_infinity(): - return jacobianpoint(1, 1, 1, 1) - - -def negate(p): - if p.__class__ == affinepoint: - return affinepoint(p.x, -p.y) - if p.__class__ == jacobianpoint: - return jacobianpoint(p.X, -p.Y, p.Z) - assert(False) - - -def on_weierstrass_curve(A, B, p): - """Return a set of zero-expressions for an affine point to be on the curve""" - return constraints(zero={p.x^3 + A*p.x + B - p.y^2: 'on_curve'}) - - -def tangential_to_weierstrass_curve(A, B, p12, p3): - """Return a set of zero-expressions for ((x12,y12),(x3,y3)) to be a line that is tangential to the curve at (x12,y12)""" - return constraints(zero={ - (p12.y - p3.y) * (p12.y * 2) - (p12.x^2 * 3 + A) * (p12.x - p3.x): 'tangential_to_curve' - }) - - -def colinear(p1, p2, p3): - """Return a set of zero-expressions for ((x1,y1),(x2,y2),(x3,y3)) to be collinear""" - return constraints(zero={ - (p1.y - p2.y) * (p1.x - p3.x) - (p1.y - p3.y) * (p1.x - p2.x): 'colinear_1', - (p2.y - p3.y) * (p2.x - p1.x) - (p2.y - p1.y) * (p2.x - p3.x): 'colinear_2', - (p3.y - p1.y) * (p3.x - p2.x) - (p3.y - p2.y) * (p3.x - p1.x): 'colinear_3' - }) - - -def good_affine_point(p): - return constraints(nonzero={p.x : 'nonzero_x', p.y : 'nonzero_y'}) - - -def good_jacobian_point(p): - return constraints(nonzero={p.X : 'nonzero_X', p.Y : 'nonzero_Y', p.Z^6 : 'nonzero_Z'}) - - -def good_point(p): - return constraints(nonzero={p.Z^6 : 'nonzero_X'}) - - -def finite(p, *affine_fns): - con = good_point(p) + constraints(zero={p.Infinity : 'finite_point'}) - if p.Z != 0: - return con + reduce(lambda a, b: a + b, (f(affinepoint(p.X / p.Z^2, p.Y / p.Z^3)) for f in affine_fns), con) - else: - return con - -def infinite(p): - return constraints(nonzero={p.Infinity : 'infinite_point'}) - - -def law_jacobian_weierstrass_add(A, B, pa, pb, pA, pB, pC): - """Check whether the passed set of coordinates is a valid Jacobian add, given assumptions""" - assumeLaw = (good_affine_point(pa) + - good_affine_point(pb) + - good_jacobian_point(pA) + - good_jacobian_point(pB) + - on_weierstrass_curve(A, B, pa) + - on_weierstrass_curve(A, B, pb) + - finite(pA) + - finite(pB) + - constraints(nonzero={pa.x - pb.x : 'different_x'})) - require = (finite(pC, lambda pc: on_weierstrass_curve(A, B, pc) + - colinear(pa, pb, negate(pc)))) - return (assumeLaw, require) - - -def law_jacobian_weierstrass_double(A, B, pa, pb, pA, pB, pC): - """Check whether the passed set of coordinates is a valid Jacobian doubling, given assumptions""" - assumeLaw = (good_affine_point(pa) + - good_affine_point(pb) + - good_jacobian_point(pA) + - good_jacobian_point(pB) + - on_weierstrass_curve(A, B, pa) + - on_weierstrass_curve(A, B, pb) + - finite(pA) + - finite(pB) + - constraints(zero={pa.x - pb.x : 'equal_x', pa.y - pb.y : 'equal_y'})) - require = (finite(pC, lambda pc: on_weierstrass_curve(A, B, pc) + - tangential_to_weierstrass_curve(A, B, pa, negate(pc)))) - return (assumeLaw, require) - - -def law_jacobian_weierstrass_add_opposites(A, B, pa, pb, pA, pB, pC): - assumeLaw = (good_affine_point(pa) + - good_affine_point(pb) + - good_jacobian_point(pA) + - good_jacobian_point(pB) + - on_weierstrass_curve(A, B, pa) + - on_weierstrass_curve(A, B, pb) + - finite(pA) + - finite(pB) + - constraints(zero={pa.x - pb.x : 'equal_x', pa.y + pb.y : 'opposite_y'})) - require = infinite(pC) - return (assumeLaw, require) - - -def law_jacobian_weierstrass_add_infinite_a(A, B, pa, pb, pA, pB, pC): - assumeLaw = (good_affine_point(pa) + - good_affine_point(pb) + - good_jacobian_point(pA) + - good_jacobian_point(pB) + - on_weierstrass_curve(A, B, pb) + - infinite(pA) + - finite(pB)) - require = finite(pC, lambda pc: constraints(zero={pc.x - pb.x : 'c.x=b.x', pc.y - pb.y : 'c.y=b.y'})) - return (assumeLaw, require) - - -def law_jacobian_weierstrass_add_infinite_b(A, B, pa, pb, pA, pB, pC): - assumeLaw = (good_affine_point(pa) + - good_affine_point(pb) + - good_jacobian_point(pA) + - good_jacobian_point(pB) + - on_weierstrass_curve(A, B, pa) + - infinite(pB) + - finite(pA)) - require = finite(pC, lambda pc: constraints(zero={pc.x - pa.x : 'c.x=a.x', pc.y - pa.y : 'c.y=a.y'})) - return (assumeLaw, require) - - -def law_jacobian_weierstrass_add_infinite_ab(A, B, pa, pb, pA, pB, pC): - assumeLaw = (good_affine_point(pa) + - good_affine_point(pb) + - good_jacobian_point(pA) + - good_jacobian_point(pB) + - infinite(pA) + - infinite(pB)) - require = infinite(pC) - return (assumeLaw, require) - - -laws_jacobian_weierstrass = { - 'add': law_jacobian_weierstrass_add, - 'double': law_jacobian_weierstrass_double, - 'add_opposite': law_jacobian_weierstrass_add_opposites, - 'add_infinite_a': law_jacobian_weierstrass_add_infinite_a, - 'add_infinite_b': law_jacobian_weierstrass_add_infinite_b, - 'add_infinite_ab': law_jacobian_weierstrass_add_infinite_ab -} - - -def check_exhaustive_jacobian_weierstrass(name, A, B, branches, formula, p): - """Verify an implementation of addition of Jacobian points on a Weierstrass curve, by executing and validating the result for every possible addition in a prime field""" - F = Integers(p) - print "Formula %s on Z%i:" % (name, p) - points = [] - for x in xrange(0, p): - for y in xrange(0, p): - point = affinepoint(F(x), F(y)) - r, e = concrete_verify(on_weierstrass_curve(A, B, point)) - if r: - points.append(point) - - for za in xrange(1, p): - for zb in xrange(1, p): - for pa in points: - for pb in points: - for ia in xrange(2): - for ib in xrange(2): - pA = jacobianpoint(pa.x * F(za)^2, pa.y * F(za)^3, F(za), ia) - pB = jacobianpoint(pb.x * F(zb)^2, pb.y * F(zb)^3, F(zb), ib) - for branch in xrange(0, branches): - assumeAssert, assumeBranch, pC = formula(branch, pA, pB) - pC.X = F(pC.X) - pC.Y = F(pC.Y) - pC.Z = F(pC.Z) - pC.Infinity = F(pC.Infinity) - r, e = concrete_verify(assumeAssert + assumeBranch) - if r: - match = False - for key in laws_jacobian_weierstrass: - assumeLaw, require = laws_jacobian_weierstrass[key](A, B, pa, pb, pA, pB, pC) - r, e = concrete_verify(assumeLaw) - if r: - if match: - print " multiple branches for (%s,%s,%s,%s) + (%s,%s,%s,%s)" % (pA.X, pA.Y, pA.Z, pA.Infinity, pB.X, pB.Y, pB.Z, pB.Infinity) - else: - match = True - r, e = concrete_verify(require) - if not r: - print " failure in branch %i for (%s,%s,%s,%s) + (%s,%s,%s,%s) = (%s,%s,%s,%s): %s" % (branch, pA.X, pA.Y, pA.Z, pA.Infinity, pB.X, pB.Y, pB.Z, pB.Infinity, pC.X, pC.Y, pC.Z, pC.Infinity, e) - print - - -def check_symbolic_function(R, assumeAssert, assumeBranch, f, A, B, pa, pb, pA, pB, pC): - assumeLaw, require = f(A, B, pa, pb, pA, pB, pC) - return check_symbolic(R, assumeLaw, assumeAssert, assumeBranch, require) - -def check_symbolic_jacobian_weierstrass(name, A, B, branches, formula): - """Verify an implementation of addition of Jacobian points on a Weierstrass curve symbolically""" - R. = PolynomialRing(QQ,8,order='invlex') - lift = lambda x: fastfrac(R,x) - ax = lift(ax) - ay = lift(ay) - Az = lift(Az) - bx = lift(bx) - by = lift(by) - Bz = lift(Bz) - Ai = lift(Ai) - Bi = lift(Bi) - - pa = affinepoint(ax, ay, Ai) - pb = affinepoint(bx, by, Bi) - pA = jacobianpoint(ax * Az^2, ay * Az^3, Az, Ai) - pB = jacobianpoint(bx * Bz^2, by * Bz^3, Bz, Bi) - - res = {} - - for key in laws_jacobian_weierstrass: - res[key] = [] - - print ("Formula " + name + ":") - count = 0 - for branch in xrange(branches): - assumeFormula, assumeBranch, pC = formula(branch, pA, pB) - pC.X = lift(pC.X) - pC.Y = lift(pC.Y) - pC.Z = lift(pC.Z) - pC.Infinity = lift(pC.Infinity) - - for key in laws_jacobian_weierstrass: - res[key].append((check_symbolic_function(R, assumeFormula, assumeBranch, laws_jacobian_weierstrass[key], A, B, pa, pb, pA, pB, pC), branch)) - - for key in res: - print " %s:" % key - val = res[key] - for x in val: - if x[0] is not None: - print " branch %i: %s" % (x[1], x[0]) - - print diff --git a/util/secp256k1/depend/secp256k1/src/asm/field_10x26_arm.s b/util/secp256k1/depend/secp256k1/src/asm/field_10x26_arm.s deleted file mode 100644 index 5a9cc3ffcf..0000000000 --- a/util/secp256k1/depend/secp256k1/src/asm/field_10x26_arm.s +++ /dev/null @@ -1,919 +0,0 @@ -@ vim: set tabstop=8 softtabstop=8 shiftwidth=8 noexpandtab syntax=armasm: -/********************************************************************** - * Copyright (c) 2014 Wladimir J. van der Laan * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ -/* -ARM implementation of field_10x26 inner loops. - -Note: - -- To avoid unnecessary loads and make use of available registers, two - 'passes' have every time been interleaved, with the odd passes accumulating c' and d' - which will be added to c and d respectively in the even passes - -*/ - - .syntax unified - .arch armv7-a - @ eabi attributes - see readelf -A - .eabi_attribute 8, 1 @ Tag_ARM_ISA_use = yes - .eabi_attribute 9, 0 @ Tag_Thumb_ISA_use = no - .eabi_attribute 10, 0 @ Tag_FP_arch = none - .eabi_attribute 24, 1 @ Tag_ABI_align_needed = 8-byte - .eabi_attribute 25, 1 @ Tag_ABI_align_preserved = 8-byte, except leaf SP - .eabi_attribute 30, 2 @ Tag_ABI_optimization_goals = Aggressive Speed - .eabi_attribute 34, 1 @ Tag_CPU_unaligned_access = v6 - .text - - @ Field constants - .set field_R0, 0x3d10 - .set field_R1, 0x400 - .set field_not_M, 0xfc000000 @ ~M = ~0x3ffffff - - .align 2 - .global secp256k1_fe_mul_inner - .type secp256k1_fe_mul_inner, %function - @ Arguments: - @ r0 r Restrict: can overlap with a, not with b - @ r1 a - @ r2 b - @ Stack (total 4+10*4 = 44) - @ sp + #0 saved 'r' pointer - @ sp + #4 + 4*X t0,t1,t2,t3,t4,t5,t6,t7,u8,t9 -secp256k1_fe_mul_inner: - stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r14} - sub sp, sp, #48 @ frame=44 + alignment - str r0, [sp, #0] @ save result address, we need it only at the end - - /****************************************** - * Main computation code. - ****************************************** - - Allocation: - r0,r14,r7,r8 scratch - r1 a (pointer) - r2 b (pointer) - r3:r4 c - r5:r6 d - r11:r12 c' - r9:r10 d' - - Note: do not write to r[] here, it may overlap with a[] - */ - - /* A - interleaved with B */ - ldr r7, [r1, #0*4] @ a[0] - ldr r8, [r2, #9*4] @ b[9] - ldr r0, [r1, #1*4] @ a[1] - umull r5, r6, r7, r8 @ d = a[0] * b[9] - ldr r14, [r2, #8*4] @ b[8] - umull r9, r10, r0, r8 @ d' = a[1] * b[9] - ldr r7, [r1, #2*4] @ a[2] - umlal r5, r6, r0, r14 @ d += a[1] * b[8] - ldr r8, [r2, #7*4] @ b[7] - umlal r9, r10, r7, r14 @ d' += a[2] * b[8] - ldr r0, [r1, #3*4] @ a[3] - umlal r5, r6, r7, r8 @ d += a[2] * b[7] - ldr r14, [r2, #6*4] @ b[6] - umlal r9, r10, r0, r8 @ d' += a[3] * b[7] - ldr r7, [r1, #4*4] @ a[4] - umlal r5, r6, r0, r14 @ d += a[3] * b[6] - ldr r8, [r2, #5*4] @ b[5] - umlal r9, r10, r7, r14 @ d' += a[4] * b[6] - ldr r0, [r1, #5*4] @ a[5] - umlal r5, r6, r7, r8 @ d += a[4] * b[5] - ldr r14, [r2, #4*4] @ b[4] - umlal r9, r10, r0, r8 @ d' += a[5] * b[5] - ldr r7, [r1, #6*4] @ a[6] - umlal r5, r6, r0, r14 @ d += a[5] * b[4] - ldr r8, [r2, #3*4] @ b[3] - umlal r9, r10, r7, r14 @ d' += a[6] * b[4] - ldr r0, [r1, #7*4] @ a[7] - umlal r5, r6, r7, r8 @ d += a[6] * b[3] - ldr r14, [r2, #2*4] @ b[2] - umlal r9, r10, r0, r8 @ d' += a[7] * b[3] - ldr r7, [r1, #8*4] @ a[8] - umlal r5, r6, r0, r14 @ d += a[7] * b[2] - ldr r8, [r2, #1*4] @ b[1] - umlal r9, r10, r7, r14 @ d' += a[8] * b[2] - ldr r0, [r1, #9*4] @ a[9] - umlal r5, r6, r7, r8 @ d += a[8] * b[1] - ldr r14, [r2, #0*4] @ b[0] - umlal r9, r10, r0, r8 @ d' += a[9] * b[1] - ldr r7, [r1, #0*4] @ a[0] - umlal r5, r6, r0, r14 @ d += a[9] * b[0] - @ r7,r14 used in B - - bic r0, r5, field_not_M @ t9 = d & M - str r0, [sp, #4 + 4*9] - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - - /* B */ - umull r3, r4, r7, r14 @ c = a[0] * b[0] - adds r5, r5, r9 @ d += d' - adc r6, r6, r10 - - bic r0, r5, field_not_M @ u0 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u0 * R0 - umlal r3, r4, r0, r14 - - bic r14, r3, field_not_M @ t0 = c & M - str r14, [sp, #4 + 0*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u0 * R1 - umlal r3, r4, r0, r14 - - /* C - interleaved with D */ - ldr r7, [r1, #0*4] @ a[0] - ldr r8, [r2, #2*4] @ b[2] - ldr r14, [r2, #1*4] @ b[1] - umull r11, r12, r7, r8 @ c' = a[0] * b[2] - ldr r0, [r1, #1*4] @ a[1] - umlal r3, r4, r7, r14 @ c += a[0] * b[1] - ldr r8, [r2, #0*4] @ b[0] - umlal r11, r12, r0, r14 @ c' += a[1] * b[1] - ldr r7, [r1, #2*4] @ a[2] - umlal r3, r4, r0, r8 @ c += a[1] * b[0] - ldr r14, [r2, #9*4] @ b[9] - umlal r11, r12, r7, r8 @ c' += a[2] * b[0] - ldr r0, [r1, #3*4] @ a[3] - umlal r5, r6, r7, r14 @ d += a[2] * b[9] - ldr r8, [r2, #8*4] @ b[8] - umull r9, r10, r0, r14 @ d' = a[3] * b[9] - ldr r7, [r1, #4*4] @ a[4] - umlal r5, r6, r0, r8 @ d += a[3] * b[8] - ldr r14, [r2, #7*4] @ b[7] - umlal r9, r10, r7, r8 @ d' += a[4] * b[8] - ldr r0, [r1, #5*4] @ a[5] - umlal r5, r6, r7, r14 @ d += a[4] * b[7] - ldr r8, [r2, #6*4] @ b[6] - umlal r9, r10, r0, r14 @ d' += a[5] * b[7] - ldr r7, [r1, #6*4] @ a[6] - umlal r5, r6, r0, r8 @ d += a[5] * b[6] - ldr r14, [r2, #5*4] @ b[5] - umlal r9, r10, r7, r8 @ d' += a[6] * b[6] - ldr r0, [r1, #7*4] @ a[7] - umlal r5, r6, r7, r14 @ d += a[6] * b[5] - ldr r8, [r2, #4*4] @ b[4] - umlal r9, r10, r0, r14 @ d' += a[7] * b[5] - ldr r7, [r1, #8*4] @ a[8] - umlal r5, r6, r0, r8 @ d += a[7] * b[4] - ldr r14, [r2, #3*4] @ b[3] - umlal r9, r10, r7, r8 @ d' += a[8] * b[4] - ldr r0, [r1, #9*4] @ a[9] - umlal r5, r6, r7, r14 @ d += a[8] * b[3] - ldr r8, [r2, #2*4] @ b[2] - umlal r9, r10, r0, r14 @ d' += a[9] * b[3] - umlal r5, r6, r0, r8 @ d += a[9] * b[2] - - bic r0, r5, field_not_M @ u1 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u1 * R0 - umlal r3, r4, r0, r14 - - bic r14, r3, field_not_M @ t1 = c & M - str r14, [sp, #4 + 1*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u1 * R1 - umlal r3, r4, r0, r14 - - /* D */ - adds r3, r3, r11 @ c += c' - adc r4, r4, r12 - adds r5, r5, r9 @ d += d' - adc r6, r6, r10 - - bic r0, r5, field_not_M @ u2 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u2 * R0 - umlal r3, r4, r0, r14 - - bic r14, r3, field_not_M @ t2 = c & M - str r14, [sp, #4 + 2*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u2 * R1 - umlal r3, r4, r0, r14 - - /* E - interleaved with F */ - ldr r7, [r1, #0*4] @ a[0] - ldr r8, [r2, #4*4] @ b[4] - umull r11, r12, r7, r8 @ c' = a[0] * b[4] - ldr r8, [r2, #3*4] @ b[3] - umlal r3, r4, r7, r8 @ c += a[0] * b[3] - ldr r7, [r1, #1*4] @ a[1] - umlal r11, r12, r7, r8 @ c' += a[1] * b[3] - ldr r8, [r2, #2*4] @ b[2] - umlal r3, r4, r7, r8 @ c += a[1] * b[2] - ldr r7, [r1, #2*4] @ a[2] - umlal r11, r12, r7, r8 @ c' += a[2] * b[2] - ldr r8, [r2, #1*4] @ b[1] - umlal r3, r4, r7, r8 @ c += a[2] * b[1] - ldr r7, [r1, #3*4] @ a[3] - umlal r11, r12, r7, r8 @ c' += a[3] * b[1] - ldr r8, [r2, #0*4] @ b[0] - umlal r3, r4, r7, r8 @ c += a[3] * b[0] - ldr r7, [r1, #4*4] @ a[4] - umlal r11, r12, r7, r8 @ c' += a[4] * b[0] - ldr r8, [r2, #9*4] @ b[9] - umlal r5, r6, r7, r8 @ d += a[4] * b[9] - ldr r7, [r1, #5*4] @ a[5] - umull r9, r10, r7, r8 @ d' = a[5] * b[9] - ldr r8, [r2, #8*4] @ b[8] - umlal r5, r6, r7, r8 @ d += a[5] * b[8] - ldr r7, [r1, #6*4] @ a[6] - umlal r9, r10, r7, r8 @ d' += a[6] * b[8] - ldr r8, [r2, #7*4] @ b[7] - umlal r5, r6, r7, r8 @ d += a[6] * b[7] - ldr r7, [r1, #7*4] @ a[7] - umlal r9, r10, r7, r8 @ d' += a[7] * b[7] - ldr r8, [r2, #6*4] @ b[6] - umlal r5, r6, r7, r8 @ d += a[7] * b[6] - ldr r7, [r1, #8*4] @ a[8] - umlal r9, r10, r7, r8 @ d' += a[8] * b[6] - ldr r8, [r2, #5*4] @ b[5] - umlal r5, r6, r7, r8 @ d += a[8] * b[5] - ldr r7, [r1, #9*4] @ a[9] - umlal r9, r10, r7, r8 @ d' += a[9] * b[5] - ldr r8, [r2, #4*4] @ b[4] - umlal r5, r6, r7, r8 @ d += a[9] * b[4] - - bic r0, r5, field_not_M @ u3 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u3 * R0 - umlal r3, r4, r0, r14 - - bic r14, r3, field_not_M @ t3 = c & M - str r14, [sp, #4 + 3*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u3 * R1 - umlal r3, r4, r0, r14 - - /* F */ - adds r3, r3, r11 @ c += c' - adc r4, r4, r12 - adds r5, r5, r9 @ d += d' - adc r6, r6, r10 - - bic r0, r5, field_not_M @ u4 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u4 * R0 - umlal r3, r4, r0, r14 - - bic r14, r3, field_not_M @ t4 = c & M - str r14, [sp, #4 + 4*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u4 * R1 - umlal r3, r4, r0, r14 - - /* G - interleaved with H */ - ldr r7, [r1, #0*4] @ a[0] - ldr r8, [r2, #6*4] @ b[6] - ldr r14, [r2, #5*4] @ b[5] - umull r11, r12, r7, r8 @ c' = a[0] * b[6] - ldr r0, [r1, #1*4] @ a[1] - umlal r3, r4, r7, r14 @ c += a[0] * b[5] - ldr r8, [r2, #4*4] @ b[4] - umlal r11, r12, r0, r14 @ c' += a[1] * b[5] - ldr r7, [r1, #2*4] @ a[2] - umlal r3, r4, r0, r8 @ c += a[1] * b[4] - ldr r14, [r2, #3*4] @ b[3] - umlal r11, r12, r7, r8 @ c' += a[2] * b[4] - ldr r0, [r1, #3*4] @ a[3] - umlal r3, r4, r7, r14 @ c += a[2] * b[3] - ldr r8, [r2, #2*4] @ b[2] - umlal r11, r12, r0, r14 @ c' += a[3] * b[3] - ldr r7, [r1, #4*4] @ a[4] - umlal r3, r4, r0, r8 @ c += a[3] * b[2] - ldr r14, [r2, #1*4] @ b[1] - umlal r11, r12, r7, r8 @ c' += a[4] * b[2] - ldr r0, [r1, #5*4] @ a[5] - umlal r3, r4, r7, r14 @ c += a[4] * b[1] - ldr r8, [r2, #0*4] @ b[0] - umlal r11, r12, r0, r14 @ c' += a[5] * b[1] - ldr r7, [r1, #6*4] @ a[6] - umlal r3, r4, r0, r8 @ c += a[5] * b[0] - ldr r14, [r2, #9*4] @ b[9] - umlal r11, r12, r7, r8 @ c' += a[6] * b[0] - ldr r0, [r1, #7*4] @ a[7] - umlal r5, r6, r7, r14 @ d += a[6] * b[9] - ldr r8, [r2, #8*4] @ b[8] - umull r9, r10, r0, r14 @ d' = a[7] * b[9] - ldr r7, [r1, #8*4] @ a[8] - umlal r5, r6, r0, r8 @ d += a[7] * b[8] - ldr r14, [r2, #7*4] @ b[7] - umlal r9, r10, r7, r8 @ d' += a[8] * b[8] - ldr r0, [r1, #9*4] @ a[9] - umlal r5, r6, r7, r14 @ d += a[8] * b[7] - ldr r8, [r2, #6*4] @ b[6] - umlal r9, r10, r0, r14 @ d' += a[9] * b[7] - umlal r5, r6, r0, r8 @ d += a[9] * b[6] - - bic r0, r5, field_not_M @ u5 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u5 * R0 - umlal r3, r4, r0, r14 - - bic r14, r3, field_not_M @ t5 = c & M - str r14, [sp, #4 + 5*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u5 * R1 - umlal r3, r4, r0, r14 - - /* H */ - adds r3, r3, r11 @ c += c' - adc r4, r4, r12 - adds r5, r5, r9 @ d += d' - adc r6, r6, r10 - - bic r0, r5, field_not_M @ u6 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u6 * R0 - umlal r3, r4, r0, r14 - - bic r14, r3, field_not_M @ t6 = c & M - str r14, [sp, #4 + 6*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u6 * R1 - umlal r3, r4, r0, r14 - - /* I - interleaved with J */ - ldr r8, [r2, #8*4] @ b[8] - ldr r7, [r1, #0*4] @ a[0] - ldr r14, [r2, #7*4] @ b[7] - umull r11, r12, r7, r8 @ c' = a[0] * b[8] - ldr r0, [r1, #1*4] @ a[1] - umlal r3, r4, r7, r14 @ c += a[0] * b[7] - ldr r8, [r2, #6*4] @ b[6] - umlal r11, r12, r0, r14 @ c' += a[1] * b[7] - ldr r7, [r1, #2*4] @ a[2] - umlal r3, r4, r0, r8 @ c += a[1] * b[6] - ldr r14, [r2, #5*4] @ b[5] - umlal r11, r12, r7, r8 @ c' += a[2] * b[6] - ldr r0, [r1, #3*4] @ a[3] - umlal r3, r4, r7, r14 @ c += a[2] * b[5] - ldr r8, [r2, #4*4] @ b[4] - umlal r11, r12, r0, r14 @ c' += a[3] * b[5] - ldr r7, [r1, #4*4] @ a[4] - umlal r3, r4, r0, r8 @ c += a[3] * b[4] - ldr r14, [r2, #3*4] @ b[3] - umlal r11, r12, r7, r8 @ c' += a[4] * b[4] - ldr r0, [r1, #5*4] @ a[5] - umlal r3, r4, r7, r14 @ c += a[4] * b[3] - ldr r8, [r2, #2*4] @ b[2] - umlal r11, r12, r0, r14 @ c' += a[5] * b[3] - ldr r7, [r1, #6*4] @ a[6] - umlal r3, r4, r0, r8 @ c += a[5] * b[2] - ldr r14, [r2, #1*4] @ b[1] - umlal r11, r12, r7, r8 @ c' += a[6] * b[2] - ldr r0, [r1, #7*4] @ a[7] - umlal r3, r4, r7, r14 @ c += a[6] * b[1] - ldr r8, [r2, #0*4] @ b[0] - umlal r11, r12, r0, r14 @ c' += a[7] * b[1] - ldr r7, [r1, #8*4] @ a[8] - umlal r3, r4, r0, r8 @ c += a[7] * b[0] - ldr r14, [r2, #9*4] @ b[9] - umlal r11, r12, r7, r8 @ c' += a[8] * b[0] - ldr r0, [r1, #9*4] @ a[9] - umlal r5, r6, r7, r14 @ d += a[8] * b[9] - ldr r8, [r2, #8*4] @ b[8] - umull r9, r10, r0, r14 @ d' = a[9] * b[9] - umlal r5, r6, r0, r8 @ d += a[9] * b[8] - - bic r0, r5, field_not_M @ u7 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u7 * R0 - umlal r3, r4, r0, r14 - - bic r14, r3, field_not_M @ t7 = c & M - str r14, [sp, #4 + 7*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u7 * R1 - umlal r3, r4, r0, r14 - - /* J */ - adds r3, r3, r11 @ c += c' - adc r4, r4, r12 - adds r5, r5, r9 @ d += d' - adc r6, r6, r10 - - bic r0, r5, field_not_M @ u8 = d & M - str r0, [sp, #4 + 8*4] - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u8 * R0 - umlal r3, r4, r0, r14 - - /****************************************** - * compute and write back result - ****************************************** - Allocation: - r0 r - r3:r4 c - r5:r6 d - r7 t0 - r8 t1 - r9 t2 - r11 u8 - r12 t9 - r1,r2,r10,r14 scratch - - Note: do not read from a[] after here, it may overlap with r[] - */ - ldr r0, [sp, #0] - add r1, sp, #4 + 3*4 @ r[3..7] = t3..7, r11=u8, r12=t9 - ldmia r1, {r2,r7,r8,r9,r10,r11,r12} - add r1, r0, #3*4 - stmia r1, {r2,r7,r8,r9,r10} - - bic r2, r3, field_not_M @ r[8] = c & M - str r2, [r0, #8*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u8 * R1 - umlal r3, r4, r11, r14 - movw r14, field_R0 @ c += d * R0 - umlal r3, r4, r5, r14 - adds r3, r3, r12 @ c += t9 - adc r4, r4, #0 - - add r1, sp, #4 + 0*4 @ r7,r8,r9 = t0,t1,t2 - ldmia r1, {r7,r8,r9} - - ubfx r2, r3, #0, #22 @ r[9] = c & (M >> 4) - str r2, [r0, #9*4] - mov r3, r3, lsr #22 @ c >>= 22 - orr r3, r3, r4, asl #10 - mov r4, r4, lsr #22 - movw r14, field_R1 << 4 @ c += d * (R1 << 4) - umlal r3, r4, r5, r14 - - movw r14, field_R0 >> 4 @ d = c * (R0 >> 4) + t0 (64x64 multiply+add) - umull r5, r6, r3, r14 @ d = c.lo * (R0 >> 4) - adds r5, r5, r7 @ d.lo += t0 - mla r6, r14, r4, r6 @ d.hi += c.hi * (R0 >> 4) - adc r6, r6, 0 @ d.hi += carry - - bic r2, r5, field_not_M @ r[0] = d & M - str r2, [r0, #0*4] - - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - - movw r14, field_R1 >> 4 @ d += c * (R1 >> 4) + t1 (64x64 multiply+add) - umull r1, r2, r3, r14 @ tmp = c.lo * (R1 >> 4) - adds r5, r5, r8 @ d.lo += t1 - adc r6, r6, #0 @ d.hi += carry - adds r5, r5, r1 @ d.lo += tmp.lo - mla r2, r14, r4, r2 @ tmp.hi += c.hi * (R1 >> 4) - adc r6, r6, r2 @ d.hi += carry + tmp.hi - - bic r2, r5, field_not_M @ r[1] = d & M - str r2, [r0, #1*4] - mov r5, r5, lsr #26 @ d >>= 26 (ignore hi) - orr r5, r5, r6, asl #6 - - add r5, r5, r9 @ d += t2 - str r5, [r0, #2*4] @ r[2] = d - - add sp, sp, #48 - ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc} - .size secp256k1_fe_mul_inner, .-secp256k1_fe_mul_inner - - .align 2 - .global secp256k1_fe_sqr_inner - .type secp256k1_fe_sqr_inner, %function - @ Arguments: - @ r0 r Can overlap with a - @ r1 a - @ Stack (total 4+10*4 = 44) - @ sp + #0 saved 'r' pointer - @ sp + #4 + 4*X t0,t1,t2,t3,t4,t5,t6,t7,u8,t9 -secp256k1_fe_sqr_inner: - stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r14} - sub sp, sp, #48 @ frame=44 + alignment - str r0, [sp, #0] @ save result address, we need it only at the end - /****************************************** - * Main computation code. - ****************************************** - - Allocation: - r0,r14,r2,r7,r8 scratch - r1 a (pointer) - r3:r4 c - r5:r6 d - r11:r12 c' - r9:r10 d' - - Note: do not write to r[] here, it may overlap with a[] - */ - /* A interleaved with B */ - ldr r0, [r1, #1*4] @ a[1]*2 - ldr r7, [r1, #0*4] @ a[0] - mov r0, r0, asl #1 - ldr r14, [r1, #9*4] @ a[9] - umull r3, r4, r7, r7 @ c = a[0] * a[0] - ldr r8, [r1, #8*4] @ a[8] - mov r7, r7, asl #1 - umull r5, r6, r7, r14 @ d = a[0]*2 * a[9] - ldr r7, [r1, #2*4] @ a[2]*2 - umull r9, r10, r0, r14 @ d' = a[1]*2 * a[9] - ldr r14, [r1, #7*4] @ a[7] - umlal r5, r6, r0, r8 @ d += a[1]*2 * a[8] - mov r7, r7, asl #1 - ldr r0, [r1, #3*4] @ a[3]*2 - umlal r9, r10, r7, r8 @ d' += a[2]*2 * a[8] - ldr r8, [r1, #6*4] @ a[6] - umlal r5, r6, r7, r14 @ d += a[2]*2 * a[7] - mov r0, r0, asl #1 - ldr r7, [r1, #4*4] @ a[4]*2 - umlal r9, r10, r0, r14 @ d' += a[3]*2 * a[7] - ldr r14, [r1, #5*4] @ a[5] - mov r7, r7, asl #1 - umlal r5, r6, r0, r8 @ d += a[3]*2 * a[6] - umlal r9, r10, r7, r8 @ d' += a[4]*2 * a[6] - umlal r5, r6, r7, r14 @ d += a[4]*2 * a[5] - umlal r9, r10, r14, r14 @ d' += a[5] * a[5] - - bic r0, r5, field_not_M @ t9 = d & M - str r0, [sp, #4 + 9*4] - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - - /* B */ - adds r5, r5, r9 @ d += d' - adc r6, r6, r10 - - bic r0, r5, field_not_M @ u0 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u0 * R0 - umlal r3, r4, r0, r14 - bic r14, r3, field_not_M @ t0 = c & M - str r14, [sp, #4 + 0*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u0 * R1 - umlal r3, r4, r0, r14 - - /* C interleaved with D */ - ldr r0, [r1, #0*4] @ a[0]*2 - ldr r14, [r1, #1*4] @ a[1] - mov r0, r0, asl #1 - ldr r8, [r1, #2*4] @ a[2] - umlal r3, r4, r0, r14 @ c += a[0]*2 * a[1] - mov r7, r8, asl #1 @ a[2]*2 - umull r11, r12, r14, r14 @ c' = a[1] * a[1] - ldr r14, [r1, #9*4] @ a[9] - umlal r11, r12, r0, r8 @ c' += a[0]*2 * a[2] - ldr r0, [r1, #3*4] @ a[3]*2 - ldr r8, [r1, #8*4] @ a[8] - umlal r5, r6, r7, r14 @ d += a[2]*2 * a[9] - mov r0, r0, asl #1 - ldr r7, [r1, #4*4] @ a[4]*2 - umull r9, r10, r0, r14 @ d' = a[3]*2 * a[9] - ldr r14, [r1, #7*4] @ a[7] - umlal r5, r6, r0, r8 @ d += a[3]*2 * a[8] - mov r7, r7, asl #1 - ldr r0, [r1, #5*4] @ a[5]*2 - umlal r9, r10, r7, r8 @ d' += a[4]*2 * a[8] - ldr r8, [r1, #6*4] @ a[6] - mov r0, r0, asl #1 - umlal r5, r6, r7, r14 @ d += a[4]*2 * a[7] - umlal r9, r10, r0, r14 @ d' += a[5]*2 * a[7] - umlal r5, r6, r0, r8 @ d += a[5]*2 * a[6] - umlal r9, r10, r8, r8 @ d' += a[6] * a[6] - - bic r0, r5, field_not_M @ u1 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u1 * R0 - umlal r3, r4, r0, r14 - bic r14, r3, field_not_M @ t1 = c & M - str r14, [sp, #4 + 1*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u1 * R1 - umlal r3, r4, r0, r14 - - /* D */ - adds r3, r3, r11 @ c += c' - adc r4, r4, r12 - adds r5, r5, r9 @ d += d' - adc r6, r6, r10 - - bic r0, r5, field_not_M @ u2 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u2 * R0 - umlal r3, r4, r0, r14 - bic r14, r3, field_not_M @ t2 = c & M - str r14, [sp, #4 + 2*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u2 * R1 - umlal r3, r4, r0, r14 - - /* E interleaved with F */ - ldr r7, [r1, #0*4] @ a[0]*2 - ldr r0, [r1, #1*4] @ a[1]*2 - ldr r14, [r1, #2*4] @ a[2] - mov r7, r7, asl #1 - ldr r8, [r1, #3*4] @ a[3] - ldr r2, [r1, #4*4] - umlal r3, r4, r7, r8 @ c += a[0]*2 * a[3] - mov r0, r0, asl #1 - umull r11, r12, r7, r2 @ c' = a[0]*2 * a[4] - mov r2, r2, asl #1 @ a[4]*2 - umlal r11, r12, r0, r8 @ c' += a[1]*2 * a[3] - ldr r8, [r1, #9*4] @ a[9] - umlal r3, r4, r0, r14 @ c += a[1]*2 * a[2] - ldr r0, [r1, #5*4] @ a[5]*2 - umlal r11, r12, r14, r14 @ c' += a[2] * a[2] - ldr r14, [r1, #8*4] @ a[8] - mov r0, r0, asl #1 - umlal r5, r6, r2, r8 @ d += a[4]*2 * a[9] - ldr r7, [r1, #6*4] @ a[6]*2 - umull r9, r10, r0, r8 @ d' = a[5]*2 * a[9] - mov r7, r7, asl #1 - ldr r8, [r1, #7*4] @ a[7] - umlal r5, r6, r0, r14 @ d += a[5]*2 * a[8] - umlal r9, r10, r7, r14 @ d' += a[6]*2 * a[8] - umlal r5, r6, r7, r8 @ d += a[6]*2 * a[7] - umlal r9, r10, r8, r8 @ d' += a[7] * a[7] - - bic r0, r5, field_not_M @ u3 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u3 * R0 - umlal r3, r4, r0, r14 - bic r14, r3, field_not_M @ t3 = c & M - str r14, [sp, #4 + 3*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u3 * R1 - umlal r3, r4, r0, r14 - - /* F */ - adds r3, r3, r11 @ c += c' - adc r4, r4, r12 - adds r5, r5, r9 @ d += d' - adc r6, r6, r10 - - bic r0, r5, field_not_M @ u4 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u4 * R0 - umlal r3, r4, r0, r14 - bic r14, r3, field_not_M @ t4 = c & M - str r14, [sp, #4 + 4*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u4 * R1 - umlal r3, r4, r0, r14 - - /* G interleaved with H */ - ldr r7, [r1, #0*4] @ a[0]*2 - ldr r0, [r1, #1*4] @ a[1]*2 - mov r7, r7, asl #1 - ldr r8, [r1, #5*4] @ a[5] - ldr r2, [r1, #6*4] @ a[6] - umlal r3, r4, r7, r8 @ c += a[0]*2 * a[5] - ldr r14, [r1, #4*4] @ a[4] - mov r0, r0, asl #1 - umull r11, r12, r7, r2 @ c' = a[0]*2 * a[6] - ldr r7, [r1, #2*4] @ a[2]*2 - umlal r11, r12, r0, r8 @ c' += a[1]*2 * a[5] - mov r7, r7, asl #1 - ldr r8, [r1, #3*4] @ a[3] - umlal r3, r4, r0, r14 @ c += a[1]*2 * a[4] - mov r0, r2, asl #1 @ a[6]*2 - umlal r11, r12, r7, r14 @ c' += a[2]*2 * a[4] - ldr r14, [r1, #9*4] @ a[9] - umlal r3, r4, r7, r8 @ c += a[2]*2 * a[3] - ldr r7, [r1, #7*4] @ a[7]*2 - umlal r11, r12, r8, r8 @ c' += a[3] * a[3] - mov r7, r7, asl #1 - ldr r8, [r1, #8*4] @ a[8] - umlal r5, r6, r0, r14 @ d += a[6]*2 * a[9] - umull r9, r10, r7, r14 @ d' = a[7]*2 * a[9] - umlal r5, r6, r7, r8 @ d += a[7]*2 * a[8] - umlal r9, r10, r8, r8 @ d' += a[8] * a[8] - - bic r0, r5, field_not_M @ u5 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u5 * R0 - umlal r3, r4, r0, r14 - bic r14, r3, field_not_M @ t5 = c & M - str r14, [sp, #4 + 5*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u5 * R1 - umlal r3, r4, r0, r14 - - /* H */ - adds r3, r3, r11 @ c += c' - adc r4, r4, r12 - adds r5, r5, r9 @ d += d' - adc r6, r6, r10 - - bic r0, r5, field_not_M @ u6 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u6 * R0 - umlal r3, r4, r0, r14 - bic r14, r3, field_not_M @ t6 = c & M - str r14, [sp, #4 + 6*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u6 * R1 - umlal r3, r4, r0, r14 - - /* I interleaved with J */ - ldr r7, [r1, #0*4] @ a[0]*2 - ldr r0, [r1, #1*4] @ a[1]*2 - mov r7, r7, asl #1 - ldr r8, [r1, #7*4] @ a[7] - ldr r2, [r1, #8*4] @ a[8] - umlal r3, r4, r7, r8 @ c += a[0]*2 * a[7] - ldr r14, [r1, #6*4] @ a[6] - mov r0, r0, asl #1 - umull r11, r12, r7, r2 @ c' = a[0]*2 * a[8] - ldr r7, [r1, #2*4] @ a[2]*2 - umlal r11, r12, r0, r8 @ c' += a[1]*2 * a[7] - ldr r8, [r1, #5*4] @ a[5] - umlal r3, r4, r0, r14 @ c += a[1]*2 * a[6] - ldr r0, [r1, #3*4] @ a[3]*2 - mov r7, r7, asl #1 - umlal r11, r12, r7, r14 @ c' += a[2]*2 * a[6] - ldr r14, [r1, #4*4] @ a[4] - mov r0, r0, asl #1 - umlal r3, r4, r7, r8 @ c += a[2]*2 * a[5] - mov r2, r2, asl #1 @ a[8]*2 - umlal r11, r12, r0, r8 @ c' += a[3]*2 * a[5] - umlal r3, r4, r0, r14 @ c += a[3]*2 * a[4] - umlal r11, r12, r14, r14 @ c' += a[4] * a[4] - ldr r8, [r1, #9*4] @ a[9] - umlal r5, r6, r2, r8 @ d += a[8]*2 * a[9] - @ r8 will be used in J - - bic r0, r5, field_not_M @ u7 = d & M - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u7 * R0 - umlal r3, r4, r0, r14 - bic r14, r3, field_not_M @ t7 = c & M - str r14, [sp, #4 + 7*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u7 * R1 - umlal r3, r4, r0, r14 - - /* J */ - adds r3, r3, r11 @ c += c' - adc r4, r4, r12 - umlal r5, r6, r8, r8 @ d += a[9] * a[9] - - bic r0, r5, field_not_M @ u8 = d & M - str r0, [sp, #4 + 8*4] - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - movw r14, field_R0 @ c += u8 * R0 - umlal r3, r4, r0, r14 - - /****************************************** - * compute and write back result - ****************************************** - Allocation: - r0 r - r3:r4 c - r5:r6 d - r7 t0 - r8 t1 - r9 t2 - r11 u8 - r12 t9 - r1,r2,r10,r14 scratch - - Note: do not read from a[] after here, it may overlap with r[] - */ - ldr r0, [sp, #0] - add r1, sp, #4 + 3*4 @ r[3..7] = t3..7, r11=u8, r12=t9 - ldmia r1, {r2,r7,r8,r9,r10,r11,r12} - add r1, r0, #3*4 - stmia r1, {r2,r7,r8,r9,r10} - - bic r2, r3, field_not_M @ r[8] = c & M - str r2, [r0, #8*4] - mov r3, r3, lsr #26 @ c >>= 26 - orr r3, r3, r4, asl #6 - mov r4, r4, lsr #26 - mov r14, field_R1 @ c += u8 * R1 - umlal r3, r4, r11, r14 - movw r14, field_R0 @ c += d * R0 - umlal r3, r4, r5, r14 - adds r3, r3, r12 @ c += t9 - adc r4, r4, #0 - - add r1, sp, #4 + 0*4 @ r7,r8,r9 = t0,t1,t2 - ldmia r1, {r7,r8,r9} - - ubfx r2, r3, #0, #22 @ r[9] = c & (M >> 4) - str r2, [r0, #9*4] - mov r3, r3, lsr #22 @ c >>= 22 - orr r3, r3, r4, asl #10 - mov r4, r4, lsr #22 - movw r14, field_R1 << 4 @ c += d * (R1 << 4) - umlal r3, r4, r5, r14 - - movw r14, field_R0 >> 4 @ d = c * (R0 >> 4) + t0 (64x64 multiply+add) - umull r5, r6, r3, r14 @ d = c.lo * (R0 >> 4) - adds r5, r5, r7 @ d.lo += t0 - mla r6, r14, r4, r6 @ d.hi += c.hi * (R0 >> 4) - adc r6, r6, 0 @ d.hi += carry - - bic r2, r5, field_not_M @ r[0] = d & M - str r2, [r0, #0*4] - - mov r5, r5, lsr #26 @ d >>= 26 - orr r5, r5, r6, asl #6 - mov r6, r6, lsr #26 - - movw r14, field_R1 >> 4 @ d += c * (R1 >> 4) + t1 (64x64 multiply+add) - umull r1, r2, r3, r14 @ tmp = c.lo * (R1 >> 4) - adds r5, r5, r8 @ d.lo += t1 - adc r6, r6, #0 @ d.hi += carry - adds r5, r5, r1 @ d.lo += tmp.lo - mla r2, r14, r4, r2 @ tmp.hi += c.hi * (R1 >> 4) - adc r6, r6, r2 @ d.hi += carry + tmp.hi - - bic r2, r5, field_not_M @ r[1] = d & M - str r2, [r0, #1*4] - mov r5, r5, lsr #26 @ d >>= 26 (ignore hi) - orr r5, r5, r6, asl #6 - - add r5, r5, r9 @ d += t2 - str r5, [r0, #2*4] @ r[2] = d - - add sp, sp, #48 - ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc} - .size secp256k1_fe_sqr_inner, .-secp256k1_fe_sqr_inner - diff --git a/util/secp256k1/depend/secp256k1/src/basic-config.h b/util/secp256k1/depend/secp256k1/src/basic-config.h deleted file mode 100644 index fc588061ca..0000000000 --- a/util/secp256k1/depend/secp256k1/src/basic-config.h +++ /dev/null @@ -1,33 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_BASIC_CONFIG_H -#define SECP256K1_BASIC_CONFIG_H - -#ifdef USE_BASIC_CONFIG - -#undef USE_ASM_X86_64 -#undef USE_ENDOMORPHISM -#undef USE_FIELD_10X26 -#undef USE_FIELD_5X52 -#undef USE_FIELD_INV_BUILTIN -#undef USE_FIELD_INV_NUM -#undef USE_NUM_GMP -#undef USE_NUM_NONE -#undef USE_SCALAR_4X64 -#undef USE_SCALAR_8X32 -#undef USE_SCALAR_INV_BUILTIN -#undef USE_SCALAR_INV_NUM - -#define USE_NUM_NONE 1 -#define USE_FIELD_INV_BUILTIN 1 -#define USE_SCALAR_INV_BUILTIN 1 -#define USE_FIELD_10X26 1 -#define USE_SCALAR_8X32 1 - -#endif /* USE_BASIC_CONFIG */ - -#endif /* SECP256K1_BASIC_CONFIG_H */ diff --git a/util/secp256k1/depend/secp256k1/src/bench.h b/util/secp256k1/depend/secp256k1/src/bench.h deleted file mode 100644 index d5ebe01301..0000000000 --- a/util/secp256k1/depend/secp256k1/src/bench.h +++ /dev/null @@ -1,66 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_BENCH_H -#define SECP256K1_BENCH_H - -#include -#include -#include "sys/time.h" - -static double gettimedouble(void) { - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_usec * 0.000001 + tv.tv_sec; -} - -void print_number(double x) { - double y = x; - int c = 0; - if (y < 0.0) { - y = -y; - } - while (y > 0 && y < 100.0) { - y *= 10.0; - c++; - } - printf("%.*f", c, x); -} - -void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) { - int i; - double min = HUGE_VAL; - double sum = 0.0; - double max = 0.0; - for (i = 0; i < count; i++) { - double begin, total; - if (setup != NULL) { - setup(data); - } - begin = gettimedouble(); - benchmark(data); - total = gettimedouble() - begin; - if (teardown != NULL) { - teardown(data); - } - if (total < min) { - min = total; - } - if (total > max) { - max = total; - } - sum += total; - } - printf("%s: min ", name); - print_number(min * 1000000.0 / iter); - printf("us / avg "); - print_number((sum / count) * 1000000.0 / iter); - printf("us / max "); - print_number(max * 1000000.0 / iter); - printf("us\n"); -} - -#endif /* SECP256K1_BENCH_H */ diff --git a/util/secp256k1/depend/secp256k1/src/bench_ecdh.c b/util/secp256k1/depend/secp256k1/src/bench_ecdh.c deleted file mode 100644 index 2de5126d63..0000000000 --- a/util/secp256k1/depend/secp256k1/src/bench_ecdh.c +++ /dev/null @@ -1,54 +0,0 @@ -/********************************************************************** - * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#include - -#include "include/secp256k1.h" -#include "include/secp256k1_ecdh.h" -#include "util.h" -#include "bench.h" - -typedef struct { - secp256k1_context *ctx; - secp256k1_pubkey point; - unsigned char scalar[32]; -} bench_ecdh; - -static void bench_ecdh_setup(void* arg) { - int i; - bench_ecdh *data = (bench_ecdh*)arg; - const unsigned char point[] = { - 0x03, - 0x54, 0x94, 0xc1, 0x5d, 0x32, 0x09, 0x97, 0x06, - 0xc2, 0x39, 0x5f, 0x94, 0x34, 0x87, 0x45, 0xfd, - 0x75, 0x7c, 0xe3, 0x0e, 0x4e, 0x8c, 0x90, 0xfb, - 0xa2, 0xba, 0xd1, 0x84, 0xf8, 0x83, 0xc6, 0x9f - }; - - /* create a context with no capabilities */ - data->ctx = secp256k1_context_create(SECP256K1_FLAGS_TYPE_CONTEXT); - for (i = 0; i < 32; i++) { - data->scalar[i] = i + 1; - } - CHECK(secp256k1_ec_pubkey_parse(data->ctx, &data->point, point, sizeof(point)) == 1); -} - -static void bench_ecdh(void* arg) { - int i; - unsigned char res[32]; - bench_ecdh *data = (bench_ecdh*)arg; - - for (i = 0; i < 20000; i++) { - CHECK(secp256k1_ecdh(data->ctx, res, &data->point, data->scalar) == 1); - } -} - -int main(void) { - bench_ecdh data; - - run_benchmark("ecdh", bench_ecdh, bench_ecdh_setup, NULL, &data, 10, 20000); - return 0; -} diff --git a/util/secp256k1/depend/secp256k1/src/bench_internal.c b/util/secp256k1/depend/secp256k1/src/bench_internal.c deleted file mode 100644 index 9b30c50d0b..0000000000 --- a/util/secp256k1/depend/secp256k1/src/bench_internal.c +++ /dev/null @@ -1,382 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ -#include - -#include "include/secp256k1.h" - -#include "util.h" -#include "hash_impl.h" -#include "num_impl.h" -#include "field_impl.h" -#include "group_impl.h" -#include "scalar_impl.h" -#include "ecmult_const_impl.h" -#include "ecmult_impl.h" -#include "bench.h" -#include "secp256k1.c" - -typedef struct { - secp256k1_scalar scalar_x, scalar_y; - secp256k1_fe fe_x, fe_y; - secp256k1_ge ge_x, ge_y; - secp256k1_gej gej_x, gej_y; - unsigned char data[64]; - int wnaf[256]; -} bench_inv; - -void bench_setup(void* arg) { - bench_inv *data = (bench_inv*)arg; - - static const unsigned char init_x[32] = { - 0x02, 0x03, 0x05, 0x07, 0x0b, 0x0d, 0x11, 0x13, - 0x17, 0x1d, 0x1f, 0x25, 0x29, 0x2b, 0x2f, 0x35, - 0x3b, 0x3d, 0x43, 0x47, 0x49, 0x4f, 0x53, 0x59, - 0x61, 0x65, 0x67, 0x6b, 0x6d, 0x71, 0x7f, 0x83 - }; - - static const unsigned char init_y[32] = { - 0x82, 0x83, 0x85, 0x87, 0x8b, 0x8d, 0x81, 0x83, - 0x97, 0xad, 0xaf, 0xb5, 0xb9, 0xbb, 0xbf, 0xc5, - 0xdb, 0xdd, 0xe3, 0xe7, 0xe9, 0xef, 0xf3, 0xf9, - 0x11, 0x15, 0x17, 0x1b, 0x1d, 0xb1, 0xbf, 0xd3 - }; - - secp256k1_scalar_set_b32(&data->scalar_x, init_x, NULL); - secp256k1_scalar_set_b32(&data->scalar_y, init_y, NULL); - secp256k1_fe_set_b32(&data->fe_x, init_x); - secp256k1_fe_set_b32(&data->fe_y, init_y); - CHECK(secp256k1_ge_set_xo_var(&data->ge_x, &data->fe_x, 0)); - CHECK(secp256k1_ge_set_xo_var(&data->ge_y, &data->fe_y, 1)); - secp256k1_gej_set_ge(&data->gej_x, &data->ge_x); - secp256k1_gej_set_ge(&data->gej_y, &data->ge_y); - memcpy(data->data, init_x, 32); - memcpy(data->data + 32, init_y, 32); -} - -void bench_scalar_add(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 2000000; i++) { - secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); - } -} - -void bench_scalar_negate(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 2000000; i++) { - secp256k1_scalar_negate(&data->scalar_x, &data->scalar_x); - } -} - -void bench_scalar_sqr(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 200000; i++) { - secp256k1_scalar_sqr(&data->scalar_x, &data->scalar_x); - } -} - -void bench_scalar_mul(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 200000; i++) { - secp256k1_scalar_mul(&data->scalar_x, &data->scalar_x, &data->scalar_y); - } -} - -#ifdef USE_ENDOMORPHISM -void bench_scalar_split(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 20000; i++) { - secp256k1_scalar l, r; - secp256k1_scalar_split_lambda(&l, &r, &data->scalar_x); - secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); - } -} -#endif - -void bench_scalar_inverse(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 2000; i++) { - secp256k1_scalar_inverse(&data->scalar_x, &data->scalar_x); - secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); - } -} - -void bench_scalar_inverse_var(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 2000; i++) { - secp256k1_scalar_inverse_var(&data->scalar_x, &data->scalar_x); - secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); - } -} - -void bench_field_normalize(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 2000000; i++) { - secp256k1_fe_normalize(&data->fe_x); - } -} - -void bench_field_normalize_weak(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 2000000; i++) { - secp256k1_fe_normalize_weak(&data->fe_x); - } -} - -void bench_field_mul(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 200000; i++) { - secp256k1_fe_mul(&data->fe_x, &data->fe_x, &data->fe_y); - } -} - -void bench_field_sqr(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 200000; i++) { - secp256k1_fe_sqr(&data->fe_x, &data->fe_x); - } -} - -void bench_field_inverse(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 20000; i++) { - secp256k1_fe_inv(&data->fe_x, &data->fe_x); - secp256k1_fe_add(&data->fe_x, &data->fe_y); - } -} - -void bench_field_inverse_var(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 20000; i++) { - secp256k1_fe_inv_var(&data->fe_x, &data->fe_x); - secp256k1_fe_add(&data->fe_x, &data->fe_y); - } -} - -void bench_field_sqrt(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 20000; i++) { - secp256k1_fe_sqrt(&data->fe_x, &data->fe_x); - secp256k1_fe_add(&data->fe_x, &data->fe_y); - } -} - -void bench_group_double_var(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 200000; i++) { - secp256k1_gej_double_var(&data->gej_x, &data->gej_x, NULL); - } -} - -void bench_group_add_var(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 200000; i++) { - secp256k1_gej_add_var(&data->gej_x, &data->gej_x, &data->gej_y, NULL); - } -} - -void bench_group_add_affine(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 200000; i++) { - secp256k1_gej_add_ge(&data->gej_x, &data->gej_x, &data->ge_y); - } -} - -void bench_group_add_affine_var(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 200000; i++) { - secp256k1_gej_add_ge_var(&data->gej_x, &data->gej_x, &data->ge_y, NULL); - } -} - -void bench_group_jacobi_var(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 20000; i++) { - secp256k1_gej_has_quad_y_var(&data->gej_x); - } -} - -void bench_ecmult_wnaf(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 20000; i++) { - secp256k1_ecmult_wnaf(data->wnaf, 256, &data->scalar_x, WINDOW_A); - secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); - } -} - -void bench_wnaf_const(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - - for (i = 0; i < 20000; i++) { - secp256k1_wnaf_const(data->wnaf, data->scalar_x, WINDOW_A); - secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); - } -} - - -void bench_sha256(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - secp256k1_sha256 sha; - - for (i = 0; i < 20000; i++) { - secp256k1_sha256_initialize(&sha); - secp256k1_sha256_write(&sha, data->data, 32); - secp256k1_sha256_finalize(&sha, data->data); - } -} - -void bench_hmac_sha256(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - secp256k1_hmac_sha256 hmac; - - for (i = 0; i < 20000; i++) { - secp256k1_hmac_sha256_initialize(&hmac, data->data, 32); - secp256k1_hmac_sha256_write(&hmac, data->data, 32); - secp256k1_hmac_sha256_finalize(&hmac, data->data); - } -} - -void bench_rfc6979_hmac_sha256(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - secp256k1_rfc6979_hmac_sha256 rng; - - for (i = 0; i < 20000; i++) { - secp256k1_rfc6979_hmac_sha256_initialize(&rng, data->data, 64); - secp256k1_rfc6979_hmac_sha256_generate(&rng, data->data, 32); - } -} - -void bench_context_verify(void* arg) { - int i; - (void)arg; - for (i = 0; i < 20; i++) { - secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_VERIFY)); - } -} - -void bench_context_sign(void* arg) { - int i; - (void)arg; - for (i = 0; i < 200; i++) { - secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_SIGN)); - } -} - -#ifndef USE_NUM_NONE -void bench_num_jacobi(void* arg) { - int i; - bench_inv *data = (bench_inv*)arg; - secp256k1_num nx, norder; - - secp256k1_scalar_get_num(&nx, &data->scalar_x); - secp256k1_scalar_order_get_num(&norder); - secp256k1_scalar_get_num(&norder, &data->scalar_y); - - for (i = 0; i < 200000; i++) { - secp256k1_num_jacobi(&nx, &norder); - } -} -#endif - -int have_flag(int argc, char** argv, char *flag) { - char** argm = argv + argc; - argv++; - if (argv == argm) { - return 1; - } - while (argv != NULL && argv != argm) { - if (strcmp(*argv, flag) == 0) { - return 1; - } - argv++; - } - return 0; -} - -int main(int argc, char **argv) { - bench_inv data; - if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "add")) run_benchmark("scalar_add", bench_scalar_add, bench_setup, NULL, &data, 10, 2000000); - if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "negate")) run_benchmark("scalar_negate", bench_scalar_negate, bench_setup, NULL, &data, 10, 2000000); - if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "sqr")) run_benchmark("scalar_sqr", bench_scalar_sqr, bench_setup, NULL, &data, 10, 200000); - if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "mul")) run_benchmark("scalar_mul", bench_scalar_mul, bench_setup, NULL, &data, 10, 200000); -#ifdef USE_ENDOMORPHISM - if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "split")) run_benchmark("scalar_split", bench_scalar_split, bench_setup, NULL, &data, 10, 20000); -#endif - if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse", bench_scalar_inverse, bench_setup, NULL, &data, 10, 2000); - if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse_var", bench_scalar_inverse_var, bench_setup, NULL, &data, 10, 2000); - - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize", bench_field_normalize, bench_setup, NULL, &data, 10, 2000000); - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize_weak", bench_field_normalize_weak, bench_setup, NULL, &data, 10, 2000000); - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqr")) run_benchmark("field_sqr", bench_field_sqr, bench_setup, NULL, &data, 10, 200000); - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "mul")) run_benchmark("field_mul", bench_field_mul, bench_setup, NULL, &data, 10, 200000); - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse", bench_field_inverse, bench_setup, NULL, &data, 10, 20000); - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse_var", bench_field_inverse_var, bench_setup, NULL, &data, 10, 20000); - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt", bench_field_sqrt, bench_setup, NULL, &data, 10, 20000); - - if (have_flag(argc, argv, "group") || have_flag(argc, argv, "double")) run_benchmark("group_double_var", bench_group_double_var, bench_setup, NULL, &data, 10, 200000); - if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, 200000); - if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, 200000); - if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, 200000); - if (have_flag(argc, argv, "group") || have_flag(argc, argv, "jacobi")) run_benchmark("group_jacobi_var", bench_group_jacobi_var, bench_setup, NULL, &data, 10, 20000); - - if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("wnaf_const", bench_wnaf_const, bench_setup, NULL, &data, 10, 20000); - if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, 20000); - - if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, 20000); - if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "hmac")) run_benchmark("hash_hmac_sha256", bench_hmac_sha256, bench_setup, NULL, &data, 10, 20000); - if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "rng6979")) run_benchmark("hash_rfc6979_hmac_sha256", bench_rfc6979_hmac_sha256, bench_setup, NULL, &data, 10, 20000); - - if (have_flag(argc, argv, "context") || have_flag(argc, argv, "verify")) run_benchmark("context_verify", bench_context_verify, bench_setup, NULL, &data, 10, 20); - if (have_flag(argc, argv, "context") || have_flag(argc, argv, "sign")) run_benchmark("context_sign", bench_context_sign, bench_setup, NULL, &data, 10, 200); - -#ifndef USE_NUM_NONE - if (have_flag(argc, argv, "num") || have_flag(argc, argv, "jacobi")) run_benchmark("num_jacobi", bench_num_jacobi, bench_setup, NULL, &data, 10, 200000); -#endif - return 0; -} diff --git a/util/secp256k1/depend/secp256k1/src/bench_recover.c b/util/secp256k1/depend/secp256k1/src/bench_recover.c deleted file mode 100644 index 506fc1880e..0000000000 --- a/util/secp256k1/depend/secp256k1/src/bench_recover.c +++ /dev/null @@ -1,60 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#include "include/secp256k1.h" -#include "include/secp256k1_recovery.h" -#include "util.h" -#include "bench.h" - -typedef struct { - secp256k1_context *ctx; - unsigned char msg[32]; - unsigned char sig[64]; -} bench_recover; - -void bench_recover(void* arg) { - int i; - bench_recover *data = (bench_recover*)arg; - secp256k1_pubkey pubkey; - unsigned char pubkeyc[33]; - - for (i = 0; i < 20000; i++) { - int j; - size_t pubkeylen = 33; - secp256k1_ecdsa_recoverable_signature sig; - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(data->ctx, &sig, data->sig, i % 2)); - CHECK(secp256k1_ecdsa_recover(data->ctx, &pubkey, &sig, data->msg)); - CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pubkeyc, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED)); - for (j = 0; j < 32; j++) { - data->sig[j + 32] = data->msg[j]; /* Move former message to S. */ - data->msg[j] = data->sig[j]; /* Move former R to message. */ - data->sig[j] = pubkeyc[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */ - } - } -} - -void bench_recover_setup(void* arg) { - int i; - bench_recover *data = (bench_recover*)arg; - - for (i = 0; i < 32; i++) { - data->msg[i] = 1 + i; - } - for (i = 0; i < 64; i++) { - data->sig[i] = 65 + i; - } -} - -int main(void) { - bench_recover data; - - data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); - - run_benchmark("ecdsa_recover", bench_recover, bench_recover_setup, NULL, &data, 10, 20000); - - secp256k1_context_destroy(data.ctx); - return 0; -} diff --git a/util/secp256k1/depend/secp256k1/src/bench_schnorr_verify.c b/util/secp256k1/depend/secp256k1/src/bench_schnorr_verify.c deleted file mode 100644 index 5f137dda23..0000000000 --- a/util/secp256k1/depend/secp256k1/src/bench_schnorr_verify.c +++ /dev/null @@ -1,73 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#include -#include - -#include "include/secp256k1.h" -#include "include/secp256k1_schnorr.h" -#include "util.h" -#include "bench.h" - -typedef struct { - unsigned char key[32]; - unsigned char sig[64]; - unsigned char pubkey[33]; - size_t pubkeylen; -} benchmark_schnorr_sig_t; - -typedef struct { - secp256k1_context *ctx; - unsigned char msg[32]; - benchmark_schnorr_sig_t sigs[64]; - int numsigs; -} benchmark_schnorr_verify_t; - -static void benchmark_schnorr_init(void* arg) { - int i, k; - benchmark_schnorr_verify_t* data = (benchmark_schnorr_verify_t*)arg; - - for (i = 0; i < 32; i++) { - data->msg[i] = 1 + i; - } - for (k = 0; k < data->numsigs; k++) { - secp256k1_pubkey pubkey; - for (i = 0; i < 32; i++) { - data->sigs[k].key[i] = 33 + i + k; - } - secp256k1_schnorr_sign(data->ctx, data->sigs[k].sig, data->msg, data->sigs[k].key, NULL, NULL); - data->sigs[k].pubkeylen = 33; - CHECK(secp256k1_ec_pubkey_create(data->ctx, &pubkey, data->sigs[k].key)); - CHECK(secp256k1_ec_pubkey_serialize(data->ctx, data->sigs[k].pubkey, &data->sigs[k].pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED)); - } -} - -static void benchmark_schnorr_verify(void* arg) { - int i; - benchmark_schnorr_verify_t* data = (benchmark_schnorr_verify_t*)arg; - - for (i = 0; i < 20000 / data->numsigs; i++) { - secp256k1_pubkey pubkey; - data->sigs[0].sig[(i >> 8) % 64] ^= (i & 0xFF); - CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->sigs[0].pubkey, data->sigs[0].pubkeylen)); - CHECK(secp256k1_schnorr_verify(data->ctx, data->sigs[0].sig, data->msg, &pubkey) == ((i & 0xFF) == 0)); - data->sigs[0].sig[(i >> 8) % 64] ^= (i & 0xFF); - } -} - - - -int main(void) { - benchmark_schnorr_verify_t data; - - data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - - data.numsigs = 1; - run_benchmark("schnorr_verify", benchmark_schnorr_verify, benchmark_schnorr_init, NULL, &data, 10, 20000); - - secp256k1_context_destroy(data.ctx); - return 0; -} diff --git a/util/secp256k1/depend/secp256k1/src/bench_sign.c b/util/secp256k1/depend/secp256k1/src/bench_sign.c deleted file mode 100644 index 544b43963c..0000000000 --- a/util/secp256k1/depend/secp256k1/src/bench_sign.c +++ /dev/null @@ -1,56 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#include "include/secp256k1.h" -#include "util.h" -#include "bench.h" - -typedef struct { - secp256k1_context* ctx; - unsigned char msg[32]; - unsigned char key[32]; -} bench_sign; - -static void bench_sign_setup(void* arg) { - int i; - bench_sign *data = (bench_sign*)arg; - - for (i = 0; i < 32; i++) { - data->msg[i] = i + 1; - } - for (i = 0; i < 32; i++) { - data->key[i] = i + 65; - } -} - -static void bench_sign_run(void* arg) { - int i; - bench_sign *data = (bench_sign*)arg; - - unsigned char sig[74]; - for (i = 0; i < 20000; i++) { - size_t siglen = 74; - int j; - secp256k1_ecdsa_signature signature; - CHECK(secp256k1_ecdsa_sign(data->ctx, &signature, data->msg, data->key, NULL, NULL)); - CHECK(secp256k1_ecdsa_signature_serialize_der(data->ctx, sig, &siglen, &signature)); - for (j = 0; j < 32; j++) { - data->msg[j] = sig[j]; - data->key[j] = sig[j + 32]; - } - } -} - -int main(void) { - bench_sign data; - - data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); - - run_benchmark("ecdsa_sign", bench_sign_run, bench_sign_setup, NULL, &data, 10, 20000); - - secp256k1_context_destroy(data.ctx); - return 0; -} diff --git a/util/secp256k1/depend/secp256k1/src/bench_verify.c b/util/secp256k1/depend/secp256k1/src/bench_verify.c deleted file mode 100644 index 418defa0aa..0000000000 --- a/util/secp256k1/depend/secp256k1/src/bench_verify.c +++ /dev/null @@ -1,112 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#include -#include - -#include "include/secp256k1.h" -#include "util.h" -#include "bench.h" - -#ifdef ENABLE_OPENSSL_TESTS -#include -#include -#include -#endif - -typedef struct { - secp256k1_context *ctx; - unsigned char msg[32]; - unsigned char key[32]; - unsigned char sig[72]; - size_t siglen; - unsigned char pubkey[33]; - size_t pubkeylen; -#ifdef ENABLE_OPENSSL_TESTS - EC_GROUP* ec_group; -#endif -} benchmark_verify_t; - -static void benchmark_verify(void* arg) { - int i; - benchmark_verify_t* data = (benchmark_verify_t*)arg; - - for (i = 0; i < 20000; i++) { - secp256k1_pubkey pubkey; - secp256k1_ecdsa_signature sig; - data->sig[data->siglen - 1] ^= (i & 0xFF); - data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); - data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); - CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->pubkey, data->pubkeylen) == 1); - CHECK(secp256k1_ecdsa_signature_parse_der(data->ctx, &sig, data->sig, data->siglen) == 1); - CHECK(secp256k1_ecdsa_verify(data->ctx, &sig, data->msg, &pubkey) == (i == 0)); - data->sig[data->siglen - 1] ^= (i & 0xFF); - data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); - data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); - } -} - -#ifdef ENABLE_OPENSSL_TESTS -static void benchmark_verify_openssl(void* arg) { - int i; - benchmark_verify_t* data = (benchmark_verify_t*)arg; - - for (i = 0; i < 20000; i++) { - data->sig[data->siglen - 1] ^= (i & 0xFF); - data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); - data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); - { - EC_KEY *pkey = EC_KEY_new(); - const unsigned char *pubkey = &data->pubkey[0]; - int result; - - CHECK(pkey != NULL); - result = EC_KEY_set_group(pkey, data->ec_group); - CHECK(result); - result = (o2i_ECPublicKey(&pkey, &pubkey, data->pubkeylen)) != NULL; - CHECK(result); - result = ECDSA_verify(0, &data->msg[0], sizeof(data->msg), &data->sig[0], data->siglen, pkey) == (i == 0); - CHECK(result); - EC_KEY_free(pkey); - } - data->sig[data->siglen - 1] ^= (i & 0xFF); - data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); - data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); - } -} -#endif - -int main(void) { - int i; - secp256k1_pubkey pubkey; - secp256k1_ecdsa_signature sig; - benchmark_verify_t data; - - data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - - for (i = 0; i < 32; i++) { - data.msg[i] = 1 + i; - } - for (i = 0; i < 32; i++) { - data.key[i] = 33 + i; - } - data.siglen = 72; - CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL)); - CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig)); - CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key)); - data.pubkeylen = 33; - CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1); - - run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000); -#ifdef ENABLE_OPENSSL_TESTS - data.ec_group = EC_GROUP_new_by_curve_name(NID_secp256k1); - run_benchmark("ecdsa_verify_openssl", benchmark_verify_openssl, NULL, NULL, &data, 10, 20000); - EC_GROUP_free(data.ec_group); -#endif - - secp256k1_context_destroy(data.ctx); - return 0; -} diff --git a/util/secp256k1/depend/secp256k1/src/ecdsa.h b/util/secp256k1/depend/secp256k1/src/ecdsa.h deleted file mode 100644 index 80590c7cc8..0000000000 --- a/util/secp256k1/depend/secp256k1/src/ecdsa.h +++ /dev/null @@ -1,21 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECDSA_H -#define SECP256K1_ECDSA_H - -#include - -#include "scalar.h" -#include "group.h" -#include "ecmult.h" - -static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *r, secp256k1_scalar *s, const unsigned char *sig, size_t size); -static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar *r, const secp256k1_scalar *s); -static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message); -static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid); - -#endif /* SECP256K1_ECDSA_H */ diff --git a/util/secp256k1/depend/secp256k1/src/ecdsa_impl.h b/util/secp256k1/depend/secp256k1/src/ecdsa_impl.h deleted file mode 100644 index c3400042d8..0000000000 --- a/util/secp256k1/depend/secp256k1/src/ecdsa_impl.h +++ /dev/null @@ -1,313 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - - -#ifndef SECP256K1_ECDSA_IMPL_H -#define SECP256K1_ECDSA_IMPL_H - -#include "scalar.h" -#include "field.h" -#include "group.h" -#include "ecmult.h" -#include "ecmult_gen.h" -#include "ecdsa.h" - -/** Group order for secp256k1 defined as 'n' in "Standards for Efficient Cryptography" (SEC2) 2.7.1 - * sage: for t in xrange(1023, -1, -1): - * .. p = 2**256 - 2**32 - t - * .. if p.is_prime(): - * .. print '%x'%p - * .. break - * 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f' - * sage: a = 0 - * sage: b = 7 - * sage: F = FiniteField (p) - * sage: '%x' % (EllipticCurve ([F (a), F (b)]).order()) - * 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141' - */ -static const secp256k1_fe secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST( - 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, - 0xBAAEDCE6UL, 0xAF48A03BUL, 0xBFD25E8CUL, 0xD0364141UL -); - -/** Difference between field and order, values 'p' and 'n' values defined in - * "Standards for Efficient Cryptography" (SEC2) 2.7.1. - * sage: p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F - * sage: a = 0 - * sage: b = 7 - * sage: F = FiniteField (p) - * sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order()) - * '14551231950b75fc4402da1722fc9baee' - */ -static const secp256k1_fe secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST( - 0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL -); - -static int secp256k1_der_read_len(const unsigned char **sigp, const unsigned char *sigend) { - int lenleft, b1; - size_t ret = 0; - if (*sigp >= sigend) { - return -1; - } - b1 = *((*sigp)++); - if (b1 == 0xFF) { - /* X.690-0207 8.1.3.5.c the value 0xFF shall not be used. */ - return -1; - } - if ((b1 & 0x80) == 0) { - /* X.690-0207 8.1.3.4 short form length octets */ - return b1; - } - if (b1 == 0x80) { - /* Indefinite length is not allowed in DER. */ - return -1; - } - /* X.690-207 8.1.3.5 long form length octets */ - lenleft = b1 & 0x7F; - if (lenleft > sigend - *sigp) { - return -1; - } - if (**sigp == 0) { - /* Not the shortest possible length encoding. */ - return -1; - } - if ((size_t)lenleft > sizeof(size_t)) { - /* The resulting length would exceed the range of a size_t, so - * certainly longer than the passed array size. - */ - return -1; - } - while (lenleft > 0) { - ret = (ret << 8) | **sigp; - if (ret + lenleft > (size_t)(sigend - *sigp)) { - /* Result exceeds the length of the passed array. */ - return -1; - } - (*sigp)++; - lenleft--; - } - if (ret < 128) { - /* Not the shortest possible length encoding. */ - return -1; - } - return ret; -} - -static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char **sig, const unsigned char *sigend) { - int overflow = 0; - unsigned char ra[32] = {0}; - int rlen; - - if (*sig == sigend || **sig != 0x02) { - /* Not a primitive integer (X.690-0207 8.3.1). */ - return 0; - } - (*sig)++; - rlen = secp256k1_der_read_len(sig, sigend); - if (rlen <= 0 || (*sig) + rlen > sigend) { - /* Exceeds bounds or not at least length 1 (X.690-0207 8.3.1). */ - return 0; - } - if (**sig == 0x00 && rlen > 1 && (((*sig)[1]) & 0x80) == 0x00) { - /* Excessive 0x00 padding. */ - return 0; - } - if (**sig == 0xFF && rlen > 1 && (((*sig)[1]) & 0x80) == 0x80) { - /* Excessive 0xFF padding. */ - return 0; - } - if ((**sig & 0x80) == 0x80) { - /* Negative. */ - overflow = 1; - } - while (rlen > 0 && **sig == 0) { - /* Skip leading zero bytes */ - rlen--; - (*sig)++; - } - if (rlen > 32) { - overflow = 1; - } - if (!overflow) { - memcpy(ra + 32 - rlen, *sig, rlen); - secp256k1_scalar_set_b32(r, ra, &overflow); - } - if (overflow) { - secp256k1_scalar_set_int(r, 0); - } - (*sig) += rlen; - return 1; -} - -static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *rr, secp256k1_scalar *rs, const unsigned char *sig, size_t size) { - const unsigned char *sigend = sig + size; - int rlen; - if (sig == sigend || *(sig++) != 0x30) { - /* The encoding doesn't start with a constructed sequence (X.690-0207 8.9.1). */ - return 0; - } - rlen = secp256k1_der_read_len(&sig, sigend); - if (rlen < 0 || sig + rlen > sigend) { - /* Tuple exceeds bounds */ - return 0; - } - if (sig + rlen != sigend) { - /* Garbage after tuple. */ - return 0; - } - - if (!secp256k1_der_parse_integer(rr, &sig, sigend)) { - return 0; - } - if (!secp256k1_der_parse_integer(rs, &sig, sigend)) { - return 0; - } - - if (sig != sigend) { - /* Trailing garbage inside tuple. */ - return 0; - } - - return 1; -} - -static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar* ar, const secp256k1_scalar* as) { - unsigned char r[33] = {0}, s[33] = {0}; - unsigned char *rp = r, *sp = s; - size_t lenR = 33, lenS = 33; - secp256k1_scalar_get_b32(&r[1], ar); - secp256k1_scalar_get_b32(&s[1], as); - while (lenR > 1 && rp[0] == 0 && rp[1] < 0x80) { lenR--; rp++; } - while (lenS > 1 && sp[0] == 0 && sp[1] < 0x80) { lenS--; sp++; } - if (*size < 6+lenS+lenR) { - *size = 6 + lenS + lenR; - return 0; - } - *size = 6 + lenS + lenR; - sig[0] = 0x30; - sig[1] = 4 + lenS + lenR; - sig[2] = 0x02; - sig[3] = lenR; - memcpy(sig+4, rp, lenR); - sig[4+lenR] = 0x02; - sig[5+lenR] = lenS; - memcpy(sig+lenR+6, sp, lenS); - return 1; -} - -static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) { - unsigned char c[32]; - secp256k1_scalar sn, u1, u2; -#if !defined(EXHAUSTIVE_TEST_ORDER) - secp256k1_fe xr; -#endif - secp256k1_gej pubkeyj; - secp256k1_gej pr; - - if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) { - return 0; - } - - secp256k1_scalar_inverse_var(&sn, sigs); - secp256k1_scalar_mul(&u1, &sn, message); - secp256k1_scalar_mul(&u2, &sn, sigr); - secp256k1_gej_set_ge(&pubkeyj, pubkey); - secp256k1_ecmult(ctx, &pr, &pubkeyj, &u2, &u1); - if (secp256k1_gej_is_infinity(&pr)) { - return 0; - } - -#if defined(EXHAUSTIVE_TEST_ORDER) -{ - secp256k1_scalar computed_r; - secp256k1_ge pr_ge; - secp256k1_ge_set_gej(&pr_ge, &pr); - secp256k1_fe_normalize(&pr_ge.x); - - secp256k1_fe_get_b32(c, &pr_ge.x); - secp256k1_scalar_set_b32(&computed_r, c, NULL); - return secp256k1_scalar_eq(sigr, &computed_r); -} -#else - secp256k1_scalar_get_b32(c, sigr); - secp256k1_fe_set_b32(&xr, c); - - /** We now have the recomputed R point in pr, and its claimed x coordinate (modulo n) - * in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p), - * compute the remainder modulo n, and compare it to xr. However: - * - * xr == X(pr) mod n - * <=> exists h. (xr + h * n < p && xr + h * n == X(pr)) - * [Since 2 * n > p, h can only be 0 or 1] - * <=> (xr == X(pr)) || (xr + n < p && xr + n == X(pr)) - * [In Jacobian coordinates, X(pr) is pr.x / pr.z^2 mod p] - * <=> (xr == pr.x / pr.z^2 mod p) || (xr + n < p && xr + n == pr.x / pr.z^2 mod p) - * [Multiplying both sides of the equations by pr.z^2 mod p] - * <=> (xr * pr.z^2 mod p == pr.x) || (xr + n < p && (xr + n) * pr.z^2 mod p == pr.x) - * - * Thus, we can avoid the inversion, but we have to check both cases separately. - * secp256k1_gej_eq_x implements the (xr * pr.z^2 mod p == pr.x) test. - */ - if (secp256k1_gej_eq_x_var(&xr, &pr)) { - /* xr * pr.z^2 mod p == pr.x, so the signature is valid. */ - return 1; - } - if (secp256k1_fe_cmp_var(&xr, &secp256k1_ecdsa_const_p_minus_order) >= 0) { - /* xr + n >= p, so we can skip testing the second case. */ - return 0; - } - secp256k1_fe_add(&xr, &secp256k1_ecdsa_const_order_as_fe); - if (secp256k1_gej_eq_x_var(&xr, &pr)) { - /* (xr + n) * pr.z^2 mod p == pr.x, so the signature is valid. */ - return 1; - } - return 0; -#endif -} - -static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid) { - unsigned char b[32]; - secp256k1_gej rp; - secp256k1_ge r; - secp256k1_scalar n; - int overflow = 0; - - secp256k1_ecmult_gen(ctx, &rp, nonce); - secp256k1_ge_set_gej(&r, &rp); - secp256k1_fe_normalize(&r.x); - secp256k1_fe_normalize(&r.y); - secp256k1_fe_get_b32(b, &r.x); - secp256k1_scalar_set_b32(sigr, b, &overflow); - /* These two conditions should be checked before calling */ - VERIFY_CHECK(!secp256k1_scalar_is_zero(sigr)); - VERIFY_CHECK(overflow == 0); - - if (recid) { - /* The overflow condition is cryptographically unreachable as hitting it requires finding the discrete log - * of some P where P.x >= order, and only 1 in about 2^127 points meet this criteria. - */ - *recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0); - } - secp256k1_scalar_mul(&n, sigr, seckey); - secp256k1_scalar_add(&n, &n, message); - secp256k1_scalar_inverse(sigs, nonce); - secp256k1_scalar_mul(sigs, sigs, &n); - secp256k1_scalar_clear(&n); - secp256k1_gej_clear(&rp); - secp256k1_ge_clear(&r); - if (secp256k1_scalar_is_zero(sigs)) { - return 0; - } - if (secp256k1_scalar_is_high(sigs)) { - secp256k1_scalar_negate(sigs, sigs); - if (recid) { - *recid ^= 1; - } - } - return 1; -} - -#endif /* SECP256K1_ECDSA_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/eckey.h b/util/secp256k1/depend/secp256k1/src/eckey.h deleted file mode 100644 index b621f1e6c3..0000000000 --- a/util/secp256k1/depend/secp256k1/src/eckey.h +++ /dev/null @@ -1,25 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECKEY_H -#define SECP256K1_ECKEY_H - -#include - -#include "group.h" -#include "scalar.h" -#include "ecmult.h" -#include "ecmult_gen.h" - -static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size); -static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed); - -static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak); -static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); -static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak); -static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); - -#endif /* SECP256K1_ECKEY_H */ diff --git a/util/secp256k1/depend/secp256k1/src/eckey_impl.h b/util/secp256k1/depend/secp256k1/src/eckey_impl.h deleted file mode 100644 index 1ab9a68ec0..0000000000 --- a/util/secp256k1/depend/secp256k1/src/eckey_impl.h +++ /dev/null @@ -1,100 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECKEY_IMPL_H -#define SECP256K1_ECKEY_IMPL_H - -#include "eckey.h" - -#include "scalar.h" -#include "field.h" -#include "group.h" -#include "ecmult_gen.h" - -static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size) { - if (size == 33 && (pub[0] == SECP256K1_TAG_PUBKEY_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_ODD)) { - secp256k1_fe x; - return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == SECP256K1_TAG_PUBKEY_ODD); - } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) { - secp256k1_fe x, y; - if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) { - return 0; - } - secp256k1_ge_set_xy(elem, &x, &y); - if ((pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD) && - secp256k1_fe_is_odd(&y) != (pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { - return 0; - } - return secp256k1_ge_is_valid_var(elem); - } else { - return 0; - } -} - -static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed) { - if (secp256k1_ge_is_infinity(elem)) { - return 0; - } - secp256k1_fe_normalize_var(&elem->x); - secp256k1_fe_normalize_var(&elem->y); - secp256k1_fe_get_b32(&pub[1], &elem->x); - if (compressed) { - *size = 33; - pub[0] = secp256k1_fe_is_odd(&elem->y) ? SECP256K1_TAG_PUBKEY_ODD : SECP256K1_TAG_PUBKEY_EVEN; - } else { - *size = 65; - pub[0] = SECP256K1_TAG_PUBKEY_UNCOMPRESSED; - secp256k1_fe_get_b32(&pub[33], &elem->y); - } - return 1; -} - -static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak) { - secp256k1_scalar_add(key, key, tweak); - if (secp256k1_scalar_is_zero(key)) { - return 0; - } - return 1; -} - -static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { - secp256k1_gej pt; - secp256k1_scalar one; - secp256k1_gej_set_ge(&pt, key); - secp256k1_scalar_set_int(&one, 1); - secp256k1_ecmult(ctx, &pt, &pt, &one, tweak); - - if (secp256k1_gej_is_infinity(&pt)) { - return 0; - } - secp256k1_ge_set_gej(key, &pt); - return 1; -} - -static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak) { - if (secp256k1_scalar_is_zero(tweak)) { - return 0; - } - - secp256k1_scalar_mul(key, key, tweak); - return 1; -} - -static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { - secp256k1_scalar zero; - secp256k1_gej pt; - if (secp256k1_scalar_is_zero(tweak)) { - return 0; - } - - secp256k1_scalar_set_int(&zero, 0); - secp256k1_gej_set_ge(&pt, key); - secp256k1_ecmult(ctx, &pt, &pt, tweak, &zero); - secp256k1_ge_set_gej(key, &pt); - return 1; -} - -#endif /* SECP256K1_ECKEY_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/ecmult.h b/util/secp256k1/depend/secp256k1/src/ecmult.h deleted file mode 100644 index 6d44aba60b..0000000000 --- a/util/secp256k1/depend/secp256k1/src/ecmult.h +++ /dev/null @@ -1,31 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECMULT_H -#define SECP256K1_ECMULT_H - -#include "num.h" -#include "group.h" - -typedef struct { - /* For accelerating the computation of a*P + b*G: */ - secp256k1_ge_storage (*pre_g)[]; /* odd multiples of the generator */ -#ifdef USE_ENDOMORPHISM - secp256k1_ge_storage (*pre_g_128)[]; /* odd multiples of 2^128*generator */ -#endif -} secp256k1_ecmult_context; - -static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx); -static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb); -static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, - const secp256k1_ecmult_context *src, const secp256k1_callback *cb); -static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx); -static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx); - -/** Double multiply: R = na*A + ng*G */ -static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng); - -#endif /* SECP256K1_ECMULT_H */ diff --git a/util/secp256k1/depend/secp256k1/src/ecmult_const.h b/util/secp256k1/depend/secp256k1/src/ecmult_const.h deleted file mode 100644 index 72bf7d7582..0000000000 --- a/util/secp256k1/depend/secp256k1/src/ecmult_const.h +++ /dev/null @@ -1,15 +0,0 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECMULT_CONST_H -#define SECP256K1_ECMULT_CONST_H - -#include "scalar.h" -#include "group.h" - -static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q); - -#endif /* SECP256K1_ECMULT_CONST_H */ diff --git a/util/secp256k1/depend/secp256k1/src/ecmult_const_impl.h b/util/secp256k1/depend/secp256k1/src/ecmult_const_impl.h deleted file mode 100644 index 7d7a172b7b..0000000000 --- a/util/secp256k1/depend/secp256k1/src/ecmult_const_impl.h +++ /dev/null @@ -1,240 +0,0 @@ -/********************************************************************** - * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECMULT_CONST_IMPL_H -#define SECP256K1_ECMULT_CONST_IMPL_H - -#include "scalar.h" -#include "group.h" -#include "ecmult_const.h" -#include "ecmult_impl.h" - -#ifdef USE_ENDOMORPHISM - #define WNAF_BITS 128 -#else - #define WNAF_BITS 256 -#endif -#define WNAF_SIZE(w) ((WNAF_BITS + (w) - 1) / (w)) - -/* This is like `ECMULT_TABLE_GET_GE` but is constant time */ -#define ECMULT_CONST_TABLE_GET_GE(r,pre,n,w) do { \ - int m; \ - int abs_n = (n) * (((n) > 0) * 2 - 1); \ - int idx_n = abs_n / 2; \ - secp256k1_fe neg_y; \ - VERIFY_CHECK(((n) & 1) == 1); \ - VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ - VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ - VERIFY_SETUP(secp256k1_fe_clear(&(r)->x)); \ - VERIFY_SETUP(secp256k1_fe_clear(&(r)->y)); \ - for (m = 0; m < ECMULT_TABLE_SIZE(w); m++) { \ - /* This loop is used to avoid secret data in array indices. See - * the comment in ecmult_gen_impl.h for rationale. */ \ - secp256k1_fe_cmov(&(r)->x, &(pre)[m].x, m == idx_n); \ - secp256k1_fe_cmov(&(r)->y, &(pre)[m].y, m == idx_n); \ - } \ - (r)->infinity = 0; \ - secp256k1_fe_negate(&neg_y, &(r)->y, 1); \ - secp256k1_fe_cmov(&(r)->y, &neg_y, (n) != abs_n); \ -} while(0) - - -/** Convert a number to WNAF notation. - * The number becomes represented by sum(2^{wi} * wnaf[i], i=0..WNAF_SIZE(w)+1) - return_val. - * It has the following guarantees: - * - each wnaf[i] an odd integer between -(1 << w) and (1 << w) - * - each wnaf[i] is nonzero - * - the number of words set is always WNAF_SIZE(w) + 1 - * - * Adapted from `The Width-w NAF Method Provides Small Memory and Fast Elliptic Scalar - * Multiplications Secure against Side Channel Attacks`, Okeya and Tagaki. M. Joye (Ed.) - * CT-RSA 2003, LNCS 2612, pp. 328-443, 2003. Springer-Verlagy Berlin Heidelberg 2003 - * - * Numbers reference steps of `Algorithm SPA-resistant Width-w NAF with Odd Scalar` on pp. 335 - */ -static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w) { - int global_sign; - int skew = 0; - int word = 0; - - /* 1 2 3 */ - int u_last; - int u; - - int flip; - int bit; - secp256k1_scalar neg_s; - int not_neg_one; - /* Note that we cannot handle even numbers by negating them to be odd, as is - * done in other implementations, since if our scalars were specified to have - * width < 256 for performance reasons, their negations would have width 256 - * and we'd lose any performance benefit. Instead, we use a technique from - * Section 4.2 of the Okeya/Tagaki paper, which is to add either 1 (for even) - * or 2 (for odd) to the number we are encoding, returning a skew value indicating - * this, and having the caller compensate after doing the multiplication. */ - - /* Negative numbers will be negated to keep their bit representation below the maximum width */ - flip = secp256k1_scalar_is_high(&s); - /* We add 1 to even numbers, 2 to odd ones, noting that negation flips parity */ - bit = flip ^ !secp256k1_scalar_is_even(&s); - /* We check for negative one, since adding 2 to it will cause an overflow */ - secp256k1_scalar_negate(&neg_s, &s); - not_neg_one = !secp256k1_scalar_is_one(&neg_s); - secp256k1_scalar_cadd_bit(&s, bit, not_neg_one); - /* If we had negative one, flip == 1, s.d[0] == 0, bit == 1, so caller expects - * that we added two to it and flipped it. In fact for -1 these operations are - * identical. We only flipped, but since skewing is required (in the sense that - * the skew must be 1 or 2, never zero) and flipping is not, we need to change - * our flags to claim that we only skewed. */ - global_sign = secp256k1_scalar_cond_negate(&s, flip); - global_sign *= not_neg_one * 2 - 1; - skew = 1 << bit; - - /* 4 */ - u_last = secp256k1_scalar_shr_int(&s, w); - while (word * w < WNAF_BITS) { - int sign; - int even; - - /* 4.1 4.4 */ - u = secp256k1_scalar_shr_int(&s, w); - /* 4.2 */ - even = ((u & 1) == 0); - sign = 2 * (u_last > 0) - 1; - u += sign * even; - u_last -= sign * even * (1 << w); - - /* 4.3, adapted for global sign change */ - wnaf[word++] = u_last * global_sign; - - u_last = u; - } - wnaf[word] = u * global_sign; - - VERIFY_CHECK(secp256k1_scalar_is_zero(&s)); - VERIFY_CHECK(word == WNAF_SIZE(w)); - return skew; -} - - -static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *scalar) { - secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_ge tmpa; - secp256k1_fe Z; - - int skew_1; - int wnaf_1[1 + WNAF_SIZE(WINDOW_A - 1)]; -#ifdef USE_ENDOMORPHISM - secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; - int wnaf_lam[1 + WNAF_SIZE(WINDOW_A - 1)]; - int skew_lam; - secp256k1_scalar q_1, q_lam; -#endif - - int i; - secp256k1_scalar sc = *scalar; - - /* build wnaf representation for q. */ -#ifdef USE_ENDOMORPHISM - /* split q into q_1 and q_lam (where q = q_1 + q_lam*lambda, and q_1 and q_lam are ~128 bit) */ - secp256k1_scalar_split_lambda(&q_1, &q_lam, &sc); - skew_1 = secp256k1_wnaf_const(wnaf_1, q_1, WINDOW_A - 1); - skew_lam = secp256k1_wnaf_const(wnaf_lam, q_lam, WINDOW_A - 1); -#else - skew_1 = secp256k1_wnaf_const(wnaf_1, sc, WINDOW_A - 1); -#endif - - /* Calculate odd multiples of a. - * All multiples are brought to the same Z 'denominator', which is stored - * in Z. Due to secp256k1' isomorphism we can do all operations pretending - * that the Z coordinate was 1, use affine addition formulae, and correct - * the Z coordinate of the result once at the end. - */ - secp256k1_gej_set_ge(r, a); - secp256k1_ecmult_odd_multiples_table_globalz_windowa(pre_a, &Z, r); - for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { - secp256k1_fe_normalize_weak(&pre_a[i].y); - } -#ifdef USE_ENDOMORPHISM - for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { - secp256k1_ge_mul_lambda(&pre_a_lam[i], &pre_a[i]); - } -#endif - - /* first loop iteration (separated out so we can directly set r, rather - * than having it start at infinity, get doubled several times, then have - * its new value added to it) */ - i = wnaf_1[WNAF_SIZE(WINDOW_A - 1)]; - VERIFY_CHECK(i != 0); - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, i, WINDOW_A); - secp256k1_gej_set_ge(r, &tmpa); -#ifdef USE_ENDOMORPHISM - i = wnaf_lam[WNAF_SIZE(WINDOW_A - 1)]; - VERIFY_CHECK(i != 0); - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, i, WINDOW_A); - secp256k1_gej_add_ge(r, r, &tmpa); -#endif - /* remaining loop iterations */ - for (i = WNAF_SIZE(WINDOW_A - 1) - 1; i >= 0; i--) { - int n; - int j; - for (j = 0; j < WINDOW_A - 1; ++j) { - secp256k1_gej_double_nonzero(r, r, NULL); - } - - n = wnaf_1[i]; - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); - VERIFY_CHECK(n != 0); - secp256k1_gej_add_ge(r, r, &tmpa); -#ifdef USE_ENDOMORPHISM - n = wnaf_lam[i]; - ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A); - VERIFY_CHECK(n != 0); - secp256k1_gej_add_ge(r, r, &tmpa); -#endif - } - - secp256k1_fe_mul(&r->z, &r->z, &Z); - - { - /* Correct for wNAF skew */ - secp256k1_ge correction = *a; - secp256k1_ge_storage correction_1_stor; -#ifdef USE_ENDOMORPHISM - secp256k1_ge_storage correction_lam_stor; -#endif - secp256k1_ge_storage a2_stor; - secp256k1_gej tmpj; - secp256k1_gej_set_ge(&tmpj, &correction); - secp256k1_gej_double_var(&tmpj, &tmpj, NULL); - secp256k1_ge_set_gej(&correction, &tmpj); - secp256k1_ge_to_storage(&correction_1_stor, a); -#ifdef USE_ENDOMORPHISM - secp256k1_ge_to_storage(&correction_lam_stor, a); -#endif - secp256k1_ge_to_storage(&a2_stor, &correction); - - /* For odd numbers this is 2a (so replace it), for even ones a (so no-op) */ - secp256k1_ge_storage_cmov(&correction_1_stor, &a2_stor, skew_1 == 2); -#ifdef USE_ENDOMORPHISM - secp256k1_ge_storage_cmov(&correction_lam_stor, &a2_stor, skew_lam == 2); -#endif - - /* Apply the correction */ - secp256k1_ge_from_storage(&correction, &correction_1_stor); - secp256k1_ge_neg(&correction, &correction); - secp256k1_gej_add_ge(r, r, &correction); - -#ifdef USE_ENDOMORPHISM - secp256k1_ge_from_storage(&correction, &correction_lam_stor); - secp256k1_ge_neg(&correction, &correction); - secp256k1_ge_mul_lambda(&correction, &correction); - secp256k1_gej_add_ge(r, r, &correction); -#endif - } -} - -#endif /* SECP256K1_ECMULT_CONST_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/ecmult_gen.h b/util/secp256k1/depend/secp256k1/src/ecmult_gen.h deleted file mode 100644 index 7564b7015f..0000000000 --- a/util/secp256k1/depend/secp256k1/src/ecmult_gen.h +++ /dev/null @@ -1,43 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECMULT_GEN_H -#define SECP256K1_ECMULT_GEN_H - -#include "scalar.h" -#include "group.h" - -typedef struct { - /* For accelerating the computation of a*G: - * To harden against timing attacks, use the following mechanism: - * * Break up the multiplicand into groups of 4 bits, called n_0, n_1, n_2, ..., n_63. - * * Compute sum(n_i * 16^i * G + U_i, i=0..63), where: - * * U_i = U * 2^i (for i=0..62) - * * U_i = U * (1-2^63) (for i=63) - * where U is a point with no known corresponding scalar. Note that sum(U_i, i=0..63) = 0. - * For each i, and each of the 16 possible values of n_i, (n_i * 16^i * G + U_i) is - * precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0..63). - * None of the resulting prec group elements have a known scalar, and neither do any of - * the intermediate sums while computing a*G. - */ - secp256k1_ge_storage (*prec)[64][16]; /* prec[j][i] = 16^j * i * G + U_i */ - secp256k1_scalar blind; - secp256k1_gej initial; -} secp256k1_ecmult_gen_context; - -static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context* ctx); -static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx, const secp256k1_callback* cb); -static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst, - const secp256k1_ecmult_gen_context* src, const secp256k1_callback* cb); -static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx); -static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx); - -/** Multiply with the generator: R = a*G */ -static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context* ctx, secp256k1_gej *r, const secp256k1_scalar *a); - -static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32); - -#endif /* SECP256K1_ECMULT_GEN_H */ diff --git a/util/secp256k1/depend/secp256k1/src/ecmult_gen_impl.h b/util/secp256k1/depend/secp256k1/src/ecmult_gen_impl.h deleted file mode 100644 index 714f02e94c..0000000000 --- a/util/secp256k1/depend/secp256k1/src/ecmult_gen_impl.h +++ /dev/null @@ -1,210 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECMULT_GEN_IMPL_H -#define SECP256K1_ECMULT_GEN_IMPL_H - -#include "scalar.h" -#include "group.h" -#include "ecmult_gen.h" -#include "hash_impl.h" -#ifdef USE_ECMULT_STATIC_PRECOMPUTATION -#include "ecmult_static_context.h" -#endif -static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context *ctx) { - ctx->prec = NULL; -} - -static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx, const secp256k1_callback* cb) { -#ifndef USE_ECMULT_STATIC_PRECOMPUTATION - secp256k1_ge prec[1024]; - secp256k1_gej gj; - secp256k1_gej nums_gej; - int i, j; -#endif - - if (ctx->prec != NULL) { - return; - } -#ifndef USE_ECMULT_STATIC_PRECOMPUTATION - ctx->prec = (secp256k1_ge_storage (*)[64][16])checked_malloc(cb, sizeof(*ctx->prec)); - - /* get the generator */ - secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); - - /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */ - { - static const unsigned char nums_b32[33] = "The scalar for this x is unknown"; - secp256k1_fe nums_x; - secp256k1_ge nums_ge; - int r; - r = secp256k1_fe_set_b32(&nums_x, nums_b32); - (void)r; - VERIFY_CHECK(r); - r = secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0); - (void)r; - VERIFY_CHECK(r); - secp256k1_gej_set_ge(&nums_gej, &nums_ge); - /* Add G to make the bits in x uniformly distributed. */ - secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, &secp256k1_ge_const_g, NULL); - } - - /* compute prec. */ - { - secp256k1_gej precj[1024]; /* Jacobian versions of prec. */ - secp256k1_gej gbase; - secp256k1_gej numsbase; - gbase = gj; /* 16^j * G */ - numsbase = nums_gej; /* 2^j * nums. */ - for (j = 0; j < 64; j++) { - /* Set precj[j*16 .. j*16+15] to (numsbase, numsbase + gbase, ..., numsbase + 15*gbase). */ - precj[j*16] = numsbase; - for (i = 1; i < 16; i++) { - secp256k1_gej_add_var(&precj[j*16 + i], &precj[j*16 + i - 1], &gbase, NULL); - } - /* Multiply gbase by 16. */ - for (i = 0; i < 4; i++) { - secp256k1_gej_double_var(&gbase, &gbase, NULL); - } - /* Multiply numbase by 2. */ - secp256k1_gej_double_var(&numsbase, &numsbase, NULL); - if (j == 62) { - /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */ - secp256k1_gej_neg(&numsbase, &numsbase); - secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL); - } - } - secp256k1_ge_set_all_gej_var(prec, precj, 1024, cb); - } - for (j = 0; j < 64; j++) { - for (i = 0; i < 16; i++) { - secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*16 + i]); - } - } -#else - (void)cb; - ctx->prec = (secp256k1_ge_storage (*)[64][16])secp256k1_ecmult_static_context; -#endif - secp256k1_ecmult_gen_blind(ctx, NULL); -} - -static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx) { - return ctx->prec != NULL; -} - -static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst, - const secp256k1_ecmult_gen_context *src, const secp256k1_callback* cb) { - if (src->prec == NULL) { - dst->prec = NULL; - } else { -#ifndef USE_ECMULT_STATIC_PRECOMPUTATION - dst->prec = (secp256k1_ge_storage (*)[64][16])checked_malloc(cb, sizeof(*dst->prec)); - memcpy(dst->prec, src->prec, sizeof(*dst->prec)); -#else - (void)cb; - dst->prec = src->prec; -#endif - dst->initial = src->initial; - dst->blind = src->blind; - } -} - -static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx) { -#ifndef USE_ECMULT_STATIC_PRECOMPUTATION - free(ctx->prec); -#endif - secp256k1_scalar_clear(&ctx->blind); - secp256k1_gej_clear(&ctx->initial); - ctx->prec = NULL; -} - -static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp256k1_gej *r, const secp256k1_scalar *gn) { - secp256k1_ge add; - secp256k1_ge_storage adds; - secp256k1_scalar gnb; - int bits; - int i, j; - memset(&adds, 0, sizeof(adds)); - *r = ctx->initial; - /* Blind scalar/point multiplication by computing (n-b)G + bG instead of nG. */ - secp256k1_scalar_add(&gnb, gn, &ctx->blind); - add.infinity = 0; - for (j = 0; j < 64; j++) { - bits = secp256k1_scalar_get_bits(&gnb, j * 4, 4); - for (i = 0; i < 16; i++) { - /** This uses a conditional move to avoid any secret data in array indexes. - * _Any_ use of secret indexes has been demonstrated to result in timing - * sidechannels, even when the cache-line access patterns are uniform. - * See also: - * "A word of warning", CHES 2013 Rump Session, by Daniel J. Bernstein and Peter Schwabe - * (https://cryptojedi.org/peter/data/chesrump-20130822.pdf) and - * "Cache Attacks and Countermeasures: the Case of AES", RSA 2006, - * by Dag Arne Osvik, Adi Shamir, and Eran Tromer - * (http://www.tau.ac.il/~tromer/papers/cache.pdf) - */ - secp256k1_ge_storage_cmov(&adds, &(*ctx->prec)[j][i], i == bits); - } - secp256k1_ge_from_storage(&add, &adds); - secp256k1_gej_add_ge(r, r, &add); - } - bits = 0; - secp256k1_ge_clear(&add); - secp256k1_scalar_clear(&gnb); -} - -/* Setup blinding values for secp256k1_ecmult_gen. */ -static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32) { - secp256k1_scalar b; - secp256k1_gej gb; - secp256k1_fe s; - unsigned char nonce32[32]; - secp256k1_rfc6979_hmac_sha256 rng; - int retry; - unsigned char keydata[64] = {0}; - if (seed32 == NULL) { - /* When seed is NULL, reset the initial point and blinding value. */ - secp256k1_gej_set_ge(&ctx->initial, &secp256k1_ge_const_g); - secp256k1_gej_neg(&ctx->initial, &ctx->initial); - secp256k1_scalar_set_int(&ctx->blind, 1); - } - /* The prior blinding value (if not reset) is chained forward by including it in the hash. */ - secp256k1_scalar_get_b32(nonce32, &ctx->blind); - /** Using a CSPRNG allows a failure free interface, avoids needing large amounts of random data, - * and guards against weak or adversarial seeds. This is a simpler and safer interface than - * asking the caller for blinding values directly and expecting them to retry on failure. - */ - memcpy(keydata, nonce32, 32); - if (seed32 != NULL) { - memcpy(keydata + 32, seed32, 32); - } - secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, seed32 ? 64 : 32); - memset(keydata, 0, sizeof(keydata)); - /* Retry for out of range results to achieve uniformity. */ - do { - secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); - retry = !secp256k1_fe_set_b32(&s, nonce32); - retry |= secp256k1_fe_is_zero(&s); - } while (retry); /* This branch true is cryptographically unreachable. Requires sha256_hmac output > Fp. */ - /* Randomize the projection to defend against multiplier sidechannels. */ - secp256k1_gej_rescale(&ctx->initial, &s); - secp256k1_fe_clear(&s); - do { - secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); - secp256k1_scalar_set_b32(&b, nonce32, &retry); - /* A blinding value of 0 works, but would undermine the projection hardening. */ - retry |= secp256k1_scalar_is_zero(&b); - } while (retry); /* This branch true is cryptographically unreachable. Requires sha256_hmac output > order. */ - secp256k1_rfc6979_hmac_sha256_finalize(&rng); - memset(nonce32, 0, 32); - secp256k1_ecmult_gen(ctx, &gb, &b); - secp256k1_scalar_negate(&b, &b); - ctx->blind = b; - ctx->initial = gb; - secp256k1_scalar_clear(&b); - secp256k1_gej_clear(&gb); -} - -#endif /* SECP256K1_ECMULT_GEN_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/ecmult_impl.h b/util/secp256k1/depend/secp256k1/src/ecmult_impl.h deleted file mode 100644 index 93d3794cb4..0000000000 --- a/util/secp256k1/depend/secp256k1/src/ecmult_impl.h +++ /dev/null @@ -1,406 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_ECMULT_IMPL_H -#define SECP256K1_ECMULT_IMPL_H - -#include - -#include "group.h" -#include "scalar.h" -#include "ecmult.h" - -#if defined(EXHAUSTIVE_TEST_ORDER) -/* We need to lower these values for exhaustive tests because - * the tables cannot have infinities in them (this breaks the - * affine-isomorphism stuff which tracks z-ratios) */ -# if EXHAUSTIVE_TEST_ORDER > 128 -# define WINDOW_A 5 -# define WINDOW_G 8 -# elif EXHAUSTIVE_TEST_ORDER > 8 -# define WINDOW_A 4 -# define WINDOW_G 4 -# else -# define WINDOW_A 2 -# define WINDOW_G 2 -# endif -#else -/* optimal for 128-bit and 256-bit exponents. */ -#define WINDOW_A 5 -/** larger numbers may result in slightly better performance, at the cost of - exponentially larger precomputed tables. */ -#ifdef USE_ENDOMORPHISM -/** Two tables for window size 15: 1.375 MiB. */ -#define WINDOW_G 15 -#else -/** One table for window size 16: 1.375 MiB. */ -#define WINDOW_G 16 -#endif -#endif - -/** The number of entries a table with precomputed multiples needs to have. */ -#define ECMULT_TABLE_SIZE(w) (1 << ((w)-2)) - -/** Fill a table 'prej' with precomputed odd multiples of a. Prej will contain - * the values [1*a,3*a,...,(2*n-1)*a], so it space for n values. zr[0] will - * contain prej[0].z / a.z. The other zr[i] values = prej[i].z / prej[i-1].z. - * Prej's Z values are undefined, except for the last value. - */ -static void secp256k1_ecmult_odd_multiples_table(int n, secp256k1_gej *prej, secp256k1_fe *zr, const secp256k1_gej *a) { - secp256k1_gej d; - secp256k1_ge a_ge, d_ge; - int i; - - VERIFY_CHECK(!a->infinity); - - secp256k1_gej_double_var(&d, a, NULL); - - /* - * Perform the additions on an isomorphism where 'd' is affine: drop the z coordinate - * of 'd', and scale the 1P starting value's x/y coordinates without changing its z. - */ - d_ge.x = d.x; - d_ge.y = d.y; - d_ge.infinity = 0; - - secp256k1_ge_set_gej_zinv(&a_ge, a, &d.z); - prej[0].x = a_ge.x; - prej[0].y = a_ge.y; - prej[0].z = a->z; - prej[0].infinity = 0; - - zr[0] = d.z; - for (i = 1; i < n; i++) { - secp256k1_gej_add_ge_var(&prej[i], &prej[i-1], &d_ge, &zr[i]); - } - - /* - * Each point in 'prej' has a z coordinate too small by a factor of 'd.z'. Only - * the final point's z coordinate is actually used though, so just update that. - */ - secp256k1_fe_mul(&prej[n-1].z, &prej[n-1].z, &d.z); -} - -/** Fill a table 'pre' with precomputed odd multiples of a. - * - * There are two versions of this function: - * - secp256k1_ecmult_odd_multiples_table_globalz_windowa which brings its - * resulting point set to a single constant Z denominator, stores the X and Y - * coordinates as ge_storage points in pre, and stores the global Z in rz. - * It only operates on tables sized for WINDOW_A wnaf multiples. - * - secp256k1_ecmult_odd_multiples_table_storage_var, which converts its - * resulting point set to actually affine points, and stores those in pre. - * It operates on tables of any size, but uses heap-allocated temporaries. - * - * To compute a*P + b*G, we compute a table for P using the first function, - * and for G using the second (which requires an inverse, but it only needs to - * happen once). - */ -static void secp256k1_ecmult_odd_multiples_table_globalz_windowa(secp256k1_ge *pre, secp256k1_fe *globalz, const secp256k1_gej *a) { - secp256k1_gej prej[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_fe zr[ECMULT_TABLE_SIZE(WINDOW_A)]; - - /* Compute the odd multiples in Jacobian form. */ - secp256k1_ecmult_odd_multiples_table(ECMULT_TABLE_SIZE(WINDOW_A), prej, zr, a); - /* Bring them to the same Z denominator. */ - secp256k1_ge_globalz_set_table_gej(ECMULT_TABLE_SIZE(WINDOW_A), pre, globalz, prej, zr); -} - -static void secp256k1_ecmult_odd_multiples_table_storage_var(int n, secp256k1_ge_storage *pre, const secp256k1_gej *a, const secp256k1_callback *cb) { - secp256k1_gej *prej = (secp256k1_gej*)checked_malloc(cb, sizeof(secp256k1_gej) * n); - secp256k1_ge *prea = (secp256k1_ge*)checked_malloc(cb, sizeof(secp256k1_ge) * n); - secp256k1_fe *zr = (secp256k1_fe*)checked_malloc(cb, sizeof(secp256k1_fe) * n); - int i; - - /* Compute the odd multiples in Jacobian form. */ - secp256k1_ecmult_odd_multiples_table(n, prej, zr, a); - /* Convert them in batch to affine coordinates. */ - secp256k1_ge_set_table_gej_var(prea, prej, zr, n); - /* Convert them to compact storage form. */ - for (i = 0; i < n; i++) { - secp256k1_ge_to_storage(&pre[i], &prea[i]); - } - - free(prea); - free(prej); - free(zr); -} - -/** The following two macro retrieves a particular odd multiple from a table - * of precomputed multiples. */ -#define ECMULT_TABLE_GET_GE(r,pre,n,w) do { \ - VERIFY_CHECK(((n) & 1) == 1); \ - VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ - VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ - if ((n) > 0) { \ - *(r) = (pre)[((n)-1)/2]; \ - } else { \ - secp256k1_ge_neg((r), &(pre)[(-(n)-1)/2]); \ - } \ -} while(0) - -#define ECMULT_TABLE_GET_GE_STORAGE(r,pre,n,w) do { \ - VERIFY_CHECK(((n) & 1) == 1); \ - VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ - VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ - if ((n) > 0) { \ - secp256k1_ge_from_storage((r), &(pre)[((n)-1)/2]); \ - } else { \ - secp256k1_ge_from_storage((r), &(pre)[(-(n)-1)/2]); \ - secp256k1_ge_neg((r), (r)); \ - } \ -} while(0) - -static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx) { - ctx->pre_g = NULL; -#ifdef USE_ENDOMORPHISM - ctx->pre_g_128 = NULL; -#endif -} - -static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb) { - secp256k1_gej gj; - - if (ctx->pre_g != NULL) { - return; - } - - /* get the generator */ - secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); - - ctx->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); - - /* precompute the tables with odd multiples */ - secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g, &gj, cb); - -#ifdef USE_ENDOMORPHISM - { - secp256k1_gej g_128j; - int i; - - ctx->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); - - /* calculate 2^128*generator */ - g_128j = gj; - for (i = 0; i < 128; i++) { - secp256k1_gej_double_var(&g_128j, &g_128j, NULL); - } - secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g_128, &g_128j, cb); - } -#endif -} - -static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, - const secp256k1_ecmult_context *src, const secp256k1_callback *cb) { - if (src->pre_g == NULL) { - dst->pre_g = NULL; - } else { - size_t size = sizeof((*dst->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G); - dst->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, size); - memcpy(dst->pre_g, src->pre_g, size); - } -#ifdef USE_ENDOMORPHISM - if (src->pre_g_128 == NULL) { - dst->pre_g_128 = NULL; - } else { - size_t size = sizeof((*dst->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G); - dst->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, size); - memcpy(dst->pre_g_128, src->pre_g_128, size); - } -#endif -} - -static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx) { - return ctx->pre_g != NULL; -} - -static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx) { - free(ctx->pre_g); -#ifdef USE_ENDOMORPHISM - free(ctx->pre_g_128); -#endif - secp256k1_ecmult_context_init(ctx); -} - -/** Convert a number to WNAF notation. The number becomes represented by sum(2^i * wnaf[i], i=0..bits), - * with the following guarantees: - * - each wnaf[i] is either 0, or an odd integer between -(1<<(w-1) - 1) and (1<<(w-1) - 1) - * - two non-zero entries in wnaf are separated by at least w-1 zeroes. - * - the number of set values in wnaf is returned. This number is at most 256, and at most one more - * than the number of bits in the (absolute value) of the input. - */ -static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar *a, int w) { - secp256k1_scalar s = *a; - int last_set_bit = -1; - int bit = 0; - int sign = 1; - int carry = 0; - - VERIFY_CHECK(wnaf != NULL); - VERIFY_CHECK(0 <= len && len <= 256); - VERIFY_CHECK(a != NULL); - VERIFY_CHECK(2 <= w && w <= 31); - - memset(wnaf, 0, len * sizeof(wnaf[0])); - - if (secp256k1_scalar_get_bits(&s, 255, 1)) { - secp256k1_scalar_negate(&s, &s); - sign = -1; - } - - while (bit < len) { - int now; - int word; - if (secp256k1_scalar_get_bits(&s, bit, 1) == (unsigned int)carry) { - bit++; - continue; - } - - now = w; - if (now > len - bit) { - now = len - bit; - } - - word = secp256k1_scalar_get_bits_var(&s, bit, now) + carry; - - carry = (word >> (w-1)) & 1; - word -= carry << w; - - wnaf[bit] = sign * word; - last_set_bit = bit; - - bit += now; - } -#ifdef VERIFY - CHECK(carry == 0); - while (bit < 256) { - CHECK(secp256k1_scalar_get_bits(&s, bit++, 1) == 0); - } -#endif - return last_set_bit + 1; -} - -static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng) { - secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_ge tmpa; - secp256k1_fe Z; -#ifdef USE_ENDOMORPHISM - secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_scalar na_1, na_lam; - /* Splitted G factors. */ - secp256k1_scalar ng_1, ng_128; - int wnaf_na_1[130]; - int wnaf_na_lam[130]; - int bits_na_1; - int bits_na_lam; - int wnaf_ng_1[129]; - int bits_ng_1; - int wnaf_ng_128[129]; - int bits_ng_128; -#else - int wnaf_na[256]; - int bits_na; - int wnaf_ng[256]; - int bits_ng; -#endif - int i; - int bits; - -#ifdef USE_ENDOMORPHISM - /* split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit) */ - secp256k1_scalar_split_lambda(&na_1, &na_lam, na); - - /* build wnaf representation for na_1 and na_lam. */ - bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, 130, &na_1, WINDOW_A); - bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, 130, &na_lam, WINDOW_A); - VERIFY_CHECK(bits_na_1 <= 130); - VERIFY_CHECK(bits_na_lam <= 130); - bits = bits_na_1; - if (bits_na_lam > bits) { - bits = bits_na_lam; - } -#else - /* build wnaf representation for na. */ - bits_na = secp256k1_ecmult_wnaf(wnaf_na, 256, na, WINDOW_A); - bits = bits_na; -#endif - - /* Calculate odd multiples of a. - * All multiples are brought to the same Z 'denominator', which is stored - * in Z. Due to secp256k1' isomorphism we can do all operations pretending - * that the Z coordinate was 1, use affine addition formulae, and correct - * the Z coordinate of the result once at the end. - * The exception is the precomputed G table points, which are actually - * affine. Compared to the base used for other points, they have a Z ratio - * of 1/Z, so we can use secp256k1_gej_add_zinv_var, which uses the same - * isomorphism to efficiently add with a known Z inverse. - */ - secp256k1_ecmult_odd_multiples_table_globalz_windowa(pre_a, &Z, a); - -#ifdef USE_ENDOMORPHISM - for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { - secp256k1_ge_mul_lambda(&pre_a_lam[i], &pre_a[i]); - } - - /* split ng into ng_1 and ng_128 (where gn = gn_1 + gn_128*2^128, and gn_1 and gn_128 are ~128 bit) */ - secp256k1_scalar_split_128(&ng_1, &ng_128, ng); - - /* Build wnaf representation for ng_1 and ng_128 */ - bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, 129, &ng_1, WINDOW_G); - bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, 129, &ng_128, WINDOW_G); - if (bits_ng_1 > bits) { - bits = bits_ng_1; - } - if (bits_ng_128 > bits) { - bits = bits_ng_128; - } -#else - bits_ng = secp256k1_ecmult_wnaf(wnaf_ng, 256, ng, WINDOW_G); - if (bits_ng > bits) { - bits = bits_ng; - } -#endif - - secp256k1_gej_set_infinity(r); - - for (i = bits - 1; i >= 0; i--) { - int n; - secp256k1_gej_double_var(r, r, NULL); -#ifdef USE_ENDOMORPHISM - if (i < bits_na_1 && (n = wnaf_na_1[i])) { - ECMULT_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); - secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); - } - if (i < bits_na_lam && (n = wnaf_na_lam[i])) { - ECMULT_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A); - secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); - } - if (i < bits_ng_1 && (n = wnaf_ng_1[i])) { - ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G); - secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); - } - if (i < bits_ng_128 && (n = wnaf_ng_128[i])) { - ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g_128, n, WINDOW_G); - secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); - } -#else - if (i < bits_na && (n = wnaf_na[i])) { - ECMULT_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); - secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); - } - if (i < bits_ng && (n = wnaf_ng[i])) { - ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G); - secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); - } -#endif - } - - if (!r->infinity) { - secp256k1_fe_mul(&r->z, &r->z, &Z); - } -} - -#endif /* SECP256K1_ECMULT_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/ext.c b/util/secp256k1/depend/secp256k1/src/ext.c deleted file mode 100644 index 885496a8f4..0000000000 --- a/util/secp256k1/depend/secp256k1/src/ext.c +++ /dev/null @@ -1,60 +0,0 @@ -/** @file ext.c - * Ethereum extensions to libecp256k1 - * @authors: - * Arkadiy Paronyan - * @date 2015 - */ - -#include "src/secp256k1.c" - -int secp256k1_ecdh_raw(const secp256k1_context* ctx, unsigned char *result, const secp256k1_pubkey *point, const unsigned char *scalar) -{ - int ret = 0; - int overflow = 0; - secp256k1_gej res; - secp256k1_ge pt; - secp256k1_scalar s; - ARG_CHECK(result != NULL); - ARG_CHECK(point != NULL); - ARG_CHECK(scalar != NULL); - - secp256k1_pubkey_load(ctx, &pt, point); - secp256k1_scalar_set_b32(&s, scalar, &overflow); - if (overflow || secp256k1_scalar_is_zero(&s)) - ret = 0; - else - { - secp256k1_ecmult_const(&res, &pt, &s); - secp256k1_ge_set_gej(&pt, &res); - secp256k1_fe_normalize(&pt.x); - secp256k1_fe_normalize(&pt.y); - secp256k1_fe_get_b32(result, &pt.x); - ret = 1; - } - - secp256k1_scalar_clear(&s); - return ret; -} - -/// Returns inverse (1 / n) of secret key `seckey` -int secp256k1_ec_privkey_inverse(const secp256k1_context* ctx, unsigned char *inversed, const unsigned char* seckey) { - secp256k1_scalar inv; - secp256k1_scalar sec; - int ret = 0; - int overflow = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(inversed != NULL); - ARG_CHECK(seckey != NULL); - - secp256k1_scalar_set_b32(&sec, seckey, NULL); - ret = !overflow; - if (ret) { - memset(inversed, 0, 32); - secp256k1_scalar_inverse(&inv, &sec); - secp256k1_scalar_get_b32(inversed, &inv); - } - - secp256k1_scalar_clear(&inv); - secp256k1_scalar_clear(&sec); - return ret; -} diff --git a/util/secp256k1/depend/secp256k1/src/field.h b/util/secp256k1/depend/secp256k1/src/field.h deleted file mode 100644 index bb6692ad57..0000000000 --- a/util/secp256k1/depend/secp256k1/src/field.h +++ /dev/null @@ -1,132 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_FIELD_H -#define SECP256K1_FIELD_H - -/** Field element module. - * - * Field elements can be represented in several ways, but code accessing - * it (and implementations) need to take certain properties into account: - * - Each field element can be normalized or not. - * - Each field element has a magnitude, which represents how far away - * its representation is away from normalization. Normalized elements - * always have a magnitude of 1, but a magnitude of 1 doesn't imply - * normality. - */ - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif - -#if defined(USE_FIELD_10X26) -#include "field_10x26.h" -#elif defined(USE_FIELD_5X52) -#include "field_5x52.h" -#else -#error "Please select field implementation" -#endif - -#include "util.h" - -/** Normalize a field element. */ -static void secp256k1_fe_normalize(secp256k1_fe *r); - -/** Weakly normalize a field element: reduce it magnitude to 1, but don't fully normalize. */ -static void secp256k1_fe_normalize_weak(secp256k1_fe *r); - -/** Normalize a field element, without constant-time guarantee. */ -static void secp256k1_fe_normalize_var(secp256k1_fe *r); - -/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field - * implementation may optionally normalize the input, but this should not be relied upon. */ -static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r); - -/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field - * implementation may optionally normalize the input, but this should not be relied upon. */ -static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r); - -/** Set a field element equal to a small integer. Resulting field element is normalized. */ -static void secp256k1_fe_set_int(secp256k1_fe *r, int a); - -/** Sets a field element equal to zero, initializing all fields. */ -static void secp256k1_fe_clear(secp256k1_fe *a); - -/** Verify whether a field element is zero. Requires the input to be normalized. */ -static int secp256k1_fe_is_zero(const secp256k1_fe *a); - -/** Check the "oddness" of a field element. Requires the input to be normalized. */ -static int secp256k1_fe_is_odd(const secp256k1_fe *a); - -/** Compare two field elements. Requires magnitude-1 inputs. */ -static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b); - -/** Same as secp256k1_fe_equal, but may be variable time. */ -static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b); - -/** Compare two field elements. Requires both inputs to be normalized */ -static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b); - -/** Set a field element equal to 32-byte big endian value. If successful, the resulting field element is normalized. */ -static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a); - -/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ -static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a); - -/** Set a field element equal to the additive inverse of another. Takes a maximum magnitude of the input - * as an argument. The magnitude of the output is one higher. */ -static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m); - -/** Multiplies the passed field element with a small integer constant. Multiplies the magnitude by that - * small integer. */ -static void secp256k1_fe_mul_int(secp256k1_fe *r, int a); - -/** Adds a field element to another. The result has the sum of the inputs' magnitudes as magnitude. */ -static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a); - -/** Sets a field element to be the product of two others. Requires the inputs' magnitudes to be at most 8. - * The output magnitude is 1 (but not guaranteed to be normalized). */ -static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b); - -/** Sets a field element to be the square of another. Requires the input's magnitude to be at most 8. - * The output magnitude is 1 (but not guaranteed to be normalized). */ -static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a); - -/** If a has a square root, it is computed in r and 1 is returned. If a does not - * have a square root, the root of its negation is computed and 0 is returned. - * The input's magnitude can be at most 8. The output magnitude is 1 (but not - * guaranteed to be normalized). The result in r will always be a square - * itself. */ -static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a); - -/** Checks whether a field element is a quadratic residue. */ -static int secp256k1_fe_is_quad_var(const secp256k1_fe *a); - -/** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be - * at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */ -static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a); - -/** Potentially faster version of secp256k1_fe_inv, without constant-time guarantee. */ -static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a); - -/** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be - * at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and - * outputs must not overlap in memory. */ -static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len); - -/** Convert a field element to the storage type. */ -static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a); - -/** Convert a field element back from the storage type. */ -static void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a); - -/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ -static void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag); - -/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ -static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag); - -#endif /* SECP256K1_FIELD_H */ diff --git a/util/secp256k1/depend/secp256k1/src/field_10x26.h b/util/secp256k1/depend/secp256k1/src/field_10x26.h deleted file mode 100644 index 727c5267fb..0000000000 --- a/util/secp256k1/depend/secp256k1/src/field_10x26.h +++ /dev/null @@ -1,48 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_FIELD_REPR_H -#define SECP256K1_FIELD_REPR_H - -#include - -typedef struct { - /* X = sum(i=0..9, elem[i]*2^26) mod n */ - uint32_t n[10]; -#ifdef VERIFY - int magnitude; - int normalized; -#endif -} secp256k1_fe; - -/* Unpacks a constant into a overlapping multi-limbed FE element. */ -#define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ - (d0) & 0x3FFFFFFUL, \ - (((uint32_t)d0) >> 26) | (((uint32_t)(d1) & 0xFFFFFUL) << 6), \ - (((uint32_t)d1) >> 20) | (((uint32_t)(d2) & 0x3FFFUL) << 12), \ - (((uint32_t)d2) >> 14) | (((uint32_t)(d3) & 0xFFUL) << 18), \ - (((uint32_t)d3) >> 8) | (((uint32_t)(d4) & 0x3UL) << 24), \ - (((uint32_t)d4) >> 2) & 0x3FFFFFFUL, \ - (((uint32_t)d4) >> 28) | (((uint32_t)(d5) & 0x3FFFFFUL) << 4), \ - (((uint32_t)d5) >> 22) | (((uint32_t)(d6) & 0xFFFFUL) << 10), \ - (((uint32_t)d6) >> 16) | (((uint32_t)(d7) & 0x3FFUL) << 16), \ - (((uint32_t)d7) >> 10) \ -} - -#ifdef VERIFY -#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1} -#else -#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} -#endif - -typedef struct { - uint32_t n[8]; -} secp256k1_fe_storage; - -#define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }} -#define SECP256K1_FE_STORAGE_CONST_GET(d) d.n[7], d.n[6], d.n[5], d.n[4],d.n[3], d.n[2], d.n[1], d.n[0] - -#endif /* SECP256K1_FIELD_REPR_H */ diff --git a/util/secp256k1/depend/secp256k1/src/field_10x26_impl.h b/util/secp256k1/depend/secp256k1/src/field_10x26_impl.h deleted file mode 100644 index 94f8132fc8..0000000000 --- a/util/secp256k1/depend/secp256k1/src/field_10x26_impl.h +++ /dev/null @@ -1,1161 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_FIELD_REPR_IMPL_H -#define SECP256K1_FIELD_REPR_IMPL_H - -#include "util.h" -#include "num.h" -#include "field.h" - -#ifdef VERIFY -static void secp256k1_fe_verify(const secp256k1_fe *a) { - const uint32_t *d = a->n; - int m = a->normalized ? 1 : 2 * a->magnitude, r = 1; - r &= (d[0] <= 0x3FFFFFFUL * m); - r &= (d[1] <= 0x3FFFFFFUL * m); - r &= (d[2] <= 0x3FFFFFFUL * m); - r &= (d[3] <= 0x3FFFFFFUL * m); - r &= (d[4] <= 0x3FFFFFFUL * m); - r &= (d[5] <= 0x3FFFFFFUL * m); - r &= (d[6] <= 0x3FFFFFFUL * m); - r &= (d[7] <= 0x3FFFFFFUL * m); - r &= (d[8] <= 0x3FFFFFFUL * m); - r &= (d[9] <= 0x03FFFFFUL * m); - r &= (a->magnitude >= 0); - r &= (a->magnitude <= 32); - if (a->normalized) { - r &= (a->magnitude <= 1); - if (r && (d[9] == 0x03FFFFFUL)) { - uint32_t mid = d[8] & d[7] & d[6] & d[5] & d[4] & d[3] & d[2]; - if (mid == 0x3FFFFFFUL) { - r &= ((d[1] + 0x40UL + ((d[0] + 0x3D1UL) >> 26)) <= 0x3FFFFFFUL); - } - } - } - VERIFY_CHECK(r == 1); -} -#endif - -static void secp256k1_fe_normalize(secp256k1_fe *r) { - uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], - t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; - - /* Reduce t9 at the start so there will be at most a single carry from the first pass */ - uint32_t m; - uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; - - /* The first pass ensures the magnitude is 1, ... */ - t0 += x * 0x3D1UL; t1 += (x << 6); - t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; - t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; - t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2; - t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3; - t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4; - t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5; - t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6; - t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7; - t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8; - - /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ - VERIFY_CHECK(t9 >> 23 == 0); - - /* At most a single final reduction is needed; check if the value is >= the field characteristic */ - x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL) - & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL)); - - /* Apply the final reduction (for constant-time behaviour, we do it always) */ - t0 += x * 0x3D1UL; t1 += (x << 6); - t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; - t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; - t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; - t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; - t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; - t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; - t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; - t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; - t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; - - /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */ - VERIFY_CHECK(t9 >> 22 == x); - - /* Mask off the possible multiple of 2^256 from the final reduction */ - t9 &= 0x03FFFFFUL; - - r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; - r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; - -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif -} - -static void secp256k1_fe_normalize_weak(secp256k1_fe *r) { - uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], - t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; - - /* Reduce t9 at the start so there will be at most a single carry from the first pass */ - uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; - - /* The first pass ensures the magnitude is 1, ... */ - t0 += x * 0x3D1UL; t1 += (x << 6); - t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; - t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; - t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; - t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; - t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; - t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; - t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; - t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; - t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; - - /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ - VERIFY_CHECK(t9 >> 23 == 0); - - r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; - r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; - -#ifdef VERIFY - r->magnitude = 1; - secp256k1_fe_verify(r); -#endif -} - -static void secp256k1_fe_normalize_var(secp256k1_fe *r) { - uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], - t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; - - /* Reduce t9 at the start so there will be at most a single carry from the first pass */ - uint32_t m; - uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; - - /* The first pass ensures the magnitude is 1, ... */ - t0 += x * 0x3D1UL; t1 += (x << 6); - t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; - t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; - t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2; - t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3; - t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4; - t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5; - t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6; - t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7; - t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8; - - /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ - VERIFY_CHECK(t9 >> 23 == 0); - - /* At most a single final reduction is needed; check if the value is >= the field characteristic */ - x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL) - & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL)); - - if (x) { - t0 += 0x3D1UL; t1 += (x << 6); - t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; - t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; - t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; - t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; - t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; - t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; - t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; - t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; - t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; - - /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */ - VERIFY_CHECK(t9 >> 22 == x); - - /* Mask off the possible multiple of 2^256 from the final reduction */ - t9 &= 0x03FFFFFUL; - } - - r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; - r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; - -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif -} - -static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r) { - uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], - t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; - - /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ - uint32_t z0, z1; - - /* Reduce t9 at the start so there will be at most a single carry from the first pass */ - uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; - - /* The first pass ensures the magnitude is 1, ... */ - t0 += x * 0x3D1UL; t1 += (x << 6); - t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; z0 = t0; z1 = t0 ^ 0x3D0UL; - t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL; - t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2; - t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3; - t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4; - t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5; - t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6; - t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7; - t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8; - z0 |= t9; z1 &= t9 ^ 0x3C00000UL; - - /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ - VERIFY_CHECK(t9 >> 23 == 0); - - return (z0 == 0) | (z1 == 0x3FFFFFFUL); -} - -static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r) { - uint32_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9; - uint32_t z0, z1; - uint32_t x; - - t0 = r->n[0]; - t9 = r->n[9]; - - /* Reduce t9 at the start so there will be at most a single carry from the first pass */ - x = t9 >> 22; - - /* The first pass ensures the magnitude is 1, ... */ - t0 += x * 0x3D1UL; - - /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ - z0 = t0 & 0x3FFFFFFUL; - z1 = z0 ^ 0x3D0UL; - - /* Fast return path should catch the majority of cases */ - if ((z0 != 0UL) & (z1 != 0x3FFFFFFUL)) { - return 0; - } - - t1 = r->n[1]; - t2 = r->n[2]; - t3 = r->n[3]; - t4 = r->n[4]; - t5 = r->n[5]; - t6 = r->n[6]; - t7 = r->n[7]; - t8 = r->n[8]; - - t9 &= 0x03FFFFFUL; - t1 += (x << 6); - - t1 += (t0 >> 26); - t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL; - t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2; - t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3; - t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4; - t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5; - t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6; - t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7; - t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8; - z0 |= t9; z1 &= t9 ^ 0x3C00000UL; - - /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ - VERIFY_CHECK(t9 >> 23 == 0); - - return (z0 == 0) | (z1 == 0x3FFFFFFUL); -} - -SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe *r, int a) { - r->n[0] = a; - r->n[1] = r->n[2] = r->n[3] = r->n[4] = r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0; -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif -} - -SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe *a) { - const uint32_t *t = a->n; -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - secp256k1_fe_verify(a); -#endif - return (t[0] | t[1] | t[2] | t[3] | t[4] | t[5] | t[6] | t[7] | t[8] | t[9]) == 0; -} - -SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - secp256k1_fe_verify(a); -#endif - return a->n[0] & 1; -} - -SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe *a) { - int i; -#ifdef VERIFY - a->magnitude = 0; - a->normalized = 1; -#endif - for (i=0; i<10; i++) { - a->n[i] = 0; - } -} - -static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { - int i; -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - VERIFY_CHECK(b->normalized); - secp256k1_fe_verify(a); - secp256k1_fe_verify(b); -#endif - for (i = 9; i >= 0; i--) { - if (a->n[i] > b->n[i]) { - return 1; - } - if (a->n[i] < b->n[i]) { - return -1; - } - } - return 0; -} - -static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) { - r->n[0] = (uint32_t)a[31] | ((uint32_t)a[30] << 8) | ((uint32_t)a[29] << 16) | ((uint32_t)(a[28] & 0x3) << 24); - r->n[1] = (uint32_t)((a[28] >> 2) & 0x3f) | ((uint32_t)a[27] << 6) | ((uint32_t)a[26] << 14) | ((uint32_t)(a[25] & 0xf) << 22); - r->n[2] = (uint32_t)((a[25] >> 4) & 0xf) | ((uint32_t)a[24] << 4) | ((uint32_t)a[23] << 12) | ((uint32_t)(a[22] & 0x3f) << 20); - r->n[3] = (uint32_t)((a[22] >> 6) & 0x3) | ((uint32_t)a[21] << 2) | ((uint32_t)a[20] << 10) | ((uint32_t)a[19] << 18); - r->n[4] = (uint32_t)a[18] | ((uint32_t)a[17] << 8) | ((uint32_t)a[16] << 16) | ((uint32_t)(a[15] & 0x3) << 24); - r->n[5] = (uint32_t)((a[15] >> 2) & 0x3f) | ((uint32_t)a[14] << 6) | ((uint32_t)a[13] << 14) | ((uint32_t)(a[12] & 0xf) << 22); - r->n[6] = (uint32_t)((a[12] >> 4) & 0xf) | ((uint32_t)a[11] << 4) | ((uint32_t)a[10] << 12) | ((uint32_t)(a[9] & 0x3f) << 20); - r->n[7] = (uint32_t)((a[9] >> 6) & 0x3) | ((uint32_t)a[8] << 2) | ((uint32_t)a[7] << 10) | ((uint32_t)a[6] << 18); - r->n[8] = (uint32_t)a[5] | ((uint32_t)a[4] << 8) | ((uint32_t)a[3] << 16) | ((uint32_t)(a[2] & 0x3) << 24); - r->n[9] = (uint32_t)((a[2] >> 2) & 0x3f) | ((uint32_t)a[1] << 6) | ((uint32_t)a[0] << 14); - - if (r->n[9] == 0x3FFFFFUL && (r->n[8] & r->n[7] & r->n[6] & r->n[5] & r->n[4] & r->n[3] & r->n[2]) == 0x3FFFFFFUL && (r->n[1] + 0x40UL + ((r->n[0] + 0x3D1UL) >> 26)) > 0x3FFFFFFUL) { - return 0; - } -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif - return 1; -} - -/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ -static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - secp256k1_fe_verify(a); -#endif - r[0] = (a->n[9] >> 14) & 0xff; - r[1] = (a->n[9] >> 6) & 0xff; - r[2] = ((a->n[9] & 0x3F) << 2) | ((a->n[8] >> 24) & 0x3); - r[3] = (a->n[8] >> 16) & 0xff; - r[4] = (a->n[8] >> 8) & 0xff; - r[5] = a->n[8] & 0xff; - r[6] = (a->n[7] >> 18) & 0xff; - r[7] = (a->n[7] >> 10) & 0xff; - r[8] = (a->n[7] >> 2) & 0xff; - r[9] = ((a->n[7] & 0x3) << 6) | ((a->n[6] >> 20) & 0x3f); - r[10] = (a->n[6] >> 12) & 0xff; - r[11] = (a->n[6] >> 4) & 0xff; - r[12] = ((a->n[6] & 0xf) << 4) | ((a->n[5] >> 22) & 0xf); - r[13] = (a->n[5] >> 14) & 0xff; - r[14] = (a->n[5] >> 6) & 0xff; - r[15] = ((a->n[5] & 0x3f) << 2) | ((a->n[4] >> 24) & 0x3); - r[16] = (a->n[4] >> 16) & 0xff; - r[17] = (a->n[4] >> 8) & 0xff; - r[18] = a->n[4] & 0xff; - r[19] = (a->n[3] >> 18) & 0xff; - r[20] = (a->n[3] >> 10) & 0xff; - r[21] = (a->n[3] >> 2) & 0xff; - r[22] = ((a->n[3] & 0x3) << 6) | ((a->n[2] >> 20) & 0x3f); - r[23] = (a->n[2] >> 12) & 0xff; - r[24] = (a->n[2] >> 4) & 0xff; - r[25] = ((a->n[2] & 0xf) << 4) | ((a->n[1] >> 22) & 0xf); - r[26] = (a->n[1] >> 14) & 0xff; - r[27] = (a->n[1] >> 6) & 0xff; - r[28] = ((a->n[1] & 0x3f) << 2) | ((a->n[0] >> 24) & 0x3); - r[29] = (a->n[0] >> 16) & 0xff; - r[30] = (a->n[0] >> 8) & 0xff; - r[31] = a->n[0] & 0xff; -} - -SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { -#ifdef VERIFY - VERIFY_CHECK(a->magnitude <= m); - secp256k1_fe_verify(a); -#endif - r->n[0] = 0x3FFFC2FUL * 2 * (m + 1) - a->n[0]; - r->n[1] = 0x3FFFFBFUL * 2 * (m + 1) - a->n[1]; - r->n[2] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[2]; - r->n[3] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[3]; - r->n[4] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[4]; - r->n[5] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[5]; - r->n[6] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[6]; - r->n[7] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[7]; - r->n[8] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[8]; - r->n[9] = 0x03FFFFFUL * 2 * (m + 1) - a->n[9]; -#ifdef VERIFY - r->magnitude = m + 1; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif -} - -SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { - r->n[0] *= a; - r->n[1] *= a; - r->n[2] *= a; - r->n[3] *= a; - r->n[4] *= a; - r->n[5] *= a; - r->n[6] *= a; - r->n[7] *= a; - r->n[8] *= a; - r->n[9] *= a; -#ifdef VERIFY - r->magnitude *= a; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif -} - -SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a) { -#ifdef VERIFY - secp256k1_fe_verify(a); -#endif - r->n[0] += a->n[0]; - r->n[1] += a->n[1]; - r->n[2] += a->n[2]; - r->n[3] += a->n[3]; - r->n[4] += a->n[4]; - r->n[5] += a->n[5]; - r->n[6] += a->n[6]; - r->n[7] += a->n[7]; - r->n[8] += a->n[8]; - r->n[9] += a->n[9]; -#ifdef VERIFY - r->magnitude += a->magnitude; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif -} - -#if defined(USE_EXTERNAL_ASM) - -/* External assembler implementation */ -void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b); -void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a); - -#else - -#ifdef VERIFY -#define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0) -#else -#define VERIFY_BITS(x, n) do { } while(0) -#endif - -SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b) { - uint64_t c, d; - uint64_t u0, u1, u2, u3, u4, u5, u6, u7, u8; - uint32_t t9, t1, t0, t2, t3, t4, t5, t6, t7; - const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL; - - VERIFY_BITS(a[0], 30); - VERIFY_BITS(a[1], 30); - VERIFY_BITS(a[2], 30); - VERIFY_BITS(a[3], 30); - VERIFY_BITS(a[4], 30); - VERIFY_BITS(a[5], 30); - VERIFY_BITS(a[6], 30); - VERIFY_BITS(a[7], 30); - VERIFY_BITS(a[8], 30); - VERIFY_BITS(a[9], 26); - VERIFY_BITS(b[0], 30); - VERIFY_BITS(b[1], 30); - VERIFY_BITS(b[2], 30); - VERIFY_BITS(b[3], 30); - VERIFY_BITS(b[4], 30); - VERIFY_BITS(b[5], 30); - VERIFY_BITS(b[6], 30); - VERIFY_BITS(b[7], 30); - VERIFY_BITS(b[8], 30); - VERIFY_BITS(b[9], 26); - - /** [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n. - * px is a shorthand for sum(a[i]*b[x-i], i=0..x). - * Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0]. - */ - - d = (uint64_t)a[0] * b[9] - + (uint64_t)a[1] * b[8] - + (uint64_t)a[2] * b[7] - + (uint64_t)a[3] * b[6] - + (uint64_t)a[4] * b[5] - + (uint64_t)a[5] * b[4] - + (uint64_t)a[6] * b[3] - + (uint64_t)a[7] * b[2] - + (uint64_t)a[8] * b[1] - + (uint64_t)a[9] * b[0]; - /* VERIFY_BITS(d, 64); */ - /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ - t9 = d & M; d >>= 26; - VERIFY_BITS(t9, 26); - VERIFY_BITS(d, 38); - /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ - - c = (uint64_t)a[0] * b[0]; - VERIFY_BITS(c, 60); - /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */ - d += (uint64_t)a[1] * b[9] - + (uint64_t)a[2] * b[8] - + (uint64_t)a[3] * b[7] - + (uint64_t)a[4] * b[6] - + (uint64_t)a[5] * b[5] - + (uint64_t)a[6] * b[4] - + (uint64_t)a[7] * b[3] - + (uint64_t)a[8] * b[2] - + (uint64_t)a[9] * b[1]; - VERIFY_BITS(d, 63); - /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - u0 = d & M; d >>= 26; c += u0 * R0; - VERIFY_BITS(u0, 26); - VERIFY_BITS(d, 37); - VERIFY_BITS(c, 61); - /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - t0 = c & M; c >>= 26; c += u0 * R1; - VERIFY_BITS(t0, 26); - VERIFY_BITS(c, 37); - /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - - c += (uint64_t)a[0] * b[1] - + (uint64_t)a[1] * b[0]; - VERIFY_BITS(c, 62); - /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */ - d += (uint64_t)a[2] * b[9] - + (uint64_t)a[3] * b[8] - + (uint64_t)a[4] * b[7] - + (uint64_t)a[5] * b[6] - + (uint64_t)a[6] * b[5] - + (uint64_t)a[7] * b[4] - + (uint64_t)a[8] * b[3] - + (uint64_t)a[9] * b[2]; - VERIFY_BITS(d, 63); - /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - u1 = d & M; d >>= 26; c += u1 * R0; - VERIFY_BITS(u1, 26); - VERIFY_BITS(d, 37); - VERIFY_BITS(c, 63); - /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - t1 = c & M; c >>= 26; c += u1 * R1; - VERIFY_BITS(t1, 26); - VERIFY_BITS(c, 38); - /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - - c += (uint64_t)a[0] * b[2] - + (uint64_t)a[1] * b[1] - + (uint64_t)a[2] * b[0]; - VERIFY_BITS(c, 62); - /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - d += (uint64_t)a[3] * b[9] - + (uint64_t)a[4] * b[8] - + (uint64_t)a[5] * b[7] - + (uint64_t)a[6] * b[6] - + (uint64_t)a[7] * b[5] - + (uint64_t)a[8] * b[4] - + (uint64_t)a[9] * b[3]; - VERIFY_BITS(d, 63); - /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - u2 = d & M; d >>= 26; c += u2 * R0; - VERIFY_BITS(u2, 26); - VERIFY_BITS(d, 37); - VERIFY_BITS(c, 63); - /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - t2 = c & M; c >>= 26; c += u2 * R1; - VERIFY_BITS(t2, 26); - VERIFY_BITS(c, 38); - /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - - c += (uint64_t)a[0] * b[3] - + (uint64_t)a[1] * b[2] - + (uint64_t)a[2] * b[1] - + (uint64_t)a[3] * b[0]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - d += (uint64_t)a[4] * b[9] - + (uint64_t)a[5] * b[8] - + (uint64_t)a[6] * b[7] - + (uint64_t)a[7] * b[6] - + (uint64_t)a[8] * b[5] - + (uint64_t)a[9] * b[4]; - VERIFY_BITS(d, 63); - /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - u3 = d & M; d >>= 26; c += u3 * R0; - VERIFY_BITS(u3, 26); - VERIFY_BITS(d, 37); - /* VERIFY_BITS(c, 64); */ - /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - t3 = c & M; c >>= 26; c += u3 * R1; - VERIFY_BITS(t3, 26); - VERIFY_BITS(c, 39); - /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - - c += (uint64_t)a[0] * b[4] - + (uint64_t)a[1] * b[3] - + (uint64_t)a[2] * b[2] - + (uint64_t)a[3] * b[1] - + (uint64_t)a[4] * b[0]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - d += (uint64_t)a[5] * b[9] - + (uint64_t)a[6] * b[8] - + (uint64_t)a[7] * b[7] - + (uint64_t)a[8] * b[6] - + (uint64_t)a[9] * b[5]; - VERIFY_BITS(d, 62); - /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - u4 = d & M; d >>= 26; c += u4 * R0; - VERIFY_BITS(u4, 26); - VERIFY_BITS(d, 36); - /* VERIFY_BITS(c, 64); */ - /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - t4 = c & M; c >>= 26; c += u4 * R1; - VERIFY_BITS(t4, 26); - VERIFY_BITS(c, 39); - /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - - c += (uint64_t)a[0] * b[5] - + (uint64_t)a[1] * b[4] - + (uint64_t)a[2] * b[3] - + (uint64_t)a[3] * b[2] - + (uint64_t)a[4] * b[1] - + (uint64_t)a[5] * b[0]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)a[6] * b[9] - + (uint64_t)a[7] * b[8] - + (uint64_t)a[8] * b[7] - + (uint64_t)a[9] * b[6]; - VERIFY_BITS(d, 62); - /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - u5 = d & M; d >>= 26; c += u5 * R0; - VERIFY_BITS(u5, 26); - VERIFY_BITS(d, 36); - /* VERIFY_BITS(c, 64); */ - /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - t5 = c & M; c >>= 26; c += u5 * R1; - VERIFY_BITS(t5, 26); - VERIFY_BITS(c, 39); - /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - - c += (uint64_t)a[0] * b[6] - + (uint64_t)a[1] * b[5] - + (uint64_t)a[2] * b[4] - + (uint64_t)a[3] * b[3] - + (uint64_t)a[4] * b[2] - + (uint64_t)a[5] * b[1] - + (uint64_t)a[6] * b[0]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)a[7] * b[9] - + (uint64_t)a[8] * b[8] - + (uint64_t)a[9] * b[7]; - VERIFY_BITS(d, 61); - /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - u6 = d & M; d >>= 26; c += u6 * R0; - VERIFY_BITS(u6, 26); - VERIFY_BITS(d, 35); - /* VERIFY_BITS(c, 64); */ - /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - t6 = c & M; c >>= 26; c += u6 * R1; - VERIFY_BITS(t6, 26); - VERIFY_BITS(c, 39); - /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - - c += (uint64_t)a[0] * b[7] - + (uint64_t)a[1] * b[6] - + (uint64_t)a[2] * b[5] - + (uint64_t)a[3] * b[4] - + (uint64_t)a[4] * b[3] - + (uint64_t)a[5] * b[2] - + (uint64_t)a[6] * b[1] - + (uint64_t)a[7] * b[0]; - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x8000007C00000007ULL); - /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)a[8] * b[9] - + (uint64_t)a[9] * b[8]; - VERIFY_BITS(d, 58); - /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - u7 = d & M; d >>= 26; c += u7 * R0; - VERIFY_BITS(u7, 26); - VERIFY_BITS(d, 32); - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL); - /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - t7 = c & M; c >>= 26; c += u7 * R1; - VERIFY_BITS(t7, 26); - VERIFY_BITS(c, 38); - /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - - c += (uint64_t)a[0] * b[8] - + (uint64_t)a[1] * b[7] - + (uint64_t)a[2] * b[6] - + (uint64_t)a[3] * b[5] - + (uint64_t)a[4] * b[4] - + (uint64_t)a[5] * b[3] - + (uint64_t)a[6] * b[2] - + (uint64_t)a[7] * b[1] - + (uint64_t)a[8] * b[0]; - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x9000007B80000008ULL); - /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)a[9] * b[9]; - VERIFY_BITS(d, 57); - /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - u8 = d & M; d >>= 26; c += u8 * R0; - VERIFY_BITS(u8, 26); - VERIFY_BITS(d, 31); - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x9000016FBFFFC2F8ULL); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - - r[3] = t3; - VERIFY_BITS(r[3], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[4] = t4; - VERIFY_BITS(r[4], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[5] = t5; - VERIFY_BITS(r[5], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[6] = t6; - VERIFY_BITS(r[6], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[7] = t7; - VERIFY_BITS(r[7], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - - r[8] = c & M; c >>= 26; c += u8 * R1; - VERIFY_BITS(r[8], 26); - VERIFY_BITS(c, 39); - /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += d * R0 + t9; - VERIFY_BITS(c, 45); - /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[9] = c & (M >> 4); c >>= 22; c += d * (R1 << 4); - VERIFY_BITS(r[9], 22); - VERIFY_BITS(c, 46); - /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - - d = c * (R0 >> 4) + t0; - VERIFY_BITS(d, 56); - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[0] = d & M; d >>= 26; - VERIFY_BITS(r[0], 26); - VERIFY_BITS(d, 30); - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += c * (R1 >> 4) + t1; - VERIFY_BITS(d, 53); - VERIFY_CHECK(d <= 0x10000003FFFFBFULL); - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[1] = d & M; d >>= 26; - VERIFY_BITS(r[1], 26); - VERIFY_BITS(d, 27); - VERIFY_CHECK(d <= 0x4000000ULL); - /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += t2; - VERIFY_BITS(d, 27); - /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[2] = d; - VERIFY_BITS(r[2], 27); - /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ -} - -SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a) { - uint64_t c, d; - uint64_t u0, u1, u2, u3, u4, u5, u6, u7, u8; - uint32_t t9, t0, t1, t2, t3, t4, t5, t6, t7; - const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL; - - VERIFY_BITS(a[0], 30); - VERIFY_BITS(a[1], 30); - VERIFY_BITS(a[2], 30); - VERIFY_BITS(a[3], 30); - VERIFY_BITS(a[4], 30); - VERIFY_BITS(a[5], 30); - VERIFY_BITS(a[6], 30); - VERIFY_BITS(a[7], 30); - VERIFY_BITS(a[8], 30); - VERIFY_BITS(a[9], 26); - - /** [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n. - * px is a shorthand for sum(a[i]*a[x-i], i=0..x). - * Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0]. - */ - - d = (uint64_t)(a[0]*2) * a[9] - + (uint64_t)(a[1]*2) * a[8] - + (uint64_t)(a[2]*2) * a[7] - + (uint64_t)(a[3]*2) * a[6] - + (uint64_t)(a[4]*2) * a[5]; - /* VERIFY_BITS(d, 64); */ - /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ - t9 = d & M; d >>= 26; - VERIFY_BITS(t9, 26); - VERIFY_BITS(d, 38); - /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ - - c = (uint64_t)a[0] * a[0]; - VERIFY_BITS(c, 60); - /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */ - d += (uint64_t)(a[1]*2) * a[9] - + (uint64_t)(a[2]*2) * a[8] - + (uint64_t)(a[3]*2) * a[7] - + (uint64_t)(a[4]*2) * a[6] - + (uint64_t)a[5] * a[5]; - VERIFY_BITS(d, 63); - /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - u0 = d & M; d >>= 26; c += u0 * R0; - VERIFY_BITS(u0, 26); - VERIFY_BITS(d, 37); - VERIFY_BITS(c, 61); - /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - t0 = c & M; c >>= 26; c += u0 * R1; - VERIFY_BITS(t0, 26); - VERIFY_BITS(c, 37); - /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ - - c += (uint64_t)(a[0]*2) * a[1]; - VERIFY_BITS(c, 62); - /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */ - d += (uint64_t)(a[2]*2) * a[9] - + (uint64_t)(a[3]*2) * a[8] - + (uint64_t)(a[4]*2) * a[7] - + (uint64_t)(a[5]*2) * a[6]; - VERIFY_BITS(d, 63); - /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - u1 = d & M; d >>= 26; c += u1 * R0; - VERIFY_BITS(u1, 26); - VERIFY_BITS(d, 37); - VERIFY_BITS(c, 63); - /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - t1 = c & M; c >>= 26; c += u1 * R1; - VERIFY_BITS(t1, 26); - VERIFY_BITS(c, 38); - /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ - - c += (uint64_t)(a[0]*2) * a[2] - + (uint64_t)a[1] * a[1]; - VERIFY_BITS(c, 62); - /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - d += (uint64_t)(a[3]*2) * a[9] - + (uint64_t)(a[4]*2) * a[8] - + (uint64_t)(a[5]*2) * a[7] - + (uint64_t)a[6] * a[6]; - VERIFY_BITS(d, 63); - /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - u2 = d & M; d >>= 26; c += u2 * R0; - VERIFY_BITS(u2, 26); - VERIFY_BITS(d, 37); - VERIFY_BITS(c, 63); - /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - t2 = c & M; c >>= 26; c += u2 * R1; - VERIFY_BITS(t2, 26); - VERIFY_BITS(c, 38); - /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ - - c += (uint64_t)(a[0]*2) * a[3] - + (uint64_t)(a[1]*2) * a[2]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - d += (uint64_t)(a[4]*2) * a[9] - + (uint64_t)(a[5]*2) * a[8] - + (uint64_t)(a[6]*2) * a[7]; - VERIFY_BITS(d, 63); - /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - u3 = d & M; d >>= 26; c += u3 * R0; - VERIFY_BITS(u3, 26); - VERIFY_BITS(d, 37); - /* VERIFY_BITS(c, 64); */ - /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - t3 = c & M; c >>= 26; c += u3 * R1; - VERIFY_BITS(t3, 26); - VERIFY_BITS(c, 39); - /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ - - c += (uint64_t)(a[0]*2) * a[4] - + (uint64_t)(a[1]*2) * a[3] - + (uint64_t)a[2] * a[2]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - d += (uint64_t)(a[5]*2) * a[9] - + (uint64_t)(a[6]*2) * a[8] - + (uint64_t)a[7] * a[7]; - VERIFY_BITS(d, 62); - /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - u4 = d & M; d >>= 26; c += u4 * R0; - VERIFY_BITS(u4, 26); - VERIFY_BITS(d, 36); - /* VERIFY_BITS(c, 64); */ - /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - t4 = c & M; c >>= 26; c += u4 * R1; - VERIFY_BITS(t4, 26); - VERIFY_BITS(c, 39); - /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ - - c += (uint64_t)(a[0]*2) * a[5] - + (uint64_t)(a[1]*2) * a[4] - + (uint64_t)(a[2]*2) * a[3]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)(a[6]*2) * a[9] - + (uint64_t)(a[7]*2) * a[8]; - VERIFY_BITS(d, 62); - /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - u5 = d & M; d >>= 26; c += u5 * R0; - VERIFY_BITS(u5, 26); - VERIFY_BITS(d, 36); - /* VERIFY_BITS(c, 64); */ - /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - t5 = c & M; c >>= 26; c += u5 * R1; - VERIFY_BITS(t5, 26); - VERIFY_BITS(c, 39); - /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ - - c += (uint64_t)(a[0]*2) * a[6] - + (uint64_t)(a[1]*2) * a[5] - + (uint64_t)(a[2]*2) * a[4] - + (uint64_t)a[3] * a[3]; - VERIFY_BITS(c, 63); - /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)(a[7]*2) * a[9] - + (uint64_t)a[8] * a[8]; - VERIFY_BITS(d, 61); - /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - u6 = d & M; d >>= 26; c += u6 * R0; - VERIFY_BITS(u6, 26); - VERIFY_BITS(d, 35); - /* VERIFY_BITS(c, 64); */ - /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - t6 = c & M; c >>= 26; c += u6 * R1; - VERIFY_BITS(t6, 26); - VERIFY_BITS(c, 39); - /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ - - c += (uint64_t)(a[0]*2) * a[7] - + (uint64_t)(a[1]*2) * a[6] - + (uint64_t)(a[2]*2) * a[5] - + (uint64_t)(a[3]*2) * a[4]; - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x8000007C00000007ULL); - /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)(a[8]*2) * a[9]; - VERIFY_BITS(d, 58); - /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - u7 = d & M; d >>= 26; c += u7 * R0; - VERIFY_BITS(u7, 26); - VERIFY_BITS(d, 32); - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL); - /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - t7 = c & M; c >>= 26; c += u7 * R1; - VERIFY_BITS(t7, 26); - VERIFY_BITS(c, 38); - /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ - - c += (uint64_t)(a[0]*2) * a[8] - + (uint64_t)(a[1]*2) * a[7] - + (uint64_t)(a[2]*2) * a[6] - + (uint64_t)(a[3]*2) * a[5] - + (uint64_t)a[4] * a[4]; - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x9000007B80000008ULL); - /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint64_t)a[9] * a[9]; - VERIFY_BITS(d, 57); - /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - u8 = d & M; d >>= 26; c += u8 * R0; - VERIFY_BITS(u8, 26); - VERIFY_BITS(d, 31); - /* VERIFY_BITS(c, 64); */ - VERIFY_CHECK(c <= 0x9000016FBFFFC2F8ULL); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - - r[3] = t3; - VERIFY_BITS(r[3], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[4] = t4; - VERIFY_BITS(r[4], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[5] = t5; - VERIFY_BITS(r[5], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[6] = t6; - VERIFY_BITS(r[6], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[7] = t7; - VERIFY_BITS(r[7], 26); - /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - - r[8] = c & M; c >>= 26; c += u8 * R1; - VERIFY_BITS(r[8], 26); - VERIFY_BITS(c, 39); - /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += d * R0 + t9; - VERIFY_BITS(c, 45); - /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[9] = c & (M >> 4); c >>= 22; c += d * (R1 << 4); - VERIFY_BITS(r[9], 22); - VERIFY_BITS(c, 46); - /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - - d = c * (R0 >> 4) + t0; - VERIFY_BITS(d, 56); - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[0] = d & M; d >>= 26; - VERIFY_BITS(r[0], 26); - VERIFY_BITS(d, 30); - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += c * (R1 >> 4) + t1; - VERIFY_BITS(d, 53); - VERIFY_CHECK(d <= 0x10000003FFFFBFULL); - /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[1] = d & M; d >>= 26; - VERIFY_BITS(r[1], 26); - VERIFY_BITS(d, 27); - VERIFY_CHECK(d <= 0x4000000ULL); - /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - d += t2; - VERIFY_BITS(d, 27); - /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[2] = d; - VERIFY_BITS(r[2], 27); - /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ -} -#endif - -static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { -#ifdef VERIFY - VERIFY_CHECK(a->magnitude <= 8); - VERIFY_CHECK(b->magnitude <= 8); - secp256k1_fe_verify(a); - secp256k1_fe_verify(b); - VERIFY_CHECK(r != b); -#endif - secp256k1_fe_mul_inner(r->n, a->n, b->n); -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif -} - -static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->magnitude <= 8); - secp256k1_fe_verify(a); -#endif - secp256k1_fe_sqr_inner(r->n, a->n); -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif -} - -static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { - uint32_t mask0, mask1; - mask0 = flag + ~((uint32_t)0); - mask1 = ~mask0; - r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); - r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); - r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); - r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); - r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); - r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1); - r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1); - r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1); - r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1); - r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1); -#ifdef VERIFY - if (a->magnitude > r->magnitude) { - r->magnitude = a->magnitude; - } - r->normalized &= a->normalized; -#endif -} - -static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { - uint32_t mask0, mask1; - mask0 = flag + ~((uint32_t)0); - mask1 = ~mask0; - r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); - r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); - r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); - r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); - r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); - r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1); - r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1); - r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1); -} - -static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->normalized); -#endif - r->n[0] = a->n[0] | a->n[1] << 26; - r->n[1] = a->n[1] >> 6 | a->n[2] << 20; - r->n[2] = a->n[2] >> 12 | a->n[3] << 14; - r->n[3] = a->n[3] >> 18 | a->n[4] << 8; - r->n[4] = a->n[4] >> 24 | a->n[5] << 2 | a->n[6] << 28; - r->n[5] = a->n[6] >> 4 | a->n[7] << 22; - r->n[6] = a->n[7] >> 10 | a->n[8] << 16; - r->n[7] = a->n[8] >> 16 | a->n[9] << 10; -} - -static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a) { - r->n[0] = a->n[0] & 0x3FFFFFFUL; - r->n[1] = a->n[0] >> 26 | ((a->n[1] << 6) & 0x3FFFFFFUL); - r->n[2] = a->n[1] >> 20 | ((a->n[2] << 12) & 0x3FFFFFFUL); - r->n[3] = a->n[2] >> 14 | ((a->n[3] << 18) & 0x3FFFFFFUL); - r->n[4] = a->n[3] >> 8 | ((a->n[4] << 24) & 0x3FFFFFFUL); - r->n[5] = (a->n[4] >> 2) & 0x3FFFFFFUL; - r->n[6] = a->n[4] >> 28 | ((a->n[5] << 4) & 0x3FFFFFFUL); - r->n[7] = a->n[5] >> 22 | ((a->n[6] << 10) & 0x3FFFFFFUL); - r->n[8] = a->n[6] >> 16 | ((a->n[7] << 16) & 0x3FFFFFFUL); - r->n[9] = a->n[7] >> 10; -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; -#endif -} - -#endif /* SECP256K1_FIELD_REPR_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/field_5x52.h b/util/secp256k1/depend/secp256k1/src/field_5x52.h deleted file mode 100644 index bccd8feb4d..0000000000 --- a/util/secp256k1/depend/secp256k1/src/field_5x52.h +++ /dev/null @@ -1,47 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_FIELD_REPR_H -#define SECP256K1_FIELD_REPR_H - -#include - -typedef struct { - /* X = sum(i=0..4, elem[i]*2^52) mod n */ - uint64_t n[5]; -#ifdef VERIFY - int magnitude; - int normalized; -#endif -} secp256k1_fe; - -/* Unpacks a constant into a overlapping multi-limbed FE element. */ -#define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ - (d0) | (((uint64_t)(d1) & 0xFFFFFUL) << 32), \ - ((uint64_t)(d1) >> 20) | (((uint64_t)(d2)) << 12) | (((uint64_t)(d3) & 0xFFUL) << 44), \ - ((uint64_t)(d3) >> 8) | (((uint64_t)(d4) & 0xFFFFFFFUL) << 24), \ - ((uint64_t)(d4) >> 28) | (((uint64_t)(d5)) << 4) | (((uint64_t)(d6) & 0xFFFFUL) << 36), \ - ((uint64_t)(d6) >> 16) | (((uint64_t)(d7)) << 16) \ -} - -#ifdef VERIFY -#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1} -#else -#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} -#endif - -typedef struct { - uint64_t n[4]; -} secp256k1_fe_storage; - -#define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ \ - (d0) | (((uint64_t)(d1)) << 32), \ - (d2) | (((uint64_t)(d3)) << 32), \ - (d4) | (((uint64_t)(d5)) << 32), \ - (d6) | (((uint64_t)(d7)) << 32) \ -}} - -#endif /* SECP256K1_FIELD_REPR_H */ diff --git a/util/secp256k1/depend/secp256k1/src/field_5x52_asm_impl.h b/util/secp256k1/depend/secp256k1/src/field_5x52_asm_impl.h deleted file mode 100644 index 1fc3171f6b..0000000000 --- a/util/secp256k1/depend/secp256k1/src/field_5x52_asm_impl.h +++ /dev/null @@ -1,502 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013-2014 Diederik Huys, Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -/** - * Changelog: - * - March 2013, Diederik Huys: original version - * - November 2014, Pieter Wuille: updated to use Peter Dettman's parallel multiplication algorithm - * - December 2014, Pieter Wuille: converted from YASM to GCC inline assembly - */ - -#ifndef SECP256K1_FIELD_INNER5X52_IMPL_H -#define SECP256K1_FIELD_INNER5X52_IMPL_H - -SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) { -/** - * Registers: rdx:rax = multiplication accumulator - * r9:r8 = c - * r15:rcx = d - * r10-r14 = a0-a4 - * rbx = b - * rdi = r - * rsi = a / t? - */ - uint64_t tmp1, tmp2, tmp3; -__asm__ __volatile__( - "movq 0(%%rsi),%%r10\n" - "movq 8(%%rsi),%%r11\n" - "movq 16(%%rsi),%%r12\n" - "movq 24(%%rsi),%%r13\n" - "movq 32(%%rsi),%%r14\n" - - /* d += a3 * b0 */ - "movq 0(%%rbx),%%rax\n" - "mulq %%r13\n" - "movq %%rax,%%rcx\n" - "movq %%rdx,%%r15\n" - /* d += a2 * b1 */ - "movq 8(%%rbx),%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a1 * b2 */ - "movq 16(%%rbx),%%rax\n" - "mulq %%r11\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d = a0 * b3 */ - "movq 24(%%rbx),%%rax\n" - "mulq %%r10\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* c = a4 * b4 */ - "movq 32(%%rbx),%%rax\n" - "mulq %%r14\n" - "movq %%rax,%%r8\n" - "movq %%rdx,%%r9\n" - /* d += (c & M) * R */ - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* c >>= 52 (%%r8 only) */ - "shrdq $52,%%r9,%%r8\n" - /* t3 (tmp1) = d & M */ - "movq %%rcx,%%rsi\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rsi\n" - "movq %%rsi,%q1\n" - /* d >>= 52 */ - "shrdq $52,%%r15,%%rcx\n" - "xorq %%r15,%%r15\n" - /* d += a4 * b0 */ - "movq 0(%%rbx),%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a3 * b1 */ - "movq 8(%%rbx),%%rax\n" - "mulq %%r13\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a2 * b2 */ - "movq 16(%%rbx),%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a1 * b3 */ - "movq 24(%%rbx),%%rax\n" - "mulq %%r11\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a0 * b4 */ - "movq 32(%%rbx),%%rax\n" - "mulq %%r10\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += c * R */ - "movq %%r8,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* t4 = d & M (%%rsi) */ - "movq %%rcx,%%rsi\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rsi\n" - /* d >>= 52 */ - "shrdq $52,%%r15,%%rcx\n" - "xorq %%r15,%%r15\n" - /* tx = t4 >> 48 (tmp3) */ - "movq %%rsi,%%rax\n" - "shrq $48,%%rax\n" - "movq %%rax,%q3\n" - /* t4 &= (M >> 4) (tmp2) */ - "movq $0xffffffffffff,%%rax\n" - "andq %%rax,%%rsi\n" - "movq %%rsi,%q2\n" - /* c = a0 * b0 */ - "movq 0(%%rbx),%%rax\n" - "mulq %%r10\n" - "movq %%rax,%%r8\n" - "movq %%rdx,%%r9\n" - /* d += a4 * b1 */ - "movq 8(%%rbx),%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a3 * b2 */ - "movq 16(%%rbx),%%rax\n" - "mulq %%r13\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a2 * b3 */ - "movq 24(%%rbx),%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a1 * b4 */ - "movq 32(%%rbx),%%rax\n" - "mulq %%r11\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* u0 = d & M (%%rsi) */ - "movq %%rcx,%%rsi\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rsi\n" - /* d >>= 52 */ - "shrdq $52,%%r15,%%rcx\n" - "xorq %%r15,%%r15\n" - /* u0 = (u0 << 4) | tx (%%rsi) */ - "shlq $4,%%rsi\n" - "movq %q3,%%rax\n" - "orq %%rax,%%rsi\n" - /* c += u0 * (R >> 4) */ - "movq $0x1000003d1,%%rax\n" - "mulq %%rsi\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* r[0] = c & M */ - "movq %%r8,%%rax\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rax\n" - "movq %%rax,0(%%rdi)\n" - /* c >>= 52 */ - "shrdq $52,%%r9,%%r8\n" - "xorq %%r9,%%r9\n" - /* c += a1 * b0 */ - "movq 0(%%rbx),%%rax\n" - "mulq %%r11\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* c += a0 * b1 */ - "movq 8(%%rbx),%%rax\n" - "mulq %%r10\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* d += a4 * b2 */ - "movq 16(%%rbx),%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a3 * b3 */ - "movq 24(%%rbx),%%rax\n" - "mulq %%r13\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a2 * b4 */ - "movq 32(%%rbx),%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* c += (d & M) * R */ - "movq %%rcx,%%rax\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* d >>= 52 */ - "shrdq $52,%%r15,%%rcx\n" - "xorq %%r15,%%r15\n" - /* r[1] = c & M */ - "movq %%r8,%%rax\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rax\n" - "movq %%rax,8(%%rdi)\n" - /* c >>= 52 */ - "shrdq $52,%%r9,%%r8\n" - "xorq %%r9,%%r9\n" - /* c += a2 * b0 */ - "movq 0(%%rbx),%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* c += a1 * b1 */ - "movq 8(%%rbx),%%rax\n" - "mulq %%r11\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* c += a0 * b2 (last use of %%r10 = a0) */ - "movq 16(%%rbx),%%rax\n" - "mulq %%r10\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* fetch t3 (%%r10, overwrites a0), t4 (%%rsi) */ - "movq %q2,%%rsi\n" - "movq %q1,%%r10\n" - /* d += a4 * b3 */ - "movq 24(%%rbx),%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* d += a3 * b4 */ - "movq 32(%%rbx),%%rax\n" - "mulq %%r13\n" - "addq %%rax,%%rcx\n" - "adcq %%rdx,%%r15\n" - /* c += (d & M) * R */ - "movq %%rcx,%%rax\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* d >>= 52 (%%rcx only) */ - "shrdq $52,%%r15,%%rcx\n" - /* r[2] = c & M */ - "movq %%r8,%%rax\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rax\n" - "movq %%rax,16(%%rdi)\n" - /* c >>= 52 */ - "shrdq $52,%%r9,%%r8\n" - "xorq %%r9,%%r9\n" - /* c += t3 */ - "addq %%r10,%%r8\n" - /* c += d * R */ - "movq %%rcx,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* r[3] = c & M */ - "movq %%r8,%%rax\n" - "movq $0xfffffffffffff,%%rdx\n" - "andq %%rdx,%%rax\n" - "movq %%rax,24(%%rdi)\n" - /* c >>= 52 (%%r8 only) */ - "shrdq $52,%%r9,%%r8\n" - /* c += t4 (%%r8 only) */ - "addq %%rsi,%%r8\n" - /* r[4] = c */ - "movq %%r8,32(%%rdi)\n" -: "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3) -: "b"(b), "D"(r) -: "%rax", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory" -); -} - -SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) { -/** - * Registers: rdx:rax = multiplication accumulator - * r9:r8 = c - * rcx:rbx = d - * r10-r14 = a0-a4 - * r15 = M (0xfffffffffffff) - * rdi = r - * rsi = a / t? - */ - uint64_t tmp1, tmp2, tmp3; -__asm__ __volatile__( - "movq 0(%%rsi),%%r10\n" - "movq 8(%%rsi),%%r11\n" - "movq 16(%%rsi),%%r12\n" - "movq 24(%%rsi),%%r13\n" - "movq 32(%%rsi),%%r14\n" - "movq $0xfffffffffffff,%%r15\n" - - /* d = (a0*2) * a3 */ - "leaq (%%r10,%%r10,1),%%rax\n" - "mulq %%r13\n" - "movq %%rax,%%rbx\n" - "movq %%rdx,%%rcx\n" - /* d += (a1*2) * a2 */ - "leaq (%%r11,%%r11,1),%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* c = a4 * a4 */ - "movq %%r14,%%rax\n" - "mulq %%r14\n" - "movq %%rax,%%r8\n" - "movq %%rdx,%%r9\n" - /* d += (c & M) * R */ - "andq %%r15,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* c >>= 52 (%%r8 only) */ - "shrdq $52,%%r9,%%r8\n" - /* t3 (tmp1) = d & M */ - "movq %%rbx,%%rsi\n" - "andq %%r15,%%rsi\n" - "movq %%rsi,%q1\n" - /* d >>= 52 */ - "shrdq $52,%%rcx,%%rbx\n" - "xorq %%rcx,%%rcx\n" - /* a4 *= 2 */ - "addq %%r14,%%r14\n" - /* d += a0 * a4 */ - "movq %%r10,%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* d+= (a1*2) * a3 */ - "leaq (%%r11,%%r11,1),%%rax\n" - "mulq %%r13\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* d += a2 * a2 */ - "movq %%r12,%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* d += c * R */ - "movq %%r8,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* t4 = d & M (%%rsi) */ - "movq %%rbx,%%rsi\n" - "andq %%r15,%%rsi\n" - /* d >>= 52 */ - "shrdq $52,%%rcx,%%rbx\n" - "xorq %%rcx,%%rcx\n" - /* tx = t4 >> 48 (tmp3) */ - "movq %%rsi,%%rax\n" - "shrq $48,%%rax\n" - "movq %%rax,%q3\n" - /* t4 &= (M >> 4) (tmp2) */ - "movq $0xffffffffffff,%%rax\n" - "andq %%rax,%%rsi\n" - "movq %%rsi,%q2\n" - /* c = a0 * a0 */ - "movq %%r10,%%rax\n" - "mulq %%r10\n" - "movq %%rax,%%r8\n" - "movq %%rdx,%%r9\n" - /* d += a1 * a4 */ - "movq %%r11,%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* d += (a2*2) * a3 */ - "leaq (%%r12,%%r12,1),%%rax\n" - "mulq %%r13\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* u0 = d & M (%%rsi) */ - "movq %%rbx,%%rsi\n" - "andq %%r15,%%rsi\n" - /* d >>= 52 */ - "shrdq $52,%%rcx,%%rbx\n" - "xorq %%rcx,%%rcx\n" - /* u0 = (u0 << 4) | tx (%%rsi) */ - "shlq $4,%%rsi\n" - "movq %q3,%%rax\n" - "orq %%rax,%%rsi\n" - /* c += u0 * (R >> 4) */ - "movq $0x1000003d1,%%rax\n" - "mulq %%rsi\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* r[0] = c & M */ - "movq %%r8,%%rax\n" - "andq %%r15,%%rax\n" - "movq %%rax,0(%%rdi)\n" - /* c >>= 52 */ - "shrdq $52,%%r9,%%r8\n" - "xorq %%r9,%%r9\n" - /* a0 *= 2 */ - "addq %%r10,%%r10\n" - /* c += a0 * a1 */ - "movq %%r10,%%rax\n" - "mulq %%r11\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* d += a2 * a4 */ - "movq %%r12,%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* d += a3 * a3 */ - "movq %%r13,%%rax\n" - "mulq %%r13\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* c += (d & M) * R */ - "movq %%rbx,%%rax\n" - "andq %%r15,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* d >>= 52 */ - "shrdq $52,%%rcx,%%rbx\n" - "xorq %%rcx,%%rcx\n" - /* r[1] = c & M */ - "movq %%r8,%%rax\n" - "andq %%r15,%%rax\n" - "movq %%rax,8(%%rdi)\n" - /* c >>= 52 */ - "shrdq $52,%%r9,%%r8\n" - "xorq %%r9,%%r9\n" - /* c += a0 * a2 (last use of %%r10) */ - "movq %%r10,%%rax\n" - "mulq %%r12\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* fetch t3 (%%r10, overwrites a0),t4 (%%rsi) */ - "movq %q2,%%rsi\n" - "movq %q1,%%r10\n" - /* c += a1 * a1 */ - "movq %%r11,%%rax\n" - "mulq %%r11\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* d += a3 * a4 */ - "movq %%r13,%%rax\n" - "mulq %%r14\n" - "addq %%rax,%%rbx\n" - "adcq %%rdx,%%rcx\n" - /* c += (d & M) * R */ - "movq %%rbx,%%rax\n" - "andq %%r15,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* d >>= 52 (%%rbx only) */ - "shrdq $52,%%rcx,%%rbx\n" - /* r[2] = c & M */ - "movq %%r8,%%rax\n" - "andq %%r15,%%rax\n" - "movq %%rax,16(%%rdi)\n" - /* c >>= 52 */ - "shrdq $52,%%r9,%%r8\n" - "xorq %%r9,%%r9\n" - /* c += t3 */ - "addq %%r10,%%r8\n" - /* c += d * R */ - "movq %%rbx,%%rax\n" - "movq $0x1000003d10,%%rdx\n" - "mulq %%rdx\n" - "addq %%rax,%%r8\n" - "adcq %%rdx,%%r9\n" - /* r[3] = c & M */ - "movq %%r8,%%rax\n" - "andq %%r15,%%rax\n" - "movq %%rax,24(%%rdi)\n" - /* c >>= 52 (%%r8 only) */ - "shrdq $52,%%r9,%%r8\n" - /* c += t4 (%%r8 only) */ - "addq %%rsi,%%r8\n" - /* r[4] = c */ - "movq %%r8,32(%%rdi)\n" -: "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3) -: "D"(r) -: "%rax", "%rbx", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory" -); -} - -#endif /* SECP256K1_FIELD_INNER5X52_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/field_5x52_impl.h b/util/secp256k1/depend/secp256k1/src/field_5x52_impl.h deleted file mode 100644 index 957c61b014..0000000000 --- a/util/secp256k1/depend/secp256k1/src/field_5x52_impl.h +++ /dev/null @@ -1,496 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_FIELD_REPR_IMPL_H -#define SECP256K1_FIELD_REPR_IMPL_H - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif - -#include "util.h" -#include "num.h" -#include "field.h" - -#if defined(USE_ASM_X86_64) -#include "field_5x52_asm_impl.h" -#else -#include "field_5x52_int128_impl.h" -#endif - -/** Implements arithmetic modulo FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F, - * represented as 5 uint64_t's in base 2^52. The values are allowed to contain >52 each. In particular, - * each FieldElem has a 'magnitude' associated with it. Internally, a magnitude M means each element - * is at most M*(2^53-1), except the most significant one, which is limited to M*(2^49-1). All operations - * accept any input with magnitude at most M, and have different rules for propagating magnitude to their - * output. - */ - -#ifdef VERIFY -static void secp256k1_fe_verify(const secp256k1_fe *a) { - const uint64_t *d = a->n; - int m = a->normalized ? 1 : 2 * a->magnitude, r = 1; - /* secp256k1 'p' value defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ - r &= (d[0] <= 0xFFFFFFFFFFFFFULL * m); - r &= (d[1] <= 0xFFFFFFFFFFFFFULL * m); - r &= (d[2] <= 0xFFFFFFFFFFFFFULL * m); - r &= (d[3] <= 0xFFFFFFFFFFFFFULL * m); - r &= (d[4] <= 0x0FFFFFFFFFFFFULL * m); - r &= (a->magnitude >= 0); - r &= (a->magnitude <= 2048); - if (a->normalized) { - r &= (a->magnitude <= 1); - if (r && (d[4] == 0x0FFFFFFFFFFFFULL) && ((d[3] & d[2] & d[1]) == 0xFFFFFFFFFFFFFULL)) { - r &= (d[0] < 0xFFFFEFFFFFC2FULL); - } - } - VERIFY_CHECK(r == 1); -} -#endif - -static void secp256k1_fe_normalize(secp256k1_fe *r) { - uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; - - /* Reduce t4 at the start so there will be at most a single carry from the first pass */ - uint64_t m; - uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; - - /* The first pass ensures the magnitude is 1, ... */ - t0 += x * 0x1000003D1ULL; - t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; - t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; m = t1; - t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; m &= t2; - t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; m &= t3; - - /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ - VERIFY_CHECK(t4 >> 49 == 0); - - /* At most a single final reduction is needed; check if the value is >= the field characteristic */ - x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL) & (m == 0xFFFFFFFFFFFFFULL) - & (t0 >= 0xFFFFEFFFFFC2FULL)); - - /* Apply the final reduction (for constant-time behaviour, we do it always) */ - t0 += x * 0x1000003D1ULL; - t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; - t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; - t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; - t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; - - /* If t4 didn't carry to bit 48 already, then it should have after any final reduction */ - VERIFY_CHECK(t4 >> 48 == x); - - /* Mask off the possible multiple of 2^256 from the final reduction */ - t4 &= 0x0FFFFFFFFFFFFULL; - - r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; - -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif -} - -static void secp256k1_fe_normalize_weak(secp256k1_fe *r) { - uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; - - /* Reduce t4 at the start so there will be at most a single carry from the first pass */ - uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; - - /* The first pass ensures the magnitude is 1, ... */ - t0 += x * 0x1000003D1ULL; - t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; - t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; - t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; - t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; - - /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ - VERIFY_CHECK(t4 >> 49 == 0); - - r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; - -#ifdef VERIFY - r->magnitude = 1; - secp256k1_fe_verify(r); -#endif -} - -static void secp256k1_fe_normalize_var(secp256k1_fe *r) { - uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; - - /* Reduce t4 at the start so there will be at most a single carry from the first pass */ - uint64_t m; - uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; - - /* The first pass ensures the magnitude is 1, ... */ - t0 += x * 0x1000003D1ULL; - t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; - t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; m = t1; - t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; m &= t2; - t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; m &= t3; - - /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ - VERIFY_CHECK(t4 >> 49 == 0); - - /* At most a single final reduction is needed; check if the value is >= the field characteristic */ - x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL) & (m == 0xFFFFFFFFFFFFFULL) - & (t0 >= 0xFFFFEFFFFFC2FULL)); - - if (x) { - t0 += 0x1000003D1ULL; - t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; - t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; - t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; - t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; - - /* If t4 didn't carry to bit 48 already, then it should have after any final reduction */ - VERIFY_CHECK(t4 >> 48 == x); - - /* Mask off the possible multiple of 2^256 from the final reduction */ - t4 &= 0x0FFFFFFFFFFFFULL; - } - - r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; - -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif -} - -static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r) { - uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; - - /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ - uint64_t z0, z1; - - /* Reduce t4 at the start so there will be at most a single carry from the first pass */ - uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; - - /* The first pass ensures the magnitude is 1, ... */ - t0 += x * 0x1000003D1ULL; - t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; z0 = t0; z1 = t0 ^ 0x1000003D0ULL; - t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1; - t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2; - t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3; - z0 |= t4; z1 &= t4 ^ 0xF000000000000ULL; - - /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ - VERIFY_CHECK(t4 >> 49 == 0); - - return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL); -} - -static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r) { - uint64_t t0, t1, t2, t3, t4; - uint64_t z0, z1; - uint64_t x; - - t0 = r->n[0]; - t4 = r->n[4]; - - /* Reduce t4 at the start so there will be at most a single carry from the first pass */ - x = t4 >> 48; - - /* The first pass ensures the magnitude is 1, ... */ - t0 += x * 0x1000003D1ULL; - - /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ - z0 = t0 & 0xFFFFFFFFFFFFFULL; - z1 = z0 ^ 0x1000003D0ULL; - - /* Fast return path should catch the majority of cases */ - if ((z0 != 0ULL) & (z1 != 0xFFFFFFFFFFFFFULL)) { - return 0; - } - - t1 = r->n[1]; - t2 = r->n[2]; - t3 = r->n[3]; - - t4 &= 0x0FFFFFFFFFFFFULL; - - t1 += (t0 >> 52); - t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1; - t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2; - t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3; - z0 |= t4; z1 &= t4 ^ 0xF000000000000ULL; - - /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ - VERIFY_CHECK(t4 >> 49 == 0); - - return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL); -} - -SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe *r, int a) { - r->n[0] = a; - r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif -} - -SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe *a) { - const uint64_t *t = a->n; -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - secp256k1_fe_verify(a); -#endif - return (t[0] | t[1] | t[2] | t[3] | t[4]) == 0; -} - -SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - secp256k1_fe_verify(a); -#endif - return a->n[0] & 1; -} - -SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe *a) { - int i; -#ifdef VERIFY - a->magnitude = 0; - a->normalized = 1; -#endif - for (i=0; i<5; i++) { - a->n[i] = 0; - } -} - -static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { - int i; -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - VERIFY_CHECK(b->normalized); - secp256k1_fe_verify(a); - secp256k1_fe_verify(b); -#endif - for (i = 4; i >= 0; i--) { - if (a->n[i] > b->n[i]) { - return 1; - } - if (a->n[i] < b->n[i]) { - return -1; - } - } - return 0; -} - -static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) { - r->n[0] = (uint64_t)a[31] - | ((uint64_t)a[30] << 8) - | ((uint64_t)a[29] << 16) - | ((uint64_t)a[28] << 24) - | ((uint64_t)a[27] << 32) - | ((uint64_t)a[26] << 40) - | ((uint64_t)(a[25] & 0xF) << 48); - r->n[1] = (uint64_t)((a[25] >> 4) & 0xF) - | ((uint64_t)a[24] << 4) - | ((uint64_t)a[23] << 12) - | ((uint64_t)a[22] << 20) - | ((uint64_t)a[21] << 28) - | ((uint64_t)a[20] << 36) - | ((uint64_t)a[19] << 44); - r->n[2] = (uint64_t)a[18] - | ((uint64_t)a[17] << 8) - | ((uint64_t)a[16] << 16) - | ((uint64_t)a[15] << 24) - | ((uint64_t)a[14] << 32) - | ((uint64_t)a[13] << 40) - | ((uint64_t)(a[12] & 0xF) << 48); - r->n[3] = (uint64_t)((a[12] >> 4) & 0xF) - | ((uint64_t)a[11] << 4) - | ((uint64_t)a[10] << 12) - | ((uint64_t)a[9] << 20) - | ((uint64_t)a[8] << 28) - | ((uint64_t)a[7] << 36) - | ((uint64_t)a[6] << 44); - r->n[4] = (uint64_t)a[5] - | ((uint64_t)a[4] << 8) - | ((uint64_t)a[3] << 16) - | ((uint64_t)a[2] << 24) - | ((uint64_t)a[1] << 32) - | ((uint64_t)a[0] << 40); - if (r->n[4] == 0x0FFFFFFFFFFFFULL && (r->n[3] & r->n[2] & r->n[1]) == 0xFFFFFFFFFFFFFULL && r->n[0] >= 0xFFFFEFFFFFC2FULL) { - return 0; - } -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; - secp256k1_fe_verify(r); -#endif - return 1; -} - -/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ -static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->normalized); - secp256k1_fe_verify(a); -#endif - r[0] = (a->n[4] >> 40) & 0xFF; - r[1] = (a->n[4] >> 32) & 0xFF; - r[2] = (a->n[4] >> 24) & 0xFF; - r[3] = (a->n[4] >> 16) & 0xFF; - r[4] = (a->n[4] >> 8) & 0xFF; - r[5] = a->n[4] & 0xFF; - r[6] = (a->n[3] >> 44) & 0xFF; - r[7] = (a->n[3] >> 36) & 0xFF; - r[8] = (a->n[3] >> 28) & 0xFF; - r[9] = (a->n[3] >> 20) & 0xFF; - r[10] = (a->n[3] >> 12) & 0xFF; - r[11] = (a->n[3] >> 4) & 0xFF; - r[12] = ((a->n[2] >> 48) & 0xF) | ((a->n[3] & 0xF) << 4); - r[13] = (a->n[2] >> 40) & 0xFF; - r[14] = (a->n[2] >> 32) & 0xFF; - r[15] = (a->n[2] >> 24) & 0xFF; - r[16] = (a->n[2] >> 16) & 0xFF; - r[17] = (a->n[2] >> 8) & 0xFF; - r[18] = a->n[2] & 0xFF; - r[19] = (a->n[1] >> 44) & 0xFF; - r[20] = (a->n[1] >> 36) & 0xFF; - r[21] = (a->n[1] >> 28) & 0xFF; - r[22] = (a->n[1] >> 20) & 0xFF; - r[23] = (a->n[1] >> 12) & 0xFF; - r[24] = (a->n[1] >> 4) & 0xFF; - r[25] = ((a->n[0] >> 48) & 0xF) | ((a->n[1] & 0xF) << 4); - r[26] = (a->n[0] >> 40) & 0xFF; - r[27] = (a->n[0] >> 32) & 0xFF; - r[28] = (a->n[0] >> 24) & 0xFF; - r[29] = (a->n[0] >> 16) & 0xFF; - r[30] = (a->n[0] >> 8) & 0xFF; - r[31] = a->n[0] & 0xFF; -} - -SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { -#ifdef VERIFY - VERIFY_CHECK(a->magnitude <= m); - secp256k1_fe_verify(a); -#endif - r->n[0] = 0xFFFFEFFFFFC2FULL * 2 * (m + 1) - a->n[0]; - r->n[1] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[1]; - r->n[2] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[2]; - r->n[3] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[3]; - r->n[4] = 0x0FFFFFFFFFFFFULL * 2 * (m + 1) - a->n[4]; -#ifdef VERIFY - r->magnitude = m + 1; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif -} - -SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { - r->n[0] *= a; - r->n[1] *= a; - r->n[2] *= a; - r->n[3] *= a; - r->n[4] *= a; -#ifdef VERIFY - r->magnitude *= a; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif -} - -SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a) { -#ifdef VERIFY - secp256k1_fe_verify(a); -#endif - r->n[0] += a->n[0]; - r->n[1] += a->n[1]; - r->n[2] += a->n[2]; - r->n[3] += a->n[3]; - r->n[4] += a->n[4]; -#ifdef VERIFY - r->magnitude += a->magnitude; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif -} - -static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { -#ifdef VERIFY - VERIFY_CHECK(a->magnitude <= 8); - VERIFY_CHECK(b->magnitude <= 8); - secp256k1_fe_verify(a); - secp256k1_fe_verify(b); - VERIFY_CHECK(r != b); -#endif - secp256k1_fe_mul_inner(r->n, a->n, b->n); -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif -} - -static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->magnitude <= 8); - secp256k1_fe_verify(a); -#endif - secp256k1_fe_sqr_inner(r->n, a->n); -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 0; - secp256k1_fe_verify(r); -#endif -} - -static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { - uint64_t mask0, mask1; - mask0 = flag + ~((uint64_t)0); - mask1 = ~mask0; - r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); - r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); - r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); - r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); - r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); -#ifdef VERIFY - if (a->magnitude > r->magnitude) { - r->magnitude = a->magnitude; - } - r->normalized &= a->normalized; -#endif -} - -static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { - uint64_t mask0, mask1; - mask0 = flag + ~((uint64_t)0); - mask1 = ~mask0; - r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); - r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); - r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1); - r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); -} - -static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) { -#ifdef VERIFY - VERIFY_CHECK(a->normalized); -#endif - r->n[0] = a->n[0] | a->n[1] << 52; - r->n[1] = a->n[1] >> 12 | a->n[2] << 40; - r->n[2] = a->n[2] >> 24 | a->n[3] << 28; - r->n[3] = a->n[3] >> 36 | a->n[4] << 16; -} - -static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a) { - r->n[0] = a->n[0] & 0xFFFFFFFFFFFFFULL; - r->n[1] = a->n[0] >> 52 | ((a->n[1] << 12) & 0xFFFFFFFFFFFFFULL); - r->n[2] = a->n[1] >> 40 | ((a->n[2] << 24) & 0xFFFFFFFFFFFFFULL); - r->n[3] = a->n[2] >> 28 | ((a->n[3] << 36) & 0xFFFFFFFFFFFFFULL); - r->n[4] = a->n[3] >> 16; -#ifdef VERIFY - r->magnitude = 1; - r->normalized = 1; -#endif -} - -#endif /* SECP256K1_FIELD_REPR_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/field_5x52_int128_impl.h b/util/secp256k1/depend/secp256k1/src/field_5x52_int128_impl.h deleted file mode 100644 index 95a0d1791c..0000000000 --- a/util/secp256k1/depend/secp256k1/src/field_5x52_int128_impl.h +++ /dev/null @@ -1,277 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_FIELD_INNER5X52_IMPL_H -#define SECP256K1_FIELD_INNER5X52_IMPL_H - -#include - -#ifdef VERIFY -#define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0) -#else -#define VERIFY_BITS(x, n) do { } while(0) -#endif - -SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) { - uint128_t c, d; - uint64_t t3, t4, tx, u0; - uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4]; - const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL; - - VERIFY_BITS(a[0], 56); - VERIFY_BITS(a[1], 56); - VERIFY_BITS(a[2], 56); - VERIFY_BITS(a[3], 56); - VERIFY_BITS(a[4], 52); - VERIFY_BITS(b[0], 56); - VERIFY_BITS(b[1], 56); - VERIFY_BITS(b[2], 56); - VERIFY_BITS(b[3], 56); - VERIFY_BITS(b[4], 52); - VERIFY_CHECK(r != b); - - /* [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n. - * px is a shorthand for sum(a[i]*b[x-i], i=0..x). - * Note that [x 0 0 0 0 0] = [x*R]. - */ - - d = (uint128_t)a0 * b[3] - + (uint128_t)a1 * b[2] - + (uint128_t)a2 * b[1] - + (uint128_t)a3 * b[0]; - VERIFY_BITS(d, 114); - /* [d 0 0 0] = [p3 0 0 0] */ - c = (uint128_t)a4 * b[4]; - VERIFY_BITS(c, 112); - /* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ - d += (c & M) * R; c >>= 52; - VERIFY_BITS(d, 115); - VERIFY_BITS(c, 60); - /* [c 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ - t3 = d & M; d >>= 52; - VERIFY_BITS(t3, 52); - VERIFY_BITS(d, 63); - /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ - - d += (uint128_t)a0 * b[4] - + (uint128_t)a1 * b[3] - + (uint128_t)a2 * b[2] - + (uint128_t)a3 * b[1] - + (uint128_t)a4 * b[0]; - VERIFY_BITS(d, 115); - /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - d += c * R; - VERIFY_BITS(d, 116); - /* [d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - t4 = d & M; d >>= 52; - VERIFY_BITS(t4, 52); - VERIFY_BITS(d, 64); - /* [d t4 t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - tx = (t4 >> 48); t4 &= (M >> 4); - VERIFY_BITS(tx, 4); - VERIFY_BITS(t4, 48); - /* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - - c = (uint128_t)a0 * b[0]; - VERIFY_BITS(c, 112); - /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */ - d += (uint128_t)a1 * b[4] - + (uint128_t)a2 * b[3] - + (uint128_t)a3 * b[2] - + (uint128_t)a4 * b[1]; - VERIFY_BITS(d, 115); - /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - u0 = d & M; d >>= 52; - VERIFY_BITS(u0, 52); - VERIFY_BITS(d, 63); - /* [d u0 t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - /* [d 0 t4+(tx<<48)+(u0<<52) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - u0 = (u0 << 4) | tx; - VERIFY_BITS(u0, 56); - /* [d 0 t4+(u0<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - c += (uint128_t)u0 * (R >> 4); - VERIFY_BITS(c, 115); - /* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - r[0] = c & M; c >>= 52; - VERIFY_BITS(r[0], 52); - VERIFY_BITS(c, 61); - /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */ - - c += (uint128_t)a0 * b[1] - + (uint128_t)a1 * b[0]; - VERIFY_BITS(c, 114); - /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */ - d += (uint128_t)a2 * b[4] - + (uint128_t)a3 * b[3] - + (uint128_t)a4 * b[2]; - VERIFY_BITS(d, 114); - /* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ - c += (d & M) * R; d >>= 52; - VERIFY_BITS(c, 115); - VERIFY_BITS(d, 62); - /* [d 0 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ - r[1] = c & M; c >>= 52; - VERIFY_BITS(r[1], 52); - VERIFY_BITS(c, 63); - /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ - - c += (uint128_t)a0 * b[2] - + (uint128_t)a1 * b[1] - + (uint128_t)a2 * b[0]; - VERIFY_BITS(c, 114); - /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint128_t)a3 * b[4] - + (uint128_t)a4 * b[3]; - VERIFY_BITS(d, 114); - /* [d 0 0 t4 t3 c t1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += (d & M) * R; d >>= 52; - VERIFY_BITS(c, 115); - VERIFY_BITS(d, 62); - /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - - /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[2] = c & M; c >>= 52; - VERIFY_BITS(r[2], 52); - VERIFY_BITS(c, 63); - /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += d * R + t3; - VERIFY_BITS(c, 100); - /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[3] = c & M; c >>= 52; - VERIFY_BITS(r[3], 52); - VERIFY_BITS(c, 48); - /* [t4+c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += t4; - VERIFY_BITS(c, 49); - /* [c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[4] = c; - VERIFY_BITS(r[4], 49); - /* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ -} - -SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) { - uint128_t c, d; - uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4]; - int64_t t3, t4, tx, u0; - const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL; - - VERIFY_BITS(a[0], 56); - VERIFY_BITS(a[1], 56); - VERIFY_BITS(a[2], 56); - VERIFY_BITS(a[3], 56); - VERIFY_BITS(a[4], 52); - - /** [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n. - * px is a shorthand for sum(a[i]*a[x-i], i=0..x). - * Note that [x 0 0 0 0 0] = [x*R]. - */ - - d = (uint128_t)(a0*2) * a3 - + (uint128_t)(a1*2) * a2; - VERIFY_BITS(d, 114); - /* [d 0 0 0] = [p3 0 0 0] */ - c = (uint128_t)a4 * a4; - VERIFY_BITS(c, 112); - /* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ - d += (c & M) * R; c >>= 52; - VERIFY_BITS(d, 115); - VERIFY_BITS(c, 60); - /* [c 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ - t3 = d & M; d >>= 52; - VERIFY_BITS(t3, 52); - VERIFY_BITS(d, 63); - /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ - - a4 *= 2; - d += (uint128_t)a0 * a4 - + (uint128_t)(a1*2) * a3 - + (uint128_t)a2 * a2; - VERIFY_BITS(d, 115); - /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - d += c * R; - VERIFY_BITS(d, 116); - /* [d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - t4 = d & M; d >>= 52; - VERIFY_BITS(t4, 52); - VERIFY_BITS(d, 64); - /* [d t4 t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - tx = (t4 >> 48); t4 &= (M >> 4); - VERIFY_BITS(tx, 4); - VERIFY_BITS(t4, 48); - /* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ - - c = (uint128_t)a0 * a0; - VERIFY_BITS(c, 112); - /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */ - d += (uint128_t)a1 * a4 - + (uint128_t)(a2*2) * a3; - VERIFY_BITS(d, 114); - /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - u0 = d & M; d >>= 52; - VERIFY_BITS(u0, 52); - VERIFY_BITS(d, 62); - /* [d u0 t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - /* [d 0 t4+(tx<<48)+(u0<<52) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - u0 = (u0 << 4) | tx; - VERIFY_BITS(u0, 56); - /* [d 0 t4+(u0<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - c += (uint128_t)u0 * (R >> 4); - VERIFY_BITS(c, 113); - /* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ - r[0] = c & M; c >>= 52; - VERIFY_BITS(r[0], 52); - VERIFY_BITS(c, 61); - /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */ - - a0 *= 2; - c += (uint128_t)a0 * a1; - VERIFY_BITS(c, 114); - /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */ - d += (uint128_t)a2 * a4 - + (uint128_t)a3 * a3; - VERIFY_BITS(d, 114); - /* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ - c += (d & M) * R; d >>= 52; - VERIFY_BITS(c, 115); - VERIFY_BITS(d, 62); - /* [d 0 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ - r[1] = c & M; c >>= 52; - VERIFY_BITS(r[1], 52); - VERIFY_BITS(c, 63); - /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ - - c += (uint128_t)a0 * a2 - + (uint128_t)a1 * a1; - VERIFY_BITS(c, 114); - /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */ - d += (uint128_t)a3 * a4; - VERIFY_BITS(d, 114); - /* [d 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += (d & M) * R; d >>= 52; - VERIFY_BITS(c, 115); - VERIFY_BITS(d, 62); - /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[2] = c & M; c >>= 52; - VERIFY_BITS(r[2], 52); - VERIFY_BITS(c, 63); - /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - - c += d * R + t3; - VERIFY_BITS(c, 100); - /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[3] = c & M; c >>= 52; - VERIFY_BITS(r[3], 52); - VERIFY_BITS(c, 48); - /* [t4+c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += t4; - VERIFY_BITS(c, 49); - /* [c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - r[4] = c; - VERIFY_BITS(r[4], 49); - /* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ -} - -#endif /* SECP256K1_FIELD_INNER5X52_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/field_impl.h b/util/secp256k1/depend/secp256k1/src/field_impl.h deleted file mode 100644 index 20428648af..0000000000 --- a/util/secp256k1/depend/secp256k1/src/field_impl.h +++ /dev/null @@ -1,315 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_FIELD_IMPL_H -#define SECP256K1_FIELD_IMPL_H - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif - -#include "util.h" - -#if defined(USE_FIELD_10X26) -#include "field_10x26_impl.h" -#elif defined(USE_FIELD_5X52) -#include "field_5x52_impl.h" -#else -#error "Please select field implementation" -#endif - -SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) { - secp256k1_fe na; - secp256k1_fe_negate(&na, a, 1); - secp256k1_fe_add(&na, b); - return secp256k1_fe_normalizes_to_zero(&na); -} - -SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b) { - secp256k1_fe na; - secp256k1_fe_negate(&na, a, 1); - secp256k1_fe_add(&na, b); - return secp256k1_fe_normalizes_to_zero_var(&na); -} - -static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a) { - /** Given that p is congruent to 3 mod 4, we can compute the square root of - * a mod p as the (p+1)/4'th power of a. - * - * As (p+1)/4 is an even number, it will have the same result for a and for - * (-a). Only one of these two numbers actually has a square root however, - * so we test at the end by squaring and comparing to the input. - * Also because (p+1)/4 is an even number, the computed square root is - * itself always a square (a ** ((p+1)/4) is the square of a ** ((p+1)/8)). - */ - secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; - int j; - - /** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in - * { 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block: - * 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] - */ - - secp256k1_fe_sqr(&x2, a); - secp256k1_fe_mul(&x2, &x2, a); - - secp256k1_fe_sqr(&x3, &x2); - secp256k1_fe_mul(&x3, &x3, a); - - x6 = x3; - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&x6, &x6); - } - secp256k1_fe_mul(&x6, &x6, &x3); - - x9 = x6; - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&x9, &x9); - } - secp256k1_fe_mul(&x9, &x9, &x3); - - x11 = x9; - for (j=0; j<2; j++) { - secp256k1_fe_sqr(&x11, &x11); - } - secp256k1_fe_mul(&x11, &x11, &x2); - - x22 = x11; - for (j=0; j<11; j++) { - secp256k1_fe_sqr(&x22, &x22); - } - secp256k1_fe_mul(&x22, &x22, &x11); - - x44 = x22; - for (j=0; j<22; j++) { - secp256k1_fe_sqr(&x44, &x44); - } - secp256k1_fe_mul(&x44, &x44, &x22); - - x88 = x44; - for (j=0; j<44; j++) { - secp256k1_fe_sqr(&x88, &x88); - } - secp256k1_fe_mul(&x88, &x88, &x44); - - x176 = x88; - for (j=0; j<88; j++) { - secp256k1_fe_sqr(&x176, &x176); - } - secp256k1_fe_mul(&x176, &x176, &x88); - - x220 = x176; - for (j=0; j<44; j++) { - secp256k1_fe_sqr(&x220, &x220); - } - secp256k1_fe_mul(&x220, &x220, &x44); - - x223 = x220; - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&x223, &x223); - } - secp256k1_fe_mul(&x223, &x223, &x3); - - /* The final result is then assembled using a sliding window over the blocks. */ - - t1 = x223; - for (j=0; j<23; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(&t1, &t1, &x22); - for (j=0; j<6; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(&t1, &t1, &x2); - secp256k1_fe_sqr(&t1, &t1); - secp256k1_fe_sqr(r, &t1); - - /* Check that a square root was actually calculated */ - - secp256k1_fe_sqr(&t1, r); - return secp256k1_fe_equal(&t1, a); -} - -static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a) { - secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; - int j; - - /** The binary representation of (p - 2) has 5 blocks of 1s, with lengths in - * { 1, 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block: - * [1], [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] - */ - - secp256k1_fe_sqr(&x2, a); - secp256k1_fe_mul(&x2, &x2, a); - - secp256k1_fe_sqr(&x3, &x2); - secp256k1_fe_mul(&x3, &x3, a); - - x6 = x3; - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&x6, &x6); - } - secp256k1_fe_mul(&x6, &x6, &x3); - - x9 = x6; - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&x9, &x9); - } - secp256k1_fe_mul(&x9, &x9, &x3); - - x11 = x9; - for (j=0; j<2; j++) { - secp256k1_fe_sqr(&x11, &x11); - } - secp256k1_fe_mul(&x11, &x11, &x2); - - x22 = x11; - for (j=0; j<11; j++) { - secp256k1_fe_sqr(&x22, &x22); - } - secp256k1_fe_mul(&x22, &x22, &x11); - - x44 = x22; - for (j=0; j<22; j++) { - secp256k1_fe_sqr(&x44, &x44); - } - secp256k1_fe_mul(&x44, &x44, &x22); - - x88 = x44; - for (j=0; j<44; j++) { - secp256k1_fe_sqr(&x88, &x88); - } - secp256k1_fe_mul(&x88, &x88, &x44); - - x176 = x88; - for (j=0; j<88; j++) { - secp256k1_fe_sqr(&x176, &x176); - } - secp256k1_fe_mul(&x176, &x176, &x88); - - x220 = x176; - for (j=0; j<44; j++) { - secp256k1_fe_sqr(&x220, &x220); - } - secp256k1_fe_mul(&x220, &x220, &x44); - - x223 = x220; - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&x223, &x223); - } - secp256k1_fe_mul(&x223, &x223, &x3); - - /* The final result is then assembled using a sliding window over the blocks. */ - - t1 = x223; - for (j=0; j<23; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(&t1, &t1, &x22); - for (j=0; j<5; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(&t1, &t1, a); - for (j=0; j<3; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(&t1, &t1, &x2); - for (j=0; j<2; j++) { - secp256k1_fe_sqr(&t1, &t1); - } - secp256k1_fe_mul(r, a, &t1); -} - -static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a) { -#if defined(USE_FIELD_INV_BUILTIN) - secp256k1_fe_inv(r, a); -#elif defined(USE_FIELD_INV_NUM) - secp256k1_num n, m; - static const secp256k1_fe negone = SECP256K1_FE_CONST( - 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, - 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, 0xFFFFFC2EUL - ); - /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ - static const unsigned char prime[32] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F - }; - unsigned char b[32]; - int res; - secp256k1_fe c = *a; - secp256k1_fe_normalize_var(&c); - secp256k1_fe_get_b32(b, &c); - secp256k1_num_set_bin(&n, b, 32); - secp256k1_num_set_bin(&m, prime, 32); - secp256k1_num_mod_inverse(&n, &n, &m); - secp256k1_num_get_bin(b, 32, &n); - res = secp256k1_fe_set_b32(r, b); - (void)res; - VERIFY_CHECK(res); - /* Verify the result is the (unique) valid inverse using non-GMP code. */ - secp256k1_fe_mul(&c, &c, r); - secp256k1_fe_add(&c, &negone); - CHECK(secp256k1_fe_normalizes_to_zero_var(&c)); -#else -#error "Please select field inverse implementation" -#endif -} - -static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len) { - secp256k1_fe u; - size_t i; - if (len < 1) { - return; - } - - VERIFY_CHECK((r + len <= a) || (a + len <= r)); - - r[0] = a[0]; - - i = 0; - while (++i < len) { - secp256k1_fe_mul(&r[i], &r[i - 1], &a[i]); - } - - secp256k1_fe_inv_var(&u, &r[--i]); - - while (i > 0) { - size_t j = i--; - secp256k1_fe_mul(&r[j], &r[i], &u); - secp256k1_fe_mul(&u, &u, &a[j]); - } - - r[0] = u; -} - -static int secp256k1_fe_is_quad_var(const secp256k1_fe *a) { -#ifndef USE_NUM_NONE - unsigned char b[32]; - secp256k1_num n; - secp256k1_num m; - /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ - static const unsigned char prime[32] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F - }; - - secp256k1_fe c = *a; - secp256k1_fe_normalize_var(&c); - secp256k1_fe_get_b32(b, &c); - secp256k1_num_set_bin(&n, b, 32); - secp256k1_num_set_bin(&m, prime, 32); - return secp256k1_num_jacobi(&n, &m) >= 0; -#else - secp256k1_fe r; - return secp256k1_fe_sqrt(&r, a); -#endif -} - -#endif /* SECP256K1_FIELD_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/gen_context.c b/util/secp256k1/depend/secp256k1/src/gen_context.c deleted file mode 100644 index 1835fd491d..0000000000 --- a/util/secp256k1/depend/secp256k1/src/gen_context.c +++ /dev/null @@ -1,74 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014, 2015 Thomas Daede, Cory Fields * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#define USE_BASIC_CONFIG 1 - -#include "basic-config.h" -#include "include/secp256k1.h" -#include "field_impl.h" -#include "scalar_impl.h" -#include "group_impl.h" -#include "ecmult_gen_impl.h" - -static void default_error_callback_fn(const char* str, void* data) { - (void)data; - fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); - abort(); -} - -static const secp256k1_callback default_error_callback = { - default_error_callback_fn, - NULL -}; - -int main(int argc, char **argv) { - secp256k1_ecmult_gen_context ctx; - int inner; - int outer; - FILE* fp; - - (void)argc; - (void)argv; - - fp = fopen("src/ecmult_static_context.h","w"); - if (fp == NULL) { - fprintf(stderr, "Could not open src/ecmult_static_context.h for writing!\n"); - return -1; - } - - fprintf(fp, "#ifndef _SECP256K1_ECMULT_STATIC_CONTEXT_\n"); - fprintf(fp, "#define _SECP256K1_ECMULT_STATIC_CONTEXT_\n"); - fprintf(fp, "#include \"group.h\"\n"); - fprintf(fp, "#define SC SECP256K1_GE_STORAGE_CONST\n"); - fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_static_context[64][16] = {\n"); - - secp256k1_ecmult_gen_context_init(&ctx); - secp256k1_ecmult_gen_context_build(&ctx, &default_error_callback); - for(outer = 0; outer != 64; outer++) { - fprintf(fp,"{\n"); - for(inner = 0; inner != 16; inner++) { - fprintf(fp," SC(%uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu)", SECP256K1_GE_STORAGE_CONST_GET((*ctx.prec)[outer][inner])); - if (inner != 15) { - fprintf(fp,",\n"); - } else { - fprintf(fp,"\n"); - } - } - if (outer != 63) { - fprintf(fp,"},\n"); - } else { - fprintf(fp,"}\n"); - } - } - fprintf(fp,"};\n"); - secp256k1_ecmult_gen_context_clear(&ctx); - - fprintf(fp, "#undef SC\n"); - fprintf(fp, "#endif\n"); - fclose(fp); - - return 0; -} diff --git a/util/secp256k1/depend/secp256k1/src/group.h b/util/secp256k1/depend/secp256k1/src/group.h deleted file mode 100644 index ea1302deb8..0000000000 --- a/util/secp256k1/depend/secp256k1/src/group.h +++ /dev/null @@ -1,144 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_GROUP_H -#define SECP256K1_GROUP_H - -#include "num.h" -#include "field.h" - -/** A group element of the secp256k1 curve, in affine coordinates. */ -typedef struct { - secp256k1_fe x; - secp256k1_fe y; - int infinity; /* whether this represents the point at infinity */ -} secp256k1_ge; - -#define SECP256K1_GE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), 0} -#define SECP256K1_GE_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} - -/** A group element of the secp256k1 curve, in jacobian coordinates. */ -typedef struct { - secp256k1_fe x; /* actual X: x/z^2 */ - secp256k1_fe y; /* actual Y: y/z^3 */ - secp256k1_fe z; - int infinity; /* whether this represents the point at infinity */ -} secp256k1_gej; - -#define SECP256K1_GEJ_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1), 0} -#define SECP256K1_GEJ_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} - -typedef struct { - secp256k1_fe_storage x; - secp256k1_fe_storage y; -} secp256k1_ge_storage; - -#define SECP256K1_GE_STORAGE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_STORAGE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_STORAGE_CONST((i),(j),(k),(l),(m),(n),(o),(p))} - -#define SECP256K1_GE_STORAGE_CONST_GET(t) SECP256K1_FE_STORAGE_CONST_GET(t.x), SECP256K1_FE_STORAGE_CONST_GET(t.y) - -/** Set a group element equal to the point with given X and Y coordinates */ -static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y); - -/** Set a group element (affine) equal to the point with the given X coordinate - * and a Y coordinate that is a quadratic residue modulo p. The return value - * is true iff a coordinate with the given X coordinate exists. - */ -static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x); - -/** Set a group element (affine) equal to the point with the given X coordinate, and given oddness - * for Y. Return value indicates whether the result is valid. */ -static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd); - -/** Check whether a group element is the point at infinity. */ -static int secp256k1_ge_is_infinity(const secp256k1_ge *a); - -/** Check whether a group element is valid (i.e., on the curve). */ -static int secp256k1_ge_is_valid_var(const secp256k1_ge *a); - -static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a); - -/** Set a group element equal to another which is given in jacobian coordinates */ -static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a); - -/** Set a batch of group elements equal to the inputs given in jacobian coordinates */ -static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len, const secp256k1_callback *cb); - -/** Set a batch of group elements equal to the inputs given in jacobian - * coordinates (with known z-ratios). zr must contain the known z-ratios such - * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. */ -static void secp256k1_ge_set_table_gej_var(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr, size_t len); - -/** Bring a batch inputs given in jacobian coordinates (with known z-ratios) to - * the same global z "denominator". zr must contain the known z-ratios such - * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. The x and y - * coordinates of the result are stored in r, the common z coordinate is - * stored in globalz. */ -static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge *r, secp256k1_fe *globalz, const secp256k1_gej *a, const secp256k1_fe *zr); - -/** Set a group element (jacobian) equal to the point at infinity. */ -static void secp256k1_gej_set_infinity(secp256k1_gej *r); - -/** Set a group element (jacobian) equal to another which is given in affine coordinates. */ -static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a); - -/** Compare the X coordinate of a group element (jacobian). */ -static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a); - -/** Set r equal to the inverse of a (i.e., mirrored around the X axis) */ -static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a); - -/** Check whether a group element is the point at infinity. */ -static int secp256k1_gej_is_infinity(const secp256k1_gej *a); - -/** Check whether a group element's y coordinate is a quadratic residue. */ -static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a); - -/** Set r equal to the double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0). - * a may not be zero. Constant time. */ -static void secp256k1_gej_double_nonzero(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); - -/** Set r equal to the double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0). */ -static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); - -/** Set r equal to the sum of a and b. If rzr is non-NULL, r->z = a->z * *rzr (a cannot be infinity in that case). */ -static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr); - -/** Set r equal to the sum of a and b (with b given in affine coordinates, and not infinity). */ -static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b); - -/** Set r equal to the sum of a and b (with b given in affine coordinates). This is more efficient - than secp256k1_gej_add_var. It is identical to secp256k1_gej_add_ge but without constant-time - guarantee, and b is allowed to be infinity. If rzr is non-NULL, r->z = a->z * *rzr (a cannot be infinity in that case). */ -static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr); - -/** Set r equal to the sum of a and b (with the inverse of b's Z coordinate passed as bzinv). */ -static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv); - -#ifdef USE_ENDOMORPHISM -/** Set r to be equal to lambda times a, where lambda is chosen in a way such that this is very fast. */ -static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a); -#endif - -/** Clear a secp256k1_gej to prevent leaking sensitive information. */ -static void secp256k1_gej_clear(secp256k1_gej *r); - -/** Clear a secp256k1_ge to prevent leaking sensitive information. */ -static void secp256k1_ge_clear(secp256k1_ge *r); - -/** Convert a group element to the storage type. */ -static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge *a); - -/** Convert a group element back from the storage type. */ -static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a); - -/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ -static void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag); - -/** Rescale a jacobian point by b which must be non-zero. Constant-time. */ -static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *b); - -#endif /* SECP256K1_GROUP_H */ diff --git a/util/secp256k1/depend/secp256k1/src/group_impl.h b/util/secp256k1/depend/secp256k1/src/group_impl.h deleted file mode 100644 index b31b6c12ef..0000000000 --- a/util/secp256k1/depend/secp256k1/src/group_impl.h +++ /dev/null @@ -1,700 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_GROUP_IMPL_H -#define SECP256K1_GROUP_IMPL_H - -#include "num.h" -#include "field.h" -#include "group.h" - -/* These points can be generated in sage as follows: - * - * 0. Setup a worksheet with the following parameters. - * b = 4 # whatever CURVE_B will be set to - * F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) - * C = EllipticCurve ([F (0), F (b)]) - * - * 1. Determine all the small orders available to you. (If there are - * no satisfactory ones, go back and change b.) - * print C.order().factor(limit=1000) - * - * 2. Choose an order as one of the prime factors listed in the above step. - * (You can also multiply some to get a composite order, though the - * tests will crash trying to invert scalars during signing.) We take a - * random point and scale it to drop its order to the desired value. - * There is some probability this won't work; just try again. - * order = 199 - * P = C.random_point() - * P = (int(P.order()) / int(order)) * P - * assert(P.order() == order) - * - * 3. Print the values. You'll need to use a vim macro or something to - * split the hex output into 4-byte chunks. - * print "%x %x" % P.xy() - */ -#if defined(EXHAUSTIVE_TEST_ORDER) -# if EXHAUSTIVE_TEST_ORDER == 199 -const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( - 0xFA7CC9A7, 0x0737F2DB, 0xA749DD39, 0x2B4FB069, - 0x3B017A7D, 0xA808C2F1, 0xFB12940C, 0x9EA66C18, - 0x78AC123A, 0x5ED8AEF3, 0x8732BC91, 0x1F3A2868, - 0x48DF246C, 0x808DAE72, 0xCFE52572, 0x7F0501ED -); - -const int CURVE_B = 4; -# elif EXHAUSTIVE_TEST_ORDER == 13 -const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( - 0xedc60018, 0xa51a786b, 0x2ea91f4d, 0x4c9416c0, - 0x9de54c3b, 0xa1316554, 0x6cf4345c, 0x7277ef15, - 0x54cb1b6b, 0xdc8c1273, 0x087844ea, 0x43f4603e, - 0x0eaf9a43, 0xf6effe55, 0x939f806d, 0x37adf8ac -); -const int CURVE_B = 2; -# else -# error No known generator for the specified exhaustive test group order. -# endif -#else -/** Generator for secp256k1, value 'g' defined in - * "Standards for Efficient Cryptography" (SEC2) 2.7.1. - */ -static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( - 0x79BE667EUL, 0xF9DCBBACUL, 0x55A06295UL, 0xCE870B07UL, - 0x029BFCDBUL, 0x2DCE28D9UL, 0x59F2815BUL, 0x16F81798UL, - 0x483ADA77UL, 0x26A3C465UL, 0x5DA4FBFCUL, 0x0E1108A8UL, - 0xFD17B448UL, 0xA6855419UL, 0x9C47D08FUL, 0xFB10D4B8UL -); - -const int CURVE_B = 7; -#endif - -static void secp256k1_ge_set_gej_zinv(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zi) { - secp256k1_fe zi2; - secp256k1_fe zi3; - secp256k1_fe_sqr(&zi2, zi); - secp256k1_fe_mul(&zi3, &zi2, zi); - secp256k1_fe_mul(&r->x, &a->x, &zi2); - secp256k1_fe_mul(&r->y, &a->y, &zi3); - r->infinity = a->infinity; -} - -static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y) { - r->infinity = 0; - r->x = *x; - r->y = *y; -} - -static int secp256k1_ge_is_infinity(const secp256k1_ge *a) { - return a->infinity; -} - -static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a) { - *r = *a; - secp256k1_fe_normalize_weak(&r->y); - secp256k1_fe_negate(&r->y, &r->y, 1); -} - -static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a) { - secp256k1_fe z2, z3; - r->infinity = a->infinity; - secp256k1_fe_inv(&a->z, &a->z); - secp256k1_fe_sqr(&z2, &a->z); - secp256k1_fe_mul(&z3, &a->z, &z2); - secp256k1_fe_mul(&a->x, &a->x, &z2); - secp256k1_fe_mul(&a->y, &a->y, &z3); - secp256k1_fe_set_int(&a->z, 1); - r->x = a->x; - r->y = a->y; -} - -static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) { - secp256k1_fe z2, z3; - r->infinity = a->infinity; - if (a->infinity) { - return; - } - secp256k1_fe_inv_var(&a->z, &a->z); - secp256k1_fe_sqr(&z2, &a->z); - secp256k1_fe_mul(&z3, &a->z, &z2); - secp256k1_fe_mul(&a->x, &a->x, &z2); - secp256k1_fe_mul(&a->y, &a->y, &z3); - secp256k1_fe_set_int(&a->z, 1); - r->x = a->x; - r->y = a->y; -} - -static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len, const secp256k1_callback *cb) { - secp256k1_fe *az; - secp256k1_fe *azi; - size_t i; - size_t count = 0; - az = (secp256k1_fe *)checked_malloc(cb, sizeof(secp256k1_fe) * len); - for (i = 0; i < len; i++) { - if (!a[i].infinity) { - az[count++] = a[i].z; - } - } - - azi = (secp256k1_fe *)checked_malloc(cb, sizeof(secp256k1_fe) * count); - secp256k1_fe_inv_all_var(azi, az, count); - free(az); - - count = 0; - for (i = 0; i < len; i++) { - r[i].infinity = a[i].infinity; - if (!a[i].infinity) { - secp256k1_ge_set_gej_zinv(&r[i], &a[i], &azi[count++]); - } - } - free(azi); -} - -static void secp256k1_ge_set_table_gej_var(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr, size_t len) { - size_t i = len - 1; - secp256k1_fe zi; - - if (len > 0) { - /* Compute the inverse of the last z coordinate, and use it to compute the last affine output. */ - secp256k1_fe_inv(&zi, &a[i].z); - secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zi); - - /* Work out way backwards, using the z-ratios to scale the x/y values. */ - while (i > 0) { - secp256k1_fe_mul(&zi, &zi, &zr[i]); - i--; - secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zi); - } - } -} - -static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge *r, secp256k1_fe *globalz, const secp256k1_gej *a, const secp256k1_fe *zr) { - size_t i = len - 1; - secp256k1_fe zs; - - if (len > 0) { - /* The z of the final point gives us the "global Z" for the table. */ - r[i].x = a[i].x; - r[i].y = a[i].y; - *globalz = a[i].z; - r[i].infinity = 0; - zs = zr[i]; - - /* Work our way backwards, using the z-ratios to scale the x/y values. */ - while (i > 0) { - if (i != len - 1) { - secp256k1_fe_mul(&zs, &zs, &zr[i]); - } - i--; - secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zs); - } - } -} - -static void secp256k1_gej_set_infinity(secp256k1_gej *r) { - r->infinity = 1; - secp256k1_fe_clear(&r->x); - secp256k1_fe_clear(&r->y); - secp256k1_fe_clear(&r->z); -} - -static void secp256k1_gej_clear(secp256k1_gej *r) { - r->infinity = 0; - secp256k1_fe_clear(&r->x); - secp256k1_fe_clear(&r->y); - secp256k1_fe_clear(&r->z); -} - -static void secp256k1_ge_clear(secp256k1_ge *r) { - r->infinity = 0; - secp256k1_fe_clear(&r->x); - secp256k1_fe_clear(&r->y); -} - -static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x) { - secp256k1_fe x2, x3, c; - r->x = *x; - secp256k1_fe_sqr(&x2, x); - secp256k1_fe_mul(&x3, x, &x2); - r->infinity = 0; - secp256k1_fe_set_int(&c, CURVE_B); - secp256k1_fe_add(&c, &x3); - return secp256k1_fe_sqrt(&r->y, &c); -} - -static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd) { - if (!secp256k1_ge_set_xquad(r, x)) { - return 0; - } - secp256k1_fe_normalize_var(&r->y); - if (secp256k1_fe_is_odd(&r->y) != odd) { - secp256k1_fe_negate(&r->y, &r->y, 1); - } - return 1; - -} - -static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a) { - r->infinity = a->infinity; - r->x = a->x; - r->y = a->y; - secp256k1_fe_set_int(&r->z, 1); -} - -static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a) { - secp256k1_fe r, r2; - VERIFY_CHECK(!a->infinity); - secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x); - r2 = a->x; secp256k1_fe_normalize_weak(&r2); - return secp256k1_fe_equal_var(&r, &r2); -} - -static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a) { - r->infinity = a->infinity; - r->x = a->x; - r->y = a->y; - r->z = a->z; - secp256k1_fe_normalize_weak(&r->y); - secp256k1_fe_negate(&r->y, &r->y, 1); -} - -static int secp256k1_gej_is_infinity(const secp256k1_gej *a) { - return a->infinity; -} - -static int secp256k1_gej_is_valid_var(const secp256k1_gej *a) { - secp256k1_fe y2, x3, z2, z6; - if (a->infinity) { - return 0; - } - /** y^2 = x^3 + 7 - * (Y/Z^3)^2 = (X/Z^2)^3 + 7 - * Y^2 / Z^6 = X^3 / Z^6 + 7 - * Y^2 = X^3 + 7*Z^6 - */ - secp256k1_fe_sqr(&y2, &a->y); - secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); - secp256k1_fe_sqr(&z2, &a->z); - secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2); - secp256k1_fe_mul_int(&z6, CURVE_B); - secp256k1_fe_add(&x3, &z6); - secp256k1_fe_normalize_weak(&x3); - return secp256k1_fe_equal_var(&y2, &x3); -} - -static int secp256k1_ge_is_valid_var(const secp256k1_ge *a) { - secp256k1_fe y2, x3, c; - if (a->infinity) { - return 0; - } - /* y^2 = x^3 + 7 */ - secp256k1_fe_sqr(&y2, &a->y); - secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); - secp256k1_fe_set_int(&c, CURVE_B); - secp256k1_fe_add(&x3, &c); - secp256k1_fe_normalize_weak(&x3); - return secp256k1_fe_equal_var(&y2, &x3); -} - -static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr) { - /* Operations: 3 mul, 4 sqr, 0 normalize, 12 mul_int/add/negate. - * - * Note that there is an implementation described at - * https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l - * which trades a multiply for a square, but in practice this is actually slower, - * mainly because it requires more normalizations. - */ - secp256k1_fe t1,t2,t3,t4; - /** For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity, - * Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have - * y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p. - * - * Having said this, if this function receives a point on a sextic twist, e.g. by - * a fault attack, it is possible for y to be 0. This happens for y^2 = x^3 + 6, - * since -6 does have a cube root mod p. For this point, this function will not set - * the infinity flag even though the point doubles to infinity, and the result - * point will be gibberish (z = 0 but infinity = 0). - */ - r->infinity = a->infinity; - if (r->infinity) { - if (rzr != NULL) { - secp256k1_fe_set_int(rzr, 1); - } - return; - } - - if (rzr != NULL) { - *rzr = a->y; - secp256k1_fe_normalize_weak(rzr); - secp256k1_fe_mul_int(rzr, 2); - } - - secp256k1_fe_mul(&r->z, &a->z, &a->y); - secp256k1_fe_mul_int(&r->z, 2); /* Z' = 2*Y*Z (2) */ - secp256k1_fe_sqr(&t1, &a->x); - secp256k1_fe_mul_int(&t1, 3); /* T1 = 3*X^2 (3) */ - secp256k1_fe_sqr(&t2, &t1); /* T2 = 9*X^4 (1) */ - secp256k1_fe_sqr(&t3, &a->y); - secp256k1_fe_mul_int(&t3, 2); /* T3 = 2*Y^2 (2) */ - secp256k1_fe_sqr(&t4, &t3); - secp256k1_fe_mul_int(&t4, 2); /* T4 = 8*Y^4 (2) */ - secp256k1_fe_mul(&t3, &t3, &a->x); /* T3 = 2*X*Y^2 (1) */ - r->x = t3; - secp256k1_fe_mul_int(&r->x, 4); /* X' = 8*X*Y^2 (4) */ - secp256k1_fe_negate(&r->x, &r->x, 4); /* X' = -8*X*Y^2 (5) */ - secp256k1_fe_add(&r->x, &t2); /* X' = 9*X^4 - 8*X*Y^2 (6) */ - secp256k1_fe_negate(&t2, &t2, 1); /* T2 = -9*X^4 (2) */ - secp256k1_fe_mul_int(&t3, 6); /* T3 = 12*X*Y^2 (6) */ - secp256k1_fe_add(&t3, &t2); /* T3 = 12*X*Y^2 - 9*X^4 (8) */ - secp256k1_fe_mul(&r->y, &t1, &t3); /* Y' = 36*X^3*Y^2 - 27*X^6 (1) */ - secp256k1_fe_negate(&t2, &t4, 2); /* T2 = -8*Y^4 (3) */ - secp256k1_fe_add(&r->y, &t2); /* Y' = 36*X^3*Y^2 - 27*X^6 - 8*Y^4 (4) */ -} - -static SECP256K1_INLINE void secp256k1_gej_double_nonzero(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr) { - VERIFY_CHECK(!secp256k1_gej_is_infinity(a)); - secp256k1_gej_double_var(r, a, rzr); -} - -static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr) { - /* Operations: 12 mul, 4 sqr, 2 normalize, 12 mul_int/add/negate */ - secp256k1_fe z22, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; - - if (a->infinity) { - VERIFY_CHECK(rzr == NULL); - *r = *b; - return; - } - - if (b->infinity) { - if (rzr != NULL) { - secp256k1_fe_set_int(rzr, 1); - } - *r = *a; - return; - } - - r->infinity = 0; - secp256k1_fe_sqr(&z22, &b->z); - secp256k1_fe_sqr(&z12, &a->z); - secp256k1_fe_mul(&u1, &a->x, &z22); - secp256k1_fe_mul(&u2, &b->x, &z12); - secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z); - secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); - secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); - secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); - if (secp256k1_fe_normalizes_to_zero_var(&h)) { - if (secp256k1_fe_normalizes_to_zero_var(&i)) { - secp256k1_gej_double_var(r, a, rzr); - } else { - if (rzr != NULL) { - secp256k1_fe_set_int(rzr, 0); - } - r->infinity = 1; - } - return; - } - secp256k1_fe_sqr(&i2, &i); - secp256k1_fe_sqr(&h2, &h); - secp256k1_fe_mul(&h3, &h, &h2); - secp256k1_fe_mul(&h, &h, &b->z); - if (rzr != NULL) { - *rzr = h; - } - secp256k1_fe_mul(&r->z, &a->z, &h); - secp256k1_fe_mul(&t, &u1, &h2); - r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); - secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); - secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); - secp256k1_fe_add(&r->y, &h3); -} - -static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr) { - /* 8 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */ - secp256k1_fe z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; - if (a->infinity) { - VERIFY_CHECK(rzr == NULL); - secp256k1_gej_set_ge(r, b); - return; - } - if (b->infinity) { - if (rzr != NULL) { - secp256k1_fe_set_int(rzr, 1); - } - *r = *a; - return; - } - r->infinity = 0; - - secp256k1_fe_sqr(&z12, &a->z); - u1 = a->x; secp256k1_fe_normalize_weak(&u1); - secp256k1_fe_mul(&u2, &b->x, &z12); - s1 = a->y; secp256k1_fe_normalize_weak(&s1); - secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); - secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); - secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); - if (secp256k1_fe_normalizes_to_zero_var(&h)) { - if (secp256k1_fe_normalizes_to_zero_var(&i)) { - secp256k1_gej_double_var(r, a, rzr); - } else { - if (rzr != NULL) { - secp256k1_fe_set_int(rzr, 0); - } - r->infinity = 1; - } - return; - } - secp256k1_fe_sqr(&i2, &i); - secp256k1_fe_sqr(&h2, &h); - secp256k1_fe_mul(&h3, &h, &h2); - if (rzr != NULL) { - *rzr = h; - } - secp256k1_fe_mul(&r->z, &a->z, &h); - secp256k1_fe_mul(&t, &u1, &h2); - r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); - secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); - secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); - secp256k1_fe_add(&r->y, &h3); -} - -static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv) { - /* 9 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */ - secp256k1_fe az, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; - - if (b->infinity) { - *r = *a; - return; - } - if (a->infinity) { - secp256k1_fe bzinv2, bzinv3; - r->infinity = b->infinity; - secp256k1_fe_sqr(&bzinv2, bzinv); - secp256k1_fe_mul(&bzinv3, &bzinv2, bzinv); - secp256k1_fe_mul(&r->x, &b->x, &bzinv2); - secp256k1_fe_mul(&r->y, &b->y, &bzinv3); - secp256k1_fe_set_int(&r->z, 1); - return; - } - r->infinity = 0; - - /** We need to calculate (rx,ry,rz) = (ax,ay,az) + (bx,by,1/bzinv). Due to - * secp256k1's isomorphism we can multiply the Z coordinates on both sides - * by bzinv, and get: (rx,ry,rz*bzinv) = (ax,ay,az*bzinv) + (bx,by,1). - * This means that (rx,ry,rz) can be calculated as - * (ax,ay,az*bzinv) + (bx,by,1), when not applying the bzinv factor to rz. - * The variable az below holds the modified Z coordinate for a, which is used - * for the computation of rx and ry, but not for rz. - */ - secp256k1_fe_mul(&az, &a->z, bzinv); - - secp256k1_fe_sqr(&z12, &az); - u1 = a->x; secp256k1_fe_normalize_weak(&u1); - secp256k1_fe_mul(&u2, &b->x, &z12); - s1 = a->y; secp256k1_fe_normalize_weak(&s1); - secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &az); - secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); - secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); - if (secp256k1_fe_normalizes_to_zero_var(&h)) { - if (secp256k1_fe_normalizes_to_zero_var(&i)) { - secp256k1_gej_double_var(r, a, NULL); - } else { - r->infinity = 1; - } - return; - } - secp256k1_fe_sqr(&i2, &i); - secp256k1_fe_sqr(&h2, &h); - secp256k1_fe_mul(&h3, &h, &h2); - r->z = a->z; secp256k1_fe_mul(&r->z, &r->z, &h); - secp256k1_fe_mul(&t, &u1, &h2); - r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); - secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); - secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); - secp256k1_fe_add(&r->y, &h3); -} - - -static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b) { - /* Operations: 7 mul, 5 sqr, 4 normalize, 21 mul_int/add/negate/cmov */ - static const secp256k1_fe fe_1 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); - secp256k1_fe zz, u1, u2, s1, s2, t, tt, m, n, q, rr; - secp256k1_fe m_alt, rr_alt; - int infinity, degenerate; - VERIFY_CHECK(!b->infinity); - VERIFY_CHECK(a->infinity == 0 || a->infinity == 1); - - /** In: - * Eric Brier and Marc Joye, Weierstrass Elliptic Curves and Side-Channel Attacks. - * In D. Naccache and P. Paillier, Eds., Public Key Cryptography, vol. 2274 of Lecture Notes in Computer Science, pages 335-345. Springer-Verlag, 2002. - * we find as solution for a unified addition/doubling formula: - * lambda = ((x1 + x2)^2 - x1 * x2 + a) / (y1 + y2), with a = 0 for secp256k1's curve equation. - * x3 = lambda^2 - (x1 + x2) - * 2*y3 = lambda * (x1 + x2 - 2 * x3) - (y1 + y2). - * - * Substituting x_i = Xi / Zi^2 and yi = Yi / Zi^3, for i=1,2,3, gives: - * U1 = X1*Z2^2, U2 = X2*Z1^2 - * S1 = Y1*Z2^3, S2 = Y2*Z1^3 - * Z = Z1*Z2 - * T = U1+U2 - * M = S1+S2 - * Q = T*M^2 - * R = T^2-U1*U2 - * X3 = 4*(R^2-Q) - * Y3 = 4*(R*(3*Q-2*R^2)-M^4) - * Z3 = 2*M*Z - * (Note that the paper uses xi = Xi / Zi and yi = Yi / Zi instead.) - * - * This formula has the benefit of being the same for both addition - * of distinct points and doubling. However, it breaks down in the - * case that either point is infinity, or that y1 = -y2. We handle - * these cases in the following ways: - * - * - If b is infinity we simply bail by means of a VERIFY_CHECK. - * - * - If a is infinity, we detect this, and at the end of the - * computation replace the result (which will be meaningless, - * but we compute to be constant-time) with b.x : b.y : 1. - * - * - If a = -b, we have y1 = -y2, which is a degenerate case. - * But here the answer is infinity, so we simply set the - * infinity flag of the result, overriding the computed values - * without even needing to cmov. - * - * - If y1 = -y2 but x1 != x2, which does occur thanks to certain - * properties of our curve (specifically, 1 has nontrivial cube - * roots in our field, and the curve equation has no x coefficient) - * then the answer is not infinity but also not given by the above - * equation. In this case, we cmov in place an alternate expression - * for lambda. Specifically (y1 - y2)/(x1 - x2). Where both these - * expressions for lambda are defined, they are equal, and can be - * obtained from each other by multiplication by (y1 + y2)/(y1 + y2) - * then substitution of x^3 + 7 for y^2 (using the curve equation). - * For all pairs of nonzero points (a, b) at least one is defined, - * so this covers everything. - */ - - secp256k1_fe_sqr(&zz, &a->z); /* z = Z1^2 */ - u1 = a->x; secp256k1_fe_normalize_weak(&u1); /* u1 = U1 = X1*Z2^2 (1) */ - secp256k1_fe_mul(&u2, &b->x, &zz); /* u2 = U2 = X2*Z1^2 (1) */ - s1 = a->y; secp256k1_fe_normalize_weak(&s1); /* s1 = S1 = Y1*Z2^3 (1) */ - secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z1^2 (1) */ - secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */ - t = u1; secp256k1_fe_add(&t, &u2); /* t = T = U1+U2 (2) */ - m = s1; secp256k1_fe_add(&m, &s2); /* m = M = S1+S2 (2) */ - secp256k1_fe_sqr(&rr, &t); /* rr = T^2 (1) */ - secp256k1_fe_negate(&m_alt, &u2, 1); /* Malt = -X2*Z1^2 */ - secp256k1_fe_mul(&tt, &u1, &m_alt); /* tt = -U1*U2 (2) */ - secp256k1_fe_add(&rr, &tt); /* rr = R = T^2-U1*U2 (3) */ - /** If lambda = R/M = 0/0 we have a problem (except in the "trivial" - * case that Z = z1z2 = 0, and this is special-cased later on). */ - degenerate = secp256k1_fe_normalizes_to_zero(&m) & - secp256k1_fe_normalizes_to_zero(&rr); - /* This only occurs when y1 == -y2 and x1^3 == x2^3, but x1 != x2. - * This means either x1 == beta*x2 or beta*x1 == x2, where beta is - * a nontrivial cube root of one. In either case, an alternate - * non-indeterminate expression for lambda is (y1 - y2)/(x1 - x2), - * so we set R/M equal to this. */ - rr_alt = s1; - secp256k1_fe_mul_int(&rr_alt, 2); /* rr = Y1*Z2^3 - Y2*Z1^3 (2) */ - secp256k1_fe_add(&m_alt, &u1); /* Malt = X1*Z2^2 - X2*Z1^2 */ - - secp256k1_fe_cmov(&rr_alt, &rr, !degenerate); - secp256k1_fe_cmov(&m_alt, &m, !degenerate); - /* Now Ralt / Malt = lambda and is guaranteed not to be 0/0. - * From here on out Ralt and Malt represent the numerator - * and denominator of lambda; R and M represent the explicit - * expressions x1^2 + x2^2 + x1x2 and y1 + y2. */ - secp256k1_fe_sqr(&n, &m_alt); /* n = Malt^2 (1) */ - secp256k1_fe_mul(&q, &n, &t); /* q = Q = T*Malt^2 (1) */ - /* These two lines use the observation that either M == Malt or M == 0, - * so M^3 * Malt is either Malt^4 (which is computed by squaring), or - * zero (which is "computed" by cmov). So the cost is one squaring - * versus two multiplications. */ - secp256k1_fe_sqr(&n, &n); - secp256k1_fe_cmov(&n, &m, degenerate); /* n = M^3 * Malt (2) */ - secp256k1_fe_sqr(&t, &rr_alt); /* t = Ralt^2 (1) */ - secp256k1_fe_mul(&r->z, &a->z, &m_alt); /* r->z = Malt*Z (1) */ - infinity = secp256k1_fe_normalizes_to_zero(&r->z) * (1 - a->infinity); - secp256k1_fe_mul_int(&r->z, 2); /* r->z = Z3 = 2*Malt*Z (2) */ - secp256k1_fe_negate(&q, &q, 1); /* q = -Q (2) */ - secp256k1_fe_add(&t, &q); /* t = Ralt^2-Q (3) */ - secp256k1_fe_normalize_weak(&t); - r->x = t; /* r->x = Ralt^2-Q (1) */ - secp256k1_fe_mul_int(&t, 2); /* t = 2*x3 (2) */ - secp256k1_fe_add(&t, &q); /* t = 2*x3 - Q: (4) */ - secp256k1_fe_mul(&t, &t, &rr_alt); /* t = Ralt*(2*x3 - Q) (1) */ - secp256k1_fe_add(&t, &n); /* t = Ralt*(2*x3 - Q) + M^3*Malt (3) */ - secp256k1_fe_negate(&r->y, &t, 3); /* r->y = Ralt*(Q - 2x3) - M^3*Malt (4) */ - secp256k1_fe_normalize_weak(&r->y); - secp256k1_fe_mul_int(&r->x, 4); /* r->x = X3 = 4*(Ralt^2-Q) */ - secp256k1_fe_mul_int(&r->y, 4); /* r->y = Y3 = 4*Ralt*(Q - 2x3) - 4*M^3*Malt (4) */ - - /** In case a->infinity == 1, replace r with (b->x, b->y, 1). */ - secp256k1_fe_cmov(&r->x, &b->x, a->infinity); - secp256k1_fe_cmov(&r->y, &b->y, a->infinity); - secp256k1_fe_cmov(&r->z, &fe_1, a->infinity); - r->infinity = infinity; -} - -static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *s) { - /* Operations: 4 mul, 1 sqr */ - secp256k1_fe zz; - VERIFY_CHECK(!secp256k1_fe_is_zero(s)); - secp256k1_fe_sqr(&zz, s); - secp256k1_fe_mul(&r->x, &r->x, &zz); /* r->x *= s^2 */ - secp256k1_fe_mul(&r->y, &r->y, &zz); - secp256k1_fe_mul(&r->y, &r->y, s); /* r->y *= s^3 */ - secp256k1_fe_mul(&r->z, &r->z, s); /* r->z *= s */ -} - -static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge *a) { - secp256k1_fe x, y; - VERIFY_CHECK(!a->infinity); - x = a->x; - secp256k1_fe_normalize(&x); - y = a->y; - secp256k1_fe_normalize(&y); - secp256k1_fe_to_storage(&r->x, &x); - secp256k1_fe_to_storage(&r->y, &y); -} - -static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a) { - secp256k1_fe_from_storage(&r->x, &a->x); - secp256k1_fe_from_storage(&r->y, &a->y); - r->infinity = 0; -} - -static SECP256K1_INLINE void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag) { - secp256k1_fe_storage_cmov(&r->x, &a->x, flag); - secp256k1_fe_storage_cmov(&r->y, &a->y, flag); -} - -#ifdef USE_ENDOMORPHISM -static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a) { - static const secp256k1_fe beta = SECP256K1_FE_CONST( - 0x7ae96a2bul, 0x657c0710ul, 0x6e64479eul, 0xac3434e9ul, - 0x9cf04975ul, 0x12f58995ul, 0xc1396c28ul, 0x719501eeul - ); - *r = *a; - secp256k1_fe_mul(&r->x, &r->x, &beta); -} -#endif - -static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a) { - secp256k1_fe yz; - - if (a->infinity) { - return 0; - } - - /* We rely on the fact that the Jacobi symbol of 1 / a->z^3 is the same as - * that of a->z. Thus a->y / a->z^3 is a quadratic residue iff a->y * a->z - is */ - secp256k1_fe_mul(&yz, &a->y, &a->z); - return secp256k1_fe_is_quad_var(&yz); -} - -#endif /* SECP256K1_GROUP_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/hash.h b/util/secp256k1/depend/secp256k1/src/hash.h deleted file mode 100644 index de26e4b89f..0000000000 --- a/util/secp256k1/depend/secp256k1/src/hash.h +++ /dev/null @@ -1,41 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_HASH_H -#define SECP256K1_HASH_H - -#include -#include - -typedef struct { - uint32_t s[8]; - uint32_t buf[16]; /* In big endian */ - size_t bytes; -} secp256k1_sha256; - -static void secp256k1_sha256_initialize(secp256k1_sha256 *hash); -static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size); -static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32); - -typedef struct { - secp256k1_sha256 inner, outer; -} secp256k1_hmac_sha256; - -static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t size); -static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size); -static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32); - -typedef struct { - unsigned char v[32]; - unsigned char k[32]; - int retry; -} secp256k1_rfc6979_hmac_sha256; - -static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen); -static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen); -static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng); - -#endif /* SECP256K1_HASH_H */ diff --git a/util/secp256k1/depend/secp256k1/src/hash_impl.h b/util/secp256k1/depend/secp256k1/src/hash_impl.h deleted file mode 100644 index c06db9e338..0000000000 --- a/util/secp256k1/depend/secp256k1/src/hash_impl.h +++ /dev/null @@ -1,281 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_HASH_IMPL_H -#define SECP256K1_HASH_IMPL_H - -#include "hash.h" - -#include -#include -#include - -#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) -#define Maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) -#define Sigma0(x) (((x) >> 2 | (x) << 30) ^ ((x) >> 13 | (x) << 19) ^ ((x) >> 22 | (x) << 10)) -#define Sigma1(x) (((x) >> 6 | (x) << 26) ^ ((x) >> 11 | (x) << 21) ^ ((x) >> 25 | (x) << 7)) -#define sigma0(x) (((x) >> 7 | (x) << 25) ^ ((x) >> 18 | (x) << 14) ^ ((x) >> 3)) -#define sigma1(x) (((x) >> 17 | (x) << 15) ^ ((x) >> 19 | (x) << 13) ^ ((x) >> 10)) - -#define Round(a,b,c,d,e,f,g,h,k,w) do { \ - uint32_t t1 = (h) + Sigma1(e) + Ch((e), (f), (g)) + (k) + (w); \ - uint32_t t2 = Sigma0(a) + Maj((a), (b), (c)); \ - (d) += t1; \ - (h) = t1 + t2; \ -} while(0) - -#ifdef WORDS_BIGENDIAN -#define BE32(x) (x) -#else -#define BE32(p) ((((p) & 0xFF) << 24) | (((p) & 0xFF00) << 8) | (((p) & 0xFF0000) >> 8) | (((p) & 0xFF000000) >> 24)) -#endif - -static void secp256k1_sha256_initialize(secp256k1_sha256 *hash) { - hash->s[0] = 0x6a09e667ul; - hash->s[1] = 0xbb67ae85ul; - hash->s[2] = 0x3c6ef372ul; - hash->s[3] = 0xa54ff53aul; - hash->s[4] = 0x510e527ful; - hash->s[5] = 0x9b05688cul; - hash->s[6] = 0x1f83d9abul; - hash->s[7] = 0x5be0cd19ul; - hash->bytes = 0; -} - -/** Perform one SHA-256 transformation, processing 16 big endian 32-bit words. */ -static void secp256k1_sha256_transform(uint32_t* s, const uint32_t* chunk) { - uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7]; - uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; - - Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = BE32(chunk[0])); - Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = BE32(chunk[1])); - Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = BE32(chunk[2])); - Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = BE32(chunk[3])); - Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = BE32(chunk[4])); - Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = BE32(chunk[5])); - Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = BE32(chunk[6])); - Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = BE32(chunk[7])); - Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = BE32(chunk[8])); - Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = BE32(chunk[9])); - Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = BE32(chunk[10])); - Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = BE32(chunk[11])); - Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = BE32(chunk[12])); - Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = BE32(chunk[13])); - Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = BE32(chunk[14])); - Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = BE32(chunk[15])); - - Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1)); - Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2)); - Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3)); - Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4)); - Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5)); - Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6)); - Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7)); - Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8)); - Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9)); - Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0)); - - Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1)); - Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2)); - Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3)); - Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4)); - Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5)); - Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6)); - Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7)); - Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8)); - Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9)); - Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0)); - - Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1)); - Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2)); - Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3)); - Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4)); - Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5)); - Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6)); - Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7)); - Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8)); - Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9)); - Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0)); - - s[0] += a; - s[1] += b; - s[2] += c; - s[3] += d; - s[4] += e; - s[5] += f; - s[6] += g; - s[7] += h; -} - -static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t len) { - size_t bufsize = hash->bytes & 0x3F; - hash->bytes += len; - while (bufsize + len >= 64) { - /* Fill the buffer, and process it. */ - memcpy(((unsigned char*)hash->buf) + bufsize, data, 64 - bufsize); - data += 64 - bufsize; - len -= 64 - bufsize; - secp256k1_sha256_transform(hash->s, hash->buf); - bufsize = 0; - } - if (len) { - /* Fill the buffer with what remains. */ - memcpy(((unsigned char*)hash->buf) + bufsize, data, len); - } -} - -static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32) { - static const unsigned char pad[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - uint32_t sizedesc[2]; - uint32_t out[8]; - int i = 0; - sizedesc[0] = BE32(hash->bytes >> 29); - sizedesc[1] = BE32(hash->bytes << 3); - secp256k1_sha256_write(hash, pad, 1 + ((119 - (hash->bytes % 64)) % 64)); - secp256k1_sha256_write(hash, (const unsigned char*)sizedesc, 8); - for (i = 0; i < 8; i++) { - out[i] = BE32(hash->s[i]); - hash->s[i] = 0; - } - memcpy(out32, (const unsigned char*)out, 32); -} - -static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t keylen) { - int n; - unsigned char rkey[64]; - if (keylen <= 64) { - memcpy(rkey, key, keylen); - memset(rkey + keylen, 0, 64 - keylen); - } else { - secp256k1_sha256 sha256; - secp256k1_sha256_initialize(&sha256); - secp256k1_sha256_write(&sha256, key, keylen); - secp256k1_sha256_finalize(&sha256, rkey); - memset(rkey + 32, 0, 32); - } - - secp256k1_sha256_initialize(&hash->outer); - for (n = 0; n < 64; n++) { - rkey[n] ^= 0x5c; - } - secp256k1_sha256_write(&hash->outer, rkey, 64); - - secp256k1_sha256_initialize(&hash->inner); - for (n = 0; n < 64; n++) { - rkey[n] ^= 0x5c ^ 0x36; - } - secp256k1_sha256_write(&hash->inner, rkey, 64); - memset(rkey, 0, 64); -} - -static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size) { - secp256k1_sha256_write(&hash->inner, data, size); -} - -static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32) { - unsigned char temp[32]; - secp256k1_sha256_finalize(&hash->inner, temp); - secp256k1_sha256_write(&hash->outer, temp, 32); - memset(temp, 0, 32); - secp256k1_sha256_finalize(&hash->outer, out32); -} - - -static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen) { - secp256k1_hmac_sha256 hmac; - static const unsigned char zero[1] = {0x00}; - static const unsigned char one[1] = {0x01}; - - memset(rng->v, 0x01, 32); /* RFC6979 3.2.b. */ - memset(rng->k, 0x00, 32); /* RFC6979 3.2.c. */ - - /* RFC6979 3.2.d. */ - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_write(&hmac, zero, 1); - secp256k1_hmac_sha256_write(&hmac, key, keylen); - secp256k1_hmac_sha256_finalize(&hmac, rng->k); - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_finalize(&hmac, rng->v); - - /* RFC6979 3.2.f. */ - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_write(&hmac, one, 1); - secp256k1_hmac_sha256_write(&hmac, key, keylen); - secp256k1_hmac_sha256_finalize(&hmac, rng->k); - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_finalize(&hmac, rng->v); - rng->retry = 0; -} - -static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen) { - /* RFC6979 3.2.h. */ - static const unsigned char zero[1] = {0x00}; - if (rng->retry) { - secp256k1_hmac_sha256 hmac; - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_write(&hmac, zero, 1); - secp256k1_hmac_sha256_finalize(&hmac, rng->k); - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_finalize(&hmac, rng->v); - } - - while (outlen > 0) { - secp256k1_hmac_sha256 hmac; - int now = outlen; - secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); - secp256k1_hmac_sha256_write(&hmac, rng->v, 32); - secp256k1_hmac_sha256_finalize(&hmac, rng->v); - if (now > 32) { - now = 32; - } - memcpy(out, rng->v, now); - out += now; - outlen -= now; - } - - rng->retry = 1; -} - -static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng) { - memset(rng->k, 0, 32); - memset(rng->v, 0, 32); - rng->retry = 0; -} - -#undef BE32 -#undef Round -#undef sigma1 -#undef sigma0 -#undef Sigma1 -#undef Sigma0 -#undef Maj -#undef Ch - -#endif /* SECP256K1_HASH_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java b/util/secp256k1/depend/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java deleted file mode 100644 index be67048fbe..0000000000 --- a/util/secp256k1/depend/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * Copyright 2014-2016 the libsecp256k1 contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.bitcoin; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import java.math.BigInteger; -import com.google.common.base.Preconditions; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import static org.bitcoin.NativeSecp256k1Util.*; - -/** - *

This class holds native methods to handle ECDSA verification.

- * - *

You can find an example library that can be used for this at https://github.com/bitcoin/secp256k1

- * - *

To build secp256k1 for use with bitcoinj, run - * `./configure --enable-jni --enable-experimental --enable-module-schnorr --enable-module-ecdh` - * and `make` then copy `.libs/libsecp256k1.so` to your system library path - * or point the JVM to the folder containing it with -Djava.library.path - *

- */ -public class NativeSecp256k1 { - - private static final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); - private static final Lock r = rwl.readLock(); - private static final Lock w = rwl.writeLock(); - private static ThreadLocal nativeECDSABuffer = new ThreadLocal(); - /** - * Verifies the given secp256k1 signature in native code. - * Calling when enabled == false is undefined (probably library not loaded) - * - * @param data The data which was signed, must be exactly 32 bytes - * @param signature The signature - * @param pub The public key which did the signing - */ - public static boolean verify(byte[] data, byte[] signature, byte[] pub) throws AssertFailException{ - Preconditions.checkArgument(data.length == 32 && signature.length <= 520 && pub.length <= 520); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < 520) { - byteBuff = ByteBuffer.allocateDirect(520); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(data); - byteBuff.put(signature); - byteBuff.put(pub); - - byte[][] retByteArray; - - r.lock(); - try { - return secp256k1_ecdsa_verify(byteBuff, Secp256k1Context.getContext(), signature.length, pub.length) == 1; - } finally { - r.unlock(); - } - } - - /** - * libsecp256k1 Create an ECDSA signature. - * - * @param data Message hash, 32 bytes - * @param key Secret key, 32 bytes - * - * Return values - * @param sig byte array of signature - */ - public static byte[] sign(byte[] data, byte[] sec) throws AssertFailException{ - Preconditions.checkArgument(data.length == 32 && sec.length <= 32); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < 32 + 32) { - byteBuff = ByteBuffer.allocateDirect(32 + 32); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(data); - byteBuff.put(sec); - - byte[][] retByteArray; - - r.lock(); - try { - retByteArray = secp256k1_ecdsa_sign(byteBuff, Secp256k1Context.getContext()); - } finally { - r.unlock(); - } - - byte[] sigArr = retByteArray[0]; - int sigLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); - int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); - - assertEquals(sigArr.length, sigLen, "Got bad signature length."); - - return retVal == 0 ? new byte[0] : sigArr; - } - - /** - * libsecp256k1 Seckey Verify - returns 1 if valid, 0 if invalid - * - * @param seckey ECDSA Secret key, 32 bytes - */ - public static boolean secKeyVerify(byte[] seckey) { - Preconditions.checkArgument(seckey.length == 32); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < seckey.length) { - byteBuff = ByteBuffer.allocateDirect(seckey.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(seckey); - - r.lock(); - try { - return secp256k1_ec_seckey_verify(byteBuff,Secp256k1Context.getContext()) == 1; - } finally { - r.unlock(); - } - } - - - /** - * libsecp256k1 Compute Pubkey - computes public key from secret key - * - * @param seckey ECDSA Secret key, 32 bytes - * - * Return values - * @param pubkey ECDSA Public key, 33 or 65 bytes - */ - //TODO add a 'compressed' arg - public static byte[] computePubkey(byte[] seckey) throws AssertFailException{ - Preconditions.checkArgument(seckey.length == 32); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < seckey.length) { - byteBuff = ByteBuffer.allocateDirect(seckey.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(seckey); - - byte[][] retByteArray; - - r.lock(); - try { - retByteArray = secp256k1_ec_pubkey_create(byteBuff, Secp256k1Context.getContext()); - } finally { - r.unlock(); - } - - byte[] pubArr = retByteArray[0]; - int pubLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); - int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); - - assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); - - return retVal == 0 ? new byte[0]: pubArr; - } - - /** - * libsecp256k1 Cleanup - This destroys the secp256k1 context object - * This should be called at the end of the program for proper cleanup of the context. - */ - public static synchronized void cleanup() { - w.lock(); - try { - secp256k1_destroy_context(Secp256k1Context.getContext()); - } finally { - w.unlock(); - } - } - - public static long cloneContext() { - r.lock(); - try { - return secp256k1_ctx_clone(Secp256k1Context.getContext()); - } finally { r.unlock(); } - } - - /** - * libsecp256k1 PrivKey Tweak-Mul - Tweak privkey by multiplying to it - * - * @param tweak some bytes to tweak with - * @param seckey 32-byte seckey - */ - public static byte[] privKeyTweakMul(byte[] privkey, byte[] tweak) throws AssertFailException{ - Preconditions.checkArgument(privkey.length == 32); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) { - byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(privkey); - byteBuff.put(tweak); - - byte[][] retByteArray; - r.lock(); - try { - retByteArray = secp256k1_privkey_tweak_mul(byteBuff,Secp256k1Context.getContext()); - } finally { - r.unlock(); - } - - byte[] privArr = retByteArray[0]; - - int privLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; - int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); - - assertEquals(privArr.length, privLen, "Got bad pubkey length."); - - assertEquals(retVal, 1, "Failed return value check."); - - return privArr; - } - - /** - * libsecp256k1 PrivKey Tweak-Add - Tweak privkey by adding to it - * - * @param tweak some bytes to tweak with - * @param seckey 32-byte seckey - */ - public static byte[] privKeyTweakAdd(byte[] privkey, byte[] tweak) throws AssertFailException{ - Preconditions.checkArgument(privkey.length == 32); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) { - byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(privkey); - byteBuff.put(tweak); - - byte[][] retByteArray; - r.lock(); - try { - retByteArray = secp256k1_privkey_tweak_add(byteBuff,Secp256k1Context.getContext()); - } finally { - r.unlock(); - } - - byte[] privArr = retByteArray[0]; - - int privLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; - int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); - - assertEquals(privArr.length, privLen, "Got bad pubkey length."); - - assertEquals(retVal, 1, "Failed return value check."); - - return privArr; - } - - /** - * libsecp256k1 PubKey Tweak-Add - Tweak pubkey by adding to it - * - * @param tweak some bytes to tweak with - * @param pubkey 32-byte seckey - */ - public static byte[] pubKeyTweakAdd(byte[] pubkey, byte[] tweak) throws AssertFailException{ - Preconditions.checkArgument(pubkey.length == 33 || pubkey.length == 65); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { - byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(pubkey); - byteBuff.put(tweak); - - byte[][] retByteArray; - r.lock(); - try { - retByteArray = secp256k1_pubkey_tweak_add(byteBuff,Secp256k1Context.getContext(), pubkey.length); - } finally { - r.unlock(); - } - - byte[] pubArr = retByteArray[0]; - - int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; - int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); - - assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); - - assertEquals(retVal, 1, "Failed return value check."); - - return pubArr; - } - - /** - * libsecp256k1 PubKey Tweak-Mul - Tweak pubkey by multiplying to it - * - * @param tweak some bytes to tweak with - * @param pubkey 32-byte seckey - */ - public static byte[] pubKeyTweakMul(byte[] pubkey, byte[] tweak) throws AssertFailException{ - Preconditions.checkArgument(pubkey.length == 33 || pubkey.length == 65); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { - byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(pubkey); - byteBuff.put(tweak); - - byte[][] retByteArray; - r.lock(); - try { - retByteArray = secp256k1_pubkey_tweak_mul(byteBuff,Secp256k1Context.getContext(), pubkey.length); - } finally { - r.unlock(); - } - - byte[] pubArr = retByteArray[0]; - - int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; - int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); - - assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); - - assertEquals(retVal, 1, "Failed return value check."); - - return pubArr; - } - - /** - * libsecp256k1 create ECDH secret - constant time ECDH calculation - * - * @param seckey byte array of secret key used in exponentiaion - * @param pubkey byte array of public key used in exponentiaion - */ - public static byte[] createECDHSecret(byte[] seckey, byte[] pubkey) throws AssertFailException{ - Preconditions.checkArgument(seckey.length <= 32 && pubkey.length <= 65); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < 32 + pubkey.length) { - byteBuff = ByteBuffer.allocateDirect(32 + pubkey.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(seckey); - byteBuff.put(pubkey); - - byte[][] retByteArray; - r.lock(); - try { - retByteArray = secp256k1_ecdh(byteBuff, Secp256k1Context.getContext(), pubkey.length); - } finally { - r.unlock(); - } - - byte[] resArr = retByteArray[0]; - int retVal = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); - - assertEquals(resArr.length, 32, "Got bad result length."); - assertEquals(retVal, 1, "Failed return value check."); - - return resArr; - } - - /** - * libsecp256k1 randomize - updates the context randomization - * - * @param seed 32-byte random seed - */ - public static synchronized boolean randomize(byte[] seed) throws AssertFailException{ - Preconditions.checkArgument(seed.length == 32 || seed == null); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null || byteBuff.capacity() < seed.length) { - byteBuff = ByteBuffer.allocateDirect(seed.length); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(seed); - - w.lock(); - try { - return secp256k1_context_randomize(byteBuff, Secp256k1Context.getContext()) == 1; - } finally { - w.unlock(); - } - } - - public static byte[] schnorrSign(byte[] data, byte[] sec) throws AssertFailException { - Preconditions.checkArgument(data.length == 32 && sec.length <= 32); - - ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null) { - byteBuff = ByteBuffer.allocateDirect(32 + 32); - byteBuff.order(ByteOrder.nativeOrder()); - nativeECDSABuffer.set(byteBuff); - } - byteBuff.rewind(); - byteBuff.put(data); - byteBuff.put(sec); - - byte[][] retByteArray; - - r.lock(); - try { - retByteArray = secp256k1_schnorr_sign(byteBuff, Secp256k1Context.getContext()); - } finally { - r.unlock(); - } - - byte[] sigArr = retByteArray[0]; - int retVal = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); - - assertEquals(sigArr.length, 64, "Got bad signature length."); - - return retVal == 0 ? new byte[0] : sigArr; - } - - private static native long secp256k1_ctx_clone(long context); - - private static native int secp256k1_context_randomize(ByteBuffer byteBuff, long context); - - private static native byte[][] secp256k1_privkey_tweak_add(ByteBuffer byteBuff, long context); - - private static native byte[][] secp256k1_privkey_tweak_mul(ByteBuffer byteBuff, long context); - - private static native byte[][] secp256k1_pubkey_tweak_add(ByteBuffer byteBuff, long context, int pubLen); - - private static native byte[][] secp256k1_pubkey_tweak_mul(ByteBuffer byteBuff, long context, int pubLen); - - private static native void secp256k1_destroy_context(long context); - - private static native int secp256k1_ecdsa_verify(ByteBuffer byteBuff, long context, int sigLen, int pubLen); - - private static native byte[][] secp256k1_ecdsa_sign(ByteBuffer byteBuff, long context); - - private static native int secp256k1_ec_seckey_verify(ByteBuffer byteBuff, long context); - - private static native byte[][] secp256k1_ec_pubkey_create(ByteBuffer byteBuff, long context); - - private static native byte[][] secp256k1_ec_pubkey_parse(ByteBuffer byteBuff, long context, int inputLen); - - private static native byte[][] secp256k1_schnorr_sign(ByteBuffer byteBuff, long context); - - private static native byte[][] secp256k1_ecdh(ByteBuffer byteBuff, long context, int inputLen); - -} diff --git a/util/secp256k1/depend/secp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java b/util/secp256k1/depend/secp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java deleted file mode 100644 index c00d08899b..0000000000 --- a/util/secp256k1/depend/secp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java +++ /dev/null @@ -1,226 +0,0 @@ -package org.bitcoin; - -import com.google.common.io.BaseEncoding; -import java.util.Arrays; -import java.math.BigInteger; -import javax.xml.bind.DatatypeConverter; -import static org.bitcoin.NativeSecp256k1Util.*; - -/** - * This class holds test cases defined for testing this library. - */ -public class NativeSecp256k1Test { - - //TODO improve comments/add more tests - /** - * This tests verify() for a valid signature - */ - public static void testVerifyPos() throws AssertFailException{ - boolean result = false; - byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing" - byte[] sig = BaseEncoding.base16().lowerCase().decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".toLowerCase()); - byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); - - result = NativeSecp256k1.verify( data, sig, pub); - assertEquals( result, true , "testVerifyPos"); - } - - /** - * This tests verify() for a non-valid signature - */ - public static void testVerifyNeg() throws AssertFailException{ - boolean result = false; - byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A91".toLowerCase()); //sha256hash of "testing" - byte[] sig = BaseEncoding.base16().lowerCase().decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".toLowerCase()); - byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); - - result = NativeSecp256k1.verify( data, sig, pub); - //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16)); - assertEquals( result, false , "testVerifyNeg"); - } - - /** - * This tests secret key verify() for a valid secretkey - */ - public static void testSecKeyVerifyPos() throws AssertFailException{ - boolean result = false; - byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); - - result = NativeSecp256k1.secKeyVerify( sec ); - //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16)); - assertEquals( result, true , "testSecKeyVerifyPos"); - } - - /** - * This tests secret key verify() for a invalid secretkey - */ - public static void testSecKeyVerifyNeg() throws AssertFailException{ - boolean result = false; - byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()); - - result = NativeSecp256k1.secKeyVerify( sec ); - //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16)); - assertEquals( result, false , "testSecKeyVerifyNeg"); - } - - /** - * This tests public key create() for a valid secretkey - */ - public static void testPubKeyCreatePos() throws AssertFailException{ - byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); - - byte[] resultArr = NativeSecp256k1.computePubkey( sec); - String pubkeyString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( pubkeyString , "04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D2103ED494718C697AC9AEBCFD19612E224DB46661011863ED2FC54E71861E2A6" , "testPubKeyCreatePos"); - } - - /** - * This tests public key create() for a invalid secretkey - */ - public static void testPubKeyCreateNeg() throws AssertFailException{ - byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()); - - byte[] resultArr = NativeSecp256k1.computePubkey( sec); - String pubkeyString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( pubkeyString, "" , "testPubKeyCreateNeg"); - } - - /** - * This tests sign() for a valid secretkey - */ - public static void testSignPos() throws AssertFailException{ - - byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing" - byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); - - byte[] resultArr = NativeSecp256k1.sign(data, sec); - String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( sigString, "30440220182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A202201C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9" , "testSignPos"); - } - - /** - * This tests sign() for a invalid secretkey - */ - public static void testSignNeg() throws AssertFailException{ - byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing" - byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()); - - byte[] resultArr = NativeSecp256k1.sign(data, sec); - String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( sigString, "" , "testSignNeg"); - } - - /** - * This tests private key tweak-add - */ - public static void testPrivKeyTweakAdd_1() throws AssertFailException { - byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); - byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" - - byte[] resultArr = NativeSecp256k1.privKeyTweakAdd( sec , data ); - String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( sigString , "A168571E189E6F9A7E2D657A4B53AE99B909F7E712D1C23CED28093CD57C88F3" , "testPrivKeyAdd_1"); - } - - /** - * This tests private key tweak-mul - */ - public static void testPrivKeyTweakMul_1() throws AssertFailException { - byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); - byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" - - byte[] resultArr = NativeSecp256k1.privKeyTweakMul( sec , data ); - String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( sigString , "97F8184235F101550F3C71C927507651BD3F1CDB4A5A33B8986ACF0DEE20FFFC" , "testPrivKeyMul_1"); - } - - /** - * This tests private key tweak-add uncompressed - */ - public static void testPrivKeyTweakAdd_2() throws AssertFailException { - byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); - byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" - - byte[] resultArr = NativeSecp256k1.pubKeyTweakAdd( pub , data ); - String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( sigString , "0411C6790F4B663CCE607BAAE08C43557EDC1A4D11D88DFCB3D841D0C6A941AF525A268E2A863C148555C48FB5FBA368E88718A46E205FABC3DBA2CCFFAB0796EF" , "testPrivKeyAdd_2"); - } - - /** - * This tests private key tweak-mul uncompressed - */ - public static void testPrivKeyTweakMul_2() throws AssertFailException { - byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); - byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" - - byte[] resultArr = NativeSecp256k1.pubKeyTweakMul( pub , data ); - String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( sigString , "04E0FE6FE55EBCA626B98A807F6CAF654139E14E5E3698F01A9A658E21DC1D2791EC060D4F412A794D5370F672BC94B722640B5F76914151CFCA6E712CA48CC589" , "testPrivKeyMul_2"); - } - - /** - * This tests seed randomization - */ - public static void testRandomize() throws AssertFailException { - byte[] seed = BaseEncoding.base16().lowerCase().decode("A441B15FE9A3CF56661190A0B93B9DEC7D04127288CC87250967CF3B52894D11".toLowerCase()); //sha256hash of "random" - boolean result = NativeSecp256k1.randomize(seed); - assertEquals( result, true, "testRandomize"); - } - - public static void testCreateECDHSecret() throws AssertFailException{ - - byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); - byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); - - byte[] resultArr = NativeSecp256k1.createECDHSecret(sec, pub); - String ecdhString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); - assertEquals( ecdhString, "2A2A67007A926E6594AF3EB564FC74005B37A9C8AEF2033C4552051B5C87F043" , "testCreateECDHSecret"); - } - - public static void main(String[] args) throws AssertFailException{ - - - System.out.println("\n libsecp256k1 enabled: " + Secp256k1Context.isEnabled() + "\n"); - - assertEquals( Secp256k1Context.isEnabled(), true, "isEnabled" ); - - //Test verify() success/fail - testVerifyPos(); - testVerifyNeg(); - - //Test secKeyVerify() success/fail - testSecKeyVerifyPos(); - testSecKeyVerifyNeg(); - - //Test computePubkey() success/fail - testPubKeyCreatePos(); - testPubKeyCreateNeg(); - - //Test sign() success/fail - testSignPos(); - testSignNeg(); - - //Test privKeyTweakAdd() 1 - testPrivKeyTweakAdd_1(); - - //Test privKeyTweakMul() 2 - testPrivKeyTweakMul_1(); - - //Test privKeyTweakAdd() 3 - testPrivKeyTweakAdd_2(); - - //Test privKeyTweakMul() 4 - testPrivKeyTweakMul_2(); - - //Test randomize() - testRandomize(); - - //Test ECDH - testCreateECDHSecret(); - - NativeSecp256k1.cleanup(); - - System.out.println(" All tests passed." ); - - } -} diff --git a/util/secp256k1/depend/secp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java b/util/secp256k1/depend/secp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java deleted file mode 100644 index 04732ba044..0000000000 --- a/util/secp256k1/depend/secp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2014-2016 the libsecp256k1 contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.bitcoin; - -public class NativeSecp256k1Util{ - - public static void assertEquals( int val, int val2, String message ) throws AssertFailException{ - if( val != val2 ) - throw new AssertFailException("FAIL: " + message); - } - - public static void assertEquals( boolean val, boolean val2, String message ) throws AssertFailException{ - if( val != val2 ) - throw new AssertFailException("FAIL: " + message); - else - System.out.println("PASS: " + message); - } - - public static void assertEquals( String val, String val2, String message ) throws AssertFailException{ - if( !val.equals(val2) ) - throw new AssertFailException("FAIL: " + message); - else - System.out.println("PASS: " + message); - } - - public static class AssertFailException extends Exception { - public AssertFailException(String message) { - super( message ); - } - } -} diff --git a/util/secp256k1/depend/secp256k1/src/java/org/bitcoin/Secp256k1Context.java b/util/secp256k1/depend/secp256k1/src/java/org/bitcoin/Secp256k1Context.java deleted file mode 100644 index 216c986a8b..0000000000 --- a/util/secp256k1/depend/secp256k1/src/java/org/bitcoin/Secp256k1Context.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2014-2016 the libsecp256k1 contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.bitcoin; - -/** - * This class holds the context reference used in native methods - * to handle ECDSA operations. - */ -public class Secp256k1Context { - private static final boolean enabled; //true if the library is loaded - private static final long context; //ref to pointer to context obj - - static { //static initializer - boolean isEnabled = true; - long contextRef = -1; - try { - System.loadLibrary("secp256k1"); - contextRef = secp256k1_init_context(); - } catch (UnsatisfiedLinkError e) { - System.out.println("UnsatisfiedLinkError: " + e.toString()); - isEnabled = false; - } - enabled = isEnabled; - context = contextRef; - } - - public static boolean isEnabled() { - return enabled; - } - - public static long getContext() { - if(!enabled) return -1; //sanity check - return context; - } - - private static native long secp256k1_init_context(); -} diff --git a/util/secp256k1/depend/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c b/util/secp256k1/depend/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c deleted file mode 100644 index dba9524dd4..0000000000 --- a/util/secp256k1/depend/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c +++ /dev/null @@ -1,411 +0,0 @@ -#include -#include -#include -#include "org_bitcoin_NativeSecp256k1.h" -#include "include/secp256k1.h" -#include "include/secp256k1_ecdh.h" -#include "include/secp256k1_recovery.h" -#include "include/secp256k1_schnorr.h" - - -SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ctx_1clone - (JNIEnv* env, jclass classObject, jlong ctx_l) -{ - const secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - - jlong ctx_clone_l = (uintptr_t) secp256k1_context_clone(ctx); - - (void)classObject;(void)env; - - return ctx_clone_l; - -} - -SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1context_1randomize - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - - const unsigned char* seed = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - - (void)classObject; - - return secp256k1_context_randomize(ctx, seed); - -} - -SECP256K1_API void JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1destroy_1context - (JNIEnv* env, jclass classObject, jlong ctx_l) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - - secp256k1_context_destroy(ctx); - - (void)classObject;(void)env; -} - -SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint siglen, jint publen) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - - unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - const unsigned char* sigdata = { (unsigned char*) (data + 32) }; - const unsigned char* pubdata = { (unsigned char*) (data + siglen + 32) }; - - secp256k1_ecdsa_signature sig; - secp256k1_pubkey pubkey; - - int ret = secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigdata, siglen); - - if( ret ) { - ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pubdata, publen); - - if( ret ) { - ret = secp256k1_ecdsa_verify(ctx, &sig, data, &pubkey); - } - } - - (void)classObject; - - return ret; -} - -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1sign - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - unsigned char* secKey = (unsigned char*) (data + 32); - - jobjectArray retArray; - jbyteArray sigArray, intsByteArray; - unsigned char intsarray[2]; - - secp256k1_ecdsa_signature sig[72]; - - int ret = secp256k1_ecdsa_sign(ctx, sig, data, secKey, NULL, NULL ); - - unsigned char outputSer[72]; - size_t outputLen = 72; - - if( ret ) { - int ret2 = secp256k1_ecdsa_signature_serialize_der(ctx,outputSer, &outputLen, sig ); (void)ret2; - } - - intsarray[0] = outputLen; - intsarray[1] = ret; - - retArray = (*env)->NewObjectArray(env, 2, - (*env)->FindClass(env, "[B"), - (*env)->NewByteArray(env, 1)); - - sigArray = (*env)->NewByteArray(env, outputLen); - (*env)->SetByteArrayRegion(env, sigArray, 0, outputLen, (jbyte*)outputSer); - (*env)->SetObjectArrayElement(env, retArray, 0, sigArray); - - intsByteArray = (*env)->NewByteArray(env, 2); - (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); - (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); - - (void)classObject; - - return retArray; -} - -SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1seckey_1verify - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - unsigned char* secKey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - - (void)classObject; - - return secp256k1_ec_seckey_verify(ctx, secKey); -} - -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1create - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - const unsigned char* secKey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - - secp256k1_pubkey pubkey; - - jobjectArray retArray; - jbyteArray pubkeyArray, intsByteArray; - unsigned char intsarray[2]; - - int ret = secp256k1_ec_pubkey_create(ctx, &pubkey, secKey); - - unsigned char outputSer[65]; - size_t outputLen = 65; - - if( ret ) { - int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey,SECP256K1_EC_UNCOMPRESSED );(void)ret2; - } - - intsarray[0] = outputLen; - intsarray[1] = ret; - - retArray = (*env)->NewObjectArray(env, 2, - (*env)->FindClass(env, "[B"), - (*env)->NewByteArray(env, 1)); - - pubkeyArray = (*env)->NewByteArray(env, outputLen); - (*env)->SetByteArrayRegion(env, pubkeyArray, 0, outputLen, (jbyte*)outputSer); - (*env)->SetObjectArrayElement(env, retArray, 0, pubkeyArray); - - intsByteArray = (*env)->NewByteArray(env, 2); - (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); - (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); - - (void)classObject; - - return retArray; - -} - -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1add - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - unsigned char* privkey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - const unsigned char* tweak = (unsigned char*) (privkey + 32); - - jobjectArray retArray; - jbyteArray privArray, intsByteArray; - unsigned char intsarray[2]; - - int privkeylen = 32; - - int ret = secp256k1_ec_privkey_tweak_add(ctx, privkey, tweak); - - intsarray[0] = privkeylen; - intsarray[1] = ret; - - retArray = (*env)->NewObjectArray(env, 2, - (*env)->FindClass(env, "[B"), - (*env)->NewByteArray(env, 1)); - - privArray = (*env)->NewByteArray(env, privkeylen); - (*env)->SetByteArrayRegion(env, privArray, 0, privkeylen, (jbyte*)privkey); - (*env)->SetObjectArrayElement(env, retArray, 0, privArray); - - intsByteArray = (*env)->NewByteArray(env, 2); - (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); - (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); - - (void)classObject; - - return retArray; -} - -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1mul - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - unsigned char* privkey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - const unsigned char* tweak = (unsigned char*) (privkey + 32); - - jobjectArray retArray; - jbyteArray privArray, intsByteArray; - unsigned char intsarray[2]; - - int privkeylen = 32; - - int ret = secp256k1_ec_privkey_tweak_mul(ctx, privkey, tweak); - - intsarray[0] = privkeylen; - intsarray[1] = ret; - - retArray = (*env)->NewObjectArray(env, 2, - (*env)->FindClass(env, "[B"), - (*env)->NewByteArray(env, 1)); - - privArray = (*env)->NewByteArray(env, privkeylen); - (*env)->SetByteArrayRegion(env, privArray, 0, privkeylen, (jbyte*)privkey); - (*env)->SetObjectArrayElement(env, retArray, 0, privArray); - - intsByteArray = (*env)->NewByteArray(env, 2); - (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); - (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); - - (void)classObject; - - return retArray; -} - -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1add - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; -/* secp256k1_pubkey* pubkey = (secp256k1_pubkey*) (*env)->GetDirectBufferAddress(env, byteBufferObject);*/ - unsigned char* pkey = (*env)->GetDirectBufferAddress(env, byteBufferObject); - const unsigned char* tweak = (unsigned char*) (pkey + publen); - - jobjectArray retArray; - jbyteArray pubArray, intsByteArray; - unsigned char intsarray[2]; - unsigned char outputSer[65]; - size_t outputLen = 65; - - secp256k1_pubkey pubkey; - int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pkey, publen); - - if( ret ) { - ret = secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, tweak); - } - - if( ret ) { - int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey,SECP256K1_EC_UNCOMPRESSED );(void)ret2; - } - - intsarray[0] = outputLen; - intsarray[1] = ret; - - retArray = (*env)->NewObjectArray(env, 2, - (*env)->FindClass(env, "[B"), - (*env)->NewByteArray(env, 1)); - - pubArray = (*env)->NewByteArray(env, outputLen); - (*env)->SetByteArrayRegion(env, pubArray, 0, outputLen, (jbyte*)outputSer); - (*env)->SetObjectArrayElement(env, retArray, 0, pubArray); - - intsByteArray = (*env)->NewByteArray(env, 2); - (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); - (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); - - (void)classObject; - - return retArray; -} - -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1mul - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - unsigned char* pkey = (*env)->GetDirectBufferAddress(env, byteBufferObject); - const unsigned char* tweak = (unsigned char*) (pkey + publen); - - jobjectArray retArray; - jbyteArray pubArray, intsByteArray; - unsigned char intsarray[2]; - unsigned char outputSer[65]; - size_t outputLen = 65; - - secp256k1_pubkey pubkey; - int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pkey, publen); - - if ( ret ) { - ret = secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, tweak); - } - - if( ret ) { - int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey,SECP256K1_EC_UNCOMPRESSED );(void)ret2; - } - - intsarray[0] = outputLen; - intsarray[1] = ret; - - retArray = (*env)->NewObjectArray(env, 2, - (*env)->FindClass(env, "[B"), - (*env)->NewByteArray(env, 1)); - - pubArray = (*env)->NewByteArray(env, outputLen); - (*env)->SetByteArrayRegion(env, pubArray, 0, outputLen, (jbyte*)outputSer); - (*env)->SetObjectArrayElement(env, retArray, 0, pubArray); - - intsByteArray = (*env)->NewByteArray(env, 2); - (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); - (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); - - (void)classObject; - - return retArray; -} - -SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1pubkey_1combine - (JNIEnv * env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint numkeys) -{ - (void)classObject;(void)env;(void)byteBufferObject;(void)ctx_l;(void)numkeys; - - return 0; -} - -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1schnorr_1sign - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - unsigned char* secKey = (unsigned char*) (data + 32); - - jobjectArray retArray; - jbyteArray sigArray, intsByteArray; - unsigned char intsarray[1]; - unsigned char sig[64]; - - int ret = secp256k1_schnorr_sign(ctx, sig, data, secKey, NULL, NULL); - - intsarray[0] = ret; - - retArray = (*env)->NewObjectArray(env, 2, - (*env)->FindClass(env, "[B"), - (*env)->NewByteArray(env, 1)); - - sigArray = (*env)->NewByteArray(env, 64); - (*env)->SetByteArrayRegion(env, sigArray, 0, 64, (jbyte*)sig); - (*env)->SetObjectArrayElement(env, retArray, 0, sigArray); - - intsByteArray = (*env)->NewByteArray(env, 1); - (*env)->SetByteArrayRegion(env, intsByteArray, 0, 1, (jbyte*)intsarray); - (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); - - (void)classObject; - - return retArray; -} - -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdh - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen) -{ - secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; - const unsigned char* secdata = (*env)->GetDirectBufferAddress(env, byteBufferObject); - const unsigned char* pubdata = (const unsigned char*) (secdata + 32); - - jobjectArray retArray; - jbyteArray outArray, intsByteArray; - unsigned char intsarray[1]; - secp256k1_pubkey pubkey; - unsigned char nonce_res[32]; - size_t outputLen = 32; - - int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pubdata, publen); - - if (ret) { - ret = secp256k1_ecdh( - ctx, - nonce_res, - &pubkey, - secdata - ); - } - - intsarray[0] = ret; - - retArray = (*env)->NewObjectArray(env, 2, - (*env)->FindClass(env, "[B"), - (*env)->NewByteArray(env, 1)); - - outArray = (*env)->NewByteArray(env, outputLen); - (*env)->SetByteArrayRegion(env, outArray, 0, 32, (jbyte*)nonce_res); - (*env)->SetObjectArrayElement(env, retArray, 0, outArray); - - intsByteArray = (*env)->NewByteArray(env, 1); - (*env)->SetByteArrayRegion(env, intsByteArray, 0, 1, (jbyte*)intsarray); - (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); - - (void)classObject; - - return retArray; -} diff --git a/util/secp256k1/depend/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h b/util/secp256k1/depend/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h deleted file mode 100644 index 4125a1f523..0000000000 --- a/util/secp256k1/depend/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h +++ /dev/null @@ -1,127 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include -#include "include/secp256k1.h" -/* Header for class org_bitcoin_NativeSecp256k1 */ - -#ifndef _Included_org_bitcoin_NativeSecp256k1 -#define _Included_org_bitcoin_NativeSecp256k1 -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ctx_clone - * Signature: (J)J - */ -SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ctx_1clone - (JNIEnv *, jclass, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_context_randomize - * Signature: (Ljava/nio/ByteBuffer;J)I - */ -SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1context_1randomize - (JNIEnv *, jclass, jobject, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_privkey_tweak_add - * Signature: (Ljava/nio/ByteBuffer;J)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1add - (JNIEnv *, jclass, jobject, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_privkey_tweak_mul - * Signature: (Ljava/nio/ByteBuffer;J)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1mul - (JNIEnv *, jclass, jobject, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_pubkey_tweak_add - * Signature: (Ljava/nio/ByteBuffer;JI)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1add - (JNIEnv *, jclass, jobject, jlong, jint); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_pubkey_tweak_mul - * Signature: (Ljava/nio/ByteBuffer;JI)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1mul - (JNIEnv *, jclass, jobject, jlong, jint); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_destroy_context - * Signature: (J)V - */ -SECP256K1_API void JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1destroy_1context - (JNIEnv *, jclass, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ecdsa_verify - * Signature: (Ljava/nio/ByteBuffer;JII)I - */ -SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify - (JNIEnv *, jclass, jobject, jlong, jint, jint); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ecdsa_sign - * Signature: (Ljava/nio/ByteBuffer;J)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1sign - (JNIEnv *, jclass, jobject, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ec_seckey_verify - * Signature: (Ljava/nio/ByteBuffer;J)I - */ -SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1seckey_1verify - (JNIEnv *, jclass, jobject, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ec_pubkey_create - * Signature: (Ljava/nio/ByteBuffer;J)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1create - (JNIEnv *, jclass, jobject, jlong); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ec_pubkey_parse - * Signature: (Ljava/nio/ByteBuffer;JI)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1parse - (JNIEnv *, jclass, jobject, jlong, jint); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_schnorr_sign - * Signature: (Ljava/nio/ByteBuffer;JI)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1schnorr_1sign - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l); - -/* - * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ecdh - * Signature: (Ljava/nio/ByteBuffer;JI)[[B - */ -SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdh - (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen); - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/util/secp256k1/depend/secp256k1/src/java/org_bitcoin_Secp256k1Context.c b/util/secp256k1/depend/secp256k1/src/java/org_bitcoin_Secp256k1Context.c deleted file mode 100644 index a52939e7e7..0000000000 --- a/util/secp256k1/depend/secp256k1/src/java/org_bitcoin_Secp256k1Context.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include -#include "org_bitcoin_Secp256k1Context.h" -#include "include/secp256k1.h" - -SECP256K1_API jlong JNICALL Java_org_bitcoin_Secp256k1Context_secp256k1_1init_1context - (JNIEnv* env, jclass classObject) -{ - secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - - (void)classObject;(void)env; - - return (uintptr_t)ctx; -} - diff --git a/util/secp256k1/depend/secp256k1/src/java/org_bitcoin_Secp256k1Context.h b/util/secp256k1/depend/secp256k1/src/java/org_bitcoin_Secp256k1Context.h deleted file mode 100644 index 0d2bc84b7f..0000000000 --- a/util/secp256k1/depend/secp256k1/src/java/org_bitcoin_Secp256k1Context.h +++ /dev/null @@ -1,22 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include -#include "include/secp256k1.h" -/* Header for class org_bitcoin_Secp256k1Context */ - -#ifndef _Included_org_bitcoin_Secp256k1Context -#define _Included_org_bitcoin_Secp256k1Context -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: org_bitcoin_Secp256k1Context - * Method: secp256k1_init_context - * Signature: ()J - */ -SECP256K1_API jlong JNICALL Java_org_bitcoin_Secp256k1Context_secp256k1_1init_1context - (JNIEnv *, jclass); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/util/secp256k1/depend/secp256k1/src/modules/ecdh/Makefile.am.include b/util/secp256k1/depend/secp256k1/src/modules/ecdh/Makefile.am.include deleted file mode 100644 index e3088b4697..0000000000 --- a/util/secp256k1/depend/secp256k1/src/modules/ecdh/Makefile.am.include +++ /dev/null @@ -1,8 +0,0 @@ -include_HEADERS += include/secp256k1_ecdh.h -noinst_HEADERS += src/modules/ecdh/main_impl.h -noinst_HEADERS += src/modules/ecdh/tests_impl.h -if USE_BENCHMARK -noinst_PROGRAMS += bench_ecdh -bench_ecdh_SOURCES = src/bench_ecdh.c -bench_ecdh_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB) -endif diff --git a/util/secp256k1/depend/secp256k1/src/modules/ecdh/main_impl.h b/util/secp256k1/depend/secp256k1/src/modules/ecdh/main_impl.h deleted file mode 100644 index bd8739eeb1..0000000000 --- a/util/secp256k1/depend/secp256k1/src/modules/ecdh/main_impl.h +++ /dev/null @@ -1,54 +0,0 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_MODULE_ECDH_MAIN_H -#define SECP256K1_MODULE_ECDH_MAIN_H - -#include "include/secp256k1_ecdh.h" -#include "ecmult_const_impl.h" - -int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *result, const secp256k1_pubkey *point, const unsigned char *scalar) { - int ret = 0; - int overflow = 0; - secp256k1_gej res; - secp256k1_ge pt; - secp256k1_scalar s; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(result != NULL); - ARG_CHECK(point != NULL); - ARG_CHECK(scalar != NULL); - - secp256k1_pubkey_load(ctx, &pt, point); - secp256k1_scalar_set_b32(&s, scalar, &overflow); - if (overflow || secp256k1_scalar_is_zero(&s)) { - ret = 0; - } else { - unsigned char x[32]; - unsigned char y[1]; - secp256k1_sha256 sha; - - secp256k1_ecmult_const(&res, &pt, &s); - secp256k1_ge_set_gej(&pt, &res); - /* Compute a hash of the point in compressed form - * Note we cannot use secp256k1_eckey_pubkey_serialize here since it does not - * expect its output to be secret and has a timing sidechannel. */ - secp256k1_fe_normalize(&pt.x); - secp256k1_fe_normalize(&pt.y); - secp256k1_fe_get_b32(x, &pt.x); - y[0] = 0x02 | secp256k1_fe_is_odd(&pt.y); - - secp256k1_sha256_initialize(&sha); - secp256k1_sha256_write(&sha, y, sizeof(y)); - secp256k1_sha256_write(&sha, x, sizeof(x)); - secp256k1_sha256_finalize(&sha, result); - ret = 1; - } - - secp256k1_scalar_clear(&s); - return ret; -} - -#endif /* SECP256K1_MODULE_ECDH_MAIN_H */ diff --git a/util/secp256k1/depend/secp256k1/src/modules/ecdh/tests_impl.h b/util/secp256k1/depend/secp256k1/src/modules/ecdh/tests_impl.h deleted file mode 100644 index 0c53f8ee08..0000000000 --- a/util/secp256k1/depend/secp256k1/src/modules/ecdh/tests_impl.h +++ /dev/null @@ -1,105 +0,0 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_MODULE_ECDH_TESTS_H -#define SECP256K1_MODULE_ECDH_TESTS_H - -void test_ecdh_api(void) { - /* Setup context that just counts errors */ - secp256k1_context *tctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); - secp256k1_pubkey point; - unsigned char res[32]; - unsigned char s_one[32] = { 0 }; - int32_t ecount = 0; - s_one[31] = 1; - - secp256k1_context_set_error_callback(tctx, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_illegal_callback(tctx, counting_illegal_callback_fn, &ecount); - CHECK(secp256k1_ec_pubkey_create(tctx, &point, s_one) == 1); - - /* Check all NULLs are detected */ - CHECK(secp256k1_ecdh(tctx, res, &point, s_one) == 1); - CHECK(ecount == 0); - CHECK(secp256k1_ecdh(tctx, NULL, &point, s_one) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ecdh(tctx, res, NULL, s_one) == 0); - CHECK(ecount == 2); - CHECK(secp256k1_ecdh(tctx, res, &point, NULL) == 0); - CHECK(ecount == 3); - CHECK(secp256k1_ecdh(tctx, res, &point, s_one) == 1); - CHECK(ecount == 3); - - /* Cleanup */ - secp256k1_context_destroy(tctx); -} - -void test_ecdh_generator_basepoint(void) { - unsigned char s_one[32] = { 0 }; - secp256k1_pubkey point[2]; - int i; - - s_one[31] = 1; - /* Check against pubkey creation when the basepoint is the generator */ - for (i = 0; i < 100; ++i) { - secp256k1_sha256 sha; - unsigned char s_b32[32]; - unsigned char output_ecdh[32]; - unsigned char output_ser[32]; - unsigned char point_ser[33]; - size_t point_ser_len = sizeof(point_ser); - secp256k1_scalar s; - - random_scalar_order(&s); - secp256k1_scalar_get_b32(s_b32, &s); - - /* compute using ECDH function */ - CHECK(secp256k1_ec_pubkey_create(ctx, &point[0], s_one) == 1); - CHECK(secp256k1_ecdh(ctx, output_ecdh, &point[0], s_b32) == 1); - /* compute "explicitly" */ - CHECK(secp256k1_ec_pubkey_create(ctx, &point[1], s_b32) == 1); - CHECK(secp256k1_ec_pubkey_serialize(ctx, point_ser, &point_ser_len, &point[1], SECP256K1_EC_COMPRESSED) == 1); - CHECK(point_ser_len == sizeof(point_ser)); - secp256k1_sha256_initialize(&sha); - secp256k1_sha256_write(&sha, point_ser, point_ser_len); - secp256k1_sha256_finalize(&sha, output_ser); - /* compare */ - CHECK(memcmp(output_ecdh, output_ser, sizeof(output_ser)) == 0); - } -} - -void test_bad_scalar(void) { - unsigned char s_zero[32] = { 0 }; - unsigned char s_overflow[32] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, - 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41 - }; - unsigned char s_rand[32] = { 0 }; - unsigned char output[32]; - secp256k1_scalar rand; - secp256k1_pubkey point; - - /* Create random point */ - random_scalar_order(&rand); - secp256k1_scalar_get_b32(s_rand, &rand); - CHECK(secp256k1_ec_pubkey_create(ctx, &point, s_rand) == 1); - - /* Try to multiply it by bad values */ - CHECK(secp256k1_ecdh(ctx, output, &point, s_zero) == 0); - CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow) == 0); - /* ...and a good one */ - s_overflow[31] -= 1; - CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow) == 1); -} - -void run_ecdh_tests(void) { - test_ecdh_api(); - test_ecdh_generator_basepoint(); - test_bad_scalar(); -} - -#endif /* SECP256K1_MODULE_ECDH_TESTS_H */ diff --git a/util/secp256k1/depend/secp256k1/src/modules/recovery/Makefile.am.include b/util/secp256k1/depend/secp256k1/src/modules/recovery/Makefile.am.include deleted file mode 100644 index bf23c26e71..0000000000 --- a/util/secp256k1/depend/secp256k1/src/modules/recovery/Makefile.am.include +++ /dev/null @@ -1,8 +0,0 @@ -include_HEADERS += include/secp256k1_recovery.h -noinst_HEADERS += src/modules/recovery/main_impl.h -noinst_HEADERS += src/modules/recovery/tests_impl.h -if USE_BENCHMARK -noinst_PROGRAMS += bench_recover -bench_recover_SOURCES = src/bench_recover.c -bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB) -endif diff --git a/util/secp256k1/depend/secp256k1/src/modules/recovery/main_impl.h b/util/secp256k1/depend/secp256k1/src/modules/recovery/main_impl.h deleted file mode 100644 index 2f6691c5a1..0000000000 --- a/util/secp256k1/depend/secp256k1/src/modules/recovery/main_impl.h +++ /dev/null @@ -1,193 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_MODULE_RECOVERY_MAIN_H -#define SECP256K1_MODULE_RECOVERY_MAIN_H - -#include "include/secp256k1_recovery.h" - -static void secp256k1_ecdsa_recoverable_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, int* recid, const secp256k1_ecdsa_recoverable_signature* sig) { - (void)ctx; - if (sizeof(secp256k1_scalar) == 32) { - /* When the secp256k1_scalar type is exactly 32 byte, use its - * representation inside secp256k1_ecdsa_signature, as conversion is very fast. - * Note that secp256k1_ecdsa_signature_save must use the same representation. */ - memcpy(r, &sig->data[0], 32); - memcpy(s, &sig->data[32], 32); - } else { - secp256k1_scalar_set_b32(r, &sig->data[0], NULL); - secp256k1_scalar_set_b32(s, &sig->data[32], NULL); - } - *recid = sig->data[64]; -} - -static void secp256k1_ecdsa_recoverable_signature_save(secp256k1_ecdsa_recoverable_signature* sig, const secp256k1_scalar* r, const secp256k1_scalar* s, int recid) { - if (sizeof(secp256k1_scalar) == 32) { - memcpy(&sig->data[0], r, 32); - memcpy(&sig->data[32], s, 32); - } else { - secp256k1_scalar_get_b32(&sig->data[0], r); - secp256k1_scalar_get_b32(&sig->data[32], s); - } - sig->data[64] = recid; -} - -int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature* sig, const unsigned char *input64, int recid) { - secp256k1_scalar r, s; - int ret = 1; - int overflow = 0; - - (void)ctx; - ARG_CHECK(sig != NULL); - ARG_CHECK(input64 != NULL); - ARG_CHECK(recid >= 0 && recid <= 3); - - secp256k1_scalar_set_b32(&r, &input64[0], &overflow); - ret &= !overflow; - secp256k1_scalar_set_b32(&s, &input64[32], &overflow); - ret &= !overflow; - if (ret) { - secp256k1_ecdsa_recoverable_signature_save(sig, &r, &s, recid); - } else { - memset(sig, 0, sizeof(*sig)); - } - return ret; -} - -int secp256k1_ecdsa_recoverable_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, int *recid, const secp256k1_ecdsa_recoverable_signature* sig) { - secp256k1_scalar r, s; - - (void)ctx; - ARG_CHECK(output64 != NULL); - ARG_CHECK(sig != NULL); - ARG_CHECK(recid != NULL); - - secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, recid, sig); - secp256k1_scalar_get_b32(&output64[0], &r); - secp256k1_scalar_get_b32(&output64[32], &s); - return 1; -} - -int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const secp256k1_ecdsa_recoverable_signature* sigin) { - secp256k1_scalar r, s; - int recid; - - (void)ctx; - ARG_CHECK(sig != NULL); - ARG_CHECK(sigin != NULL); - - secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, sigin); - secp256k1_ecdsa_signature_save(sig, &r, &s); - return 1; -} - -static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar* sigs, secp256k1_ge *pubkey, const secp256k1_scalar *message, int recid) { - unsigned char brx[32]; - secp256k1_fe fx; - secp256k1_ge x; - secp256k1_gej xj; - secp256k1_scalar rn, u1, u2; - secp256k1_gej qj; - int r; - - if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) { - return 0; - } - - secp256k1_scalar_get_b32(brx, sigr); - r = secp256k1_fe_set_b32(&fx, brx); - (void)r; - VERIFY_CHECK(r); /* brx comes from a scalar, so is less than the order; certainly less than p */ - if (recid & 2) { - if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0) { - return 0; - } - secp256k1_fe_add(&fx, &secp256k1_ecdsa_const_order_as_fe); - } - if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) { - return 0; - } - secp256k1_gej_set_ge(&xj, &x); - secp256k1_scalar_inverse_var(&rn, sigr); - secp256k1_scalar_mul(&u1, &rn, message); - secp256k1_scalar_negate(&u1, &u1); - secp256k1_scalar_mul(&u2, &rn, sigs); - secp256k1_ecmult(ctx, &qj, &xj, &u2, &u1); - secp256k1_ge_set_gej_var(pubkey, &qj); - return !secp256k1_gej_is_infinity(&qj); -} - -int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { - secp256k1_scalar r, s; - secp256k1_scalar sec, non, msg; - int recid; - int ret = 0; - int overflow = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(signature != NULL); - ARG_CHECK(seckey != NULL); - if (noncefp == NULL) { - noncefp = secp256k1_nonce_function_default; - } - - secp256k1_scalar_set_b32(&sec, seckey, &overflow); - /* Fail if the secret key is invalid. */ - if (!overflow && !secp256k1_scalar_is_zero(&sec)) { - unsigned char nonce32[32]; - unsigned int count = 0; - secp256k1_scalar_set_b32(&msg, msg32, NULL); - while (1) { - ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); - if (!ret) { - break; - } - secp256k1_scalar_set_b32(&non, nonce32, &overflow); - if (!secp256k1_scalar_is_zero(&non) && !overflow) { - if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, &recid)) { - break; - } - } - count++; - } - memset(nonce32, 0, 32); - secp256k1_scalar_clear(&msg); - secp256k1_scalar_clear(&non); - secp256k1_scalar_clear(&sec); - } - if (ret) { - secp256k1_ecdsa_recoverable_signature_save(signature, &r, &s, recid); - } else { - memset(signature, 0, sizeof(*signature)); - } - return ret; -} - -int secp256k1_ecdsa_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32) { - secp256k1_ge q; - secp256k1_scalar r, s; - secp256k1_scalar m; - int recid; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(signature != NULL); - ARG_CHECK(pubkey != NULL); - - secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, signature); - VERIFY_CHECK(recid >= 0 && recid < 4); /* should have been caught in parse_compact */ - secp256k1_scalar_set_b32(&m, msg32, NULL); - if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &r, &s, &q, &m, recid)) { - secp256k1_pubkey_save(pubkey, &q); - return 1; - } else { - memset(pubkey, 0, sizeof(*pubkey)); - return 0; - } -} - -#endif /* SECP256K1_MODULE_RECOVERY_MAIN_H */ diff --git a/util/secp256k1/depend/secp256k1/src/modules/recovery/tests_impl.h b/util/secp256k1/depend/secp256k1/src/modules/recovery/tests_impl.h deleted file mode 100644 index 5c9bbe8610..0000000000 --- a/util/secp256k1/depend/secp256k1/src/modules/recovery/tests_impl.h +++ /dev/null @@ -1,393 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_MODULE_RECOVERY_TESTS_H -#define SECP256K1_MODULE_RECOVERY_TESTS_H - -static int recovery_test_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { - (void) msg32; - (void) key32; - (void) algo16; - (void) data; - - /* On the first run, return 0 to force a second run */ - if (counter == 0) { - memset(nonce32, 0, 32); - return 1; - } - /* On the second run, return an overflow to force a third run */ - if (counter == 1) { - memset(nonce32, 0xff, 32); - return 1; - } - /* On the next run, return a valid nonce, but flip a coin as to whether or not to fail signing. */ - memset(nonce32, 1, 32); - return secp256k1_rand_bits(1); -} - -void test_ecdsa_recovery_api(void) { - /* Setup contexts that just count errors */ - secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE); - secp256k1_context *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); - secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); - secp256k1_context *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - secp256k1_pubkey pubkey; - secp256k1_pubkey recpubkey; - secp256k1_ecdsa_signature normal_sig; - secp256k1_ecdsa_recoverable_signature recsig; - unsigned char privkey[32] = { 1 }; - unsigned char message[32] = { 2 }; - int32_t ecount = 0; - int recid = 0; - unsigned char sig[74]; - unsigned char zero_privkey[32] = { 0 }; - unsigned char over_privkey[32] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - - secp256k1_context_set_error_callback(none, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_error_callback(vrfy, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_error_callback(both, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_illegal_callback(both, counting_illegal_callback_fn, &ecount); - - /* Construct and verify corresponding public key. */ - CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); - - /* Check bad contexts and NULLs for signing */ - ecount = 0; - CHECK(secp256k1_ecdsa_sign_recoverable(none, &recsig, message, privkey, NULL, NULL) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ecdsa_sign_recoverable(sign, &recsig, message, privkey, NULL, NULL) == 1); - CHECK(ecount == 1); - CHECK(secp256k1_ecdsa_sign_recoverable(vrfy, &recsig, message, privkey, NULL, NULL) == 0); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, NULL, NULL) == 1); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_sign_recoverable(both, NULL, message, privkey, NULL, NULL) == 0); - CHECK(ecount == 3); - CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, NULL, privkey, NULL, NULL) == 0); - CHECK(ecount == 4); - CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, NULL, NULL, NULL) == 0); - CHECK(ecount == 5); - /* This will fail or succeed randomly, and in either case will not ARG_CHECK failure */ - secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, recovery_test_nonce_function, NULL); - CHECK(ecount == 5); - /* These will all fail, but not in ARG_CHECK way */ - CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, zero_privkey, NULL, NULL) == 0); - CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, over_privkey, NULL, NULL) == 0); - /* This one will succeed. */ - CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, NULL, NULL) == 1); - CHECK(ecount == 5); - - /* Check signing with a goofy nonce function */ - - /* Check bad contexts and NULLs for recovery */ - ecount = 0; - CHECK(secp256k1_ecdsa_recover(none, &recpubkey, &recsig, message) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ecdsa_recover(sign, &recpubkey, &recsig, message) == 0); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_recover(vrfy, &recpubkey, &recsig, message) == 1); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_recover(both, &recpubkey, &recsig, message) == 1); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_recover(both, NULL, &recsig, message) == 0); - CHECK(ecount == 3); - CHECK(secp256k1_ecdsa_recover(both, &recpubkey, NULL, message) == 0); - CHECK(ecount == 4); - CHECK(secp256k1_ecdsa_recover(both, &recpubkey, &recsig, NULL) == 0); - CHECK(ecount == 5); - - /* Check NULLs for conversion */ - CHECK(secp256k1_ecdsa_sign(both, &normal_sig, message, privkey, NULL, NULL) == 1); - ecount = 0; - CHECK(secp256k1_ecdsa_recoverable_signature_convert(both, NULL, &recsig) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ecdsa_recoverable_signature_convert(both, &normal_sig, NULL) == 0); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_recoverable_signature_convert(both, &normal_sig, &recsig) == 1); - - /* Check NULLs for de/serialization */ - CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, NULL, NULL) == 1); - ecount = 0; - CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, NULL, &recid, &recsig) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, sig, NULL, &recsig) == 0); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, sig, &recid, NULL) == 0); - CHECK(ecount == 3); - CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, sig, &recid, &recsig) == 1); - - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, NULL, sig, recid) == 0); - CHECK(ecount == 4); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, NULL, recid) == 0); - CHECK(ecount == 5); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, sig, -1) == 0); - CHECK(ecount == 6); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, sig, 5) == 0); - CHECK(ecount == 7); - /* overflow in signature will fail but not affect ecount */ - memcpy(sig, over_privkey, 32); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, sig, recid) == 0); - CHECK(ecount == 7); - - /* cleanup */ - secp256k1_context_destroy(none); - secp256k1_context_destroy(sign); - secp256k1_context_destroy(vrfy); - secp256k1_context_destroy(both); -} - -void test_ecdsa_recovery_end_to_end(void) { - unsigned char extra[32] = {0x00}; - unsigned char privkey[32]; - unsigned char message[32]; - secp256k1_ecdsa_signature signature[5]; - secp256k1_ecdsa_recoverable_signature rsignature[5]; - unsigned char sig[74]; - secp256k1_pubkey pubkey; - secp256k1_pubkey recpubkey; - int recid = 0; - - /* Generate a random key and message. */ - { - secp256k1_scalar msg, key; - random_scalar_order_test(&msg); - random_scalar_order_test(&key); - secp256k1_scalar_get_b32(privkey, &key); - secp256k1_scalar_get_b32(message, &msg); - } - - /* Construct and verify corresponding public key. */ - CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); - - /* Serialize/parse compact and verify/recover. */ - extra[0] = 0; - CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[0], message, privkey, NULL, NULL) == 1); - CHECK(secp256k1_ecdsa_sign(ctx, &signature[0], message, privkey, NULL, NULL) == 1); - CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[4], message, privkey, NULL, NULL) == 1); - CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[1], message, privkey, NULL, extra) == 1); - extra[31] = 1; - CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[2], message, privkey, NULL, extra) == 1); - extra[31] = 0; - extra[0] = 1; - CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[3], message, privkey, NULL, extra) == 1); - CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1); - CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1); - CHECK(memcmp(&signature[4], &signature[0], 64) == 0); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1); - memset(&rsignature[4], 0, sizeof(rsignature[4])); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1); - CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1); - /* Parse compact (with recovery id) and recover. */ - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1); - CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 1); - CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0); - /* Serialize/destroy/parse signature and verify again. */ - CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1); - sig[secp256k1_rand_bits(6)] += 1 + secp256k1_rand_int(255); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1); - CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 0); - /* Recover again */ - CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 0 || - memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0); -} - -/* Tests several edge cases. */ -void test_ecdsa_recovery_edge_cases(void) { - const unsigned char msg32[32] = { - 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', - 'a', ' ', 'v', 'e', 'r', 'y', ' ', 's', - 'e', 'c', 'r', 'e', 't', ' ', 'm', 'e', - 's', 's', 'a', 'g', 'e', '.', '.', '.' - }; - const unsigned char sig64[64] = { - /* Generated by signing the above message with nonce 'This is the nonce we will use...' - * and secret key 0 (which is not valid), resulting in recid 0. */ - 0x67, 0xCB, 0x28, 0x5F, 0x9C, 0xD1, 0x94, 0xE8, - 0x40, 0xD6, 0x29, 0x39, 0x7A, 0xF5, 0x56, 0x96, - 0x62, 0xFD, 0xE4, 0x46, 0x49, 0x99, 0x59, 0x63, - 0x17, 0x9A, 0x7D, 0xD1, 0x7B, 0xD2, 0x35, 0x32, - 0x4B, 0x1B, 0x7D, 0xF3, 0x4C, 0xE1, 0xF6, 0x8E, - 0x69, 0x4F, 0xF6, 0xF1, 0x1A, 0xC7, 0x51, 0xDD, - 0x7D, 0xD7, 0x3E, 0x38, 0x7E, 0xE4, 0xFC, 0x86, - 0x6E, 0x1B, 0xE8, 0xEC, 0xC7, 0xDD, 0x95, 0x57 - }; - secp256k1_pubkey pubkey; - /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */ - const unsigned char sigb64[64] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - }; - secp256k1_pubkey pubkeyb; - secp256k1_ecdsa_recoverable_signature rsig; - secp256k1_ecdsa_signature sig; - int recid; - - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 0)); - CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 1)); - CHECK(secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 2)); - CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 3)); - CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); - - for (recid = 0; recid < 4; recid++) { - int i; - int recid2; - /* (4,4) encoded in DER. */ - unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04}; - unsigned char sigcder_zr[7] = {0x30, 0x05, 0x02, 0x00, 0x02, 0x01, 0x01}; - unsigned char sigcder_zs[7] = {0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x00}; - unsigned char sigbderalt1[39] = { - 0x30, 0x25, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04, - }; - unsigned char sigbderalt2[39] = { - 0x30, 0x25, 0x02, 0x01, 0x04, 0x02, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - }; - unsigned char sigbderalt3[40] = { - 0x30, 0x26, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04, - }; - unsigned char sigbderalt4[40] = { - 0x30, 0x26, 0x02, 0x01, 0x04, 0x02, 0x21, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - }; - /* (order + r,4) encoded in DER. */ - unsigned char sigbderlong[40] = { - 0x30, 0x26, 0x02, 0x21, 0x00, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, - 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, - 0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04 - }; - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid) == 1); - CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 1); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1); - for (recid2 = 0; recid2 < 4; recid2++) { - secp256k1_pubkey pubkey2b; - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid2) == 1); - CHECK(secp256k1_ecdsa_recover(ctx, &pubkey2b, &rsig, msg32) == 1); - /* Verifying with (order + r,4) should always fail. */ - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderlong, sizeof(sigbderlong)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); - } - /* DER parsing tests. */ - /* Zero length r/s. */ - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder_zr, sizeof(sigcder_zr)) == 0); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder_zs, sizeof(sigcder_zs)) == 0); - /* Leading zeros. */ - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt1, sizeof(sigbderalt1)) == 0); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt2, sizeof(sigbderalt2)) == 0); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 0); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt4, sizeof(sigbderalt4)) == 0); - sigbderalt3[4] = 1; - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); - sigbderalt4[7] = 1; - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt4, sizeof(sigbderalt4)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); - /* Damage signature. */ - sigbder[7]++; - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); - sigbder[7]--; - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, 6) == 0); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder) - 1) == 0); - for(i = 0; i < 8; i++) { - int c; - unsigned char orig = sigbder[i]; - /*Try every single-byte change.*/ - for (c = 0; c < 256; c++) { - if (c == orig ) { - continue; - } - sigbder[i] = c; - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 0 || secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); - } - sigbder[i] = orig; - } - } - - /* Test r/s equal to zero */ - { - /* (1,1) encoded in DER. */ - unsigned char sigcder[8] = {0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01}; - unsigned char sigc64[64] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - }; - secp256k1_pubkey pubkeyc; - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1); - CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyc, &rsig, msg32) == 1); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 1); - sigcder[4] = 0; - sigc64[31] = 0; - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1); - CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0); - sigcder[4] = 1; - sigcder[7] = 0; - sigc64[31] = 1; - sigc64[63] = 0; - CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1); - CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0); - } -} - -void run_recovery_tests(void) { - int i; - for (i = 0; i < count; i++) { - test_ecdsa_recovery_api(); - } - for (i = 0; i < 64*count; i++) { - test_ecdsa_recovery_end_to_end(); - } - test_ecdsa_recovery_edge_cases(); -} - -#endif /* SECP256K1_MODULE_RECOVERY_TESTS_H */ diff --git a/util/secp256k1/depend/secp256k1/src/modules/schnorr/Makefile.am.include b/util/secp256k1/depend/secp256k1/src/modules/schnorr/Makefile.am.include deleted file mode 100644 index f1af8e8325..0000000000 --- a/util/secp256k1/depend/secp256k1/src/modules/schnorr/Makefile.am.include +++ /dev/null @@ -1,10 +0,0 @@ -include_HEADERS += include/secp256k1_schnorr.h -noinst_HEADERS += src/modules/schnorr/main_impl.h -noinst_HEADERS += src/modules/schnorr/schnorr.h -noinst_HEADERS += src/modules/schnorr/schnorr_impl.h -noinst_HEADERS += src/modules/schnorr/tests_impl.h -if USE_BENCHMARK -noinst_PROGRAMS += bench_schnorr_verify -bench_schnorr_verify_SOURCES = src/bench_schnorr_verify.c -bench_schnorr_verify_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB) -endif diff --git a/util/secp256k1/depend/secp256k1/src/modules/schnorr/main_impl.h b/util/secp256k1/depend/secp256k1/src/modules/schnorr/main_impl.h deleted file mode 100644 index 60277d7dad..0000000000 --- a/util/secp256k1/depend/secp256k1/src/modules/schnorr/main_impl.h +++ /dev/null @@ -1,164 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_MODULE_SCHNORR_MAIN -#define SECP256K1_MODULE_SCHNORR_MAIN - -#include "include/secp256k1_schnorr.h" -#include "modules/schnorr/schnorr_impl.h" - -static void secp256k1_schnorr_msghash_sha256(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32) { - secp256k1_sha256 sha; - secp256k1_sha256_initialize(&sha); - secp256k1_sha256_write(&sha, r32, 32); - secp256k1_sha256_write(&sha, msg32, 32); - secp256k1_sha256_finalize(&sha, h32); -} - -static const unsigned char secp256k1_schnorr_algo16[17] = "Schnorr+SHA256 "; - -int secp256k1_schnorr_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { - secp256k1_scalar sec, non; - int ret = 0; - int overflow = 0; - unsigned int count = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sig64 != NULL); - ARG_CHECK(seckey != NULL); - if (noncefp == NULL) { - noncefp = secp256k1_nonce_function_default; - } - - secp256k1_scalar_set_b32(&sec, seckey, NULL); - while (1) { - unsigned char nonce32[32]; - ret = noncefp(nonce32, msg32, seckey, secp256k1_schnorr_algo16, (void*)noncedata, count); - if (!ret) { - break; - } - secp256k1_scalar_set_b32(&non, nonce32, &overflow); - memset(nonce32, 0, 32); - if (!secp256k1_scalar_is_zero(&non) && !overflow) { - if (secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64, &sec, &non, NULL, secp256k1_schnorr_msghash_sha256, msg32)) { - break; - } - } - count++; - } - if (!ret) { - memset(sig64, 0, 64); - } - secp256k1_scalar_clear(&non); - secp256k1_scalar_clear(&sec); - return ret; -} - -int secp256k1_schnorr_verify(const secp256k1_context* ctx, const unsigned char *sig64, const unsigned char *msg32, const secp256k1_pubkey *pubkey) { - secp256k1_ge q; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sig64 != NULL); - ARG_CHECK(pubkey != NULL); - - secp256k1_pubkey_load(ctx, &q, pubkey); - return secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64, &q, secp256k1_schnorr_msghash_sha256, msg32); -} - -int secp256k1_schnorr_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *sig64, const unsigned char *msg32) { - secp256k1_ge q; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sig64 != NULL); - ARG_CHECK(pubkey != NULL); - - if (secp256k1_schnorr_sig_recover(&ctx->ecmult_ctx, sig64, &q, secp256k1_schnorr_msghash_sha256, msg32)) { - secp256k1_pubkey_save(pubkey, &q); - return 1; - } else { - memset(pubkey, 0, sizeof(*pubkey)); - return 0; - } -} - -int secp256k1_schnorr_generate_nonce_pair(const secp256k1_context* ctx, secp256k1_pubkey *pubnonce, unsigned char *privnonce32, const unsigned char *sec32, const unsigned char *msg32, secp256k1_nonce_function noncefp, const void* noncedata) { - int count = 0; - int ret = 1; - secp256k1_gej Qj; - secp256k1_ge Q; - secp256k1_scalar sec; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sec32 != NULL); - ARG_CHECK(pubnonce != NULL); - ARG_CHECK(privnonce32 != NULL); - - if (noncefp == NULL) { - noncefp = secp256k1_nonce_function_default; - } - - do { - int overflow; - ret = noncefp(privnonce32, sec32, msg32, secp256k1_schnorr_algo16, (void*)noncedata, count++); - if (!ret) { - break; - } - secp256k1_scalar_set_b32(&sec, privnonce32, &overflow); - if (overflow || secp256k1_scalar_is_zero(&sec)) { - continue; - } - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &Qj, &sec); - secp256k1_ge_set_gej(&Q, &Qj); - - secp256k1_pubkey_save(pubnonce, &Q); - break; - } while(1); - - secp256k1_scalar_clear(&sec); - if (!ret) { - memset(pubnonce, 0, sizeof(*pubnonce)); - } - return ret; -} - -int secp256k1_schnorr_partial_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const unsigned char *sec32, const secp256k1_pubkey *pubnonce_others, const unsigned char *secnonce32) { - int overflow = 0; - secp256k1_scalar sec, non; - secp256k1_ge pubnon; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sig64 != NULL); - ARG_CHECK(sec32 != NULL); - ARG_CHECK(secnonce32 != NULL); - ARG_CHECK(pubnonce_others != NULL); - - secp256k1_scalar_set_b32(&sec, sec32, &overflow); - if (overflow || secp256k1_scalar_is_zero(&sec)) { - return -1; - } - secp256k1_scalar_set_b32(&non, secnonce32, &overflow); - if (overflow || secp256k1_scalar_is_zero(&non)) { - return -1; - } - secp256k1_pubkey_load(ctx, &pubnon, pubnonce_others); - return secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64, &sec, &non, &pubnon, secp256k1_schnorr_msghash_sha256, msg32); -} - -int secp256k1_schnorr_partial_combine(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char * const *sig64sin, size_t n) { - ARG_CHECK(sig64 != NULL); - ARG_CHECK(n >= 1); - ARG_CHECK(sig64sin != NULL); - return secp256k1_schnorr_sig_combine(sig64, n, sig64sin); -} - -#endif diff --git a/util/secp256k1/depend/secp256k1/src/modules/schnorr/schnorr.h b/util/secp256k1/depend/secp256k1/src/modules/schnorr/schnorr.h deleted file mode 100644 index de18147bd5..0000000000 --- a/util/secp256k1/depend/secp256k1/src/modules/schnorr/schnorr.h +++ /dev/null @@ -1,20 +0,0 @@ -/*********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php. * - ***********************************************************************/ - -#ifndef _SECP256K1_MODULE_SCHNORR_H_ -#define _SECP256K1_MODULE_SCHNORR_H_ - -#include "scalar.h" -#include "group.h" - -typedef void (*secp256k1_schnorr_msghash)(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32); - -static int secp256k1_schnorr_sig_sign(const secp256k1_ecmult_gen_context* ctx, unsigned char *sig64, const secp256k1_scalar *key, const secp256k1_scalar *nonce, const secp256k1_ge *pubnonce, secp256k1_schnorr_msghash hash, const unsigned char *msg32); -static int secp256k1_schnorr_sig_verify(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, const secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32); -static int secp256k1_schnorr_sig_recover(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32); -static int secp256k1_schnorr_sig_combine(unsigned char *sig64, size_t n, const unsigned char * const *sig64ins); - -#endif diff --git a/util/secp256k1/depend/secp256k1/src/modules/schnorr/schnorr_impl.h b/util/secp256k1/depend/secp256k1/src/modules/schnorr/schnorr_impl.h deleted file mode 100644 index e13ab6db7c..0000000000 --- a/util/secp256k1/depend/secp256k1/src/modules/schnorr/schnorr_impl.h +++ /dev/null @@ -1,207 +0,0 @@ -/*********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php. * - ***********************************************************************/ - -#ifndef _SECP256K1_SCHNORR_IMPL_H_ -#define _SECP256K1_SCHNORR_IMPL_H_ - -#include - -#include "schnorr.h" -#include "num.h" -#include "field.h" -#include "group.h" -#include "ecmult.h" -#include "ecmult_gen.h" - -/** - * Custom Schnorr-based signature scheme. They support multiparty signing, public key - * recovery and batch validation. - * - * Rationale for verifying R's y coordinate: - * In order to support batch validation and public key recovery, the full R point must - * be known to verifiers, rather than just its x coordinate. In order to not risk - * being more strict in batch validation than normal validation, validators must be - * required to reject signatures with incorrect y coordinate. This is only possible - * by including a (relatively slow) field inverse, or a field square root. However, - * batch validation offers potentially much higher benefits than this cost. - * - * Rationale for having an implicit y coordinate oddness: - * If we commit to having the full R point known to verifiers, there are two mechanism. - * Either include its oddness in the signature, or give it an implicit fixed value. - * As the R y coordinate can be flipped by a simple negation of the nonce, we choose the - * latter, as it comes with nearly zero impact on signing or validation performance, and - * saves a byte in the signature. - * - * Signing: - * Inputs: 32-byte message m, 32-byte scalar key x (!=0), 32-byte scalar nonce k (!=0) - * - * Compute point R = k * G. Reject nonce if R's y coordinate is odd (or negate nonce). - * Compute 32-byte r, the serialization of R's x coordinate. - * Compute scalar h = Hash(r || m). Reject nonce if h == 0 or h >= order. - * Compute scalar s = k - h * x. - * The signature is (r, s). - * - * - * Verification: - * Inputs: 32-byte message m, public key point Q, signature: (32-byte r, scalar s) - * - * Signature is invalid if s >= order. - * Signature is invalid if r >= p. - * Compute scalar h = Hash(r || m). Signature is invalid if h == 0 or h >= order. - * Option 1 (faster for single verification): - * Compute point R = h * Q + s * G. Signature is invalid if R is infinity or R's y coordinate is odd. - * Signature is valid if the serialization of R's x coordinate equals r. - * Option 2 (allows batch validation and pubkey recovery): - * Decompress x coordinate r into point R, with odd y coordinate. Fail if R is not on the curve. - * Signature is valid if R + h * Q + s * G == 0. - */ - -static int secp256k1_schnorr_sig_sign(const secp256k1_ecmult_gen_context* ctx, unsigned char *sig64, const secp256k1_scalar *key, const secp256k1_scalar *nonce, const secp256k1_ge *pubnonce, secp256k1_schnorr_msghash hash, const unsigned char *msg32) { - secp256k1_gej Rj; - secp256k1_ge Ra; - unsigned char h32[32]; - secp256k1_scalar h, s; - int overflow; - secp256k1_scalar n; - - if (secp256k1_scalar_is_zero(key) || secp256k1_scalar_is_zero(nonce)) { - return 0; - } - n = *nonce; - - secp256k1_ecmult_gen(ctx, &Rj, &n); - if (pubnonce != NULL) { - secp256k1_gej_add_ge(&Rj, &Rj, pubnonce); - } - secp256k1_ge_set_gej(&Ra, &Rj); - secp256k1_fe_normalize(&Ra.y); - if (secp256k1_fe_is_odd(&Ra.y)) { - /* R's y coordinate is odd, which is not allowed (see rationale above). - Force it to be even by negating the nonce. Note that this even works - for multiparty signing, as the R point is known to all participants, - which can all decide to flip the sign in unison, resulting in the - overall R point to be negated too. */ - secp256k1_scalar_negate(&n, &n); - } - secp256k1_fe_normalize(&Ra.x); - secp256k1_fe_get_b32(sig64, &Ra.x); - hash(h32, sig64, msg32); - overflow = 0; - secp256k1_scalar_set_b32(&h, h32, &overflow); - if (overflow || secp256k1_scalar_is_zero(&h)) { - secp256k1_scalar_clear(&n); - return 0; - } - secp256k1_scalar_mul(&s, &h, key); - secp256k1_scalar_negate(&s, &s); - secp256k1_scalar_add(&s, &s, &n); - secp256k1_scalar_clear(&n); - secp256k1_scalar_get_b32(sig64 + 32, &s); - return 1; -} - -static int secp256k1_schnorr_sig_verify(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, const secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32) { - secp256k1_gej Qj, Rj; - secp256k1_ge Ra; - secp256k1_fe Rx; - secp256k1_scalar h, s; - unsigned char hh[32]; - int overflow; - - if (secp256k1_ge_is_infinity(pubkey)) { - return 0; - } - hash(hh, sig64, msg32); - overflow = 0; - secp256k1_scalar_set_b32(&h, hh, &overflow); - if (overflow || secp256k1_scalar_is_zero(&h)) { - return 0; - } - overflow = 0; - secp256k1_scalar_set_b32(&s, sig64 + 32, &overflow); - if (overflow) { - return 0; - } - if (!secp256k1_fe_set_b32(&Rx, sig64)) { - return 0; - } - secp256k1_gej_set_ge(&Qj, pubkey); - secp256k1_ecmult(ctx, &Rj, &Qj, &h, &s); - if (secp256k1_gej_is_infinity(&Rj)) { - return 0; - } - secp256k1_ge_set_gej_var(&Ra, &Rj); - secp256k1_fe_normalize_var(&Ra.y); - if (secp256k1_fe_is_odd(&Ra.y)) { - return 0; - } - return secp256k1_fe_equal_var(&Rx, &Ra.x); -} - -static int secp256k1_schnorr_sig_recover(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32) { - secp256k1_gej Qj, Rj; - secp256k1_ge Ra; - secp256k1_fe Rx; - secp256k1_scalar h, s; - unsigned char hh[32]; - int overflow; - - hash(hh, sig64, msg32); - overflow = 0; - secp256k1_scalar_set_b32(&h, hh, &overflow); - if (overflow || secp256k1_scalar_is_zero(&h)) { - return 0; - } - overflow = 0; - secp256k1_scalar_set_b32(&s, sig64 + 32, &overflow); - if (overflow) { - return 0; - } - if (!secp256k1_fe_set_b32(&Rx, sig64)) { - return 0; - } - if (!secp256k1_ge_set_xo_var(&Ra, &Rx, 0)) { - return 0; - } - secp256k1_gej_set_ge(&Rj, &Ra); - secp256k1_scalar_inverse_var(&h, &h); - secp256k1_scalar_negate(&s, &s); - secp256k1_scalar_mul(&s, &s, &h); - secp256k1_ecmult(ctx, &Qj, &Rj, &h, &s); - if (secp256k1_gej_is_infinity(&Qj)) { - return 0; - } - secp256k1_ge_set_gej(pubkey, &Qj); - return 1; -} - -static int secp256k1_schnorr_sig_combine(unsigned char *sig64, size_t n, const unsigned char * const *sig64ins) { - secp256k1_scalar s = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); - size_t i; - for (i = 0; i < n; i++) { - secp256k1_scalar si; - int overflow; - secp256k1_scalar_set_b32(&si, sig64ins[i] + 32, &overflow); - if (overflow) { - return -1; - } - if (i) { - if (memcmp(sig64ins[i - 1], sig64ins[i], 32) != 0) { - return -1; - } - } - secp256k1_scalar_add(&s, &s, &si); - } - if (secp256k1_scalar_is_zero(&s)) { - return 0; - } - memcpy(sig64, sig64ins[0], 32); - secp256k1_scalar_get_b32(sig64 + 32, &s); - secp256k1_scalar_clear(&s); - return 1; -} - -#endif diff --git a/util/secp256k1/depend/secp256k1/src/modules/schnorr/tests_impl.h b/util/secp256k1/depend/secp256k1/src/modules/schnorr/tests_impl.h deleted file mode 100644 index 5bd14a03e3..0000000000 --- a/util/secp256k1/depend/secp256k1/src/modules/schnorr/tests_impl.h +++ /dev/null @@ -1,175 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_MODULE_SCHNORR_TESTS -#define SECP256K1_MODULE_SCHNORR_TESTS - -#include "include/secp256k1_schnorr.h" - -void test_schnorr_end_to_end(void) { - unsigned char privkey[32]; - unsigned char message[32]; - unsigned char schnorr_signature[64]; - secp256k1_pubkey pubkey, recpubkey; - - /* Generate a random key and message. */ - { - secp256k1_scalar key; - random_scalar_order_test(&key); - secp256k1_scalar_get_b32(privkey, &key); - secp256k1_rand256_test(message); - } - - /* Construct and verify corresponding public key. */ - CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); - - /* Schnorr sign. */ - CHECK(secp256k1_schnorr_sign(ctx, schnorr_signature, message, privkey, NULL, NULL) == 1); - CHECK(secp256k1_schnorr_verify(ctx, schnorr_signature, message, &pubkey) == 1); - CHECK(secp256k1_schnorr_recover(ctx, &recpubkey, schnorr_signature, message) == 1); - CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0); - /* Destroy signature and verify again. */ - schnorr_signature[secp256k1_rand_bits(6)] += 1 + secp256k1_rand_int(255); - CHECK(secp256k1_schnorr_verify(ctx, schnorr_signature, message, &pubkey) == 0); - CHECK(secp256k1_schnorr_recover(ctx, &recpubkey, schnorr_signature, message) != 1 || - memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0); -} - -/** Horribly broken hash function. Do not use for anything but tests. */ -void test_schnorr_hash(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32) { - int i; - for (i = 0; i < 32; i++) { - h32[i] = r32[i] ^ msg32[i]; - } -} - -void test_schnorr_sign_verify(void) { - unsigned char msg32[32]; - unsigned char sig64[3][64]; - secp256k1_gej pubkeyj[3]; - secp256k1_ge pubkey[3]; - secp256k1_scalar nonce[3], key[3]; - int i = 0; - int k; - - secp256k1_rand256_test(msg32); - - for (k = 0; k < 3; k++) { - random_scalar_order_test(&key[k]); - - do { - random_scalar_order_test(&nonce[k]); - if (secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64[k], &key[k], &nonce[k], NULL, &test_schnorr_hash, msg32)) { - break; - } - } while(1); - - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubkeyj[k], &key[k]); - secp256k1_ge_set_gej_var(&pubkey[k], &pubkeyj[k]); - CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64[k], &pubkey[k], &test_schnorr_hash, msg32)); - - for (i = 0; i < 4; i++) { - int pos = secp256k1_rand_bits(6); - int mod = 1 + secp256k1_rand_int(255); - sig64[k][pos] ^= mod; - CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64[k], &pubkey[k], &test_schnorr_hash, msg32) == 0); - sig64[k][pos] ^= mod; - } - } -} - -void test_schnorr_threshold(void) { - unsigned char msg[32]; - unsigned char sec[5][32]; - secp256k1_pubkey pub[5]; - unsigned char nonce[5][32]; - secp256k1_pubkey pubnonce[5]; - unsigned char sig[5][64]; - const unsigned char* sigs[5]; - unsigned char allsig[64]; - const secp256k1_pubkey* pubs[5]; - secp256k1_pubkey allpub; - int n, i; - int damage; - int ret = 0; - - damage = secp256k1_rand_bits(1) ? (1 + secp256k1_rand_int(4)) : 0; - secp256k1_rand256_test(msg); - n = 2 + secp256k1_rand_int(4); - for (i = 0; i < n; i++) { - do { - secp256k1_rand256_test(sec[i]); - } while (!secp256k1_ec_seckey_verify(ctx, sec[i])); - CHECK(secp256k1_ec_pubkey_create(ctx, &pub[i], sec[i])); - CHECK(secp256k1_schnorr_generate_nonce_pair(ctx, &pubnonce[i], nonce[i], msg, sec[i], NULL, NULL)); - pubs[i] = &pub[i]; - } - if (damage == 1) { - nonce[secp256k1_rand_int(n)][secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); - } else if (damage == 2) { - sec[secp256k1_rand_int(n)][secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); - } - for (i = 0; i < n; i++) { - secp256k1_pubkey allpubnonce; - const secp256k1_pubkey *pubnonces[4]; - int j; - for (j = 0; j < i; j++) { - pubnonces[j] = &pubnonce[j]; - } - for (j = i + 1; j < n; j++) { - pubnonces[j - 1] = &pubnonce[j]; - } - CHECK(secp256k1_ec_pubkey_combine(ctx, &allpubnonce, pubnonces, n - 1)); - ret |= (secp256k1_schnorr_partial_sign(ctx, sig[i], msg, sec[i], &allpubnonce, nonce[i]) != 1) * 1; - sigs[i] = sig[i]; - } - if (damage == 3) { - sig[secp256k1_rand_int(n)][secp256k1_rand_bits(6)] ^= 1 + secp256k1_rand_int(255); - } - ret |= (secp256k1_ec_pubkey_combine(ctx, &allpub, pubs, n) != 1) * 2; - if ((ret & 1) == 0) { - ret |= (secp256k1_schnorr_partial_combine(ctx, allsig, sigs, n) != 1) * 4; - } - if (damage == 4) { - allsig[secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); - } - if ((ret & 7) == 0) { - ret |= (secp256k1_schnorr_verify(ctx, allsig, msg, &allpub) != 1) * 8; - } - CHECK((ret == 0) == (damage == 0)); -} - -void test_schnorr_recovery(void) { - unsigned char msg32[32]; - unsigned char sig64[64]; - secp256k1_ge Q; - - secp256k1_rand256_test(msg32); - secp256k1_rand256_test(sig64); - secp256k1_rand256_test(sig64 + 32); - if (secp256k1_schnorr_sig_recover(&ctx->ecmult_ctx, sig64, &Q, &test_schnorr_hash, msg32) == 1) { - CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64, &Q, &test_schnorr_hash, msg32) == 1); - } -} - -void run_schnorr_tests(void) { - int i; - for (i = 0; i < 32*count; i++) { - test_schnorr_end_to_end(); - } - for (i = 0; i < 32 * count; i++) { - test_schnorr_sign_verify(); - } - for (i = 0; i < 16 * count; i++) { - test_schnorr_recovery(); - } - for (i = 0; i < 10 * count; i++) { - test_schnorr_threshold(); - } -} - -#endif diff --git a/util/secp256k1/depend/secp256k1/src/num.h b/util/secp256k1/depend/secp256k1/src/num.h deleted file mode 100644 index 49f2dd791d..0000000000 --- a/util/secp256k1/depend/secp256k1/src/num.h +++ /dev/null @@ -1,74 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_NUM_H -#define SECP256K1_NUM_H - -#ifndef USE_NUM_NONE - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif - -#if defined(USE_NUM_GMP) -#include "num_gmp.h" -#else -#error "Please select num implementation" -#endif - -/** Copy a number. */ -static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *a); - -/** Convert a number's absolute value to a binary big-endian string. - * There must be enough place. */ -static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a); - -/** Set a number to the value of a binary big-endian string. */ -static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen); - -/** Compute a modular inverse. The input must be less than the modulus. */ -static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m); - -/** Compute the jacobi symbol (a|b). b must be positive and odd. */ -static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b); - -/** Compare the absolute value of two numbers. */ -static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b); - -/** Test whether two number are equal (including sign). */ -static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b); - -/** Add two (signed) numbers. */ -static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); - -/** Subtract two (signed) numbers. */ -static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); - -/** Multiply two (signed) numbers. */ -static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); - -/** Replace a number by its remainder modulo m. M's sign is ignored. The result is a number between 0 and m-1, - even if r was negative. */ -static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m); - -/** Right-shift the passed number by bits bits. */ -static void secp256k1_num_shift(secp256k1_num *r, int bits); - -/** Check whether a number is zero. */ -static int secp256k1_num_is_zero(const secp256k1_num *a); - -/** Check whether a number is one. */ -static int secp256k1_num_is_one(const secp256k1_num *a); - -/** Check whether a number is strictly negative. */ -static int secp256k1_num_is_neg(const secp256k1_num *a); - -/** Change a number's sign. */ -static void secp256k1_num_negate(secp256k1_num *r); - -#endif - -#endif /* SECP256K1_NUM_H */ diff --git a/util/secp256k1/depend/secp256k1/src/num_gmp.h b/util/secp256k1/depend/secp256k1/src/num_gmp.h deleted file mode 100644 index 3619844bd5..0000000000 --- a/util/secp256k1/depend/secp256k1/src/num_gmp.h +++ /dev/null @@ -1,20 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_NUM_REPR_H -#define SECP256K1_NUM_REPR_H - -#include - -#define NUM_LIMBS ((256+GMP_NUMB_BITS-1)/GMP_NUMB_BITS) - -typedef struct { - mp_limb_t data[2*NUM_LIMBS]; - int neg; - int limbs; -} secp256k1_num; - -#endif /* SECP256K1_NUM_REPR_H */ diff --git a/util/secp256k1/depend/secp256k1/src/num_gmp_impl.h b/util/secp256k1/depend/secp256k1/src/num_gmp_impl.h deleted file mode 100644 index 0ae2a8ba0e..0000000000 --- a/util/secp256k1/depend/secp256k1/src/num_gmp_impl.h +++ /dev/null @@ -1,288 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_NUM_REPR_IMPL_H -#define SECP256K1_NUM_REPR_IMPL_H - -#include -#include -#include - -#include "util.h" -#include "num.h" - -#ifdef VERIFY -static void secp256k1_num_sanity(const secp256k1_num *a) { - VERIFY_CHECK(a->limbs == 1 || (a->limbs > 1 && a->data[a->limbs-1] != 0)); -} -#else -#define secp256k1_num_sanity(a) do { } while(0) -#endif - -static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *a) { - *r = *a; -} - -static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a) { - unsigned char tmp[65]; - int len = 0; - int shift = 0; - if (a->limbs>1 || a->data[0] != 0) { - len = mpn_get_str(tmp, 256, (mp_limb_t*)a->data, a->limbs); - } - while (shift < len && tmp[shift] == 0) shift++; - VERIFY_CHECK(len-shift <= (int)rlen); - memset(r, 0, rlen - len + shift); - if (len > shift) { - memcpy(r + rlen - len + shift, tmp + shift, len - shift); - } - memset(tmp, 0, sizeof(tmp)); -} - -static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen) { - int len; - VERIFY_CHECK(alen > 0); - VERIFY_CHECK(alen <= 64); - len = mpn_set_str(r->data, a, alen, 256); - if (len == 0) { - r->data[0] = 0; - len = 1; - } - VERIFY_CHECK(len <= NUM_LIMBS*2); - r->limbs = len; - r->neg = 0; - while (r->limbs > 1 && r->data[r->limbs-1]==0) { - r->limbs--; - } -} - -static void secp256k1_num_add_abs(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { - mp_limb_t c = mpn_add(r->data, a->data, a->limbs, b->data, b->limbs); - r->limbs = a->limbs; - if (c != 0) { - VERIFY_CHECK(r->limbs < 2*NUM_LIMBS); - r->data[r->limbs++] = c; - } -} - -static void secp256k1_num_sub_abs(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { - mp_limb_t c = mpn_sub(r->data, a->data, a->limbs, b->data, b->limbs); - (void)c; - VERIFY_CHECK(c == 0); - r->limbs = a->limbs; - while (r->limbs > 1 && r->data[r->limbs-1]==0) { - r->limbs--; - } -} - -static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m) { - secp256k1_num_sanity(r); - secp256k1_num_sanity(m); - - if (r->limbs >= m->limbs) { - mp_limb_t t[2*NUM_LIMBS]; - mpn_tdiv_qr(t, r->data, 0, r->data, r->limbs, m->data, m->limbs); - memset(t, 0, sizeof(t)); - r->limbs = m->limbs; - while (r->limbs > 1 && r->data[r->limbs-1]==0) { - r->limbs--; - } - } - - if (r->neg && (r->limbs > 1 || r->data[0] != 0)) { - secp256k1_num_sub_abs(r, m, r); - r->neg = 0; - } -} - -static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m) { - int i; - mp_limb_t g[NUM_LIMBS+1]; - mp_limb_t u[NUM_LIMBS+1]; - mp_limb_t v[NUM_LIMBS+1]; - mp_size_t sn; - mp_size_t gn; - secp256k1_num_sanity(a); - secp256k1_num_sanity(m); - - /** mpn_gcdext computes: (G,S) = gcdext(U,V), where - * * G = gcd(U,V) - * * G = U*S + V*T - * * U has equal or more limbs than V, and V has no padding - * If we set U to be (a padded version of) a, and V = m: - * G = a*S + m*T - * G = a*S mod m - * Assuming G=1: - * S = 1/a mod m - */ - VERIFY_CHECK(m->limbs <= NUM_LIMBS); - VERIFY_CHECK(m->data[m->limbs-1] != 0); - for (i = 0; i < m->limbs; i++) { - u[i] = (i < a->limbs) ? a->data[i] : 0; - v[i] = m->data[i]; - } - sn = NUM_LIMBS+1; - gn = mpn_gcdext(g, r->data, &sn, u, m->limbs, v, m->limbs); - (void)gn; - VERIFY_CHECK(gn == 1); - VERIFY_CHECK(g[0] == 1); - r->neg = a->neg ^ m->neg; - if (sn < 0) { - mpn_sub(r->data, m->data, m->limbs, r->data, -sn); - r->limbs = m->limbs; - while (r->limbs > 1 && r->data[r->limbs-1]==0) { - r->limbs--; - } - } else { - r->limbs = sn; - } - memset(g, 0, sizeof(g)); - memset(u, 0, sizeof(u)); - memset(v, 0, sizeof(v)); -} - -static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b) { - int ret; - mpz_t ga, gb; - secp256k1_num_sanity(a); - secp256k1_num_sanity(b); - VERIFY_CHECK(!b->neg && (b->limbs > 0) && (b->data[0] & 1)); - - mpz_inits(ga, gb, NULL); - - mpz_import(gb, b->limbs, -1, sizeof(mp_limb_t), 0, 0, b->data); - mpz_import(ga, a->limbs, -1, sizeof(mp_limb_t), 0, 0, a->data); - if (a->neg) { - mpz_neg(ga, ga); - } - - ret = mpz_jacobi(ga, gb); - - mpz_clears(ga, gb, NULL); - - return ret; -} - -static int secp256k1_num_is_one(const secp256k1_num *a) { - return (a->limbs == 1 && a->data[0] == 1); -} - -static int secp256k1_num_is_zero(const secp256k1_num *a) { - return (a->limbs == 1 && a->data[0] == 0); -} - -static int secp256k1_num_is_neg(const secp256k1_num *a) { - return (a->limbs > 1 || a->data[0] != 0) && a->neg; -} - -static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b) { - if (a->limbs > b->limbs) { - return 1; - } - if (a->limbs < b->limbs) { - return -1; - } - return mpn_cmp(a->data, b->data, a->limbs); -} - -static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b) { - if (a->limbs > b->limbs) { - return 0; - } - if (a->limbs < b->limbs) { - return 0; - } - if ((a->neg && !secp256k1_num_is_zero(a)) != (b->neg && !secp256k1_num_is_zero(b))) { - return 0; - } - return mpn_cmp(a->data, b->data, a->limbs) == 0; -} - -static void secp256k1_num_subadd(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b, int bneg) { - if (!(b->neg ^ bneg ^ a->neg)) { /* a and b have the same sign */ - r->neg = a->neg; - if (a->limbs >= b->limbs) { - secp256k1_num_add_abs(r, a, b); - } else { - secp256k1_num_add_abs(r, b, a); - } - } else { - if (secp256k1_num_cmp(a, b) > 0) { - r->neg = a->neg; - secp256k1_num_sub_abs(r, a, b); - } else { - r->neg = b->neg ^ bneg; - secp256k1_num_sub_abs(r, b, a); - } - } -} - -static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { - secp256k1_num_sanity(a); - secp256k1_num_sanity(b); - secp256k1_num_subadd(r, a, b, 0); -} - -static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { - secp256k1_num_sanity(a); - secp256k1_num_sanity(b); - secp256k1_num_subadd(r, a, b, 1); -} - -static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { - mp_limb_t tmp[2*NUM_LIMBS+1]; - secp256k1_num_sanity(a); - secp256k1_num_sanity(b); - - VERIFY_CHECK(a->limbs + b->limbs <= 2*NUM_LIMBS+1); - if ((a->limbs==1 && a->data[0]==0) || (b->limbs==1 && b->data[0]==0)) { - r->limbs = 1; - r->neg = 0; - r->data[0] = 0; - return; - } - if (a->limbs >= b->limbs) { - mpn_mul(tmp, a->data, a->limbs, b->data, b->limbs); - } else { - mpn_mul(tmp, b->data, b->limbs, a->data, a->limbs); - } - r->limbs = a->limbs + b->limbs; - if (r->limbs > 1 && tmp[r->limbs - 1]==0) { - r->limbs--; - } - VERIFY_CHECK(r->limbs <= 2*NUM_LIMBS); - mpn_copyi(r->data, tmp, r->limbs); - r->neg = a->neg ^ b->neg; - memset(tmp, 0, sizeof(tmp)); -} - -static void secp256k1_num_shift(secp256k1_num *r, int bits) { - if (bits % GMP_NUMB_BITS) { - /* Shift within limbs. */ - mpn_rshift(r->data, r->data, r->limbs, bits % GMP_NUMB_BITS); - } - if (bits >= GMP_NUMB_BITS) { - int i; - /* Shift full limbs. */ - for (i = 0; i < r->limbs; i++) { - int index = i + (bits / GMP_NUMB_BITS); - if (index < r->limbs && index < 2*NUM_LIMBS) { - r->data[i] = r->data[index]; - } else { - r->data[i] = 0; - } - } - } - while (r->limbs>1 && r->data[r->limbs-1]==0) { - r->limbs--; - } -} - -static void secp256k1_num_negate(secp256k1_num *r) { - r->neg ^= 1; -} - -#endif /* SECP256K1_NUM_REPR_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/num_impl.h b/util/secp256k1/depend/secp256k1/src/num_impl.h deleted file mode 100644 index c45193b033..0000000000 --- a/util/secp256k1/depend/secp256k1/src/num_impl.h +++ /dev/null @@ -1,24 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_NUM_IMPL_H -#define SECP256K1_NUM_IMPL_H - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif - -#include "num.h" - -#if defined(USE_NUM_GMP) -#include "num_gmp_impl.h" -#elif defined(USE_NUM_NONE) -/* Nothing. */ -#else -#error "Please select num implementation" -#endif - -#endif /* SECP256K1_NUM_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/scalar.h b/util/secp256k1/depend/secp256k1/src/scalar.h deleted file mode 100644 index 59304cb66e..0000000000 --- a/util/secp256k1/depend/secp256k1/src/scalar.h +++ /dev/null @@ -1,106 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_SCALAR_H -#define SECP256K1_SCALAR_H - -#include "num.h" - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif - -#if defined(EXHAUSTIVE_TEST_ORDER) -#include "scalar_low.h" -#elif defined(USE_SCALAR_4X64) -#include "scalar_4x64.h" -#elif defined(USE_SCALAR_8X32) -#include "scalar_8x32.h" -#else -#error "Please select scalar implementation" -#endif - -/** Clear a scalar to prevent the leak of sensitive data. */ -static void secp256k1_scalar_clear(secp256k1_scalar *r); - -/** Access bits from a scalar. All requested bits must belong to the same 32-bit limb. */ -static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count); - -/** Access bits from a scalar. Not constant time. */ -static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count); - -/** Set a scalar from a big endian byte array. */ -static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow); - -/** Set a scalar to an unsigned integer. */ -static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v); - -/** Convert a scalar to a byte array. */ -static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a); - -/** Add two scalars together (modulo the group order). Returns whether it overflowed. */ -static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); - -/** Conditionally add a power of two to a scalar. The result is not allowed to overflow. */ -static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag); - -/** Multiply two scalars (modulo the group order). */ -static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); - -/** Shift a scalar right by some amount strictly between 0 and 16, returning - * the low bits that were shifted off */ -static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n); - -/** Compute the square of a scalar (modulo the group order). */ -static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a); - -/** Compute the inverse of a scalar (modulo the group order). */ -static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *a); - -/** Compute the inverse of a scalar (modulo the group order), without constant-time guarantee. */ -static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *a); - -/** Compute the complement of a scalar (modulo the group order). */ -static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a); - -/** Check whether a scalar equals zero. */ -static int secp256k1_scalar_is_zero(const secp256k1_scalar *a); - -/** Check whether a scalar equals one. */ -static int secp256k1_scalar_is_one(const secp256k1_scalar *a); - -/** Check whether a scalar, considered as an nonnegative integer, is even. */ -static int secp256k1_scalar_is_even(const secp256k1_scalar *a); - -/** Check whether a scalar is higher than the group order divided by 2. */ -static int secp256k1_scalar_is_high(const secp256k1_scalar *a); - -/** Conditionally negate a number, in constant time. - * Returns -1 if the number was negated, 1 otherwise */ -static int secp256k1_scalar_cond_negate(secp256k1_scalar *a, int flag); - -#ifndef USE_NUM_NONE -/** Convert a scalar to a number. */ -static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a); - -/** Get the order of the group as a number. */ -static void secp256k1_scalar_order_get_num(secp256k1_num *r); -#endif - -/** Compare two scalars. */ -static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b); - -#ifdef USE_ENDOMORPHISM -/** Find r1 and r2 such that r1+r2*2^128 = a. */ -static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a); -/** Find r1 and r2 such that r1+r2*lambda = a, and r1 and r2 are maximum 128 bits long (see secp256k1_gej_mul_lambda). */ -static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a); -#endif - -/** Multiply a and b (without taking the modulus!), divide by 2**shift, and round to the nearest integer. Shift must be at least 256. */ -static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift); - -#endif /* SECP256K1_SCALAR_H */ diff --git a/util/secp256k1/depend/secp256k1/src/scalar_4x64.h b/util/secp256k1/depend/secp256k1/src/scalar_4x64.h deleted file mode 100644 index 19c7495d1c..0000000000 --- a/util/secp256k1/depend/secp256k1/src/scalar_4x64.h +++ /dev/null @@ -1,19 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_SCALAR_REPR_H -#define SECP256K1_SCALAR_REPR_H - -#include - -/** A scalar modulo the group order of the secp256k1 curve. */ -typedef struct { - uint64_t d[4]; -} secp256k1_scalar; - -#define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{((uint64_t)(d1)) << 32 | (d0), ((uint64_t)(d3)) << 32 | (d2), ((uint64_t)(d5)) << 32 | (d4), ((uint64_t)(d7)) << 32 | (d6)}} - -#endif /* SECP256K1_SCALAR_REPR_H */ diff --git a/util/secp256k1/depend/secp256k1/src/scalar_4x64_impl.h b/util/secp256k1/depend/secp256k1/src/scalar_4x64_impl.h deleted file mode 100644 index db1ebf94be..0000000000 --- a/util/secp256k1/depend/secp256k1/src/scalar_4x64_impl.h +++ /dev/null @@ -1,949 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_SCALAR_REPR_IMPL_H -#define SECP256K1_SCALAR_REPR_IMPL_H - -/* Limbs of the secp256k1 order. */ -#define SECP256K1_N_0 ((uint64_t)0xBFD25E8CD0364141ULL) -#define SECP256K1_N_1 ((uint64_t)0xBAAEDCE6AF48A03BULL) -#define SECP256K1_N_2 ((uint64_t)0xFFFFFFFFFFFFFFFEULL) -#define SECP256K1_N_3 ((uint64_t)0xFFFFFFFFFFFFFFFFULL) - -/* Limbs of 2^256 minus the secp256k1 order. */ -#define SECP256K1_N_C_0 (~SECP256K1_N_0 + 1) -#define SECP256K1_N_C_1 (~SECP256K1_N_1) -#define SECP256K1_N_C_2 (1) - -/* Limbs of half the secp256k1 order. */ -#define SECP256K1_N_H_0 ((uint64_t)0xDFE92F46681B20A0ULL) -#define SECP256K1_N_H_1 ((uint64_t)0x5D576E7357A4501DULL) -#define SECP256K1_N_H_2 ((uint64_t)0xFFFFFFFFFFFFFFFFULL) -#define SECP256K1_N_H_3 ((uint64_t)0x7FFFFFFFFFFFFFFFULL) - -SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { - r->d[0] = 0; - r->d[1] = 0; - r->d[2] = 0; - r->d[3] = 0; -} - -SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { - r->d[0] = v; - r->d[1] = 0; - r->d[2] = 0; - r->d[3] = 0; -} - -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { - VERIFY_CHECK((offset + count - 1) >> 6 == offset >> 6); - return (a->d[offset >> 6] >> (offset & 0x3F)) & ((((uint64_t)1) << count) - 1); -} - -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { - VERIFY_CHECK(count < 32); - VERIFY_CHECK(offset + count <= 256); - if ((offset + count - 1) >> 6 == offset >> 6) { - return secp256k1_scalar_get_bits(a, offset, count); - } else { - VERIFY_CHECK((offset >> 6) + 1 < 4); - return ((a->d[offset >> 6] >> (offset & 0x3F)) | (a->d[(offset >> 6) + 1] << (64 - (offset & 0x3F)))) & ((((uint64_t)1) << count) - 1); - } -} - -SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { - int yes = 0; - int no = 0; - no |= (a->d[3] < SECP256K1_N_3); /* No need for a > check. */ - no |= (a->d[2] < SECP256K1_N_2); - yes |= (a->d[2] > SECP256K1_N_2) & ~no; - no |= (a->d[1] < SECP256K1_N_1); - yes |= (a->d[1] > SECP256K1_N_1) & ~no; - yes |= (a->d[0] >= SECP256K1_N_0) & ~no; - return yes; -} - -SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, unsigned int overflow) { - uint128_t t; - VERIFY_CHECK(overflow <= 1); - t = (uint128_t)r->d[0] + overflow * SECP256K1_N_C_0; - r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)r->d[1] + overflow * SECP256K1_N_C_1; - r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)r->d[2] + overflow * SECP256K1_N_C_2; - r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint64_t)r->d[3]; - r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; - return overflow; -} - -static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { - int overflow; - uint128_t t = (uint128_t)a->d[0] + b->d[0]; - r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)a->d[1] + b->d[1]; - r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)a->d[2] + b->d[2]; - r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)a->d[3] + b->d[3]; - r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - overflow = t + secp256k1_scalar_check_overflow(r); - VERIFY_CHECK(overflow == 0 || overflow == 1); - secp256k1_scalar_reduce(r, overflow); - return overflow; -} - -static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { - uint128_t t; - VERIFY_CHECK(bit < 256); - bit += ((uint32_t) flag - 1) & 0x100; /* forcing (bit >> 6) > 3 makes this a noop */ - t = (uint128_t)r->d[0] + (((uint64_t)((bit >> 6) == 0)) << (bit & 0x3F)); - r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)r->d[1] + (((uint64_t)((bit >> 6) == 1)) << (bit & 0x3F)); - r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)r->d[2] + (((uint64_t)((bit >> 6) == 2)) << (bit & 0x3F)); - r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; - t += (uint128_t)r->d[3] + (((uint64_t)((bit >> 6) == 3)) << (bit & 0x3F)); - r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; -#ifdef VERIFY - VERIFY_CHECK((t >> 64) == 0); - VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); -#endif -} - -static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { - int over; - r->d[0] = (uint64_t)b32[31] | (uint64_t)b32[30] << 8 | (uint64_t)b32[29] << 16 | (uint64_t)b32[28] << 24 | (uint64_t)b32[27] << 32 | (uint64_t)b32[26] << 40 | (uint64_t)b32[25] << 48 | (uint64_t)b32[24] << 56; - r->d[1] = (uint64_t)b32[23] | (uint64_t)b32[22] << 8 | (uint64_t)b32[21] << 16 | (uint64_t)b32[20] << 24 | (uint64_t)b32[19] << 32 | (uint64_t)b32[18] << 40 | (uint64_t)b32[17] << 48 | (uint64_t)b32[16] << 56; - r->d[2] = (uint64_t)b32[15] | (uint64_t)b32[14] << 8 | (uint64_t)b32[13] << 16 | (uint64_t)b32[12] << 24 | (uint64_t)b32[11] << 32 | (uint64_t)b32[10] << 40 | (uint64_t)b32[9] << 48 | (uint64_t)b32[8] << 56; - r->d[3] = (uint64_t)b32[7] | (uint64_t)b32[6] << 8 | (uint64_t)b32[5] << 16 | (uint64_t)b32[4] << 24 | (uint64_t)b32[3] << 32 | (uint64_t)b32[2] << 40 | (uint64_t)b32[1] << 48 | (uint64_t)b32[0] << 56; - over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r)); - if (overflow) { - *overflow = over; - } -} - -static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { - bin[0] = a->d[3] >> 56; bin[1] = a->d[3] >> 48; bin[2] = a->d[3] >> 40; bin[3] = a->d[3] >> 32; bin[4] = a->d[3] >> 24; bin[5] = a->d[3] >> 16; bin[6] = a->d[3] >> 8; bin[7] = a->d[3]; - bin[8] = a->d[2] >> 56; bin[9] = a->d[2] >> 48; bin[10] = a->d[2] >> 40; bin[11] = a->d[2] >> 32; bin[12] = a->d[2] >> 24; bin[13] = a->d[2] >> 16; bin[14] = a->d[2] >> 8; bin[15] = a->d[2]; - bin[16] = a->d[1] >> 56; bin[17] = a->d[1] >> 48; bin[18] = a->d[1] >> 40; bin[19] = a->d[1] >> 32; bin[20] = a->d[1] >> 24; bin[21] = a->d[1] >> 16; bin[22] = a->d[1] >> 8; bin[23] = a->d[1]; - bin[24] = a->d[0] >> 56; bin[25] = a->d[0] >> 48; bin[26] = a->d[0] >> 40; bin[27] = a->d[0] >> 32; bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0]; -} - -SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { - return (a->d[0] | a->d[1] | a->d[2] | a->d[3]) == 0; -} - -static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { - uint64_t nonzero = 0xFFFFFFFFFFFFFFFFULL * (secp256k1_scalar_is_zero(a) == 0); - uint128_t t = (uint128_t)(~a->d[0]) + SECP256K1_N_0 + 1; - r->d[0] = t & nonzero; t >>= 64; - t += (uint128_t)(~a->d[1]) + SECP256K1_N_1; - r->d[1] = t & nonzero; t >>= 64; - t += (uint128_t)(~a->d[2]) + SECP256K1_N_2; - r->d[2] = t & nonzero; t >>= 64; - t += (uint128_t)(~a->d[3]) + SECP256K1_N_3; - r->d[3] = t & nonzero; -} - -SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { - return ((a->d[0] ^ 1) | a->d[1] | a->d[2] | a->d[3]) == 0; -} - -static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { - int yes = 0; - int no = 0; - no |= (a->d[3] < SECP256K1_N_H_3); - yes |= (a->d[3] > SECP256K1_N_H_3) & ~no; - no |= (a->d[2] < SECP256K1_N_H_2) & ~yes; /* No need for a > check. */ - no |= (a->d[1] < SECP256K1_N_H_1) & ~yes; - yes |= (a->d[1] > SECP256K1_N_H_1) & ~no; - yes |= (a->d[0] > SECP256K1_N_H_0) & ~no; - return yes; -} - -static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { - /* If we are flag = 0, mask = 00...00 and this is a no-op; - * if we are flag = 1, mask = 11...11 and this is identical to secp256k1_scalar_negate */ - uint64_t mask = !flag - 1; - uint64_t nonzero = (secp256k1_scalar_is_zero(r) != 0) - 1; - uint128_t t = (uint128_t)(r->d[0] ^ mask) + ((SECP256K1_N_0 + 1) & mask); - r->d[0] = t & nonzero; t >>= 64; - t += (uint128_t)(r->d[1] ^ mask) + (SECP256K1_N_1 & mask); - r->d[1] = t & nonzero; t >>= 64; - t += (uint128_t)(r->d[2] ^ mask) + (SECP256K1_N_2 & mask); - r->d[2] = t & nonzero; t >>= 64; - t += (uint128_t)(r->d[3] ^ mask) + (SECP256K1_N_3 & mask); - r->d[3] = t & nonzero; - return 2 * (mask == 0) - 1; -} - -/* Inspired by the macros in OpenSSL's crypto/bn/asm/x86_64-gcc.c. */ - -/** Add a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ -#define muladd(a,b) { \ - uint64_t tl, th; \ - { \ - uint128_t t = (uint128_t)a * b; \ - th = t >> 64; /* at most 0xFFFFFFFFFFFFFFFE */ \ - tl = t; \ - } \ - c0 += tl; /* overflow is handled on the next line */ \ - th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFFFFFFFFFF */ \ - c1 += th; /* overflow is handled on the next line */ \ - c2 += (c1 < th) ? 1 : 0; /* never overflows by contract (verified in the next line) */ \ - VERIFY_CHECK((c1 >= th) || (c2 != 0)); \ -} - -/** Add a*b to the number defined by (c0,c1). c1 must never overflow. */ -#define muladd_fast(a,b) { \ - uint64_t tl, th; \ - { \ - uint128_t t = (uint128_t)a * b; \ - th = t >> 64; /* at most 0xFFFFFFFFFFFFFFFE */ \ - tl = t; \ - } \ - c0 += tl; /* overflow is handled on the next line */ \ - th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFFFFFFFFFF */ \ - c1 += th; /* never overflows by contract (verified in the next line) */ \ - VERIFY_CHECK(c1 >= th); \ -} - -/** Add 2*a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ -#define muladd2(a,b) { \ - uint64_t tl, th, th2, tl2; \ - { \ - uint128_t t = (uint128_t)a * b; \ - th = t >> 64; /* at most 0xFFFFFFFFFFFFFFFE */ \ - tl = t; \ - } \ - th2 = th + th; /* at most 0xFFFFFFFFFFFFFFFE (in case th was 0x7FFFFFFFFFFFFFFF) */ \ - c2 += (th2 < th) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((th2 >= th) || (c2 != 0)); \ - tl2 = tl + tl; /* at most 0xFFFFFFFFFFFFFFFE (in case the lowest 63 bits of tl were 0x7FFFFFFFFFFFFFFF) */ \ - th2 += (tl2 < tl) ? 1 : 0; /* at most 0xFFFFFFFFFFFFFFFF */ \ - c0 += tl2; /* overflow is handled on the next line */ \ - th2 += (c0 < tl2) ? 1 : 0; /* second overflow is handled on the next line */ \ - c2 += (c0 < tl2) & (th2 == 0); /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((c0 >= tl2) || (th2 != 0) || (c2 != 0)); \ - c1 += th2; /* overflow is handled on the next line */ \ - c2 += (c1 < th2) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((c1 >= th2) || (c2 != 0)); \ -} - -/** Add a to the number defined by (c0,c1,c2). c2 must never overflow. */ -#define sumadd(a) { \ - unsigned int over; \ - c0 += (a); /* overflow is handled on the next line */ \ - over = (c0 < (a)) ? 1 : 0; \ - c1 += over; /* overflow is handled on the next line */ \ - c2 += (c1 < over) ? 1 : 0; /* never overflows by contract */ \ -} - -/** Add a to the number defined by (c0,c1). c1 must never overflow, c2 must be zero. */ -#define sumadd_fast(a) { \ - c0 += (a); /* overflow is handled on the next line */ \ - c1 += (c0 < (a)) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((c1 != 0) | (c0 >= (a))); \ - VERIFY_CHECK(c2 == 0); \ -} - -/** Extract the lowest 64 bits of (c0,c1,c2) into n, and left shift the number 64 bits. */ -#define extract(n) { \ - (n) = c0; \ - c0 = c1; \ - c1 = c2; \ - c2 = 0; \ -} - -/** Extract the lowest 64 bits of (c0,c1,c2) into n, and left shift the number 64 bits. c2 is required to be zero. */ -#define extract_fast(n) { \ - (n) = c0; \ - c0 = c1; \ - c1 = 0; \ - VERIFY_CHECK(c2 == 0); \ -} - -static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) { -#ifdef USE_ASM_X86_64 - /* Reduce 512 bits into 385. */ - uint64_t m0, m1, m2, m3, m4, m5, m6; - uint64_t p0, p1, p2, p3, p4; - uint64_t c; - - __asm__ __volatile__( - /* Preload. */ - "movq 32(%%rsi), %%r11\n" - "movq 40(%%rsi), %%r12\n" - "movq 48(%%rsi), %%r13\n" - "movq 56(%%rsi), %%r14\n" - /* Initialize r8,r9,r10 */ - "movq 0(%%rsi), %%r8\n" - "xorq %%r9, %%r9\n" - "xorq %%r10, %%r10\n" - /* (r8,r9) += n0 * c0 */ - "movq %8, %%rax\n" - "mulq %%r11\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - /* extract m0 */ - "movq %%r8, %q0\n" - "xorq %%r8, %%r8\n" - /* (r9,r10) += l1 */ - "addq 8(%%rsi), %%r9\n" - "adcq $0, %%r10\n" - /* (r9,r10,r8) += n1 * c0 */ - "movq %8, %%rax\n" - "mulq %%r12\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* (r9,r10,r8) += n0 * c1 */ - "movq %9, %%rax\n" - "mulq %%r11\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* extract m1 */ - "movq %%r9, %q1\n" - "xorq %%r9, %%r9\n" - /* (r10,r8,r9) += l2 */ - "addq 16(%%rsi), %%r10\n" - "adcq $0, %%r8\n" - "adcq $0, %%r9\n" - /* (r10,r8,r9) += n2 * c0 */ - "movq %8, %%rax\n" - "mulq %%r13\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - /* (r10,r8,r9) += n1 * c1 */ - "movq %9, %%rax\n" - "mulq %%r12\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - /* (r10,r8,r9) += n0 */ - "addq %%r11, %%r10\n" - "adcq $0, %%r8\n" - "adcq $0, %%r9\n" - /* extract m2 */ - "movq %%r10, %q2\n" - "xorq %%r10, %%r10\n" - /* (r8,r9,r10) += l3 */ - "addq 24(%%rsi), %%r8\n" - "adcq $0, %%r9\n" - "adcq $0, %%r10\n" - /* (r8,r9,r10) += n3 * c0 */ - "movq %8, %%rax\n" - "mulq %%r14\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - /* (r8,r9,r10) += n2 * c1 */ - "movq %9, %%rax\n" - "mulq %%r13\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - /* (r8,r9,r10) += n1 */ - "addq %%r12, %%r8\n" - "adcq $0, %%r9\n" - "adcq $0, %%r10\n" - /* extract m3 */ - "movq %%r8, %q3\n" - "xorq %%r8, %%r8\n" - /* (r9,r10,r8) += n3 * c1 */ - "movq %9, %%rax\n" - "mulq %%r14\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* (r9,r10,r8) += n2 */ - "addq %%r13, %%r9\n" - "adcq $0, %%r10\n" - "adcq $0, %%r8\n" - /* extract m4 */ - "movq %%r9, %q4\n" - /* (r10,r8) += n3 */ - "addq %%r14, %%r10\n" - "adcq $0, %%r8\n" - /* extract m5 */ - "movq %%r10, %q5\n" - /* extract m6 */ - "movq %%r8, %q6\n" - : "=g"(m0), "=g"(m1), "=g"(m2), "=g"(m3), "=g"(m4), "=g"(m5), "=g"(m6) - : "S"(l), "n"(SECP256K1_N_C_0), "n"(SECP256K1_N_C_1) - : "rax", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "cc"); - - /* Reduce 385 bits into 258. */ - __asm__ __volatile__( - /* Preload */ - "movq %q9, %%r11\n" - "movq %q10, %%r12\n" - "movq %q11, %%r13\n" - /* Initialize (r8,r9,r10) */ - "movq %q5, %%r8\n" - "xorq %%r9, %%r9\n" - "xorq %%r10, %%r10\n" - /* (r8,r9) += m4 * c0 */ - "movq %12, %%rax\n" - "mulq %%r11\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - /* extract p0 */ - "movq %%r8, %q0\n" - "xorq %%r8, %%r8\n" - /* (r9,r10) += m1 */ - "addq %q6, %%r9\n" - "adcq $0, %%r10\n" - /* (r9,r10,r8) += m5 * c0 */ - "movq %12, %%rax\n" - "mulq %%r12\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* (r9,r10,r8) += m4 * c1 */ - "movq %13, %%rax\n" - "mulq %%r11\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* extract p1 */ - "movq %%r9, %q1\n" - "xorq %%r9, %%r9\n" - /* (r10,r8,r9) += m2 */ - "addq %q7, %%r10\n" - "adcq $0, %%r8\n" - "adcq $0, %%r9\n" - /* (r10,r8,r9) += m6 * c0 */ - "movq %12, %%rax\n" - "mulq %%r13\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - /* (r10,r8,r9) += m5 * c1 */ - "movq %13, %%rax\n" - "mulq %%r12\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - /* (r10,r8,r9) += m4 */ - "addq %%r11, %%r10\n" - "adcq $0, %%r8\n" - "adcq $0, %%r9\n" - /* extract p2 */ - "movq %%r10, %q2\n" - /* (r8,r9) += m3 */ - "addq %q8, %%r8\n" - "adcq $0, %%r9\n" - /* (r8,r9) += m6 * c1 */ - "movq %13, %%rax\n" - "mulq %%r13\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - /* (r8,r9) += m5 */ - "addq %%r12, %%r8\n" - "adcq $0, %%r9\n" - /* extract p3 */ - "movq %%r8, %q3\n" - /* (r9) += m6 */ - "addq %%r13, %%r9\n" - /* extract p4 */ - "movq %%r9, %q4\n" - : "=&g"(p0), "=&g"(p1), "=&g"(p2), "=g"(p3), "=g"(p4) - : "g"(m0), "g"(m1), "g"(m2), "g"(m3), "g"(m4), "g"(m5), "g"(m6), "n"(SECP256K1_N_C_0), "n"(SECP256K1_N_C_1) - : "rax", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "cc"); - - /* Reduce 258 bits into 256. */ - __asm__ __volatile__( - /* Preload */ - "movq %q5, %%r10\n" - /* (rax,rdx) = p4 * c0 */ - "movq %7, %%rax\n" - "mulq %%r10\n" - /* (rax,rdx) += p0 */ - "addq %q1, %%rax\n" - "adcq $0, %%rdx\n" - /* extract r0 */ - "movq %%rax, 0(%q6)\n" - /* Move to (r8,r9) */ - "movq %%rdx, %%r8\n" - "xorq %%r9, %%r9\n" - /* (r8,r9) += p1 */ - "addq %q2, %%r8\n" - "adcq $0, %%r9\n" - /* (r8,r9) += p4 * c1 */ - "movq %8, %%rax\n" - "mulq %%r10\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - /* Extract r1 */ - "movq %%r8, 8(%q6)\n" - "xorq %%r8, %%r8\n" - /* (r9,r8) += p4 */ - "addq %%r10, %%r9\n" - "adcq $0, %%r8\n" - /* (r9,r8) += p2 */ - "addq %q3, %%r9\n" - "adcq $0, %%r8\n" - /* Extract r2 */ - "movq %%r9, 16(%q6)\n" - "xorq %%r9, %%r9\n" - /* (r8,r9) += p3 */ - "addq %q4, %%r8\n" - "adcq $0, %%r9\n" - /* Extract r3 */ - "movq %%r8, 24(%q6)\n" - /* Extract c */ - "movq %%r9, %q0\n" - : "=g"(c) - : "g"(p0), "g"(p1), "g"(p2), "g"(p3), "g"(p4), "D"(r), "n"(SECP256K1_N_C_0), "n"(SECP256K1_N_C_1) - : "rax", "rdx", "r8", "r9", "r10", "cc", "memory"); -#else - uint128_t c; - uint64_t c0, c1, c2; - uint64_t n0 = l[4], n1 = l[5], n2 = l[6], n3 = l[7]; - uint64_t m0, m1, m2, m3, m4, m5; - uint32_t m6; - uint64_t p0, p1, p2, p3; - uint32_t p4; - - /* Reduce 512 bits into 385. */ - /* m[0..6] = l[0..3] + n[0..3] * SECP256K1_N_C. */ - c0 = l[0]; c1 = 0; c2 = 0; - muladd_fast(n0, SECP256K1_N_C_0); - extract_fast(m0); - sumadd_fast(l[1]); - muladd(n1, SECP256K1_N_C_0); - muladd(n0, SECP256K1_N_C_1); - extract(m1); - sumadd(l[2]); - muladd(n2, SECP256K1_N_C_0); - muladd(n1, SECP256K1_N_C_1); - sumadd(n0); - extract(m2); - sumadd(l[3]); - muladd(n3, SECP256K1_N_C_0); - muladd(n2, SECP256K1_N_C_1); - sumadd(n1); - extract(m3); - muladd(n3, SECP256K1_N_C_1); - sumadd(n2); - extract(m4); - sumadd_fast(n3); - extract_fast(m5); - VERIFY_CHECK(c0 <= 1); - m6 = c0; - - /* Reduce 385 bits into 258. */ - /* p[0..4] = m[0..3] + m[4..6] * SECP256K1_N_C. */ - c0 = m0; c1 = 0; c2 = 0; - muladd_fast(m4, SECP256K1_N_C_0); - extract_fast(p0); - sumadd_fast(m1); - muladd(m5, SECP256K1_N_C_0); - muladd(m4, SECP256K1_N_C_1); - extract(p1); - sumadd(m2); - muladd(m6, SECP256K1_N_C_0); - muladd(m5, SECP256K1_N_C_1); - sumadd(m4); - extract(p2); - sumadd_fast(m3); - muladd_fast(m6, SECP256K1_N_C_1); - sumadd_fast(m5); - extract_fast(p3); - p4 = c0 + m6; - VERIFY_CHECK(p4 <= 2); - - /* Reduce 258 bits into 256. */ - /* r[0..3] = p[0..3] + p[4] * SECP256K1_N_C. */ - c = p0 + (uint128_t)SECP256K1_N_C_0 * p4; - r->d[0] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; - c += p1 + (uint128_t)SECP256K1_N_C_1 * p4; - r->d[1] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; - c += p2 + (uint128_t)p4; - r->d[2] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; - c += p3; - r->d[3] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; -#endif - - /* Final reduction of r. */ - secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r)); -} - -static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar *a, const secp256k1_scalar *b) { -#ifdef USE_ASM_X86_64 - const uint64_t *pb = b->d; - __asm__ __volatile__( - /* Preload */ - "movq 0(%%rdi), %%r15\n" - "movq 8(%%rdi), %%rbx\n" - "movq 16(%%rdi), %%rcx\n" - "movq 0(%%rdx), %%r11\n" - "movq 8(%%rdx), %%r12\n" - "movq 16(%%rdx), %%r13\n" - "movq 24(%%rdx), %%r14\n" - /* (rax,rdx) = a0 * b0 */ - "movq %%r15, %%rax\n" - "mulq %%r11\n" - /* Extract l0 */ - "movq %%rax, 0(%%rsi)\n" - /* (r8,r9,r10) = (rdx) */ - "movq %%rdx, %%r8\n" - "xorq %%r9, %%r9\n" - "xorq %%r10, %%r10\n" - /* (r8,r9,r10) += a0 * b1 */ - "movq %%r15, %%rax\n" - "mulq %%r12\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - /* (r8,r9,r10) += a1 * b0 */ - "movq %%rbx, %%rax\n" - "mulq %%r11\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - /* Extract l1 */ - "movq %%r8, 8(%%rsi)\n" - "xorq %%r8, %%r8\n" - /* (r9,r10,r8) += a0 * b2 */ - "movq %%r15, %%rax\n" - "mulq %%r13\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* (r9,r10,r8) += a1 * b1 */ - "movq %%rbx, %%rax\n" - "mulq %%r12\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* (r9,r10,r8) += a2 * b0 */ - "movq %%rcx, %%rax\n" - "mulq %%r11\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* Extract l2 */ - "movq %%r9, 16(%%rsi)\n" - "xorq %%r9, %%r9\n" - /* (r10,r8,r9) += a0 * b3 */ - "movq %%r15, %%rax\n" - "mulq %%r14\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - /* Preload a3 */ - "movq 24(%%rdi), %%r15\n" - /* (r10,r8,r9) += a1 * b2 */ - "movq %%rbx, %%rax\n" - "mulq %%r13\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - /* (r10,r8,r9) += a2 * b1 */ - "movq %%rcx, %%rax\n" - "mulq %%r12\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - /* (r10,r8,r9) += a3 * b0 */ - "movq %%r15, %%rax\n" - "mulq %%r11\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - /* Extract l3 */ - "movq %%r10, 24(%%rsi)\n" - "xorq %%r10, %%r10\n" - /* (r8,r9,r10) += a1 * b3 */ - "movq %%rbx, %%rax\n" - "mulq %%r14\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - /* (r8,r9,r10) += a2 * b2 */ - "movq %%rcx, %%rax\n" - "mulq %%r13\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - /* (r8,r9,r10) += a3 * b1 */ - "movq %%r15, %%rax\n" - "mulq %%r12\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - /* Extract l4 */ - "movq %%r8, 32(%%rsi)\n" - "xorq %%r8, %%r8\n" - /* (r9,r10,r8) += a2 * b3 */ - "movq %%rcx, %%rax\n" - "mulq %%r14\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* (r9,r10,r8) += a3 * b2 */ - "movq %%r15, %%rax\n" - "mulq %%r13\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* Extract l5 */ - "movq %%r9, 40(%%rsi)\n" - /* (r10,r8) += a3 * b3 */ - "movq %%r15, %%rax\n" - "mulq %%r14\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - /* Extract l6 */ - "movq %%r10, 48(%%rsi)\n" - /* Extract l7 */ - "movq %%r8, 56(%%rsi)\n" - : "+d"(pb) - : "S"(l), "D"(a->d) - : "rax", "rbx", "rcx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "cc", "memory"); -#else - /* 160 bit accumulator. */ - uint64_t c0 = 0, c1 = 0; - uint32_t c2 = 0; - - /* l[0..7] = a[0..3] * b[0..3]. */ - muladd_fast(a->d[0], b->d[0]); - extract_fast(l[0]); - muladd(a->d[0], b->d[1]); - muladd(a->d[1], b->d[0]); - extract(l[1]); - muladd(a->d[0], b->d[2]); - muladd(a->d[1], b->d[1]); - muladd(a->d[2], b->d[0]); - extract(l[2]); - muladd(a->d[0], b->d[3]); - muladd(a->d[1], b->d[2]); - muladd(a->d[2], b->d[1]); - muladd(a->d[3], b->d[0]); - extract(l[3]); - muladd(a->d[1], b->d[3]); - muladd(a->d[2], b->d[2]); - muladd(a->d[3], b->d[1]); - extract(l[4]); - muladd(a->d[2], b->d[3]); - muladd(a->d[3], b->d[2]); - extract(l[5]); - muladd_fast(a->d[3], b->d[3]); - extract_fast(l[6]); - VERIFY_CHECK(c1 == 0); - l[7] = c0; -#endif -} - -static void secp256k1_scalar_sqr_512(uint64_t l[8], const secp256k1_scalar *a) { -#ifdef USE_ASM_X86_64 - __asm__ __volatile__( - /* Preload */ - "movq 0(%%rdi), %%r11\n" - "movq 8(%%rdi), %%r12\n" - "movq 16(%%rdi), %%r13\n" - "movq 24(%%rdi), %%r14\n" - /* (rax,rdx) = a0 * a0 */ - "movq %%r11, %%rax\n" - "mulq %%r11\n" - /* Extract l0 */ - "movq %%rax, 0(%%rsi)\n" - /* (r8,r9,r10) = (rdx,0) */ - "movq %%rdx, %%r8\n" - "xorq %%r9, %%r9\n" - "xorq %%r10, %%r10\n" - /* (r8,r9,r10) += 2 * a0 * a1 */ - "movq %%r11, %%rax\n" - "mulq %%r12\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - /* Extract l1 */ - "movq %%r8, 8(%%rsi)\n" - "xorq %%r8, %%r8\n" - /* (r9,r10,r8) += 2 * a0 * a2 */ - "movq %%r11, %%rax\n" - "mulq %%r13\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* (r9,r10,r8) += a1 * a1 */ - "movq %%r12, %%rax\n" - "mulq %%r12\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* Extract l2 */ - "movq %%r9, 16(%%rsi)\n" - "xorq %%r9, %%r9\n" - /* (r10,r8,r9) += 2 * a0 * a3 */ - "movq %%r11, %%rax\n" - "mulq %%r14\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - /* (r10,r8,r9) += 2 * a1 * a2 */ - "movq %%r12, %%rax\n" - "mulq %%r13\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - "adcq $0, %%r9\n" - /* Extract l3 */ - "movq %%r10, 24(%%rsi)\n" - "xorq %%r10, %%r10\n" - /* (r8,r9,r10) += 2 * a1 * a3 */ - "movq %%r12, %%rax\n" - "mulq %%r14\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - /* (r8,r9,r10) += a2 * a2 */ - "movq %%r13, %%rax\n" - "mulq %%r13\n" - "addq %%rax, %%r8\n" - "adcq %%rdx, %%r9\n" - "adcq $0, %%r10\n" - /* Extract l4 */ - "movq %%r8, 32(%%rsi)\n" - "xorq %%r8, %%r8\n" - /* (r9,r10,r8) += 2 * a2 * a3 */ - "movq %%r13, %%rax\n" - "mulq %%r14\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - "addq %%rax, %%r9\n" - "adcq %%rdx, %%r10\n" - "adcq $0, %%r8\n" - /* Extract l5 */ - "movq %%r9, 40(%%rsi)\n" - /* (r10,r8) += a3 * a3 */ - "movq %%r14, %%rax\n" - "mulq %%r14\n" - "addq %%rax, %%r10\n" - "adcq %%rdx, %%r8\n" - /* Extract l6 */ - "movq %%r10, 48(%%rsi)\n" - /* Extract l7 */ - "movq %%r8, 56(%%rsi)\n" - : - : "S"(l), "D"(a->d) - : "rax", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "cc", "memory"); -#else - /* 160 bit accumulator. */ - uint64_t c0 = 0, c1 = 0; - uint32_t c2 = 0; - - /* l[0..7] = a[0..3] * b[0..3]. */ - muladd_fast(a->d[0], a->d[0]); - extract_fast(l[0]); - muladd2(a->d[0], a->d[1]); - extract(l[1]); - muladd2(a->d[0], a->d[2]); - muladd(a->d[1], a->d[1]); - extract(l[2]); - muladd2(a->d[0], a->d[3]); - muladd2(a->d[1], a->d[2]); - extract(l[3]); - muladd2(a->d[1], a->d[3]); - muladd(a->d[2], a->d[2]); - extract(l[4]); - muladd2(a->d[2], a->d[3]); - extract(l[5]); - muladd_fast(a->d[3], a->d[3]); - extract_fast(l[6]); - VERIFY_CHECK(c1 == 0); - l[7] = c0; -#endif -} - -#undef sumadd -#undef sumadd_fast -#undef muladd -#undef muladd_fast -#undef muladd2 -#undef extract -#undef extract_fast - -static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { - uint64_t l[8]; - secp256k1_scalar_mul_512(l, a, b); - secp256k1_scalar_reduce_512(r, l); -} - -static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { - int ret; - VERIFY_CHECK(n > 0); - VERIFY_CHECK(n < 16); - ret = r->d[0] & ((1 << n) - 1); - r->d[0] = (r->d[0] >> n) + (r->d[1] << (64 - n)); - r->d[1] = (r->d[1] >> n) + (r->d[2] << (64 - n)); - r->d[2] = (r->d[2] >> n) + (r->d[3] << (64 - n)); - r->d[3] = (r->d[3] >> n); - return ret; -} - -static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { - uint64_t l[8]; - secp256k1_scalar_sqr_512(l, a); - secp256k1_scalar_reduce_512(r, l); -} - -#ifdef USE_ENDOMORPHISM -static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { - r1->d[0] = a->d[0]; - r1->d[1] = a->d[1]; - r1->d[2] = 0; - r1->d[3] = 0; - r2->d[0] = a->d[2]; - r2->d[1] = a->d[3]; - r2->d[2] = 0; - r2->d[3] = 0; -} -#endif - -SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { - return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3])) == 0; -} - -SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift) { - uint64_t l[8]; - unsigned int shiftlimbs; - unsigned int shiftlow; - unsigned int shifthigh; - VERIFY_CHECK(shift >= 256); - secp256k1_scalar_mul_512(l, a, b); - shiftlimbs = shift >> 6; - shiftlow = shift & 0x3F; - shifthigh = 64 - shiftlow; - r->d[0] = shift < 512 ? (l[0 + shiftlimbs] >> shiftlow | (shift < 448 && shiftlow ? (l[1 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[1] = shift < 448 ? (l[1 + shiftlimbs] >> shiftlow | (shift < 384 && shiftlow ? (l[2 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[2] = shift < 384 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[3] = shift < 320 ? (l[3 + shiftlimbs] >> shiftlow) : 0; - secp256k1_scalar_cadd_bit(r, 0, (l[(shift - 1) >> 6] >> ((shift - 1) & 0x3f)) & 1); -} - -#endif /* SECP256K1_SCALAR_REPR_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/scalar_8x32.h b/util/secp256k1/depend/secp256k1/src/scalar_8x32.h deleted file mode 100644 index 2c9a348e24..0000000000 --- a/util/secp256k1/depend/secp256k1/src/scalar_8x32.h +++ /dev/null @@ -1,19 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_SCALAR_REPR_H -#define SECP256K1_SCALAR_REPR_H - -#include - -/** A scalar modulo the group order of the secp256k1 curve. */ -typedef struct { - uint32_t d[8]; -} secp256k1_scalar; - -#define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)}} - -#endif /* SECP256K1_SCALAR_REPR_H */ diff --git a/util/secp256k1/depend/secp256k1/src/scalar_8x32_impl.h b/util/secp256k1/depend/secp256k1/src/scalar_8x32_impl.h deleted file mode 100644 index 4f9ed61fea..0000000000 --- a/util/secp256k1/depend/secp256k1/src/scalar_8x32_impl.h +++ /dev/null @@ -1,721 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_SCALAR_REPR_IMPL_H -#define SECP256K1_SCALAR_REPR_IMPL_H - -/* Limbs of the secp256k1 order. */ -#define SECP256K1_N_0 ((uint32_t)0xD0364141UL) -#define SECP256K1_N_1 ((uint32_t)0xBFD25E8CUL) -#define SECP256K1_N_2 ((uint32_t)0xAF48A03BUL) -#define SECP256K1_N_3 ((uint32_t)0xBAAEDCE6UL) -#define SECP256K1_N_4 ((uint32_t)0xFFFFFFFEUL) -#define SECP256K1_N_5 ((uint32_t)0xFFFFFFFFUL) -#define SECP256K1_N_6 ((uint32_t)0xFFFFFFFFUL) -#define SECP256K1_N_7 ((uint32_t)0xFFFFFFFFUL) - -/* Limbs of 2^256 minus the secp256k1 order. */ -#define SECP256K1_N_C_0 (~SECP256K1_N_0 + 1) -#define SECP256K1_N_C_1 (~SECP256K1_N_1) -#define SECP256K1_N_C_2 (~SECP256K1_N_2) -#define SECP256K1_N_C_3 (~SECP256K1_N_3) -#define SECP256K1_N_C_4 (1) - -/* Limbs of half the secp256k1 order. */ -#define SECP256K1_N_H_0 ((uint32_t)0x681B20A0UL) -#define SECP256K1_N_H_1 ((uint32_t)0xDFE92F46UL) -#define SECP256K1_N_H_2 ((uint32_t)0x57A4501DUL) -#define SECP256K1_N_H_3 ((uint32_t)0x5D576E73UL) -#define SECP256K1_N_H_4 ((uint32_t)0xFFFFFFFFUL) -#define SECP256K1_N_H_5 ((uint32_t)0xFFFFFFFFUL) -#define SECP256K1_N_H_6 ((uint32_t)0xFFFFFFFFUL) -#define SECP256K1_N_H_7 ((uint32_t)0x7FFFFFFFUL) - -SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { - r->d[0] = 0; - r->d[1] = 0; - r->d[2] = 0; - r->d[3] = 0; - r->d[4] = 0; - r->d[5] = 0; - r->d[6] = 0; - r->d[7] = 0; -} - -SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { - r->d[0] = v; - r->d[1] = 0; - r->d[2] = 0; - r->d[3] = 0; - r->d[4] = 0; - r->d[5] = 0; - r->d[6] = 0; - r->d[7] = 0; -} - -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { - VERIFY_CHECK((offset + count - 1) >> 5 == offset >> 5); - return (a->d[offset >> 5] >> (offset & 0x1F)) & ((1 << count) - 1); -} - -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { - VERIFY_CHECK(count < 32); - VERIFY_CHECK(offset + count <= 256); - if ((offset + count - 1) >> 5 == offset >> 5) { - return secp256k1_scalar_get_bits(a, offset, count); - } else { - VERIFY_CHECK((offset >> 5) + 1 < 8); - return ((a->d[offset >> 5] >> (offset & 0x1F)) | (a->d[(offset >> 5) + 1] << (32 - (offset & 0x1F)))) & ((((uint32_t)1) << count) - 1); - } -} - -SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { - int yes = 0; - int no = 0; - no |= (a->d[7] < SECP256K1_N_7); /* No need for a > check. */ - no |= (a->d[6] < SECP256K1_N_6); /* No need for a > check. */ - no |= (a->d[5] < SECP256K1_N_5); /* No need for a > check. */ - no |= (a->d[4] < SECP256K1_N_4); - yes |= (a->d[4] > SECP256K1_N_4) & ~no; - no |= (a->d[3] < SECP256K1_N_3) & ~yes; - yes |= (a->d[3] > SECP256K1_N_3) & ~no; - no |= (a->d[2] < SECP256K1_N_2) & ~yes; - yes |= (a->d[2] > SECP256K1_N_2) & ~no; - no |= (a->d[1] < SECP256K1_N_1) & ~yes; - yes |= (a->d[1] > SECP256K1_N_1) & ~no; - yes |= (a->d[0] >= SECP256K1_N_0) & ~no; - return yes; -} - -SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, uint32_t overflow) { - uint64_t t; - VERIFY_CHECK(overflow <= 1); - t = (uint64_t)r->d[0] + overflow * SECP256K1_N_C_0; - r->d[0] = t & 0xFFFFFFFFUL; t >>= 32; - t += (uint64_t)r->d[1] + overflow * SECP256K1_N_C_1; - r->d[1] = t & 0xFFFFFFFFUL; t >>= 32; - t += (uint64_t)r->d[2] + overflow * SECP256K1_N_C_2; - r->d[2] = t & 0xFFFFFFFFUL; t >>= 32; - t += (uint64_t)r->d[3] + overflow * SECP256K1_N_C_3; - r->d[3] = t & 0xFFFFFFFFUL; t >>= 32; - t += (uint64_t)r->d[4] + overflow * SECP256K1_N_C_4; - r->d[4] = t & 0xFFFFFFFFUL; t >>= 32; - t += (uint64_t)r->d[5]; - r->d[5] = t & 0xFFFFFFFFUL; t >>= 32; - t += (uint64_t)r->d[6]; - r->d[6] = t & 0xFFFFFFFFUL; t >>= 32; - t += (uint64_t)r->d[7]; - r->d[7] = t & 0xFFFFFFFFUL; - return overflow; -} - -static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { - int overflow; - uint64_t t = (uint64_t)a->d[0] + b->d[0]; - r->d[0] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)a->d[1] + b->d[1]; - r->d[1] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)a->d[2] + b->d[2]; - r->d[2] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)a->d[3] + b->d[3]; - r->d[3] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)a->d[4] + b->d[4]; - r->d[4] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)a->d[5] + b->d[5]; - r->d[5] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)a->d[6] + b->d[6]; - r->d[6] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)a->d[7] + b->d[7]; - r->d[7] = t & 0xFFFFFFFFULL; t >>= 32; - overflow = t + secp256k1_scalar_check_overflow(r); - VERIFY_CHECK(overflow == 0 || overflow == 1); - secp256k1_scalar_reduce(r, overflow); - return overflow; -} - -static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { - uint64_t t; - VERIFY_CHECK(bit < 256); - bit += ((uint32_t) flag - 1) & 0x100; /* forcing (bit >> 5) > 7 makes this a noop */ - t = (uint64_t)r->d[0] + (((uint32_t)((bit >> 5) == 0)) << (bit & 0x1F)); - r->d[0] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)r->d[1] + (((uint32_t)((bit >> 5) == 1)) << (bit & 0x1F)); - r->d[1] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)r->d[2] + (((uint32_t)((bit >> 5) == 2)) << (bit & 0x1F)); - r->d[2] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)r->d[3] + (((uint32_t)((bit >> 5) == 3)) << (bit & 0x1F)); - r->d[3] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)r->d[4] + (((uint32_t)((bit >> 5) == 4)) << (bit & 0x1F)); - r->d[4] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)r->d[5] + (((uint32_t)((bit >> 5) == 5)) << (bit & 0x1F)); - r->d[5] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)r->d[6] + (((uint32_t)((bit >> 5) == 6)) << (bit & 0x1F)); - r->d[6] = t & 0xFFFFFFFFULL; t >>= 32; - t += (uint64_t)r->d[7] + (((uint32_t)((bit >> 5) == 7)) << (bit & 0x1F)); - r->d[7] = t & 0xFFFFFFFFULL; -#ifdef VERIFY - VERIFY_CHECK((t >> 32) == 0); - VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); -#endif -} - -static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { - int over; - r->d[0] = (uint32_t)b32[31] | (uint32_t)b32[30] << 8 | (uint32_t)b32[29] << 16 | (uint32_t)b32[28] << 24; - r->d[1] = (uint32_t)b32[27] | (uint32_t)b32[26] << 8 | (uint32_t)b32[25] << 16 | (uint32_t)b32[24] << 24; - r->d[2] = (uint32_t)b32[23] | (uint32_t)b32[22] << 8 | (uint32_t)b32[21] << 16 | (uint32_t)b32[20] << 24; - r->d[3] = (uint32_t)b32[19] | (uint32_t)b32[18] << 8 | (uint32_t)b32[17] << 16 | (uint32_t)b32[16] << 24; - r->d[4] = (uint32_t)b32[15] | (uint32_t)b32[14] << 8 | (uint32_t)b32[13] << 16 | (uint32_t)b32[12] << 24; - r->d[5] = (uint32_t)b32[11] | (uint32_t)b32[10] << 8 | (uint32_t)b32[9] << 16 | (uint32_t)b32[8] << 24; - r->d[6] = (uint32_t)b32[7] | (uint32_t)b32[6] << 8 | (uint32_t)b32[5] << 16 | (uint32_t)b32[4] << 24; - r->d[7] = (uint32_t)b32[3] | (uint32_t)b32[2] << 8 | (uint32_t)b32[1] << 16 | (uint32_t)b32[0] << 24; - over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r)); - if (overflow) { - *overflow = over; - } -} - -static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { - bin[0] = a->d[7] >> 24; bin[1] = a->d[7] >> 16; bin[2] = a->d[7] >> 8; bin[3] = a->d[7]; - bin[4] = a->d[6] >> 24; bin[5] = a->d[6] >> 16; bin[6] = a->d[6] >> 8; bin[7] = a->d[6]; - bin[8] = a->d[5] >> 24; bin[9] = a->d[5] >> 16; bin[10] = a->d[5] >> 8; bin[11] = a->d[5]; - bin[12] = a->d[4] >> 24; bin[13] = a->d[4] >> 16; bin[14] = a->d[4] >> 8; bin[15] = a->d[4]; - bin[16] = a->d[3] >> 24; bin[17] = a->d[3] >> 16; bin[18] = a->d[3] >> 8; bin[19] = a->d[3]; - bin[20] = a->d[2] >> 24; bin[21] = a->d[2] >> 16; bin[22] = a->d[2] >> 8; bin[23] = a->d[2]; - bin[24] = a->d[1] >> 24; bin[25] = a->d[1] >> 16; bin[26] = a->d[1] >> 8; bin[27] = a->d[1]; - bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0]; -} - -SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { - return (a->d[0] | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0; -} - -static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { - uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(a) == 0); - uint64_t t = (uint64_t)(~a->d[0]) + SECP256K1_N_0 + 1; - r->d[0] = t & nonzero; t >>= 32; - t += (uint64_t)(~a->d[1]) + SECP256K1_N_1; - r->d[1] = t & nonzero; t >>= 32; - t += (uint64_t)(~a->d[2]) + SECP256K1_N_2; - r->d[2] = t & nonzero; t >>= 32; - t += (uint64_t)(~a->d[3]) + SECP256K1_N_3; - r->d[3] = t & nonzero; t >>= 32; - t += (uint64_t)(~a->d[4]) + SECP256K1_N_4; - r->d[4] = t & nonzero; t >>= 32; - t += (uint64_t)(~a->d[5]) + SECP256K1_N_5; - r->d[5] = t & nonzero; t >>= 32; - t += (uint64_t)(~a->d[6]) + SECP256K1_N_6; - r->d[6] = t & nonzero; t >>= 32; - t += (uint64_t)(~a->d[7]) + SECP256K1_N_7; - r->d[7] = t & nonzero; -} - -SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { - return ((a->d[0] ^ 1) | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0; -} - -static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { - int yes = 0; - int no = 0; - no |= (a->d[7] < SECP256K1_N_H_7); - yes |= (a->d[7] > SECP256K1_N_H_7) & ~no; - no |= (a->d[6] < SECP256K1_N_H_6) & ~yes; /* No need for a > check. */ - no |= (a->d[5] < SECP256K1_N_H_5) & ~yes; /* No need for a > check. */ - no |= (a->d[4] < SECP256K1_N_H_4) & ~yes; /* No need for a > check. */ - no |= (a->d[3] < SECP256K1_N_H_3) & ~yes; - yes |= (a->d[3] > SECP256K1_N_H_3) & ~no; - no |= (a->d[2] < SECP256K1_N_H_2) & ~yes; - yes |= (a->d[2] > SECP256K1_N_H_2) & ~no; - no |= (a->d[1] < SECP256K1_N_H_1) & ~yes; - yes |= (a->d[1] > SECP256K1_N_H_1) & ~no; - yes |= (a->d[0] > SECP256K1_N_H_0) & ~no; - return yes; -} - -static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { - /* If we are flag = 0, mask = 00...00 and this is a no-op; - * if we are flag = 1, mask = 11...11 and this is identical to secp256k1_scalar_negate */ - uint32_t mask = !flag - 1; - uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(r) == 0); - uint64_t t = (uint64_t)(r->d[0] ^ mask) + ((SECP256K1_N_0 + 1) & mask); - r->d[0] = t & nonzero; t >>= 32; - t += (uint64_t)(r->d[1] ^ mask) + (SECP256K1_N_1 & mask); - r->d[1] = t & nonzero; t >>= 32; - t += (uint64_t)(r->d[2] ^ mask) + (SECP256K1_N_2 & mask); - r->d[2] = t & nonzero; t >>= 32; - t += (uint64_t)(r->d[3] ^ mask) + (SECP256K1_N_3 & mask); - r->d[3] = t & nonzero; t >>= 32; - t += (uint64_t)(r->d[4] ^ mask) + (SECP256K1_N_4 & mask); - r->d[4] = t & nonzero; t >>= 32; - t += (uint64_t)(r->d[5] ^ mask) + (SECP256K1_N_5 & mask); - r->d[5] = t & nonzero; t >>= 32; - t += (uint64_t)(r->d[6] ^ mask) + (SECP256K1_N_6 & mask); - r->d[6] = t & nonzero; t >>= 32; - t += (uint64_t)(r->d[7] ^ mask) + (SECP256K1_N_7 & mask); - r->d[7] = t & nonzero; - return 2 * (mask == 0) - 1; -} - - -/* Inspired by the macros in OpenSSL's crypto/bn/asm/x86_64-gcc.c. */ - -/** Add a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ -#define muladd(a,b) { \ - uint32_t tl, th; \ - { \ - uint64_t t = (uint64_t)a * b; \ - th = t >> 32; /* at most 0xFFFFFFFE */ \ - tl = t; \ - } \ - c0 += tl; /* overflow is handled on the next line */ \ - th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \ - c1 += th; /* overflow is handled on the next line */ \ - c2 += (c1 < th) ? 1 : 0; /* never overflows by contract (verified in the next line) */ \ - VERIFY_CHECK((c1 >= th) || (c2 != 0)); \ -} - -/** Add a*b to the number defined by (c0,c1). c1 must never overflow. */ -#define muladd_fast(a,b) { \ - uint32_t tl, th; \ - { \ - uint64_t t = (uint64_t)a * b; \ - th = t >> 32; /* at most 0xFFFFFFFE */ \ - tl = t; \ - } \ - c0 += tl; /* overflow is handled on the next line */ \ - th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \ - c1 += th; /* never overflows by contract (verified in the next line) */ \ - VERIFY_CHECK(c1 >= th); \ -} - -/** Add 2*a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ -#define muladd2(a,b) { \ - uint32_t tl, th, th2, tl2; \ - { \ - uint64_t t = (uint64_t)a * b; \ - th = t >> 32; /* at most 0xFFFFFFFE */ \ - tl = t; \ - } \ - th2 = th + th; /* at most 0xFFFFFFFE (in case th was 0x7FFFFFFF) */ \ - c2 += (th2 < th) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((th2 >= th) || (c2 != 0)); \ - tl2 = tl + tl; /* at most 0xFFFFFFFE (in case the lowest 63 bits of tl were 0x7FFFFFFF) */ \ - th2 += (tl2 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \ - c0 += tl2; /* overflow is handled on the next line */ \ - th2 += (c0 < tl2) ? 1 : 0; /* second overflow is handled on the next line */ \ - c2 += (c0 < tl2) & (th2 == 0); /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((c0 >= tl2) || (th2 != 0) || (c2 != 0)); \ - c1 += th2; /* overflow is handled on the next line */ \ - c2 += (c1 < th2) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((c1 >= th2) || (c2 != 0)); \ -} - -/** Add a to the number defined by (c0,c1,c2). c2 must never overflow. */ -#define sumadd(a) { \ - unsigned int over; \ - c0 += (a); /* overflow is handled on the next line */ \ - over = (c0 < (a)) ? 1 : 0; \ - c1 += over; /* overflow is handled on the next line */ \ - c2 += (c1 < over) ? 1 : 0; /* never overflows by contract */ \ -} - -/** Add a to the number defined by (c0,c1). c1 must never overflow, c2 must be zero. */ -#define sumadd_fast(a) { \ - c0 += (a); /* overflow is handled on the next line */ \ - c1 += (c0 < (a)) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ - VERIFY_CHECK((c1 != 0) | (c0 >= (a))); \ - VERIFY_CHECK(c2 == 0); \ -} - -/** Extract the lowest 32 bits of (c0,c1,c2) into n, and left shift the number 32 bits. */ -#define extract(n) { \ - (n) = c0; \ - c0 = c1; \ - c1 = c2; \ - c2 = 0; \ -} - -/** Extract the lowest 32 bits of (c0,c1,c2) into n, and left shift the number 32 bits. c2 is required to be zero. */ -#define extract_fast(n) { \ - (n) = c0; \ - c0 = c1; \ - c1 = 0; \ - VERIFY_CHECK(c2 == 0); \ -} - -static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint32_t *l) { - uint64_t c; - uint32_t n0 = l[8], n1 = l[9], n2 = l[10], n3 = l[11], n4 = l[12], n5 = l[13], n6 = l[14], n7 = l[15]; - uint32_t m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12; - uint32_t p0, p1, p2, p3, p4, p5, p6, p7, p8; - - /* 96 bit accumulator. */ - uint32_t c0, c1, c2; - - /* Reduce 512 bits into 385. */ - /* m[0..12] = l[0..7] + n[0..7] * SECP256K1_N_C. */ - c0 = l[0]; c1 = 0; c2 = 0; - muladd_fast(n0, SECP256K1_N_C_0); - extract_fast(m0); - sumadd_fast(l[1]); - muladd(n1, SECP256K1_N_C_0); - muladd(n0, SECP256K1_N_C_1); - extract(m1); - sumadd(l[2]); - muladd(n2, SECP256K1_N_C_0); - muladd(n1, SECP256K1_N_C_1); - muladd(n0, SECP256K1_N_C_2); - extract(m2); - sumadd(l[3]); - muladd(n3, SECP256K1_N_C_0); - muladd(n2, SECP256K1_N_C_1); - muladd(n1, SECP256K1_N_C_2); - muladd(n0, SECP256K1_N_C_3); - extract(m3); - sumadd(l[4]); - muladd(n4, SECP256K1_N_C_0); - muladd(n3, SECP256K1_N_C_1); - muladd(n2, SECP256K1_N_C_2); - muladd(n1, SECP256K1_N_C_3); - sumadd(n0); - extract(m4); - sumadd(l[5]); - muladd(n5, SECP256K1_N_C_0); - muladd(n4, SECP256K1_N_C_1); - muladd(n3, SECP256K1_N_C_2); - muladd(n2, SECP256K1_N_C_3); - sumadd(n1); - extract(m5); - sumadd(l[6]); - muladd(n6, SECP256K1_N_C_0); - muladd(n5, SECP256K1_N_C_1); - muladd(n4, SECP256K1_N_C_2); - muladd(n3, SECP256K1_N_C_3); - sumadd(n2); - extract(m6); - sumadd(l[7]); - muladd(n7, SECP256K1_N_C_0); - muladd(n6, SECP256K1_N_C_1); - muladd(n5, SECP256K1_N_C_2); - muladd(n4, SECP256K1_N_C_3); - sumadd(n3); - extract(m7); - muladd(n7, SECP256K1_N_C_1); - muladd(n6, SECP256K1_N_C_2); - muladd(n5, SECP256K1_N_C_3); - sumadd(n4); - extract(m8); - muladd(n7, SECP256K1_N_C_2); - muladd(n6, SECP256K1_N_C_3); - sumadd(n5); - extract(m9); - muladd(n7, SECP256K1_N_C_3); - sumadd(n6); - extract(m10); - sumadd_fast(n7); - extract_fast(m11); - VERIFY_CHECK(c0 <= 1); - m12 = c0; - - /* Reduce 385 bits into 258. */ - /* p[0..8] = m[0..7] + m[8..12] * SECP256K1_N_C. */ - c0 = m0; c1 = 0; c2 = 0; - muladd_fast(m8, SECP256K1_N_C_0); - extract_fast(p0); - sumadd_fast(m1); - muladd(m9, SECP256K1_N_C_0); - muladd(m8, SECP256K1_N_C_1); - extract(p1); - sumadd(m2); - muladd(m10, SECP256K1_N_C_0); - muladd(m9, SECP256K1_N_C_1); - muladd(m8, SECP256K1_N_C_2); - extract(p2); - sumadd(m3); - muladd(m11, SECP256K1_N_C_0); - muladd(m10, SECP256K1_N_C_1); - muladd(m9, SECP256K1_N_C_2); - muladd(m8, SECP256K1_N_C_3); - extract(p3); - sumadd(m4); - muladd(m12, SECP256K1_N_C_0); - muladd(m11, SECP256K1_N_C_1); - muladd(m10, SECP256K1_N_C_2); - muladd(m9, SECP256K1_N_C_3); - sumadd(m8); - extract(p4); - sumadd(m5); - muladd(m12, SECP256K1_N_C_1); - muladd(m11, SECP256K1_N_C_2); - muladd(m10, SECP256K1_N_C_3); - sumadd(m9); - extract(p5); - sumadd(m6); - muladd(m12, SECP256K1_N_C_2); - muladd(m11, SECP256K1_N_C_3); - sumadd(m10); - extract(p6); - sumadd_fast(m7); - muladd_fast(m12, SECP256K1_N_C_3); - sumadd_fast(m11); - extract_fast(p7); - p8 = c0 + m12; - VERIFY_CHECK(p8 <= 2); - - /* Reduce 258 bits into 256. */ - /* r[0..7] = p[0..7] + p[8] * SECP256K1_N_C. */ - c = p0 + (uint64_t)SECP256K1_N_C_0 * p8; - r->d[0] = c & 0xFFFFFFFFUL; c >>= 32; - c += p1 + (uint64_t)SECP256K1_N_C_1 * p8; - r->d[1] = c & 0xFFFFFFFFUL; c >>= 32; - c += p2 + (uint64_t)SECP256K1_N_C_2 * p8; - r->d[2] = c & 0xFFFFFFFFUL; c >>= 32; - c += p3 + (uint64_t)SECP256K1_N_C_3 * p8; - r->d[3] = c & 0xFFFFFFFFUL; c >>= 32; - c += p4 + (uint64_t)p8; - r->d[4] = c & 0xFFFFFFFFUL; c >>= 32; - c += p5; - r->d[5] = c & 0xFFFFFFFFUL; c >>= 32; - c += p6; - r->d[6] = c & 0xFFFFFFFFUL; c >>= 32; - c += p7; - r->d[7] = c & 0xFFFFFFFFUL; c >>= 32; - - /* Final reduction of r. */ - secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r)); -} - -static void secp256k1_scalar_mul_512(uint32_t *l, const secp256k1_scalar *a, const secp256k1_scalar *b) { - /* 96 bit accumulator. */ - uint32_t c0 = 0, c1 = 0, c2 = 0; - - /* l[0..15] = a[0..7] * b[0..7]. */ - muladd_fast(a->d[0], b->d[0]); - extract_fast(l[0]); - muladd(a->d[0], b->d[1]); - muladd(a->d[1], b->d[0]); - extract(l[1]); - muladd(a->d[0], b->d[2]); - muladd(a->d[1], b->d[1]); - muladd(a->d[2], b->d[0]); - extract(l[2]); - muladd(a->d[0], b->d[3]); - muladd(a->d[1], b->d[2]); - muladd(a->d[2], b->d[1]); - muladd(a->d[3], b->d[0]); - extract(l[3]); - muladd(a->d[0], b->d[4]); - muladd(a->d[1], b->d[3]); - muladd(a->d[2], b->d[2]); - muladd(a->d[3], b->d[1]); - muladd(a->d[4], b->d[0]); - extract(l[4]); - muladd(a->d[0], b->d[5]); - muladd(a->d[1], b->d[4]); - muladd(a->d[2], b->d[3]); - muladd(a->d[3], b->d[2]); - muladd(a->d[4], b->d[1]); - muladd(a->d[5], b->d[0]); - extract(l[5]); - muladd(a->d[0], b->d[6]); - muladd(a->d[1], b->d[5]); - muladd(a->d[2], b->d[4]); - muladd(a->d[3], b->d[3]); - muladd(a->d[4], b->d[2]); - muladd(a->d[5], b->d[1]); - muladd(a->d[6], b->d[0]); - extract(l[6]); - muladd(a->d[0], b->d[7]); - muladd(a->d[1], b->d[6]); - muladd(a->d[2], b->d[5]); - muladd(a->d[3], b->d[4]); - muladd(a->d[4], b->d[3]); - muladd(a->d[5], b->d[2]); - muladd(a->d[6], b->d[1]); - muladd(a->d[7], b->d[0]); - extract(l[7]); - muladd(a->d[1], b->d[7]); - muladd(a->d[2], b->d[6]); - muladd(a->d[3], b->d[5]); - muladd(a->d[4], b->d[4]); - muladd(a->d[5], b->d[3]); - muladd(a->d[6], b->d[2]); - muladd(a->d[7], b->d[1]); - extract(l[8]); - muladd(a->d[2], b->d[7]); - muladd(a->d[3], b->d[6]); - muladd(a->d[4], b->d[5]); - muladd(a->d[5], b->d[4]); - muladd(a->d[6], b->d[3]); - muladd(a->d[7], b->d[2]); - extract(l[9]); - muladd(a->d[3], b->d[7]); - muladd(a->d[4], b->d[6]); - muladd(a->d[5], b->d[5]); - muladd(a->d[6], b->d[4]); - muladd(a->d[7], b->d[3]); - extract(l[10]); - muladd(a->d[4], b->d[7]); - muladd(a->d[5], b->d[6]); - muladd(a->d[6], b->d[5]); - muladd(a->d[7], b->d[4]); - extract(l[11]); - muladd(a->d[5], b->d[7]); - muladd(a->d[6], b->d[6]); - muladd(a->d[7], b->d[5]); - extract(l[12]); - muladd(a->d[6], b->d[7]); - muladd(a->d[7], b->d[6]); - extract(l[13]); - muladd_fast(a->d[7], b->d[7]); - extract_fast(l[14]); - VERIFY_CHECK(c1 == 0); - l[15] = c0; -} - -static void secp256k1_scalar_sqr_512(uint32_t *l, const secp256k1_scalar *a) { - /* 96 bit accumulator. */ - uint32_t c0 = 0, c1 = 0, c2 = 0; - - /* l[0..15] = a[0..7]^2. */ - muladd_fast(a->d[0], a->d[0]); - extract_fast(l[0]); - muladd2(a->d[0], a->d[1]); - extract(l[1]); - muladd2(a->d[0], a->d[2]); - muladd(a->d[1], a->d[1]); - extract(l[2]); - muladd2(a->d[0], a->d[3]); - muladd2(a->d[1], a->d[2]); - extract(l[3]); - muladd2(a->d[0], a->d[4]); - muladd2(a->d[1], a->d[3]); - muladd(a->d[2], a->d[2]); - extract(l[4]); - muladd2(a->d[0], a->d[5]); - muladd2(a->d[1], a->d[4]); - muladd2(a->d[2], a->d[3]); - extract(l[5]); - muladd2(a->d[0], a->d[6]); - muladd2(a->d[1], a->d[5]); - muladd2(a->d[2], a->d[4]); - muladd(a->d[3], a->d[3]); - extract(l[6]); - muladd2(a->d[0], a->d[7]); - muladd2(a->d[1], a->d[6]); - muladd2(a->d[2], a->d[5]); - muladd2(a->d[3], a->d[4]); - extract(l[7]); - muladd2(a->d[1], a->d[7]); - muladd2(a->d[2], a->d[6]); - muladd2(a->d[3], a->d[5]); - muladd(a->d[4], a->d[4]); - extract(l[8]); - muladd2(a->d[2], a->d[7]); - muladd2(a->d[3], a->d[6]); - muladd2(a->d[4], a->d[5]); - extract(l[9]); - muladd2(a->d[3], a->d[7]); - muladd2(a->d[4], a->d[6]); - muladd(a->d[5], a->d[5]); - extract(l[10]); - muladd2(a->d[4], a->d[7]); - muladd2(a->d[5], a->d[6]); - extract(l[11]); - muladd2(a->d[5], a->d[7]); - muladd(a->d[6], a->d[6]); - extract(l[12]); - muladd2(a->d[6], a->d[7]); - extract(l[13]); - muladd_fast(a->d[7], a->d[7]); - extract_fast(l[14]); - VERIFY_CHECK(c1 == 0); - l[15] = c0; -} - -#undef sumadd -#undef sumadd_fast -#undef muladd -#undef muladd_fast -#undef muladd2 -#undef extract -#undef extract_fast - -static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { - uint32_t l[16]; - secp256k1_scalar_mul_512(l, a, b); - secp256k1_scalar_reduce_512(r, l); -} - -static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { - int ret; - VERIFY_CHECK(n > 0); - VERIFY_CHECK(n < 16); - ret = r->d[0] & ((1 << n) - 1); - r->d[0] = (r->d[0] >> n) + (r->d[1] << (32 - n)); - r->d[1] = (r->d[1] >> n) + (r->d[2] << (32 - n)); - r->d[2] = (r->d[2] >> n) + (r->d[3] << (32 - n)); - r->d[3] = (r->d[3] >> n) + (r->d[4] << (32 - n)); - r->d[4] = (r->d[4] >> n) + (r->d[5] << (32 - n)); - r->d[5] = (r->d[5] >> n) + (r->d[6] << (32 - n)); - r->d[6] = (r->d[6] >> n) + (r->d[7] << (32 - n)); - r->d[7] = (r->d[7] >> n); - return ret; -} - -static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { - uint32_t l[16]; - secp256k1_scalar_sqr_512(l, a); - secp256k1_scalar_reduce_512(r, l); -} - -#ifdef USE_ENDOMORPHISM -static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { - r1->d[0] = a->d[0]; - r1->d[1] = a->d[1]; - r1->d[2] = a->d[2]; - r1->d[3] = a->d[3]; - r1->d[4] = 0; - r1->d[5] = 0; - r1->d[6] = 0; - r1->d[7] = 0; - r2->d[0] = a->d[4]; - r2->d[1] = a->d[5]; - r2->d[2] = a->d[6]; - r2->d[3] = a->d[7]; - r2->d[4] = 0; - r2->d[5] = 0; - r2->d[6] = 0; - r2->d[7] = 0; -} -#endif - -SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { - return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3]) | (a->d[4] ^ b->d[4]) | (a->d[5] ^ b->d[5]) | (a->d[6] ^ b->d[6]) | (a->d[7] ^ b->d[7])) == 0; -} - -SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift) { - uint32_t l[16]; - unsigned int shiftlimbs; - unsigned int shiftlow; - unsigned int shifthigh; - VERIFY_CHECK(shift >= 256); - secp256k1_scalar_mul_512(l, a, b); - shiftlimbs = shift >> 5; - shiftlow = shift & 0x1F; - shifthigh = 32 - shiftlow; - r->d[0] = shift < 512 ? (l[0 + shiftlimbs] >> shiftlow | (shift < 480 && shiftlow ? (l[1 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[1] = shift < 480 ? (l[1 + shiftlimbs] >> shiftlow | (shift < 448 && shiftlow ? (l[2 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[2] = shift < 448 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 416 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[3] = shift < 416 ? (l[3 + shiftlimbs] >> shiftlow | (shift < 384 && shiftlow ? (l[4 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[4] = shift < 384 ? (l[4 + shiftlimbs] >> shiftlow | (shift < 352 && shiftlow ? (l[5 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[5] = shift < 352 ? (l[5 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[6 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[6] = shift < 320 ? (l[6 + shiftlimbs] >> shiftlow | (shift < 288 && shiftlow ? (l[7 + shiftlimbs] << shifthigh) : 0)) : 0; - r->d[7] = shift < 288 ? (l[7 + shiftlimbs] >> shiftlow) : 0; - secp256k1_scalar_cadd_bit(r, 0, (l[(shift - 1) >> 5] >> ((shift - 1) & 0x1f)) & 1); -} - -#endif /* SECP256K1_SCALAR_REPR_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/scalar_impl.h b/util/secp256k1/depend/secp256k1/src/scalar_impl.h deleted file mode 100644 index fa790570ff..0000000000 --- a/util/secp256k1/depend/secp256k1/src/scalar_impl.h +++ /dev/null @@ -1,333 +0,0 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_SCALAR_IMPL_H -#define SECP256K1_SCALAR_IMPL_H - -#include "group.h" -#include "scalar.h" - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif - -#if defined(EXHAUSTIVE_TEST_ORDER) -#include "scalar_low_impl.h" -#elif defined(USE_SCALAR_4X64) -#include "scalar_4x64_impl.h" -#elif defined(USE_SCALAR_8X32) -#include "scalar_8x32_impl.h" -#else -#error "Please select scalar implementation" -#endif - -#ifndef USE_NUM_NONE -static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a) { - unsigned char c[32]; - secp256k1_scalar_get_b32(c, a); - secp256k1_num_set_bin(r, c, 32); -} - -/** secp256k1 curve order, see secp256k1_ecdsa_const_order_as_fe in ecdsa_impl.h */ -static void secp256k1_scalar_order_get_num(secp256k1_num *r) { -#if defined(EXHAUSTIVE_TEST_ORDER) - static const unsigned char order[32] = { - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,EXHAUSTIVE_TEST_ORDER - }; -#else - static const unsigned char order[32] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, - 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, - 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 - }; -#endif - secp256k1_num_set_bin(r, order, 32); -} -#endif - -static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) { -#if defined(EXHAUSTIVE_TEST_ORDER) - int i; - *r = 0; - for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) - if ((i * *x) % EXHAUSTIVE_TEST_ORDER == 1) - *r = i; - /* If this VERIFY_CHECK triggers we were given a noninvertible scalar (and thus - * have a composite group order; fix it in exhaustive_tests.c). */ - VERIFY_CHECK(*r != 0); -} -#else - secp256k1_scalar *t; - int i; - /* First compute xN as x ^ (2^N - 1) for some values of N, - * and uM as x ^ M for some values of M. */ - secp256k1_scalar x2, x3, x6, x8, x14, x28, x56, x112, x126; - secp256k1_scalar u2, u5, u9, u11, u13; - - secp256k1_scalar_sqr(&u2, x); - secp256k1_scalar_mul(&x2, &u2, x); - secp256k1_scalar_mul(&u5, &u2, &x2); - secp256k1_scalar_mul(&x3, &u5, &u2); - secp256k1_scalar_mul(&u9, &x3, &u2); - secp256k1_scalar_mul(&u11, &u9, &u2); - secp256k1_scalar_mul(&u13, &u11, &u2); - - secp256k1_scalar_sqr(&x6, &u13); - secp256k1_scalar_sqr(&x6, &x6); - secp256k1_scalar_mul(&x6, &x6, &u11); - - secp256k1_scalar_sqr(&x8, &x6); - secp256k1_scalar_sqr(&x8, &x8); - secp256k1_scalar_mul(&x8, &x8, &x2); - - secp256k1_scalar_sqr(&x14, &x8); - for (i = 0; i < 5; i++) { - secp256k1_scalar_sqr(&x14, &x14); - } - secp256k1_scalar_mul(&x14, &x14, &x6); - - secp256k1_scalar_sqr(&x28, &x14); - for (i = 0; i < 13; i++) { - secp256k1_scalar_sqr(&x28, &x28); - } - secp256k1_scalar_mul(&x28, &x28, &x14); - - secp256k1_scalar_sqr(&x56, &x28); - for (i = 0; i < 27; i++) { - secp256k1_scalar_sqr(&x56, &x56); - } - secp256k1_scalar_mul(&x56, &x56, &x28); - - secp256k1_scalar_sqr(&x112, &x56); - for (i = 0; i < 55; i++) { - secp256k1_scalar_sqr(&x112, &x112); - } - secp256k1_scalar_mul(&x112, &x112, &x56); - - secp256k1_scalar_sqr(&x126, &x112); - for (i = 0; i < 13; i++) { - secp256k1_scalar_sqr(&x126, &x126); - } - secp256k1_scalar_mul(&x126, &x126, &x14); - - /* Then accumulate the final result (t starts at x126). */ - t = &x126; - for (i = 0; i < 3; i++) { - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u5); /* 101 */ - for (i = 0; i < 4; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 4; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u5); /* 101 */ - for (i = 0; i < 5; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u11); /* 1011 */ - for (i = 0; i < 4; i++) { - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u11); /* 1011 */ - for (i = 0; i < 4; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 5; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 6; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u13); /* 1101 */ - for (i = 0; i < 4; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u5); /* 101 */ - for (i = 0; i < 3; i++) { - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 5; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u9); /* 1001 */ - for (i = 0; i < 6; i++) { /* 000 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u5); /* 101 */ - for (i = 0; i < 10; i++) { /* 0000000 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 4; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 9; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x8); /* 11111111 */ - for (i = 0; i < 5; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u9); /* 1001 */ - for (i = 0; i < 6; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u11); /* 1011 */ - for (i = 0; i < 4; i++) { - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u13); /* 1101 */ - for (i = 0; i < 5; i++) { - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 6; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u13); /* 1101 */ - for (i = 0; i < 10; i++) { /* 000000 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u13); /* 1101 */ - for (i = 0; i < 4; i++) { - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &u9); /* 1001 */ - for (i = 0; i < 6; i++) { /* 00000 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 8; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(r, t, &x6); /* 111111 */ -} - -SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { - return !(a->d[0] & 1); -} -#endif - -static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) { -#if defined(USE_SCALAR_INV_BUILTIN) - secp256k1_scalar_inverse(r, x); -#elif defined(USE_SCALAR_INV_NUM) - unsigned char b[32]; - secp256k1_num n, m; - secp256k1_scalar t = *x; - secp256k1_scalar_get_b32(b, &t); - secp256k1_num_set_bin(&n, b, 32); - secp256k1_scalar_order_get_num(&m); - secp256k1_num_mod_inverse(&n, &n, &m); - secp256k1_num_get_bin(b, 32, &n); - secp256k1_scalar_set_b32(r, b, NULL); - /* Verify that the inverse was computed correctly, without GMP code. */ - secp256k1_scalar_mul(&t, &t, r); - CHECK(secp256k1_scalar_is_one(&t)); -#else -#error "Please select scalar inverse implementation" -#endif -} - -#ifdef USE_ENDOMORPHISM -#if defined(EXHAUSTIVE_TEST_ORDER) -/** - * Find k1 and k2 given k, such that k1 + k2 * lambda == k mod n; unlike in the - * full case we don't bother making k1 and k2 be small, we just want them to be - * nontrivial to get full test coverage for the exhaustive tests. We therefore - * (arbitrarily) set k2 = k + 5 and k1 = k - k2 * lambda. - */ -static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { - *r2 = (*a + 5) % EXHAUSTIVE_TEST_ORDER; - *r1 = (*a + (EXHAUSTIVE_TEST_ORDER - *r2) * EXHAUSTIVE_TEST_LAMBDA) % EXHAUSTIVE_TEST_ORDER; -} -#else -/** - * The Secp256k1 curve has an endomorphism, where lambda * (x, y) = (beta * x, y), where - * lambda is {0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0,0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a, - * 0x12,0x2e,0x22,0xea,0x20,0x81,0x66,0x78,0xdf,0x02,0x96,0x7c,0x1b,0x23,0xbd,0x72} - * - * "Guide to Elliptic Curve Cryptography" (Hankerson, Menezes, Vanstone) gives an algorithm - * (algorithm 3.74) to find k1 and k2 given k, such that k1 + k2 * lambda == k mod n, and k1 - * and k2 have a small size. - * It relies on constants a1, b1, a2, b2. These constants for the value of lambda above are: - * - * - a1 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} - * - b1 = -{0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28,0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3} - * - a2 = {0x01,0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6,0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8} - * - b2 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} - * - * The algorithm then computes c1 = round(b1 * k / n) and c2 = round(b2 * k / n), and gives - * k1 = k - (c1*a1 + c2*a2) and k2 = -(c1*b1 + c2*b2). Instead, we use modular arithmetic, and - * compute k1 as k - k2 * lambda, avoiding the need for constants a1 and a2. - * - * g1, g2 are precomputed constants used to replace division with a rounded multiplication - * when decomposing the scalar for an endomorphism-based point multiplication. - * - * The possibility of using precomputed estimates is mentioned in "Guide to Elliptic Curve - * Cryptography" (Hankerson, Menezes, Vanstone) in section 3.5. - * - * The derivation is described in the paper "Efficient Software Implementation of Public-Key - * Cryptography on Sensor Networks Using the MSP430X Microcontroller" (Gouvea, Oliveira, Lopez), - * Section 4.3 (here we use a somewhat higher-precision estimate): - * d = a1*b2 - b1*a2 - * g1 = round((2^272)*b2/d) - * g2 = round((2^272)*b1/d) - * - * (Note that 'd' is also equal to the curve order here because [a1,b1] and [a2,b2] are found - * as outputs of the Extended Euclidean Algorithm on inputs 'order' and 'lambda'). - * - * The function below splits a in r1 and r2, such that r1 + lambda * r2 == a (mod order). - */ - -static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { - secp256k1_scalar c1, c2; - static const secp256k1_scalar minus_lambda = SECP256K1_SCALAR_CONST( - 0xAC9C52B3UL, 0x3FA3CF1FUL, 0x5AD9E3FDUL, 0x77ED9BA4UL, - 0xA880B9FCUL, 0x8EC739C2UL, 0xE0CFC810UL, 0xB51283CFUL - ); - static const secp256k1_scalar minus_b1 = SECP256K1_SCALAR_CONST( - 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, - 0xE4437ED6UL, 0x010E8828UL, 0x6F547FA9UL, 0x0ABFE4C3UL - ); - static const secp256k1_scalar minus_b2 = SECP256K1_SCALAR_CONST( - 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, - 0x8A280AC5UL, 0x0774346DUL, 0xD765CDA8UL, 0x3DB1562CUL - ); - static const secp256k1_scalar g1 = SECP256K1_SCALAR_CONST( - 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00003086UL, - 0xD221A7D4UL, 0x6BCDE86CUL, 0x90E49284UL, 0xEB153DABUL - ); - static const secp256k1_scalar g2 = SECP256K1_SCALAR_CONST( - 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x0000E443UL, - 0x7ED6010EUL, 0x88286F54UL, 0x7FA90ABFUL, 0xE4C42212UL - ); - VERIFY_CHECK(r1 != a); - VERIFY_CHECK(r2 != a); - /* these _var calls are constant time since the shift amount is constant */ - secp256k1_scalar_mul_shift_var(&c1, a, &g1, 272); - secp256k1_scalar_mul_shift_var(&c2, a, &g2, 272); - secp256k1_scalar_mul(&c1, &c1, &minus_b1); - secp256k1_scalar_mul(&c2, &c2, &minus_b2); - secp256k1_scalar_add(r2, &c1, &c2); - secp256k1_scalar_mul(r1, r2, &minus_lambda); - secp256k1_scalar_add(r1, r1, a); -} -#endif -#endif - -#endif /* SECP256K1_SCALAR_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/scalar_low.h b/util/secp256k1/depend/secp256k1/src/scalar_low.h deleted file mode 100644 index 5836febc5b..0000000000 --- a/util/secp256k1/depend/secp256k1/src/scalar_low.h +++ /dev/null @@ -1,15 +0,0 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_SCALAR_REPR_H -#define SECP256K1_SCALAR_REPR_H - -#include - -/** A scalar modulo the group order of the secp256k1 curve. */ -typedef uint32_t secp256k1_scalar; - -#endif /* SECP256K1_SCALAR_REPR_H */ diff --git a/util/secp256k1/depend/secp256k1/src/scalar_low_impl.h b/util/secp256k1/depend/secp256k1/src/scalar_low_impl.h deleted file mode 100644 index c80e70c5a2..0000000000 --- a/util/secp256k1/depend/secp256k1/src/scalar_low_impl.h +++ /dev/null @@ -1,114 +0,0 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_SCALAR_REPR_IMPL_H -#define SECP256K1_SCALAR_REPR_IMPL_H - -#include "scalar.h" - -#include - -SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { - return !(*a & 1); -} - -SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { *r = 0; } -SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { *r = v; } - -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { - if (offset < 32) - return ((*a >> offset) & ((((uint32_t)1) << count) - 1)); - else - return 0; -} - -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { - return secp256k1_scalar_get_bits(a, offset, count); -} - -SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { return *a >= EXHAUSTIVE_TEST_ORDER; } - -static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { - *r = (*a + *b) % EXHAUSTIVE_TEST_ORDER; - return *r < *b; -} - -static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { - if (flag && bit < 32) - *r += (1 << bit); -#ifdef VERIFY - VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); -#endif -} - -static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { - const int base = 0x100 % EXHAUSTIVE_TEST_ORDER; - int i; - *r = 0; - for (i = 0; i < 32; i++) { - *r = ((*r * base) + b32[i]) % EXHAUSTIVE_TEST_ORDER; - } - /* just deny overflow, it basically always happens */ - if (overflow) *overflow = 0; -} - -static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { - memset(bin, 0, 32); - bin[28] = *a >> 24; bin[29] = *a >> 16; bin[30] = *a >> 8; bin[31] = *a; -} - -SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { - return *a == 0; -} - -static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { - if (*a == 0) { - *r = 0; - } else { - *r = EXHAUSTIVE_TEST_ORDER - *a; - } -} - -SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { - return *a == 1; -} - -static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { - return *a > EXHAUSTIVE_TEST_ORDER / 2; -} - -static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { - if (flag) secp256k1_scalar_negate(r, r); - return flag ? -1 : 1; -} - -static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { - *r = (*a * *b) % EXHAUSTIVE_TEST_ORDER; -} - -static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { - int ret; - VERIFY_CHECK(n > 0); - VERIFY_CHECK(n < 16); - ret = *r & ((1 << n) - 1); - *r >>= n; - return ret; -} - -static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { - *r = (*a * *a) % EXHAUSTIVE_TEST_ORDER; -} - -static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { - *r1 = *a; - *r2 = 0; -} - -SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { - return *a == *b; -} - -#endif /* SECP256K1_SCALAR_REPR_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/secp256k1.c b/util/secp256k1/depend/secp256k1/src/secp256k1.c deleted file mode 100644 index a34e82eda5..0000000000 --- a/util/secp256k1/depend/secp256k1/src/secp256k1.c +++ /dev/null @@ -1,588 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#include "include/secp256k1.h" - -#include "util.h" -#include "num_impl.h" -#include "field_impl.h" -#include "scalar_impl.h" -#include "group_impl.h" -#include "ecmult_impl.h" -#include "ecmult_const_impl.h" -#include "ecmult_gen_impl.h" -#include "ecdsa_impl.h" -#include "eckey_impl.h" -#include "hash_impl.h" - -#define ARG_CHECK(cond) do { \ - if (EXPECT(!(cond), 0)) { \ - secp256k1_callback_call(&ctx->illegal_callback, #cond); \ - return 0; \ - } \ -} while(0) - -static void default_illegal_callback_fn(const char* str, void* data) { - (void)data; - fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str); - abort(); -} - -static const secp256k1_callback default_illegal_callback = { - default_illegal_callback_fn, - NULL -}; - -static void default_error_callback_fn(const char* str, void* data) { - (void)data; - fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); - abort(); -} - -static const secp256k1_callback default_error_callback = { - default_error_callback_fn, - NULL -}; - - -struct secp256k1_context_struct { - secp256k1_ecmult_context ecmult_ctx; - secp256k1_ecmult_gen_context ecmult_gen_ctx; - secp256k1_callback illegal_callback; - secp256k1_callback error_callback; -}; - -secp256k1_context* secp256k1_context_create(unsigned int flags) { - secp256k1_context* ret = (secp256k1_context*)checked_malloc(&default_error_callback, sizeof(secp256k1_context)); - ret->illegal_callback = default_illegal_callback; - ret->error_callback = default_error_callback; - - if (EXPECT((flags & SECP256K1_FLAGS_TYPE_MASK) != SECP256K1_FLAGS_TYPE_CONTEXT, 0)) { - secp256k1_callback_call(&ret->illegal_callback, - "Invalid flags"); - free(ret); - return NULL; - } - - secp256k1_ecmult_context_init(&ret->ecmult_ctx); - secp256k1_ecmult_gen_context_init(&ret->ecmult_gen_ctx); - - if (flags & SECP256K1_FLAGS_BIT_CONTEXT_SIGN) { - secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx, &ret->error_callback); - } - if (flags & SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) { - secp256k1_ecmult_context_build(&ret->ecmult_ctx, &ret->error_callback); - } - - return ret; -} - -secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) { - secp256k1_context* ret = (secp256k1_context*)checked_malloc(&ctx->error_callback, sizeof(secp256k1_context)); - ret->illegal_callback = ctx->illegal_callback; - ret->error_callback = ctx->error_callback; - secp256k1_ecmult_context_clone(&ret->ecmult_ctx, &ctx->ecmult_ctx, &ctx->error_callback); - secp256k1_ecmult_gen_context_clone(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx, &ctx->error_callback); - return ret; -} - -void secp256k1_context_destroy(secp256k1_context* ctx) { - if (ctx != NULL) { - secp256k1_ecmult_context_clear(&ctx->ecmult_ctx); - secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); - - free(ctx); - } -} - -void secp256k1_context_set_illegal_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { - if (fun == NULL) { - fun = default_illegal_callback_fn; - } - ctx->illegal_callback.fn = fun; - ctx->illegal_callback.data = data; -} - -void secp256k1_context_set_error_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { - if (fun == NULL) { - fun = default_error_callback_fn; - } - ctx->error_callback.fn = fun; - ctx->error_callback.data = data; -} - -static int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey) { - if (sizeof(secp256k1_ge_storage) == 64) { - /* When the secp256k1_ge_storage type is exactly 64 byte, use its - * representation inside secp256k1_pubkey, as conversion is very fast. - * Note that secp256k1_pubkey_save must use the same representation. */ - secp256k1_ge_storage s; - memcpy(&s, &pubkey->data[0], 64); - secp256k1_ge_from_storage(ge, &s); - } else { - /* Otherwise, fall back to 32-byte big endian for X and Y. */ - secp256k1_fe x, y; - secp256k1_fe_set_b32(&x, pubkey->data); - secp256k1_fe_set_b32(&y, pubkey->data + 32); - secp256k1_ge_set_xy(ge, &x, &y); - } - ARG_CHECK(!secp256k1_fe_is_zero(&ge->x)); - return 1; -} - -static void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) { - if (sizeof(secp256k1_ge_storage) == 64) { - secp256k1_ge_storage s; - secp256k1_ge_to_storage(&s, ge); - memcpy(&pubkey->data[0], &s, 64); - } else { - VERIFY_CHECK(!secp256k1_ge_is_infinity(ge)); - secp256k1_fe_normalize_var(&ge->x); - secp256k1_fe_normalize_var(&ge->y); - secp256k1_fe_get_b32(pubkey->data, &ge->x); - secp256k1_fe_get_b32(pubkey->data + 32, &ge->y); - } -} - -int secp256k1_ec_pubkey_parse(const secp256k1_context* ctx, secp256k1_pubkey* pubkey, const unsigned char *input, size_t inputlen) { - secp256k1_ge Q; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(pubkey != NULL); - memset(pubkey, 0, sizeof(*pubkey)); - ARG_CHECK(input != NULL); - if (!secp256k1_eckey_pubkey_parse(&Q, input, inputlen)) { - return 0; - } - secp256k1_pubkey_save(pubkey, &Q); - secp256k1_ge_clear(&Q); - return 1; -} - -int secp256k1_ec_pubkey_serialize(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey* pubkey, unsigned int flags) { - secp256k1_ge Q; - size_t len; - int ret = 0; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(outputlen != NULL); - ARG_CHECK(*outputlen >= ((flags & SECP256K1_FLAGS_BIT_COMPRESSION) ? 33 : 65)); - len = *outputlen; - *outputlen = 0; - ARG_CHECK(output != NULL); - memset(output, 0, len); - ARG_CHECK(pubkey != NULL); - ARG_CHECK((flags & SECP256K1_FLAGS_TYPE_MASK) == SECP256K1_FLAGS_TYPE_COMPRESSION); - if (secp256k1_pubkey_load(ctx, &Q, pubkey)) { - ret = secp256k1_eckey_pubkey_serialize(&Q, output, &len, flags & SECP256K1_FLAGS_BIT_COMPRESSION); - if (ret) { - *outputlen = len; - } - } - return ret; -} - -static void secp256k1_ecdsa_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_ecdsa_signature* sig) { - (void)ctx; - if (sizeof(secp256k1_scalar) == 32) { - /* When the secp256k1_scalar type is exactly 32 byte, use its - * representation inside secp256k1_ecdsa_signature, as conversion is very fast. - * Note that secp256k1_ecdsa_signature_save must use the same representation. */ - memcpy(r, &sig->data[0], 32); - memcpy(s, &sig->data[32], 32); - } else { - secp256k1_scalar_set_b32(r, &sig->data[0], NULL); - secp256k1_scalar_set_b32(s, &sig->data[32], NULL); - } -} - -static void secp256k1_ecdsa_signature_save(secp256k1_ecdsa_signature* sig, const secp256k1_scalar* r, const secp256k1_scalar* s) { - if (sizeof(secp256k1_scalar) == 32) { - memcpy(&sig->data[0], r, 32); - memcpy(&sig->data[32], s, 32); - } else { - secp256k1_scalar_get_b32(&sig->data[0], r); - secp256k1_scalar_get_b32(&sig->data[32], s); - } -} - -int secp256k1_ecdsa_signature_parse_der(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { - secp256k1_scalar r, s; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(sig != NULL); - ARG_CHECK(input != NULL); - - if (secp256k1_ecdsa_sig_parse(&r, &s, input, inputlen)) { - secp256k1_ecdsa_signature_save(sig, &r, &s); - return 1; - } else { - memset(sig, 0, sizeof(*sig)); - return 0; - } -} - -int secp256k1_ecdsa_signature_parse_compact(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input64) { - secp256k1_scalar r, s; - int ret = 1; - int overflow = 0; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(sig != NULL); - ARG_CHECK(input64 != NULL); - - secp256k1_scalar_set_b32(&r, &input64[0], &overflow); - ret &= !overflow; - secp256k1_scalar_set_b32(&s, &input64[32], &overflow); - ret &= !overflow; - if (ret) { - secp256k1_ecdsa_signature_save(sig, &r, &s); - } else { - memset(sig, 0, sizeof(*sig)); - } - return ret; -} - -int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_ecdsa_signature* sig) { - secp256k1_scalar r, s; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(output != NULL); - ARG_CHECK(outputlen != NULL); - ARG_CHECK(sig != NULL); - - secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); - return secp256k1_ecdsa_sig_serialize(output, outputlen, &r, &s); -} - -int secp256k1_ecdsa_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, const secp256k1_ecdsa_signature* sig) { - secp256k1_scalar r, s; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(output64 != NULL); - ARG_CHECK(sig != NULL); - - secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); - secp256k1_scalar_get_b32(&output64[0], &r); - secp256k1_scalar_get_b32(&output64[32], &s); - return 1; -} - -int secp256k1_ecdsa_signature_normalize(const secp256k1_context* ctx, secp256k1_ecdsa_signature *sigout, const secp256k1_ecdsa_signature *sigin) { - secp256k1_scalar r, s; - int ret = 0; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(sigin != NULL); - - secp256k1_ecdsa_signature_load(ctx, &r, &s, sigin); - ret = secp256k1_scalar_is_high(&s); - if (sigout != NULL) { - if (ret) { - secp256k1_scalar_negate(&s, &s); - } - secp256k1_ecdsa_signature_save(sigout, &r, &s); - } - - return ret; -} - -int secp256k1_ecdsa_verify(const secp256k1_context* ctx, const secp256k1_ecdsa_signature *sig, const unsigned char *msg32, const secp256k1_pubkey *pubkey) { - secp256k1_ge q; - secp256k1_scalar r, s; - secp256k1_scalar m; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(sig != NULL); - ARG_CHECK(pubkey != NULL); - - secp256k1_scalar_set_b32(&m, msg32, NULL); - secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); - return (!secp256k1_scalar_is_high(&s) && - secp256k1_pubkey_load(ctx, &q, pubkey) && - secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &r, &s, &q, &m)); -} - -static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { - unsigned char keydata[112]; - int keylen = 64; - secp256k1_rfc6979_hmac_sha256 rng; - unsigned int i; - /* We feed a byte array to the PRNG as input, consisting of: - * - the private key (32 bytes) and message (32 bytes), see RFC 6979 3.2d. - * - optionally 32 extra bytes of data, see RFC 6979 3.6 Additional Data. - * - optionally 16 extra bytes with the algorithm name. - * Because the arguments have distinct fixed lengths it is not possible for - * different argument mixtures to emulate each other and result in the same - * nonces. - */ - memcpy(keydata, key32, 32); - memcpy(keydata + 32, msg32, 32); - if (data != NULL) { - memcpy(keydata + 64, data, 32); - keylen = 96; - } - if (algo16 != NULL) { - memcpy(keydata + keylen, algo16, 16); - keylen += 16; - } - secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, keylen); - memset(keydata, 0, sizeof(keydata)); - for (i = 0; i <= counter; i++) { - secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); - } - secp256k1_rfc6979_hmac_sha256_finalize(&rng); - return 1; -} - -const secp256k1_nonce_function secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979; -const secp256k1_nonce_function secp256k1_nonce_function_default = nonce_function_rfc6979; - -int secp256k1_ecdsa_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { - secp256k1_scalar r, s; - secp256k1_scalar sec, non, msg; - int ret = 0; - int overflow = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); - ARG_CHECK(signature != NULL); - ARG_CHECK(seckey != NULL); - if (noncefp == NULL) { - noncefp = secp256k1_nonce_function_default; - } - - secp256k1_scalar_set_b32(&sec, seckey, &overflow); - /* Fail if the secret key is invalid. */ - if (!overflow && !secp256k1_scalar_is_zero(&sec)) { - unsigned char nonce32[32]; - unsigned int count = 0; - secp256k1_scalar_set_b32(&msg, msg32, NULL); - while (1) { - ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); - if (!ret) { - break; - } - secp256k1_scalar_set_b32(&non, nonce32, &overflow); - if (!overflow && !secp256k1_scalar_is_zero(&non)) { - if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, NULL)) { - break; - } - } - count++; - } - memset(nonce32, 0, 32); - secp256k1_scalar_clear(&msg); - secp256k1_scalar_clear(&non); - secp256k1_scalar_clear(&sec); - } - if (ret) { - secp256k1_ecdsa_signature_save(signature, &r, &s); - } else { - memset(signature, 0, sizeof(*signature)); - } - return ret; -} - -int secp256k1_ec_seckey_verify(const secp256k1_context* ctx, const unsigned char *seckey) { - secp256k1_scalar sec; - int ret; - int overflow; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(seckey != NULL); - - secp256k1_scalar_set_b32(&sec, seckey, &overflow); - ret = !overflow && !secp256k1_scalar_is_zero(&sec); - secp256k1_scalar_clear(&sec); - return ret; -} - -int secp256k1_ec_pubkey_create(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) { - secp256k1_gej pj; - secp256k1_ge p; - secp256k1_scalar sec; - int overflow; - int ret = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(pubkey != NULL); - memset(pubkey, 0, sizeof(*pubkey)); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(seckey != NULL); - - secp256k1_scalar_set_b32(&sec, seckey, &overflow); - ret = (!overflow) & (!secp256k1_scalar_is_zero(&sec)); - if (ret) { - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pj, &sec); - secp256k1_ge_set_gej(&p, &pj); - secp256k1_pubkey_save(pubkey, &p); - } - secp256k1_scalar_clear(&sec); - return ret; -} - -int secp256k1_ec_privkey_negate(const secp256k1_context* ctx, unsigned char *seckey) { - secp256k1_scalar sec; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(seckey != NULL); - - secp256k1_scalar_set_b32(&sec, seckey, NULL); - secp256k1_scalar_negate(&sec, &sec); - secp256k1_scalar_get_b32(seckey, &sec); - - return 1; -} - -int secp256k1_ec_pubkey_negate(const secp256k1_context* ctx, secp256k1_pubkey *pubkey) { - int ret = 0; - secp256k1_ge p; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(pubkey != NULL); - - ret = secp256k1_pubkey_load(ctx, &p, pubkey); - memset(pubkey, 0, sizeof(*pubkey)); - if (ret) { - secp256k1_ge_neg(&p, &p); - secp256k1_pubkey_save(pubkey, &p); - } - return ret; -} - -int secp256k1_ec_privkey_tweak_add(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak) { - secp256k1_scalar term; - secp256k1_scalar sec; - int ret = 0; - int overflow = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(seckey != NULL); - ARG_CHECK(tweak != NULL); - - secp256k1_scalar_set_b32(&term, tweak, &overflow); - secp256k1_scalar_set_b32(&sec, seckey, NULL); - - ret = !overflow && secp256k1_eckey_privkey_tweak_add(&sec, &term); - memset(seckey, 0, 32); - if (ret) { - secp256k1_scalar_get_b32(seckey, &sec); - } - - secp256k1_scalar_clear(&sec); - secp256k1_scalar_clear(&term); - return ret; -} - -int secp256k1_ec_pubkey_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak) { - secp256k1_ge p; - secp256k1_scalar term; - int ret = 0; - int overflow = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(pubkey != NULL); - ARG_CHECK(tweak != NULL); - - secp256k1_scalar_set_b32(&term, tweak, &overflow); - ret = !overflow && secp256k1_pubkey_load(ctx, &p, pubkey); - memset(pubkey, 0, sizeof(*pubkey)); - if (ret) { - if (secp256k1_eckey_pubkey_tweak_add(&ctx->ecmult_ctx, &p, &term)) { - secp256k1_pubkey_save(pubkey, &p); - } else { - ret = 0; - } - } - - return ret; -} - -int secp256k1_ec_privkey_tweak_mul(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak) { - secp256k1_scalar factor; - secp256k1_scalar sec; - int ret = 0; - int overflow = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(seckey != NULL); - ARG_CHECK(tweak != NULL); - - secp256k1_scalar_set_b32(&factor, tweak, &overflow); - secp256k1_scalar_set_b32(&sec, seckey, NULL); - ret = !overflow && secp256k1_eckey_privkey_tweak_mul(&sec, &factor); - memset(seckey, 0, 32); - if (ret) { - secp256k1_scalar_get_b32(seckey, &sec); - } - - secp256k1_scalar_clear(&sec); - secp256k1_scalar_clear(&factor); - return ret; -} - -int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak) { - secp256k1_ge p; - secp256k1_scalar factor; - int ret = 0; - int overflow = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(pubkey != NULL); - ARG_CHECK(tweak != NULL); - - secp256k1_scalar_set_b32(&factor, tweak, &overflow); - ret = !overflow && secp256k1_pubkey_load(ctx, &p, pubkey); - memset(pubkey, 0, sizeof(*pubkey)); - if (ret) { - if (secp256k1_eckey_pubkey_tweak_mul(&ctx->ecmult_ctx, &p, &factor)) { - secp256k1_pubkey_save(pubkey, &p); - } else { - ret = 0; - } - } - - return ret; -} - -int secp256k1_context_randomize(secp256k1_context* ctx, const unsigned char *seed32) { - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); - return 1; -} - -int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey *pubnonce, const secp256k1_pubkey * const *pubnonces, size_t n) { - size_t i; - secp256k1_gej Qj; - secp256k1_ge Q; - - ARG_CHECK(pubnonce != NULL); - memset(pubnonce, 0, sizeof(*pubnonce)); - ARG_CHECK(n >= 1); - ARG_CHECK(pubnonces != NULL); - - secp256k1_gej_set_infinity(&Qj); - - for (i = 0; i < n; i++) { - secp256k1_pubkey_load(ctx, &Q, pubnonces[i]); - secp256k1_gej_add_ge(&Qj, &Qj, &Q); - } - if (secp256k1_gej_is_infinity(&Qj)) { - return 0; - } - secp256k1_ge_set_gej(&Q, &Qj); - secp256k1_pubkey_save(pubnonce, &Q); - return 1; -} - -#ifdef ENABLE_MODULE_ECDH -# include "modules/ecdh/main_impl.h" -#endif - -#ifdef ENABLE_MODULE_SCHNORR -# include "modules/schnorr/main_impl.h" -#endif - -#ifdef ENABLE_MODULE_RECOVERY -# include "modules/recovery/main_impl.h" -#endif diff --git a/util/secp256k1/depend/secp256k1/src/testrand.h b/util/secp256k1/depend/secp256k1/src/testrand.h deleted file mode 100644 index f1f9be077e..0000000000 --- a/util/secp256k1/depend/secp256k1/src/testrand.h +++ /dev/null @@ -1,38 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_TESTRAND_H -#define SECP256K1_TESTRAND_H - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif - -/* A non-cryptographic RNG used only for test infrastructure. */ - -/** Seed the pseudorandom number generator for testing. */ -SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16); - -/** Generate a pseudorandom number in the range [0..2**32-1]. */ -static uint32_t secp256k1_rand32(void); - -/** Generate a pseudorandom number in the range [0..2**bits-1]. Bits must be 1 or - * more. */ -static uint32_t secp256k1_rand_bits(int bits); - -/** Generate a pseudorandom number in the range [0..range-1]. */ -static uint32_t secp256k1_rand_int(uint32_t range); - -/** Generate a pseudorandom 32-byte array. */ -static void secp256k1_rand256(unsigned char *b32); - -/** Generate a pseudorandom 32-byte array with long sequences of zero and one bits. */ -static void secp256k1_rand256_test(unsigned char *b32); - -/** Generate pseudorandom bytes with long sequences of zero and one bits. */ -static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len); - -#endif /* SECP256K1_TESTRAND_H */ diff --git a/util/secp256k1/depend/secp256k1/src/testrand_impl.h b/util/secp256k1/depend/secp256k1/src/testrand_impl.h deleted file mode 100644 index 30a91e5296..0000000000 --- a/util/secp256k1/depend/secp256k1/src/testrand_impl.h +++ /dev/null @@ -1,110 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_TESTRAND_IMPL_H -#define SECP256K1_TESTRAND_IMPL_H - -#include -#include - -#include "testrand.h" -#include "hash.h" - -static secp256k1_rfc6979_hmac_sha256 secp256k1_test_rng; -static uint32_t secp256k1_test_rng_precomputed[8]; -static int secp256k1_test_rng_precomputed_used = 8; -static uint64_t secp256k1_test_rng_integer; -static int secp256k1_test_rng_integer_bits_left = 0; - -SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16) { - secp256k1_rfc6979_hmac_sha256_initialize(&secp256k1_test_rng, seed16, 16); -} - -SECP256K1_INLINE static uint32_t secp256k1_rand32(void) { - if (secp256k1_test_rng_precomputed_used == 8) { - secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, (unsigned char*)(&secp256k1_test_rng_precomputed[0]), sizeof(secp256k1_test_rng_precomputed)); - secp256k1_test_rng_precomputed_used = 0; - } - return secp256k1_test_rng_precomputed[secp256k1_test_rng_precomputed_used++]; -} - -static uint32_t secp256k1_rand_bits(int bits) { - uint32_t ret; - if (secp256k1_test_rng_integer_bits_left < bits) { - secp256k1_test_rng_integer |= (((uint64_t)secp256k1_rand32()) << secp256k1_test_rng_integer_bits_left); - secp256k1_test_rng_integer_bits_left += 32; - } - ret = secp256k1_test_rng_integer; - secp256k1_test_rng_integer >>= bits; - secp256k1_test_rng_integer_bits_left -= bits; - ret &= ((~((uint32_t)0)) >> (32 - bits)); - return ret; -} - -static uint32_t secp256k1_rand_int(uint32_t range) { - /* We want a uniform integer between 0 and range-1, inclusive. - * B is the smallest number such that range <= 2**B. - * two mechanisms implemented here: - * - generate B bits numbers until one below range is found, and return it - * - find the largest multiple M of range that is <= 2**(B+A), generate B+A - * bits numbers until one below M is found, and return it modulo range - * The second mechanism consumes A more bits of entropy in every iteration, - * but may need fewer iterations due to M being closer to 2**(B+A) then - * range is to 2**B. The array below (indexed by B) contains a 0 when the - * first mechanism is to be used, and the number A otherwise. - */ - static const int addbits[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0}; - uint32_t trange, mult; - int bits = 0; - if (range <= 1) { - return 0; - } - trange = range - 1; - while (trange > 0) { - trange >>= 1; - bits++; - } - if (addbits[bits]) { - bits = bits + addbits[bits]; - mult = ((~((uint32_t)0)) >> (32 - bits)) / range; - trange = range * mult; - } else { - trange = range; - mult = 1; - } - while(1) { - uint32_t x = secp256k1_rand_bits(bits); - if (x < trange) { - return (mult == 1) ? x : (x % range); - } - } -} - -static void secp256k1_rand256(unsigned char *b32) { - secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, b32, 32); -} - -static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len) { - size_t bits = 0; - memset(bytes, 0, len); - while (bits < len * 8) { - int now; - uint32_t val; - now = 1 + (secp256k1_rand_bits(6) * secp256k1_rand_bits(5) + 16) / 31; - val = secp256k1_rand_bits(1); - while (now > 0 && bits < len * 8) { - bytes[bits / 8] |= val << (bits % 8); - now--; - bits++; - } - } -} - -static void secp256k1_rand256_test(unsigned char *b32) { - secp256k1_rand_bytes_test(b32, 32); -} - -#endif /* SECP256K1_TESTRAND_IMPL_H */ diff --git a/util/secp256k1/depend/secp256k1/src/tests.c b/util/secp256k1/depend/secp256k1/src/tests.c deleted file mode 100644 index 281bcf3a23..0000000000 --- a/util/secp256k1/depend/secp256k1/src/tests.c +++ /dev/null @@ -1,4545 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif - -#include -#include -#include - -#include - -#include "secp256k1.c" -#include "include/secp256k1.h" -#include "testrand_impl.h" - -#ifdef ENABLE_OPENSSL_TESTS -#include "openssl/bn.h" -#include "openssl/ec.h" -#include "openssl/ecdsa.h" -#include "openssl/obj_mac.h" -#endif - -#include "contrib/lax_der_parsing.c" -#include "contrib/lax_der_privatekey_parsing.c" - -#if !defined(VG_CHECK) -# if defined(VALGRIND) -# include -# define VG_UNDEF(x,y) VALGRIND_MAKE_MEM_UNDEFINED((x),(y)) -# define VG_CHECK(x,y) VALGRIND_CHECK_MEM_IS_DEFINED((x),(y)) -# else -# define VG_UNDEF(x,y) -# define VG_CHECK(x,y) -# endif -#endif - -static int count = 64; -static secp256k1_context *ctx = NULL; - -static void counting_illegal_callback_fn(const char* str, void* data) { - /* Dummy callback function that just counts. */ - int32_t *p; - (void)str; - p = data; - (*p)++; -} - -static void uncounting_illegal_callback_fn(const char* str, void* data) { - /* Dummy callback function that just counts (backwards). */ - int32_t *p; - (void)str; - p = data; - (*p)--; -} - -void random_field_element_test(secp256k1_fe *fe) { - do { - unsigned char b32[32]; - secp256k1_rand256_test(b32); - if (secp256k1_fe_set_b32(fe, b32)) { - break; - } - } while(1); -} - -void random_field_element_magnitude(secp256k1_fe *fe) { - secp256k1_fe zero; - int n = secp256k1_rand_int(9); - secp256k1_fe_normalize(fe); - if (n == 0) { - return; - } - secp256k1_fe_clear(&zero); - secp256k1_fe_negate(&zero, &zero, 0); - secp256k1_fe_mul_int(&zero, n - 1); - secp256k1_fe_add(fe, &zero); - VERIFY_CHECK(fe->magnitude == n); -} - -void random_group_element_test(secp256k1_ge *ge) { - secp256k1_fe fe; - do { - random_field_element_test(&fe); - if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_rand_bits(1))) { - secp256k1_fe_normalize(&ge->y); - break; - } - } while(1); -} - -void random_group_element_jacobian_test(secp256k1_gej *gej, const secp256k1_ge *ge) { - secp256k1_fe z2, z3; - do { - random_field_element_test(&gej->z); - if (!secp256k1_fe_is_zero(&gej->z)) { - break; - } - } while(1); - secp256k1_fe_sqr(&z2, &gej->z); - secp256k1_fe_mul(&z3, &z2, &gej->z); - secp256k1_fe_mul(&gej->x, &ge->x, &z2); - secp256k1_fe_mul(&gej->y, &ge->y, &z3); - gej->infinity = ge->infinity; -} - -void random_scalar_order_test(secp256k1_scalar *num) { - do { - unsigned char b32[32]; - int overflow = 0; - secp256k1_rand256_test(b32); - secp256k1_scalar_set_b32(num, b32, &overflow); - if (overflow || secp256k1_scalar_is_zero(num)) { - continue; - } - break; - } while(1); -} - -void random_scalar_order(secp256k1_scalar *num) { - do { - unsigned char b32[32]; - int overflow = 0; - secp256k1_rand256(b32); - secp256k1_scalar_set_b32(num, b32, &overflow); - if (overflow || secp256k1_scalar_is_zero(num)) { - continue; - } - break; - } while(1); -} - -void run_context_tests(void) { - secp256k1_pubkey pubkey; - secp256k1_pubkey zero_pubkey; - secp256k1_ecdsa_signature sig; - unsigned char ctmp[32]; - int32_t ecount; - int32_t ecount2; - secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE); - secp256k1_context *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); - secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); - secp256k1_context *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - - secp256k1_gej pubj; - secp256k1_ge pub; - secp256k1_scalar msg, key, nonce; - secp256k1_scalar sigr, sigs; - - memset(&zero_pubkey, 0, sizeof(zero_pubkey)); - - ecount = 0; - ecount2 = 10; - secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount); - secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount2); - secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, NULL); - CHECK(vrfy->error_callback.fn != sign->error_callback.fn); - - /*** clone and destroy all of them to make sure cloning was complete ***/ - { - secp256k1_context *ctx_tmp; - - ctx_tmp = none; none = secp256k1_context_clone(none); secp256k1_context_destroy(ctx_tmp); - ctx_tmp = sign; sign = secp256k1_context_clone(sign); secp256k1_context_destroy(ctx_tmp); - ctx_tmp = vrfy; vrfy = secp256k1_context_clone(vrfy); secp256k1_context_destroy(ctx_tmp); - ctx_tmp = both; both = secp256k1_context_clone(both); secp256k1_context_destroy(ctx_tmp); - } - - /* Verify that the error callback makes it across the clone. */ - CHECK(vrfy->error_callback.fn != sign->error_callback.fn); - /* And that it resets back to default. */ - secp256k1_context_set_error_callback(sign, NULL, NULL); - CHECK(vrfy->error_callback.fn == sign->error_callback.fn); - - /*** attempt to use them ***/ - random_scalar_order_test(&msg); - random_scalar_order_test(&key); - secp256k1_ecmult_gen(&both->ecmult_gen_ctx, &pubj, &key); - secp256k1_ge_set_gej(&pub, &pubj); - - /* Verify context-type checking illegal-argument errors. */ - memset(ctmp, 1, 32); - CHECK(secp256k1_ec_pubkey_create(vrfy, &pubkey, ctmp) == 0); - CHECK(ecount == 1); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(sign, &pubkey, ctmp) == 1); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ecdsa_sign(vrfy, &sig, ctmp, ctmp, NULL, NULL) == 0); - CHECK(ecount == 2); - VG_UNDEF(&sig, sizeof(sig)); - CHECK(secp256k1_ecdsa_sign(sign, &sig, ctmp, ctmp, NULL, NULL) == 1); - VG_CHECK(&sig, sizeof(sig)); - CHECK(ecount2 == 10); - CHECK(secp256k1_ecdsa_verify(sign, &sig, ctmp, &pubkey) == 0); - CHECK(ecount2 == 11); - CHECK(secp256k1_ecdsa_verify(vrfy, &sig, ctmp, &pubkey) == 1); - CHECK(ecount == 2); - CHECK(secp256k1_ec_pubkey_tweak_add(sign, &pubkey, ctmp) == 0); - CHECK(ecount2 == 12); - CHECK(secp256k1_ec_pubkey_tweak_add(vrfy, &pubkey, ctmp) == 1); - CHECK(ecount == 2); - CHECK(secp256k1_ec_pubkey_tweak_mul(sign, &pubkey, ctmp) == 0); - CHECK(ecount2 == 13); - CHECK(secp256k1_ec_pubkey_negate(vrfy, &pubkey) == 1); - CHECK(ecount == 2); - CHECK(secp256k1_ec_pubkey_negate(sign, &pubkey) == 1); - CHECK(ecount == 2); - CHECK(secp256k1_ec_pubkey_negate(sign, NULL) == 0); - CHECK(ecount2 == 14); - CHECK(secp256k1_ec_pubkey_negate(vrfy, &zero_pubkey) == 0); - CHECK(ecount == 3); - CHECK(secp256k1_ec_pubkey_tweak_mul(vrfy, &pubkey, ctmp) == 1); - CHECK(ecount == 3); - CHECK(secp256k1_context_randomize(vrfy, ctmp) == 0); - CHECK(ecount == 4); - CHECK(secp256k1_context_randomize(sign, NULL) == 1); - CHECK(ecount2 == 14); - secp256k1_context_set_illegal_callback(vrfy, NULL, NULL); - secp256k1_context_set_illegal_callback(sign, NULL, NULL); - - /* This shouldn't leak memory, due to already-set tests. */ - secp256k1_ecmult_gen_context_build(&sign->ecmult_gen_ctx, NULL); - secp256k1_ecmult_context_build(&vrfy->ecmult_ctx, NULL); - - /* obtain a working nonce */ - do { - random_scalar_order_test(&nonce); - } while(!secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); - - /* try signing */ - CHECK(secp256k1_ecdsa_sig_sign(&sign->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); - CHECK(secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); - - /* try verifying */ - CHECK(secp256k1_ecdsa_sig_verify(&vrfy->ecmult_ctx, &sigr, &sigs, &pub, &msg)); - CHECK(secp256k1_ecdsa_sig_verify(&both->ecmult_ctx, &sigr, &sigs, &pub, &msg)); - - /* cleanup */ - secp256k1_context_destroy(none); - secp256k1_context_destroy(sign); - secp256k1_context_destroy(vrfy); - secp256k1_context_destroy(both); - /* Defined as no-op. */ - secp256k1_context_destroy(NULL); -} - -/***** HASH TESTS *****/ - -void run_sha256_tests(void) { - static const char *inputs[8] = { - "", "abc", "message digest", "secure hash algorithm", "SHA256 is considered to be safe", - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "For this sample, this 63-byte string will be used as input data", - "This is exactly 64 bytes long, not counting the terminating byte" - }; - static const unsigned char outputs[8][32] = { - {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}, - {0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad}, - {0xf7, 0x84, 0x6f, 0x55, 0xcf, 0x23, 0xe1, 0x4e, 0xeb, 0xea, 0xb5, 0xb4, 0xe1, 0x55, 0x0c, 0xad, 0x5b, 0x50, 0x9e, 0x33, 0x48, 0xfb, 0xc4, 0xef, 0xa3, 0xa1, 0x41, 0x3d, 0x39, 0x3c, 0xb6, 0x50}, - {0xf3, 0x0c, 0xeb, 0x2b, 0xb2, 0x82, 0x9e, 0x79, 0xe4, 0xca, 0x97, 0x53, 0xd3, 0x5a, 0x8e, 0xcc, 0x00, 0x26, 0x2d, 0x16, 0x4c, 0xc0, 0x77, 0x08, 0x02, 0x95, 0x38, 0x1c, 0xbd, 0x64, 0x3f, 0x0d}, - {0x68, 0x19, 0xd9, 0x15, 0xc7, 0x3f, 0x4d, 0x1e, 0x77, 0xe4, 0xe1, 0xb5, 0x2d, 0x1f, 0xa0, 0xf9, 0xcf, 0x9b, 0xea, 0xea, 0xd3, 0x93, 0x9f, 0x15, 0x87, 0x4b, 0xd9, 0x88, 0xe2, 0xa2, 0x36, 0x30}, - {0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1}, - {0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, 0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42}, - {0xab, 0x64, 0xef, 0xf7, 0xe8, 0x8e, 0x2e, 0x46, 0x16, 0x5e, 0x29, 0xf2, 0xbc, 0xe4, 0x18, 0x26, 0xbd, 0x4c, 0x7b, 0x35, 0x52, 0xf6, 0xb3, 0x82, 0xa9, 0xe7, 0xd3, 0xaf, 0x47, 0xc2, 0x45, 0xf8} - }; - int i; - for (i = 0; i < 8; i++) { - unsigned char out[32]; - secp256k1_sha256 hasher; - secp256k1_sha256_initialize(&hasher); - secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i])); - secp256k1_sha256_finalize(&hasher, out); - CHECK(memcmp(out, outputs[i], 32) == 0); - if (strlen(inputs[i]) > 0) { - int split = secp256k1_rand_int(strlen(inputs[i])); - secp256k1_sha256_initialize(&hasher); - secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); - secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); - secp256k1_sha256_finalize(&hasher, out); - CHECK(memcmp(out, outputs[i], 32) == 0); - } - } -} - -void run_hmac_sha256_tests(void) { - static const char *keys[6] = { - "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", - "\x4a\x65\x66\x65", - "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", - "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", - "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", - "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" - }; - static const char *inputs[6] = { - "\x48\x69\x20\x54\x68\x65\x72\x65", - "\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f", - "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd", - "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd", - "\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74", - "\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e" - }; - static const unsigned char outputs[6][32] = { - {0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7}, - {0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43}, - {0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7, 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22, 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe}, - {0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e, 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a, 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07, 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b}, - {0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14, 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54}, - {0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44, 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93, 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2} - }; - int i; - for (i = 0; i < 6; i++) { - secp256k1_hmac_sha256 hasher; - unsigned char out[32]; - secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); - secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i])); - secp256k1_hmac_sha256_finalize(&hasher, out); - CHECK(memcmp(out, outputs[i], 32) == 0); - if (strlen(inputs[i]) > 0) { - int split = secp256k1_rand_int(strlen(inputs[i])); - secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); - secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); - secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); - secp256k1_hmac_sha256_finalize(&hasher, out); - CHECK(memcmp(out, outputs[i], 32) == 0); - } - } -} - -void run_rfc6979_hmac_sha256_tests(void) { - static const unsigned char key1[65] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x4b, 0xf5, 0x12, 0x2f, 0x34, 0x45, 0x54, 0xc5, 0x3b, 0xde, 0x2e, 0xbb, 0x8c, 0xd2, 0xb7, 0xe3, 0xd1, 0x60, 0x0a, 0xd6, 0x31, 0xc3, 0x85, 0xa5, 0xd7, 0xcc, 0xe2, 0x3c, 0x77, 0x85, 0x45, 0x9a, 0}; - static const unsigned char out1[3][32] = { - {0x4f, 0xe2, 0x95, 0x25, 0xb2, 0x08, 0x68, 0x09, 0x15, 0x9a, 0xcd, 0xf0, 0x50, 0x6e, 0xfb, 0x86, 0xb0, 0xec, 0x93, 0x2c, 0x7b, 0xa4, 0x42, 0x56, 0xab, 0x32, 0x1e, 0x42, 0x1e, 0x67, 0xe9, 0xfb}, - {0x2b, 0xf0, 0xff, 0xf1, 0xd3, 0xc3, 0x78, 0xa2, 0x2d, 0xc5, 0xde, 0x1d, 0x85, 0x65, 0x22, 0x32, 0x5c, 0x65, 0xb5, 0x04, 0x49, 0x1a, 0x0c, 0xbd, 0x01, 0xcb, 0x8f, 0x3a, 0xa6, 0x7f, 0xfd, 0x4a}, - {0xf5, 0x28, 0xb4, 0x10, 0xcb, 0x54, 0x1f, 0x77, 0x00, 0x0d, 0x7a, 0xfb, 0x6c, 0x5b, 0x53, 0xc5, 0xc4, 0x71, 0xea, 0xb4, 0x3e, 0x46, 0x6d, 0x9a, 0xc5, 0x19, 0x0c, 0x39, 0xc8, 0x2f, 0xd8, 0x2e} - }; - - static const unsigned char key2[64] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}; - static const unsigned char out2[3][32] = { - {0x9c, 0x23, 0x6c, 0x16, 0x5b, 0x82, 0xae, 0x0c, 0xd5, 0x90, 0x65, 0x9e, 0x10, 0x0b, 0x6b, 0xab, 0x30, 0x36, 0xe7, 0xba, 0x8b, 0x06, 0x74, 0x9b, 0xaf, 0x69, 0x81, 0xe1, 0x6f, 0x1a, 0x2b, 0x95}, - {0xdf, 0x47, 0x10, 0x61, 0x62, 0x5b, 0xc0, 0xea, 0x14, 0xb6, 0x82, 0xfe, 0xee, 0x2c, 0x9c, 0x02, 0xf2, 0x35, 0xda, 0x04, 0x20, 0x4c, 0x1d, 0x62, 0xa1, 0x53, 0x6c, 0x6e, 0x17, 0xae, 0xd7, 0xa9}, - {0x75, 0x97, 0x88, 0x7c, 0xbd, 0x76, 0x32, 0x1f, 0x32, 0xe3, 0x04, 0x40, 0x67, 0x9a, 0x22, 0xcf, 0x7f, 0x8d, 0x9d, 0x2e, 0xac, 0x39, 0x0e, 0x58, 0x1f, 0xea, 0x09, 0x1c, 0xe2, 0x02, 0xba, 0x94} - }; - - secp256k1_rfc6979_hmac_sha256 rng; - unsigned char out[32]; - int i; - - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 64); - for (i = 0; i < 3; i++) { - secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); - CHECK(memcmp(out, out1[i], 32) == 0); - } - secp256k1_rfc6979_hmac_sha256_finalize(&rng); - - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 65); - for (i = 0; i < 3; i++) { - secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); - CHECK(memcmp(out, out1[i], 32) != 0); - } - secp256k1_rfc6979_hmac_sha256_finalize(&rng); - - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key2, 64); - for (i = 0; i < 3; i++) { - secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); - CHECK(memcmp(out, out2[i], 32) == 0); - } - secp256k1_rfc6979_hmac_sha256_finalize(&rng); -} - -/***** RANDOM TESTS *****/ - -void test_rand_bits(int rand32, int bits) { - /* (1-1/2^B)^rounds[B] < 1/10^9, so rounds is the number of iterations to - * get a false negative chance below once in a billion */ - static const unsigned int rounds[7] = {1, 30, 73, 156, 322, 653, 1316}; - /* We try multiplying the results with various odd numbers, which shouldn't - * influence the uniform distribution modulo a power of 2. */ - static const uint32_t mults[6] = {1, 3, 21, 289, 0x9999, 0x80402011}; - /* We only select up to 6 bits from the output to analyse */ - unsigned int usebits = bits > 6 ? 6 : bits; - unsigned int maxshift = bits - usebits; - /* For each of the maxshift+1 usebits-bit sequences inside a bits-bit - number, track all observed outcomes, one per bit in a uint64_t. */ - uint64_t x[6][27] = {{0}}; - unsigned int i, shift, m; - /* Multiply the output of all rand calls with the odd number m, which - should not change the uniformity of its distribution. */ - for (i = 0; i < rounds[usebits]; i++) { - uint32_t r = (rand32 ? secp256k1_rand32() : secp256k1_rand_bits(bits)); - CHECK((((uint64_t)r) >> bits) == 0); - for (m = 0; m < sizeof(mults) / sizeof(mults[0]); m++) { - uint32_t rm = r * mults[m]; - for (shift = 0; shift <= maxshift; shift++) { - x[m][shift] |= (((uint64_t)1) << ((rm >> shift) & ((1 << usebits) - 1))); - } - } - } - for (m = 0; m < sizeof(mults) / sizeof(mults[0]); m++) { - for (shift = 0; shift <= maxshift; shift++) { - /* Test that the lower usebits bits of x[shift] are 1 */ - CHECK(((~x[m][shift]) << (64 - (1 << usebits))) == 0); - } - } -} - -/* Subrange must be a whole divisor of range, and at most 64 */ -void test_rand_int(uint32_t range, uint32_t subrange) { - /* (1-1/subrange)^rounds < 1/10^9 */ - int rounds = (subrange * 2073) / 100; - int i; - uint64_t x = 0; - CHECK((range % subrange) == 0); - for (i = 0; i < rounds; i++) { - uint32_t r = secp256k1_rand_int(range); - CHECK(r < range); - r = r % subrange; - x |= (((uint64_t)1) << r); - } - /* Test that the lower subrange bits of x are 1. */ - CHECK(((~x) << (64 - subrange)) == 0); -} - -void run_rand_bits(void) { - size_t b; - test_rand_bits(1, 32); - for (b = 1; b <= 32; b++) { - test_rand_bits(0, b); - } -} - -void run_rand_int(void) { - static const uint32_t ms[] = {1, 3, 17, 1000, 13771, 999999, 33554432}; - static const uint32_t ss[] = {1, 3, 6, 9, 13, 31, 64}; - unsigned int m, s; - for (m = 0; m < sizeof(ms) / sizeof(ms[0]); m++) { - for (s = 0; s < sizeof(ss) / sizeof(ss[0]); s++) { - test_rand_int(ms[m] * ss[s], ss[s]); - } - } -} - -/***** NUM TESTS *****/ - -#ifndef USE_NUM_NONE -void random_num_negate(secp256k1_num *num) { - if (secp256k1_rand_bits(1)) { - secp256k1_num_negate(num); - } -} - -void random_num_order_test(secp256k1_num *num) { - secp256k1_scalar sc; - random_scalar_order_test(&sc); - secp256k1_scalar_get_num(num, &sc); -} - -void random_num_order(secp256k1_num *num) { - secp256k1_scalar sc; - random_scalar_order(&sc); - secp256k1_scalar_get_num(num, &sc); -} - -void test_num_negate(void) { - secp256k1_num n1; - secp256k1_num n2; - random_num_order_test(&n1); /* n1 = R */ - random_num_negate(&n1); - secp256k1_num_copy(&n2, &n1); /* n2 = R */ - secp256k1_num_sub(&n1, &n2, &n1); /* n1 = n2-n1 = 0 */ - CHECK(secp256k1_num_is_zero(&n1)); - secp256k1_num_copy(&n1, &n2); /* n1 = R */ - secp256k1_num_negate(&n1); /* n1 = -R */ - CHECK(!secp256k1_num_is_zero(&n1)); - secp256k1_num_add(&n1, &n2, &n1); /* n1 = n2+n1 = 0 */ - CHECK(secp256k1_num_is_zero(&n1)); - secp256k1_num_copy(&n1, &n2); /* n1 = R */ - secp256k1_num_negate(&n1); /* n1 = -R */ - CHECK(secp256k1_num_is_neg(&n1) != secp256k1_num_is_neg(&n2)); - secp256k1_num_negate(&n1); /* n1 = R */ - CHECK(secp256k1_num_eq(&n1, &n2)); -} - -void test_num_add_sub(void) { - int i; - secp256k1_scalar s; - secp256k1_num n1; - secp256k1_num n2; - secp256k1_num n1p2, n2p1, n1m2, n2m1; - random_num_order_test(&n1); /* n1 = R1 */ - if (secp256k1_rand_bits(1)) { - random_num_negate(&n1); - } - random_num_order_test(&n2); /* n2 = R2 */ - if (secp256k1_rand_bits(1)) { - random_num_negate(&n2); - } - secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = R1 + R2 */ - secp256k1_num_add(&n2p1, &n2, &n1); /* n2p1 = R2 + R1 */ - secp256k1_num_sub(&n1m2, &n1, &n2); /* n1m2 = R1 - R2 */ - secp256k1_num_sub(&n2m1, &n2, &n1); /* n2m1 = R2 - R1 */ - CHECK(secp256k1_num_eq(&n1p2, &n2p1)); - CHECK(!secp256k1_num_eq(&n1p2, &n1m2)); - secp256k1_num_negate(&n2m1); /* n2m1 = -R2 + R1 */ - CHECK(secp256k1_num_eq(&n2m1, &n1m2)); - CHECK(!secp256k1_num_eq(&n2m1, &n1)); - secp256k1_num_add(&n2m1, &n2m1, &n2); /* n2m1 = -R2 + R1 + R2 = R1 */ - CHECK(secp256k1_num_eq(&n2m1, &n1)); - CHECK(!secp256k1_num_eq(&n2p1, &n1)); - secp256k1_num_sub(&n2p1, &n2p1, &n2); /* n2p1 = R2 + R1 - R2 = R1 */ - CHECK(secp256k1_num_eq(&n2p1, &n1)); - - /* check is_one */ - secp256k1_scalar_set_int(&s, 1); - secp256k1_scalar_get_num(&n1, &s); - CHECK(secp256k1_num_is_one(&n1)); - /* check that 2^n + 1 is never 1 */ - secp256k1_scalar_get_num(&n2, &s); - for (i = 0; i < 250; ++i) { - secp256k1_num_add(&n1, &n1, &n1); /* n1 *= 2 */ - secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = n1 + 1 */ - CHECK(!secp256k1_num_is_one(&n1p2)); - } -} - -void test_num_mod(void) { - int i; - secp256k1_scalar s; - secp256k1_num order, n; - - /* check that 0 mod anything is 0 */ - random_scalar_order_test(&s); - secp256k1_scalar_get_num(&order, &s); - secp256k1_scalar_set_int(&s, 0); - secp256k1_scalar_get_num(&n, &s); - secp256k1_num_mod(&n, &order); - CHECK(secp256k1_num_is_zero(&n)); - - /* check that anything mod 1 is 0 */ - secp256k1_scalar_set_int(&s, 1); - secp256k1_scalar_get_num(&order, &s); - secp256k1_scalar_get_num(&n, &s); - secp256k1_num_mod(&n, &order); - CHECK(secp256k1_num_is_zero(&n)); - - /* check that increasing the number past 2^256 does not break this */ - random_scalar_order_test(&s); - secp256k1_scalar_get_num(&n, &s); - /* multiply by 2^8, which'll test this case with high probability */ - for (i = 0; i < 8; ++i) { - secp256k1_num_add(&n, &n, &n); - } - secp256k1_num_mod(&n, &order); - CHECK(secp256k1_num_is_zero(&n)); -} - -void test_num_jacobi(void) { - secp256k1_scalar sqr; - secp256k1_scalar small; - secp256k1_scalar five; /* five is not a quadratic residue */ - secp256k1_num order, n; - int i; - /* squares mod 5 are 1, 4 */ - const int jacobi5[10] = { 0, 1, -1, -1, 1, 0, 1, -1, -1, 1 }; - - /* check some small values with 5 as the order */ - secp256k1_scalar_set_int(&five, 5); - secp256k1_scalar_get_num(&order, &five); - for (i = 0; i < 10; ++i) { - secp256k1_scalar_set_int(&small, i); - secp256k1_scalar_get_num(&n, &small); - CHECK(secp256k1_num_jacobi(&n, &order) == jacobi5[i]); - } - - /** test large values with 5 as group order */ - secp256k1_scalar_get_num(&order, &five); - /* we first need a scalar which is not a multiple of 5 */ - do { - secp256k1_num fiven; - random_scalar_order_test(&sqr); - secp256k1_scalar_get_num(&fiven, &five); - secp256k1_scalar_get_num(&n, &sqr); - secp256k1_num_mod(&n, &fiven); - } while (secp256k1_num_is_zero(&n)); - /* next force it to be a residue. 2 is a nonresidue mod 5 so we can - * just multiply by two, i.e. add the number to itself */ - if (secp256k1_num_jacobi(&n, &order) == -1) { - secp256k1_num_add(&n, &n, &n); - } - - /* test residue */ - CHECK(secp256k1_num_jacobi(&n, &order) == 1); - /* test nonresidue */ - secp256k1_num_add(&n, &n, &n); - CHECK(secp256k1_num_jacobi(&n, &order) == -1); - - /** test with secp group order as order */ - secp256k1_scalar_order_get_num(&order); - random_scalar_order_test(&sqr); - secp256k1_scalar_sqr(&sqr, &sqr); - /* test residue */ - secp256k1_scalar_get_num(&n, &sqr); - CHECK(secp256k1_num_jacobi(&n, &order) == 1); - /* test nonresidue */ - secp256k1_scalar_mul(&sqr, &sqr, &five); - secp256k1_scalar_get_num(&n, &sqr); - CHECK(secp256k1_num_jacobi(&n, &order) == -1); - /* test multiple of the order*/ - CHECK(secp256k1_num_jacobi(&order, &order) == 0); - - /* check one less than the order */ - secp256k1_scalar_set_int(&small, 1); - secp256k1_scalar_get_num(&n, &small); - secp256k1_num_sub(&n, &order, &n); - CHECK(secp256k1_num_jacobi(&n, &order) == 1); /* sage confirms this is 1 */ -} - -void run_num_smalltests(void) { - int i; - for (i = 0; i < 100*count; i++) { - test_num_negate(); - test_num_add_sub(); - test_num_mod(); - test_num_jacobi(); - } -} -#endif - -/***** SCALAR TESTS *****/ - -void scalar_test(void) { - secp256k1_scalar s; - secp256k1_scalar s1; - secp256k1_scalar s2; -#ifndef USE_NUM_NONE - secp256k1_num snum, s1num, s2num; - secp256k1_num order, half_order; -#endif - unsigned char c[32]; - - /* Set 's' to a random scalar, with value 'snum'. */ - random_scalar_order_test(&s); - - /* Set 's1' to a random scalar, with value 's1num'. */ - random_scalar_order_test(&s1); - - /* Set 's2' to a random scalar, with value 'snum2', and byte array representation 'c'. */ - random_scalar_order_test(&s2); - secp256k1_scalar_get_b32(c, &s2); - -#ifndef USE_NUM_NONE - secp256k1_scalar_get_num(&snum, &s); - secp256k1_scalar_get_num(&s1num, &s1); - secp256k1_scalar_get_num(&s2num, &s2); - - secp256k1_scalar_order_get_num(&order); - half_order = order; - secp256k1_num_shift(&half_order, 1); -#endif - - { - int i; - /* Test that fetching groups of 4 bits from a scalar and recursing n(i)=16*n(i-1)+p(i) reconstructs it. */ - secp256k1_scalar n; - secp256k1_scalar_set_int(&n, 0); - for (i = 0; i < 256; i += 4) { - secp256k1_scalar t; - int j; - secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits(&s, 256 - 4 - i, 4)); - for (j = 0; j < 4; j++) { - secp256k1_scalar_add(&n, &n, &n); - } - secp256k1_scalar_add(&n, &n, &t); - } - CHECK(secp256k1_scalar_eq(&n, &s)); - } - - { - /* Test that fetching groups of randomly-sized bits from a scalar and recursing n(i)=b*n(i-1)+p(i) reconstructs it. */ - secp256k1_scalar n; - int i = 0; - secp256k1_scalar_set_int(&n, 0); - while (i < 256) { - secp256k1_scalar t; - int j; - int now = secp256k1_rand_int(15) + 1; - if (now + i > 256) { - now = 256 - i; - } - secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits_var(&s, 256 - now - i, now)); - for (j = 0; j < now; j++) { - secp256k1_scalar_add(&n, &n, &n); - } - secp256k1_scalar_add(&n, &n, &t); - i += now; - } - CHECK(secp256k1_scalar_eq(&n, &s)); - } - -#ifndef USE_NUM_NONE - { - /* Test that adding the scalars together is equal to adding their numbers together modulo the order. */ - secp256k1_num rnum; - secp256k1_num r2num; - secp256k1_scalar r; - secp256k1_num_add(&rnum, &snum, &s2num); - secp256k1_num_mod(&rnum, &order); - secp256k1_scalar_add(&r, &s, &s2); - secp256k1_scalar_get_num(&r2num, &r); - CHECK(secp256k1_num_eq(&rnum, &r2num)); - } - - { - /* Test that multiplying the scalars is equal to multiplying their numbers modulo the order. */ - secp256k1_scalar r; - secp256k1_num r2num; - secp256k1_num rnum; - secp256k1_num_mul(&rnum, &snum, &s2num); - secp256k1_num_mod(&rnum, &order); - secp256k1_scalar_mul(&r, &s, &s2); - secp256k1_scalar_get_num(&r2num, &r); - CHECK(secp256k1_num_eq(&rnum, &r2num)); - /* The result can only be zero if at least one of the factors was zero. */ - CHECK(secp256k1_scalar_is_zero(&r) == (secp256k1_scalar_is_zero(&s) || secp256k1_scalar_is_zero(&s2))); - /* The results can only be equal to one of the factors if that factor was zero, or the other factor was one. */ - CHECK(secp256k1_num_eq(&rnum, &snum) == (secp256k1_scalar_is_zero(&s) || secp256k1_scalar_is_one(&s2))); - CHECK(secp256k1_num_eq(&rnum, &s2num) == (secp256k1_scalar_is_zero(&s2) || secp256k1_scalar_is_one(&s))); - } - - { - secp256k1_scalar neg; - secp256k1_num negnum; - secp256k1_num negnum2; - /* Check that comparison with zero matches comparison with zero on the number. */ - CHECK(secp256k1_num_is_zero(&snum) == secp256k1_scalar_is_zero(&s)); - /* Check that comparison with the half order is equal to testing for high scalar. */ - CHECK(secp256k1_scalar_is_high(&s) == (secp256k1_num_cmp(&snum, &half_order) > 0)); - secp256k1_scalar_negate(&neg, &s); - secp256k1_num_sub(&negnum, &order, &snum); - secp256k1_num_mod(&negnum, &order); - /* Check that comparison with the half order is equal to testing for high scalar after negation. */ - CHECK(secp256k1_scalar_is_high(&neg) == (secp256k1_num_cmp(&negnum, &half_order) > 0)); - /* Negating should change the high property, unless the value was already zero. */ - CHECK((secp256k1_scalar_is_high(&s) == secp256k1_scalar_is_high(&neg)) == secp256k1_scalar_is_zero(&s)); - secp256k1_scalar_get_num(&negnum2, &neg); - /* Negating a scalar should be equal to (order - n) mod order on the number. */ - CHECK(secp256k1_num_eq(&negnum, &negnum2)); - secp256k1_scalar_add(&neg, &neg, &s); - /* Adding a number to its negation should result in zero. */ - CHECK(secp256k1_scalar_is_zero(&neg)); - secp256k1_scalar_negate(&neg, &neg); - /* Negating zero should still result in zero. */ - CHECK(secp256k1_scalar_is_zero(&neg)); - } - - { - /* Test secp256k1_scalar_mul_shift_var. */ - secp256k1_scalar r; - secp256k1_num one; - secp256k1_num rnum; - secp256k1_num rnum2; - unsigned char cone[1] = {0x01}; - unsigned int shift = 256 + secp256k1_rand_int(257); - secp256k1_scalar_mul_shift_var(&r, &s1, &s2, shift); - secp256k1_num_mul(&rnum, &s1num, &s2num); - secp256k1_num_shift(&rnum, shift - 1); - secp256k1_num_set_bin(&one, cone, 1); - secp256k1_num_add(&rnum, &rnum, &one); - secp256k1_num_shift(&rnum, 1); - secp256k1_scalar_get_num(&rnum2, &r); - CHECK(secp256k1_num_eq(&rnum, &rnum2)); - } - - { - /* test secp256k1_scalar_shr_int */ - secp256k1_scalar r; - int i; - random_scalar_order_test(&r); - for (i = 0; i < 100; ++i) { - int low; - int shift = 1 + secp256k1_rand_int(15); - int expected = r.d[0] % (1 << shift); - low = secp256k1_scalar_shr_int(&r, shift); - CHECK(expected == low); - } - } -#endif - - { - /* Test that scalar inverses are equal to the inverse of their number modulo the order. */ - if (!secp256k1_scalar_is_zero(&s)) { - secp256k1_scalar inv; -#ifndef USE_NUM_NONE - secp256k1_num invnum; - secp256k1_num invnum2; -#endif - secp256k1_scalar_inverse(&inv, &s); -#ifndef USE_NUM_NONE - secp256k1_num_mod_inverse(&invnum, &snum, &order); - secp256k1_scalar_get_num(&invnum2, &inv); - CHECK(secp256k1_num_eq(&invnum, &invnum2)); -#endif - secp256k1_scalar_mul(&inv, &inv, &s); - /* Multiplying a scalar with its inverse must result in one. */ - CHECK(secp256k1_scalar_is_one(&inv)); - secp256k1_scalar_inverse(&inv, &inv); - /* Inverting one must result in one. */ - CHECK(secp256k1_scalar_is_one(&inv)); -#ifndef USE_NUM_NONE - secp256k1_scalar_get_num(&invnum, &inv); - CHECK(secp256k1_num_is_one(&invnum)); -#endif - } - } - - { - /* Test commutativity of add. */ - secp256k1_scalar r1, r2; - secp256k1_scalar_add(&r1, &s1, &s2); - secp256k1_scalar_add(&r2, &s2, &s1); - CHECK(secp256k1_scalar_eq(&r1, &r2)); - } - - { - secp256k1_scalar r1, r2; - secp256k1_scalar b; - int i; - /* Test add_bit. */ - int bit = secp256k1_rand_bits(8); - secp256k1_scalar_set_int(&b, 1); - CHECK(secp256k1_scalar_is_one(&b)); - for (i = 0; i < bit; i++) { - secp256k1_scalar_add(&b, &b, &b); - } - r1 = s1; - r2 = s1; - if (!secp256k1_scalar_add(&r1, &r1, &b)) { - /* No overflow happened. */ - secp256k1_scalar_cadd_bit(&r2, bit, 1); - CHECK(secp256k1_scalar_eq(&r1, &r2)); - /* cadd is a noop when flag is zero */ - secp256k1_scalar_cadd_bit(&r2, bit, 0); - CHECK(secp256k1_scalar_eq(&r1, &r2)); - } - } - - { - /* Test commutativity of mul. */ - secp256k1_scalar r1, r2; - secp256k1_scalar_mul(&r1, &s1, &s2); - secp256k1_scalar_mul(&r2, &s2, &s1); - CHECK(secp256k1_scalar_eq(&r1, &r2)); - } - - { - /* Test associativity of add. */ - secp256k1_scalar r1, r2; - secp256k1_scalar_add(&r1, &s1, &s2); - secp256k1_scalar_add(&r1, &r1, &s); - secp256k1_scalar_add(&r2, &s2, &s); - secp256k1_scalar_add(&r2, &s1, &r2); - CHECK(secp256k1_scalar_eq(&r1, &r2)); - } - - { - /* Test associativity of mul. */ - secp256k1_scalar r1, r2; - secp256k1_scalar_mul(&r1, &s1, &s2); - secp256k1_scalar_mul(&r1, &r1, &s); - secp256k1_scalar_mul(&r2, &s2, &s); - secp256k1_scalar_mul(&r2, &s1, &r2); - CHECK(secp256k1_scalar_eq(&r1, &r2)); - } - - { - /* Test distributitivity of mul over add. */ - secp256k1_scalar r1, r2, t; - secp256k1_scalar_add(&r1, &s1, &s2); - secp256k1_scalar_mul(&r1, &r1, &s); - secp256k1_scalar_mul(&r2, &s1, &s); - secp256k1_scalar_mul(&t, &s2, &s); - secp256k1_scalar_add(&r2, &r2, &t); - CHECK(secp256k1_scalar_eq(&r1, &r2)); - } - - { - /* Test square. */ - secp256k1_scalar r1, r2; - secp256k1_scalar_sqr(&r1, &s1); - secp256k1_scalar_mul(&r2, &s1, &s1); - CHECK(secp256k1_scalar_eq(&r1, &r2)); - } - - { - /* Test multiplicative identity. */ - secp256k1_scalar r1, v1; - secp256k1_scalar_set_int(&v1,1); - secp256k1_scalar_mul(&r1, &s1, &v1); - CHECK(secp256k1_scalar_eq(&r1, &s1)); - } - - { - /* Test additive identity. */ - secp256k1_scalar r1, v0; - secp256k1_scalar_set_int(&v0,0); - secp256k1_scalar_add(&r1, &s1, &v0); - CHECK(secp256k1_scalar_eq(&r1, &s1)); - } - - { - /* Test zero product property. */ - secp256k1_scalar r1, v0; - secp256k1_scalar_set_int(&v0,0); - secp256k1_scalar_mul(&r1, &s1, &v0); - CHECK(secp256k1_scalar_eq(&r1, &v0)); - } - -} - -void run_scalar_tests(void) { - int i; - for (i = 0; i < 128 * count; i++) { - scalar_test(); - } - - { - /* (-1)+1 should be zero. */ - secp256k1_scalar s, o; - secp256k1_scalar_set_int(&s, 1); - CHECK(secp256k1_scalar_is_one(&s)); - secp256k1_scalar_negate(&o, &s); - secp256k1_scalar_add(&o, &o, &s); - CHECK(secp256k1_scalar_is_zero(&o)); - secp256k1_scalar_negate(&o, &o); - CHECK(secp256k1_scalar_is_zero(&o)); - } - -#ifndef USE_NUM_NONE - { - /* A scalar with value of the curve order should be 0. */ - secp256k1_num order; - secp256k1_scalar zero; - unsigned char bin[32]; - int overflow = 0; - secp256k1_scalar_order_get_num(&order); - secp256k1_num_get_bin(bin, 32, &order); - secp256k1_scalar_set_b32(&zero, bin, &overflow); - CHECK(overflow == 1); - CHECK(secp256k1_scalar_is_zero(&zero)); - } -#endif - - { - /* Does check_overflow check catch all ones? */ - static const secp256k1_scalar overflowed = SECP256K1_SCALAR_CONST( - 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, - 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL - ); - CHECK(secp256k1_scalar_check_overflow(&overflowed)); - } - - { - /* Static test vectors. - * These were reduced from ~10^12 random vectors based on comparison-decision - * and edge-case coverage on 32-bit and 64-bit implementations. - * The responses were generated with Sage 5.9. - */ - secp256k1_scalar x; - secp256k1_scalar y; - secp256k1_scalar z; - secp256k1_scalar zz; - secp256k1_scalar one; - secp256k1_scalar r1; - secp256k1_scalar r2; -#if defined(USE_SCALAR_INV_NUM) - secp256k1_scalar zzv; -#endif - int overflow; - unsigned char chal[33][2][32] = { - {{0xff, 0xff, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, - 0xff, 0xff, 0x03, 0x00, 0xc0, 0xff, 0xff, 0xff}, - {0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff}}, - {{0xef, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, - 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x80, 0xff}}, - {{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x80, 0xff, 0x3f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x00}, - {0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x80, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xe0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff}}, - {{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x1e, 0xf8, 0xff, 0xff, 0xff, 0xfd, 0xff}, - {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, - 0x00, 0x00, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xe0, - 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, - 0xf3, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff}, - {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, - 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x1f, 0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, - 0x00, 0xfe, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff}}, - {{0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xfc, 0x9f, - 0xff, 0xff, 0xff, 0x00, 0x80, 0x00, 0x00, 0x80, - 0xff, 0x0f, 0xfc, 0xff, 0x7f, 0x00, 0x00, 0x00, - 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}, - {0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x00, 0x00, 0xf8, 0xff, 0x0f, 0xc0, 0xff, 0xff, - 0xff, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x07, 0x80, 0xff, 0xff, 0xff}}, - {{0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, - 0xf7, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0x00, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf0}, - {0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, - {{0x00, 0xf8, 0xff, 0x03, 0xff, 0xff, 0xff, 0x00, - 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x03, 0xc0, 0xff, 0x0f, 0xfc, 0xff}, - {0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, - 0xff, 0x01, 0x00, 0x00, 0x00, 0x3f, 0x00, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, - {{0x8f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x7f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}, - {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x03, 0x00, 0x80, 0x00, 0x00, 0x80, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x80, 0xff, 0x7f}, - {0xff, 0xcf, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, - 0xbf, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00}}, - {{0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, - 0xff, 0xff, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x80, 0x00, 0x00, 0x80, - 0xff, 0x01, 0xfc, 0xff, 0x01, 0x00, 0xfe, 0xff}, - {0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00}}, - {{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x7f, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf0, 0xff, 0xff, - 0xe0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x00}, - {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0xfc, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, - 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x0f, 0x7e, 0x00, 0x00}}, - {{0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x1f, 0x00, 0x00, 0xfe, 0x07, 0x00}, - {0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfb, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60}}, - {{0xff, 0x01, 0x00, 0xff, 0xff, 0xff, 0x0f, 0x00, - 0x80, 0x7f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0xff, 0xff, 0x1f, 0x00, 0xf0, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00}}, - {{0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, - 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff}}, - {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0xff, 0xff, 0xcf, 0xff, 0x1f, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x7e, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00}, - {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0xff, 0xff, 0x7f, 0x00, 0x80, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff}}, - {{0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x80, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}, - {0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x80, - 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0x7f, 0xf8, 0xff, 0xff, 0x1f, 0x00, 0xfe}}, - {{0xff, 0xff, 0xff, 0x3f, 0xf8, 0xff, 0xff, 0xff, - 0xff, 0x03, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x00, - 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07}, - {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0xff, 0xff, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}}, - {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, - 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40}}, - {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, - {{0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xc0, - 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}, - {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, - 0xf0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff}}, - {{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}}, - {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, - 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}, - {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x7e, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x07, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0xff, 0x01, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x80, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, - {{0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x00, - 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, - 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, - 0xff, 0xff, 0x3f, 0x00, 0xf8, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x3f, 0x00, 0x00, 0xc0, 0xf1, 0x7f, 0x00}}, - {{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x00}, - {0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, - 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, - 0x00, 0x00, 0xfc, 0xff, 0xff, 0x01, 0xff, 0xff}}, - {{0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x80, 0x00, 0x00, 0x80, 0xff, 0x03, 0xe0, 0x01, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xfc, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}, - {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0xff, 0xff, 0xf0, 0x07, 0x00, 0x3c, 0x80, - 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x07, 0xe0, 0xff, 0x00, 0x00, 0x00}}, - {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf8, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80}, - {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x80, 0x00, - 0x00, 0x00, 0x00, 0xc0, 0x7f, 0xfe, 0xff, 0x1f, - 0x00, 0xfe, 0xff, 0x03, 0x00, 0x00, 0xfe, 0xff}}, - {{0xff, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, - 0xff, 0xff, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, - 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xf0}, - {0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, - 0xf8, 0x07, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xc7, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff}}, - {{0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, - 0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0x03, 0xfb, - 0xfa, 0x8a, 0x7d, 0xdf, 0x13, 0x86, 0xe2, 0x03}, - {0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, - 0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0x03, 0xfb, - 0xfa, 0x8a, 0x7d, 0xdf, 0x13, 0x86, 0xe2, 0x03}} - }; - unsigned char res[33][2][32] = { - {{0x0c, 0x3b, 0x0a, 0xca, 0x8d, 0x1a, 0x2f, 0xb9, - 0x8a, 0x7b, 0x53, 0x5a, 0x1f, 0xc5, 0x22, 0xa1, - 0x07, 0x2a, 0x48, 0xea, 0x02, 0xeb, 0xb3, 0xd6, - 0x20, 0x1e, 0x86, 0xd0, 0x95, 0xf6, 0x92, 0x35}, - {0xdc, 0x90, 0x7a, 0x07, 0x2e, 0x1e, 0x44, 0x6d, - 0xf8, 0x15, 0x24, 0x5b, 0x5a, 0x96, 0x37, 0x9c, - 0x37, 0x7b, 0x0d, 0xac, 0x1b, 0x65, 0x58, 0x49, - 0x43, 0xb7, 0x31, 0xbb, 0xa7, 0xf4, 0x97, 0x15}}, - {{0xf1, 0xf7, 0x3a, 0x50, 0xe6, 0x10, 0xba, 0x22, - 0x43, 0x4d, 0x1f, 0x1f, 0x7c, 0x27, 0xca, 0x9c, - 0xb8, 0xb6, 0xa0, 0xfc, 0xd8, 0xc0, 0x05, 0x2f, - 0xf7, 0x08, 0xe1, 0x76, 0xdd, 0xd0, 0x80, 0xc8}, - {0xe3, 0x80, 0x80, 0xb8, 0xdb, 0xe3, 0xa9, 0x77, - 0x00, 0xb0, 0xf5, 0x2e, 0x27, 0xe2, 0x68, 0xc4, - 0x88, 0xe8, 0x04, 0xc1, 0x12, 0xbf, 0x78, 0x59, - 0xe6, 0xa9, 0x7c, 0xe1, 0x81, 0xdd, 0xb9, 0xd5}}, - {{0x96, 0xe2, 0xee, 0x01, 0xa6, 0x80, 0x31, 0xef, - 0x5c, 0xd0, 0x19, 0xb4, 0x7d, 0x5f, 0x79, 0xab, - 0xa1, 0x97, 0xd3, 0x7e, 0x33, 0xbb, 0x86, 0x55, - 0x60, 0x20, 0x10, 0x0d, 0x94, 0x2d, 0x11, 0x7c}, - {0xcc, 0xab, 0xe0, 0xe8, 0x98, 0x65, 0x12, 0x96, - 0x38, 0x5a, 0x1a, 0xf2, 0x85, 0x23, 0x59, 0x5f, - 0xf9, 0xf3, 0xc2, 0x81, 0x70, 0x92, 0x65, 0x12, - 0x9c, 0x65, 0x1e, 0x96, 0x00, 0xef, 0xe7, 0x63}}, - {{0xac, 0x1e, 0x62, 0xc2, 0x59, 0xfc, 0x4e, 0x5c, - 0x83, 0xb0, 0xd0, 0x6f, 0xce, 0x19, 0xf6, 0xbf, - 0xa4, 0xb0, 0xe0, 0x53, 0x66, 0x1f, 0xbf, 0xc9, - 0x33, 0x47, 0x37, 0xa9, 0x3d, 0x5d, 0xb0, 0x48}, - {0x86, 0xb9, 0x2a, 0x7f, 0x8e, 0xa8, 0x60, 0x42, - 0x26, 0x6d, 0x6e, 0x1c, 0xa2, 0xec, 0xe0, 0xe5, - 0x3e, 0x0a, 0x33, 0xbb, 0x61, 0x4c, 0x9f, 0x3c, - 0xd1, 0xdf, 0x49, 0x33, 0xcd, 0x72, 0x78, 0x18}}, - {{0xf7, 0xd3, 0xcd, 0x49, 0x5c, 0x13, 0x22, 0xfb, - 0x2e, 0xb2, 0x2f, 0x27, 0xf5, 0x8a, 0x5d, 0x74, - 0xc1, 0x58, 0xc5, 0xc2, 0x2d, 0x9f, 0x52, 0xc6, - 0x63, 0x9f, 0xba, 0x05, 0x76, 0x45, 0x7a, 0x63}, - {0x8a, 0xfa, 0x55, 0x4d, 0xdd, 0xa3, 0xb2, 0xc3, - 0x44, 0xfd, 0xec, 0x72, 0xde, 0xef, 0xc0, 0x99, - 0xf5, 0x9f, 0xe2, 0x52, 0xb4, 0x05, 0x32, 0x58, - 0x57, 0xc1, 0x8f, 0xea, 0xc3, 0x24, 0x5b, 0x94}}, - {{0x05, 0x83, 0xee, 0xdd, 0x64, 0xf0, 0x14, 0x3b, - 0xa0, 0x14, 0x4a, 0x3a, 0x41, 0x82, 0x7c, 0xa7, - 0x2c, 0xaa, 0xb1, 0x76, 0xbb, 0x59, 0x64, 0x5f, - 0x52, 0xad, 0x25, 0x29, 0x9d, 0x8f, 0x0b, 0xb0}, - {0x7e, 0xe3, 0x7c, 0xca, 0xcd, 0x4f, 0xb0, 0x6d, - 0x7a, 0xb2, 0x3e, 0xa0, 0x08, 0xb9, 0xa8, 0x2d, - 0xc2, 0xf4, 0x99, 0x66, 0xcc, 0xac, 0xd8, 0xb9, - 0x72, 0x2a, 0x4a, 0x3e, 0x0f, 0x7b, 0xbf, 0xf4}}, - {{0x8c, 0x9c, 0x78, 0x2b, 0x39, 0x61, 0x7e, 0xf7, - 0x65, 0x37, 0x66, 0x09, 0x38, 0xb9, 0x6f, 0x70, - 0x78, 0x87, 0xff, 0xcf, 0x93, 0xca, 0x85, 0x06, - 0x44, 0x84, 0xa7, 0xfe, 0xd3, 0xa4, 0xe3, 0x7e}, - {0xa2, 0x56, 0x49, 0x23, 0x54, 0xa5, 0x50, 0xe9, - 0x5f, 0xf0, 0x4d, 0xe7, 0xdc, 0x38, 0x32, 0x79, - 0x4f, 0x1c, 0xb7, 0xe4, 0xbb, 0xf8, 0xbb, 0x2e, - 0x40, 0x41, 0x4b, 0xcc, 0xe3, 0x1e, 0x16, 0x36}}, - {{0x0c, 0x1e, 0xd7, 0x09, 0x25, 0x40, 0x97, 0xcb, - 0x5c, 0x46, 0xa8, 0xda, 0xef, 0x25, 0xd5, 0xe5, - 0x92, 0x4d, 0xcf, 0xa3, 0xc4, 0x5d, 0x35, 0x4a, - 0xe4, 0x61, 0x92, 0xf3, 0xbf, 0x0e, 0xcd, 0xbe}, - {0xe4, 0xaf, 0x0a, 0xb3, 0x30, 0x8b, 0x9b, 0x48, - 0x49, 0x43, 0xc7, 0x64, 0x60, 0x4a, 0x2b, 0x9e, - 0x95, 0x5f, 0x56, 0xe8, 0x35, 0xdc, 0xeb, 0xdc, - 0xc7, 0xc4, 0xfe, 0x30, 0x40, 0xc7, 0xbf, 0xa4}}, - {{0xd4, 0xa0, 0xf5, 0x81, 0x49, 0x6b, 0xb6, 0x8b, - 0x0a, 0x69, 0xf9, 0xfe, 0xa8, 0x32, 0xe5, 0xe0, - 0xa5, 0xcd, 0x02, 0x53, 0xf9, 0x2c, 0xe3, 0x53, - 0x83, 0x36, 0xc6, 0x02, 0xb5, 0xeb, 0x64, 0xb8}, - {0x1d, 0x42, 0xb9, 0xf9, 0xe9, 0xe3, 0x93, 0x2c, - 0x4c, 0xee, 0x6c, 0x5a, 0x47, 0x9e, 0x62, 0x01, - 0x6b, 0x04, 0xfe, 0xa4, 0x30, 0x2b, 0x0d, 0x4f, - 0x71, 0x10, 0xd3, 0x55, 0xca, 0xf3, 0x5e, 0x80}}, - {{0x77, 0x05, 0xf6, 0x0c, 0x15, 0x9b, 0x45, 0xe7, - 0xb9, 0x11, 0xb8, 0xf5, 0xd6, 0xda, 0x73, 0x0c, - 0xda, 0x92, 0xea, 0xd0, 0x9d, 0xd0, 0x18, 0x92, - 0xce, 0x9a, 0xaa, 0xee, 0x0f, 0xef, 0xde, 0x30}, - {0xf1, 0xf1, 0xd6, 0x9b, 0x51, 0xd7, 0x77, 0x62, - 0x52, 0x10, 0xb8, 0x7a, 0x84, 0x9d, 0x15, 0x4e, - 0x07, 0xdc, 0x1e, 0x75, 0x0d, 0x0c, 0x3b, 0xdb, - 0x74, 0x58, 0x62, 0x02, 0x90, 0x54, 0x8b, 0x43}}, - {{0xa6, 0xfe, 0x0b, 0x87, 0x80, 0x43, 0x67, 0x25, - 0x57, 0x5d, 0xec, 0x40, 0x50, 0x08, 0xd5, 0x5d, - 0x43, 0xd7, 0xe0, 0xaa, 0xe0, 0x13, 0xb6, 0xb0, - 0xc0, 0xd4, 0xe5, 0x0d, 0x45, 0x83, 0xd6, 0x13}, - {0x40, 0x45, 0x0a, 0x92, 0x31, 0xea, 0x8c, 0x60, - 0x8c, 0x1f, 0xd8, 0x76, 0x45, 0xb9, 0x29, 0x00, - 0x26, 0x32, 0xd8, 0xa6, 0x96, 0x88, 0xe2, 0xc4, - 0x8b, 0xdb, 0x7f, 0x17, 0x87, 0xcc, 0xc8, 0xf2}}, - {{0xc2, 0x56, 0xe2, 0xb6, 0x1a, 0x81, 0xe7, 0x31, - 0x63, 0x2e, 0xbb, 0x0d, 0x2f, 0x81, 0x67, 0xd4, - 0x22, 0xe2, 0x38, 0x02, 0x25, 0x97, 0xc7, 0x88, - 0x6e, 0xdf, 0xbe, 0x2a, 0xa5, 0x73, 0x63, 0xaa}, - {0x50, 0x45, 0xe2, 0xc3, 0xbd, 0x89, 0xfc, 0x57, - 0xbd, 0x3c, 0xa3, 0x98, 0x7e, 0x7f, 0x36, 0x38, - 0x92, 0x39, 0x1f, 0x0f, 0x81, 0x1a, 0x06, 0x51, - 0x1f, 0x8d, 0x6a, 0xff, 0x47, 0x16, 0x06, 0x9c}}, - {{0x33, 0x95, 0xa2, 0x6f, 0x27, 0x5f, 0x9c, 0x9c, - 0x64, 0x45, 0xcb, 0xd1, 0x3c, 0xee, 0x5e, 0x5f, - 0x48, 0xa6, 0xaf, 0xe3, 0x79, 0xcf, 0xb1, 0xe2, - 0xbf, 0x55, 0x0e, 0xa2, 0x3b, 0x62, 0xf0, 0xe4}, - {0x14, 0xe8, 0x06, 0xe3, 0xbe, 0x7e, 0x67, 0x01, - 0xc5, 0x21, 0x67, 0xd8, 0x54, 0xb5, 0x7f, 0xa4, - 0xf9, 0x75, 0x70, 0x1c, 0xfd, 0x79, 0xdb, 0x86, - 0xad, 0x37, 0x85, 0x83, 0x56, 0x4e, 0xf0, 0xbf}}, - {{0xbc, 0xa6, 0xe0, 0x56, 0x4e, 0xef, 0xfa, 0xf5, - 0x1d, 0x5d, 0x3f, 0x2a, 0x5b, 0x19, 0xab, 0x51, - 0xc5, 0x8b, 0xdd, 0x98, 0x28, 0x35, 0x2f, 0xc3, - 0x81, 0x4f, 0x5c, 0xe5, 0x70, 0xb9, 0xeb, 0x62}, - {0xc4, 0x6d, 0x26, 0xb0, 0x17, 0x6b, 0xfe, 0x6c, - 0x12, 0xf8, 0xe7, 0xc1, 0xf5, 0x2f, 0xfa, 0x91, - 0x13, 0x27, 0xbd, 0x73, 0xcc, 0x33, 0x31, 0x1c, - 0x39, 0xe3, 0x27, 0x6a, 0x95, 0xcf, 0xc5, 0xfb}}, - {{0x30, 0xb2, 0x99, 0x84, 0xf0, 0x18, 0x2a, 0x6e, - 0x1e, 0x27, 0xed, 0xa2, 0x29, 0x99, 0x41, 0x56, - 0xe8, 0xd4, 0x0d, 0xef, 0x99, 0x9c, 0xf3, 0x58, - 0x29, 0x55, 0x1a, 0xc0, 0x68, 0xd6, 0x74, 0xa4}, - {0x07, 0x9c, 0xe7, 0xec, 0xf5, 0x36, 0x73, 0x41, - 0xa3, 0x1c, 0xe5, 0x93, 0x97, 0x6a, 0xfd, 0xf7, - 0x53, 0x18, 0xab, 0xaf, 0xeb, 0x85, 0xbd, 0x92, - 0x90, 0xab, 0x3c, 0xbf, 0x30, 0x82, 0xad, 0xf6}}, - {{0xc6, 0x87, 0x8a, 0x2a, 0xea, 0xc0, 0xa9, 0xec, - 0x6d, 0xd3, 0xdc, 0x32, 0x23, 0xce, 0x62, 0x19, - 0xa4, 0x7e, 0xa8, 0xdd, 0x1c, 0x33, 0xae, 0xd3, - 0x4f, 0x62, 0x9f, 0x52, 0xe7, 0x65, 0x46, 0xf4}, - {0x97, 0x51, 0x27, 0x67, 0x2d, 0xa2, 0x82, 0x87, - 0x98, 0xd3, 0xb6, 0x14, 0x7f, 0x51, 0xd3, 0x9a, - 0x0b, 0xd0, 0x76, 0x81, 0xb2, 0x4f, 0x58, 0x92, - 0xa4, 0x86, 0xa1, 0xa7, 0x09, 0x1d, 0xef, 0x9b}}, - {{0xb3, 0x0f, 0x2b, 0x69, 0x0d, 0x06, 0x90, 0x64, - 0xbd, 0x43, 0x4c, 0x10, 0xe8, 0x98, 0x1c, 0xa3, - 0xe1, 0x68, 0xe9, 0x79, 0x6c, 0x29, 0x51, 0x3f, - 0x41, 0xdc, 0xdf, 0x1f, 0xf3, 0x60, 0xbe, 0x33}, - {0xa1, 0x5f, 0xf7, 0x1d, 0xb4, 0x3e, 0x9b, 0x3c, - 0xe7, 0xbd, 0xb6, 0x06, 0xd5, 0x60, 0x06, 0x6d, - 0x50, 0xd2, 0xf4, 0x1a, 0x31, 0x08, 0xf2, 0xea, - 0x8e, 0xef, 0x5f, 0x7d, 0xb6, 0xd0, 0xc0, 0x27}}, - {{0x62, 0x9a, 0xd9, 0xbb, 0x38, 0x36, 0xce, 0xf7, - 0x5d, 0x2f, 0x13, 0xec, 0xc8, 0x2d, 0x02, 0x8a, - 0x2e, 0x72, 0xf0, 0xe5, 0x15, 0x9d, 0x72, 0xae, - 0xfc, 0xb3, 0x4f, 0x02, 0xea, 0xe1, 0x09, 0xfe}, - {0x00, 0x00, 0x00, 0x00, 0xfa, 0x0a, 0x3d, 0xbc, - 0xad, 0x16, 0x0c, 0xb6, 0xe7, 0x7c, 0x8b, 0x39, - 0x9a, 0x43, 0xbb, 0xe3, 0xc2, 0x55, 0x15, 0x14, - 0x75, 0xac, 0x90, 0x9b, 0x7f, 0x9a, 0x92, 0x00}}, - {{0x8b, 0xac, 0x70, 0x86, 0x29, 0x8f, 0x00, 0x23, - 0x7b, 0x45, 0x30, 0xaa, 0xb8, 0x4c, 0xc7, 0x8d, - 0x4e, 0x47, 0x85, 0xc6, 0x19, 0xe3, 0x96, 0xc2, - 0x9a, 0xa0, 0x12, 0xed, 0x6f, 0xd7, 0x76, 0x16}, - {0x45, 0xaf, 0x7e, 0x33, 0xc7, 0x7f, 0x10, 0x6c, - 0x7c, 0x9f, 0x29, 0xc1, 0xa8, 0x7e, 0x15, 0x84, - 0xe7, 0x7d, 0xc0, 0x6d, 0xab, 0x71, 0x5d, 0xd0, - 0x6b, 0x9f, 0x97, 0xab, 0xcb, 0x51, 0x0c, 0x9f}}, - {{0x9e, 0xc3, 0x92, 0xb4, 0x04, 0x9f, 0xc8, 0xbb, - 0xdd, 0x9e, 0xc6, 0x05, 0xfd, 0x65, 0xec, 0x94, - 0x7f, 0x2c, 0x16, 0xc4, 0x40, 0xac, 0x63, 0x7b, - 0x7d, 0xb8, 0x0c, 0xe4, 0x5b, 0xe3, 0xa7, 0x0e}, - {0x43, 0xf4, 0x44, 0xe8, 0xcc, 0xc8, 0xd4, 0x54, - 0x33, 0x37, 0x50, 0xf2, 0x87, 0x42, 0x2e, 0x00, - 0x49, 0x60, 0x62, 0x02, 0xfd, 0x1a, 0x7c, 0xdb, - 0x29, 0x6c, 0x6d, 0x54, 0x53, 0x08, 0xd1, 0xc8}}, - {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, - {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}, - {{0x27, 0x59, 0xc7, 0x35, 0x60, 0x71, 0xa6, 0xf1, - 0x79, 0xa5, 0xfd, 0x79, 0x16, 0xf3, 0x41, 0xf0, - 0x57, 0xb4, 0x02, 0x97, 0x32, 0xe7, 0xde, 0x59, - 0xe2, 0x2d, 0x9b, 0x11, 0xea, 0x2c, 0x35, 0x92}, - {0x27, 0x59, 0xc7, 0x35, 0x60, 0x71, 0xa6, 0xf1, - 0x79, 0xa5, 0xfd, 0x79, 0x16, 0xf3, 0x41, 0xf0, - 0x57, 0xb4, 0x02, 0x97, 0x32, 0xe7, 0xde, 0x59, - 0xe2, 0x2d, 0x9b, 0x11, 0xea, 0x2c, 0x35, 0x92}}, - {{0x28, 0x56, 0xac, 0x0e, 0x4f, 0x98, 0x09, 0xf0, - 0x49, 0xfa, 0x7f, 0x84, 0xac, 0x7e, 0x50, 0x5b, - 0x17, 0x43, 0x14, 0x89, 0x9c, 0x53, 0xa8, 0x94, - 0x30, 0xf2, 0x11, 0x4d, 0x92, 0x14, 0x27, 0xe8}, - {0x39, 0x7a, 0x84, 0x56, 0x79, 0x9d, 0xec, 0x26, - 0x2c, 0x53, 0xc1, 0x94, 0xc9, 0x8d, 0x9e, 0x9d, - 0x32, 0x1f, 0xdd, 0x84, 0x04, 0xe8, 0xe2, 0x0a, - 0x6b, 0xbe, 0xbb, 0x42, 0x40, 0x67, 0x30, 0x6c}}, - {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x45, 0x51, 0x23, 0x19, 0x50, 0xb7, 0x5f, 0xc4, - 0x40, 0x2d, 0xa1, 0x73, 0x2f, 0xc9, 0xbe, 0xbd}, - {0x27, 0x59, 0xc7, 0x35, 0x60, 0x71, 0xa6, 0xf1, - 0x79, 0xa5, 0xfd, 0x79, 0x16, 0xf3, 0x41, 0xf0, - 0x57, 0xb4, 0x02, 0x97, 0x32, 0xe7, 0xde, 0x59, - 0xe2, 0x2d, 0x9b, 0x11, 0xea, 0x2c, 0x35, 0x92}}, - {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, - 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}, - {{0x1c, 0xc4, 0xf7, 0xda, 0x0f, 0x65, 0xca, 0x39, - 0x70, 0x52, 0x92, 0x8e, 0xc3, 0xc8, 0x15, 0xea, - 0x7f, 0x10, 0x9e, 0x77, 0x4b, 0x6e, 0x2d, 0xdf, - 0xe8, 0x30, 0x9d, 0xda, 0xe8, 0x9a, 0x65, 0xae}, - {0x02, 0xb0, 0x16, 0xb1, 0x1d, 0xc8, 0x57, 0x7b, - 0xa2, 0x3a, 0xa2, 0xa3, 0x38, 0x5c, 0x8f, 0xeb, - 0x66, 0x37, 0x91, 0xa8, 0x5f, 0xef, 0x04, 0xf6, - 0x59, 0x75, 0xe1, 0xee, 0x92, 0xf6, 0x0e, 0x30}}, - {{0x8d, 0x76, 0x14, 0xa4, 0x14, 0x06, 0x9f, 0x9a, - 0xdf, 0x4a, 0x85, 0xa7, 0x6b, 0xbf, 0x29, 0x6f, - 0xbc, 0x34, 0x87, 0x5d, 0xeb, 0xbb, 0x2e, 0xa9, - 0xc9, 0x1f, 0x58, 0xd6, 0x9a, 0x82, 0xa0, 0x56}, - {0xd4, 0xb9, 0xdb, 0x88, 0x1d, 0x04, 0xe9, 0x93, - 0x8d, 0x3f, 0x20, 0xd5, 0x86, 0xa8, 0x83, 0x07, - 0xdb, 0x09, 0xd8, 0x22, 0x1f, 0x7f, 0xf1, 0x71, - 0xc8, 0xe7, 0x5d, 0x47, 0xaf, 0x8b, 0x72, 0xe9}}, - {{0x83, 0xb9, 0x39, 0xb2, 0xa4, 0xdf, 0x46, 0x87, - 0xc2, 0xb8, 0xf1, 0xe6, 0x4c, 0xd1, 0xe2, 0xa9, - 0xe4, 0x70, 0x30, 0x34, 0xbc, 0x52, 0x7c, 0x55, - 0xa6, 0xec, 0x80, 0xa4, 0xe5, 0xd2, 0xdc, 0x73}, - {0x08, 0xf1, 0x03, 0xcf, 0x16, 0x73, 0xe8, 0x7d, - 0xb6, 0x7e, 0x9b, 0xc0, 0xb4, 0xc2, 0xa5, 0x86, - 0x02, 0x77, 0xd5, 0x27, 0x86, 0xa5, 0x15, 0xfb, - 0xae, 0x9b, 0x8c, 0xa9, 0xf9, 0xf8, 0xa8, 0x4a}}, - {{0x8b, 0x00, 0x49, 0xdb, 0xfa, 0xf0, 0x1b, 0xa2, - 0xed, 0x8a, 0x9a, 0x7a, 0x36, 0x78, 0x4a, 0xc7, - 0xf7, 0xad, 0x39, 0xd0, 0x6c, 0x65, 0x7a, 0x41, - 0xce, 0xd6, 0xd6, 0x4c, 0x20, 0x21, 0x6b, 0xc7}, - {0xc6, 0xca, 0x78, 0x1d, 0x32, 0x6c, 0x6c, 0x06, - 0x91, 0xf2, 0x1a, 0xe8, 0x43, 0x16, 0xea, 0x04, - 0x3c, 0x1f, 0x07, 0x85, 0xf7, 0x09, 0x22, 0x08, - 0xba, 0x13, 0xfd, 0x78, 0x1e, 0x3f, 0x6f, 0x62}}, - {{0x25, 0x9b, 0x7c, 0xb0, 0xac, 0x72, 0x6f, 0xb2, - 0xe3, 0x53, 0x84, 0x7a, 0x1a, 0x9a, 0x98, 0x9b, - 0x44, 0xd3, 0x59, 0xd0, 0x8e, 0x57, 0x41, 0x40, - 0x78, 0xa7, 0x30, 0x2f, 0x4c, 0x9c, 0xb9, 0x68}, - {0xb7, 0x75, 0x03, 0x63, 0x61, 0xc2, 0x48, 0x6e, - 0x12, 0x3d, 0xbf, 0x4b, 0x27, 0xdf, 0xb1, 0x7a, - 0xff, 0x4e, 0x31, 0x07, 0x83, 0xf4, 0x62, 0x5b, - 0x19, 0xa5, 0xac, 0xa0, 0x32, 0x58, 0x0d, 0xa7}}, - {{0x43, 0x4f, 0x10, 0xa4, 0xca, 0xdb, 0x38, 0x67, - 0xfa, 0xae, 0x96, 0xb5, 0x6d, 0x97, 0xff, 0x1f, - 0xb6, 0x83, 0x43, 0xd3, 0xa0, 0x2d, 0x70, 0x7a, - 0x64, 0x05, 0x4c, 0xa7, 0xc1, 0xa5, 0x21, 0x51}, - {0xe4, 0xf1, 0x23, 0x84, 0xe1, 0xb5, 0x9d, 0xf2, - 0xb8, 0x73, 0x8b, 0x45, 0x2b, 0x35, 0x46, 0x38, - 0x10, 0x2b, 0x50, 0xf8, 0x8b, 0x35, 0xcd, 0x34, - 0xc8, 0x0e, 0xf6, 0xdb, 0x09, 0x35, 0xf0, 0xda}}, - {{0xdb, 0x21, 0x5c, 0x8d, 0x83, 0x1d, 0xb3, 0x34, - 0xc7, 0x0e, 0x43, 0xa1, 0x58, 0x79, 0x67, 0x13, - 0x1e, 0x86, 0x5d, 0x89, 0x63, 0xe6, 0x0a, 0x46, - 0x5c, 0x02, 0x97, 0x1b, 0x62, 0x43, 0x86, 0xf5}, - {0xdb, 0x21, 0x5c, 0x8d, 0x83, 0x1d, 0xb3, 0x34, - 0xc7, 0x0e, 0x43, 0xa1, 0x58, 0x79, 0x67, 0x13, - 0x1e, 0x86, 0x5d, 0x89, 0x63, 0xe6, 0x0a, 0x46, - 0x5c, 0x02, 0x97, 0x1b, 0x62, 0x43, 0x86, 0xf5}} - }; - secp256k1_scalar_set_int(&one, 1); - for (i = 0; i < 33; i++) { - secp256k1_scalar_set_b32(&x, chal[i][0], &overflow); - CHECK(!overflow); - secp256k1_scalar_set_b32(&y, chal[i][1], &overflow); - CHECK(!overflow); - secp256k1_scalar_set_b32(&r1, res[i][0], &overflow); - CHECK(!overflow); - secp256k1_scalar_set_b32(&r2, res[i][1], &overflow); - CHECK(!overflow); - secp256k1_scalar_mul(&z, &x, &y); - CHECK(!secp256k1_scalar_check_overflow(&z)); - CHECK(secp256k1_scalar_eq(&r1, &z)); - if (!secp256k1_scalar_is_zero(&y)) { - secp256k1_scalar_inverse(&zz, &y); - CHECK(!secp256k1_scalar_check_overflow(&zz)); -#if defined(USE_SCALAR_INV_NUM) - secp256k1_scalar_inverse_var(&zzv, &y); - CHECK(secp256k1_scalar_eq(&zzv, &zz)); -#endif - secp256k1_scalar_mul(&z, &z, &zz); - CHECK(!secp256k1_scalar_check_overflow(&z)); - CHECK(secp256k1_scalar_eq(&x, &z)); - secp256k1_scalar_mul(&zz, &zz, &y); - CHECK(!secp256k1_scalar_check_overflow(&zz)); - CHECK(secp256k1_scalar_eq(&one, &zz)); - } - secp256k1_scalar_mul(&z, &x, &x); - CHECK(!secp256k1_scalar_check_overflow(&z)); - secp256k1_scalar_sqr(&zz, &x); - CHECK(!secp256k1_scalar_check_overflow(&zz)); - CHECK(secp256k1_scalar_eq(&zz, &z)); - CHECK(secp256k1_scalar_eq(&r2, &zz)); - } - } -} - -/***** FIELD TESTS *****/ - -void random_fe(secp256k1_fe *x) { - unsigned char bin[32]; - do { - secp256k1_rand256(bin); - if (secp256k1_fe_set_b32(x, bin)) { - return; - } - } while(1); -} - -void random_fe_test(secp256k1_fe *x) { - unsigned char bin[32]; - do { - secp256k1_rand256_test(bin); - if (secp256k1_fe_set_b32(x, bin)) { - return; - } - } while(1); -} - -void random_fe_non_zero(secp256k1_fe *nz) { - int tries = 10; - while (--tries >= 0) { - random_fe(nz); - secp256k1_fe_normalize(nz); - if (!secp256k1_fe_is_zero(nz)) { - break; - } - } - /* Infinitesimal probability of spurious failure here */ - CHECK(tries >= 0); -} - -void random_fe_non_square(secp256k1_fe *ns) { - secp256k1_fe r; - random_fe_non_zero(ns); - if (secp256k1_fe_sqrt(&r, ns)) { - secp256k1_fe_negate(ns, ns, 1); - } -} - -int check_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) { - secp256k1_fe an = *a; - secp256k1_fe bn = *b; - secp256k1_fe_normalize_weak(&an); - secp256k1_fe_normalize_var(&bn); - return secp256k1_fe_equal_var(&an, &bn); -} - -int check_fe_inverse(const secp256k1_fe *a, const secp256k1_fe *ai) { - secp256k1_fe x; - secp256k1_fe one = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); - secp256k1_fe_mul(&x, a, ai); - return check_fe_equal(&x, &one); -} - -void run_field_convert(void) { - static const unsigned char b32[32] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, - 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40 - }; - static const secp256k1_fe_storage fes = SECP256K1_FE_STORAGE_CONST( - 0x00010203UL, 0x04050607UL, 0x11121314UL, 0x15161718UL, - 0x22232425UL, 0x26272829UL, 0x33343536UL, 0x37383940UL - ); - static const secp256k1_fe fe = SECP256K1_FE_CONST( - 0x00010203UL, 0x04050607UL, 0x11121314UL, 0x15161718UL, - 0x22232425UL, 0x26272829UL, 0x33343536UL, 0x37383940UL - ); - secp256k1_fe fe2; - unsigned char b322[32]; - secp256k1_fe_storage fes2; - /* Check conversions to fe. */ - CHECK(secp256k1_fe_set_b32(&fe2, b32)); - CHECK(secp256k1_fe_equal_var(&fe, &fe2)); - secp256k1_fe_from_storage(&fe2, &fes); - CHECK(secp256k1_fe_equal_var(&fe, &fe2)); - /* Check conversion from fe. */ - secp256k1_fe_get_b32(b322, &fe); - CHECK(memcmp(b322, b32, 32) == 0); - secp256k1_fe_to_storage(&fes2, &fe); - CHECK(memcmp(&fes2, &fes, sizeof(fes)) == 0); -} - -int fe_memcmp(const secp256k1_fe *a, const secp256k1_fe *b) { - secp256k1_fe t = *b; -#ifdef VERIFY - t.magnitude = a->magnitude; - t.normalized = a->normalized; -#endif - return memcmp(a, &t, sizeof(secp256k1_fe)); -} - -void run_field_misc(void) { - secp256k1_fe x; - secp256k1_fe y; - secp256k1_fe z; - secp256k1_fe q; - secp256k1_fe fe5 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 5); - int i, j; - for (i = 0; i < 5*count; i++) { - secp256k1_fe_storage xs, ys, zs; - random_fe(&x); - random_fe_non_zero(&y); - /* Test the fe equality and comparison operations. */ - CHECK(secp256k1_fe_cmp_var(&x, &x) == 0); - CHECK(secp256k1_fe_equal_var(&x, &x)); - z = x; - secp256k1_fe_add(&z,&y); - /* Test fe conditional move; z is not normalized here. */ - q = x; - secp256k1_fe_cmov(&x, &z, 0); - VERIFY_CHECK(!x.normalized && x.magnitude == z.magnitude); - secp256k1_fe_cmov(&x, &x, 1); - CHECK(fe_memcmp(&x, &z) != 0); - CHECK(fe_memcmp(&x, &q) == 0); - secp256k1_fe_cmov(&q, &z, 1); - VERIFY_CHECK(!q.normalized && q.magnitude == z.magnitude); - CHECK(fe_memcmp(&q, &z) == 0); - secp256k1_fe_normalize_var(&x); - secp256k1_fe_normalize_var(&z); - CHECK(!secp256k1_fe_equal_var(&x, &z)); - secp256k1_fe_normalize_var(&q); - secp256k1_fe_cmov(&q, &z, (i&1)); - VERIFY_CHECK(q.normalized && q.magnitude == 1); - for (j = 0; j < 6; j++) { - secp256k1_fe_negate(&z, &z, j+1); - secp256k1_fe_normalize_var(&q); - secp256k1_fe_cmov(&q, &z, (j&1)); - VERIFY_CHECK(!q.normalized && q.magnitude == (j+2)); - } - secp256k1_fe_normalize_var(&z); - /* Test storage conversion and conditional moves. */ - secp256k1_fe_to_storage(&xs, &x); - secp256k1_fe_to_storage(&ys, &y); - secp256k1_fe_to_storage(&zs, &z); - secp256k1_fe_storage_cmov(&zs, &xs, 0); - secp256k1_fe_storage_cmov(&zs, &zs, 1); - CHECK(memcmp(&xs, &zs, sizeof(xs)) != 0); - secp256k1_fe_storage_cmov(&ys, &xs, 1); - CHECK(memcmp(&xs, &ys, sizeof(xs)) == 0); - secp256k1_fe_from_storage(&x, &xs); - secp256k1_fe_from_storage(&y, &ys); - secp256k1_fe_from_storage(&z, &zs); - /* Test that mul_int, mul, and add agree. */ - secp256k1_fe_add(&y, &x); - secp256k1_fe_add(&y, &x); - z = x; - secp256k1_fe_mul_int(&z, 3); - CHECK(check_fe_equal(&y, &z)); - secp256k1_fe_add(&y, &x); - secp256k1_fe_add(&z, &x); - CHECK(check_fe_equal(&z, &y)); - z = x; - secp256k1_fe_mul_int(&z, 5); - secp256k1_fe_mul(&q, &x, &fe5); - CHECK(check_fe_equal(&z, &q)); - secp256k1_fe_negate(&x, &x, 1); - secp256k1_fe_add(&z, &x); - secp256k1_fe_add(&q, &x); - CHECK(check_fe_equal(&y, &z)); - CHECK(check_fe_equal(&q, &y)); - } -} - -void run_field_inv(void) { - secp256k1_fe x, xi, xii; - int i; - for (i = 0; i < 10*count; i++) { - random_fe_non_zero(&x); - secp256k1_fe_inv(&xi, &x); - CHECK(check_fe_inverse(&x, &xi)); - secp256k1_fe_inv(&xii, &xi); - CHECK(check_fe_equal(&x, &xii)); - } -} - -void run_field_inv_var(void) { - secp256k1_fe x, xi, xii; - int i; - for (i = 0; i < 10*count; i++) { - random_fe_non_zero(&x); - secp256k1_fe_inv_var(&xi, &x); - CHECK(check_fe_inverse(&x, &xi)); - secp256k1_fe_inv_var(&xii, &xi); - CHECK(check_fe_equal(&x, &xii)); - } -} - -void run_field_inv_all_var(void) { - secp256k1_fe x[16], xi[16], xii[16]; - int i; - /* Check it's safe to call for 0 elements */ - secp256k1_fe_inv_all_var(xi, x, 0); - for (i = 0; i < count; i++) { - size_t j; - size_t len = secp256k1_rand_int(15) + 1; - for (j = 0; j < len; j++) { - random_fe_non_zero(&x[j]); - } - secp256k1_fe_inv_all_var(xi, x, len); - for (j = 0; j < len; j++) { - CHECK(check_fe_inverse(&x[j], &xi[j])); - } - secp256k1_fe_inv_all_var(xii, xi, len); - for (j = 0; j < len; j++) { - CHECK(check_fe_equal(&x[j], &xii[j])); - } - } -} - -void run_sqr(void) { - secp256k1_fe x, s; - - { - int i; - secp256k1_fe_set_int(&x, 1); - secp256k1_fe_negate(&x, &x, 1); - - for (i = 1; i <= 512; ++i) { - secp256k1_fe_mul_int(&x, 2); - secp256k1_fe_normalize(&x); - secp256k1_fe_sqr(&s, &x); - } - } -} - -void test_sqrt(const secp256k1_fe *a, const secp256k1_fe *k) { - secp256k1_fe r1, r2; - int v = secp256k1_fe_sqrt(&r1, a); - CHECK((v == 0) == (k == NULL)); - - if (k != NULL) { - /* Check that the returned root is +/- the given known answer */ - secp256k1_fe_negate(&r2, &r1, 1); - secp256k1_fe_add(&r1, k); secp256k1_fe_add(&r2, k); - secp256k1_fe_normalize(&r1); secp256k1_fe_normalize(&r2); - CHECK(secp256k1_fe_is_zero(&r1) || secp256k1_fe_is_zero(&r2)); - } -} - -void run_sqrt(void) { - secp256k1_fe ns, x, s, t; - int i; - - /* Check sqrt(0) is 0 */ - secp256k1_fe_set_int(&x, 0); - secp256k1_fe_sqr(&s, &x); - test_sqrt(&s, &x); - - /* Check sqrt of small squares (and their negatives) */ - for (i = 1; i <= 100; i++) { - secp256k1_fe_set_int(&x, i); - secp256k1_fe_sqr(&s, &x); - test_sqrt(&s, &x); - secp256k1_fe_negate(&t, &s, 1); - test_sqrt(&t, NULL); - } - - /* Consistency checks for large random values */ - for (i = 0; i < 10; i++) { - int j; - random_fe_non_square(&ns); - for (j = 0; j < count; j++) { - random_fe(&x); - secp256k1_fe_sqr(&s, &x); - test_sqrt(&s, &x); - secp256k1_fe_negate(&t, &s, 1); - test_sqrt(&t, NULL); - secp256k1_fe_mul(&t, &s, &ns); - test_sqrt(&t, NULL); - } - } -} - -/***** GROUP TESTS *****/ - -void ge_equals_ge(const secp256k1_ge *a, const secp256k1_ge *b) { - CHECK(a->infinity == b->infinity); - if (a->infinity) { - return; - } - CHECK(secp256k1_fe_equal_var(&a->x, &b->x)); - CHECK(secp256k1_fe_equal_var(&a->y, &b->y)); -} - -/* This compares jacobian points including their Z, not just their geometric meaning. */ -int gej_xyz_equals_gej(const secp256k1_gej *a, const secp256k1_gej *b) { - secp256k1_gej a2; - secp256k1_gej b2; - int ret = 1; - ret &= a->infinity == b->infinity; - if (ret && !a->infinity) { - a2 = *a; - b2 = *b; - secp256k1_fe_normalize(&a2.x); - secp256k1_fe_normalize(&a2.y); - secp256k1_fe_normalize(&a2.z); - secp256k1_fe_normalize(&b2.x); - secp256k1_fe_normalize(&b2.y); - secp256k1_fe_normalize(&b2.z); - ret &= secp256k1_fe_cmp_var(&a2.x, &b2.x) == 0; - ret &= secp256k1_fe_cmp_var(&a2.y, &b2.y) == 0; - ret &= secp256k1_fe_cmp_var(&a2.z, &b2.z) == 0; - } - return ret; -} - -void ge_equals_gej(const secp256k1_ge *a, const secp256k1_gej *b) { - secp256k1_fe z2s; - secp256k1_fe u1, u2, s1, s2; - CHECK(a->infinity == b->infinity); - if (a->infinity) { - return; - } - /* Check a.x * b.z^2 == b.x && a.y * b.z^3 == b.y, to avoid inverses. */ - secp256k1_fe_sqr(&z2s, &b->z); - secp256k1_fe_mul(&u1, &a->x, &z2s); - u2 = b->x; secp256k1_fe_normalize_weak(&u2); - secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z); - s2 = b->y; secp256k1_fe_normalize_weak(&s2); - CHECK(secp256k1_fe_equal_var(&u1, &u2)); - CHECK(secp256k1_fe_equal_var(&s1, &s2)); -} - -void test_ge(void) { - int i, i1; -#ifdef USE_ENDOMORPHISM - int runs = 6; -#else - int runs = 4; -#endif - /* Points: (infinity, p1, p1, -p1, -p1, p2, p2, -p2, -p2, p3, p3, -p3, -p3, p4, p4, -p4, -p4). - * The second in each pair of identical points uses a random Z coordinate in the Jacobian form. - * All magnitudes are randomized. - * All 17*17 combinations of points are added to each other, using all applicable methods. - * - * When the endomorphism code is compiled in, p5 = lambda*p1 and p6 = lambda^2*p1 are added as well. - */ - secp256k1_ge *ge = (secp256k1_ge *)checked_malloc(&ctx->error_callback, sizeof(secp256k1_ge) * (1 + 4 * runs)); - secp256k1_gej *gej = (secp256k1_gej *)checked_malloc(&ctx->error_callback, sizeof(secp256k1_gej) * (1 + 4 * runs)); - secp256k1_fe *zinv = (secp256k1_fe *)checked_malloc(&ctx->error_callback, sizeof(secp256k1_fe) * (1 + 4 * runs)); - secp256k1_fe zf; - secp256k1_fe zfi2, zfi3; - - secp256k1_gej_set_infinity(&gej[0]); - secp256k1_ge_clear(&ge[0]); - secp256k1_ge_set_gej_var(&ge[0], &gej[0]); - for (i = 0; i < runs; i++) { - int j; - secp256k1_ge g; - random_group_element_test(&g); -#ifdef USE_ENDOMORPHISM - if (i >= runs - 2) { - secp256k1_ge_mul_lambda(&g, &ge[1]); - } - if (i >= runs - 1) { - secp256k1_ge_mul_lambda(&g, &g); - } -#endif - ge[1 + 4 * i] = g; - ge[2 + 4 * i] = g; - secp256k1_ge_neg(&ge[3 + 4 * i], &g); - secp256k1_ge_neg(&ge[4 + 4 * i], &g); - secp256k1_gej_set_ge(&gej[1 + 4 * i], &ge[1 + 4 * i]); - random_group_element_jacobian_test(&gej[2 + 4 * i], &ge[2 + 4 * i]); - secp256k1_gej_set_ge(&gej[3 + 4 * i], &ge[3 + 4 * i]); - random_group_element_jacobian_test(&gej[4 + 4 * i], &ge[4 + 4 * i]); - for (j = 0; j < 4; j++) { - random_field_element_magnitude(&ge[1 + j + 4 * i].x); - random_field_element_magnitude(&ge[1 + j + 4 * i].y); - random_field_element_magnitude(&gej[1 + j + 4 * i].x); - random_field_element_magnitude(&gej[1 + j + 4 * i].y); - random_field_element_magnitude(&gej[1 + j + 4 * i].z); - } - } - - /* Compute z inverses. */ - { - secp256k1_fe *zs = checked_malloc(&ctx->error_callback, sizeof(secp256k1_fe) * (1 + 4 * runs)); - for (i = 0; i < 4 * runs + 1; i++) { - if (i == 0) { - /* The point at infinity does not have a meaningful z inverse. Any should do. */ - do { - random_field_element_test(&zs[i]); - } while(secp256k1_fe_is_zero(&zs[i])); - } else { - zs[i] = gej[i].z; - } - } - secp256k1_fe_inv_all_var(zinv, zs, 4 * runs + 1); - free(zs); - } - - /* Generate random zf, and zfi2 = 1/zf^2, zfi3 = 1/zf^3 */ - do { - random_field_element_test(&zf); - } while(secp256k1_fe_is_zero(&zf)); - random_field_element_magnitude(&zf); - secp256k1_fe_inv_var(&zfi3, &zf); - secp256k1_fe_sqr(&zfi2, &zfi3); - secp256k1_fe_mul(&zfi3, &zfi3, &zfi2); - - for (i1 = 0; i1 < 1 + 4 * runs; i1++) { - int i2; - for (i2 = 0; i2 < 1 + 4 * runs; i2++) { - /* Compute reference result using gej + gej (var). */ - secp256k1_gej refj, resj; - secp256k1_ge ref; - secp256k1_fe zr; - secp256k1_gej_add_var(&refj, &gej[i1], &gej[i2], secp256k1_gej_is_infinity(&gej[i1]) ? NULL : &zr); - /* Check Z ratio. */ - if (!secp256k1_gej_is_infinity(&gej[i1]) && !secp256k1_gej_is_infinity(&refj)) { - secp256k1_fe zrz; secp256k1_fe_mul(&zrz, &zr, &gej[i1].z); - CHECK(secp256k1_fe_equal_var(&zrz, &refj.z)); - } - secp256k1_ge_set_gej_var(&ref, &refj); - - /* Test gej + ge with Z ratio result (var). */ - secp256k1_gej_add_ge_var(&resj, &gej[i1], &ge[i2], secp256k1_gej_is_infinity(&gej[i1]) ? NULL : &zr); - ge_equals_gej(&ref, &resj); - if (!secp256k1_gej_is_infinity(&gej[i1]) && !secp256k1_gej_is_infinity(&resj)) { - secp256k1_fe zrz; secp256k1_fe_mul(&zrz, &zr, &gej[i1].z); - CHECK(secp256k1_fe_equal_var(&zrz, &resj.z)); - } - - /* Test gej + ge (var, with additional Z factor). */ - { - secp256k1_ge ge2_zfi = ge[i2]; /* the second term with x and y rescaled for z = 1/zf */ - secp256k1_fe_mul(&ge2_zfi.x, &ge2_zfi.x, &zfi2); - secp256k1_fe_mul(&ge2_zfi.y, &ge2_zfi.y, &zfi3); - random_field_element_magnitude(&ge2_zfi.x); - random_field_element_magnitude(&ge2_zfi.y); - secp256k1_gej_add_zinv_var(&resj, &gej[i1], &ge2_zfi, &zf); - ge_equals_gej(&ref, &resj); - } - - /* Test gej + ge (const). */ - if (i2 != 0) { - /* secp256k1_gej_add_ge does not support its second argument being infinity. */ - secp256k1_gej_add_ge(&resj, &gej[i1], &ge[i2]); - ge_equals_gej(&ref, &resj); - } - - /* Test doubling (var). */ - if ((i1 == 0 && i2 == 0) || ((i1 + 3)/4 == (i2 + 3)/4 && ((i1 + 3)%4)/2 == ((i2 + 3)%4)/2)) { - secp256k1_fe zr2; - /* Normal doubling with Z ratio result. */ - secp256k1_gej_double_var(&resj, &gej[i1], &zr2); - ge_equals_gej(&ref, &resj); - /* Check Z ratio. */ - secp256k1_fe_mul(&zr2, &zr2, &gej[i1].z); - CHECK(secp256k1_fe_equal_var(&zr2, &resj.z)); - /* Normal doubling. */ - secp256k1_gej_double_var(&resj, &gej[i2], NULL); - ge_equals_gej(&ref, &resj); - } - - /* Test adding opposites. */ - if ((i1 == 0 && i2 == 0) || ((i1 + 3)/4 == (i2 + 3)/4 && ((i1 + 3)%4)/2 != ((i2 + 3)%4)/2)) { - CHECK(secp256k1_ge_is_infinity(&ref)); - } - - /* Test adding infinity. */ - if (i1 == 0) { - CHECK(secp256k1_ge_is_infinity(&ge[i1])); - CHECK(secp256k1_gej_is_infinity(&gej[i1])); - ge_equals_gej(&ref, &gej[i2]); - } - if (i2 == 0) { - CHECK(secp256k1_ge_is_infinity(&ge[i2])); - CHECK(secp256k1_gej_is_infinity(&gej[i2])); - ge_equals_gej(&ref, &gej[i1]); - } - } - } - - /* Test adding all points together in random order equals infinity. */ - { - secp256k1_gej sum = SECP256K1_GEJ_CONST_INFINITY; - secp256k1_gej *gej_shuffled = (secp256k1_gej *)checked_malloc(&ctx->error_callback, (4 * runs + 1) * sizeof(secp256k1_gej)); - for (i = 0; i < 4 * runs + 1; i++) { - gej_shuffled[i] = gej[i]; - } - for (i = 0; i < 4 * runs + 1; i++) { - int swap = i + secp256k1_rand_int(4 * runs + 1 - i); - if (swap != i) { - secp256k1_gej t = gej_shuffled[i]; - gej_shuffled[i] = gej_shuffled[swap]; - gej_shuffled[swap] = t; - } - } - for (i = 0; i < 4 * runs + 1; i++) { - secp256k1_gej_add_var(&sum, &sum, &gej_shuffled[i], NULL); - } - CHECK(secp256k1_gej_is_infinity(&sum)); - free(gej_shuffled); - } - - /* Test batch gej -> ge conversion with and without known z ratios. */ - { - secp256k1_fe *zr = (secp256k1_fe *)checked_malloc(&ctx->error_callback, (4 * runs + 1) * sizeof(secp256k1_fe)); - secp256k1_ge *ge_set_table = (secp256k1_ge *)checked_malloc(&ctx->error_callback, (4 * runs + 1) * sizeof(secp256k1_ge)); - secp256k1_ge *ge_set_all = (secp256k1_ge *)checked_malloc(&ctx->error_callback, (4 * runs + 1) * sizeof(secp256k1_ge)); - for (i = 0; i < 4 * runs + 1; i++) { - /* Compute gej[i + 1].z / gez[i].z (with gej[n].z taken to be 1). */ - if (i < 4 * runs) { - secp256k1_fe_mul(&zr[i + 1], &zinv[i], &gej[i + 1].z); - } - } - secp256k1_ge_set_table_gej_var(ge_set_table, gej, zr, 4 * runs + 1); - secp256k1_ge_set_all_gej_var(ge_set_all, gej, 4 * runs + 1, &ctx->error_callback); - for (i = 0; i < 4 * runs + 1; i++) { - secp256k1_fe s; - random_fe_non_zero(&s); - secp256k1_gej_rescale(&gej[i], &s); - ge_equals_gej(&ge_set_table[i], &gej[i]); - ge_equals_gej(&ge_set_all[i], &gej[i]); - } - free(ge_set_table); - free(ge_set_all); - free(zr); - } - - free(ge); - free(gej); - free(zinv); -} - -void test_add_neg_y_diff_x(void) { - /* The point of this test is to check that we can add two points - * whose y-coordinates are negatives of each other but whose x - * coordinates differ. If the x-coordinates were the same, these - * points would be negatives of each other and their sum is - * infinity. This is cool because it "covers up" any degeneracy - * in the addition algorithm that would cause the xy coordinates - * of the sum to be wrong (since infinity has no xy coordinates). - * HOWEVER, if the x-coordinates are different, infinity is the - * wrong answer, and such degeneracies are exposed. This is the - * root of https://github.com/bitcoin-core/secp256k1/issues/257 - * which this test is a regression test for. - * - * These points were generated in sage as - * # secp256k1 params - * F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) - * C = EllipticCurve ([F (0), F (7)]) - * G = C.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798) - * N = FiniteField(G.order()) - * - * # endomorphism values (lambda is 1^{1/3} in N, beta is 1^{1/3} in F) - * x = polygen(N) - * lam = (1 - x^3).roots()[1][0] - * - * # random "bad pair" - * P = C.random_element() - * Q = -int(lam) * P - * print " P: %x %x" % P.xy() - * print " Q: %x %x" % Q.xy() - * print "P + Q: %x %x" % (P + Q).xy() - */ - secp256k1_gej aj = SECP256K1_GEJ_CONST( - 0x8d24cd95, 0x0a355af1, 0x3c543505, 0x44238d30, - 0x0643d79f, 0x05a59614, 0x2f8ec030, 0xd58977cb, - 0x001e337a, 0x38093dcd, 0x6c0f386d, 0x0b1293a8, - 0x4d72c879, 0xd7681924, 0x44e6d2f3, 0x9190117d - ); - secp256k1_gej bj = SECP256K1_GEJ_CONST( - 0xc7b74206, 0x1f788cd9, 0xabd0937d, 0x164a0d86, - 0x95f6ff75, 0xf19a4ce9, 0xd013bd7b, 0xbf92d2a7, - 0xffe1cc85, 0xc7f6c232, 0x93f0c792, 0xf4ed6c57, - 0xb28d3786, 0x2897e6db, 0xbb192d0b, 0x6e6feab2 - ); - secp256k1_gej sumj = SECP256K1_GEJ_CONST( - 0x671a63c0, 0x3efdad4c, 0x389a7798, 0x24356027, - 0xb3d69010, 0x278625c3, 0x5c86d390, 0x184a8f7a, - 0x5f6409c2, 0x2ce01f2b, 0x511fd375, 0x25071d08, - 0xda651801, 0x70e95caf, 0x8f0d893c, 0xbed8fbbe - ); - secp256k1_ge b; - secp256k1_gej resj; - secp256k1_ge res; - secp256k1_ge_set_gej(&b, &bj); - - secp256k1_gej_add_var(&resj, &aj, &bj, NULL); - secp256k1_ge_set_gej(&res, &resj); - ge_equals_gej(&res, &sumj); - - secp256k1_gej_add_ge(&resj, &aj, &b); - secp256k1_ge_set_gej(&res, &resj); - ge_equals_gej(&res, &sumj); - - secp256k1_gej_add_ge_var(&resj, &aj, &b, NULL); - secp256k1_ge_set_gej(&res, &resj); - ge_equals_gej(&res, &sumj); -} - -void run_ge(void) { - int i; - for (i = 0; i < count * 32; i++) { - test_ge(); - } - test_add_neg_y_diff_x(); -} - -void test_ec_combine(void) { - secp256k1_scalar sum = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); - secp256k1_pubkey data[6]; - const secp256k1_pubkey* d[6]; - secp256k1_pubkey sd; - secp256k1_pubkey sd2; - secp256k1_gej Qj; - secp256k1_ge Q; - int i; - for (i = 1; i <= 6; i++) { - secp256k1_scalar s; - random_scalar_order_test(&s); - secp256k1_scalar_add(&sum, &sum, &s); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &Qj, &s); - secp256k1_ge_set_gej(&Q, &Qj); - secp256k1_pubkey_save(&data[i - 1], &Q); - d[i - 1] = &data[i - 1]; - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &Qj, &sum); - secp256k1_ge_set_gej(&Q, &Qj); - secp256k1_pubkey_save(&sd, &Q); - CHECK(secp256k1_ec_pubkey_combine(ctx, &sd2, d, i) == 1); - CHECK(memcmp(&sd, &sd2, sizeof(sd)) == 0); - } -} - -void run_ec_combine(void) { - int i; - for (i = 0; i < count * 8; i++) { - test_ec_combine(); - } -} - -void test_group_decompress(const secp256k1_fe* x) { - /* The input itself, normalized. */ - secp256k1_fe fex = *x; - secp256k1_fe fez; - /* Results of set_xquad_var, set_xo_var(..., 0), set_xo_var(..., 1). */ - secp256k1_ge ge_quad, ge_even, ge_odd; - secp256k1_gej gej_quad; - /* Return values of the above calls. */ - int res_quad, res_even, res_odd; - - secp256k1_fe_normalize_var(&fex); - - res_quad = secp256k1_ge_set_xquad(&ge_quad, &fex); - res_even = secp256k1_ge_set_xo_var(&ge_even, &fex, 0); - res_odd = secp256k1_ge_set_xo_var(&ge_odd, &fex, 1); - - CHECK(res_quad == res_even); - CHECK(res_quad == res_odd); - - if (res_quad) { - secp256k1_fe_normalize_var(&ge_quad.x); - secp256k1_fe_normalize_var(&ge_odd.x); - secp256k1_fe_normalize_var(&ge_even.x); - secp256k1_fe_normalize_var(&ge_quad.y); - secp256k1_fe_normalize_var(&ge_odd.y); - secp256k1_fe_normalize_var(&ge_even.y); - - /* No infinity allowed. */ - CHECK(!ge_quad.infinity); - CHECK(!ge_even.infinity); - CHECK(!ge_odd.infinity); - - /* Check that the x coordinates check out. */ - CHECK(secp256k1_fe_equal_var(&ge_quad.x, x)); - CHECK(secp256k1_fe_equal_var(&ge_even.x, x)); - CHECK(secp256k1_fe_equal_var(&ge_odd.x, x)); - - /* Check that the Y coordinate result in ge_quad is a square. */ - CHECK(secp256k1_fe_is_quad_var(&ge_quad.y)); - - /* Check odd/even Y in ge_odd, ge_even. */ - CHECK(secp256k1_fe_is_odd(&ge_odd.y)); - CHECK(!secp256k1_fe_is_odd(&ge_even.y)); - - /* Check secp256k1_gej_has_quad_y_var. */ - secp256k1_gej_set_ge(&gej_quad, &ge_quad); - CHECK(secp256k1_gej_has_quad_y_var(&gej_quad)); - do { - random_fe_test(&fez); - } while (secp256k1_fe_is_zero(&fez)); - secp256k1_gej_rescale(&gej_quad, &fez); - CHECK(secp256k1_gej_has_quad_y_var(&gej_quad)); - secp256k1_gej_neg(&gej_quad, &gej_quad); - CHECK(!secp256k1_gej_has_quad_y_var(&gej_quad)); - do { - random_fe_test(&fez); - } while (secp256k1_fe_is_zero(&fez)); - secp256k1_gej_rescale(&gej_quad, &fez); - CHECK(!secp256k1_gej_has_quad_y_var(&gej_quad)); - secp256k1_gej_neg(&gej_quad, &gej_quad); - CHECK(secp256k1_gej_has_quad_y_var(&gej_quad)); - } -} - -void run_group_decompress(void) { - int i; - for (i = 0; i < count * 4; i++) { - secp256k1_fe fe; - random_fe_test(&fe); - test_group_decompress(&fe); - } -} - -/***** ECMULT TESTS *****/ - -void run_ecmult_chain(void) { - /* random starting point A (on the curve) */ - secp256k1_gej a = SECP256K1_GEJ_CONST( - 0x8b30bbe9, 0xae2a9906, 0x96b22f67, 0x0709dff3, - 0x727fd8bc, 0x04d3362c, 0x6c7bf458, 0xe2846004, - 0xa357ae91, 0x5c4a6528, 0x1309edf2, 0x0504740f, - 0x0eb33439, 0x90216b4f, 0x81063cb6, 0x5f2f7e0f - ); - /* two random initial factors xn and gn */ - secp256k1_scalar xn = SECP256K1_SCALAR_CONST( - 0x84cc5452, 0xf7fde1ed, 0xb4d38a8c, 0xe9b1b84c, - 0xcef31f14, 0x6e569be9, 0x705d357a, 0x42985407 - ); - secp256k1_scalar gn = SECP256K1_SCALAR_CONST( - 0xa1e58d22, 0x553dcd42, 0xb2398062, 0x5d4c57a9, - 0x6e9323d4, 0x2b3152e5, 0xca2c3990, 0xedc7c9de - ); - /* two small multipliers to be applied to xn and gn in every iteration: */ - static const secp256k1_scalar xf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x1337); - static const secp256k1_scalar gf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x7113); - /* accumulators with the resulting coefficients to A and G */ - secp256k1_scalar ae = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); - secp256k1_scalar ge = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); - /* actual points */ - secp256k1_gej x; - secp256k1_gej x2; - int i; - - /* the point being computed */ - x = a; - for (i = 0; i < 200*count; i++) { - /* in each iteration, compute X = xn*X + gn*G; */ - secp256k1_ecmult(&ctx->ecmult_ctx, &x, &x, &xn, &gn); - /* also compute ae and ge: the actual accumulated factors for A and G */ - /* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */ - secp256k1_scalar_mul(&ae, &ae, &xn); - secp256k1_scalar_mul(&ge, &ge, &xn); - secp256k1_scalar_add(&ge, &ge, &gn); - /* modify xn and gn */ - secp256k1_scalar_mul(&xn, &xn, &xf); - secp256k1_scalar_mul(&gn, &gn, &gf); - - /* verify */ - if (i == 19999) { - /* expected result after 19999 iterations */ - secp256k1_gej rp = SECP256K1_GEJ_CONST( - 0xD6E96687, 0xF9B10D09, 0x2A6F3543, 0x9D86CEBE, - 0xA4535D0D, 0x409F5358, 0x6440BD74, 0xB933E830, - 0xB95CBCA2, 0xC77DA786, 0x539BE8FD, 0x53354D2D, - 0x3B4F566A, 0xE6580454, 0x07ED6015, 0xEE1B2A88 - ); - - secp256k1_gej_neg(&rp, &rp); - secp256k1_gej_add_var(&rp, &rp, &x, NULL); - CHECK(secp256k1_gej_is_infinity(&rp)); - } - } - /* redo the computation, but directly with the resulting ae and ge coefficients: */ - secp256k1_ecmult(&ctx->ecmult_ctx, &x2, &a, &ae, &ge); - secp256k1_gej_neg(&x2, &x2); - secp256k1_gej_add_var(&x2, &x2, &x, NULL); - CHECK(secp256k1_gej_is_infinity(&x2)); -} - -void test_point_times_order(const secp256k1_gej *point) { - /* X * (point + G) + (order-X) * (pointer + G) = 0 */ - secp256k1_scalar x; - secp256k1_scalar nx; - secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); - secp256k1_scalar one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); - secp256k1_gej res1, res2; - secp256k1_ge res3; - unsigned char pub[65]; - size_t psize = 65; - random_scalar_order_test(&x); - secp256k1_scalar_negate(&nx, &x); - secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &x, &x); /* calc res1 = x * point + x * G; */ - secp256k1_ecmult(&ctx->ecmult_ctx, &res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */ - secp256k1_gej_add_var(&res1, &res1, &res2, NULL); - CHECK(secp256k1_gej_is_infinity(&res1)); - CHECK(secp256k1_gej_is_valid_var(&res1) == 0); - secp256k1_ge_set_gej(&res3, &res1); - CHECK(secp256k1_ge_is_infinity(&res3)); - CHECK(secp256k1_ge_is_valid_var(&res3) == 0); - CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 0) == 0); - psize = 65; - CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 1) == 0); - /* check zero/one edge cases */ - secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &zero, &zero); - secp256k1_ge_set_gej(&res3, &res1); - CHECK(secp256k1_ge_is_infinity(&res3)); - secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &one, &zero); - secp256k1_ge_set_gej(&res3, &res1); - ge_equals_gej(&res3, point); - secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &zero, &one); - secp256k1_ge_set_gej(&res3, &res1); - ge_equals_ge(&res3, &secp256k1_ge_const_g); -} - -void run_point_times_order(void) { - int i; - secp256k1_fe x = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 2); - static const secp256k1_fe xr = SECP256K1_FE_CONST( - 0x7603CB59, 0xB0EF6C63, 0xFE608479, 0x2A0C378C, - 0xDB3233A8, 0x0F8A9A09, 0xA877DEAD, 0x31B38C45 - ); - for (i = 0; i < 500; i++) { - secp256k1_ge p; - if (secp256k1_ge_set_xo_var(&p, &x, 1)) { - secp256k1_gej j; - CHECK(secp256k1_ge_is_valid_var(&p)); - secp256k1_gej_set_ge(&j, &p); - CHECK(secp256k1_gej_is_valid_var(&j)); - test_point_times_order(&j); - } - secp256k1_fe_sqr(&x, &x); - } - secp256k1_fe_normalize_var(&x); - CHECK(secp256k1_fe_equal_var(&x, &xr)); -} - -void ecmult_const_random_mult(void) { - /* random starting point A (on the curve) */ - secp256k1_ge a = SECP256K1_GE_CONST( - 0x6d986544, 0x57ff52b8, 0xcf1b8126, 0x5b802a5b, - 0xa97f9263, 0xb1e88044, 0x93351325, 0x91bc450a, - 0x535c59f7, 0x325e5d2b, 0xc391fbe8, 0x3c12787c, - 0x337e4a98, 0xe82a9011, 0x0123ba37, 0xdd769c7d - ); - /* random initial factor xn */ - secp256k1_scalar xn = SECP256K1_SCALAR_CONST( - 0x649d4f77, 0xc4242df7, 0x7f2079c9, 0x14530327, - 0xa31b876a, 0xd2d8ce2a, 0x2236d5c6, 0xd7b2029b - ); - /* expected xn * A (from sage) */ - secp256k1_ge expected_b = SECP256K1_GE_CONST( - 0x23773684, 0x4d209dc7, 0x098a786f, 0x20d06fcd, - 0x070a38bf, 0xc11ac651, 0x03004319, 0x1e2a8786, - 0xed8c3b8e, 0xc06dd57b, 0xd06ea66e, 0x45492b0f, - 0xb84e4e1b, 0xfb77e21f, 0x96baae2a, 0x63dec956 - ); - secp256k1_gej b; - secp256k1_ecmult_const(&b, &a, &xn); - - CHECK(secp256k1_ge_is_valid_var(&a)); - ge_equals_gej(&expected_b, &b); -} - -void ecmult_const_commutativity(void) { - secp256k1_scalar a; - secp256k1_scalar b; - secp256k1_gej res1; - secp256k1_gej res2; - secp256k1_ge mid1; - secp256k1_ge mid2; - random_scalar_order_test(&a); - random_scalar_order_test(&b); - - secp256k1_ecmult_const(&res1, &secp256k1_ge_const_g, &a); - secp256k1_ecmult_const(&res2, &secp256k1_ge_const_g, &b); - secp256k1_ge_set_gej(&mid1, &res1); - secp256k1_ge_set_gej(&mid2, &res2); - secp256k1_ecmult_const(&res1, &mid1, &b); - secp256k1_ecmult_const(&res2, &mid2, &a); - secp256k1_ge_set_gej(&mid1, &res1); - secp256k1_ge_set_gej(&mid2, &res2); - ge_equals_ge(&mid1, &mid2); -} - -void ecmult_const_mult_zero_one(void) { - secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); - secp256k1_scalar one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); - secp256k1_scalar negone; - secp256k1_gej res1; - secp256k1_ge res2; - secp256k1_ge point; - secp256k1_scalar_negate(&negone, &one); - - random_group_element_test(&point); - secp256k1_ecmult_const(&res1, &point, &zero); - secp256k1_ge_set_gej(&res2, &res1); - CHECK(secp256k1_ge_is_infinity(&res2)); - secp256k1_ecmult_const(&res1, &point, &one); - secp256k1_ge_set_gej(&res2, &res1); - ge_equals_ge(&res2, &point); - secp256k1_ecmult_const(&res1, &point, &negone); - secp256k1_gej_neg(&res1, &res1); - secp256k1_ge_set_gej(&res2, &res1); - ge_equals_ge(&res2, &point); -} - -void ecmult_const_chain_multiply(void) { - /* Check known result (randomly generated test problem from sage) */ - const secp256k1_scalar scalar = SECP256K1_SCALAR_CONST( - 0x4968d524, 0x2abf9b7a, 0x466abbcf, 0x34b11b6d, - 0xcd83d307, 0x827bed62, 0x05fad0ce, 0x18fae63b - ); - const secp256k1_gej expected_point = SECP256K1_GEJ_CONST( - 0x5494c15d, 0x32099706, 0xc2395f94, 0x348745fd, - 0x757ce30e, 0x4e8c90fb, 0xa2bad184, 0xf883c69f, - 0x5d195d20, 0xe191bf7f, 0x1be3e55f, 0x56a80196, - 0x6071ad01, 0xf1462f66, 0xc997fa94, 0xdb858435 - ); - secp256k1_gej point; - secp256k1_ge res; - int i; - - secp256k1_gej_set_ge(&point, &secp256k1_ge_const_g); - for (i = 0; i < 100; ++i) { - secp256k1_ge tmp; - secp256k1_ge_set_gej(&tmp, &point); - secp256k1_ecmult_const(&point, &tmp, &scalar); - } - secp256k1_ge_set_gej(&res, &point); - ge_equals_gej(&res, &expected_point); -} - -void run_ecmult_const_tests(void) { - ecmult_const_mult_zero_one(); - ecmult_const_random_mult(); - ecmult_const_commutativity(); - ecmult_const_chain_multiply(); -} - -void test_wnaf(const secp256k1_scalar *number, int w) { - secp256k1_scalar x, two, t; - int wnaf[256]; - int zeroes = -1; - int i; - int bits; - secp256k1_scalar_set_int(&x, 0); - secp256k1_scalar_set_int(&two, 2); - bits = secp256k1_ecmult_wnaf(wnaf, 256, number, w); - CHECK(bits <= 256); - for (i = bits-1; i >= 0; i--) { - int v = wnaf[i]; - secp256k1_scalar_mul(&x, &x, &two); - if (v) { - CHECK(zeroes == -1 || zeroes >= w-1); /* check that distance between non-zero elements is at least w-1 */ - zeroes=0; - CHECK((v & 1) == 1); /* check non-zero elements are odd */ - CHECK(v <= (1 << (w-1)) - 1); /* check range below */ - CHECK(v >= -(1 << (w-1)) - 1); /* check range above */ - } else { - CHECK(zeroes != -1); /* check that no unnecessary zero padding exists */ - zeroes++; - } - if (v >= 0) { - secp256k1_scalar_set_int(&t, v); - } else { - secp256k1_scalar_set_int(&t, -v); - secp256k1_scalar_negate(&t, &t); - } - secp256k1_scalar_add(&x, &x, &t); - } - CHECK(secp256k1_scalar_eq(&x, number)); /* check that wnaf represents number */ -} - -void test_constant_wnaf_negate(const secp256k1_scalar *number) { - secp256k1_scalar neg1 = *number; - secp256k1_scalar neg2 = *number; - int sign1 = 1; - int sign2 = 1; - - if (!secp256k1_scalar_get_bits(&neg1, 0, 1)) { - secp256k1_scalar_negate(&neg1, &neg1); - sign1 = -1; - } - sign2 = secp256k1_scalar_cond_negate(&neg2, secp256k1_scalar_is_even(&neg2)); - CHECK(sign1 == sign2); - CHECK(secp256k1_scalar_eq(&neg1, &neg2)); -} - -void test_constant_wnaf(const secp256k1_scalar *number, int w) { - secp256k1_scalar x, shift; - int wnaf[256] = {0}; - int i; - int skew; - secp256k1_scalar num = *number; - - secp256k1_scalar_set_int(&x, 0); - secp256k1_scalar_set_int(&shift, 1 << w); - /* With USE_ENDOMORPHISM on we only consider 128-bit numbers */ -#ifdef USE_ENDOMORPHISM - for (i = 0; i < 16; ++i) { - secp256k1_scalar_shr_int(&num, 8); - } -#endif - skew = secp256k1_wnaf_const(wnaf, num, w); - - for (i = WNAF_SIZE(w); i >= 0; --i) { - secp256k1_scalar t; - int v = wnaf[i]; - CHECK(v != 0); /* check nonzero */ - CHECK(v & 1); /* check parity */ - CHECK(v > -(1 << w)); /* check range above */ - CHECK(v < (1 << w)); /* check range below */ - - secp256k1_scalar_mul(&x, &x, &shift); - if (v >= 0) { - secp256k1_scalar_set_int(&t, v); - } else { - secp256k1_scalar_set_int(&t, -v); - secp256k1_scalar_negate(&t, &t); - } - secp256k1_scalar_add(&x, &x, &t); - } - /* Skew num because when encoding numbers as odd we use an offset */ - secp256k1_scalar_cadd_bit(&num, skew == 2, 1); - CHECK(secp256k1_scalar_eq(&x, &num)); -} - -void run_wnaf(void) { - int i; - secp256k1_scalar n = {{0}}; - - /* Sanity check: 1 and 2 are the smallest odd and even numbers and should - * have easier-to-diagnose failure modes */ - n.d[0] = 1; - test_constant_wnaf(&n, 4); - n.d[0] = 2; - test_constant_wnaf(&n, 4); - /* Random tests */ - for (i = 0; i < count; i++) { - random_scalar_order(&n); - test_wnaf(&n, 4+(i%10)); - test_constant_wnaf_negate(&n); - test_constant_wnaf(&n, 4 + (i % 10)); - } - secp256k1_scalar_set_int(&n, 0); - CHECK(secp256k1_scalar_cond_negate(&n, 1) == -1); - CHECK(secp256k1_scalar_is_zero(&n)); - CHECK(secp256k1_scalar_cond_negate(&n, 0) == 1); - CHECK(secp256k1_scalar_is_zero(&n)); -} - -void test_ecmult_constants(void) { - /* Test ecmult_gen() for [0..36) and [order-36..0). */ - secp256k1_scalar x; - secp256k1_gej r; - secp256k1_ge ng; - int i; - int j; - secp256k1_ge_neg(&ng, &secp256k1_ge_const_g); - for (i = 0; i < 36; i++ ) { - secp256k1_scalar_set_int(&x, i); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &r, &x); - for (j = 0; j < i; j++) { - if (j == i - 1) { - ge_equals_gej(&secp256k1_ge_const_g, &r); - } - secp256k1_gej_add_ge(&r, &r, &ng); - } - CHECK(secp256k1_gej_is_infinity(&r)); - } - for (i = 1; i <= 36; i++ ) { - secp256k1_scalar_set_int(&x, i); - secp256k1_scalar_negate(&x, &x); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &r, &x); - for (j = 0; j < i; j++) { - if (j == i - 1) { - ge_equals_gej(&ng, &r); - } - secp256k1_gej_add_ge(&r, &r, &secp256k1_ge_const_g); - } - CHECK(secp256k1_gej_is_infinity(&r)); - } -} - -void run_ecmult_constants(void) { - test_ecmult_constants(); -} - -void test_ecmult_gen_blind(void) { - /* Test ecmult_gen() blinding and confirm that the blinding changes, the affine points match, and the z's don't match. */ - secp256k1_scalar key; - secp256k1_scalar b; - unsigned char seed32[32]; - secp256k1_gej pgej; - secp256k1_gej pgej2; - secp256k1_gej i; - secp256k1_ge pge; - random_scalar_order_test(&key); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pgej, &key); - secp256k1_rand256(seed32); - b = ctx->ecmult_gen_ctx.blind; - i = ctx->ecmult_gen_ctx.initial; - secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); - CHECK(!secp256k1_scalar_eq(&b, &ctx->ecmult_gen_ctx.blind)); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pgej2, &key); - CHECK(!gej_xyz_equals_gej(&pgej, &pgej2)); - CHECK(!gej_xyz_equals_gej(&i, &ctx->ecmult_gen_ctx.initial)); - secp256k1_ge_set_gej(&pge, &pgej); - ge_equals_gej(&pge, &pgej2); -} - -void test_ecmult_gen_blind_reset(void) { - /* Test ecmult_gen() blinding reset and confirm that the blinding is consistent. */ - secp256k1_scalar b; - secp256k1_gej initial; - secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, 0); - b = ctx->ecmult_gen_ctx.blind; - initial = ctx->ecmult_gen_ctx.initial; - secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, 0); - CHECK(secp256k1_scalar_eq(&b, &ctx->ecmult_gen_ctx.blind)); - CHECK(gej_xyz_equals_gej(&initial, &ctx->ecmult_gen_ctx.initial)); -} - -void run_ecmult_gen_blind(void) { - int i; - test_ecmult_gen_blind_reset(); - for (i = 0; i < 10; i++) { - test_ecmult_gen_blind(); - } -} - -#ifdef USE_ENDOMORPHISM -/***** ENDOMORPHISH TESTS *****/ -void test_scalar_split(void) { - secp256k1_scalar full; - secp256k1_scalar s1, slam; - const unsigned char zero[32] = {0}; - unsigned char tmp[32]; - - random_scalar_order_test(&full); - secp256k1_scalar_split_lambda(&s1, &slam, &full); - - /* check that both are <= 128 bits in size */ - if (secp256k1_scalar_is_high(&s1)) { - secp256k1_scalar_negate(&s1, &s1); - } - if (secp256k1_scalar_is_high(&slam)) { - secp256k1_scalar_negate(&slam, &slam); - } - - secp256k1_scalar_get_b32(tmp, &s1); - CHECK(memcmp(zero, tmp, 16) == 0); - secp256k1_scalar_get_b32(tmp, &slam); - CHECK(memcmp(zero, tmp, 16) == 0); -} - -void run_endomorphism_tests(void) { - test_scalar_split(); -} -#endif - -void ec_pubkey_parse_pointtest(const unsigned char *input, int xvalid, int yvalid) { - unsigned char pubkeyc[65]; - secp256k1_pubkey pubkey; - secp256k1_ge ge; - size_t pubkeyclen; - int32_t ecount; - ecount = 0; - secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); - for (pubkeyclen = 3; pubkeyclen <= 65; pubkeyclen++) { - /* Smaller sizes are tested exhaustively elsewhere. */ - int32_t i; - memcpy(&pubkeyc[1], input, 64); - VG_UNDEF(&pubkeyc[pubkeyclen], 65 - pubkeyclen); - for (i = 0; i < 256; i++) { - /* Try all type bytes. */ - int xpass; - int ypass; - int ysign; - pubkeyc[0] = i; - /* What sign does this point have? */ - ysign = (input[63] & 1) + 2; - /* For the current type (i) do we expect parsing to work? Handled all of compressed/uncompressed/hybrid. */ - xpass = xvalid && (pubkeyclen == 33) && ((i & 254) == 2); - /* Do we expect a parse and re-serialize as uncompressed to give a matching y? */ - ypass = xvalid && yvalid && ((i & 4) == ((pubkeyclen == 65) << 2)) && - ((i == 4) || ((i & 251) == ysign)) && ((pubkeyclen == 33) || (pubkeyclen == 65)); - if (xpass || ypass) { - /* These cases must parse. */ - unsigned char pubkeyo[65]; - size_t outl; - memset(&pubkey, 0, sizeof(pubkey)); - VG_UNDEF(&pubkey, sizeof(pubkey)); - ecount = 0; - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 1); - VG_CHECK(&pubkey, sizeof(pubkey)); - outl = 65; - VG_UNDEF(pubkeyo, 65); - CHECK(secp256k1_ec_pubkey_serialize(ctx, pubkeyo, &outl, &pubkey, SECP256K1_EC_COMPRESSED) == 1); - VG_CHECK(pubkeyo, outl); - CHECK(outl == 33); - CHECK(memcmp(&pubkeyo[1], &pubkeyc[1], 32) == 0); - CHECK((pubkeyclen != 33) || (pubkeyo[0] == pubkeyc[0])); - if (ypass) { - /* This test isn't always done because we decode with alternative signs, so the y won't match. */ - CHECK(pubkeyo[0] == ysign); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 1); - memset(&pubkey, 0, sizeof(pubkey)); - VG_UNDEF(&pubkey, sizeof(pubkey)); - secp256k1_pubkey_save(&pubkey, &ge); - VG_CHECK(&pubkey, sizeof(pubkey)); - outl = 65; - VG_UNDEF(pubkeyo, 65); - CHECK(secp256k1_ec_pubkey_serialize(ctx, pubkeyo, &outl, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 1); - VG_CHECK(pubkeyo, outl); - CHECK(outl == 65); - CHECK(pubkeyo[0] == 4); - CHECK(memcmp(&pubkeyo[1], input, 64) == 0); - } - CHECK(ecount == 0); - } else { - /* These cases must fail to parse. */ - memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 1); - } - } - } - secp256k1_context_set_illegal_callback(ctx, NULL, NULL); -} - -void run_ec_pubkey_parse_test(void) { -#define SECP256K1_EC_PARSE_TEST_NVALID (12) - const unsigned char valid[SECP256K1_EC_PARSE_TEST_NVALID][64] = { - { - /* Point with leading and trailing zeros in x and y serialization. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x52, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x64, 0xef, 0xa1, 0x7b, 0x77, 0x61, 0xe1, 0xe4, 0x27, 0x06, 0x98, 0x9f, 0xb4, 0x83, - 0xb8, 0xd2, 0xd4, 0x9b, 0xf7, 0x8f, 0xae, 0x98, 0x03, 0xf0, 0x99, 0xb8, 0x34, 0xed, 0xeb, 0x00 - }, - { - /* Point with x equal to a 3rd root of unity.*/ - 0x7a, 0xe9, 0x6a, 0x2b, 0x65, 0x7c, 0x07, 0x10, 0x6e, 0x64, 0x47, 0x9e, 0xac, 0x34, 0x34, 0xe9, - 0x9c, 0xf0, 0x49, 0x75, 0x12, 0xf5, 0x89, 0x95, 0xc1, 0x39, 0x6c, 0x28, 0x71, 0x95, 0x01, 0xee, - 0x42, 0x18, 0xf2, 0x0a, 0xe6, 0xc6, 0x46, 0xb3, 0x63, 0xdb, 0x68, 0x60, 0x58, 0x22, 0xfb, 0x14, - 0x26, 0x4c, 0xa8, 0xd2, 0x58, 0x7f, 0xdd, 0x6f, 0xbc, 0x75, 0x0d, 0x58, 0x7e, 0x76, 0xa7, 0xee, - }, - { - /* Point with largest x. (1/2) */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2c, - 0x0e, 0x99, 0x4b, 0x14, 0xea, 0x72, 0xf8, 0xc3, 0xeb, 0x95, 0xc7, 0x1e, 0xf6, 0x92, 0x57, 0x5e, - 0x77, 0x50, 0x58, 0x33, 0x2d, 0x7e, 0x52, 0xd0, 0x99, 0x5c, 0xf8, 0x03, 0x88, 0x71, 0xb6, 0x7d, - }, - { - /* Point with largest x. (2/2) */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2c, - 0xf1, 0x66, 0xb4, 0xeb, 0x15, 0x8d, 0x07, 0x3c, 0x14, 0x6a, 0x38, 0xe1, 0x09, 0x6d, 0xa8, 0xa1, - 0x88, 0xaf, 0xa7, 0xcc, 0xd2, 0x81, 0xad, 0x2f, 0x66, 0xa3, 0x07, 0xfb, 0x77, 0x8e, 0x45, 0xb2, - }, - { - /* Point with smallest x. (1/2) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x42, 0x18, 0xf2, 0x0a, 0xe6, 0xc6, 0x46, 0xb3, 0x63, 0xdb, 0x68, 0x60, 0x58, 0x22, 0xfb, 0x14, - 0x26, 0x4c, 0xa8, 0xd2, 0x58, 0x7f, 0xdd, 0x6f, 0xbc, 0x75, 0x0d, 0x58, 0x7e, 0x76, 0xa7, 0xee, - }, - { - /* Point with smallest x. (2/2) */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0xbd, 0xe7, 0x0d, 0xf5, 0x19, 0x39, 0xb9, 0x4c, 0x9c, 0x24, 0x97, 0x9f, 0xa7, 0xdd, 0x04, 0xeb, - 0xd9, 0xb3, 0x57, 0x2d, 0xa7, 0x80, 0x22, 0x90, 0x43, 0x8a, 0xf2, 0xa6, 0x81, 0x89, 0x54, 0x41, - }, - { - /* Point with largest y. (1/3) */ - 0x1f, 0xe1, 0xe5, 0xef, 0x3f, 0xce, 0xb5, 0xc1, 0x35, 0xab, 0x77, 0x41, 0x33, 0x3c, 0xe5, 0xa6, - 0xe8, 0x0d, 0x68, 0x16, 0x76, 0x53, 0xf6, 0xb2, 0xb2, 0x4b, 0xcb, 0xcf, 0xaa, 0xaf, 0xf5, 0x07, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2e, - }, - { - /* Point with largest y. (2/3) */ - 0xcb, 0xb0, 0xde, 0xab, 0x12, 0x57, 0x54, 0xf1, 0xfd, 0xb2, 0x03, 0x8b, 0x04, 0x34, 0xed, 0x9c, - 0xb3, 0xfb, 0x53, 0xab, 0x73, 0x53, 0x91, 0x12, 0x99, 0x94, 0xa5, 0x35, 0xd9, 0x25, 0xf6, 0x73, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2e, - }, - { - /* Point with largest y. (3/3) */ - 0x14, 0x6d, 0x3b, 0x65, 0xad, 0xd9, 0xf5, 0x4c, 0xcc, 0xa2, 0x85, 0x33, 0xc8, 0x8e, 0x2c, 0xbc, - 0x63, 0xf7, 0x44, 0x3e, 0x16, 0x58, 0x78, 0x3a, 0xb4, 0x1f, 0x8e, 0xf9, 0x7c, 0x2a, 0x10, 0xb5, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2e, - }, - { - /* Point with smallest y. (1/3) */ - 0x1f, 0xe1, 0xe5, 0xef, 0x3f, 0xce, 0xb5, 0xc1, 0x35, 0xab, 0x77, 0x41, 0x33, 0x3c, 0xe5, 0xa6, - 0xe8, 0x0d, 0x68, 0x16, 0x76, 0x53, 0xf6, 0xb2, 0xb2, 0x4b, 0xcb, 0xcf, 0xaa, 0xaf, 0xf5, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - }, - { - /* Point with smallest y. (2/3) */ - 0xcb, 0xb0, 0xde, 0xab, 0x12, 0x57, 0x54, 0xf1, 0xfd, 0xb2, 0x03, 0x8b, 0x04, 0x34, 0xed, 0x9c, - 0xb3, 0xfb, 0x53, 0xab, 0x73, 0x53, 0x91, 0x12, 0x99, 0x94, 0xa5, 0x35, 0xd9, 0x25, 0xf6, 0x73, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - }, - { - /* Point with smallest y. (3/3) */ - 0x14, 0x6d, 0x3b, 0x65, 0xad, 0xd9, 0xf5, 0x4c, 0xcc, 0xa2, 0x85, 0x33, 0xc8, 0x8e, 0x2c, 0xbc, - 0x63, 0xf7, 0x44, 0x3e, 0x16, 0x58, 0x78, 0x3a, 0xb4, 0x1f, 0x8e, 0xf9, 0x7c, 0x2a, 0x10, 0xb5, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 - } - }; -#define SECP256K1_EC_PARSE_TEST_NXVALID (4) - const unsigned char onlyxvalid[SECP256K1_EC_PARSE_TEST_NXVALID][64] = { - { - /* Valid if y overflow ignored (y = 1 mod p). (1/3) */ - 0x1f, 0xe1, 0xe5, 0xef, 0x3f, 0xce, 0xb5, 0xc1, 0x35, 0xab, 0x77, 0x41, 0x33, 0x3c, 0xe5, 0xa6, - 0xe8, 0x0d, 0x68, 0x16, 0x76, 0x53, 0xf6, 0xb2, 0xb2, 0x4b, 0xcb, 0xcf, 0xaa, 0xaf, 0xf5, 0x07, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x30, - }, - { - /* Valid if y overflow ignored (y = 1 mod p). (2/3) */ - 0xcb, 0xb0, 0xde, 0xab, 0x12, 0x57, 0x54, 0xf1, 0xfd, 0xb2, 0x03, 0x8b, 0x04, 0x34, 0xed, 0x9c, - 0xb3, 0xfb, 0x53, 0xab, 0x73, 0x53, 0x91, 0x12, 0x99, 0x94, 0xa5, 0x35, 0xd9, 0x25, 0xf6, 0x73, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x30, - }, - { - /* Valid if y overflow ignored (y = 1 mod p). (3/3)*/ - 0x14, 0x6d, 0x3b, 0x65, 0xad, 0xd9, 0xf5, 0x4c, 0xcc, 0xa2, 0x85, 0x33, 0xc8, 0x8e, 0x2c, 0xbc, - 0x63, 0xf7, 0x44, 0x3e, 0x16, 0x58, 0x78, 0x3a, 0xb4, 0x1f, 0x8e, 0xf9, 0x7c, 0x2a, 0x10, 0xb5, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x30, - }, - { - /* x on curve, y is from y^2 = x^3 + 8. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 - } - }; -#define SECP256K1_EC_PARSE_TEST_NINVALID (7) - const unsigned char invalid[SECP256K1_EC_PARSE_TEST_NINVALID][64] = { - { - /* x is third root of -8, y is -1 * (x^3+7); also on the curve for y^2 = x^3 + 9. */ - 0x0a, 0x2d, 0x2b, 0xa9, 0x35, 0x07, 0xf1, 0xdf, 0x23, 0x37, 0x70, 0xc2, 0xa7, 0x97, 0x96, 0x2c, - 0xc6, 0x1f, 0x6d, 0x15, 0xda, 0x14, 0xec, 0xd4, 0x7d, 0x8d, 0x27, 0xae, 0x1c, 0xd5, 0xf8, 0x53, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - }, - { - /* Valid if x overflow ignored (x = 1 mod p). */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x30, - 0x42, 0x18, 0xf2, 0x0a, 0xe6, 0xc6, 0x46, 0xb3, 0x63, 0xdb, 0x68, 0x60, 0x58, 0x22, 0xfb, 0x14, - 0x26, 0x4c, 0xa8, 0xd2, 0x58, 0x7f, 0xdd, 0x6f, 0xbc, 0x75, 0x0d, 0x58, 0x7e, 0x76, 0xa7, 0xee, - }, - { - /* Valid if x overflow ignored (x = 1 mod p). */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x30, - 0xbd, 0xe7, 0x0d, 0xf5, 0x19, 0x39, 0xb9, 0x4c, 0x9c, 0x24, 0x97, 0x9f, 0xa7, 0xdd, 0x04, 0xeb, - 0xd9, 0xb3, 0x57, 0x2d, 0xa7, 0x80, 0x22, 0x90, 0x43, 0x8a, 0xf2, 0xa6, 0x81, 0x89, 0x54, 0x41, - }, - { - /* x is -1, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 5. */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2e, - 0xf4, 0x84, 0x14, 0x5c, 0xb0, 0x14, 0x9b, 0x82, 0x5d, 0xff, 0x41, 0x2f, 0xa0, 0x52, 0xa8, 0x3f, - 0xcb, 0x72, 0xdb, 0x61, 0xd5, 0x6f, 0x37, 0x70, 0xce, 0x06, 0x6b, 0x73, 0x49, 0xa2, 0xaa, 0x28, - }, - { - /* x is -1, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 5. */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2e, - 0x0b, 0x7b, 0xeb, 0xa3, 0x4f, 0xeb, 0x64, 0x7d, 0xa2, 0x00, 0xbe, 0xd0, 0x5f, 0xad, 0x57, 0xc0, - 0x34, 0x8d, 0x24, 0x9e, 0x2a, 0x90, 0xc8, 0x8f, 0x31, 0xf9, 0x94, 0x8b, 0xb6, 0x5d, 0x52, 0x07, - }, - { - /* x is zero, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 7. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x8f, 0x53, 0x7e, 0xef, 0xdf, 0xc1, 0x60, 0x6a, 0x07, 0x27, 0xcd, 0x69, 0xb4, 0xa7, 0x33, 0x3d, - 0x38, 0xed, 0x44, 0xe3, 0x93, 0x2a, 0x71, 0x79, 0xee, 0xcb, 0x4b, 0x6f, 0xba, 0x93, 0x60, 0xdc, - }, - { - /* x is zero, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 7. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x70, 0xac, 0x81, 0x10, 0x20, 0x3e, 0x9f, 0x95, 0xf8, 0xd8, 0x32, 0x96, 0x4b, 0x58, 0xcc, 0xc2, - 0xc7, 0x12, 0xbb, 0x1c, 0x6c, 0xd5, 0x8e, 0x86, 0x11, 0x34, 0xb4, 0x8f, 0x45, 0x6c, 0x9b, 0x53 - } - }; - const unsigned char pubkeyc[66] = { - /* Serialization of G. */ - 0x04, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, - 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, - 0x98, 0x48, 0x3A, 0xDA, 0x77, 0x26, 0xA3, 0xC4, 0x65, 0x5D, 0xA4, 0xFB, 0xFC, 0x0E, 0x11, 0x08, - 0xA8, 0xFD, 0x17, 0xB4, 0x48, 0xA6, 0x85, 0x54, 0x19, 0x9C, 0x47, 0xD0, 0x8F, 0xFB, 0x10, 0xD4, - 0xB8, 0x00 - }; - unsigned char sout[65]; - unsigned char shortkey[2]; - secp256k1_ge ge; - secp256k1_pubkey pubkey; - size_t len; - int32_t i; - int32_t ecount; - int32_t ecount2; - ecount = 0; - /* Nothing should be reading this far into pubkeyc. */ - VG_UNDEF(&pubkeyc[65], 1); - secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); - /* Zero length claimed, fail, zeroize, no illegal arg error. */ - memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; - VG_UNDEF(shortkey, 2); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, shortkey, 0) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 1); - /* Length one claimed, fail, zeroize, no illegal arg error. */ - for (i = 0; i < 256 ; i++) { - memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; - shortkey[0] = i; - VG_UNDEF(&shortkey[1], 1); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, shortkey, 1) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 1); - } - /* Length two claimed, fail, zeroize, no illegal arg error. */ - for (i = 0; i < 65536 ; i++) { - memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; - shortkey[0] = i & 255; - shortkey[1] = i >> 8; - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, shortkey, 2) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 1); - } - memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; - VG_UNDEF(&pubkey, sizeof(pubkey)); - /* 33 bytes claimed on otherwise valid input starting with 0x04, fail, zeroize output, no illegal arg error. */ - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 33) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 1); - /* NULL pubkey, illegal arg error. Pubkey isn't rewritten before this step, since it's NULL into the parser. */ - CHECK(secp256k1_ec_pubkey_parse(ctx, NULL, pubkeyc, 65) == 0); - CHECK(ecount == 2); - /* NULL input string. Illegal arg and zeroize output. */ - memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, NULL, 65) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 1); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 2); - /* 64 bytes claimed on input starting with 0x04, fail, zeroize output, no illegal arg error. */ - memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 64) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 1); - /* 66 bytes claimed, fail, zeroize output, no illegal arg error. */ - memset(&pubkey, 0xfe, sizeof(pubkey)); - ecount = 0; - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 66) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); - CHECK(ecount == 1); - /* Valid parse. */ - memset(&pubkey, 0, sizeof(pubkey)); - ecount = 0; - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 65) == 1); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(ecount == 0); - VG_UNDEF(&ge, sizeof(ge)); - CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 1); - VG_CHECK(&ge.x, sizeof(ge.x)); - VG_CHECK(&ge.y, sizeof(ge.y)); - VG_CHECK(&ge.infinity, sizeof(ge.infinity)); - ge_equals_ge(&secp256k1_ge_const_g, &ge); - CHECK(ecount == 0); - /* secp256k1_ec_pubkey_serialize illegal args. */ - ecount = 0; - len = 65; - CHECK(secp256k1_ec_pubkey_serialize(ctx, NULL, &len, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 0); - CHECK(ecount == 1); - CHECK(len == 0); - CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, NULL, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 0); - CHECK(ecount == 2); - len = 65; - VG_UNDEF(sout, 65); - CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, &len, NULL, SECP256K1_EC_UNCOMPRESSED) == 0); - VG_CHECK(sout, 65); - CHECK(ecount == 3); - CHECK(len == 0); - len = 65; - CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, &len, &pubkey, ~0) == 0); - CHECK(ecount == 4); - CHECK(len == 0); - len = 65; - VG_UNDEF(sout, 65); - CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, &len, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 1); - VG_CHECK(sout, 65); - CHECK(ecount == 4); - CHECK(len == 65); - /* Multiple illegal args. Should still set arg error only once. */ - ecount = 0; - ecount2 = 11; - CHECK(secp256k1_ec_pubkey_parse(ctx, NULL, NULL, 65) == 0); - CHECK(ecount == 1); - /* Does the illegal arg callback actually change the behavior? */ - secp256k1_context_set_illegal_callback(ctx, uncounting_illegal_callback_fn, &ecount2); - CHECK(secp256k1_ec_pubkey_parse(ctx, NULL, NULL, 65) == 0); - CHECK(ecount == 1); - CHECK(ecount2 == 10); - secp256k1_context_set_illegal_callback(ctx, NULL, NULL); - /* Try a bunch of prefabbed points with all possible encodings. */ - for (i = 0; i < SECP256K1_EC_PARSE_TEST_NVALID; i++) { - ec_pubkey_parse_pointtest(valid[i], 1, 1); - } - for (i = 0; i < SECP256K1_EC_PARSE_TEST_NXVALID; i++) { - ec_pubkey_parse_pointtest(onlyxvalid[i], 1, 0); - } - for (i = 0; i < SECP256K1_EC_PARSE_TEST_NINVALID; i++) { - ec_pubkey_parse_pointtest(invalid[i], 0, 0); - } -} - -void run_eckey_edge_case_test(void) { - const unsigned char orderc[32] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, - 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41 - }; - const unsigned char zeros[sizeof(secp256k1_pubkey)] = {0x00}; - unsigned char ctmp[33]; - unsigned char ctmp2[33]; - secp256k1_pubkey pubkey; - secp256k1_pubkey pubkey2; - secp256k1_pubkey pubkey_one; - secp256k1_pubkey pubkey_negone; - const secp256k1_pubkey *pubkeys[3]; - size_t len; - int32_t ecount; - /* Group order is too large, reject. */ - CHECK(secp256k1_ec_seckey_verify(ctx, orderc) == 0); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, orderc) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); - /* Maximum value is too large, reject. */ - memset(ctmp, 255, 32); - CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 0); - memset(&pubkey, 1, sizeof(pubkey)); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); - /* Zero is too small, reject. */ - memset(ctmp, 0, 32); - CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 0); - memset(&pubkey, 1, sizeof(pubkey)); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); - /* One must be accepted. */ - ctmp[31] = 0x01; - CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 1); - memset(&pubkey, 0, sizeof(pubkey)); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 1); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); - pubkey_one = pubkey; - /* Group order + 1 is too large, reject. */ - memcpy(ctmp, orderc, 32); - ctmp[31] = 0x42; - CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 0); - memset(&pubkey, 1, sizeof(pubkey)); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 0); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); - /* -1 must be accepted. */ - ctmp[31] = 0x40; - CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 1); - memset(&pubkey, 0, sizeof(pubkey)); - VG_UNDEF(&pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 1); - VG_CHECK(&pubkey, sizeof(pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); - pubkey_negone = pubkey; - /* Tweak of zero leaves the value changed. */ - memset(ctmp2, 0, 32); - CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp, ctmp2) == 1); - CHECK(memcmp(orderc, ctmp, 31) == 0 && ctmp[31] == 0x40); - memcpy(&pubkey2, &pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 1); - CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); - /* Multiply tweak of zero zeroizes the output. */ - CHECK(secp256k1_ec_privkey_tweak_mul(ctx, ctmp, ctmp2) == 0); - CHECK(memcmp(zeros, ctmp, 32) == 0); - CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, ctmp2) == 0); - CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); - memcpy(&pubkey, &pubkey2, sizeof(pubkey)); - /* Overflowing key tweak zeroizes. */ - memcpy(ctmp, orderc, 32); - ctmp[31] = 0x40; - CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp, orderc) == 0); - CHECK(memcmp(zeros, ctmp, 32) == 0); - memcpy(ctmp, orderc, 32); - ctmp[31] = 0x40; - CHECK(secp256k1_ec_privkey_tweak_mul(ctx, ctmp, orderc) == 0); - CHECK(memcmp(zeros, ctmp, 32) == 0); - memcpy(ctmp, orderc, 32); - ctmp[31] = 0x40; - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, orderc) == 0); - CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); - memcpy(&pubkey, &pubkey2, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, orderc) == 0); - CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); - memcpy(&pubkey, &pubkey2, sizeof(pubkey)); - /* Private key tweaks results in a key of zero. */ - ctmp2[31] = 1; - CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp2, ctmp) == 0); - CHECK(memcmp(zeros, ctmp2, 32) == 0); - ctmp2[31] = 1; - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 0); - CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); - memcpy(&pubkey, &pubkey2, sizeof(pubkey)); - /* Tweak computation wraps and results in a key of 1. */ - ctmp2[31] = 2; - CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp2, ctmp) == 1); - CHECK(memcmp(ctmp2, zeros, 31) == 0 && ctmp2[31] == 1); - ctmp2[31] = 2; - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 1); - ctmp2[31] = 1; - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey2, ctmp2) == 1); - CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); - /* Tweak mul * 2 = 1+1. */ - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 1); - ctmp2[31] = 2; - CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey2, ctmp2) == 1); - CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); - /* Test argument errors. */ - ecount = 0; - secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); - CHECK(ecount == 0); - /* Zeroize pubkey on parse error. */ - memset(&pubkey, 0, 32); - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 0); - CHECK(ecount == 1); - CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); - memcpy(&pubkey, &pubkey2, sizeof(pubkey)); - memset(&pubkey2, 0, 32); - CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey2, ctmp2) == 0); - CHECK(ecount == 2); - CHECK(memcmp(&pubkey2, zeros, sizeof(pubkey2)) == 0); - /* Plain argument errors. */ - ecount = 0; - CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 1); - CHECK(ecount == 0); - CHECK(secp256k1_ec_seckey_verify(ctx, NULL) == 0); - CHECK(ecount == 1); - ecount = 0; - memset(ctmp2, 0, 32); - ctmp2[31] = 4; - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, NULL, ctmp2) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, NULL) == 0); - CHECK(ecount == 2); - ecount = 0; - memset(ctmp2, 0, 32); - ctmp2[31] = 4; - CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, NULL, ctmp2) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, NULL) == 0); - CHECK(ecount == 2); - ecount = 0; - memset(ctmp2, 0, 32); - CHECK(secp256k1_ec_privkey_tweak_add(ctx, NULL, ctmp2) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp, NULL) == 0); - CHECK(ecount == 2); - ecount = 0; - memset(ctmp2, 0, 32); - ctmp2[31] = 1; - CHECK(secp256k1_ec_privkey_tweak_mul(ctx, NULL, ctmp2) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ec_privkey_tweak_mul(ctx, ctmp, NULL) == 0); - CHECK(ecount == 2); - ecount = 0; - CHECK(secp256k1_ec_pubkey_create(ctx, NULL, ctmp) == 0); - CHECK(ecount == 1); - memset(&pubkey, 1, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, NULL) == 0); - CHECK(ecount == 2); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); - /* secp256k1_ec_pubkey_combine tests. */ - ecount = 0; - pubkeys[0] = &pubkey_one; - VG_UNDEF(&pubkeys[0], sizeof(secp256k1_pubkey *)); - VG_UNDEF(&pubkeys[1], sizeof(secp256k1_pubkey *)); - VG_UNDEF(&pubkeys[2], sizeof(secp256k1_pubkey *)); - memset(&pubkey, 255, sizeof(secp256k1_pubkey)); - VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 0) == 0); - VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ec_pubkey_combine(ctx, NULL, pubkeys, 1) == 0); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); - CHECK(ecount == 2); - memset(&pubkey, 255, sizeof(secp256k1_pubkey)); - VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, NULL, 1) == 0); - VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); - CHECK(ecount == 3); - pubkeys[0] = &pubkey_negone; - memset(&pubkey, 255, sizeof(secp256k1_pubkey)); - VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 1) == 1); - VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); - CHECK(ecount == 3); - len = 33; - CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp, &len, &pubkey, SECP256K1_EC_COMPRESSED) == 1); - CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp2, &len, &pubkey_negone, SECP256K1_EC_COMPRESSED) == 1); - CHECK(memcmp(ctmp, ctmp2, 33) == 0); - /* Result is infinity. */ - pubkeys[0] = &pubkey_one; - pubkeys[1] = &pubkey_negone; - memset(&pubkey, 255, sizeof(secp256k1_pubkey)); - VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 2) == 0); - VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); - CHECK(ecount == 3); - /* Passes through infinity but comes out one. */ - pubkeys[2] = &pubkey_one; - memset(&pubkey, 255, sizeof(secp256k1_pubkey)); - VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 3) == 1); - VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); - CHECK(ecount == 3); - len = 33; - CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp, &len, &pubkey, SECP256K1_EC_COMPRESSED) == 1); - CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp2, &len, &pubkey_one, SECP256K1_EC_COMPRESSED) == 1); - CHECK(memcmp(ctmp, ctmp2, 33) == 0); - /* Adds to two. */ - pubkeys[1] = &pubkey_one; - memset(&pubkey, 255, sizeof(secp256k1_pubkey)); - VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 2) == 1); - VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); - CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); - CHECK(ecount == 3); - secp256k1_context_set_illegal_callback(ctx, NULL, NULL); -} - -void random_sign(secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *key, const secp256k1_scalar *msg, int *recid) { - secp256k1_scalar nonce; - do { - random_scalar_order_test(&nonce); - } while(!secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, sigr, sigs, key, msg, &nonce, recid)); -} - -void test_ecdsa_sign_verify(void) { - secp256k1_gej pubj; - secp256k1_ge pub; - secp256k1_scalar one; - secp256k1_scalar msg, key; - secp256k1_scalar sigr, sigs; - int recid; - int getrec; - random_scalar_order_test(&msg); - random_scalar_order_test(&key); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubj, &key); - secp256k1_ge_set_gej(&pub, &pubj); - getrec = secp256k1_rand_bits(1); - random_sign(&sigr, &sigs, &key, &msg, getrec?&recid:NULL); - if (getrec) { - CHECK(recid >= 0 && recid < 4); - } - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &pub, &msg)); - secp256k1_scalar_set_int(&one, 1); - secp256k1_scalar_add(&msg, &msg, &one); - CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &pub, &msg)); -} - -void run_ecdsa_sign_verify(void) { - int i; - for (i = 0; i < 10*count; i++) { - test_ecdsa_sign_verify(); - } -} - -/** Dummy nonce generation function that just uses a precomputed nonce, and fails if it is not accepted. Use only for testing. */ -static int precomputed_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { - (void)msg32; - (void)key32; - (void)algo16; - memcpy(nonce32, data, 32); - return (counter == 0); -} - -static int nonce_function_test_fail(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { - /* Dummy nonce generator that has a fatal error on the first counter value. */ - if (counter == 0) { - return 0; - } - return nonce_function_rfc6979(nonce32, msg32, key32, algo16, data, counter - 1); -} - -static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { - /* Dummy nonce generator that produces unacceptable nonces for the first several counter values. */ - if (counter < 3) { - memset(nonce32, counter==0 ? 0 : 255, 32); - if (counter == 2) { - nonce32[31]--; - } - return 1; - } - if (counter < 5) { - static const unsigned char order[] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, - 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, - 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 - }; - memcpy(nonce32, order, 32); - if (counter == 4) { - nonce32[31]++; - } - return 1; - } - /* Retry rate of 6979 is negligible esp. as we only call this in deterministic tests. */ - /* If someone does fine a case where it retries for secp256k1, we'd like to know. */ - if (counter > 5) { - return 0; - } - return nonce_function_rfc6979(nonce32, msg32, key32, algo16, data, counter - 5); -} - -int is_empty_signature(const secp256k1_ecdsa_signature *sig) { - static const unsigned char res[sizeof(secp256k1_ecdsa_signature)] = {0}; - return memcmp(sig, res, sizeof(secp256k1_ecdsa_signature)) == 0; -} - -void test_ecdsa_end_to_end(void) { - unsigned char extra[32] = {0x00}; - unsigned char privkey[32]; - unsigned char message[32]; - unsigned char privkey2[32]; - secp256k1_ecdsa_signature signature[6]; - secp256k1_scalar r, s; - unsigned char sig[74]; - size_t siglen = 74; - unsigned char pubkeyc[65]; - size_t pubkeyclen = 65; - secp256k1_pubkey pubkey; - secp256k1_pubkey pubkey_tmp; - unsigned char seckey[300]; - size_t seckeylen = 300; - - /* Generate a random key and message. */ - { - secp256k1_scalar msg, key; - random_scalar_order_test(&msg); - random_scalar_order_test(&key); - secp256k1_scalar_get_b32(privkey, &key); - secp256k1_scalar_get_b32(message, &msg); - } - - /* Construct and verify corresponding public key. */ - CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); - - /* Verify exporting and importing public key. */ - CHECK(secp256k1_ec_pubkey_serialize(ctx, pubkeyc, &pubkeyclen, &pubkey, secp256k1_rand_bits(1) == 1 ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED)); - memset(&pubkey, 0, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 1); - - /* Verify negation changes the key and changes it back */ - memcpy(&pubkey_tmp, &pubkey, sizeof(pubkey)); - CHECK(secp256k1_ec_pubkey_negate(ctx, &pubkey_tmp) == 1); - CHECK(memcmp(&pubkey_tmp, &pubkey, sizeof(pubkey)) != 0); - CHECK(secp256k1_ec_pubkey_negate(ctx, &pubkey_tmp) == 1); - CHECK(memcmp(&pubkey_tmp, &pubkey, sizeof(pubkey)) == 0); - - /* Verify private key import and export. */ - CHECK(ec_privkey_export_der(ctx, seckey, &seckeylen, privkey, secp256k1_rand_bits(1) == 1)); - CHECK(ec_privkey_import_der(ctx, privkey2, seckey, seckeylen) == 1); - CHECK(memcmp(privkey, privkey2, 32) == 0); - - /* Optionally tweak the keys using addition. */ - if (secp256k1_rand_int(3) == 0) { - int ret1; - int ret2; - unsigned char rnd[32]; - secp256k1_pubkey pubkey2; - secp256k1_rand256_test(rnd); - ret1 = secp256k1_ec_privkey_tweak_add(ctx, privkey, rnd); - ret2 = secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, rnd); - CHECK(ret1 == ret2); - if (ret1 == 0) { - return; - } - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey2, privkey) == 1); - CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); - } - - /* Optionally tweak the keys using multiplication. */ - if (secp256k1_rand_int(3) == 0) { - int ret1; - int ret2; - unsigned char rnd[32]; - secp256k1_pubkey pubkey2; - secp256k1_rand256_test(rnd); - ret1 = secp256k1_ec_privkey_tweak_mul(ctx, privkey, rnd); - ret2 = secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, rnd); - CHECK(ret1 == ret2); - if (ret1 == 0) { - return; - } - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey2, privkey) == 1); - CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); - } - - /* Sign. */ - CHECK(secp256k1_ecdsa_sign(ctx, &signature[0], message, privkey, NULL, NULL) == 1); - CHECK(secp256k1_ecdsa_sign(ctx, &signature[4], message, privkey, NULL, NULL) == 1); - CHECK(secp256k1_ecdsa_sign(ctx, &signature[1], message, privkey, NULL, extra) == 1); - extra[31] = 1; - CHECK(secp256k1_ecdsa_sign(ctx, &signature[2], message, privkey, NULL, extra) == 1); - extra[31] = 0; - extra[0] = 1; - CHECK(secp256k1_ecdsa_sign(ctx, &signature[3], message, privkey, NULL, extra) == 1); - CHECK(memcmp(&signature[0], &signature[4], sizeof(signature[0])) == 0); - CHECK(memcmp(&signature[0], &signature[1], sizeof(signature[0])) != 0); - CHECK(memcmp(&signature[0], &signature[2], sizeof(signature[0])) != 0); - CHECK(memcmp(&signature[0], &signature[3], sizeof(signature[0])) != 0); - CHECK(memcmp(&signature[1], &signature[2], sizeof(signature[0])) != 0); - CHECK(memcmp(&signature[1], &signature[3], sizeof(signature[0])) != 0); - CHECK(memcmp(&signature[2], &signature[3], sizeof(signature[0])) != 0); - /* Verify. */ - CHECK(secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[1], message, &pubkey) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[2], message, &pubkey) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[3], message, &pubkey) == 1); - /* Test lower-S form, malleate, verify and fail, test again, malleate again */ - CHECK(!secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[0])); - secp256k1_ecdsa_signature_load(ctx, &r, &s, &signature[0]); - secp256k1_scalar_negate(&s, &s); - secp256k1_ecdsa_signature_save(&signature[5], &r, &s); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[5], message, &pubkey) == 0); - CHECK(secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[5])); - CHECK(secp256k1_ecdsa_signature_normalize(ctx, &signature[5], &signature[5])); - CHECK(!secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[5])); - CHECK(!secp256k1_ecdsa_signature_normalize(ctx, &signature[5], &signature[5])); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[5], message, &pubkey) == 1); - secp256k1_scalar_negate(&s, &s); - secp256k1_ecdsa_signature_save(&signature[5], &r, &s); - CHECK(!secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[5])); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[5], message, &pubkey) == 1); - CHECK(memcmp(&signature[5], &signature[0], 64) == 0); - - /* Serialize/parse DER and verify again */ - CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature[0]) == 1); - memset(&signature[0], 0, sizeof(signature[0])); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &signature[0], sig, siglen) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 1); - /* Serialize/destroy/parse DER and verify again. */ - siglen = 74; - CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature[0]) == 1); - sig[secp256k1_rand_int(siglen)] += 1 + secp256k1_rand_int(255); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &signature[0], sig, siglen) == 0 || - secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 0); -} - -void test_random_pubkeys(void) { - secp256k1_ge elem; - secp256k1_ge elem2; - unsigned char in[65]; - /* Generate some randomly sized pubkeys. */ - size_t len = secp256k1_rand_bits(2) == 0 ? 65 : 33; - if (secp256k1_rand_bits(2) == 0) { - len = secp256k1_rand_bits(6); - } - if (len == 65) { - in[0] = secp256k1_rand_bits(1) ? 4 : (secp256k1_rand_bits(1) ? 6 : 7); - } else { - in[0] = secp256k1_rand_bits(1) ? 2 : 3; - } - if (secp256k1_rand_bits(3) == 0) { - in[0] = secp256k1_rand_bits(8); - } - if (len > 1) { - secp256k1_rand256(&in[1]); - } - if (len > 33) { - secp256k1_rand256(&in[33]); - } - if (secp256k1_eckey_pubkey_parse(&elem, in, len)) { - unsigned char out[65]; - unsigned char firstb; - int res; - size_t size = len; - firstb = in[0]; - /* If the pubkey can be parsed, it should round-trip... */ - CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, len == 33)); - CHECK(size == len); - CHECK(memcmp(&in[1], &out[1], len-1) == 0); - /* ... except for the type of hybrid inputs. */ - if ((in[0] != 6) && (in[0] != 7)) { - CHECK(in[0] == out[0]); - } - size = 65; - CHECK(secp256k1_eckey_pubkey_serialize(&elem, in, &size, 0)); - CHECK(size == 65); - CHECK(secp256k1_eckey_pubkey_parse(&elem2, in, size)); - ge_equals_ge(&elem,&elem2); - /* Check that the X9.62 hybrid type is checked. */ - in[0] = secp256k1_rand_bits(1) ? 6 : 7; - res = secp256k1_eckey_pubkey_parse(&elem2, in, size); - if (firstb == 2 || firstb == 3) { - if (in[0] == firstb + 4) { - CHECK(res); - } else { - CHECK(!res); - } - } - if (res) { - ge_equals_ge(&elem,&elem2); - CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, 0)); - CHECK(memcmp(&in[1], &out[1], 64) == 0); - } - } -} - -void run_random_pubkeys(void) { - int i; - for (i = 0; i < 10*count; i++) { - test_random_pubkeys(); - } -} - -void run_ecdsa_end_to_end(void) { - int i; - for (i = 0; i < 64*count; i++) { - test_ecdsa_end_to_end(); - } -} - -int test_ecdsa_der_parse(const unsigned char *sig, size_t siglen, int certainly_der, int certainly_not_der) { - static const unsigned char zeroes[32] = {0}; -#ifdef ENABLE_OPENSSL_TESTS - static const unsigned char max_scalar[32] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, - 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40 - }; -#endif - - int ret = 0; - - secp256k1_ecdsa_signature sig_der; - unsigned char roundtrip_der[2048]; - unsigned char compact_der[64]; - size_t len_der = 2048; - int parsed_der = 0, valid_der = 0, roundtrips_der = 0; - - secp256k1_ecdsa_signature sig_der_lax; - unsigned char roundtrip_der_lax[2048]; - unsigned char compact_der_lax[64]; - size_t len_der_lax = 2048; - int parsed_der_lax = 0, valid_der_lax = 0, roundtrips_der_lax = 0; - -#ifdef ENABLE_OPENSSL_TESTS - ECDSA_SIG *sig_openssl; - const unsigned char *sigptr; - unsigned char roundtrip_openssl[2048]; - int len_openssl = 2048; - int parsed_openssl, valid_openssl = 0, roundtrips_openssl = 0; -#endif - - parsed_der = secp256k1_ecdsa_signature_parse_der(ctx, &sig_der, sig, siglen); - if (parsed_der) { - ret |= (!secp256k1_ecdsa_signature_serialize_compact(ctx, compact_der, &sig_der)) << 0; - valid_der = (memcmp(compact_der, zeroes, 32) != 0) && (memcmp(compact_der + 32, zeroes, 32) != 0); - } - if (valid_der) { - ret |= (!secp256k1_ecdsa_signature_serialize_der(ctx, roundtrip_der, &len_der, &sig_der)) << 1; - roundtrips_der = (len_der == siglen) && memcmp(roundtrip_der, sig, siglen) == 0; - } - - parsed_der_lax = ecdsa_signature_parse_der_lax(ctx, &sig_der_lax, sig, siglen); - if (parsed_der_lax) { - ret |= (!secp256k1_ecdsa_signature_serialize_compact(ctx, compact_der_lax, &sig_der_lax)) << 10; - valid_der_lax = (memcmp(compact_der_lax, zeroes, 32) != 0) && (memcmp(compact_der_lax + 32, zeroes, 32) != 0); - } - if (valid_der_lax) { - ret |= (!secp256k1_ecdsa_signature_serialize_der(ctx, roundtrip_der_lax, &len_der_lax, &sig_der_lax)) << 11; - roundtrips_der_lax = (len_der_lax == siglen) && memcmp(roundtrip_der_lax, sig, siglen) == 0; - } - - if (certainly_der) { - ret |= (!parsed_der) << 2; - } - if (certainly_not_der) { - ret |= (parsed_der) << 17; - } - if (valid_der) { - ret |= (!roundtrips_der) << 3; - } - - if (valid_der) { - ret |= (!roundtrips_der_lax) << 12; - ret |= (len_der != len_der_lax) << 13; - ret |= (memcmp(roundtrip_der_lax, roundtrip_der, len_der) != 0) << 14; - } - ret |= (roundtrips_der != roundtrips_der_lax) << 15; - if (parsed_der) { - ret |= (!parsed_der_lax) << 16; - } - -#ifdef ENABLE_OPENSSL_TESTS - sig_openssl = ECDSA_SIG_new(); - sigptr = sig; - parsed_openssl = (d2i_ECDSA_SIG(&sig_openssl, &sigptr, siglen) != NULL); - if (parsed_openssl) { - valid_openssl = !BN_is_negative(sig_openssl->r) && !BN_is_negative(sig_openssl->s) && BN_num_bits(sig_openssl->r) > 0 && BN_num_bits(sig_openssl->r) <= 256 && BN_num_bits(sig_openssl->s) > 0 && BN_num_bits(sig_openssl->s) <= 256; - if (valid_openssl) { - unsigned char tmp[32] = {0}; - BN_bn2bin(sig_openssl->r, tmp + 32 - BN_num_bytes(sig_openssl->r)); - valid_openssl = memcmp(tmp, max_scalar, 32) < 0; - } - if (valid_openssl) { - unsigned char tmp[32] = {0}; - BN_bn2bin(sig_openssl->s, tmp + 32 - BN_num_bytes(sig_openssl->s)); - valid_openssl = memcmp(tmp, max_scalar, 32) < 0; - } - } - len_openssl = i2d_ECDSA_SIG(sig_openssl, NULL); - if (len_openssl <= 2048) { - unsigned char *ptr = roundtrip_openssl; - CHECK(i2d_ECDSA_SIG(sig_openssl, &ptr) == len_openssl); - roundtrips_openssl = valid_openssl && ((size_t)len_openssl == siglen) && (memcmp(roundtrip_openssl, sig, siglen) == 0); - } else { - len_openssl = 0; - } - ECDSA_SIG_free(sig_openssl); - - ret |= (parsed_der && !parsed_openssl) << 4; - ret |= (valid_der && !valid_openssl) << 5; - ret |= (roundtrips_openssl && !parsed_der) << 6; - ret |= (roundtrips_der != roundtrips_openssl) << 7; - if (roundtrips_openssl) { - ret |= (len_der != (size_t)len_openssl) << 8; - ret |= (memcmp(roundtrip_der, roundtrip_openssl, len_der) != 0) << 9; - } -#endif - return ret; -} - -static void assign_big_endian(unsigned char *ptr, size_t ptrlen, uint32_t val) { - size_t i; - for (i = 0; i < ptrlen; i++) { - int shift = ptrlen - 1 - i; - if (shift >= 4) { - ptr[i] = 0; - } else { - ptr[i] = (val >> shift) & 0xFF; - } - } -} - -static void damage_array(unsigned char *sig, size_t *len) { - int pos; - int action = secp256k1_rand_bits(3); - if (action < 1 && *len > 3) { - /* Delete a byte. */ - pos = secp256k1_rand_int(*len); - memmove(sig + pos, sig + pos + 1, *len - pos - 1); - (*len)--; - return; - } else if (action < 2 && *len < 2048) { - /* Insert a byte. */ - pos = secp256k1_rand_int(1 + *len); - memmove(sig + pos + 1, sig + pos, *len - pos); - sig[pos] = secp256k1_rand_bits(8); - (*len)++; - return; - } else if (action < 4) { - /* Modify a byte. */ - sig[secp256k1_rand_int(*len)] += 1 + secp256k1_rand_int(255); - return; - } else { /* action < 8 */ - /* Modify a bit. */ - sig[secp256k1_rand_int(*len)] ^= 1 << secp256k1_rand_bits(3); - return; - } -} - -static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly_der, int* certainly_not_der) { - int der; - int nlow[2], nlen[2], nlenlen[2], nhbit[2], nhbyte[2], nzlen[2]; - size_t tlen, elen, glen; - int indet; - int n; - - *len = 0; - der = secp256k1_rand_bits(2) == 0; - *certainly_der = der; - *certainly_not_der = 0; - indet = der ? 0 : secp256k1_rand_int(10) == 0; - - for (n = 0; n < 2; n++) { - /* We generate two classes of numbers: nlow==1 "low" ones (up to 32 bytes), nlow==0 "high" ones (32 bytes with 129 top bits set, or larger than 32 bytes) */ - nlow[n] = der ? 1 : (secp256k1_rand_bits(3) != 0); - /* The length of the number in bytes (the first byte of which will always be nonzero) */ - nlen[n] = nlow[n] ? secp256k1_rand_int(33) : 32 + secp256k1_rand_int(200) * secp256k1_rand_int(8) / 8; - CHECK(nlen[n] <= 232); - /* The top bit of the number. */ - nhbit[n] = (nlow[n] == 0 && nlen[n] == 32) ? 1 : (nlen[n] == 0 ? 0 : secp256k1_rand_bits(1)); - /* The top byte of the number (after the potential hardcoded 16 0xFF characters for "high" 32 bytes numbers) */ - nhbyte[n] = nlen[n] == 0 ? 0 : (nhbit[n] ? 128 + secp256k1_rand_bits(7) : 1 + secp256k1_rand_int(127)); - /* The number of zero bytes in front of the number (which is 0 or 1 in case of DER, otherwise we extend up to 300 bytes) */ - nzlen[n] = der ? ((nlen[n] == 0 || nhbit[n]) ? 1 : 0) : (nlow[n] ? secp256k1_rand_int(3) : secp256k1_rand_int(300 - nlen[n]) * secp256k1_rand_int(8) / 8); - if (nzlen[n] > ((nlen[n] == 0 || nhbit[n]) ? 1 : 0)) { - *certainly_not_der = 1; - } - CHECK(nlen[n] + nzlen[n] <= 300); - /* The length of the length descriptor for the number. 0 means short encoding, anything else is long encoding. */ - nlenlen[n] = nlen[n] + nzlen[n] < 128 ? 0 : (nlen[n] + nzlen[n] < 256 ? 1 : 2); - if (!der) { - /* nlenlen[n] max 127 bytes */ - int add = secp256k1_rand_int(127 - nlenlen[n]) * secp256k1_rand_int(16) * secp256k1_rand_int(16) / 256; - nlenlen[n] += add; - if (add != 0) { - *certainly_not_der = 1; - } - } - CHECK(nlen[n] + nzlen[n] + nlenlen[n] <= 427); - } - - /* The total length of the data to go, so far */ - tlen = 2 + nlenlen[0] + nlen[0] + nzlen[0] + 2 + nlenlen[1] + nlen[1] + nzlen[1]; - CHECK(tlen <= 856); - - /* The length of the garbage inside the tuple. */ - elen = (der || indet) ? 0 : secp256k1_rand_int(980 - tlen) * secp256k1_rand_int(8) / 8; - if (elen != 0) { - *certainly_not_der = 1; - } - tlen += elen; - CHECK(tlen <= 980); - - /* The length of the garbage after the end of the tuple. */ - glen = der ? 0 : secp256k1_rand_int(990 - tlen) * secp256k1_rand_int(8) / 8; - if (glen != 0) { - *certainly_not_der = 1; - } - CHECK(tlen + glen <= 990); - - /* Write the tuple header. */ - sig[(*len)++] = 0x30; - if (indet) { - /* Indeterminate length */ - sig[(*len)++] = 0x80; - *certainly_not_der = 1; - } else { - int tlenlen = tlen < 128 ? 0 : (tlen < 256 ? 1 : 2); - if (!der) { - int add = secp256k1_rand_int(127 - tlenlen) * secp256k1_rand_int(16) * secp256k1_rand_int(16) / 256; - tlenlen += add; - if (add != 0) { - *certainly_not_der = 1; - } - } - if (tlenlen == 0) { - /* Short length notation */ - sig[(*len)++] = tlen; - } else { - /* Long length notation */ - sig[(*len)++] = 128 + tlenlen; - assign_big_endian(sig + *len, tlenlen, tlen); - *len += tlenlen; - } - tlen += tlenlen; - } - tlen += 2; - CHECK(tlen + glen <= 1119); - - for (n = 0; n < 2; n++) { - /* Write the integer header. */ - sig[(*len)++] = 0x02; - if (nlenlen[n] == 0) { - /* Short length notation */ - sig[(*len)++] = nlen[n] + nzlen[n]; - } else { - /* Long length notation. */ - sig[(*len)++] = 128 + nlenlen[n]; - assign_big_endian(sig + *len, nlenlen[n], nlen[n] + nzlen[n]); - *len += nlenlen[n]; - } - /* Write zero padding */ - while (nzlen[n] > 0) { - sig[(*len)++] = 0x00; - nzlen[n]--; - } - if (nlen[n] == 32 && !nlow[n]) { - /* Special extra 16 0xFF bytes in "high" 32-byte numbers */ - int i; - for (i = 0; i < 16; i++) { - sig[(*len)++] = 0xFF; - } - nlen[n] -= 16; - } - /* Write first byte of number */ - if (nlen[n] > 0) { - sig[(*len)++] = nhbyte[n]; - nlen[n]--; - } - /* Generate remaining random bytes of number */ - secp256k1_rand_bytes_test(sig + *len, nlen[n]); - *len += nlen[n]; - nlen[n] = 0; - } - - /* Generate random garbage inside tuple. */ - secp256k1_rand_bytes_test(sig + *len, elen); - *len += elen; - - /* Generate end-of-contents bytes. */ - if (indet) { - sig[(*len)++] = 0; - sig[(*len)++] = 0; - tlen += 2; - } - CHECK(tlen + glen <= 1121); - - /* Generate random garbage outside tuple. */ - secp256k1_rand_bytes_test(sig + *len, glen); - *len += glen; - tlen += glen; - CHECK(tlen <= 1121); - CHECK(tlen == *len); -} - -void run_ecdsa_der_parse(void) { - int i,j; - for (i = 0; i < 200 * count; i++) { - unsigned char buffer[2048]; - size_t buflen = 0; - int certainly_der = 0; - int certainly_not_der = 0; - random_ber_signature(buffer, &buflen, &certainly_der, &certainly_not_der); - CHECK(buflen <= 2048); - for (j = 0; j < 16; j++) { - int ret = 0; - if (j > 0) { - damage_array(buffer, &buflen); - /* We don't know anything anymore about the DERness of the result */ - certainly_der = 0; - certainly_not_der = 0; - } - ret = test_ecdsa_der_parse(buffer, buflen, certainly_der, certainly_not_der); - if (ret != 0) { - size_t k; - fprintf(stderr, "Failure %x on ", ret); - for (k = 0; k < buflen; k++) { - fprintf(stderr, "%02x ", buffer[k]); - } - fprintf(stderr, "\n"); - } - CHECK(ret == 0); - } - } -} - -/* Tests several edge cases. */ -void test_ecdsa_edge_cases(void) { - int t; - secp256k1_ecdsa_signature sig; - - /* Test the case where ECDSA recomputes a point that is infinity. */ - { - secp256k1_gej keyj; - secp256k1_ge key; - secp256k1_scalar msg; - secp256k1_scalar sr, ss; - secp256k1_scalar_set_int(&ss, 1); - secp256k1_scalar_negate(&ss, &ss); - secp256k1_scalar_inverse(&ss, &ss); - secp256k1_scalar_set_int(&sr, 1); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &keyj, &sr); - secp256k1_ge_set_gej(&key, &keyj); - msg = ss; - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); - } - - /* Verify signature with r of zero fails. */ - { - const unsigned char pubkey_mods_zero[33] = { - 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, - 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, - 0x41 - }; - secp256k1_ge key; - secp256k1_scalar msg; - secp256k1_scalar sr, ss; - secp256k1_scalar_set_int(&ss, 1); - secp256k1_scalar_set_int(&msg, 0); - secp256k1_scalar_set_int(&sr, 0); - CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey_mods_zero, 33)); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); - } - - /* Verify signature with s of zero fails. */ - { - const unsigned char pubkey[33] = { - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01 - }; - secp256k1_ge key; - secp256k1_scalar msg; - secp256k1_scalar sr, ss; - secp256k1_scalar_set_int(&ss, 0); - secp256k1_scalar_set_int(&msg, 0); - secp256k1_scalar_set_int(&sr, 1); - CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); - } - - /* Verify signature with message 0 passes. */ - { - const unsigned char pubkey[33] = { - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02 - }; - const unsigned char pubkey2[33] = { - 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, - 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, - 0x43 - }; - secp256k1_ge key; - secp256k1_ge key2; - secp256k1_scalar msg; - secp256k1_scalar sr, ss; - secp256k1_scalar_set_int(&ss, 2); - secp256k1_scalar_set_int(&msg, 0); - secp256k1_scalar_set_int(&sr, 2); - CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); - CHECK(secp256k1_eckey_pubkey_parse(&key2, pubkey2, 33)); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); - secp256k1_scalar_negate(&ss, &ss); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); - secp256k1_scalar_set_int(&ss, 1); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 0); - } - - /* Verify signature with message 1 passes. */ - { - const unsigned char pubkey[33] = { - 0x02, 0x14, 0x4e, 0x5a, 0x58, 0xef, 0x5b, 0x22, - 0x6f, 0xd2, 0xe2, 0x07, 0x6a, 0x77, 0xcf, 0x05, - 0xb4, 0x1d, 0xe7, 0x4a, 0x30, 0x98, 0x27, 0x8c, - 0x93, 0xe6, 0xe6, 0x3c, 0x0b, 0xc4, 0x73, 0x76, - 0x25 - }; - const unsigned char pubkey2[33] = { - 0x02, 0x8a, 0xd5, 0x37, 0xed, 0x73, 0xd9, 0x40, - 0x1d, 0xa0, 0x33, 0xd2, 0xdc, 0xf0, 0xaf, 0xae, - 0x34, 0xcf, 0x5f, 0x96, 0x4c, 0x73, 0x28, 0x0f, - 0x92, 0xc0, 0xf6, 0x9d, 0xd9, 0xb2, 0x09, 0x10, - 0x62 - }; - const unsigned char csr[32] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x45, 0x51, 0x23, 0x19, 0x50, 0xb7, 0x5f, 0xc4, - 0x40, 0x2d, 0xa1, 0x72, 0x2f, 0xc9, 0xba, 0xeb - }; - secp256k1_ge key; - secp256k1_ge key2; - secp256k1_scalar msg; - secp256k1_scalar sr, ss; - secp256k1_scalar_set_int(&ss, 1); - secp256k1_scalar_set_int(&msg, 1); - secp256k1_scalar_set_b32(&sr, csr, NULL); - CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); - CHECK(secp256k1_eckey_pubkey_parse(&key2, pubkey2, 33)); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); - secp256k1_scalar_negate(&ss, &ss); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); - secp256k1_scalar_set_int(&ss, 2); - secp256k1_scalar_inverse_var(&ss, &ss); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 0); - } - - /* Verify signature with message -1 passes. */ - { - const unsigned char pubkey[33] = { - 0x03, 0xaf, 0x97, 0xff, 0x7d, 0x3a, 0xf6, 0xa0, - 0x02, 0x94, 0xbd, 0x9f, 0x4b, 0x2e, 0xd7, 0x52, - 0x28, 0xdb, 0x49, 0x2a, 0x65, 0xcb, 0x1e, 0x27, - 0x57, 0x9c, 0xba, 0x74, 0x20, 0xd5, 0x1d, 0x20, - 0xf1 - }; - const unsigned char csr[32] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x45, 0x51, 0x23, 0x19, 0x50, 0xb7, 0x5f, 0xc4, - 0x40, 0x2d, 0xa1, 0x72, 0x2f, 0xc9, 0xba, 0xee - }; - secp256k1_ge key; - secp256k1_scalar msg; - secp256k1_scalar sr, ss; - secp256k1_scalar_set_int(&ss, 1); - secp256k1_scalar_set_int(&msg, 1); - secp256k1_scalar_negate(&msg, &msg); - secp256k1_scalar_set_b32(&sr, csr, NULL); - CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); - secp256k1_scalar_negate(&ss, &ss); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); - secp256k1_scalar_set_int(&ss, 3); - secp256k1_scalar_inverse_var(&ss, &ss); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); - } - - /* Signature where s would be zero. */ - { - secp256k1_pubkey pubkey; - size_t siglen; - int32_t ecount; - unsigned char signature[72]; - static const unsigned char nonce[32] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - }; - static const unsigned char nonce2[32] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, - 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, - 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40 - }; - const unsigned char key[32] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - }; - unsigned char msg[32] = { - 0x86, 0x41, 0x99, 0x81, 0x06, 0x23, 0x44, 0x53, - 0xaa, 0x5f, 0x9d, 0x6a, 0x31, 0x78, 0xf4, 0xf7, - 0xb8, 0x12, 0xe0, 0x0b, 0x81, 0x7a, 0x77, 0x62, - 0x65, 0xdf, 0xdd, 0x31, 0xb9, 0x3e, 0x29, 0xa9, - }; - ecount = 0; - secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce) == 0); - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce2) == 0); - msg[31] = 0xaa; - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce) == 1); - CHECK(ecount == 0); - CHECK(secp256k1_ecdsa_sign(ctx, NULL, msg, key, precomputed_nonce_function, nonce2) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ecdsa_sign(ctx, &sig, NULL, key, precomputed_nonce_function, nonce2) == 0); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, NULL, precomputed_nonce_function, nonce2) == 0); - CHECK(ecount == 3); - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce2) == 1); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, key) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, NULL, msg, &pubkey) == 0); - CHECK(ecount == 4); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, NULL, &pubkey) == 0); - CHECK(ecount == 5); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg, NULL) == 0); - CHECK(ecount == 6); - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg, &pubkey) == 1); - CHECK(ecount == 6); - CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, NULL) == 0); - CHECK(ecount == 7); - /* That pubkeyload fails via an ARGCHECK is a little odd but makes sense because pubkeys are an opaque data type. */ - CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg, &pubkey) == 0); - CHECK(ecount == 8); - siglen = 72; - CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, NULL, &siglen, &sig) == 0); - CHECK(ecount == 9); - CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, NULL, &sig) == 0); - CHECK(ecount == 10); - CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, &siglen, NULL) == 0); - CHECK(ecount == 11); - CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, &siglen, &sig) == 1); - CHECK(ecount == 11); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, NULL, signature, siglen) == 0); - CHECK(ecount == 12); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, NULL, siglen) == 0); - CHECK(ecount == 13); - CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, signature, siglen) == 1); - CHECK(ecount == 13); - siglen = 10; - /* Too little room for a signature does not fail via ARGCHECK. */ - CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, &siglen, &sig) == 0); - CHECK(ecount == 13); - ecount = 0; - CHECK(secp256k1_ecdsa_signature_normalize(ctx, NULL, NULL) == 0); - CHECK(ecount == 1); - CHECK(secp256k1_ecdsa_signature_serialize_compact(ctx, NULL, &sig) == 0); - CHECK(ecount == 2); - CHECK(secp256k1_ecdsa_signature_serialize_compact(ctx, signature, NULL) == 0); - CHECK(ecount == 3); - CHECK(secp256k1_ecdsa_signature_serialize_compact(ctx, signature, &sig) == 1); - CHECK(ecount == 3); - CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, NULL, signature) == 0); - CHECK(ecount == 4); - CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, &sig, NULL) == 0); - CHECK(ecount == 5); - CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, &sig, signature) == 1); - CHECK(ecount == 5); - memset(signature, 255, 64); - CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, &sig, signature) == 0); - CHECK(ecount == 5); - secp256k1_context_set_illegal_callback(ctx, NULL, NULL); - } - - /* Nonce function corner cases. */ - for (t = 0; t < 2; t++) { - static const unsigned char zero[32] = {0x00}; - int i; - unsigned char key[32]; - unsigned char msg[32]; - secp256k1_ecdsa_signature sig2; - secp256k1_scalar sr[512], ss; - const unsigned char *extra; - extra = t == 0 ? NULL : zero; - memset(msg, 0, 32); - msg[31] = 1; - /* High key results in signature failure. */ - memset(key, 0xFF, 32); - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, NULL, extra) == 0); - CHECK(is_empty_signature(&sig)); - /* Zero key results in signature failure. */ - memset(key, 0, 32); - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, NULL, extra) == 0); - CHECK(is_empty_signature(&sig)); - /* Nonce function failure results in signature failure. */ - key[31] = 1; - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, nonce_function_test_fail, extra) == 0); - CHECK(is_empty_signature(&sig)); - /* The retry loop successfully makes its way to the first good value. */ - CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, nonce_function_test_retry, extra) == 1); - CHECK(!is_empty_signature(&sig)); - CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, nonce_function_rfc6979, extra) == 1); - CHECK(!is_empty_signature(&sig2)); - CHECK(memcmp(&sig, &sig2, sizeof(sig)) == 0); - /* The default nonce function is deterministic. */ - CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, NULL, extra) == 1); - CHECK(!is_empty_signature(&sig2)); - CHECK(memcmp(&sig, &sig2, sizeof(sig)) == 0); - /* The default nonce function changes output with different messages. */ - for(i = 0; i < 256; i++) { - int j; - msg[0] = i; - CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, NULL, extra) == 1); - CHECK(!is_empty_signature(&sig2)); - secp256k1_ecdsa_signature_load(ctx, &sr[i], &ss, &sig2); - for (j = 0; j < i; j++) { - CHECK(!secp256k1_scalar_eq(&sr[i], &sr[j])); - } - } - msg[0] = 0; - msg[31] = 2; - /* The default nonce function changes output with different keys. */ - for(i = 256; i < 512; i++) { - int j; - key[0] = i - 256; - CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, NULL, extra) == 1); - CHECK(!is_empty_signature(&sig2)); - secp256k1_ecdsa_signature_load(ctx, &sr[i], &ss, &sig2); - for (j = 0; j < i; j++) { - CHECK(!secp256k1_scalar_eq(&sr[i], &sr[j])); - } - } - key[0] = 0; - } - - { - /* Check that optional nonce arguments do not have equivalent effect. */ - const unsigned char zeros[32] = {0}; - unsigned char nonce[32]; - unsigned char nonce2[32]; - unsigned char nonce3[32]; - unsigned char nonce4[32]; - VG_UNDEF(nonce,32); - VG_UNDEF(nonce2,32); - VG_UNDEF(nonce3,32); - VG_UNDEF(nonce4,32); - CHECK(nonce_function_rfc6979(nonce, zeros, zeros, NULL, NULL, 0) == 1); - VG_CHECK(nonce,32); - CHECK(nonce_function_rfc6979(nonce2, zeros, zeros, zeros, NULL, 0) == 1); - VG_CHECK(nonce2,32); - CHECK(nonce_function_rfc6979(nonce3, zeros, zeros, NULL, (void *)zeros, 0) == 1); - VG_CHECK(nonce3,32); - CHECK(nonce_function_rfc6979(nonce4, zeros, zeros, zeros, (void *)zeros, 0) == 1); - VG_CHECK(nonce4,32); - CHECK(memcmp(nonce, nonce2, 32) != 0); - CHECK(memcmp(nonce, nonce3, 32) != 0); - CHECK(memcmp(nonce, nonce4, 32) != 0); - CHECK(memcmp(nonce2, nonce3, 32) != 0); - CHECK(memcmp(nonce2, nonce4, 32) != 0); - CHECK(memcmp(nonce3, nonce4, 32) != 0); - } - - - /* Privkey export where pubkey is the point at infinity. */ - { - unsigned char privkey[300]; - unsigned char seckey[32] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, - 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41, - }; - size_t outlen = 300; - CHECK(!ec_privkey_export_der(ctx, privkey, &outlen, seckey, 0)); - outlen = 300; - CHECK(!ec_privkey_export_der(ctx, privkey, &outlen, seckey, 1)); - } -} - -void run_ecdsa_edge_cases(void) { - test_ecdsa_edge_cases(); -} - -#ifdef ENABLE_OPENSSL_TESTS -EC_KEY *get_openssl_key(const unsigned char *key32) { - unsigned char privkey[300]; - size_t privkeylen; - const unsigned char* pbegin = privkey; - int compr = secp256k1_rand_bits(1); - EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1); - CHECK(ec_privkey_export_der(ctx, privkey, &privkeylen, key32, compr)); - CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen)); - CHECK(EC_KEY_check_key(ec_key)); - return ec_key; -} - -void test_ecdsa_openssl(void) { - secp256k1_gej qj; - secp256k1_ge q; - secp256k1_scalar sigr, sigs; - secp256k1_scalar one; - secp256k1_scalar msg2; - secp256k1_scalar key, msg; - EC_KEY *ec_key; - unsigned int sigsize = 80; - size_t secp_sigsize = 80; - unsigned char message[32]; - unsigned char signature[80]; - unsigned char key32[32]; - secp256k1_rand256_test(message); - secp256k1_scalar_set_b32(&msg, message, NULL); - random_scalar_order_test(&key); - secp256k1_scalar_get_b32(key32, &key); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &qj, &key); - secp256k1_ge_set_gej(&q, &qj); - ec_key = get_openssl_key(key32); - CHECK(ec_key != NULL); - CHECK(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key)); - CHECK(secp256k1_ecdsa_sig_parse(&sigr, &sigs, signature, sigsize)); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &q, &msg)); - secp256k1_scalar_set_int(&one, 1); - secp256k1_scalar_add(&msg2, &msg, &one); - CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &q, &msg2)); - - random_sign(&sigr, &sigs, &key, &msg, NULL); - CHECK(secp256k1_ecdsa_sig_serialize(signature, &secp_sigsize, &sigr, &sigs)); - CHECK(ECDSA_verify(0, message, sizeof(message), signature, secp_sigsize, ec_key) == 1); - - EC_KEY_free(ec_key); -} - -void run_ecdsa_openssl(void) { - int i; - for (i = 0; i < 10*count; i++) { - test_ecdsa_openssl(); - } -} -#endif - -#ifdef ENABLE_MODULE_ECDH -# include "modules/ecdh/tests_impl.h" -#endif - -#ifdef ENABLE_MODULE_SCHNORR -# include "modules/schnorr/tests_impl.h" -#endif - -#ifdef ENABLE_MODULE_RECOVERY -# include "modules/recovery/tests_impl.h" -#endif - -int main(int argc, char **argv) { - unsigned char seed16[16] = {0}; - unsigned char run32[32] = {0}; - /* find iteration count */ - if (argc > 1) { - count = strtol(argv[1], NULL, 0); - } - - /* find random seed */ - if (argc > 2) { - int pos = 0; - const char* ch = argv[2]; - while (pos < 16 && ch[0] != 0 && ch[1] != 0) { - unsigned short sh; - if (sscanf(ch, "%2hx", &sh)) { - seed16[pos] = sh; - } else { - break; - } - ch += 2; - pos++; - } - } else { - FILE *frand = fopen("/dev/urandom", "r"); - if ((frand == NULL) || !fread(&seed16, sizeof(seed16), 1, frand)) { - uint64_t t = time(NULL) * (uint64_t)1337; - seed16[0] ^= t; - seed16[1] ^= t >> 8; - seed16[2] ^= t >> 16; - seed16[3] ^= t >> 24; - seed16[4] ^= t >> 32; - seed16[5] ^= t >> 40; - seed16[6] ^= t >> 48; - seed16[7] ^= t >> 56; - } - fclose(frand); - } - secp256k1_rand_seed(seed16); - - printf("test count = %i\n", count); - printf("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", seed16[0], seed16[1], seed16[2], seed16[3], seed16[4], seed16[5], seed16[6], seed16[7], seed16[8], seed16[9], seed16[10], seed16[11], seed16[12], seed16[13], seed16[14], seed16[15]); - - /* initialize */ - run_context_tests(); - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - if (secp256k1_rand_bits(1)) { - secp256k1_rand256(run32); - CHECK(secp256k1_context_randomize(ctx, secp256k1_rand_bits(1) ? run32 : NULL)); - } - - run_rand_bits(); - run_rand_int(); - - run_sha256_tests(); - run_hmac_sha256_tests(); - run_rfc6979_hmac_sha256_tests(); - -#ifndef USE_NUM_NONE - /* num tests */ - run_num_smalltests(); -#endif - - /* scalar tests */ - run_scalar_tests(); - - /* field tests */ - run_field_inv(); - run_field_inv_var(); - run_field_inv_all_var(); - run_field_misc(); - run_field_convert(); - run_sqr(); - run_sqrt(); - - /* group tests */ - run_ge(); - run_group_decompress(); - - /* ecmult tests */ - run_wnaf(); - run_point_times_order(); - run_ecmult_chain(); - run_ecmult_constants(); - run_ecmult_gen_blind(); - run_ecmult_const_tests(); - run_ec_combine(); - - /* endomorphism tests */ -#ifdef USE_ENDOMORPHISM - run_endomorphism_tests(); -#endif - - /* EC point parser test */ - run_ec_pubkey_parse_test(); - - /* EC key edge cases */ - run_eckey_edge_case_test(); - -#ifdef ENABLE_MODULE_ECDH - /* ecdh tests */ - run_ecdh_tests(); -#endif - - /* ecdsa tests */ - run_random_pubkeys(); - run_ecdsa_der_parse(); - run_ecdsa_sign_verify(); - run_ecdsa_end_to_end(); - run_ecdsa_edge_cases(); -#ifdef ENABLE_OPENSSL_TESTS - run_ecdsa_openssl(); -#endif - -#ifdef ENABLE_MODULE_SCHNORR - /* Schnorr tests */ - run_schnorr_tests(); -#endif - -#ifdef ENABLE_MODULE_RECOVERY - /* ECDSA pubkey recovery tests */ - run_recovery_tests(); -#endif - - secp256k1_rand256(run32); - printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]); - - /* shutdown */ - secp256k1_context_destroy(ctx); - - printf("no problems found\n"); - return 0; -} diff --git a/util/secp256k1/depend/secp256k1/src/tests_exhaustive.c b/util/secp256k1/depend/secp256k1/src/tests_exhaustive.c deleted file mode 100644 index b040bb0733..0000000000 --- a/util/secp256k1/depend/secp256k1/src/tests_exhaustive.c +++ /dev/null @@ -1,470 +0,0 @@ -/*********************************************************************** - * Copyright (c) 2016 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif - -#include -#include - -#include - -#undef USE_ECMULT_STATIC_PRECOMPUTATION - -#ifndef EXHAUSTIVE_TEST_ORDER -/* see group_impl.h for allowable values */ -#define EXHAUSTIVE_TEST_ORDER 13 -#define EXHAUSTIVE_TEST_LAMBDA 9 /* cube root of 1 mod 13 */ -#endif - -#include "include/secp256k1.h" -#include "group.h" -#include "secp256k1.c" -#include "testrand_impl.h" - -#ifdef ENABLE_MODULE_RECOVERY -#include "src/modules/recovery/main_impl.h" -#include "include/secp256k1_recovery.h" -#endif - -/** stolen from tests.c */ -void ge_equals_ge(const secp256k1_ge *a, const secp256k1_ge *b) { - CHECK(a->infinity == b->infinity); - if (a->infinity) { - return; - } - CHECK(secp256k1_fe_equal_var(&a->x, &b->x)); - CHECK(secp256k1_fe_equal_var(&a->y, &b->y)); -} - -void ge_equals_gej(const secp256k1_ge *a, const secp256k1_gej *b) { - secp256k1_fe z2s; - secp256k1_fe u1, u2, s1, s2; - CHECK(a->infinity == b->infinity); - if (a->infinity) { - return; - } - /* Check a.x * b.z^2 == b.x && a.y * b.z^3 == b.y, to avoid inverses. */ - secp256k1_fe_sqr(&z2s, &b->z); - secp256k1_fe_mul(&u1, &a->x, &z2s); - u2 = b->x; secp256k1_fe_normalize_weak(&u2); - secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z); - s2 = b->y; secp256k1_fe_normalize_weak(&s2); - CHECK(secp256k1_fe_equal_var(&u1, &u2)); - CHECK(secp256k1_fe_equal_var(&s1, &s2)); -} - -void random_fe(secp256k1_fe *x) { - unsigned char bin[32]; - do { - secp256k1_rand256(bin); - if (secp256k1_fe_set_b32(x, bin)) { - return; - } - } while(1); -} -/** END stolen from tests.c */ - -int secp256k1_nonce_function_smallint(unsigned char *nonce32, const unsigned char *msg32, - const unsigned char *key32, const unsigned char *algo16, - void *data, unsigned int attempt) { - secp256k1_scalar s; - int *idata = data; - (void)msg32; - (void)key32; - (void)algo16; - /* Some nonces cannot be used because they'd cause s and/or r to be zero. - * The signing function has retry logic here that just re-calls the nonce - * function with an increased `attempt`. So if attempt > 0 this means we - * need to change the nonce to avoid an infinite loop. */ - if (attempt > 0) { - *idata = (*idata + 1) % EXHAUSTIVE_TEST_ORDER; - } - secp256k1_scalar_set_int(&s, *idata); - secp256k1_scalar_get_b32(nonce32, &s); - return 1; -} - -#ifdef USE_ENDOMORPHISM -void test_exhaustive_endomorphism(const secp256k1_ge *group, int order) { - int i; - for (i = 0; i < order; i++) { - secp256k1_ge res; - secp256k1_ge_mul_lambda(&res, &group[i]); - ge_equals_ge(&group[i * EXHAUSTIVE_TEST_LAMBDA % EXHAUSTIVE_TEST_ORDER], &res); - } -} -#endif - -void test_exhaustive_addition(const secp256k1_ge *group, const secp256k1_gej *groupj, int order) { - int i, j; - - /* Sanity-check (and check infinity functions) */ - CHECK(secp256k1_ge_is_infinity(&group[0])); - CHECK(secp256k1_gej_is_infinity(&groupj[0])); - for (i = 1; i < order; i++) { - CHECK(!secp256k1_ge_is_infinity(&group[i])); - CHECK(!secp256k1_gej_is_infinity(&groupj[i])); - } - - /* Check all addition formulae */ - for (j = 0; j < order; j++) { - secp256k1_fe fe_inv; - secp256k1_fe_inv(&fe_inv, &groupj[j].z); - for (i = 0; i < order; i++) { - secp256k1_ge zless_gej; - secp256k1_gej tmp; - /* add_var */ - secp256k1_gej_add_var(&tmp, &groupj[i], &groupj[j], NULL); - ge_equals_gej(&group[(i + j) % order], &tmp); - /* add_ge */ - if (j > 0) { - secp256k1_gej_add_ge(&tmp, &groupj[i], &group[j]); - ge_equals_gej(&group[(i + j) % order], &tmp); - } - /* add_ge_var */ - secp256k1_gej_add_ge_var(&tmp, &groupj[i], &group[j], NULL); - ge_equals_gej(&group[(i + j) % order], &tmp); - /* add_zinv_var */ - zless_gej.infinity = groupj[j].infinity; - zless_gej.x = groupj[j].x; - zless_gej.y = groupj[j].y; - secp256k1_gej_add_zinv_var(&tmp, &groupj[i], &zless_gej, &fe_inv); - ge_equals_gej(&group[(i + j) % order], &tmp); - } - } - - /* Check doubling */ - for (i = 0; i < order; i++) { - secp256k1_gej tmp; - if (i > 0) { - secp256k1_gej_double_nonzero(&tmp, &groupj[i], NULL); - ge_equals_gej(&group[(2 * i) % order], &tmp); - } - secp256k1_gej_double_var(&tmp, &groupj[i], NULL); - ge_equals_gej(&group[(2 * i) % order], &tmp); - } - - /* Check negation */ - for (i = 1; i < order; i++) { - secp256k1_ge tmp; - secp256k1_gej tmpj; - secp256k1_ge_neg(&tmp, &group[i]); - ge_equals_ge(&group[order - i], &tmp); - secp256k1_gej_neg(&tmpj, &groupj[i]); - ge_equals_gej(&group[order - i], &tmpj); - } -} - -void test_exhaustive_ecmult(const secp256k1_context *ctx, const secp256k1_ge *group, const secp256k1_gej *groupj, int order) { - int i, j, r_log; - for (r_log = 1; r_log < order; r_log++) { - for (j = 0; j < order; j++) { - for (i = 0; i < order; i++) { - secp256k1_gej tmp; - secp256k1_scalar na, ng; - secp256k1_scalar_set_int(&na, i); - secp256k1_scalar_set_int(&ng, j); - - secp256k1_ecmult(&ctx->ecmult_ctx, &tmp, &groupj[r_log], &na, &ng); - ge_equals_gej(&group[(i * r_log + j) % order], &tmp); - - if (i > 0) { - secp256k1_ecmult_const(&tmp, &group[i], &ng); - ge_equals_gej(&group[(i * j) % order], &tmp); - } - } - } - } -} - -void r_from_k(secp256k1_scalar *r, const secp256k1_ge *group, int k) { - secp256k1_fe x; - unsigned char x_bin[32]; - k %= EXHAUSTIVE_TEST_ORDER; - x = group[k].x; - secp256k1_fe_normalize(&x); - secp256k1_fe_get_b32(x_bin, &x); - secp256k1_scalar_set_b32(r, x_bin, NULL); -} - -void test_exhaustive_verify(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { - int s, r, msg, key; - for (s = 1; s < order; s++) { - for (r = 1; r < order; r++) { - for (msg = 1; msg < order; msg++) { - for (key = 1; key < order; key++) { - secp256k1_ge nonconst_ge; - secp256k1_ecdsa_signature sig; - secp256k1_pubkey pk; - secp256k1_scalar sk_s, msg_s, r_s, s_s; - secp256k1_scalar s_times_k_s, msg_plus_r_times_sk_s; - int k, should_verify; - unsigned char msg32[32]; - - secp256k1_scalar_set_int(&s_s, s); - secp256k1_scalar_set_int(&r_s, r); - secp256k1_scalar_set_int(&msg_s, msg); - secp256k1_scalar_set_int(&sk_s, key); - - /* Verify by hand */ - /* Run through every k value that gives us this r and check that *one* works. - * Note there could be none, there could be multiple, ECDSA is weird. */ - should_verify = 0; - for (k = 0; k < order; k++) { - secp256k1_scalar check_x_s; - r_from_k(&check_x_s, group, k); - if (r_s == check_x_s) { - secp256k1_scalar_set_int(&s_times_k_s, k); - secp256k1_scalar_mul(&s_times_k_s, &s_times_k_s, &s_s); - secp256k1_scalar_mul(&msg_plus_r_times_sk_s, &r_s, &sk_s); - secp256k1_scalar_add(&msg_plus_r_times_sk_s, &msg_plus_r_times_sk_s, &msg_s); - should_verify |= secp256k1_scalar_eq(&s_times_k_s, &msg_plus_r_times_sk_s); - } - } - /* nb we have a "high s" rule */ - should_verify &= !secp256k1_scalar_is_high(&s_s); - - /* Verify by calling verify */ - secp256k1_ecdsa_signature_save(&sig, &r_s, &s_s); - memcpy(&nonconst_ge, &group[sk_s], sizeof(nonconst_ge)); - secp256k1_pubkey_save(&pk, &nonconst_ge); - secp256k1_scalar_get_b32(msg32, &msg_s); - CHECK(should_verify == - secp256k1_ecdsa_verify(ctx, &sig, msg32, &pk)); - } - } - } - } -} - -void test_exhaustive_sign(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { - int i, j, k; - - /* Loop */ - for (i = 1; i < order; i++) { /* message */ - for (j = 1; j < order; j++) { /* key */ - for (k = 1; k < order; k++) { /* nonce */ - const int starting_k = k; - secp256k1_ecdsa_signature sig; - secp256k1_scalar sk, msg, r, s, expected_r; - unsigned char sk32[32], msg32[32]; - secp256k1_scalar_set_int(&msg, i); - secp256k1_scalar_set_int(&sk, j); - secp256k1_scalar_get_b32(sk32, &sk); - secp256k1_scalar_get_b32(msg32, &msg); - - secp256k1_ecdsa_sign(ctx, &sig, msg32, sk32, secp256k1_nonce_function_smallint, &k); - - secp256k1_ecdsa_signature_load(ctx, &r, &s, &sig); - /* Note that we compute expected_r *after* signing -- this is important - * because our nonce-computing function function might change k during - * signing. */ - r_from_k(&expected_r, group, k); - CHECK(r == expected_r); - CHECK((k * s) % order == (i + r * j) % order || - (k * (EXHAUSTIVE_TEST_ORDER - s)) % order == (i + r * j) % order); - - /* Overflow means we've tried every possible nonce */ - if (k < starting_k) { - break; - } - } - } - } - - /* We would like to verify zero-knowledge here by counting how often every - * possible (s, r) tuple appears, but because the group order is larger - * than the field order, when coercing the x-values to scalar values, some - * appear more often than others, so we are actually not zero-knowledge. - * (This effect also appears in the real code, but the difference is on the - * order of 1/2^128th the field order, so the deviation is not useful to a - * computationally bounded attacker.) - */ -} - -#ifdef ENABLE_MODULE_RECOVERY -void test_exhaustive_recovery_sign(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { - int i, j, k; - - /* Loop */ - for (i = 1; i < order; i++) { /* message */ - for (j = 1; j < order; j++) { /* key */ - for (k = 1; k < order; k++) { /* nonce */ - const int starting_k = k; - secp256k1_fe r_dot_y_normalized; - secp256k1_ecdsa_recoverable_signature rsig; - secp256k1_ecdsa_signature sig; - secp256k1_scalar sk, msg, r, s, expected_r; - unsigned char sk32[32], msg32[32]; - int expected_recid; - int recid; - secp256k1_scalar_set_int(&msg, i); - secp256k1_scalar_set_int(&sk, j); - secp256k1_scalar_get_b32(sk32, &sk); - secp256k1_scalar_get_b32(msg32, &msg); - - secp256k1_ecdsa_sign_recoverable(ctx, &rsig, msg32, sk32, secp256k1_nonce_function_smallint, &k); - - /* Check directly */ - secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, &rsig); - r_from_k(&expected_r, group, k); - CHECK(r == expected_r); - CHECK((k * s) % order == (i + r * j) % order || - (k * (EXHAUSTIVE_TEST_ORDER - s)) % order == (i + r * j) % order); - /* In computing the recid, there is an overflow condition that is disabled in - * scalar_low_impl.h `secp256k1_scalar_set_b32` because almost every r.y value - * will exceed the group order, and our signing code always holds out for r - * values that don't overflow, so with a proper overflow check the tests would - * loop indefinitely. */ - r_dot_y_normalized = group[k].y; - secp256k1_fe_normalize(&r_dot_y_normalized); - /* Also the recovery id is flipped depending if we hit the low-s branch */ - if ((k * s) % order == (i + r * j) % order) { - expected_recid = secp256k1_fe_is_odd(&r_dot_y_normalized) ? 1 : 0; - } else { - expected_recid = secp256k1_fe_is_odd(&r_dot_y_normalized) ? 0 : 1; - } - CHECK(recid == expected_recid); - - /* Convert to a standard sig then check */ - secp256k1_ecdsa_recoverable_signature_convert(ctx, &sig, &rsig); - secp256k1_ecdsa_signature_load(ctx, &r, &s, &sig); - /* Note that we compute expected_r *after* signing -- this is important - * because our nonce-computing function function might change k during - * signing. */ - r_from_k(&expected_r, group, k); - CHECK(r == expected_r); - CHECK((k * s) % order == (i + r * j) % order || - (k * (EXHAUSTIVE_TEST_ORDER - s)) % order == (i + r * j) % order); - - /* Overflow means we've tried every possible nonce */ - if (k < starting_k) { - break; - } - } - } - } -} - -void test_exhaustive_recovery_verify(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { - /* This is essentially a copy of test_exhaustive_verify, with recovery added */ - int s, r, msg, key; - for (s = 1; s < order; s++) { - for (r = 1; r < order; r++) { - for (msg = 1; msg < order; msg++) { - for (key = 1; key < order; key++) { - secp256k1_ge nonconst_ge; - secp256k1_ecdsa_recoverable_signature rsig; - secp256k1_ecdsa_signature sig; - secp256k1_pubkey pk; - secp256k1_scalar sk_s, msg_s, r_s, s_s; - secp256k1_scalar s_times_k_s, msg_plus_r_times_sk_s; - int recid = 0; - int k, should_verify; - unsigned char msg32[32]; - - secp256k1_scalar_set_int(&s_s, s); - secp256k1_scalar_set_int(&r_s, r); - secp256k1_scalar_set_int(&msg_s, msg); - secp256k1_scalar_set_int(&sk_s, key); - secp256k1_scalar_get_b32(msg32, &msg_s); - - /* Verify by hand */ - /* Run through every k value that gives us this r and check that *one* works. - * Note there could be none, there could be multiple, ECDSA is weird. */ - should_verify = 0; - for (k = 0; k < order; k++) { - secp256k1_scalar check_x_s; - r_from_k(&check_x_s, group, k); - if (r_s == check_x_s) { - secp256k1_scalar_set_int(&s_times_k_s, k); - secp256k1_scalar_mul(&s_times_k_s, &s_times_k_s, &s_s); - secp256k1_scalar_mul(&msg_plus_r_times_sk_s, &r_s, &sk_s); - secp256k1_scalar_add(&msg_plus_r_times_sk_s, &msg_plus_r_times_sk_s, &msg_s); - should_verify |= secp256k1_scalar_eq(&s_times_k_s, &msg_plus_r_times_sk_s); - } - } - /* nb we have a "high s" rule */ - should_verify &= !secp256k1_scalar_is_high(&s_s); - - /* We would like to try recovering the pubkey and checking that it matches, - * but pubkey recovery is impossible in the exhaustive tests (the reason - * being that there are 12 nonzero r values, 12 nonzero points, and no - * overlap between the sets, so there are no valid signatures). */ - - /* Verify by converting to a standard signature and calling verify */ - secp256k1_ecdsa_recoverable_signature_save(&rsig, &r_s, &s_s, recid); - secp256k1_ecdsa_recoverable_signature_convert(ctx, &sig, &rsig); - memcpy(&nonconst_ge, &group[sk_s], sizeof(nonconst_ge)); - secp256k1_pubkey_save(&pk, &nonconst_ge); - CHECK(should_verify == - secp256k1_ecdsa_verify(ctx, &sig, msg32, &pk)); - } - } - } - } -} -#endif - -int main(void) { - int i; - secp256k1_gej groupj[EXHAUSTIVE_TEST_ORDER]; - secp256k1_ge group[EXHAUSTIVE_TEST_ORDER]; - - /* Build context */ - secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - - /* TODO set z = 1, then do num_tests runs with random z values */ - - /* Generate the entire group */ - secp256k1_gej_set_infinity(&groupj[0]); - secp256k1_ge_set_gej(&group[0], &groupj[0]); - for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { - /* Set a different random z-value for each Jacobian point */ - secp256k1_fe z; - random_fe(&z); - - secp256k1_gej_add_ge(&groupj[i], &groupj[i - 1], &secp256k1_ge_const_g); - secp256k1_ge_set_gej(&group[i], &groupj[i]); - secp256k1_gej_rescale(&groupj[i], &z); - - /* Verify against ecmult_gen */ - { - secp256k1_scalar scalar_i; - secp256k1_gej generatedj; - secp256k1_ge generated; - - secp256k1_scalar_set_int(&scalar_i, i); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &generatedj, &scalar_i); - secp256k1_ge_set_gej(&generated, &generatedj); - - CHECK(group[i].infinity == 0); - CHECK(generated.infinity == 0); - CHECK(secp256k1_fe_equal_var(&generated.x, &group[i].x)); - CHECK(secp256k1_fe_equal_var(&generated.y, &group[i].y)); - } - } - - /* Run the tests */ -#ifdef USE_ENDOMORPHISM - test_exhaustive_endomorphism(group, EXHAUSTIVE_TEST_ORDER); -#endif - test_exhaustive_addition(group, groupj, EXHAUSTIVE_TEST_ORDER); - test_exhaustive_ecmult(ctx, group, groupj, EXHAUSTIVE_TEST_ORDER); - test_exhaustive_sign(ctx, group, EXHAUSTIVE_TEST_ORDER); - test_exhaustive_verify(ctx, group, EXHAUSTIVE_TEST_ORDER); - -#ifdef ENABLE_MODULE_RECOVERY - test_exhaustive_recovery_sign(ctx, group, EXHAUSTIVE_TEST_ORDER); - test_exhaustive_recovery_verify(ctx, group, EXHAUSTIVE_TEST_ORDER); -#endif - - secp256k1_context_destroy(ctx); - return 0; -} - diff --git a/util/secp256k1/depend/secp256k1/src/util.h b/util/secp256k1/depend/secp256k1/src/util.h deleted file mode 100644 index b0441d8e30..0000000000 --- a/util/secp256k1/depend/secp256k1/src/util.h +++ /dev/null @@ -1,113 +0,0 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef SECP256K1_UTIL_H -#define SECP256K1_UTIL_H - -#if defined HAVE_CONFIG_H -#include "libsecp256k1-config.h" -#endif - -#include -#include -#include - -typedef struct { - void (*fn)(const char *text, void* data); - const void* data; -} secp256k1_callback; - -static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * const cb, const char * const text) { - cb->fn(text, (void*)cb->data); -} - -#ifdef DETERMINISTIC -#define TEST_FAILURE(msg) do { \ - fprintf(stderr, "%s\n", msg); \ - abort(); \ -} while(0); -#else -#define TEST_FAILURE(msg) do { \ - fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \ - abort(); \ -} while(0) -#endif - -#ifdef HAVE_BUILTIN_EXPECT -#define EXPECT(x,c) __builtin_expect((x),(c)) -#else -#define EXPECT(x,c) (x) -#endif - -#ifdef DETERMINISTIC -#define CHECK(cond) do { \ - if (EXPECT(!(cond), 0)) { \ - TEST_FAILURE("test condition failed"); \ - } \ -} while(0) -#else -#define CHECK(cond) do { \ - if (EXPECT(!(cond), 0)) { \ - TEST_FAILURE("test condition failed: " #cond); \ - } \ -} while(0) -#endif - -/* Like assert(), but when VERIFY is defined, and side-effect safe. */ -#if defined(COVERAGE) -#define VERIFY_CHECK(check) -#define VERIFY_SETUP(stmt) -#elif defined(VERIFY) -#define VERIFY_CHECK CHECK -#define VERIFY_SETUP(stmt) do { stmt; } while(0) -#else -#define VERIFY_CHECK(cond) do { (void)(cond); } while(0) -#define VERIFY_SETUP(stmt) -#endif - -static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_t size) { - void *ret = malloc(size); - if (ret == NULL) { - secp256k1_callback_call(cb, "Out of memory"); - } - return ret; -} - -/* Macro for restrict, when available and not in a VERIFY build. */ -#if defined(SECP256K1_BUILD) && defined(VERIFY) -# define SECP256K1_RESTRICT -#else -# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) -# if SECP256K1_GNUC_PREREQ(3,0) -# define SECP256K1_RESTRICT __restrict__ -# elif (defined(_MSC_VER) && _MSC_VER >= 1400) -# define SECP256K1_RESTRICT __restrict -# else -# define SECP256K1_RESTRICT -# endif -# else -# define SECP256K1_RESTRICT restrict -# endif -#endif - -#if defined(_WIN32) -# define I64FORMAT "I64d" -# define I64uFORMAT "I64u" -#else -# define I64FORMAT "lld" -# define I64uFORMAT "llu" -#endif - -#if defined(HAVE___INT128) -# if defined(__GNUC__) -# define SECP256K1_GNUC_EXT __extension__ -# else -# define SECP256K1_GNUC_EXT -# endif -SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t; -#endif - -#endif /* SECP256K1_UTIL_H */ diff --git a/util/secp256k1/src/constants.rs b/util/secp256k1/src/constants.rs deleted file mode 100644 index efb70dc7e1..0000000000 --- a/util/secp256k1/src/constants.rs +++ /dev/null @@ -1,60 +0,0 @@ -// Bitcoin secp256k1 bindings -// Written in 2014 by -// Dawid Ciężarkiewicz -// Andrew Poelstra -// -// To the extent possible under law, the author(s) have dedicated all -// copyright and related and neighboring rights to this software to -// the public domain worldwide. This software is distributed without -// any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication -// along with this software. -// If not, see . -// - -//! # Constants -//! Constants related to the API and the underlying curve - -/// The size (in bytes) of a message -pub const MESSAGE_SIZE: usize = 32; - -/// The size (in bytes) of a secret key -pub const SECRET_KEY_SIZE: usize = 32; - -/// The size (in bytes) of a public key array. This only needs to be 65 -/// but must be 72 for compatibility with the `ArrayVec` library. -pub const PUBLIC_KEY_SIZE: usize = 72; - -/// The size (in bytes) of an uncompressed public key -pub const UNCOMPRESSED_PUBLIC_KEY_SIZE: usize = 65; - -/// The size (in bytes) of a compressed public key -pub const COMPRESSED_PUBLIC_KEY_SIZE: usize = 33; - -/// The maximum size of a signature -pub const MAX_SIGNATURE_SIZE: usize = 72; - -/// The size of a Schnorr signature -pub const SCHNORR_SIGNATURE_SIZE: usize = 64; - -/// The maximum size of a compact signature -pub const COMPACT_SIGNATURE_SIZE: usize = 64; - -/// The order of the secp256k1 curve -pub const CURVE_ORDER: [u8; 32] = [ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, - 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41, -]; - -/// The X coordinate of the generator -pub const GENERATOR_X: [u8; 32] = [ - 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb, 0xac, 0x55, 0xa0, 0x62, 0x95, 0xce, 0x87, 0x0b, 0x07, 0x02, 0x9b, 0xfc, - 0xdb, 0x2d, 0xce, 0x28, 0xd9, 0x59, 0xf2, 0x81, 0x5b, 0x16, 0xf8, 0x17, 0x98, -]; - -/// The Y coordinate of the generator -pub const GENERATOR_Y: [u8; 32] = [ - 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, 0xfc, 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, - 0x48, 0xa6, 0x85, 0x54, 0x19, 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10, 0xd4, 0xb8, -]; diff --git a/util/secp256k1/src/ecdh.rs b/util/secp256k1/src/ecdh.rs deleted file mode 100644 index a121a136a2..0000000000 --- a/util/secp256k1/src/ecdh.rs +++ /dev/null @@ -1,144 +0,0 @@ -// Bitcoin secp256k1 bindings -// Written in 2015 by -// Andrew Poelstra -// -// To the extent possible under law, the author(s) have dedicated all -// copyright and related and neighboring rights to this software to -// the public domain worldwide. This software is distributed without -// any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication -// along with this software. -// If not, see . -// - -//! # ECDH -//! Support for shared secret computations -//! - -use std::ops; - -use super::Secp256k1; -use ffi; -use key::{PublicKey, SecretKey}; - -/// A tag used for recovering the public key from a compact signature -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -#[repr(C)] -pub struct SharedSecret(ffi::SharedSecret); - -impl SharedSecret { - /// Creates a new shared secret from a pubkey and secret key - #[inline] - pub fn new(secp: &Secp256k1, point: &PublicKey, scalar: &SecretKey) -> SharedSecret { - unsafe { - let mut ss = ffi::SharedSecret::blank(); - let res = ffi::secp256k1_ecdh(secp.ctx, &mut ss, point.as_ptr(), scalar.as_ptr()); - debug_assert_eq!(res, 1); - SharedSecret(ss) - } - } - - /// Creates a new unhashed shared secret from a pubkey and secret key - #[inline] - pub fn new_raw(secp: &Secp256k1, point: &PublicKey, scalar: &SecretKey) -> SharedSecret { - unsafe { - let mut ss = ffi::SharedSecret::blank(); - let res = ffi::secp256k1_ecdh_raw(secp.ctx, &mut ss, point.as_ptr(), scalar.as_ptr()); - debug_assert_eq!(res, 1); - SharedSecret(ss) - } - } - - /// Obtains a raw pointer suitable for use with FFI functions - #[inline] - pub fn as_ptr(&self) -> *const ffi::SharedSecret { - &self.0 as *const _ - } -} - -/// Creates a new shared secret from a FFI shared secret -impl From for SharedSecret { - #[inline] - fn from(ss: ffi::SharedSecret) -> SharedSecret { - SharedSecret(ss) - } -} - - -impl ops::Index for SharedSecret { - type Output = u8; - - #[inline] - fn index(&self, index: usize) -> &u8 { - &self.0[index] - } -} - -impl ops::Index> for SharedSecret { - type Output = [u8]; - - #[inline] - fn index(&self, index: ops::Range) -> &[u8] { - &self.0[index] - } -} - -impl ops::Index> for SharedSecret { - type Output = [u8]; - - #[inline] - fn index(&self, index: ops::RangeFrom) -> &[u8] { - &self.0[index.start..] - } -} - -impl ops::Index for SharedSecret { - type Output = [u8]; - - #[inline] - fn index(&self, _: ops::RangeFull) -> &[u8] { - &self.0[..] - } -} - -#[cfg(test)] -mod tests { - use super::super::Secp256k1; - use super::SharedSecret; - use rand::thread_rng; - - #[test] - fn ecdh() { - let s = Secp256k1::with_caps(::ContextFlag::SignOnly); - let (sk1, pk1) = s.generate_keypair(&mut thread_rng()).unwrap(); - let (sk2, pk2) = s.generate_keypair(&mut thread_rng()).unwrap(); - - let sec1 = SharedSecret::new(&s, &pk1, &sk2); - let sec2 = SharedSecret::new(&s, &pk2, &sk1); - let sec_odd = SharedSecret::new(&s, &pk1, &sk1); - assert_eq!(sec1, sec2); - assert!(sec_odd != sec2); - } -} - -#[cfg(all(test, feature = "unstable"))] -mod benches { - use rand::thread_rng; - use test::{black_box, Bencher}; - - use super::super::Secp256k1; - use super::SharedSecret; - - #[bench] - pub fn bench_ecdh(bh: &mut Bencher) { - let s = Secp256k1::with_caps(::ContextFlag::SignOnly); - let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap(); - - let s = Secp256k1::new(); - bh.iter(|| { - let res = SharedSecret::new(&s, &pk, &sk); - black_box(res); - }); - } -} diff --git a/util/secp256k1/src/ffi.rs b/util/secp256k1/src/ffi.rs deleted file mode 100644 index bf61a2a69f..0000000000 --- a/util/secp256k1/src/ffi.rs +++ /dev/null @@ -1,337 +0,0 @@ -// Bitcoin secp256k1 bindings -// Written in 2014 by -// Dawid Ciężarkiewicz -// Andrew Poelstra -// -// To the extent possible under law, the author(s) have dedicated all -// copyright and related and neighboring rights to this software to -// the public domain worldwide. This software is distributed without -// any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication -// along with this software. -// If not, see . -// - -//! # FFI bindings -//! Direct bindings to the underlying C library functions. These should -//! not be needed for most users. -use std::hash; -use std::mem; -use std::os::raw::{c_int, c_uchar, c_uint, c_void}; - -/// Flag for context to enable no precomputation -pub const SECP256K1_START_NONE: c_uint = 0b0001; // (1 << 0) | 0 -/// Flag for context to enable verification precomputation -pub const SECP256K1_START_VERIFY: c_uint = 0b0001 | 0b0001_0000_0000; // (1 << 0) | (1 << 8) -/// Flag for context to enable signing precomputation -pub const SECP256K1_START_SIGN: c_uint = 0b0001 | 0b0010_0000_0000; // (1 << 0) | (1 << 9) -/// Flag for keys to indicate uncompressed serialization format -pub const SECP256K1_SER_UNCOMPRESSED: c_uint = 0b0010; // (1 << 1) | 0 -/// Flag for keys to indicate compressed serialization format -pub const SECP256K1_SER_COMPRESSED: c_uint = 0b0010 | 0b0001_0000_0000; // (1 << 1) | (1 << 8) - -/// A nonce generation function. Ordinary users of the library -/// never need to see this type; only if you need to control -/// nonce generation do you need to use it. I have deliberately -/// made this hard to do: you have to write your own wrapper -/// around the FFI functions to use it. And it's an unsafe type. -/// Nonces are generated deterministically by RFC6979 by -/// default; there should be no need to ever change this. -pub type NonceFn = unsafe extern "C" fn( - nonce32: *mut c_uchar, - msg32: *const c_uchar, - key32: *const c_uchar, - algo16: *const c_uchar, - attempt: c_uint, - data: *const c_void, -); - - -/// A Secp256k1 context, containing various precomputed values and such -/// needed to do elliptic curve computations. If you create one of these -/// with `secp256k1_context_create` you MUST destroy it with -/// `secp256k1_context_destroy`, or else you will have a memory leak. -#[derive(Clone, Debug)] -#[repr(C)] -pub struct Context(c_int); - -/// Library-internal representation of a Secp256k1 public key -#[repr(C)] -pub struct PublicKey([c_uchar; 64]); -impl_array_newtype!(PublicKey, c_uchar, 64); -impl_raw_debug!(PublicKey); - -impl PublicKey { - /// Create a new (zeroed) public key usable for the FFI interface - pub fn new() -> Self { - Self::default() - } - /// Create a new (uninitialized) public key usable for the FFI interface - pub unsafe fn blank() -> PublicKey { - mem::uninitialized() - } -} - -impl Default for PublicKey { - fn default() -> Self { - PublicKey([0; 64]) - } -} - -impl hash::Hash for PublicKey { - fn hash(&self, state: &mut H) { - state.write(&self.0) - } -} - -/// Library-internal representation of a Secp256k1 signature -#[repr(C)] -pub struct Signature([c_uchar; 64]); -impl_array_newtype!(Signature, c_uchar, 64); -impl_raw_debug!(Signature); - -/// Library-internal representation of a Secp256k1 signature + recovery ID -#[repr(C)] -pub struct RecoverableSignature([c_uchar; 65]); -impl_array_newtype!(RecoverableSignature, c_uchar, 65); -impl_raw_debug!(RecoverableSignature); - -impl Signature { - /// Create a new (zeroed) signature usable for the FFI interface - pub fn new() -> Self { - Self::default() - } - /// Create a new (uninitialized) signature usable for the FFI interface - pub unsafe fn blank() -> Signature { - mem::uninitialized() - } -} - -impl Default for Signature { - fn default() -> Self { - Signature([0; 64]) - } -} - -impl RecoverableSignature { - /// Create a new (zeroed) signature usable for the FFI interface - pub fn new() -> Self { - Self::default() - } - /// Create a new (uninitialized) signature usable for the FFI interface - pub unsafe fn blank() -> RecoverableSignature { - mem::uninitialized() - } -} - -impl Default for RecoverableSignature { - fn default() -> Self { - RecoverableSignature([0; 65]) - } -} - -/// Library-internal representation of an ECDH shared secret -#[repr(C)] -pub struct SharedSecret([c_uchar; 32]); -impl_array_newtype!(SharedSecret, c_uchar, 32); -impl_raw_debug!(SharedSecret); - -impl SharedSecret { - /// Create a new (zeroed) signature usable for the FFI interface - pub fn new() -> Self { - Self::default() - } - /// Create a new (uninitialized) signature usable for the FFI interface - pub unsafe fn blank() -> SharedSecret { - mem::uninitialized() - } -} - -impl Default for SharedSecret { - fn default() -> Self { - SharedSecret([0; 32]) - } -} - -extern "C" { - pub static secp256k1_nonce_function_rfc6979: NonceFn; - - pub static secp256k1_nonce_function_default: NonceFn; - - // Contexts - pub fn secp256k1_context_create(flags: c_uint) -> *mut Context; - - pub fn secp256k1_context_clone(cx: *mut Context) -> *mut Context; - - pub fn secp256k1_context_destroy(cx: *mut Context); - - pub fn secp256k1_context_randomize(cx: *mut Context, seed32: *const c_uchar) -> c_int; - - // TODO secp256k1_context_set_illegal_callback - // TODO secp256k1_context_set_error_callback - // (Actually, I don't really want these exposed; if either of these - // are ever triggered it indicates a bug in rust-secp256k1, since - // one goal is to use Rust's type system to eliminate all possible - // bad inputs.) - - // Pubkeys - pub fn secp256k1_ec_pubkey_parse( - cx: *const Context, - pk: *mut PublicKey, - input: *const c_uchar, - in_len: usize, - ) -> c_int; - - pub fn secp256k1_ec_pubkey_serialize( - cx: *const Context, - output: *const c_uchar, - out_len: *mut usize, - pk: *const PublicKey, - compressed: c_uint, - ) -> c_int; - - // Signatures - pub fn secp256k1_ecdsa_signature_parse_der( - cx: *const Context, - sig: *mut Signature, - input: *const c_uchar, - in_len: usize, - ) -> c_int; - - pub fn ecdsa_signature_parse_der_lax( - cx: *const Context, - sig: *mut Signature, - input: *const c_uchar, - in_len: usize, - ) -> c_int; - - pub fn secp256k1_ecdsa_signature_serialize_der( - cx: *const Context, - output: *const c_uchar, - out_len: *mut usize, - sig: *const Signature, - ) -> c_int; - - pub fn secp256k1_ecdsa_recoverable_signature_parse_compact( - cx: *const Context, - sig: *mut RecoverableSignature, - input64: *const c_uchar, - recid: c_int, - ) -> c_int; - - pub fn secp256k1_ecdsa_recoverable_signature_serialize_compact( - cx: *const Context, - output64: *const c_uchar, - recid: *mut c_int, - sig: *const RecoverableSignature, - ) -> c_int; - - pub fn secp256k1_ecdsa_recoverable_signature_convert( - cx: *const Context, - sig: *mut Signature, - input: *const RecoverableSignature, - ) -> c_int; - - pub fn secp256k1_ecdsa_signature_normalize( - cx: *const Context, - out_sig: *mut Signature, - in_sig: *const Signature, - ) -> c_int; - - // ECDSA - pub fn secp256k1_ecdsa_verify( - cx: *const Context, - sig: *const Signature, - msg32: *const c_uchar, - pk: *const PublicKey, - ) -> c_int; - - pub fn secp256k1_ecdsa_sign( - cx: *const Context, - sig: *mut Signature, - msg32: *const c_uchar, - sk: *const c_uchar, - noncefn: NonceFn, - noncedata: *const c_void, - ) -> c_int; - - pub fn secp256k1_ecdsa_sign_recoverable( - cx: *const Context, - sig: *mut RecoverableSignature, - msg32: *const c_uchar, - sk: *const c_uchar, - noncefn: NonceFn, - noncedata: *const c_void, - ) -> c_int; - - pub fn secp256k1_ecdsa_recover( - cx: *const Context, - pk: *mut PublicKey, - sig: *const RecoverableSignature, - msg32: *const c_uchar, - ) -> c_int; - - // Schnorr - pub fn secp256k1_schnorr_sign( - cx: *const Context, - sig64: *mut c_uchar, - msg32: *const c_uchar, - sk: *const c_uchar, - noncefn: NonceFn, - noncedata: *const c_void, - ) -> c_int; - - pub fn secp256k1_schnorr_verify( - cx: *const Context, - sig64: *const c_uchar, - msg32: *const c_uchar, - pk: *const PublicKey, - ) -> c_int; - - pub fn secp256k1_schnorr_recover( - cx: *const Context, - pk: *mut PublicKey, - sig64: *const c_uchar, - msg32: *const c_uchar, - ) -> c_int; - - // EC - pub fn secp256k1_ec_seckey_verify(cx: *const Context, sk: *const c_uchar) -> c_int; - - pub fn secp256k1_ec_pubkey_create(cx: *const Context, pk: *mut PublicKey, sk: *const c_uchar) -> c_int; - - //TODO secp256k1_ec_privkey_export - //TODO secp256k1_ec_privkey_import - - pub fn secp256k1_ec_privkey_tweak_add(cx: *const Context, sk: *mut c_uchar, tweak: *const c_uchar) -> c_int; - - pub fn secp256k1_ec_pubkey_tweak_add(cx: *const Context, pk: *mut PublicKey, tweak: *const c_uchar) -> c_int; - - pub fn secp256k1_ec_privkey_tweak_mul(cx: *const Context, sk: *mut c_uchar, tweak: *const c_uchar) -> c_int; - - pub fn secp256k1_ec_pubkey_tweak_mul(cx: *const Context, pk: *mut PublicKey, tweak: *const c_uchar) -> c_int; - - pub fn secp256k1_ec_pubkey_combine( - cx: *const Context, - out: *mut PublicKey, - ins: *const *const PublicKey, - n: c_int, - ) -> c_int; - - pub fn secp256k1_ecdh( - cx: *const Context, - out: *mut SharedSecret, - point: *const PublicKey, - scalar: *const c_uchar, - ) -> c_int; - - pub fn secp256k1_ecdh_raw( - cx: *const Context, - out: *mut SharedSecret, - point: *const PublicKey, - scalar: *const c_uchar, - ) -> c_int; - - pub fn secp256k1_ec_privkey_inverse(cx: *const Context, out: *mut c_uchar, scalar: *const c_uchar) -> c_int; -} diff --git a/util/secp256k1/src/key.rs b/util/secp256k1/src/key.rs deleted file mode 100644 index 6cfdd4f14d..0000000000 --- a/util/secp256k1/src/key.rs +++ /dev/null @@ -1,635 +0,0 @@ -// Bitcoin secp256k1 bindings -// Written in 2014 by -// Dawid Ciężarkiewicz -// Andrew Poelstra -// -// To the extent possible under law, the author(s) have dedicated all -// copyright and related and neighboring rights to this software to -// the public domain worldwide. This software is distributed without -// any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication -// along with this software. -// If not, see . -// - -//! # Public and secret keys - -use arrayvec::ArrayVec; -use rand::Rng; - -use super::Error::{self, IncapableContext, InvalidPublicKey, InvalidSecretKey}; -use super::{ContextFlag, Secp256k1}; -use constants; -use ffi; - -/// Secret 256-bit key used as `x` in an ECDSA signature -#[repr(C)] -pub struct SecretKey([u8; constants::SECRET_KEY_SIZE]); -impl_array_newtype!(SecretKey, u8, constants::SECRET_KEY_SIZE); -impl_pretty_debug!(SecretKey); - -impl From<[u8; constants::SECRET_KEY_SIZE]> for SecretKey { - fn from(raw: [u8; constants::SECRET_KEY_SIZE]) -> Self { - SecretKey(raw) - } -} - -/// The number 1 encoded as a secret key -/// Deprecated; `static` is not what I want; use `ONE_KEY` instead -pub static ONE: SecretKey = - SecretKey([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); - -/// The number 0 encoded as a secret key -pub const ZERO_KEY: SecretKey = - SecretKey([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - -/// The number 1 encoded as a secret key -pub const ONE_KEY: SecretKey = - SecretKey([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); - -/// The number 2 encoded as a secret key -pub const TWO_KEY: SecretKey = - SecretKey([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]); - -/// The number -1 encoded as a secret key -pub const MINUS_ONE_KEY: SecretKey = SecretKey([ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, - 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40, -]); - -/// A Secp256k1 public key, used for verification of signatures -#[derive(Copy, Clone, Default, PartialEq, Eq, Debug, Hash)] -pub struct PublicKey(ffi::PublicKey); - -fn random_32_bytes(rng: &mut R) -> [u8; 32] { - let mut ret = [0u8; 32]; - rng.fill_bytes(&mut ret); - ret -} - -impl SecretKey { - /// Creates a new random secret key - #[inline] - pub fn new(secp: &Secp256k1, rng: &mut R) -> SecretKey { - let mut data = random_32_bytes(rng); - unsafe { - while ffi::secp256k1_ec_seckey_verify(secp.ctx, data.as_ptr()) == 0 { - data = random_32_bytes(rng); - } - } - SecretKey(data) - } - - /// Converts a `SECRET_KEY_SIZE`-byte slice to a secret key - #[inline] - pub fn from_slice(secp: &Secp256k1, data: &[u8]) -> Result { - match data.len() { - constants::SECRET_KEY_SIZE => { - let mut ret = [0; constants::SECRET_KEY_SIZE]; - unsafe { - if ffi::secp256k1_ec_seckey_verify(secp.ctx, data.as_ptr()) == 0 { - return Err(InvalidSecretKey) - } - } - ret[..].copy_from_slice(data); - Ok(SecretKey(ret)) - } - _ => Err(InvalidSecretKey), - } - } - - #[inline] - /// Adds one secret key to another, modulo the curve order - pub fn add_assign(&mut self, secp: &Secp256k1, other: &SecretKey) -> Result<(), Error> { - unsafe { - if ffi::secp256k1_ec_privkey_tweak_add(secp.ctx, self.as_mut_ptr(), other.as_ptr()) != 1 { - Err(InvalidSecretKey) - } else { - Ok(()) - } - } - } - - #[inline] - /// Multiplies one secret key by another, modulo the curve order - pub fn mul_assign(&mut self, secp: &Secp256k1, other: &SecretKey) -> Result<(), Error> { - unsafe { - if ffi::secp256k1_ec_privkey_tweak_mul(secp.ctx, self.as_mut_ptr(), other.as_ptr()) != 1 { - Err(InvalidSecretKey) - } else { - Ok(()) - } - } - } - - #[inline] - /// Inverts (1 / self) this secret key. - pub fn inv_assign(&mut self, secp: &Secp256k1) -> Result<(), Error> { - let original = *self; - unsafe { - if ffi::secp256k1_ec_privkey_inverse(secp.ctx, self.as_mut_ptr(), original.as_ptr()) != 1 { - Err(InvalidSecretKey) - } else { - Ok(()) - } - } - } -} - -impl PublicKey { - /// Creates a new zeroed out public key - #[inline] - pub fn new() -> Self { - Self::default() - } - - /// Determines whether a pubkey is valid - #[inline] - pub fn is_valid(&self) -> bool { - // The only invalid pubkey the API should be able to create is - // the zero one. - self.0[..].iter().any(|&x| x != 0) - } - - /// Obtains a raw pointer suitable for use with FFI functions - #[inline] - pub fn as_ptr(&self) -> *const ffi::PublicKey { - &self.0 as *const _ - } - - /// Creates a new public key from a secret key. - #[inline] - pub fn from_secret_key(secp: &Secp256k1, sk: &SecretKey) -> Result { - if secp.caps == ContextFlag::VerifyOnly || secp.caps == ContextFlag::None { - return Err(IncapableContext) - } - let mut pk = unsafe { ffi::PublicKey::blank() }; - unsafe { - // We can assume the return value because it's not possible to construct - // an invalid `SecretKey` without transmute trickery or something - let res = ffi::secp256k1_ec_pubkey_create(secp.ctx, &mut pk, sk.as_ptr()); - debug_assert_eq!(res, 1); - } - Ok(PublicKey(pk)) - } - - /// Creates a public key directly from a slice - #[inline] - pub fn from_slice(secp: &Secp256k1, data: &[u8]) -> Result { - let mut pk = unsafe { ffi::PublicKey::blank() }; - unsafe { - if ffi::secp256k1_ec_pubkey_parse(secp.ctx, &mut pk, data.as_ptr(), data.len() as usize) == 1 { - Ok(PublicKey(pk)) - } else { - Err(InvalidPublicKey) - } - } - } - - #[inline] - /// Serialize the key as a byte-encoded pair of values. In compressed form - /// the y-coordinate is represented by only a single bit, as x determines - /// it up to one bit. - pub fn serialize_vec(&self, secp: &Secp256k1, compressed: bool) -> ArrayVec<[u8; constants::PUBLIC_KEY_SIZE]> { - let mut ret = ArrayVec::new(); - - unsafe { - let mut ret_len = constants::PUBLIC_KEY_SIZE as usize; - let compressed = if compressed { - ffi::SECP256K1_SER_COMPRESSED - } else { - ffi::SECP256K1_SER_UNCOMPRESSED - }; - let err = - ffi::secp256k1_ec_pubkey_serialize(secp.ctx, ret.as_ptr(), &mut ret_len, self.as_ptr(), compressed); - debug_assert_eq!(err, 1); - ret.set_len(ret_len as usize); - } - ret - } - - #[inline] - /// Adds the pk corresponding to `other` to the pk `self` in place - pub fn add_exp_assign(&mut self, secp: &Secp256k1, other: &SecretKey) -> Result<(), Error> { - if secp.caps == ContextFlag::SignOnly || secp.caps == ContextFlag::None { - return Err(IncapableContext) - } - unsafe { - if ffi::secp256k1_ec_pubkey_tweak_add(secp.ctx, &mut self.0 as *mut _, other.as_ptr()) == 1 { - Ok(()) - } else { - Err(InvalidSecretKey) - } - } - } - - #[inline] - /// Adds another point on the curve in place - pub fn add_assign(&mut self, secp: &Secp256k1, other: &PublicKey) -> Result<(), Error> { - let mut public = ffi::PublicKey::new(); - let res = unsafe { - if ffi::secp256k1_ec_pubkey_combine( - secp.ctx, - &mut public as *mut _, - [other.as_ptr(), self.as_ptr()].as_ptr(), - 2, - ) == 1 - { - Ok(()) - } else { - Err(InvalidSecretKey) - } - }; - if res.is_ok() { - self.0 = public - } - res - } - - #[inline] - /// Multiplies this point by `secret` scalar - pub fn mul_assign(&mut self, secp: &Secp256k1, other: &SecretKey) -> Result<(), Error> { - if secp.caps == ContextFlag::SignOnly || secp.caps == ContextFlag::None { - return Err(IncapableContext) - } - unsafe { - if ffi::secp256k1_ec_pubkey_tweak_mul(secp.ctx, &mut self.0 as *mut _, other.as_ptr()) == 1 { - Ok(()) - } else { - Err(InvalidSecretKey) - } - } - } -} - -/// Creates a new public key from a FFI public key -impl From for PublicKey { - #[inline] - fn from(pk: ffi::PublicKey) -> PublicKey { - PublicKey(pk) - } -} - -#[cfg(test)] -mod test { - use super::super::constants; - use super::super::Error::{IncapableContext, InvalidPublicKey, InvalidSecretKey}; - use super::super::{ContextFlag, Secp256k1}; - use super::{PublicKey, SecretKey}; - - use rand::{thread_rng, Error, RngCore}; - - #[test] - fn skey_from_slice() { - let s = Secp256k1::new(); - let sk = SecretKey::from_slice(&s, &[1; 31]); - assert_eq!(sk, Err(InvalidSecretKey)); - - let sk = SecretKey::from_slice(&s, &[1; 32]); - assert!(sk.is_ok()); - } - - #[test] - fn pubkey_from_slice() { - let s = Secp256k1::new(); - assert_eq!(PublicKey::from_slice(&s, &[]), Err(InvalidPublicKey)); - assert_eq!(PublicKey::from_slice(&s, &[1, 2, 3]), Err(InvalidPublicKey)); - - let uncompressed = PublicKey::from_slice(&s, &[ - 4, 54, 57, 149, 239, 162, 148, 175, 246, 254, 239, 75, 154, 152, 10, 82, 234, 224, 85, 220, 40, 100, 57, - 121, 30, 162, 94, 156, 135, 67, 74, 49, 179, 57, 236, 53, 162, 124, 149, 144, 168, 77, 74, 30, 72, 211, - 229, 110, 111, 55, 96, 193, 86, 227, 183, 152, 195, 155, 51, 247, 123, 113, 60, 228, 188, - ]); - assert!(uncompressed.is_ok()); - - let compressed = PublicKey::from_slice(&s, &[ - 3, 23, 183, 225, 206, 31, 159, 148, 195, 42, 67, 115, 146, 41, 248, 140, 11, 3, 51, 41, 111, 180, 110, 143, - 114, 134, 88, 73, 198, 174, 52, 184, 78, - ]); - assert!(compressed.is_ok()); - } - - #[test] - fn keypair_slice_round_trip() { - let s = Secp256k1::new(); - - let (sk1, pk1) = s.generate_keypair(&mut thread_rng()).unwrap(); - assert_eq!(SecretKey::from_slice(&s, &sk1[..]), Ok(sk1)); - assert_eq!(PublicKey::from_slice(&s, &pk1.serialize_vec(&s, true)[..]), Ok(pk1)); - assert_eq!(PublicKey::from_slice(&s, &pk1.serialize_vec(&s, false)[..]), Ok(pk1)); - } - - #[test] - fn invalid_secret_key() { - let s = Secp256k1::new(); - // Zero - assert_eq!(SecretKey::from_slice(&s, &[0; 32]), Err(InvalidSecretKey)); - // -1 - assert_eq!(SecretKey::from_slice(&s, &[0xff; 32]), Err(InvalidSecretKey)); - // Top of range - assert!(SecretKey::from_slice(&s, &[ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, - 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x40, - ]) - .is_ok()); - // One past top of range - assert!(SecretKey::from_slice(&s, &[ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, - 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41, - ]) - .is_err()); - } - - #[test] - fn pubkey_from_slice_bad_context() { - let s = Secp256k1::without_caps(); - let sk = SecretKey::new(&s, &mut thread_rng()); - assert_eq!(PublicKey::from_secret_key(&s, &sk), Err(IncapableContext)); - - let s = Secp256k1::with_caps(ContextFlag::VerifyOnly); - assert_eq!(PublicKey::from_secret_key(&s, &sk), Err(IncapableContext)); - - let s = Secp256k1::with_caps(ContextFlag::SignOnly); - assert!(PublicKey::from_secret_key(&s, &sk).is_ok()); - - let s = Secp256k1::with_caps(ContextFlag::Full); - assert!(PublicKey::from_secret_key(&s, &sk).is_ok()); - } - - #[test] - fn add_exp_bad_context() { - let s = Secp256k1::with_caps(ContextFlag::Full); - let (sk, mut pk) = s.generate_keypair(&mut thread_rng()).unwrap(); - - assert!(pk.add_exp_assign(&s, &sk).is_ok()); - - let s = Secp256k1::with_caps(ContextFlag::VerifyOnly); - assert!(pk.add_exp_assign(&s, &sk).is_ok()); - - let s = Secp256k1::with_caps(ContextFlag::SignOnly); - assert_eq!(pk.add_exp_assign(&s, &sk), Err(IncapableContext)); - - let s = Secp256k1::with_caps(ContextFlag::None); - assert_eq!(pk.add_exp_assign(&s, &sk), Err(IncapableContext)); - } - - #[test] - fn out_of_range() { - struct BadRng(u8); - impl RngCore for BadRng { - fn next_u32(&mut self) -> u32 { - unimplemented!() - } - fn next_u64(&mut self) -> u64 { - unimplemented!() - } - - // This will set a secret key to a little over the - // group order, then decrement with repeated calls - // until it returns a valid key - fn fill_bytes(&mut self, data: &mut [u8]) { - let group_order: [u8; 32] = [ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41, - ]; - assert_eq!(data.len(), 32); - data.copy_from_slice(&group_order[..]); - data[31] = self.0; - self.0 -= 1; - } - - fn try_fill_bytes(&mut self, data: &mut [u8]) -> Result<(), Error> { - self.fill_bytes(data); - Ok(()) - } - } - - let s = Secp256k1::new(); - s.generate_keypair(&mut BadRng(0xff)).unwrap(); - } - - #[test] - fn pubkey_from_bad_slice() { - let s = Secp256k1::new(); - // Bad sizes - assert_eq!(PublicKey::from_slice(&s, &[0; constants::COMPRESSED_PUBLIC_KEY_SIZE - 1]), Err(InvalidPublicKey)); - assert_eq!(PublicKey::from_slice(&s, &[0; constants::COMPRESSED_PUBLIC_KEY_SIZE + 1]), Err(InvalidPublicKey)); - assert_eq!(PublicKey::from_slice(&s, &[0; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE - 1]), Err(InvalidPublicKey)); - assert_eq!(PublicKey::from_slice(&s, &[0; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE + 1]), Err(InvalidPublicKey)); - - // Bad parse - assert_eq!(PublicKey::from_slice(&s, &[0xff; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]), Err(InvalidPublicKey)); - assert_eq!(PublicKey::from_slice(&s, &[0x55; constants::COMPRESSED_PUBLIC_KEY_SIZE]), Err(InvalidPublicKey)); - } - - #[test] - fn debug_output() { - struct DumbRng(u32); - impl RngCore for DumbRng { - fn next_u32(&mut self) -> u32 { - self.0 = self.0.wrapping_add(1); - self.0 - } - fn next_u64(&mut self) -> u64 { - (u64::from(self.next_u32()) << 32) | u64::from(self.next_u32()) - } - fn fill_bytes(&mut self, dest: &mut [u8]) { - // this could, in theory, be done by transmuting dest to a - // [u64], but this is (1) likely to be undefined behaviour for - // LLVM, (2) has to be very careful about alignment concerns, - // (3) adds more `unsafe` that needs to be checked, (4) - // probably doesn't give much performance gain if - // optimisations are on. - let mut count = 0; - let mut num = 0; - for byte in dest.iter_mut() { - if count == 0 { - // we could micro-optimise here by generating a u32 if - // we only need a few more bytes to fill the vector - // (i.e. at most 4). - num = self.next_u64(); - count = 8; - } - - *byte = (num & 0xff) as u8; - num >>= 8; - count -= 1; - } - } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.fill_bytes(dest); - Ok(()) - } - } - - let s = Secp256k1::new(); - let (sk, _) = s.generate_keypair(&mut DumbRng(0)).unwrap(); - - assert_eq!(&format!("{:?}", sk), "SecretKey(0200000001000000040000000300000006000000050000000800000007000000)"); - } - - #[test] - fn pubkey_serialize() { - struct DumbRng(u32); - impl RngCore for DumbRng { - fn next_u32(&mut self) -> u32 { - self.0 = self.0.wrapping_add(1); - self.0 - } - fn next_u64(&mut self) -> u64 { - (u64::from(self.next_u32()) << 32) | u64::from(self.next_u32()) - } - fn fill_bytes(&mut self, dest: &mut [u8]) { - // this could, in theory, be done by transmuting dest to a - // [u64], but this is (1) likely to be undefined behaviour for - // LLVM, (2) has to be very careful about alignment concerns, - // (3) adds more `unsafe` that needs to be checked, (4) - // probably doesn't give much performance gain if - // optimisations are on. - let mut count = 0; - let mut num = 0; - for byte in dest.iter_mut() { - if count == 0 { - // we could micro-optimise here by generating a u32 if - // we only need a few more bytes to fill the vector - // (i.e. at most 4). - num = self.next_u64(); - count = 8; - } - - *byte = (num & 0xff) as u8; - num >>= 8; - count -= 1; - } - } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.fill_bytes(dest); - Ok(()) - } - } - - let s = Secp256k1::new(); - let (_, pk1) = s.generate_keypair(&mut DumbRng(0)).unwrap(); - assert_eq!( - &pk1.serialize_vec(&s, false)[..], - &[ - 4, 149, 16, 196, 140, 38, 92, 239, 179, 65, 59, 224, 230, 183, 91, 238, 240, 46, 186, 252, 175, 102, - 52, 249, 98, 178, 123, 72, 50, 171, 196, 254, 236, 1, 189, 143, 242, 227, 16, 87, 247, 183, 162, 68, - 237, 140, 92, 205, 151, 129, 166, 58, 111, 96, 123, 64, 180, 147, 51, 12, 209, 89, 236, 213, 206, - ][..] - ); - assert_eq!( - &pk1.serialize_vec(&s, true)[..], - &[ - 2, 149, 16, 196, 140, 38, 92, 239, 179, 65, 59, 224, 230, 183, 91, 238, 240, 46, 186, 252, 175, 102, - 52, 249, 98, 178, 123, 72, 50, 171, 196, 254, 236, - ][..] - ); - } - - #[test] - fn addition() { - let s = Secp256k1::new(); - - let (mut sk1, mut pk1) = s.generate_keypair(&mut thread_rng()).unwrap(); - let (mut sk2, mut pk2) = s.generate_keypair(&mut thread_rng()).unwrap(); - - assert_eq!(PublicKey::from_secret_key(&s, &sk1).unwrap(), pk1); - assert!(sk1.add_assign(&s, &sk2).is_ok()); - assert!(pk1.add_exp_assign(&s, &sk2).is_ok()); - assert_eq!(PublicKey::from_secret_key(&s, &sk1).unwrap(), pk1); - - assert_eq!(PublicKey::from_secret_key(&s, &sk2).unwrap(), pk2); - assert!(sk2.add_assign(&s, &sk1).is_ok()); - assert!(pk2.add_exp_assign(&s, &sk1).is_ok()); - assert_eq!(PublicKey::from_secret_key(&s, &sk2).unwrap(), pk2); - } - - #[test] - fn multiplication() { - let s = Secp256k1::new(); - - let (mut sk1, mut pk1) = s.generate_keypair(&mut thread_rng()).unwrap(); - let (mut sk2, mut pk2) = s.generate_keypair(&mut thread_rng()).unwrap(); - - assert_eq!(PublicKey::from_secret_key(&s, &sk1).unwrap(), pk1); - assert!(sk1.mul_assign(&s, &sk2).is_ok()); - assert!(pk1.mul_assign(&s, &sk2).is_ok()); - assert_eq!(PublicKey::from_secret_key(&s, &sk1).unwrap(), pk1); - - assert_eq!(PublicKey::from_secret_key(&s, &sk2).unwrap(), pk2); - assert!(sk2.mul_assign(&s, &sk1).is_ok()); - assert!(pk2.mul_assign(&s, &sk1).is_ok()); - assert_eq!(PublicKey::from_secret_key(&s, &sk2).unwrap(), pk2); - } - - #[test] - fn pubkey_hash() { - use std::collections::hash_map::DefaultHasher; - use std::collections::HashSet; - use std::hash::{Hash, Hasher}; - - fn hash(t: &T) -> u64 { - let mut s = DefaultHasher::new(); - t.hash(&mut s); - s.finish() - } - - let s = Secp256k1::new(); - let mut set = HashSet::new(); - const COUNT: usize = 1024; - let count = (0..COUNT) - .map(|_| { - let (_, pk) = s.generate_keypair(&mut thread_rng()).unwrap(); - let hash = hash(&pk); - assert!(!set.contains(&hash)); - set.insert(hash); - }) - .count(); - assert_eq!(count, COUNT); - } - - #[test] - fn pubkey_add() { - let s = Secp256k1::new(); - let (_, mut pk1) = s.generate_keypair(&mut thread_rng()).unwrap(); - let (_, pk2) = s.generate_keypair(&mut thread_rng()).unwrap(); - - let result = pk1.add_assign(&s, &pk2); - - assert!(result.is_ok()); - } - - #[test] - fn pubkey_mul() { - let s = Secp256k1::new(); - let (_, mut pk1) = s.generate_keypair(&mut thread_rng()).unwrap(); - let (sk2, _) = s.generate_keypair(&mut thread_rng()).unwrap(); - - let result = pk1.mul_assign(&s, &sk2); - - assert!(result.is_ok()); - } - - #[test] - fn skey_mul() { - let s = Secp256k1::new(); - let (mut sk1, _) = s.generate_keypair(&mut thread_rng()).unwrap(); - let (sk2, _) = s.generate_keypair(&mut thread_rng()).unwrap(); - - let result = sk1.mul_assign(&s, &sk2); - - assert!(result.is_ok()); - } - - #[test] - fn skey_inv() { - let s = Secp256k1::new(); - let (mut sk, _) = s.generate_keypair(&mut thread_rng()).unwrap(); - - let result = sk.inv_assign(&s); - - assert!(result.is_ok()); - } -} diff --git a/util/secp256k1/src/lib.rs b/util/secp256k1/src/lib.rs deleted file mode 100644 index 21b37dc0d4..0000000000 --- a/util/secp256k1/src/lib.rs +++ /dev/null @@ -1,964 +0,0 @@ -// Bitcoin secp256k1 bindings -// Written in 2014 by -// Dawid Ciężarkiewicz -// Andrew Poelstra -// -// To the extent possible under law, the author(s) have dedicated all -// copyright and related and neighboring rights to this software to -// the public domain worldwide. This software is distributed without -// any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication -// along with this software. -// If not, see . -// - -//! # Secp256k1 -//! Rust bindings for Pieter Wuille's secp256k1 library, which is used for -//! fast and accurate manipulation of ECDSA signatures on the secp256k1 -//! curve. Such signatures are used extensively by the Bitcoin network -//! and its derivatives. -//! - -#![crate_type = "lib"] -#![crate_type = "rlib"] -#![crate_type = "dylib"] -#![crate_name = "secp256k1"] -// Coding conventions -#![deny(non_upper_case_globals)] -#![deny(non_camel_case_types)] -#![deny(non_snake_case)] -#![deny(unused_mut)] -#![warn(missing_docs)] -#![cfg_attr(feature = "dev", allow(unstable_features))] -#![cfg_attr(feature = "dev", feature(plugin))] -#![cfg_attr(feature = "dev", plugin(clippy))] -#![cfg_attr(all(test, feature = "unstable"), feature(test))] -#[cfg(all(test, feature = "unstable"))] -extern crate test; - -extern crate arrayvec; -extern crate rand; - -use rand::Rng; -use std::{error, fmt, ops, ptr}; - -#[macro_use] -mod macros; -pub mod constants; -pub mod ecdh; -pub mod ffi; -pub mod key; -pub mod schnorr; - -/// A tag used for recovering the public key from a compact signature -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub struct RecoveryId(i32); - -/// An ECDSA signature -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub struct Signature(ffi::Signature); - -/// An ECDSA signature with a recovery ID for pubkey recovery -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub struct RecoverableSignature(ffi::RecoverableSignature); - -impl RecoveryId { - #[inline] - /// Allows library users to create valid recovery IDs from i32. - pub fn from_i32(id: i32) -> Result { - match id { - 0 | 1 | 2 | 3 => Ok(RecoveryId(id)), - _ => Err(Error::InvalidRecoveryId), - } - } -} - -impl From for i32 { - /// Allows library users to convert recovery IDs to i32. - #[inline] - fn from(id: RecoveryId) -> Self { - id.0 - } -} - -impl Signature { - #[inline] - /// Converts a DER-encoded byte slice to a signature - pub fn from_der(secp: &Secp256k1, data: &[u8]) -> Result { - let mut ret = unsafe { ffi::Signature::blank() }; - - unsafe { - if ffi::secp256k1_ecdsa_signature_parse_der(secp.ctx, &mut ret, data.as_ptr(), data.len() as usize) == 1 { - Ok(Signature(ret)) - } else { - Err(Error::InvalidSignature) - } - } - } - - /// Converts a "lax DER"-encoded byte slice to a signature. This is basically - /// only useful for validating signatures in the Bitcoin blockchain from before - /// 2016. It should never be used in new applications. This library does not - /// support serializing to this "format" - pub fn from_der_lax(secp: &Secp256k1, data: &[u8]) -> Result { - unsafe { - let mut ret = ffi::Signature::blank(); - if ffi::ecdsa_signature_parse_der_lax(secp.ctx, &mut ret, data.as_ptr(), data.len() as usize) == 1 { - Ok(Signature(ret)) - } else { - Err(Error::InvalidSignature) - } - } - } - - /// Normalizes a signature to a "low S" form. In ECDSA, signatures are - /// of the form (r, s) where r and s are numbers lying in some finite - /// field. The verification equation will pass for (r, s) iff it passes - /// for (r, -s), so it is possible to ``modify'' signatures in transit - /// by flipping the sign of s. This does not constitute a forgery since - /// the signed message still cannot be changed, but for some applications, - /// changing even the signature itself can be a problem. Such applications - /// require a "strong signature". It is believed that ECDSA is a strong - /// signature except for this ambiguity in the sign of s, so to accomodate - /// these applications libsecp256k1 will only accept signatures for which - /// s is in the lower half of the field range. This eliminates the - /// ambiguity. - /// - /// However, for some systems, signatures with high s-values are considered - /// valid. (For example, parsing the historic Bitcoin blockchain requires - /// this.) For these applications we provide this normalization function, - /// which ensures that the s value lies in the lower half of its range. - pub fn normalize_s(&mut self, secp: &Secp256k1) { - unsafe { - // Ignore return value, which indicates whether the sig - // was already normalized. We don't care. - ffi::secp256k1_ecdsa_signature_normalize(secp.ctx, self.as_mut_ptr(), self.as_ptr()); - } - } - - /// Obtains a raw pointer suitable for use with FFI functions - #[inline] - pub fn as_ptr(&self) -> *const ffi::Signature { - &self.0 as *const _ - } - - /// Obtains a raw mutable pointer suitable for use with FFI functions - #[inline] - pub fn as_mut_ptr(&mut self) -> *mut ffi::Signature { - &mut self.0 as *mut _ - } - - #[inline] - /// Serializes the signature in DER format - pub fn serialize_der(&self, secp: &Secp256k1) -> Vec { - let mut ret = Vec::with_capacity(72); - let mut len: usize = ret.capacity() as usize; - unsafe { - let err = ffi::secp256k1_ecdsa_signature_serialize_der(secp.ctx, ret.as_mut_ptr(), &mut len, self.as_ptr()); - debug_assert!(err == 1); - ret.set_len(len as usize); - } - ret - } -} - -/// Creates a new signature from a FFI signature -impl From for Signature { - #[inline] - fn from(sig: ffi::Signature) -> Signature { - Signature(sig) - } -} - - -impl RecoverableSignature { - #[inline] - /// Converts a compact-encoded byte slice to a signature. This - /// representation is nonstandard and defined by the libsecp256k1 - /// library. - pub fn from_compact(secp: &Secp256k1, data: &[u8], recid: RecoveryId) -> Result { - let mut ret = unsafe { ffi::RecoverableSignature::blank() }; - - unsafe { - if data.len() != 64 { - Err(Error::InvalidSignature) - } else if ffi::secp256k1_ecdsa_recoverable_signature_parse_compact( - secp.ctx, - &mut ret, - data.as_ptr(), - recid.0, - ) == 1 - { - Ok(RecoverableSignature(ret)) - } else { - Err(Error::InvalidSignature) - } - } - } - - /// Obtains a raw pointer suitable for use with FFI functions - #[inline] - pub fn as_ptr(&self) -> *const ffi::RecoverableSignature { - &self.0 as *const _ - } - - #[inline] - /// Serializes the recoverable signature in compact format - pub fn serialize_compact(&self, secp: &Secp256k1) -> (RecoveryId, [u8; 64]) { - let mut ret = [0u8; 64]; - let mut recid = 0i32; - unsafe { - let err = ffi::secp256k1_ecdsa_recoverable_signature_serialize_compact( - secp.ctx, - ret.as_mut_ptr(), - &mut recid, - self.as_ptr(), - ); - assert!(err == 1); - } - (RecoveryId(recid), ret) - } - - /// Converts a recoverable signature to a non-recoverable one (this is needed - /// for verification - #[inline] - pub fn to_standard(&self, secp: &Secp256k1) -> Signature { - let mut ret = unsafe { ffi::Signature::blank() }; - unsafe { - let err = ffi::secp256k1_ecdsa_recoverable_signature_convert(secp.ctx, &mut ret, self.as_ptr()); - assert!(err == 1); - } - Signature(ret) - } -} - -/// Creates a new recoverable signature from a FFI one -impl From for RecoverableSignature { - #[inline] - fn from(sig: ffi::RecoverableSignature) -> RecoverableSignature { - RecoverableSignature(sig) - } -} - -impl ops::Index for Signature { - type Output = u8; - - #[inline] - fn index(&self, index: usize) -> &u8 { - &self.0[index] - } -} - -impl ops::Index> for Signature { - type Output = [u8]; - - #[inline] - fn index(&self, index: ops::Range) -> &[u8] { - &self.0[index] - } -} - -impl ops::Index> for Signature { - type Output = [u8]; - - #[inline] - fn index(&self, index: ops::RangeFrom) -> &[u8] { - &self.0[index.start..] - } -} - -impl ops::Index for Signature { - type Output = [u8]; - - #[inline] - fn index(&self, _: ops::RangeFull) -> &[u8] { - &self.0[..] - } -} - -/// A (hashed) message input to an ECDSA signature -pub struct Message([u8; constants::MESSAGE_SIZE]); -impl_array_newtype!(Message, u8, constants::MESSAGE_SIZE); -impl_pretty_debug!(Message); - -impl Message { - /// Converts a `MESSAGE_SIZE`-byte slice to a message object - #[inline] - pub fn from_slice(data: &[u8]) -> Result { - match data.len() { - constants::MESSAGE_SIZE => { - let mut ret = [0; constants::MESSAGE_SIZE]; - ret[..].copy_from_slice(data); - Ok(Message(ret)) - } - _ => Err(Error::InvalidMessage), - } - } -} - -/// Creates a message from a `MESSAGE_SIZE` byte array -impl From<[u8; constants::MESSAGE_SIZE]> for Message { - fn from(buf: [u8; constants::MESSAGE_SIZE]) -> Message { - Message(buf) - } -} - -/// An ECDSA error -#[derive(Copy, PartialEq, Eq, Clone, Debug)] -pub enum Error { - /// A `Secp256k1` was used for an operation, but it was not created to - /// support this (so necessary precomputations have not been done) - IncapableContext, - /// Signature failed verification - IncorrectSignature, - /// Badly sized message ("messages" are actually fixed-sized digests; see the `MESSAGE_SIZE` - /// constant) - InvalidMessage, - /// Bad public key - InvalidPublicKey, - /// Bad signature - InvalidSignature, - /// Bad secret key - InvalidSecretKey, - /// Bad recovery id - InvalidRecoveryId, -} - -// Passthrough Debug to Display, since errors should be user-visible -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - f.write_str(error::Error::description(self)) - } -} - -impl error::Error for Error { - fn cause(&self) -> Option<&dyn error::Error> { - None - } - - fn description(&self) -> &str { - match *self { - Error::IncapableContext => "secp: context does not have sufficient capabilities", - Error::IncorrectSignature => "secp: signature failed verification", - Error::InvalidMessage => "secp: message was not 32 bytes (do you need to hash?)", - Error::InvalidPublicKey => "secp: malformed public key", - Error::InvalidSignature => "secp: malformed signature", - Error::InvalidSecretKey => "secp: malformed or out-of-range secret key", - Error::InvalidRecoveryId => "secp: bad recovery id", - } - } -} - -/// The secp256k1 engine, used to execute all signature operations -pub struct Secp256k1 { - ctx: *mut ffi::Context, - caps: ContextFlag, -} - -unsafe impl Send for Secp256k1 {} -unsafe impl Sync for Secp256k1 {} - -/// Flags used to determine the capabilities of a `Secp256k1` object; -/// the more capabilities, the more expensive it is to create. -#[derive(PartialEq, Eq, Copy, Clone, Debug)] -pub enum ContextFlag { - /// Can neither sign nor verify signatures (cheapest to create, useful - /// for cases not involving signatures, such as creating keys from slices) - None, - /// Can sign but not verify signatures - SignOnly, - /// Can verify but not create signatures - VerifyOnly, - /// Can verify and create signatures - Full, -} - -// Passthrough Debug to Display, since caps should be user-visible -impl fmt::Display for ContextFlag { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - fmt::Debug::fmt(self, f) - } -} - -impl Clone for Secp256k1 { - fn clone(&self) -> Secp256k1 { - Secp256k1 { - ctx: unsafe { ffi::secp256k1_context_clone(self.ctx) }, - caps: self.caps, - } - } -} - -impl PartialEq for Secp256k1 { - fn eq(&self, other: &Secp256k1) -> bool { - self.caps == other.caps - } -} -impl Eq for Secp256k1 {} - -impl fmt::Debug for Secp256k1 { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(f, "Secp256k1 {{ [private], caps: {:?} }}", self.caps) - } -} - -impl Drop for Secp256k1 { - fn drop(&mut self) { - unsafe { - ffi::secp256k1_context_destroy(self.ctx); - } - } -} - -impl Secp256k1 { - /// Creates a new Secp256k1 context - #[inline] - pub fn new() -> Self { - Self::default() - } - - /// Creates a new Secp256k1 context with the specified capabilities - pub fn with_caps(caps: ContextFlag) -> Secp256k1 { - let flag = match caps { - ContextFlag::None => ffi::SECP256K1_START_NONE, - ContextFlag::SignOnly => ffi::SECP256K1_START_SIGN, - ContextFlag::VerifyOnly => ffi::SECP256K1_START_VERIFY, - ContextFlag::Full => ffi::SECP256K1_START_SIGN | ffi::SECP256K1_START_VERIFY, - }; - Secp256k1 { - ctx: unsafe { ffi::secp256k1_context_create(flag) }, - caps, - } - } - - /// Creates a new Secp256k1 context with no capabilities (just de/serialization) - pub fn without_caps() -> Secp256k1 { - Secp256k1::with_caps(ContextFlag::None) - } - - /// (Re)randomizes the Secp256k1 context for cheap sidechannel resistence; - /// see comment in libsecp256k1 commit d2275795f by Gregory Maxwell - pub fn randomize(&mut self, rng: &mut R) { - let mut seed = [0; 32]; - rng.fill_bytes(&mut seed); - unsafe { - let err = ffi::secp256k1_context_randomize(self.ctx, seed.as_ptr()); - // This function cannot fail; it has an error return for future-proofing. - // We do not expose this error since it is impossible to hit, and we have - // precedent for not exposing impossible errors (for example in - // `PublicKey::from_secret_key` where it is impossble to create an invalid - // secret key through the API.) - // However, if this DOES fail, the result is potentially weaker side-channel - // resistance, which is deadly and undetectable, so we take out the entire - // thread to be on the safe side. - assert!(err == 1); - } - } - - /// Generates a random keypair. Convenience function for `key::SecretKey::new` - /// and `key::PublicKey::from_secret_key`; call those functions directly for - /// batch key generation. Requires a signing-capable context. - #[inline] - pub fn generate_keypair(&self, rng: &mut R) -> Result<(key::SecretKey, key::PublicKey), Error> { - let sk = key::SecretKey::new(self, rng); - let pk = key::PublicKey::from_secret_key(self, &sk)?; - Ok((sk, pk)) - } - - /// Constructs a signature for `msg` using the secret key `sk` and RFC6979 nonce - /// Requires a signing-capable context. - pub fn sign(&self, msg: &Message, sk: &key::SecretKey) -> Result { - if self.caps == ContextFlag::VerifyOnly || self.caps == ContextFlag::None { - return Err(Error::IncapableContext) - } - - let mut ret = unsafe { ffi::Signature::blank() }; - unsafe { - // We can assume the return value because it's not possible to construct - // an invalid signature from a valid `Message` and `SecretKey` - assert_eq!( - ffi::secp256k1_ecdsa_sign( - self.ctx, - &mut ret, - msg.as_ptr(), - sk.as_ptr(), - ffi::secp256k1_nonce_function_rfc6979, - ptr::null() - ), - 1 - ); - } - Ok(Signature::from(ret)) - } - - /// Constructs a signature for `msg` using the secret key `sk` and RFC6979 nonce - /// Requires a signing-capable context. - pub fn sign_recoverable(&self, msg: &Message, sk: &key::SecretKey) -> Result { - if self.caps == ContextFlag::VerifyOnly || self.caps == ContextFlag::None { - return Err(Error::IncapableContext) - } - - let mut ret = unsafe { ffi::RecoverableSignature::blank() }; - unsafe { - // We can assume the return value because it's not possible to construct - // an invalid signature from a valid `Message` and `SecretKey` - assert_eq!( - ffi::secp256k1_ecdsa_sign_recoverable( - self.ctx, - &mut ret, - msg.as_ptr(), - sk.as_ptr(), - ffi::secp256k1_nonce_function_rfc6979, - ptr::null() - ), - 1 - ); - } - Ok(RecoverableSignature::from(ret)) - } - - /// Determines the public key for which `sig` is a valid signature for - /// `msg`. Requires a verify-capable context. - pub fn recover(&self, msg: &Message, sig: &RecoverableSignature) -> Result { - if self.caps == ContextFlag::SignOnly || self.caps == ContextFlag::None { - return Err(Error::IncapableContext) - } - - let mut pk = unsafe { ffi::PublicKey::blank() }; - - unsafe { - if ffi::secp256k1_ecdsa_recover(self.ctx, &mut pk, sig.as_ptr(), msg.as_ptr()) != 1 { - return Err(Error::InvalidSignature) - } - }; - Ok(key::PublicKey::from(pk)) - } - - /// Checks that `sig` is a valid ECDSA signature for `msg` using the public - /// key `pubkey`. Returns `Ok(true)` on success. Note that this function cannot - /// be used for Bitcoin consensus checking since there may exist signatures - /// which OpenSSL would verify but not libsecp256k1, or vice-versa. Requires a - /// verify-capable context. - #[inline] - pub fn verify(&self, msg: &Message, sig: &Signature, pk: &key::PublicKey) -> Result<(), Error> { - if self.caps == ContextFlag::SignOnly || self.caps == ContextFlag::None { - return Err(Error::IncapableContext) - } - - if !pk.is_valid() { - Err(Error::InvalidPublicKey) - } else if unsafe { ffi::secp256k1_ecdsa_verify(self.ctx, sig.as_ptr(), msg.as_ptr(), pk.as_ptr()) } == 0 { - Err(Error::IncorrectSignature) - } else { - Ok(()) - } - } -} - -impl Default for Secp256k1 { - fn default() -> Secp256k1 { - Secp256k1::with_caps(ContextFlag::Full) - } -} - - -#[cfg(test)] -mod tests { - extern crate hex; - use rand::{thread_rng, RngCore}; - - use super::constants; - use super::Error::{IncapableContext, IncorrectSignature, InvalidMessage, InvalidPublicKey, InvalidSignature}; - use super::{ContextFlag, Message, RecoverableSignature, RecoveryId, Secp256k1, Signature}; - use key::{PublicKey, SecretKey}; - - macro_rules! hex (($hex:expr) => (hex::decode($hex).unwrap())); - - #[test] - #[allow(clippy::cognitive_complexity)] - fn capabilities() { - let none = Secp256k1::with_caps(ContextFlag::None); - let sign = Secp256k1::with_caps(ContextFlag::SignOnly); - let vrfy = Secp256k1::with_caps(ContextFlag::VerifyOnly); - let full = Secp256k1::with_caps(ContextFlag::Full); - - let mut msg = [0u8; 32]; - thread_rng().fill_bytes(&mut msg); - let msg = Message::from_slice(&msg).unwrap(); - - // Try key generation - assert_eq!(none.generate_keypair(&mut thread_rng()), Err(IncapableContext)); - assert_eq!(vrfy.generate_keypair(&mut thread_rng()), Err(IncapableContext)); - assert!(sign.generate_keypair(&mut thread_rng()).is_ok()); - assert!(full.generate_keypair(&mut thread_rng()).is_ok()); - let (sk, pk) = full.generate_keypair(&mut thread_rng()).unwrap(); - - // Try signing - assert_eq!(none.sign(&msg, &sk), Err(IncapableContext)); - assert_eq!(vrfy.sign(&msg, &sk), Err(IncapableContext)); - assert!(sign.sign(&msg, &sk).is_ok()); - assert!(full.sign(&msg, &sk).is_ok()); - assert_eq!(none.sign_recoverable(&msg, &sk), Err(IncapableContext)); - assert_eq!(vrfy.sign_recoverable(&msg, &sk), Err(IncapableContext)); - assert!(sign.sign_recoverable(&msg, &sk).is_ok()); - assert!(full.sign_recoverable(&msg, &sk).is_ok()); - assert_eq!(sign.sign(&msg, &sk), full.sign(&msg, &sk)); - assert_eq!(sign.sign_recoverable(&msg, &sk), full.sign_recoverable(&msg, &sk)); - let sig = full.sign(&msg, &sk).unwrap(); - let sigr = full.sign_recoverable(&msg, &sk).unwrap(); - - // Try verifying - assert_eq!(none.verify(&msg, &sig, &pk), Err(IncapableContext)); - assert_eq!(sign.verify(&msg, &sig, &pk), Err(IncapableContext)); - assert!(vrfy.verify(&msg, &sig, &pk).is_ok()); - assert!(full.verify(&msg, &sig, &pk).is_ok()); - - // Try pk recovery - assert_eq!(none.recover(&msg, &sigr), Err(IncapableContext)); - assert_eq!(sign.recover(&msg, &sigr), Err(IncapableContext)); - assert!(vrfy.recover(&msg, &sigr).is_ok()); - assert!(full.recover(&msg, &sigr).is_ok()); - - assert_eq!(vrfy.recover(&msg, &sigr), full.recover(&msg, &sigr)); - assert_eq!(full.recover(&msg, &sigr), Ok(pk)); - - // Check that we can produce keys from slices with no precomputation - let (pk_slice, sk_slice) = (&pk.serialize_vec(&none, true), &sk[..]); - let new_pk = PublicKey::from_slice(&none, pk_slice).unwrap(); - let new_sk = SecretKey::from_slice(&none, sk_slice).unwrap(); - assert_eq!(sk, new_sk); - assert_eq!(pk, new_pk); - } - - #[test] - fn invalid_pubkey() { - let s = Secp256k1::new(); - let sig = RecoverableSignature::from_compact(&s, &[1; 64], RecoveryId(0)).unwrap(); - let pk = PublicKey::new(); - let mut msg = [0u8; 32]; - thread_rng().fill_bytes(&mut msg); - let msg = Message::from_slice(&msg).unwrap(); - - assert_eq!(s.verify(&msg, &sig.to_standard(&s), &pk), Err(InvalidPublicKey)); - } - - #[test] - fn sign() { - let mut s = Secp256k1::new(); - s.randomize(&mut thread_rng()); - let one = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]; - - let sk = SecretKey::from_slice(&s, &one).unwrap(); - let msg = Message::from_slice(&one).unwrap(); - - let sig = s.sign_recoverable(&msg, &sk).unwrap(); - assert_eq!( - Ok(sig), - RecoverableSignature::from_compact( - &s, - &[ - 0x66, 0x73, 0xff, 0xad, 0x21, 0x47, 0x74, 0x1f, 0x04, 0x77, 0x2b, 0x6f, 0x92, 0x1f, 0x0b, 0xa6, - 0xaf, 0x0c, 0x1e, 0x77, 0xfc, 0x43, 0x9e, 0x65, 0xc3, 0x6d, 0xed, 0xf4, 0x09, 0x2e, 0x88, 0x98, - 0x4c, 0x1a, 0x97, 0x16, 0x52, 0xe0, 0xad, 0xa8, 0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f, - 0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, 0xae, 0x06, 0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89, - ], - RecoveryId(1) - ) - ) - } - - #[test] - fn signature_der_roundtrip() { - let mut s = Secp256k1::new(); - s.randomize(&mut thread_rng()); - - let mut msg = [0; 32]; - for _ in 0..100 { - thread_rng().fill_bytes(&mut msg); - let msg = Message::from_slice(&msg).unwrap(); - - let (sk, _) = s.generate_keypair(&mut thread_rng()).unwrap(); - let sig1 = s.sign(&msg, &sk).unwrap(); - let der = sig1.serialize_der(&s); - let sig2 = Signature::from_der(&s, &der[..]).unwrap(); - assert_eq!(sig1, sig2); - } - } - - #[test] - fn signature_lax_der() { - macro_rules! check_lax_sig( - ($hex:expr) => ({ - let secp = Secp256k1::without_caps(); - let sig = hex!($hex); - assert!(Signature::from_der_lax(&secp, &sig[..]).is_ok()); - }) - ); - - check_lax_sig!("304402204c2dd8a9b6f8d425fcd8ee9a20ac73b619906a6367eac6cb93e70375225ec0160220356878eff111ff3663d7e6bf08947f94443845e0dcc54961664d922f7660b80c"); - check_lax_sig!("304402202ea9d51c7173b1d96d331bd41b3d1b4e78e66148e64ed5992abd6ca66290321c0220628c47517e049b3e41509e9d71e480a0cdc766f8cdec265ef0017711c1b5336f"); - check_lax_sig!("3045022100bf8e050c85ffa1c313108ad8c482c4849027937916374617af3f2e9a881861c9022023f65814222cab09d5ec41032ce9c72ca96a5676020736614de7b78a4e55325a"); - check_lax_sig!("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45"); - check_lax_sig!("3046022100eaa5f90483eb20224616775891397d47efa64c68b969db1dacb1c30acdfc50aa022100cf9903bbefb1c8000cf482b0aeeb5af19287af20bd794de11d82716f9bae3db1"); - check_lax_sig!("3045022047d512bc85842ac463ca3b669b62666ab8672ee60725b6c06759e476cebdc6c102210083805e93bd941770109bcc797784a71db9e48913f702c56e60b1c3e2ff379a60"); - check_lax_sig!("3044022023ee4e95151b2fbbb08a72f35babe02830d14d54bd7ed1320e4751751d1baa4802206235245254f58fd1be6ff19ca291817da76da65c2f6d81d654b5185dd86b8acf"); - } - - #[test] - fn sign_and_verify() { - let mut s = Secp256k1::new(); - s.randomize(&mut thread_rng()); - - let mut msg = [0; 32]; - for _ in 0..100 { - thread_rng().fill_bytes(&mut msg); - let msg = Message::from_slice(&msg).unwrap(); - - let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap(); - let sig = s.sign(&msg, &sk).unwrap(); - assert_eq!(s.verify(&msg, &sig, &pk), Ok(())); - } - } - - #[test] - fn sign_and_verify_extreme() { - let mut s = Secp256k1::new(); - s.randomize(&mut thread_rng()); - - // Wild keys: 1, CURVE_ORDER - 1 - // Wild msgs: 0, 1, CURVE_ORDER - 1, CURVE_ORDER - let mut wild_keys = [[0; 32]; 2]; - let mut wild_msgs = [[0; 32]; 4]; - - wild_keys[0][0] = 1; - wild_msgs[1][0] = 1; - - use constants; - wild_keys[1][..].copy_from_slice(&constants::CURVE_ORDER[..]); - wild_msgs[1][..].copy_from_slice(&constants::CURVE_ORDER[..]); - wild_msgs[2][..].copy_from_slice(&constants::CURVE_ORDER[..]); - - wild_keys[1][0] -= 1; - wild_msgs[1][0] -= 1; - - for key in wild_keys.iter().map(|k| SecretKey::from_slice(&s, &k[..]).unwrap()) { - for msg in wild_msgs.iter().map(|m| Message::from_slice(&m[..]).unwrap()) { - let sig = s.sign(&msg, &key).unwrap(); - let pk = PublicKey::from_secret_key(&s, &key).unwrap(); - assert_eq!(s.verify(&msg, &sig, &pk), Ok(())); - } - } - } - - #[test] - fn sign_and_verify_fail() { - let mut s = Secp256k1::new(); - s.randomize(&mut thread_rng()); - - let mut msg = [0u8; 32]; - thread_rng().fill_bytes(&mut msg); - let msg = Message::from_slice(&msg).unwrap(); - - let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap(); - - let sigr = s.sign_recoverable(&msg, &sk).unwrap(); - let sig = sigr.to_standard(&s); - - let mut msg = [0u8; 32]; - thread_rng().fill_bytes(&mut msg); - let msg = Message::from_slice(&msg).unwrap(); - assert_eq!(s.verify(&msg, &sig, &pk), Err(IncorrectSignature)); - - let recovered_key = s.recover(&msg, &sigr).unwrap(); - assert!(recovered_key != pk); - } - - #[test] - fn sign_with_recovery() { - let mut s = Secp256k1::new(); - s.randomize(&mut thread_rng()); - - let mut msg = [0u8; 32]; - thread_rng().fill_bytes(&mut msg); - let msg = Message::from_slice(&msg).unwrap(); - - let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap(); - - let sig = s.sign_recoverable(&msg, &sk).unwrap(); - - assert_eq!(s.recover(&msg, &sig), Ok(pk)); - } - - #[test] - fn bad_recovery() { - let mut s = Secp256k1::new(); - s.randomize(&mut thread_rng()); - - let msg = Message::from_slice(&[0x55; 32]).unwrap(); - - // Zero is not a valid sig - let sig = RecoverableSignature::from_compact(&s, &[0; 64], RecoveryId(0)).unwrap(); - assert_eq!(s.recover(&msg, &sig), Err(InvalidSignature)); - // ...but 111..111 is - let sig = RecoverableSignature::from_compact(&s, &[1; 64], RecoveryId(0)).unwrap(); - assert!(s.recover(&msg, &sig).is_ok()); - } - - #[test] - fn bad_slice() { - let s = Secp256k1::new(); - assert_eq!(Signature::from_der(&s, &[0; constants::MAX_SIGNATURE_SIZE + 1]), Err(InvalidSignature)); - assert_eq!(Signature::from_der(&s, &[0; constants::MAX_SIGNATURE_SIZE]), Err(InvalidSignature)); - - assert_eq!(Message::from_slice(&[0; constants::MESSAGE_SIZE - 1]), Err(InvalidMessage)); - assert_eq!(Message::from_slice(&[0; constants::MESSAGE_SIZE + 1]), Err(InvalidMessage)); - assert!(Message::from_slice(&[0; constants::MESSAGE_SIZE]).is_ok()); - } - - #[test] - fn debug_output() { - let s = Secp256k1::new(); - let sig = RecoverableSignature::from_compact( - &s, - &[ - 0x66, 0x73, 0xff, 0xad, 0x21, 0x47, 0x74, 0x1f, 0x04, 0x77, 0x2b, 0x6f, 0x92, 0x1f, 0x0b, 0xa6, 0xaf, - 0x0c, 0x1e, 0x77, 0xfc, 0x43, 0x9e, 0x65, 0xc3, 0x6d, 0xed, 0xf4, 0x09, 0x2e, 0x88, 0x98, 0x4c, 0x1a, - 0x97, 0x16, 0x52, 0xe0, 0xad, 0xa8, 0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f, 0xff, 0x20, 0x80, - 0xc4, 0xa3, 0x9a, 0xae, 0x06, 0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89, - ], - RecoveryId(1), - ) - .unwrap(); - assert_eq!(&format!("{:?}", sig), "RecoverableSignature(98882e09f4ed6dc3659e43fc771e0cafa60b1f926f2b77041f744721adff7366898cb609d0ee128d06ae9aa3c48020ff9f705e02f80e1280a8ade05216971a4c01)"); - - let msg = Message([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 255, - ]); - assert_eq!(&format!("{:?}", msg), "Message(0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fff)"); - } - - #[test] - fn recov_sig_serialize_compact() { - let s = Secp256k1::new(); - - let recid_in = RecoveryId(1); - let bytes_in = &[ - 0x66, 0x73, 0xff, 0xad, 0x21, 0x47, 0x74, 0x1f, 0x04, 0x77, 0x2b, 0x6f, 0x92, 0x1f, 0x0b, 0xa6, 0xaf, 0x0c, - 0x1e, 0x77, 0xfc, 0x43, 0x9e, 0x65, 0xc3, 0x6d, 0xed, 0xf4, 0x09, 0x2e, 0x88, 0x98, 0x4c, 0x1a, 0x97, 0x16, - 0x52, 0xe0, 0xad, 0xa8, 0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f, 0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, - 0xae, 0x06, 0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89, - ]; - let sig = RecoverableSignature::from_compact(&s, bytes_in, recid_in).unwrap(); - let (recid_out, bytes_out) = sig.serialize_compact(&s); - assert_eq!(recid_in, recid_out); - assert_eq!(&bytes_in[..], &bytes_out[..]); - } - - #[test] - fn recov_id_conversion_between_i32() { - assert!(RecoveryId::from_i32(-1).is_err()); - assert!(RecoveryId::from_i32(0).is_ok()); - assert!(RecoveryId::from_i32(1).is_ok()); - assert!(RecoveryId::from_i32(2).is_ok()); - assert!(RecoveryId::from_i32(3).is_ok()); - assert!(RecoveryId::from_i32(4).is_err()); - let id0 = RecoveryId::from_i32(0).unwrap(); - assert_eq!(i32::from(id0), 0); - let id1 = RecoveryId(1); - assert_eq!(i32::from(id1), 1); - } - - #[test] - fn low_s() { - // nb this is a parcel on testnet - // txid 8ccc87b72d766ab3128f03176bb1c98293f2d1f85ebfaf07b82cc81ea6891fa9 - // input number 3 - let sig = hex!("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45"); - let pk = hex!("031ee99d2b786ab3b0991325f2de8489246a6a3fdb700f6d0511b1d80cf5f4cd43"); - let msg = hex!("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d"); - - let secp = Secp256k1::new(); - let mut sig = Signature::from_der(&secp, &sig[..]).unwrap(); - let pk = PublicKey::from_slice(&secp, &pk[..]).unwrap(); - let msg = Message::from_slice(&msg[..]).unwrap(); - - // without normalization we expect this will fail - assert_eq!(secp.verify(&msg, &sig, &pk), Err(IncorrectSignature)); - // after normalization it should pass - sig.normalize_s(&secp); - assert_eq!(secp.verify(&msg, &sig, &pk), Ok(())); - } -} - -#[cfg(all(test, feature = "unstable"))] -mod benches { - use rand::{thread_rng, Rng}; - use test::{black_box, Bencher}; - - use super::{Message, Secp256k1}; - - #[bench] - pub fn generate(bh: &mut Bencher) { - struct CounterRng(u32); - impl Rng for CounterRng { - fn next_u32(&mut self) -> u32 { - self.0 += 1; - self.0 - } - } - - let s = Secp256k1::new(); - let mut r = CounterRng(0); - bh.iter(|| { - let (sk, pk) = s.generate_keypair(&mut r).unwrap(); - black_box(sk); - black_box(pk); - }); - } - - #[bench] - pub fn bench_sign(bh: &mut Bencher) { - let s = Secp256k1::new(); - let mut msg = [0u8; 32]; - thread_rng().fill_bytes(&mut msg); - let msg = Message::from_slice(&msg).unwrap(); - let (sk, _) = s.generate_keypair(&mut thread_rng()).unwrap(); - - bh.iter(|| { - let sig = s.sign(&msg, &sk).unwrap(); - black_box(sig); - }); - } - - #[bench] - pub fn bench_verify(bh: &mut Bencher) { - let s = Secp256k1::new(); - let mut msg = [0u8; 32]; - thread_rng().fill_bytes(&mut msg); - let msg = Message::from_slice(&msg).unwrap(); - let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap(); - let sig = s.sign(&msg, &sk).unwrap(); - - bh.iter(|| { - let res = s.verify(&msg, &sig, &pk).unwrap(); - black_box(res); - }); - } - - #[bench] - pub fn bench_recover(bh: &mut Bencher) { - let s = Secp256k1::new(); - let mut msg = [0u8; 32]; - thread_rng().fill_bytes(&mut msg); - let msg = Message::from_slice(&msg).unwrap(); - let (sk, _) = s.generate_keypair(&mut thread_rng()).unwrap(); - let sig = s.sign_recoverable(&msg, &sk).unwrap(); - - bh.iter(|| { - let res = s.recover(&msg, &sig).unwrap(); - black_box(res); - }); - } -} diff --git a/util/secp256k1/src/macros.rs b/util/secp256k1/src/macros.rs deleted file mode 100644 index 371283d609..0000000000 --- a/util/secp256k1/src/macros.rs +++ /dev/null @@ -1,148 +0,0 @@ -// Bitcoin secp256k1 bindings -// Written in 2014 by -// Dawid Ciężarkiewicz -// Andrew Poelstra -// -// To the extent possible under law, the author(s) have dedicated all -// copyright and related and neighboring rights to this software to -// the public domain worldwide. This software is distributed without -// any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication -// along with this software. -// If not, see . -// - -// This is a macro that routinely comes in handy -macro_rules! impl_array_newtype { - ($thing:ident, $ty:ty, $len:expr) => { - impl Copy for $thing {} - - impl $thing { - #[inline] - /// Converts the object to a raw pointer for FFI interfacing - pub fn as_ptr(&self) -> *const $ty { - let &$thing(ref dat) = self; - dat.as_ptr() - } - - #[inline] - /// Converts the object to a mutable raw pointer for FFI interfacing - pub fn as_mut_ptr(&mut self) -> *mut $ty { - let &mut $thing(ref mut dat) = self; - dat.as_mut_ptr() - } - - #[inline] - /// Returns the length of the object as an array - pub fn len(&self) -> usize { - $len - } - - #[inline] - /// Returns whether the object as an array is empty - pub fn is_empty(&self) -> bool { - false - } - } - - impl PartialEq for $thing { - #[inline] - fn eq(&self, other: &$thing) -> bool { - &self[..] == &other[..] - } - } - - impl Eq for $thing {} - - impl Clone for $thing { - #[inline] - fn clone(&self) -> $thing { - unsafe { - use std::intrinsics::copy_nonoverlapping; - use std::mem; - let mut ret: $thing = mem::uninitialized(); - copy_nonoverlapping(self.as_ptr(), ret.as_mut_ptr(), mem::size_of::<$thing>()); - ret - } - } - } - - impl ::std::ops::Index for $thing { - type Output = $ty; - - #[inline] - fn index(&self, index: usize) -> &$ty { - let &$thing(ref dat) = self; - &dat[index] - } - } - - impl ::std::ops::Index<::std::ops::Range> for $thing { - type Output = [$ty]; - - #[inline] - fn index(&self, index: ::std::ops::Range) -> &[$ty] { - let &$thing(ref dat) = self; - &dat[index] - } - } - - impl ::std::ops::Index<::std::ops::RangeTo> for $thing { - type Output = [$ty]; - - #[inline] - fn index(&self, index: ::std::ops::RangeTo) -> &[$ty] { - let &$thing(ref dat) = self; - &dat[index] - } - } - - impl ::std::ops::Index<::std::ops::RangeFrom> for $thing { - type Output = [$ty]; - - #[inline] - fn index(&self, index: ::std::ops::RangeFrom) -> &[$ty] { - let &$thing(ref dat) = self; - &dat[index] - } - } - - impl ::std::ops::Index<::std::ops::RangeFull> for $thing { - type Output = [$ty]; - - #[inline] - fn index(&self, _: ::std::ops::RangeFull) -> &[$ty] { - let &$thing(ref dat) = self; - &dat[..] - } - } - }; -} - -macro_rules! impl_pretty_debug { - ($thing:ident) => { - impl ::std::fmt::Debug for $thing { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - write!(f, "{}(", stringify!($thing))?; - for i in self[..].iter().cloned() { - write!(f, "{:02x}", i)?; - } - write!(f, ")") - } - } - }; -} - -macro_rules! impl_raw_debug { - ($thing:ident) => { - impl ::std::fmt::Debug for $thing { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - for i in self[..].iter().cloned() { - write!(f, "{:02x}", i)?; - } - Ok(()) - } - } - }; -} diff --git a/util/secp256k1/src/schnorr.rs b/util/secp256k1/src/schnorr.rs deleted file mode 100644 index ba53cc647b..0000000000 --- a/util/secp256k1/src/schnorr.rs +++ /dev/null @@ -1,182 +0,0 @@ -// Bitcoin secp256k1 bindings -// Written in 2014 by -// Dawid Ciężarkiewicz -// Andrew Poelstra -// -// To the extent possible under law, the author(s) have dedicated all -// copyright and related and neighboring rights to this software to -// the public domain worldwide. This software is distributed without -// any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication -// along with this software. -// If not, see . -// - -//! # Schnorr signatures - -use ContextFlag; -use Error; -use Message; -use Secp256k1; - -use constants; -use ffi; -use key::{PublicKey, SecretKey}; - -use std::convert::From; -use std::{mem, ptr}; - -/// A Schnorr signature. -pub struct Signature([u8; constants::SCHNORR_SIGNATURE_SIZE]); -impl_array_newtype!(Signature, u8, constants::SCHNORR_SIGNATURE_SIZE); -impl_pretty_debug!(Signature); - -impl Signature { - /// Deserializes a signature from a 64-byte vector - pub fn deserialize(data: &[u8]) -> Signature { - assert_eq!(data.len(), constants::SCHNORR_SIGNATURE_SIZE); - let mut ret = [0; constants::SCHNORR_SIGNATURE_SIZE]; - ret[..].copy_from_slice(data); - Signature(ret) - } - - /// Serializes a signature to a 64-byte vector - pub fn serialize(&self) -> Vec { - Vec::from(&self.0[..]) - } -} - -impl Secp256k1 { - /// Create a Schnorr signature - pub fn sign_schnorr(&self, msg: &Message, sk: &SecretKey) -> Result { - if self.caps == ContextFlag::VerifyOnly || self.caps == ContextFlag::None { - return Err(Error::IncapableContext) - } - - let mut ret: Signature = unsafe { mem::uninitialized() }; - unsafe { - // We can assume the return value because it's not possible to construct - // an invalid signature from a valid `Message` and `SecretKey` - let err = ffi::secp256k1_schnorr_sign( - self.ctx, - ret.as_mut_ptr(), - msg.as_ptr(), - sk.as_ptr(), - ffi::secp256k1_nonce_function_rfc6979, - ptr::null(), - ); - debug_assert_eq!(err, 1); - } - Ok(ret) - } - - /// Verify a Schnorr signature - pub fn verify_schnorr(&self, msg: &Message, sig: &Signature, pk: &PublicKey) -> Result<(), Error> { - if self.caps == ContextFlag::SignOnly || self.caps == ContextFlag::None { - return Err(Error::IncapableContext) - } - - if !pk.is_valid() { - Err(Error::InvalidPublicKey) - } else if unsafe { ffi::secp256k1_schnorr_verify(self.ctx, sig.as_ptr(), msg.as_ptr(), pk.as_ptr()) } == 0 { - Err(Error::IncorrectSignature) - } else { - Ok(()) - } - } - - /// Retrieves the public key for which `sig` is a valid signature for `msg`. - /// Requires a verify-capable context. - pub fn recover_schnorr(&self, msg: &Message, sig: &Signature) -> Result { - if self.caps == ContextFlag::SignOnly || self.caps == ContextFlag::None { - return Err(Error::IncapableContext) - } - - let mut pk = unsafe { ffi::PublicKey::blank() }; - unsafe { - if ffi::secp256k1_schnorr_recover(self.ctx, &mut pk, sig.as_ptr(), msg.as_ptr()) != 1 { - return Err(Error::InvalidSignature) - } - }; - Ok(PublicKey::from(pk)) - } -} - -#[cfg(test)] -mod tests { - use super::Signature; - use rand::{thread_rng, RngCore}; - use ContextFlag; - use Error::IncapableContext; - use Message; - use Secp256k1; - - #[test] - fn capabilities() { - let none = Secp256k1::with_caps(ContextFlag::None); - let sign = Secp256k1::with_caps(ContextFlag::SignOnly); - let vrfy = Secp256k1::with_caps(ContextFlag::VerifyOnly); - let full = Secp256k1::with_caps(ContextFlag::Full); - - let mut msg = [0u8; 32]; - thread_rng().fill_bytes(&mut msg); - let msg = Message::from_slice(&msg).unwrap(); - - let (sk, pk) = full.generate_keypair(&mut thread_rng()).unwrap(); - - // Try signing - assert_eq!(none.sign_schnorr(&msg, &sk), Err(IncapableContext)); - assert_eq!(vrfy.sign_schnorr(&msg, &sk), Err(IncapableContext)); - assert!(sign.sign_schnorr(&msg, &sk).is_ok()); - assert!(full.sign_schnorr(&msg, &sk).is_ok()); - assert_eq!(sign.sign_schnorr(&msg, &sk), full.sign_schnorr(&msg, &sk)); - let sig = full.sign_schnorr(&msg, &sk).unwrap(); - - // Try verifying - assert_eq!(none.verify_schnorr(&msg, &sig, &pk), Err(IncapableContext)); - assert_eq!(sign.verify_schnorr(&msg, &sig, &pk), Err(IncapableContext)); - assert!(vrfy.verify_schnorr(&msg, &sig, &pk).is_ok()); - assert!(full.verify_schnorr(&msg, &sig, &pk).is_ok()); - - // Try pk recovery - assert_eq!(none.recover_schnorr(&msg, &sig), Err(IncapableContext)); - assert_eq!(sign.recover_schnorr(&msg, &sig), Err(IncapableContext)); - assert!(vrfy.recover_schnorr(&msg, &sig).is_ok()); - assert!(full.recover_schnorr(&msg, &sig).is_ok()); - - assert_eq!(vrfy.recover_schnorr(&msg, &sig), full.recover_schnorr(&msg, &sig)); - assert_eq!(full.recover_schnorr(&msg, &sig), Ok(pk)); - } - - #[test] - fn sign_verify() { - let mut s = Secp256k1::new(); - s.randomize(&mut thread_rng()); - - let mut msg = [0u8; 32]; - thread_rng().fill_bytes(&mut msg); - let msg = Message::from_slice(&msg).unwrap(); - - let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap(); - - let sig = s.sign_schnorr(&msg, &sk).unwrap(); - assert!(s.verify_schnorr(&msg, &sig, &pk).is_ok()); - } - - #[test] - fn deserialize() { - let mut s = Secp256k1::new(); - s.randomize(&mut thread_rng()); - - let mut msg = [0u8; 32]; - thread_rng().fill_bytes(&mut msg); - let msg = Message::from_slice(&msg).unwrap(); - - let (sk, _) = s.generate_keypair(&mut thread_rng()).unwrap(); - - let sig1 = s.sign_schnorr(&msg, &sk).unwrap(); - let sig2 = Signature::deserialize(&sig1.serialize()); - assert_eq!(sig1, sig2); - } -} diff --git a/vm/Cargo.toml b/vm/Cargo.toml index 7bdc28ac6f..175fe7a29f 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -13,4 +13,4 @@ primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.%20rlp%20=%20%7B%20path%20="../util/rlp" } [dev-dependencies] -secp256k1 = { path = "../util/secp256k1" } +secp256k1 = { git = "https://github.com/CodeChain-io/rust-secp256k1.git", version = "0.6" } From 733d1090d041690ef96e425e02e9a94b58b97825 Mon Sep 17 00:00:00 2001 From: Seulgi Kim Date: Thu, 10 Oct 2019 13:29:32 +0900 Subject: [PATCH 049/105] Upgrade url url 1.7.0 which CodeChain used, has a lifetime bug. --- Cargo.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 65cf759da9..a5162a3ada 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -574,7 +574,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1055,7 +1055,7 @@ dependencies = [ "spmc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "vecio 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2037,7 +2037,7 @@ dependencies = [ "serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2244,7 +2244,7 @@ dependencies = [ "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2280,7 +2280,7 @@ dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2817,7 +2817,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "url" -version = "1.7.0" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2966,7 +2966,7 @@ dependencies = [ "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3247,7 +3247,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" -"checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7" +"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" "checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" From 04cbbabe4d8dcdbfb17b9f07bd3c6789e2aec6ed Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Fri, 11 Oct 2019 17:10:25 +0900 Subject: [PATCH 050/105] Fix typo meatdata --- core/src/client/client.rs | 2 +- spec/JSON-RPC.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/client/client.rs b/core/src/client/client.rs index 3117abd55f..ba1538effe 100644 --- a/core/src/client/client.rs +++ b/core/src/client/client.rs @@ -811,7 +811,7 @@ impl BlockChainClient for Client { impl TermInfo for Client { fn last_term_finished_block_num(&self, id: BlockId) -> Option { self.state_at(id) - .map(|state| state.metadata().unwrap().expect("Meatadata always exist")) + .map(|state| state.metadata().unwrap().expect("Metadata always exist")) .map(|metadata| metadata.last_term_finished_block_num()) } diff --git a/spec/JSON-RPC.md b/spec/JSON-RPC.md index 940676b59d..8127e45591 100644 --- a/spec/JSON-RPC.md +++ b/spec/JSON-RPC.md @@ -1489,7 +1489,7 @@ It returns null if the block number parameter is larger than the current best bl ``` curl \ -H 'Content-Type: application/json' \ - -d '{"jsonrpc": "2.0", "method": "chain_getMeatadataSeq", "params": [53], "id": 7}' \ + -d '{"jsonrpc": "2.0", "method": "chain_getMetadataSeq", "params": [53], "id": 7}' \ localhost:8080 ``` From c9d881b7ecdeb4182881d48787da7b787bea1fbb Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Thu, 10 Oct 2019 16:01:20 +0900 Subject: [PATCH 051/105] Add comment of can_change_canon_chain function --- core/src/consensus/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/consensus/mod.rs b/core/src/consensus/mod.rs index 7be9fdce92..28b2414cac 100644 --- a/core/src/consensus/mod.rs +++ b/core/src/consensus/mod.rs @@ -266,6 +266,9 @@ pub trait ConsensusEngine: Sync + Send { header.hash() } + /// In PoW consensus, the higher scored block became the best block. + /// In Tendermint consensus, the highest scored block may not be the best block. + /// Only the child of the current best block could be the next best block in Tendermint consensus. fn can_change_canon_chain(&self, _header: &HeaderView) -> bool { true } From 04a95b765de4c754e36d53e2171fa8480f28e1f3 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Thu, 10 Oct 2019 18:14:16 +0900 Subject: [PATCH 052/105] Fix the condition to check whether the new block could change the best block When a new block is imported in Tendermint consensus, CodeChain checks the conditions below to judge whether it is safe to change the best block: First, whether the score is higher than before. Second, whether the height of a new block is higher than the finalized block's height. This commit fixes the code that is calculating the finalized block's height erroneously. --- core/src/blockchain/blockchain.rs | 6 ++++-- core/src/blockchain/headerchain.rs | 5 +++-- core/src/consensus/mod.rs | 11 ++++++++--- core/src/consensus/tendermint/engine.rs | 17 ++++++++--------- core/src/consensus/tendermint/worker.rs | 13 ------------- 5 files changed, 23 insertions(+), 29 deletions(-) diff --git a/core/src/blockchain/blockchain.rs b/core/src/blockchain/blockchain.rs index 3b55954fb3..78a59c18f3 100644 --- a/core/src/blockchain/blockchain.rs +++ b/core/src/blockchain/blockchain.rs @@ -184,9 +184,11 @@ impl BlockChain { let new_header = new_block.header_view(); let parent_hash_of_new_block = new_header.parent_hash(); let parent_details_of_new_block = self.block_details(&parent_hash_of_new_block).expect("Invalid parent hash"); + let prev_best_proposal_hash = self.best_proposal_block_hash(); + let prev_best_hash = self.best_block_hash(); if parent_details_of_new_block.total_score + new_header.score() > self.best_proposal_block_detail().total_score - && engine.can_change_canon_chain(&new_header) + && engine.can_change_canon_chain(&new_header, prev_best_hash, prev_best_proposal_hash) { cinfo!( BLOCKCHAIN, @@ -194,7 +196,7 @@ impl BlockChain { new_header.number(), new_header.hash() ); - let prev_best_hash = self.best_block_hash(); + let route = tree_route(self, prev_best_hash, parent_hash_of_new_block) .expect("blocks being imported always within recent history; qed"); diff --git a/core/src/blockchain/headerchain.rs b/core/src/blockchain/headerchain.rs index 490510f556..ab1d592775 100644 --- a/core/src/blockchain/headerchain.rs +++ b/core/src/blockchain/headerchain.rs @@ -242,9 +242,11 @@ impl HeaderChain { fn best_header_changed(&self, new_header: &HeaderView, engine: &dyn CodeChainEngine) -> BestHeaderChanged { let parent_hash_of_new_header = new_header.parent_hash(); let parent_details_of_new_header = self.block_details(&parent_hash_of_new_header).expect("Invalid parent hash"); + let prev_best_proposal_hash = self.best_proposal_header_hash(); + let prev_best_hash = self.best_header_hash(); let is_new_best = parent_details_of_new_header.total_score + new_header.score() > self.best_proposal_header_detail().total_score - && engine.can_change_canon_chain(&new_header); + && engine.can_change_canon_chain(&new_header, prev_best_hash, prev_best_proposal_hash); if is_new_best { ctrace!( @@ -256,7 +258,6 @@ impl HeaderChain { // on new best block we need to make sure that all ancestors // are moved to "canon chain" // find the route between old best block and the new one - let prev_best_hash = self.best_header_hash(); let route = tree_route(self, prev_best_hash, parent_hash_of_new_header) .expect("blocks being imported always within recent history; qed"); diff --git a/core/src/consensus/mod.rs b/core/src/consensus/mod.rs index 28b2414cac..2a682d93f4 100644 --- a/core/src/consensus/mod.rs +++ b/core/src/consensus/mod.rs @@ -266,10 +266,15 @@ pub trait ConsensusEngine: Sync + Send { header.hash() } - /// In PoW consensus, the higher scored block became the best block. + /// In PoW consensus, the higher scored block becomes the best block. /// In Tendermint consensus, the highest scored block may not be the best block. - /// Only the child of the current best block could be the next best block in Tendermint consensus. - fn can_change_canon_chain(&self, _header: &HeaderView) -> bool { + /// Only the descendant of the current best block could be the next best block in Tendermint consensus. + fn can_change_canon_chain( + &self, + _new_header: &HeaderView, + _previous_best_hash: H256, + _previous_best_proposal_hash: H256, + ) -> bool { true } diff --git a/core/src/consensus/tendermint/engine.rs b/core/src/consensus/tendermint/engine.rs index 1805caef4b..2617ef403e 100644 --- a/core/src/consensus/tendermint/engine.rs +++ b/core/src/consensus/tendermint/engine.rs @@ -308,15 +308,14 @@ impl ConsensusEngine for Tendermint { header.parent_hash() } - fn can_change_canon_chain(&self, header: &HeaderView) -> bool { - let (result, receiver) = crossbeam::bounded(1); - self.inner - .send(worker::Event::AllowedHeight { - result, - }) - .unwrap(); - let allowed_height = receiver.recv().unwrap(); - header.number() >= allowed_height + + fn can_change_canon_chain( + &self, + new_header: &HeaderView, + prev_best_hash: H256, + prev_best_proposal_hash: H256, + ) -> bool { + new_header.parent_hash() == prev_best_hash || new_header.parent_hash() == prev_best_proposal_hash } fn action_handlers(&self) -> &[Arc] { diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 04df0942bd..95f9b3d3a3 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -133,9 +133,6 @@ pub enum Event { ap: Arc, address: Address, }, - AllowedHeight { - result: crossbeam::Sender, - }, Restore(crossbeam::Sender<()>), ProposalBlock { signature: SchnorrSignature, @@ -307,16 +304,6 @@ impl Worker { }) => { inner.set_signer(ap, address); } - Ok(Event::AllowedHeight { - result, - }) => { - let allowed_height = if inner.step.is_commit() { - inner.height + 1 - } else { - inner.height - }; - result.send(allowed_height).unwrap(); - } Ok(Event::Restore(result)) => { inner.restore(); result.send(()).unwrap(); From ee8c87b8a982b1f362e2a1917efa356c196f72bb Mon Sep 17 00:00:00 2001 From: Seonpyo Kim Date: Tue, 2 Apr 2019 11:13:13 +0900 Subject: [PATCH 053/105] Fix typos --- core/src/miner/miner.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index 43f1e00dbf..e0991a3010 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -499,15 +499,15 @@ impl Miner { let mut tx_count: usize = 0; let tx_total = transactions.len(); - let mut invald_tx_users = HashSet::new(); + let mut invalid_tx_users = HashSet::new(); for tx in transactions { let signer_public = tx.signer_public(); - if invald_tx_users.contains(&signer_public) { + if invalid_tx_users.contains(&signer_public) { // The previous transaction has failed continue } if !self.is_allowed_transaction(&tx.action) { - invald_tx_users.insert(signer_public); + invalid_tx_users.insert(signer_public); invalid_transactions.push(tx.hash()); continue } @@ -524,7 +524,7 @@ impl Miner { // already have transaction - ignore Err(Error::History(HistoryError::TransactionAlreadyImported)) => {} Err(e) => { - invald_tx_users.insert(signer_public); + invalid_tx_users.insert(signer_public); invalid_transactions.push(hash); cinfo!( MINER, From 2284195645316243a4c30e5028bb301047b6858d Mon Sep 17 00:00:00 2001 From: Seonpyo Kim Date: Tue, 2 Apr 2019 20:01:33 +0900 Subject: [PATCH 054/105] Block malicious users who generated runtime errors --- core/src/miner/mem_pool.rs | 5 +++++ core/src/miner/miner.rs | 23 ++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/core/src/miner/mem_pool.rs b/core/src/miner/mem_pool.rs index d95627f55a..65e126388a 100644 --- a/core/src/miner/mem_pool.rs +++ b/core/src/miner/mem_pool.rs @@ -958,6 +958,11 @@ impl MemPool { self.current.queue.iter().any(|tx| tx.origin.is_local()) } + /// Returns Some(true) if the given transaction is local and None for not found. + pub fn is_local_transaction(&self, tx_hash: H256) -> Option { + self.by_hash.get(&tx_hash).and_then(|found_item| Some(found_item.origin.is_local())) + } + /// Checks the given timelock with the current time/timestamp. fn should_wait_timelock(timelock: &TxTimelock, best_block_number: BlockNumber, best_block_timestamp: u64) -> bool { if let Some(block_number) = timelock.block { diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index e0991a3010..4ca1c41d0b 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -23,7 +23,7 @@ use std::time::{Duration, Instant}; use ckey::{public_to_address, Address, Password, PlatformAddress, Public}; use cstate::{FindActionHandler, TopLevelState}; -use ctypes::errors::HistoryError; +use ctypes::errors::{HistoryError, RuntimeError}; use ctypes::transaction::{Action, IncompleteTransaction, Timelock}; use ctypes::{BlockNumber, Header}; use cvm::ChainTimeInfo; @@ -127,6 +127,7 @@ pub struct Miner { accounts: Option>, notifiers: RwLock>>, + malicious_users: RwLock>, } impl Miner { @@ -184,6 +185,7 @@ impl Miner { sealing_enabled: AtomicBool::new(true), accounts, notifiers: RwLock::new(notifiers), + malicious_users: RwLock::new(HashSet::new()), } } @@ -502,6 +504,11 @@ impl Miner { let mut invalid_tx_users = HashSet::new(); for tx in transactions { let signer_public = tx.signer_public(); + let signer_address = public_to_address(&signer_public); + if self.malicious_users.read().contains(&signer_address) { + invalid_transactions.push(tx.hash()); + continue + } if invalid_tx_users.contains(&signer_public) { // The previous transaction has failed continue @@ -524,6 +531,20 @@ impl Miner { // already have transaction - ignore Err(Error::History(HistoryError::TransactionAlreadyImported)) => {} Err(e) => { + match e { + Error::Runtime(RuntimeError::AssetSupplyOverflow) + | Error::Runtime(RuntimeError::InvalidScript) => { + if !self + .mem_pool + .read() + .is_local_transaction(hash) + .expect("The tx is clearly fetched from the mempool") + { + self.malicious_users.write().insert(signer_address); + } + } + _ => {} + } invalid_tx_users.insert(signer_public); invalid_transactions.push(hash); cinfo!( From fc8bb8c6c959efdff0797720e47e6692824301e6 Mon Sep 17 00:00:00 2001 From: Seonpyo Kim Date: Tue, 2 Apr 2019 21:10:02 +0900 Subject: [PATCH 055/105] Block malicious users who generated syntax errors --- core/src/miner/miner.rs | 66 ++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index 4ca1c41d0b..bff7666b38 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -271,6 +271,23 @@ impl Miner { .into_iter() .map(|tx| { let hash = tx.hash(); + // FIXME: Refactoring is needed. recover_public is calling in verify_transaction_unordered. + let signer_public = tx.recover_public()?; + let signer_address = public_to_address(&signer_public); + let origin = self + .accounts + .as_ref() + .and_then(|accounts| match accounts.has_public(&signer_public) { + Ok(true) => Some(TxOrigin::Local), + Ok(false) => None, + Err(_) => None, + }) + .unwrap_or(default_origin); + + if self.malicious_users.read().contains(&signer_address) { + // FIXME: just to skip, think about another way. + return Ok(()) + } if client.transaction_block(&TransactionId::Hash(hash)).is_some() { cdebug!(MINER, "Rejected transaction {:?}: already in the blockchain", hash); return Err(HistoryError::TransactionAlreadyImported.into()) @@ -278,7 +295,7 @@ impl Miner { if !self.is_allowed_transaction(&tx.action) { cdebug!(MINER, "Rejected transaction {:?}: {:?} is not allowed transaction", hash, tx.action); } - match tx + let tx = tx .verify_basic() .map_err(From::from) .and_then(|_| { @@ -286,33 +303,34 @@ impl Miner { self.engine.verify_transaction_with_params(&tx, &common_params) }) .and_then(|_| CodeChainMachine::verify_transaction_seal(tx, &fake_header)) - { - Err(e) => { + .map_err(|e| { + match e { + Error::Syntax(_) if !origin.is_local() => { + self.malicious_users.write().insert(signer_address); + } + _ => {} + } cdebug!(MINER, "Rejected transaction {:?} with invalid signature: {:?}", hash, e); - Err(e) + e + })?; + + // This check goes here because verify_transaction takes SignedTransaction parameter + self.engine.machine().verify_transaction(&tx, &fake_header, client, false).map_err(|e| { + match e { + Error::Syntax(_) if !origin.is_local() => { + self.malicious_users.write().insert(signer_address); + } + _ => {} } - Ok(tx) => { - // This check goes here because verify_transaction takes SignedTransaction parameter - self.engine.machine().verify_transaction(&tx, &fake_header, client, false)?; - - let origin = self - .accounts - .as_ref() - .and_then(|accounts| match accounts.has_public(&tx.signer_public()) { - Ok(true) => Some(TxOrigin::Local), - Ok(false) => None, - Err(_) => None, - }) - .unwrap_or(default_origin); + e + })?; - let timelock = self.calculate_timelock(&tx, client)?; - let tx_hash = tx.hash(); + let timelock = self.calculate_timelock(&tx, client)?; + let tx_hash = tx.hash(); - to_insert.push(MemPoolInput::new(tx, origin, timelock)); - tx_hashes.push(tx_hash); - Ok(()) - } - } + to_insert.push(MemPoolInput::new(tx, origin, timelock)); + tx_hashes.push(tx_hash); + Ok(()) }) .collect(); From 3083001d36def2ff10be8f29e0ea8c8cc07fdf86 Mon Sep 17 00:00:00 2001 From: Seonpyo Kim Date: Tue, 1 Oct 2019 18:20:00 +0900 Subject: [PATCH 056/105] Add a new type of users called immune users Immune users are immune from getting banned. --- core/src/miner/miner.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index bff7666b38..2b4c622929 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -128,6 +128,7 @@ pub struct Miner { accounts: Option>, notifiers: RwLock>>, malicious_users: RwLock>, + immune_users: RwLock>, } impl Miner { @@ -186,6 +187,7 @@ impl Miner { accounts, notifiers: RwLock::new(notifiers), malicious_users: RwLock::new(HashSet::new()), + immune_users: RwLock::new(HashSet::new()), } } @@ -274,6 +276,10 @@ impl Miner { // FIXME: Refactoring is needed. recover_public is calling in verify_transaction_unordered. let signer_public = tx.recover_public()?; let signer_address = public_to_address(&signer_public); + if default_origin.is_local() { + self.immune_users.write().insert(signer_address); + } + let origin = self .accounts .as_ref() @@ -295,6 +301,7 @@ impl Miner { if !self.is_allowed_transaction(&tx.action) { cdebug!(MINER, "Rejected transaction {:?}: {:?} is not allowed transaction", hash, tx.action); } + let immune_users = self.immune_users.read(); let tx = tx .verify_basic() .map_err(From::from) @@ -305,7 +312,7 @@ impl Miner { .and_then(|_| CodeChainMachine::verify_transaction_seal(tx, &fake_header)) .map_err(|e| { match e { - Error::Syntax(_) if !origin.is_local() => { + Error::Syntax(_) if !origin.is_local() && !immune_users.contains(&signer_address) => { self.malicious_users.write().insert(signer_address); } _ => {} @@ -317,7 +324,7 @@ impl Miner { // This check goes here because verify_transaction takes SignedTransaction parameter self.engine.machine().verify_transaction(&tx, &fake_header, client, false).map_err(|e| { match e { - Error::Syntax(_) if !origin.is_local() => { + Error::Syntax(_) if !origin.is_local() && !immune_users.contains(&signer_address) => { self.malicious_users.write().insert(signer_address); } _ => {} @@ -520,6 +527,8 @@ impl Miner { let mut tx_count: usize = 0; let tx_total = transactions.len(); let mut invalid_tx_users = HashSet::new(); + + let immune_users = self.immune_users.read(); for tx in transactions { let signer_public = tx.signer_public(); let signer_address = public_to_address(&signer_public); @@ -557,6 +566,7 @@ impl Miner { .read() .is_local_transaction(hash) .expect("The tx is clearly fetched from the mempool") + && !immune_users.contains(&signer_address) { self.malicious_users.write().insert(signer_address); } From 4d66702a96abca3d0cc3cd674a25f079cd603ea3 Mon Sep 17 00:00:00 2001 From: Seonpyo Kim Date: Mon, 8 Apr 2019 20:28:56 +0900 Subject: [PATCH 057/105] Implement new RPCs related banned users --- core/src/client/client.rs | 28 +++++++++++++++++++++++-- core/src/client/mod.rs | 22 ++++++++++++++++++-- core/src/client/test_client.rs | 26 ++++++++++++++++++++++- core/src/miner/miner.rs | 30 +++++++++++++++++++++++++++ core/src/miner/mod.rs | 15 ++++++++++++++ rpc/src/v1/impls/mempool.rs | 38 ++++++++++++++++++++++++++++++++-- rpc/src/v1/traits/mempool.rs | 16 ++++++++++++++ 7 files changed, 168 insertions(+), 7 deletions(-) diff --git a/core/src/client/client.rs b/core/src/client/client.rs index ba1538effe..9c3fb6824c 100644 --- a/core/src/client/client.rs +++ b/core/src/client/client.rs @@ -20,7 +20,7 @@ use std::sync::{Arc, Weak}; use std::time::Instant; use cio::IoChannel; -use ckey::{Address, PlatformAddress, Public}; +use ckey::{Address, NetworkId, PlatformAddress, Public}; use cmerkle::Result as TrieResult; use cnetwork::NodeId; use cstate::{ @@ -892,7 +892,31 @@ impl BlockProducer for Client { } } -impl MiningBlockChainClient for Client {} +impl MiningBlockChainClient for Client { + fn get_malicious_users(&self) -> Vec
{ + self.importer.miner.get_malicious_users() + } + + fn release_malicious_users(&self, prisoner_vec: Vec
) { + self.importer.miner.release_malicious_users(prisoner_vec) + } + + fn imprison_malicious_users(&self, prisoner_vec: Vec
) { + self.importer.miner.imprison_malicious_users(prisoner_vec) + } + + fn get_immune_users(&self) -> Vec
{ + self.importer.miner.get_immune_users() + } + + fn register_immune_users(&self, immune_user_vec: Vec
) { + self.importer.miner.register_immune_users(immune_user_vec) + } + + fn get_network_id(&self) -> NetworkId { + self.common_params(BlockId::Latest).unwrap().network_id() + } +} impl ChainTimeInfo for Client { fn transaction_block_age(&self, tracker: &H256, parent_block_number: BlockNumber) -> Option { diff --git a/core/src/client/mod.rs b/core/src/client/mod.rs index 33594dcf4a..d80f5b0301 100644 --- a/core/src/client/mod.rs +++ b/core/src/client/mod.rs @@ -32,7 +32,7 @@ pub use self::test_client::TestBlockChainClient; use std::ops::Range; use std::sync::Arc; -use ckey::{Address, PlatformAddress, Public}; +use ckey::{Address, NetworkId, PlatformAddress, Public}; use cmerkle::Result as TrieResult; use cnetwork::NodeId; use cstate::{AssetScheme, FindActionHandler, OwnedAsset, StateResult, Text, TopLevelState, TopStateView}; @@ -271,7 +271,25 @@ pub trait BlockProducer { } /// Extended client interface used for mining -pub trait MiningBlockChainClient: BlockChainClient + BlockProducer + FindActionHandler {} +pub trait MiningBlockChainClient: BlockChainClient + BlockProducer + FindActionHandler { + /// Returns malicious users who sent failing transactions. + fn get_malicious_users(&self) -> Vec
; + + /// Release designated users from the malicious user list. + fn release_malicious_users(&self, prisoner_vec: Vec
); + + /// Append designated users to the malicious user list. + fn imprison_malicious_users(&self, prisoner_vec: Vec
); + + /// Returns users immune from getting banned. + fn get_immune_users(&self) -> Vec
; + + /// Append designated users to the immune user list. + fn register_immune_users(&self, immune_user_vec: Vec
); + + /// Returns network id. + fn get_network_id(&self) -> NetworkId; +} /// Provides methods to access database. pub trait DatabaseClient { diff --git a/core/src/client/test_client.rs b/core/src/client/test_client.rs index f823758c79..af2791e459 100644 --- a/core/src/client/test_client.rs +++ b/core/src/client/test_client.rs @@ -362,7 +362,31 @@ impl BlockProducer for TestBlockChainClient { } } -impl MiningBlockChainClient for TestBlockChainClient {} +impl MiningBlockChainClient for TestBlockChainClient { + fn get_malicious_users(&self) -> Vec
{ + self.miner.get_malicious_users() + } + + fn release_malicious_users(&self, prisoner_vec: Vec
) { + self.miner.release_malicious_users(prisoner_vec) + } + + fn imprison_malicious_users(&self, prisoner_vec: Vec
) { + self.miner.imprison_malicious_users(prisoner_vec) + } + + fn get_immune_users(&self) -> Vec
{ + self.miner.get_immune_users() + } + + fn register_immune_users(&self, immune_user_vec: Vec
) { + self.miner.register_immune_users(immune_user_vec) + } + + fn get_network_id(&self) -> NetworkId { + NetworkId::default() + } +} impl AccountData for TestBlockChainClient { fn seq(&self, address: &Address, id: BlockId) -> Option { diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index 2b4c622929..09a8b5ee63 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -16,6 +16,7 @@ use std::collections::HashSet; use std::iter::once; +use std::iter::FromIterator; use std::ops::Range; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; @@ -1123,6 +1124,35 @@ impl MinerService for Miner { cdebug!(MINER, "Stop sealing"); self.sealing_enabled.store(false, Ordering::Relaxed); } + + fn get_malicious_users(&self) -> Vec
{ + Vec::from_iter(self.malicious_users.read().iter().map(Clone::clone)) + } + + fn release_malicious_users(&self, prisoner_vec: Vec
) { + let mut malicious_users = self.malicious_users.write(); + for address in prisoner_vec { + malicious_users.remove(&address); + } + } + + fn imprison_malicious_users(&self, prisoner_vec: Vec
) { + let mut malicious_users = self.malicious_users.write(); + for address in prisoner_vec { + malicious_users.insert(address); + } + } + + fn get_immune_users(&self) -> Vec
{ + Vec::from_iter(self.immune_users.read().iter().map(Clone::clone)) + } + + fn register_immune_users(&self, immune_user_vec: Vec
) { + let mut immune_users = self.immune_users.write(); + for address in immune_user_vec { + immune_users.insert(address); + } + } } fn get_next_seq(transactions: impl IntoIterator, addresses: &[Address]) -> Option { diff --git a/core/src/miner/mod.rs b/core/src/miner/mod.rs index 63f599efe7..1922977013 100644 --- a/core/src/miner/mod.rs +++ b/core/src/miner/mod.rs @@ -150,6 +150,21 @@ pub trait MinerService: Send + Sync { /// Stop sealing. fn stop_sealing(&self); + + /// Get malicious users + fn get_malicious_users(&self) -> Vec
; + + /// Release target malicious users from malicious user set. + fn release_malicious_users(&self, prisoner_vec: Vec
); + + /// Imprison target malicious users to malicious user set. + fn imprison_malicious_users(&self, prisoner_vec: Vec
); + + /// Get ban-immune users. + fn get_immune_users(&self) -> Vec
; + + /// Register users to ban-immune users. + fn register_immune_users(&self, immune_user_vec: Vec
); } /// Mining status diff --git a/rpc/src/v1/impls/mempool.rs b/rpc/src/v1/impls/mempool.rs index d534c6fabb..e61f9d6928 100644 --- a/rpc/src/v1/impls/mempool.rs +++ b/rpc/src/v1/impls/mempool.rs @@ -16,8 +16,9 @@ use std::sync::Arc; -use ccore::{BlockChainClient, SignedTransaction}; +use ccore::{BlockChainClient, MiningBlockChainClient, SignedTransaction}; use cjson::bytes::Bytes; +use ckey::{Address, PlatformAddress}; use primitives::H256; use rlp::UntrustedRlp; @@ -41,7 +42,7 @@ impl MempoolClient { impl Mempool for MempoolClient where - C: BlockChainClient + 'static, + C: BlockChainClient + MiningBlockChainClient + 'static, { fn send_signed_transaction(&self, raw: Bytes) -> Result { UntrustedRlp::new(&raw.into_vec()) @@ -78,4 +79,37 @@ where fn get_pending_transactions_count(&self, from: Option, to: Option) -> Result { Ok(self.client.count_pending_transactions(from.unwrap_or(0)..to.unwrap_or(::std::u64::MAX))) } + + fn get_banned_accounts(&self) -> Result> { + let malicious_user_vec = self.client.get_malicious_users(); + let network_id = self.client.get_network_id(); + Ok(malicious_user_vec.into_iter().map(|address| PlatformAddress::new_v1(network_id, address)).collect()) + } + + fn unban_accounts(&self, prisoner_list: Vec) -> Result<()> { + let prisoner_vec: Vec
= prisoner_list.into_iter().map(PlatformAddress::into_address).collect(); + + self.client.release_malicious_users(prisoner_vec); + Ok(()) + } + + fn ban_accounts(&self, prisoner_list: Vec) -> Result<()> { + let prisoner_vec: Vec
= prisoner_list.into_iter().map(PlatformAddress::into_address).collect(); + + self.client.imprison_malicious_users(prisoner_vec); + Ok(()) + } + + fn get_immune_accounts(&self) -> Result> { + let immune_user_vec = self.client.get_immune_users(); + let network_id = self.client.get_network_id(); + Ok(immune_user_vec.into_iter().map(|address| PlatformAddress::new_v1(network_id, address)).collect()) + } + + fn register_immune_accounts(&self, immune_user_list: Vec) -> Result<()> { + let immune_user_vec: Vec
= immune_user_list.into_iter().map(PlatformAddress::into_address).collect(); + + self.client.register_immune_users(immune_user_vec); + Ok(()) + } } diff --git a/rpc/src/v1/traits/mempool.rs b/rpc/src/v1/traits/mempool.rs index ef482ad89a..571b9fa919 100644 --- a/rpc/src/v1/traits/mempool.rs +++ b/rpc/src/v1/traits/mempool.rs @@ -17,6 +17,7 @@ use cjson::bytes::Bytes; use primitives::H256; +use ckey::PlatformAddress; use jsonrpc_core::Result; use super::super::types::PendingTransactions; @@ -42,5 +43,20 @@ build_rpc_trait! { /// Gets the count of transactions in the current mem pool. # [rpc(name = "mempool_getPendingTransactionsCount")] fn get_pending_transactions_count(&self, Option, Option) -> Result; + + #[rpc(name = "mempool_getBannedAccounts")] + fn get_banned_accounts(&self) -> Result>; + + #[rpc(name = "mempool_unbanAccounts")] + fn unban_accounts(&self, Vec) -> Result<()>; + + #[rpc(name = "mempool_banAccounts")] + fn ban_accounts(&self, Vec) -> Result<()>; + + #[rpc(name = "mempool_getImmuneAccounts")] + fn get_immune_accounts(&self) -> Result>; + + #[rpc(name = "mempool_registerImmuneAccounts")] + fn register_immune_accounts(&self, Vec) -> Result<()>; } } From e93bd494a1259dbbad0ec7b9ff88527f797f0332 Mon Sep 17 00:00:00 2001 From: Seonpyo Kim Date: Tue, 16 Apr 2019 15:10:03 +0900 Subject: [PATCH 058/105] Add newly implemented RPCs to spec file --- spec/JSON-RPC.md | 159 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) diff --git a/spec/JSON-RPC.md b/spec/JSON-RPC.md index 8127e45591..61e2375710 100644 --- a/spec/JSON-RPC.md +++ b/spec/JSON-RPC.md @@ -323,6 +323,11 @@ When `Transaction` is included in any response, there will be an additional fiel * [mempool_getTransactionResultsByTracker](#mempool_getTransactionResultsByTracker) * [mempool_getPendingTransactions](#mempool_getpendingtransactions) * [mempool_getPendingTransactionsCount](#mempool_getpendingtransactionscount) + * [mempool_getBannedAccounts](#mempool_getbannedaccounts) + * [mempool_unbanAccounts](#mempool_unbanaccounts) + * [mempool_banAccounts](#mempool_banaccounts) + * [mempool_registerImmuneAccounts](#mempool_registerimmuneaccounts) + * [mempool_getRegisteredImmuneAccounts](#mempool_getregisteredimmuneaccounts) *** * [engine_getCoinbase](#engine_getcoinbase) * [engine_getBlockReward](#engine_getblockreward) @@ -1803,6 +1808,160 @@ Returns a count of the transactions that have insertion_timestamps within the gi [Back to **List of methods**](#list-of-methods) +## mempool_banAccounts +Register accounts to the mempool's banned account list. The mempool would not import the transactions from the users on the list. + +### Params + 1. prisoner_list: `PlatformAccount[]` + +### Returns +`null` + +Errors: `Invalid params` + +### Request Example +``` +curl \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc": "2.0", "method": "mempool_getBannedAccounts", "params": [], "id": null}' \ + localhost:8080 +``` + +### Response Example +``` +{ + "jsonrpc": "2.0", + "result": null, + "id": null +} +``` + +[Back to **List of methods**](#list-of-methods) + +## mempool_unbanAccounts +Release accounts from the mempool's banned account list. + +### Params + 1. trusty_list: `PlatformAccount[]` + +### Returns +`null` + +Errors: `Invalid params` + +### Request Example +``` +curl \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc": "2.0", "method": "mempool_unbanAccounts", "params": [["tccq9h7vnl68frvqapzv3tujrxtxtwqdnxw6yamrrgd"]], "id": null}' \ + localhost:8080 +``` + +### Response Example +``` +{ + "jsonrpc": "2.0", + "result": null, + "id": null +} +``` + +[Back to **List of methods**](#list-of-methods) + +## mempool_getBannedAccounts +Returns accounts banned for propagating transactions which cause syntax errors or runtime errors. + +### Params +No parameters + +### Returns +`PlatformAddress[]` + +Error: `Invalid params` + +### Request Example +``` +curl \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc": "2.0", "method": "mempool_getBannedAccounts", "params": [], "id": null}' \ + localhost:8080 +``` + +### Response Example +``` +{ + "jsonrpc": "2.0", + "result": [ + "tccq9h7vnl68frvqapzv3tujrxtxtwqdnxw6yamrrgd" + ], + "id": null +} +``` + +[Back to **List of methods**](#list-of-methods) + +## mempool_registerImmuneAccounts +Register accounts immune from getting banned. The trasactions from these accounts would never be rejected for the reason they are malicious. + +### Params + 1. immune_user_list: `PlatformAccount[]` + +### Returns +`null` + +Error: `Invalid params` + +### Request Example +``` +curl \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc": "2.0", "method": "mempool_registerImmuneAccounts", "params": [["tccq9h7vnl68frvqapzv3tujrxtxtwqdnxw6yamrrgd"]], "id": null}' \ + localhost:8080 +``` + +### Response Example +``` +{ + "jsonrpc": "2.0", + "result": null, + "id": null +} +``` + +[Back to **List of methods**](#list-of-methods) + +## mempool_getRegisteredImmuneAccounts +Gets immune accounts registered by `mempool_registerImmuneAccounts`. + +### Params +No parameters + +### Returns +`PlatformAccount[]` + +Error: `Invalid params` + +### Request Example +``` +curl \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc": "2.0", "method": "mempool_getImmuneAccounts", "params": [], "id": null}' \ + localhost:8080 +``` + +### Response Example +``` +{ + "jsonrpc": "2.0", + "result": [ + "tccq9h7vnl68frvqapzv3tujrxtxtwqdnxw6yamrrgd" + ], + "id": null +} +``` + +[Back to **List of methods**](#list-of-methods) + ## engine_getCoinbase Gets coinbase's account id. From daa0c3fe3a28606c93b77fb409ca31f1704ea2b0 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Mon, 14 Oct 2019 15:10:05 +0900 Subject: [PATCH 059/105] Enable all grandchild of the best block to become a best proposal block Before this commit, only the child of the best block and the child of the best proposal block could be a new best proposal block. A block that is a grandchild of the best block but not the child of the best proposal block should be able to become a best proposal block. After this commit, CodeChain checks whether a new block is the best block's child or grandchild. --- core/src/blockchain/blockchain.rs | 9 +++++++-- core/src/blockchain/headerchain.rs | 9 +++++++-- core/src/consensus/mod.rs | 5 +++-- core/src/consensus/tendermint/engine.rs | 7 ++++--- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/core/src/blockchain/blockchain.rs b/core/src/blockchain/blockchain.rs index 78a59c18f3..948ee0c3b4 100644 --- a/core/src/blockchain/blockchain.rs +++ b/core/src/blockchain/blockchain.rs @@ -184,11 +184,16 @@ impl BlockChain { let new_header = new_block.header_view(); let parent_hash_of_new_block = new_header.parent_hash(); let parent_details_of_new_block = self.block_details(&parent_hash_of_new_block).expect("Invalid parent hash"); - let prev_best_proposal_hash = self.best_proposal_block_hash(); + let grandparent_hash_of_new_block = parent_details_of_new_block.parent; let prev_best_hash = self.best_block_hash(); if parent_details_of_new_block.total_score + new_header.score() > self.best_proposal_block_detail().total_score - && engine.can_change_canon_chain(&new_header, prev_best_hash, prev_best_proposal_hash) + && engine.can_change_canon_chain( + new_header.hash(), + parent_hash_of_new_block, + grandparent_hash_of_new_block, + prev_best_hash, + ) { cinfo!( BLOCKCHAIN, diff --git a/core/src/blockchain/headerchain.rs b/core/src/blockchain/headerchain.rs index ab1d592775..25dffc4178 100644 --- a/core/src/blockchain/headerchain.rs +++ b/core/src/blockchain/headerchain.rs @@ -242,11 +242,16 @@ impl HeaderChain { fn best_header_changed(&self, new_header: &HeaderView, engine: &dyn CodeChainEngine) -> BestHeaderChanged { let parent_hash_of_new_header = new_header.parent_hash(); let parent_details_of_new_header = self.block_details(&parent_hash_of_new_header).expect("Invalid parent hash"); - let prev_best_proposal_hash = self.best_proposal_header_hash(); + let grandparent_hash_of_new_header = parent_details_of_new_header.parent; let prev_best_hash = self.best_header_hash(); let is_new_best = parent_details_of_new_header.total_score + new_header.score() > self.best_proposal_header_detail().total_score - && engine.can_change_canon_chain(&new_header, prev_best_hash, prev_best_proposal_hash); + && engine.can_change_canon_chain( + new_header.hash(), + parent_hash_of_new_header, + grandparent_hash_of_new_header, + prev_best_hash, + ); if is_new_best { ctrace!( diff --git a/core/src/consensus/mod.rs b/core/src/consensus/mod.rs index 2a682d93f4..bc8babf156 100644 --- a/core/src/consensus/mod.rs +++ b/core/src/consensus/mod.rs @@ -271,9 +271,10 @@ pub trait ConsensusEngine: Sync + Send { /// Only the descendant of the current best block could be the next best block in Tendermint consensus. fn can_change_canon_chain( &self, - _new_header: &HeaderView, + _new_block_hash: H256, + _parent_hash_of_new_header: H256, + _grandparent_hash_of_new_header: H256, _previous_best_hash: H256, - _previous_best_proposal_hash: H256, ) -> bool { true } diff --git a/core/src/consensus/tendermint/engine.rs b/core/src/consensus/tendermint/engine.rs index 2617ef403e..63943bf72a 100644 --- a/core/src/consensus/tendermint/engine.rs +++ b/core/src/consensus/tendermint/engine.rs @@ -311,11 +311,12 @@ impl ConsensusEngine for Tendermint { fn can_change_canon_chain( &self, - new_header: &HeaderView, + _new_header_hash: H256, + parent_hash_of_new_header: H256, + grandparent_hash_of_new_header: H256, prev_best_hash: H256, - prev_best_proposal_hash: H256, ) -> bool { - new_header.parent_hash() == prev_best_hash || new_header.parent_hash() == prev_best_proposal_hash + parent_hash_of_new_header == prev_best_hash || grandparent_hash_of_new_header == prev_best_hash } fn action_handlers(&self) -> &[Arc] { From fe44086e1e5aa10377db12021b1b720b1a12fd03 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Tue, 15 Oct 2019 14:39:53 +0900 Subject: [PATCH 060/105] Disable tests for IoService on macos --- util/io/src/service.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util/io/src/service.rs b/util/io/src/service.rs index 91d564b333..531037dc91 100644 --- a/util/io/src/service.rs +++ b/util/io/src/service.rs @@ -508,7 +508,8 @@ where } } -#[cfg(test)] +// TODO: Test fails on macos >= 10.14 +#[cfg(all(test, not(target_os = "macos")))] mod tests { use std::net::{IpAddr, Ipv4Addr, SocketAddr}; From c8e730f78bb3a29007620bf83735c8415a804392 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Thu, 26 Sep 2019 17:58:33 +0900 Subject: [PATCH 061/105] Use github actions for lint and unit test tasks And simplify travis.yml --- .github/workflows/cargo-test.yml | 47 +++++++++++++++++++++++++++++ .github/workflows/yarn-lint.yml | 18 +++++++++++ .mergify.yml | 1 + .travis.yml | 51 ++++++++------------------------ 4 files changed, 78 insertions(+), 39 deletions(-) create mode 100644 .github/workflows/cargo-test.yml create mode 100644 .github/workflows/yarn-lint.yml diff --git a/.github/workflows/cargo-test.yml b/.github/workflows/cargo-test.yml new file mode 100644 index 0000000000..2eb39694dc --- /dev/null +++ b/.github/workflows/cargo-test.yml @@ -0,0 +1,47 @@ +on: [push, pull_request] + +name: Actions - cargo + +jobs: + clippy: + name: clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly-2019-05-17 + override: true + - run: rustup component add clippy + - run: cargo fetch --verbose + - run: cargo clippy --all --all-targets -- -D warnings + + rustfmt: + name: rustfmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly-2019-05-17 + override: true + - run: rustup component add rustfmt + - run: cargo fmt -- --check + + build: + name: unit test + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macOS-latest, ubuntu-latest] + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: 1.37.0 + override: true + - run: cargo fetch --verbose + - run: cargo build + - run: cargo test --verbose --all + env: + RUST_BACKTRACE: 1 diff --git a/.github/workflows/yarn-lint.yml b/.github/workflows/yarn-lint.yml new file mode 100644 index 0000000000..0edf2821ad --- /dev/null +++ b/.github/workflows/yarn-lint.yml @@ -0,0 +1,18 @@ +on: [push, pull_request] + +name: Actions - yarn + +jobs: + lint: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + with: + node-version: '10.x' + - run: npm install yarn + - working-directory: ./test + run: yarn + - working-directory: ./test + run: yarn lint diff --git a/.mergify.yml b/.mergify.yml index e2286139c2..2da2d6e798 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -4,6 +4,7 @@ pull_request_rules: - "#approved-reviews-by>=1" - "#review-requested=0" - "#changes-requested-reviews-by=0" + - "status-success~=^Actions - " - status-success=continuous-integration/travis-ci/pr - base=master - label!=do-not-merge diff --git a/.travis.yml b/.travis.yml index e377307b98..ce29c89d00 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,96 +15,69 @@ jobs: before_install: - SKIP=`.travis/check-mergify-merge` && if [[ "$SKIP" = "skip" ]]; then exit 0; fi - SKIP=`.travis/check-change '(^spec/|\.md$)'` && if [[ "$SKIP" = "skip" ]]; then exit 0; fi - - SKIP=`.travis/check-change '^test/'` && if [[ "$SKIP" = "noskip" ]]; then RUN_UNIT_TEST=1; fi install: - nvm install 10 - nvm use 10 - npm install -g yarn before_script: - cargo fetch --verbose + - cargo build + - cd test && yarn script: - - if [[ $RUN_UNIT_TEST ]]; then RUST_BACKTRACE=1 cargo test --verbose --all; fi - - cargo build || exit 1 - - cd test && yarn || exit 1 - - INT_TEST_FLAG=true && yarn start-short + - yarn start-short - yarn start-long after_failure: - - test $INT_TEST_FLAG && ./upload_logs.sh + - ./upload_logs.sh - os: linux name: linux before_install: - SKIP=`.travis/check-mergify-merge` && if [[ "$SKIP" = "skip" ]]; then exit 0; fi - SKIP=`.travis/check-change '^spec/|\.md$'` && if [[ "$SKIP" = "skip" ]]; then exit 0; fi - - SKIP=`.travis/check-change '^test/'` && if [[ "$SKIP" = "noskip" ]]; then RUN_UNIT_TEST=1; fi install: - nvm install 10 - nvm use 10 - npm install -g yarn before_script: - cargo fetch --verbose + - cargo build + - cd test && yarn script: - - if [[ $RUN_UNIT_TEST ]]; then RUST_BACKTRACE=1 cargo test --verbose --all; fi - - cargo build || exit 1 - - cd test && yarn || exit 1 - - INT_TEST_FLAG=true && yarn start-short + - yarn start-short - yarn start-long after_failure: - - test $INT_TEST_FLAG && ./upload_logs.sh + - ./upload_logs.sh - os: linux name: dynamic-validator-1 before_install: - SKIP=`.travis/check-mergify-merge` && if [[ "$SKIP" = "skip" ]]; then exit 0; fi - SKIP=`.travis/check-change '^spec/|\.md$'` && if [[ "$SKIP" = "skip" ]]; then exit 0; fi - - SKIP=`.travis/check-change '^test/'` && if [[ "$SKIP" = "noskip" ]]; then RUN_UNIT_TEST=1; fi install: - nvm install 10 - nvm use 10 - npm install -g yarn before_script: - cargo build --verbose + - cd test && yarn script: - - cd test && yarn || exit 1 - yarn start-dyn-val-1 after_failure: - - test $INT_TEST_FLAG && ./upload_logs.sh + - ./upload_logs.sh - os: linux name: dynamic-validator-2 before_install: - SKIP=`.travis/check-mergify-merge` && if [[ "$SKIP" = "skip" ]]; then exit 0; fi - SKIP=`.travis/check-change '^spec/|\.md$'` && if [[ "$SKIP" = "skip" ]]; then exit 0; fi - - SKIP=`.travis/check-change '^test/'` && if [[ "$SKIP" = "noskip" ]]; then RUN_UNIT_TEST=1; fi install: - nvm install 10 - nvm use 10 - npm install -g yarn before_script: - cargo build --verbose + - cd test && yarn script: - - cd test && yarn || exit 1 - yarn start-dyn-val-2 after_failure: - - test $INT_TEST_FLAG && ./upload_logs.sh - - os: linux - name: static - before_install: - - SKIP=`.travis/check-mergify-merge` && if [[ "$SKIP" = "skip" ]]; then exit 0; fi - - SKIP=`.travis/check-change '^spec/|\.md$'` && if [[ "$SKIP" = "skip" ]]; then exit 0; fi - - SKIP=`.travis/check-change '^test/'` && if [[ "$SKIP" = "noskip" ]]; then CHECK_RUST=1; fi - install: - - if [[ $CHECK_RUST ]]; then - rustup toolchain install nightly-2019-05-17 || exit 1; - rustup component add rustfmt --toolchain nightly-2019-05-17 || exit 1; - rustup component add clippy --toolchain nightly-2019-05-17 || exit 1; - fi - - nvm install 10 - - nvm use 10 - - npm install -g yarn - script: - - if [[ $CHECK_RUST ]]; then - cargo +nightly-2019-05-17 fmt -- --check || FAILED=1; - cargo +nightly-2019-05-17 clippy --all --all-targets -- -D warnings || FAILED=1; - fi; test ! $FAILED - - cd test && yarn && yarn lint + - ./upload_logs.sh - stage: deploy name: deploy script: skip From 5128b2908e4abf4d5e383a66d36fe8d54748a5fb Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Thu, 10 Oct 2019 19:48:46 +0900 Subject: [PATCH 062/105] Upgrade jsonrpc versions to v14.0.0 --- codechain/rpc.rs | 23 ++- rpc/Cargo.toml | 10 +- rpc/src/lib.rs | 5 +- rpc/src/v1/traits/account.rs | 64 ++++---- rpc/src/v1/traits/chain.rs | 308 +++++++++++++++++++---------------- rpc/src/v1/traits/devel.rs | 29 ++-- rpc/src/v1/traits/engine.rs | 34 ++-- rpc/src/v1/traits/mempool.rs | 55 +++---- rpc/src/v1/traits/miner.rs | 13 +- rpc/src/v1/traits/net.rs | 81 +++++---- stratum/Cargo.toml | 6 +- stratum/src/lib.rs | 5 +- 12 files changed, 336 insertions(+), 297 deletions(-) diff --git a/codechain/rpc.rs b/codechain/rpc.rs index 8c63058d84..f642c42005 100644 --- a/codechain/rpc.rs +++ b/codechain/rpc.rs @@ -19,9 +19,9 @@ use std::net::SocketAddr; use crate::rpc_apis; use crpc::{ - jsonrpc_core, start_http, start_ipc, start_ws, HttpServer, IpcServer, MetaIoHandler, Middleware, WsError, - WsErrorKind, WsServer, + jsonrpc_core, start_http, start_ipc, start_ws, HttpServer, IpcServer, MetaIoHandler, Middleware, WsError, WsServer, }; +use futures::future::Either; use serde_json; #[derive(Debug, PartialEq)] @@ -109,7 +109,7 @@ pub fn rpc_ws_start( let addr = url.parse().map_err(|_| format!("Invalid WebSockets listen host/port given: {}", url))?; let start_result = start_ws(&addr, server, cfg.max_connections); match start_result { - Err(WsError(WsErrorKind::Io(ref err), _)) if err.kind() == io::ErrorKind::AddrInUse => { + Err(WsError::Io(ref err)) if err.kind() == io::ErrorKind::AddrInUse => { Err(format!("WebSockets address {} is already in use, make sure that another instance of a Codechain node is not running or change the address using the --ws-port options.", addr)) }, Err(e) => Err(format!("WebSockets error: {:?}", e)), @@ -133,8 +133,9 @@ struct LogMiddleware {} impl jsonrpc_core::Middleware for LogMiddleware { type Future = jsonrpc_core::FutureResponse; + type CallFuture = jsonrpc_core::FutureOutput; - fn on_request(&self, request: jsonrpc_core::Request, meta: M, next: F) -> Self::Future + fn on_request(&self, request: jsonrpc_core::Request, meta: M, next: F) -> Either where F: FnOnce(jsonrpc_core::Request, M) -> X + Send, X: futures::Future, Error = ()> + Send + 'static, { @@ -146,7 +147,15 @@ impl jsonrpc_core::Middleware for LogMiddleware { } } } - Box::new(next(request, meta)) + Either::B(next(request, meta)) + } + + fn on_call(&self, call: jsonrpc_core::Call, meta: M, next: F) -> Either + where + F: FnOnce(jsonrpc_core::Call, M) -> X + Send, + X: futures::Future, Error = ()> + Send + 'static, { + Self::print_call(&call); + Either::B(next(call, meta)) } } @@ -166,7 +175,9 @@ impl LogMiddleware { ); } jsonrpc_core::Call::Notification(_) => {} - jsonrpc_core::Call::Invalid(_) => {} + jsonrpc_core::Call::Invalid { + .. + } => {} } } } diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 181aaddd46..6a1cc5dabf 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -33,8 +33,8 @@ rustc-hex = "1.0" rustc-serialize = "0.3" time = "0.1" tokio-core = "0.1.17" -jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } -jsonrpc-macros = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } -jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } -jsonrpc-ipc-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } -jsonrpc-ws-server = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } +jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", tag = "v14.0.0" } +jsonrpc-derive = { git = "https://github.com/paritytech/jsonrpc.git", tag = "v14.0.0" } +jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", tag = "v14.0.0" } +jsonrpc-ipc-server = { git = "https://github.com/paritytech/jsonrpc.git", tag = "v14.0.0" } +jsonrpc-ws-server = { git = "https://github.com/paritytech/jsonrpc.git", tag = "v14.0.0" } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 87685defbd..a0d8d4771e 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -51,7 +51,7 @@ extern crate time; extern crate tokio_core; #[macro_use] -extern crate jsonrpc_macros; +extern crate jsonrpc_derive; pub mod rpc_server; pub mod v1; @@ -59,7 +59,6 @@ pub mod v1; pub use rustc_serialize::hex; pub use jsonrpc_core::{Compatibility, Error, MetaIoHandler, Middleware, Params, Value}; -pub use jsonrpc_http_server::tokio_core::reactor::Remote; pub use jsonrpc_http_server::Server as HttpServer; pub use rpc_server::start_http; @@ -67,5 +66,5 @@ pub use rpc_server::start_http; pub use jsonrpc_ipc_server::Server as IpcServer; pub use rpc_server::start_ipc; -pub use jsonrpc_ws_server::{Error as WsError, ErrorKind as WsErrorKind, Server as WsServer}; +pub use jsonrpc_ws_server::{Error as WsError, Server as WsServer}; pub use rpc_server::start_ws; diff --git a/rpc/src/v1/traits/account.rs b/rpc/src/v1/traits/account.rs index d0df49c92f..dd8ab5f452 100644 --- a/rpc/src/v1/traits/account.rs +++ b/rpc/src/v1/traits/account.rs @@ -20,34 +20,38 @@ use primitives::H256; use super::super::types::{SendTransactionResult, UnsignedTransaction}; -build_rpc_trait! { - pub trait Account { - /// Gets a list of accounts - # [rpc(name = "account_getList")] - fn get_account_list(&self) -> Result>; - - /// Creates a new account - # [rpc(name = "account_create")] - fn create_account(&self, Option) -> Result; - - /// Imports a private key - # [rpc(name = "account_importRaw")] - fn create_account_from_secret(&self, H256, Option) -> Result; - - /// Unlocks the specified account for use. - # [rpc(name = "account_unlock")] - fn unlock(&self, PlatformAddress, Password, Option) -> Result<()>; - - /// Calculates the account's signature for a given message - # [rpc(name = "account_sign")] - fn sign(&self, H256, PlatformAddress, Option) -> Result; - - /// Sends a transaction with a signature of the account - # [rpc(name = "account_sendTransaction")] - fn send_transaction(&self, UnsignedTransaction, PlatformAddress, Option) -> Result; - - /// Changes the account's password - # [rpc(name = "account_changePassword")] - fn change_password(&self, PlatformAddress, Password, Password) -> Result<()>; - } +#[rpc(server)] +pub trait Account { + /// Gets a list of accounts + #[rpc(name = "account_getList")] + fn get_account_list(&self) -> Result>; + + /// Creates a new account + #[rpc(name = "account_create")] + fn create_account(&self, passphrase: Option) -> Result; + + /// Imports a private key + #[rpc(name = "account_importRaw")] + fn create_account_from_secret(&self, secret: H256, passphrase: Option) -> Result; + + /// Unlocks the specified account for use. + #[rpc(name = "account_unlock")] + fn unlock(&self, address: PlatformAddress, password: Password, duration: Option) -> Result<()>; + + /// Calculates the account's signature for a given message + #[rpc(name = "account_sign")] + fn sign(&self, message_digest: H256, address: PlatformAddress, passphrase: Option) -> Result; + + /// Sends a transaction with a signature of the account + #[rpc(name = "account_sendTransaction")] + fn send_transaction( + &self, + tx: UnsignedTransaction, + platform_address: PlatformAddress, + passphrase: Option, + ) -> Result; + + /// Changes the account's password + #[rpc(name = "account_changePassword")] + fn change_password(&self, address: PlatformAddress, old_password: Password, new_password: Password) -> Result<()>; } diff --git a/rpc/src/v1/traits/chain.rs b/rpc/src/v1/traits/chain.rs index 928bf5f5f6..268d13b193 100644 --- a/rpc/src/v1/traits/chain.rs +++ b/rpc/src/v1/traits/chain.rs @@ -24,145 +24,171 @@ use jsonrpc_core::Result; use super::super::types::{AssetScheme, Block, BlockNumberAndHash, OwnedAsset, Text, Transaction, UnsignedTransaction}; -build_rpc_trait! { - pub trait Chain { - /// Gets transaction with given hash. - # [rpc(name = "chain_getTransaction")] - fn get_transaction(&self, H256) -> Result>; - - /// Gets the signer of transaction with given hash. - # [rpc(name = "chain_getTransactionSigner")] - fn get_transaction_signer(&self, H256) -> Result>; - - /// Query whether the chain has the transaction with given transaction hash. - # [rpc(name = "chain_containsTransaction")] - fn contains_transaction(&self, H256) -> Result; - - # [rpc(name = "chain_containTransaction")] - fn contain_transaction(&self, H256) -> Result; - - /// Gets transaction with given transaction tracker. - # [rpc(name = "chain_getTransactionByTracker")] - fn get_transaction_by_tracker(&self, H256) -> Result>; - - /// Gets asset scheme with given transaction tracker. - # [rpc(name = "chain_getAssetSchemeByTracker")] - fn get_asset_scheme_by_tracker(&self, H256, ShardId, Option) -> Result>; - - /// Gets asset scheme with given asset type. - # [rpc(name = "chain_getAssetSchemeByType")] - fn get_asset_scheme_by_type(&self, H160, ShardId, Option) -> Result>; - - /// Gets text with given transaction hash. - # [rpc(name = "chain_getText")] - fn get_text(&self, H256, Option) -> Result>; - - /// Gets asset with given asset type. - # [rpc(name = "chain_getAsset")] - fn get_asset(&self, H256, usize, ShardId, Option) -> Result>; - - /// Checks whether an asset is spent or not. - # [rpc(name = "chain_isAssetSpent")] - fn is_asset_spent(&self, H256, usize, ShardId, Option) -> Result>; - - /// Gets seq with given account. - # [rpc(name = "chain_getSeq")] - fn get_seq(&self, PlatformAddress, Option) -> Result>; - - /// Gets balance with given account. - # [rpc(name = "chain_getBalance")] - fn get_balance(&self, PlatformAddress, Option) -> Result>; - - /// Gets regular key with given account - # [rpc(name = "chain_getRegularKey")] - fn get_regular_key(&self, PlatformAddress, Option) -> Result>; - - /// Gets the owner of given regular key. - # [rpc(name = "chain_getRegularKeyOwner")] - fn get_regular_key_owner(&self, Public, Option) -> Result>; - - /// Gets the genesis accounts - # [rpc(name = "chain_getGenesisAccounts")] - fn get_genesis_accounts(&self) -> Result>; - - /// Gets the number of shards - # [rpc(name = "chain_getNumberOfShards")] - fn get_number_of_shards(&self, Option) -> Result>; - - /// Gets shard id - # [rpc(name = "chain_getShardIdByHash")] - fn get_shard_id_by_hash(&self, H256, Option) -> Result>; - - /// Gets shard root - # [rpc(name = "chain_getShardRoot")] - fn get_shard_root(&self, ShardId, Option) -> Result>; - - /// Gets shard owners - # [rpc(name = "chain_getShardOwners")] - fn get_shard_owners(&self, ShardId, Option) -> Result>>; - - /// Gets shard users - # [rpc(name = "chain_getShardUsers")] - fn get_shard_users(&self, ShardId, Option) -> Result>>; - - /// Gets number of best block. - # [rpc(name = "chain_getBestBlockNumber")] - fn get_best_block_number(&self) -> Result; - - /// Gets the number and the hash of the best block. - # [rpc(name = "chain_getBestBlockId")] - fn get_best_block_id(&self) -> Result; - - /// Gets the hash of the block with given number. - # [rpc(name = "chain_getBlockHash")] - fn get_block_hash(&self, u64) -> Result>; - - /// Gets block with given number. - # [rpc(name = "chain_getBlockByNumber")] - fn get_block_by_number(&self, u64) -> Result>; - - /// Gets block with given hash. - # [rpc(name = "chain_getBlockByHash")] - fn get_block_by_hash(&self, H256) -> Result>; - - ///Gets the count of transactions in a block with given hash. - # [rpc(name = "chain_getBlockTransactionCountByHash")] - fn get_block_transaction_count_by_hash(&self, H256) -> Result>; - - ///Gets the minimum transaction fee of the given name. - # [rpc(name = "chain_getMinTransactionFee")] - fn get_min_transaction_fee(&self, String, Option) -> Result>; - - /// Gets the mining given block number - # [rpc(name = "chain_getMiningReward")] - fn get_mining_reward(&self, u64) -> Result>; - - /// Return the network id that is used in this chain. - # [rpc(name = "chain_getNetworkId")] - fn get_network_id(&self) -> Result; - - /// Return common params at given block number - #[rpc(name = "chain_getCommonParams")] - fn get_common_params(&self, Option) -> Result>; - - /// Return the current term id at given block number - #[rpc(name = "chain_getTermMetadata")] - fn get_term_metadata(&self, Option) -> Result>; - - /// Return the current metadata seq at given block number - #[rpc(name = "chain_getMetadataSeq")] - fn get_metadata_seq(&self, Option) -> Result>; - - /// Return the valid block authors - #[rpc(name = "chain_getPossibleAuthors")] - fn get_possible_authors(&self, Option) -> Result>>; - - /// Execute Transactions - # [rpc(name = "chain_executeTransaction")] - fn execute_transaction(&self, UnsignedTransaction, PlatformAddress) -> Result>; - - /// Execute AssetTransfer transaction inputs in VM - # [rpc(name = "chain_executeVM")] - fn execute_vm(&self, UnsignedTransaction, Vec>, Vec) -> Result>; - } +#[rpc(server)] +pub trait Chain { + /// Gets transaction with given hash. + #[rpc(name = "chain_getTransaction")] + fn get_transaction(&self, transaction_hash: H256) -> Result>; + + /// Gets the signer of transaction with given hash. + #[rpc(name = "chain_getTransactionSigner")] + fn get_transaction_signer(&self, transaction_hash: H256) -> Result>; + + /// Query whether the chain has the transaction with given transaction hash. + #[rpc(name = "chain_containsTransaction")] + fn contains_transaction(&self, transaction_hash: H256) -> Result; + + #[rpc(name = "chain_containTransaction")] + fn contain_transaction(&self, transaction_hash: H256) -> Result; + + /// Gets transaction with given transaction tracker. + #[rpc(name = "chain_getTransactionByTracker")] + fn get_transaction_by_tracker(&self, tracker: H256) -> Result>; + + /// Gets asset scheme with given transaction tracker. + #[rpc(name = "chain_getAssetSchemeByTracker")] + fn get_asset_scheme_by_tracker( + &self, + tracker: H256, + shard_id: ShardId, + block_number: Option, + ) -> Result>; + + /// Gets asset scheme with given asset type. + #[rpc(name = "chain_getAssetSchemeByType")] + fn get_asset_scheme_by_type( + &self, + asset_type: H160, + shard_id: ShardId, + block_number: Option, + ) -> Result>; + + /// Gets text with given transaction hash. + #[rpc(name = "chain_getText")] + fn get_text(&self, transaction_hash: H256, block_number: Option) -> Result>; + + /// Gets asset with given asset type. + #[rpc(name = "chain_getAsset")] + fn get_asset( + &self, + tracker: H256, + index: usize, + shard_id: ShardId, + block_number: Option, + ) -> Result>; + + /// Checks whether an asset is spent or not. + #[rpc(name = "chain_isAssetSpent")] + fn is_asset_spent( + &self, + transaction_hash: H256, + index: usize, + shard_id: ShardId, + block_number: Option, + ) -> Result>; + + /// Gets seq with given account. + #[rpc(name = "chain_getSeq")] + fn get_seq(&self, address: PlatformAddress, block_number: Option) -> Result>; + + /// Gets balance with given account. + #[rpc(name = "chain_getBalance")] + fn get_balance(&self, address: PlatformAddress, block_number: Option) -> Result>; + + /// Gets regular key with given account + #[rpc(name = "chain_getRegularKey")] + fn get_regular_key(&self, address: PlatformAddress, block_number: Option) -> Result>; + + /// Gets the owner of given regular key. + #[rpc(name = "chain_getRegularKeyOwner")] + fn get_regular_key_owner(&self, public: Public, block_number: Option) -> Result>; + + /// Gets the genesis accounts + #[rpc(name = "chain_getGenesisAccounts")] + fn get_genesis_accounts(&self) -> Result>; + + /// Gets the number of shards + #[rpc(name = "chain_getNumberOfShards")] + fn get_number_of_shards(&self, block_number: Option) -> Result>; + + /// Gets shard id + #[rpc(name = "chain_getShardIdByHash")] + fn get_shard_id_by_hash(&self, create_shard_tx_hash: H256, block_number: Option) -> Result>; + + /// Gets shard root + #[rpc(name = "chain_getShardRoot")] + fn get_shard_root(&self, shard_id: ShardId, block_number: Option) -> Result>; + + /// Gets shard owners + #[rpc(name = "chain_getShardOwners")] + fn get_shard_owners(&self, shard_id: ShardId, block_number: Option) -> Result>>; + + /// Gets shard users + #[rpc(name = "chain_getShardUsers")] + fn get_shard_users(&self, shard_id: ShardId, block_number: Option) -> Result>>; + + /// Gets number of best block. + #[rpc(name = "chain_getBestBlockNumber")] + fn get_best_block_number(&self) -> Result; + + /// Gets the number and the hash of the best block. + #[rpc(name = "chain_getBestBlockId")] + fn get_best_block_id(&self) -> Result; + + /// Gets the hash of the block with given number. + #[rpc(name = "chain_getBlockHash")] + fn get_block_hash(&self, block_number: u64) -> Result>; + + /// Gets block with given number. + #[rpc(name = "chain_getBlockByNumber")] + fn get_block_by_number(&self, block_number: u64) -> Result>; + + /// Gets block with given hash. + #[rpc(name = "chain_getBlockByHash")] + fn get_block_by_hash(&self, block_hash: H256) -> Result>; + + ///Gets the count of transactions in a block with given hash. + #[rpc(name = "chain_getBlockTransactionCountByHash")] + fn get_block_transaction_count_by_hash(&self, block_hash: H256) -> Result>; + + ///Gets the minimum transaction fee of the given name. + #[rpc(name = "chain_getMinTransactionFee")] + fn get_min_transaction_fee(&self, action_type: String, block_number: Option) -> Result>; + + /// Gets the mining given block number + #[rpc(name = "chain_getMiningReward")] + fn get_mining_reward(&self, block_number: u64) -> Result>; + + /// Return the network id that is used in this chain. + #[rpc(name = "chain_getNetworkId")] + fn get_network_id(&self) -> Result; + + /// Return common params at given block number + #[rpc(name = "chain_getCommonParams")] + fn get_common_params(&self, block_number: Option) -> Result>; + + /// Return the current term id at given block number + #[rpc(name = "chain_getTermMetadata")] + fn get_term_metadata(&self, block_number: Option) -> Result>; + + /// Return the current metadata seq at given block number + #[rpc(name = "chain_getMetadataSeq")] + fn get_metadata_seq(&self, block_number: Option) -> Result>; + + /// Return the valid block authors + #[rpc(name = "chain_getPossibleAuthors")] + fn get_possible_authors(&self, block_number: Option) -> Result>>; + + /// Execute Transactions + #[rpc(name = "chain_executeTransaction")] + fn execute_transaction(&self, tx: UnsignedTransaction, sender: PlatformAddress) -> Result>; + + /// Execute AssetTransfer transaction inputs in VM + #[rpc(name = "chain_executeVM")] + fn execute_vm( + &self, + tx: UnsignedTransaction, + params: Vec>, + indices: Vec, + ) -> Result>; } diff --git a/rpc/src/v1/traits/devel.rs b/rpc/src/v1/traits/devel.rs index e714f78140..e8604e910e 100644 --- a/rpc/src/v1/traits/devel.rs +++ b/rpc/src/v1/traits/devel.rs @@ -22,24 +22,23 @@ use primitives::H256; use super::super::types::TPSTestSetting; -build_rpc_trait! { - pub trait Devel { - # [rpc(name = "devel_getStateTrieKeys")] - fn get_state_trie_keys(&self, usize, usize) -> Result>; +#[rpc(server)] +pub trait Devel { + #[rpc(name = "devel_getStateTrieKeys")] + fn get_state_trie_keys(&self, offset: usize, limit: usize) -> Result>; - # [rpc(name = "devel_getStateTrieValue")] - fn get_state_trie_value(&self, H256) -> Result>; + #[rpc(name = "devel_getStateTrieValue")] + fn get_state_trie_value(&self, key: H256) -> Result>; - # [rpc(name = "devel_startSealing")] - fn start_sealing(&self) -> Result<()>; + #[rpc(name = "devel_startSealing")] + fn start_sealing(&self) -> Result<()>; - # [rpc(name = "devel_stopSealing")] - fn stop_sealing(&self) -> Result<()>; + #[rpc(name = "devel_stopSealing")] + fn stop_sealing(&self) -> Result<()>; - # [rpc(name = "devel_getBlockSyncPeers")] - fn get_block_sync_peers(&self) -> Result>; + #[rpc(name = "devel_getBlockSyncPeers")] + fn get_block_sync_peers(&self) -> Result>; - # [rpc(name = "devel_testTPS")] - fn test_tps(&self, TPSTestSetting) -> Result; - } + #[rpc(name = "devel_testTPS")] + fn test_tps(&self, setting: TPSTestSetting) -> Result; } diff --git a/rpc/src/v1/traits/engine.rs b/rpc/src/v1/traits/engine.rs index 78cf1c2b57..67ed1a43c0 100644 --- a/rpc/src/v1/traits/engine.rs +++ b/rpc/src/v1/traits/engine.rs @@ -19,22 +19,26 @@ use ckey::PlatformAddress; use jsonrpc_core::Result; -build_rpc_trait! { - pub trait Engine { - /// Gets the reward of the given block number - # [rpc(name = "engine_getBlockReward")] - fn get_block_reward(&self, u64) -> Result; +#[rpc(server)] +pub trait Engine { + /// Gets the reward of the given block number + #[rpc(name = "engine_getBlockReward")] + fn get_block_reward(&self, block_number: u64) -> Result; - /// Gets coinbase's account id - # [rpc(name = "engine_getCoinbase")] - fn get_coinbase(&self) -> Result>; + /// Gets coinbase's account id + #[rpc(name = "engine_getCoinbase")] + fn get_coinbase(&self) -> Result>; - /// Gets the recommended minimum confirmations - # [rpc(name = "engine_getRecommendedConfirmation")] - fn get_recommended_confirmation(&self) -> Result; + /// Gets the recommended minimum confirmations + #[rpc(name = "engine_getRecommendedConfirmation")] + fn get_recommended_confirmation(&self) -> Result; - /// Gets custom action data for given custom action handler id and rlp encoded key. - # [rpc(name = "engine_getCustomActionData")] - fn get_custom_action_data(&self, u64, Bytes, Option) -> Result>>; - } + /// Gets custom action data for given custom action handler id and rlp encoded key. + #[rpc(name = "engine_getCustomActionData")] + fn get_custom_action_data( + &self, + handler_id: u64, + key_fragment: Bytes, + block_number: Option, + ) -> Result>>; } diff --git a/rpc/src/v1/traits/mempool.rs b/rpc/src/v1/traits/mempool.rs index 571b9fa919..a7094210e4 100644 --- a/rpc/src/v1/traits/mempool.rs +++ b/rpc/src/v1/traits/mempool.rs @@ -22,41 +22,40 @@ use jsonrpc_core::Result; use super::super::types::PendingTransactions; -build_rpc_trait! { - pub trait Mempool { - /// Sends signed transaction, returning its hash. - # [rpc(name = "mempool_sendSignedTransaction")] - fn send_signed_transaction(&self, Bytes) -> Result; +#[rpc(server)] +pub trait Mempool { + /// Sends signed transaction, returning its hash. + #[rpc(name = "mempool_sendSignedTransaction")] + fn send_signed_transaction(&self, raw: Bytes) -> Result; - /// Gets transaction results with given transaction tracker. - # [rpc(name = "mempool_getTransactionResultsByTracker")] - fn get_transaction_results_by_tracker(&self, H256) -> Result>; + /// Gets transaction results with given transaction tracker. + #[rpc(name = "mempool_getTransactionResultsByTracker")] + fn get_transaction_results_by_tracker(&self, tracker: H256) -> Result>; - /// Gets a hint to find out why the transaction failed. - # [rpc(name = "mempool_getErrorHint")] - fn get_error_hint(&self, H256) -> Result>; + /// Gets a hint to find out why the transaction failed. + #[rpc(name = "mempool_getErrorHint")] + fn get_error_hint(&self, transaction_hash: H256) -> Result>; - /// Gets transactions in the current mem pool. - # [rpc(name = "mempool_getPendingTransactions")] - fn get_pending_transactions(&self, Option, Option) -> Result; + /// Gets transactions in the current mem pool. + #[rpc(name = "mempool_getPendingTransactions")] + fn get_pending_transactions(&self, from: Option, to: Option) -> Result; - /// Gets the count of transactions in the current mem pool. - # [rpc(name = "mempool_getPendingTransactionsCount")] - fn get_pending_transactions_count(&self, Option, Option) -> Result; + /// Gets the count of transactions in the current mem pool. + #[rpc(name = "mempool_getPendingTransactionsCount")] + fn get_pending_transactions_count(&self, from: Option, to: Option) -> Result; - #[rpc(name = "mempool_getBannedAccounts")] - fn get_banned_accounts(&self) -> Result>; + #[rpc(name = "mempool_getBannedAccounts")] + fn get_banned_accounts(&self) -> Result>; - #[rpc(name = "mempool_unbanAccounts")] - fn unban_accounts(&self, Vec) -> Result<()>; + #[rpc(name = "mempool_unbanAccounts")] + fn unban_accounts(&self, prisoner_list: Vec) -> Result<()>; - #[rpc(name = "mempool_banAccounts")] - fn ban_accounts(&self, Vec) -> Result<()>; + #[rpc(name = "mempool_banAccounts")] + fn ban_accounts(&self, prisoner_list: Vec) -> Result<()>; - #[rpc(name = "mempool_getImmuneAccounts")] - fn get_immune_accounts(&self) -> Result>; + #[rpc(name = "mempool_getImmuneAccounts")] + fn get_immune_accounts(&self) -> Result>; - #[rpc(name = "mempool_registerImmuneAccounts")] - fn register_immune_accounts(&self, Vec) -> Result<()>; - } + #[rpc(name = "mempool_registerImmuneAccounts")] + fn register_immune_accounts(&self, immune_user_list: Vec) -> Result<()>; } diff --git a/rpc/src/v1/traits/miner.rs b/rpc/src/v1/traits/miner.rs index 33283ebb6e..79965bd450 100644 --- a/rpc/src/v1/traits/miner.rs +++ b/rpc/src/v1/traits/miner.rs @@ -20,12 +20,11 @@ use primitives::H256; use super::super::types::Work; -build_rpc_trait! { - pub trait Miner { - # [rpc(name = "miner_getWork")] - fn get_work(&self) -> Result; +#[rpc(server)] +pub trait Miner { + #[rpc(name = "miner_getWork")] + fn get_work(&self) -> Result; - # [rpc(name = "miner_submitWork")] - fn submit_work(&self, H256, Vec) -> Result; - } + #[rpc(name = "miner_submitWork")] + fn submit_work(&self, pow_hash: H256, seal: Vec) -> Result; } diff --git a/rpc/src/v1/traits/net.rs b/rpc/src/v1/traits/net.rs index 5ad5a553b1..b77694942a 100644 --- a/rpc/src/v1/traits/net.rs +++ b/rpc/src/v1/traits/net.rs @@ -23,63 +23,62 @@ use jsonrpc_core::Result; use super::super::types::FilterStatus; -build_rpc_trait! { - pub trait Net { - # [rpc(name = "net_localKeyFor")] - fn local_key_for(&self, ::std::net::IpAddr, u16) -> Result; +#[rpc(server)] +pub trait Net { + #[rpc(name = "net_localKeyFor")] + fn local_key_for(&self, addr: IpAddr, port: u16) -> Result; - # [rpc(name = "net_registerRemoteKeyFor")] - fn register_remote_key_for(&self, ::std::net::IpAddr, u16, Public) -> Result; + #[rpc(name = "net_registerRemoteKeyFor")] + fn register_remote_key_for(&self, addr: IpAddr, port: u16, public: Public) -> Result; - # [rpc(name = "net_connect")] - fn connect(&self, IpAddr, u16) -> Result<()>; + #[rpc(name = "net_connect")] + fn connect(&self, addr: IpAddr, port: u16) -> Result<()>; - # [rpc(name = "net_disconnect")] - fn disconnect(&self, IpAddr, u16) -> Result<()>; + #[rpc(name = "net_disconnect")] + fn disconnect(&self, addr: IpAddr, port: u16) -> Result<()>; - # [rpc(name = "net_isConnected")] - fn is_connected(&self, IpAddr, u16) -> Result; + #[rpc(name = "net_isConnected")] + fn is_connected(&self, addr: IpAddr, port: u16) -> Result; - # [rpc(name = "net_getPort")] - fn get_port(&self) -> Result; + #[rpc(name = "net_getPort")] + fn get_port(&self) -> Result; - # [rpc(name = "net_getPeerCount")] - fn get_peer_count(&self) -> Result; + #[rpc(name = "net_getPeerCount")] + fn get_peer_count(&self) -> Result; - # [rpc(name = "net_getEstablishedPeers")] - fn get_established_peers(&self) -> Result>; + #[rpc(name = "net_getEstablishedPeers")] + fn get_established_peers(&self) -> Result>; - #[rpc(name = "net_addToWhitelist")] - fn add_to_whitelist(&self, IpCidr, Option) -> Result<()>; + #[rpc(name = "net_addToWhitelist")] + fn add_to_whitelist(&self, addr: IpCidr, tag: Option) -> Result<()>; - #[rpc(name = "net_removeFromWhitelist")] - fn remove_from_whitelist(&self, IpCidr) -> Result<()>; + #[rpc(name = "net_removeFromWhitelist")] + fn remove_from_whitelist(&self, addr: IpCidr) -> Result<()>; - #[rpc(name = "net_addToBlacklist")] - fn add_to_blacklist(&self, IpCidr, Option) -> Result<()>; + #[rpc(name = "net_addToBlacklist")] + fn add_to_blacklist(&self, addr: IpCidr, tag: Option) -> Result<()>; - #[rpc(name = "net_removeFromBlacklist")] - fn remove_from_blacklist(&self, IpCidr) -> Result<()>; + #[rpc(name = "net_removeFromBlacklist")] + fn remove_from_blacklist(&self, addr: IpCidr) -> Result<()>; - #[rpc(name = "net_enableWhitelist")] - fn enable_whitelist(&self) -> Result<()>; + #[rpc(name = "net_enableWhitelist")] + fn enable_whitelist(&self) -> Result<()>; - #[rpc(name = "net_disableWhitelist")] - fn disable_whitelist(&self) -> Result<()>; + #[rpc(name = "net_disableWhitelist")] + fn disable_whitelist(&self) -> Result<()>; - #[rpc(name = "net_enableBlacklist")] - fn enable_blacklist(&self) -> Result<()>; + #[rpc(name = "net_enableBlacklist")] + fn enable_blacklist(&self) -> Result<()>; - #[rpc(name = "net_disableBlacklist")] - fn disable_blacklist(&self) -> Result<()>; + #[rpc(name = "net_disableBlacklist")] + fn disable_blacklist(&self) -> Result<()>; - #[rpc(name = "net_getWhitelist")] - fn get_whitelist(&self) -> Result; + #[rpc(name = "net_getWhitelist")] + fn get_whitelist(&self) -> Result; - #[rpc(name = "net_getBlacklist")] - fn get_blacklist(&self) -> Result; + #[rpc(name = "net_getBlacklist")] + fn get_blacklist(&self) -> Result; - #[rpc(name = "net_recentNetworkUsage")] - fn recent_network_usage(&self) -> Result>; - } + #[rpc(name = "net_recentNetworkUsage")] + fn recent_network_usage(&self) -> Result>; } diff --git a/stratum/Cargo.toml b/stratum/Cargo.toml index 7840f2cabb..a280169bd5 100644 --- a/stratum/Cargo.toml +++ b/stratum/Cargo.toml @@ -9,9 +9,9 @@ authors = ["Parity Technologies ", "CodeChain Team Date: Tue, 15 Oct 2019 11:34:41 +0900 Subject: [PATCH 063/105] Update bytes(v0.4.12), parking_lot_core(0.6.2), toml(0.5.3), tokio(0.1.17) Update following packages: bytes v0.4.7 -> v0.4.12 parking_lot_core v0.6.1 -> v0.6.2 toml v0.5.1 -> v0.5.3 tokio v0.1.7 -> v0.1.17 Commands were: ``` cargo update --package bytes cargo update --package parking_lot_core:0.6.1 cargo update --package toml:0.5.1 cargo update --package tokio:0.1.7 --precise 0.1.17 ``` Errors were: 1. bytes: jsonrpc requires ^0.4.8, and bytes were pinned to v0.4.7 for sendgrid v0.8.1. 2. parking_lot_core: https://github.com/Amanieu/parking_lot/issues/181 3. toml: `forward_to_deserialize_any_helper` was replaced by forward_to_deserialize_any 4. tokio: `Builder::core_threads` was introduced in 0.1.10 --- Cargo.lock | 820 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 516 insertions(+), 304 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a5162a3ada..ca5db3521b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,7 +45,7 @@ name = "atty" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -61,8 +61,8 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -73,7 +73,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -100,6 +100,30 @@ name = "bitstring" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "block-padding" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "byteorder" version = "1.2.7" @@ -107,13 +131,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bytes" -version = "0.4.7" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "c2-chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "c_linked_list" version = "1.1.1" @@ -129,7 +162,7 @@ dependencies = [ [[package]] name = "cfg-if" -version = "0.1.3" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -148,7 +181,7 @@ version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitstring 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -210,7 +243,7 @@ dependencies = [ "primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)", "rpassword 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -308,7 +341,7 @@ dependencies = [ "codechain-key 0.1.0", "primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -329,7 +362,7 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "secp256k1 0.6.0 (git+https://github.com/CodeChain-io/rust-secp256k1.git)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -342,14 +375,14 @@ dependencies = [ "codechain-json 0.1.0", "codechain-key 0.1.0", "codechain-types 0.1.0", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -368,7 +401,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "sendgrid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -430,11 +463,11 @@ dependencies = [ "codechain-sync 0.1.0", "codechain-types 0.1.0", "codechain-vm 0.1.0", - "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "jsonrpc-ipc-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", + "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-derive 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-http-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-ipc-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-ws-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", "kvdb 0.1.0", "kvdb-rocksdb 0.1.0", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -445,7 +478,7 @@ dependencies = [ "rlp 0.2.1", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -484,9 +517,9 @@ dependencies = [ "codechain-json 0.1.0", "codechain-logger 0.1.0", "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "jsonrpc-tcp-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", + "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-derive 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-tcp-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)", @@ -543,7 +576,7 @@ dependencies = [ "primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)", "rlp 0.2.1", "rlp_derive 0.1.0", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -583,7 +616,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -596,7 +629,7 @@ name = "crc32fast" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -604,7 +637,7 @@ name = "crossbeam" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-deque 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -647,7 +680,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -661,7 +694,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -673,7 +706,7 @@ name = "crossbeam-utils" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -681,7 +714,7 @@ name = "crossbeam-utils" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -696,7 +729,7 @@ version = "1.1.1" source = "git+https://github.com/paritytech/rust-ctrlc.git#b523017108bb2d571a7a69bd97bc406e63bc7a9d" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -716,7 +749,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "curl-sys 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)", "schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", @@ -730,7 +763,7 @@ version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -743,6 +776,14 @@ name = "data-encoding" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "dtoa" version = "0.4.2" @@ -766,7 +807,7 @@ name = "encoding_rs" version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -793,14 +834,6 @@ dependencies = [ "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "error-chain" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "error-chain" version = "0.12.0" @@ -817,7 +850,7 @@ dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -830,7 +863,7 @@ dependencies = [ "ethbloom 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -839,7 +872,7 @@ name = "ethereum-types-serialize" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -862,12 +895,17 @@ dependencies = [ "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "fdlimit" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -881,7 +919,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -937,6 +975,14 @@ name = "gcc" version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "get_if_addrs" version = "0.5.3" @@ -944,7 +990,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "get_if_addrs-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -954,7 +1000,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -962,6 +1008,16 @@ name = "getopts" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "getrandom" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "getset" version = "0.0.6" @@ -974,14 +1030,14 @@ dependencies = [ [[package]] name = "globset" -version = "0.2.1" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -990,13 +1046,13 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1022,7 +1078,7 @@ name = "http" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1059,37 +1115,12 @@ dependencies = [ "vecio 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "hyper" -version = "0.11.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "hyper" version = "0.12.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "h2 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1100,13 +1131,13 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-threadpool 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1115,7 +1146,7 @@ name = "hyper-tls" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1132,6 +1163,16 @@ dependencies = [ "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "idna" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "indexmap" version = "1.0.2" @@ -1147,7 +1188,7 @@ name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1172,98 +1213,92 @@ dependencies = [ [[package]] name = "jsonrpc-core" -version = "8.0.1" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11#811b0204cadd9c9ffb5c0e205f1694d57f550a7d" +version = "14.0.0" +source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0#7b94363c79c95f343b29fda362ed17b6d28319f1" dependencies = [ "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "jsonrpc-derive" +version = "14.0.0" +source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0#7b94363c79c95f343b29fda362ed17b6d28319f1" +dependencies = [ + "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "jsonrpc-http-server" -version = "8.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11#811b0204cadd9c9ffb5c0e205f1694d57f550a7d" +version = "14.0.0" +source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0#7b94363c79c95f343b29fda362ed17b6d28319f1" dependencies = [ - "hyper 0.11.26 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-ipc-server" -version = "8.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11#811b0204cadd9c9ffb5c0e205f1694d57f550a7d" +version = "14.0.0" +source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0#7b94363c79c95f343b29fda362ed17b6d28319f1" dependencies = [ - "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc?rev=7c9bbe3bc45d8e72a92b0951acc877da228abd50)", + "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-tokio-ipc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "jsonrpc-macros" -version = "8.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11#811b0204cadd9c9ffb5c0e205f1694d57f550a7d" -dependencies = [ - "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "jsonrpc-pubsub" -version = "8.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11#811b0204cadd9c9ffb5c0e205f1694d57f550a7d" -dependencies = [ - "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "jsonrpc-server-utils" -version = "8.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11#811b0204cadd9c9ffb5c0e205f1694d57f550a7d" +version = "14.0.0" +source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0#7b94363c79c95f343b29fda362ed17b6d28319f1" dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "globset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "globset 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-tcp-server" -version = "8.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11#811b0204cadd9c9ffb5c0e205f1694d57f550a7d" +version = "14.0.0" +source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0#7b94363c79c95f343b29fda362ed17b6d28319f1" dependencies = [ - "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-ws-server" -version = "8.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11#811b0204cadd9c9ffb5c0e205f1694d57f550a7d" +version = "14.0.0" +source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0#7b94363c79c95f343b29fda362ed17b6d28319f1" dependencies = [ - "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ws 0.7.5 (git+https://github.com/tomusdrw/ws-rs)", + "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ws 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1332,7 +1367,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.48" +version = "0.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1351,7 +1386,7 @@ version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1361,7 +1396,7 @@ name = "limited-table" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1388,6 +1423,14 @@ dependencies = [ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "lock_api" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "log" version = "0.3.9" @@ -1401,7 +1444,7 @@ name = "log" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1422,7 +1465,7 @@ name = "memchr" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1479,18 +1522,29 @@ dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mio-extras" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mio-named-pipes" version = "0.1.6" -source = "git+https://github.com/alexcrichton/mio-named-pipes#2072ae0de5b3632dbb065fcd9c8be6c6a2fc39ae" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1504,7 +1558,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1542,7 +1596,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.10.23 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1558,8 +1612,8 @@ name = "net2" version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1610,7 +1664,7 @@ name = "num_cpus" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1622,16 +1676,21 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "openssl" version = "0.10.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1647,7 +1706,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1672,19 +1731,18 @@ dependencies = [ [[package]] name = "parity-tokio-ipc" -version = "0.1.5" -source = "git+https://github.com/nikvolf/parity-tokio-ipc?rev=7c9bbe3bc45d8e72a92b0951acc877da228abd50#7c9bbe3bc45d8e72a92b0951acc877da228abd50" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-named-pipes 0.1.6 (git+https://github.com/alexcrichton/mio-named-pipes)", + "mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-named-pipes 0.2.0 (git+https://github.com/nikvolf/tokio-named-pipes)", - "tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-named-pipes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1697,23 +1755,52 @@ dependencies = [ "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parking_lot_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "percent-encoding" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "phf" version = "0.7.24" @@ -1762,6 +1849,11 @@ dependencies = [ "primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)", ] +[[package]] +name = "ppv-lite86" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "primitives" version = "0.4.0" @@ -1770,6 +1862,14 @@ dependencies = [ "ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro-crate" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro2" version = "0.3.8" @@ -1826,7 +1926,7 @@ version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1836,7 +1936,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1847,7 +1947,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1859,7 +1959,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1870,15 +1970,36 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_chacha" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_chacha" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_core" version = "0.2.2" @@ -1892,12 +2013,28 @@ name = "rand_core" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_hc" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1922,7 +2059,7 @@ name = "rand_xorshift" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1941,7 +2078,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1999,14 +2136,6 @@ dependencies = [ "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "relay" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "remove_dir_all" version = "0.5.1" @@ -2021,7 +2150,7 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2032,10 +2161,10 @@ dependencies = [ "mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2048,7 +2177,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2087,7 +2216,7 @@ name = "rocksdb" version = "0.4.5" source = "git+https://github.com/paritytech/rust-rocksdb?rev=ecf06adf3148ab10f6f7686b724498382ff4f36e#ecf06adf3148ab10f6f7686b724498382ff4f36e" dependencies = [ - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rocksdb-sys 0.3.0 (git+https://github.com/paritytech/rust-rocksdb?rev=ecf06adf3148ab10f6f7686b724498382ff4f36e)", ] @@ -2098,7 +2227,7 @@ version = "0.3.0" source = "git+https://github.com/paritytech/rust-rocksdb?rev=ecf06adf3148ab10f6f7686b724498382ff4f36e#ecf06adf3148ab10f6f7686b724498382ff4f36e" dependencies = [ "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)", ] @@ -2121,7 +2250,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2131,7 +2260,7 @@ version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2189,6 +2318,11 @@ name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "scopeguard" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "secp256k1" version = "0.6.0" @@ -2196,7 +2330,7 @@ source = "git+https://github.com/CodeChain-io/rust-secp256k1.git#7da4cfd232735b5 dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2207,7 +2341,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2241,7 +2375,7 @@ dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2249,7 +2383,7 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.53" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2269,7 +2403,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2279,14 +2413,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "sha1" -version = "0.2.0" +name = "sha-1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "shell32-sys" @@ -2318,12 +2458,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "slab" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "smallvec" -version = "0.2.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2354,7 +2489,7 @@ version = "0.1.0" source = "git+https://github.com/paritytech/rust-snappy#40ac9a0d9fd613e7f38df800a11a589b7296da73" dependencies = [ "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2362,8 +2497,8 @@ name = "socket2" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2446,11 +2581,6 @@ dependencies = [ name = "table" version = "0.1.0" -[[package]] -name = "take" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "tempdir" version = "0.3.7" @@ -2465,8 +2595,8 @@ name = "tempfile" version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2494,7 +2624,7 @@ name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2520,7 +2650,7 @@ name = "time" version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2543,19 +2673,36 @@ dependencies = [ [[package]] name = "tokio" -version = "0.1.7" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-fs 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-threadpool 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-trace-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-codec" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2563,30 +2710,40 @@ name = "tokio-core" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-current-thread" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-executor" -version = "0.1.2" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-fs" -version = "0.1.0" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2599,58 +2756,50 @@ name = "tokio-io" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-named-pipes" -version = "0.2.0" -source = "git+https://github.com/nikvolf/tokio-named-pipes#0afa6247222a7aa6e8b370e949a0f4007f0018b6" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-named-pipes 0.1.6 (git+https://github.com/alexcrichton/mio-named-pipes)", - "tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "tokio-proto" +name = "tokio-reactor" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "tokio-reactor" -version = "0.1.1" +name = "tokio-service" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "tokio-service" -version = "0.1.0" +name = "tokio-sync" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2659,7 +2808,7 @@ name = "tokio-tcp" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2679,16 +2828,26 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-timer" -version = "0.2.5" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-trace-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2696,7 +2855,7 @@ name = "tokio-udp" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2706,18 +2865,19 @@ dependencies = [ [[package]] name = "tokio-uds" -version = "0.1.7" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2725,7 +2885,15 @@ name = "toml" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "toml" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2742,6 +2910,11 @@ name = "try-lock" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "typenum" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ucd-util" version = "0.1.1" @@ -2825,6 +2998,16 @@ dependencies = [ "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "url" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "utf8-ranges" version = "1.0.0" @@ -2899,6 +3082,11 @@ dependencies = [ "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "wasi" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "winapi" version = "0.2.8" @@ -2955,18 +3143,19 @@ dependencies = [ [[package]] name = "ws" -version = "0.7.5" -source = "git+https://github.com/tomusdrw/ws-rs#f12d19c4c19422fc79af28a3181f598bc07ecd1e" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3002,11 +3191,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bech32 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1955ebdd52d5c5f1fb4f94e97aa241c2ce5729d200b3c34fc71ac6ff7a7cc556" "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" "checksum bitstring 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3e54f7b7a46d7b183eb41e2d82965261fa8a1597c68b50aced268ee1fc70272d" +"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +"checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09" +"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" -"checksum bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1d50c876fb7545f5f289cd8b2aee3f359d073ae819eed5d6373638e2c61e59" +"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" +"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" "checksum c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" "checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e" -"checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18" +"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e48d85528df61dc964aa43c5f6ca681a19cfa74939b2348d204bd08a981f2fb0" "checksum cidr 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0bf7340fd56c8198b28f1115fb6e8482538727ec1526d57334b444af578b1193" "checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" @@ -3031,19 +3224,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum curl 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf20bbe084f285f215eef2165feed70d6b75ba29cad24469badb853a4a287d0" "checksum curl-sys 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)" = "9d91a0052d5b982887d8e829bee0faffc7218ea3c6ebd3d6c2c8f678a93c9a42" "checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" +"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "88d4851b005ef16de812ea9acdb7bece2f0a40dd86c07b85631d7dafa54537bb" "checksum encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4155785c79f2f6701f185eb2e6b4caf0555ec03477cb4c70db67b465311620ed" "checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a" "checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e" -"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" "checksum ethbloom 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a93a43ce2e9f09071449da36bfa7a1b20b950ee344b6904ff23de493b03b386" "checksum ethereum-types 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "35b3c5a18bc5e73a32a110ac743ec04b02bbbcd3b71d3118d40a6113d509378a" "checksum ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ac59a21a9ce98e188f3dace9eb67a6c4a3c67ec7fbc7218cb827852679dc002" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" +"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum finally-block 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb881f88714a5f816e69131f0103e2c4b444e3a2a8741077b4b68586f2d32129" "checksum fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18d6fd718fb4396e7a9c93ac59ba7143501467ca7a143c145b5555a571d5576" @@ -3055,45 +3249,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)" = "a2037ec1c6c1c4f79557762eab1f7eae1f64f6cb418ace90fae88f0942b60139" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" +"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" "checksum get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7" "checksum get_if_addrs-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" "checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05" +"checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" "checksum getset 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "54c7f36a235738bb25904d6a2b3dbb28f6f5736cd3918c4bf80d6bb236200782" -"checksum globset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "464627f948c3190ae3d04b1bc6d7dca2f785bda0ac01278e6db129ad383dbeb6" +"checksum globset 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8e49edbcc9c7fc5beb8c0a54e7319ff8bed353a2b55e85811c6281188c2a6c84" "checksum h2 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "2b53def7bb0253af7718036fe9338c15defd209136819464384f3a553e07481b" "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" "checksum http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "eed324f0f0daf6ec10c474f150505af2c143f251722bf9dbd1261bd1f2ee2c1a" "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" "checksum hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)" = "" -"checksum hyper 0.11.26 (registry+https://github.com/rust-lang/crates.io-index)" = "66b16eb6213713f3c72d0ed14ce56423ae84dced8df73d2a2c8675f0495ae7ea" "checksum hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)" = "f1ebec079129e43af5e234ef36ee3d7e6085687d145b7ea653b262d16c6b65f1" "checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" +"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" -"checksum jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)" = "" -"checksum jsonrpc-http-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)" = "" -"checksum jsonrpc-ipc-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)" = "" -"checksum jsonrpc-macros 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)" = "" -"checksum jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)" = "" -"checksum jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)" = "" -"checksum jsonrpc-tcp-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)" = "" -"checksum jsonrpc-ws-server 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)" = "" +"checksum jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)" = "" +"checksum jsonrpc-derive 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)" = "" +"checksum jsonrpc-http-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)" = "" +"checksum jsonrpc-ipc-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)" = "" +"checksum jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)" = "" +"checksum jsonrpc-tcp-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)" = "" +"checksum jsonrpc-ws-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)" = "" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" "checksum lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddba4c30a78328befecec92fc94970e53b3ae385827d28620f0f5bb2493081e0" -"checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" +"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" "checksum libflate 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "76912aa0196b6f0e06d9c43ee877be45369157c06172ade12fe20ac3ee5ffa15" "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" "checksum limited-table 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5edd8173067e26a4f03c90698a4de70084862bbbe0c7f2dfe65a1274c35a4d3e" "checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" "checksum local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1ceb20f39ff7ae42f3ff9795f3986b1daad821caaa1e1732a0944103a5a1a66" "checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54" +"checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" @@ -3104,7 +3300,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0b28683d0b09bbc20be1c9b3f6f24854efb1356ffcffee08ea3f6e65596e85fa" "checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed" "checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" -"checksum mio-named-pipes 0.1.6 (git+https://github.com/alexcrichton/mio-named-pipes)" = "" +"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" +"checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" "checksum mio-uds 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "84c7b5caa3a118a6e34dbac36504503b1e8dc5835e833306b9d6af0e05929f79" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" @@ -3119,20 +3316,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" +"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" "checksum openssl 0.10.23 (registry+https://github.com/rust-lang/crates.io-index)" = "97c140cbb82f3b3468193dd14c1b88def39f341f68257f8a7fe8ed9ed3f628a5" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" "checksum openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)" = "75bdd6dbbb4958d38e47a1d2348847ad1eb4dc205dc5d37473ae504391865acc" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" -"checksum parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc?rev=7c9bbe3bc45d8e72a92b0951acc877da228abd50)" = "" +"checksum parity-tokio-ipc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8281bf4f1d6429573f89589bf68d89451c46750977a8264f8ea3edbabeba7947" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" +"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" "checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" +"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" "checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" "checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" "checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" "checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" +"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" "checksum primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)" = "" +"checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" "checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07" @@ -3144,10 +3347,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" "checksum rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a" +"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" "checksum rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a" +"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372" "checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" +"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" "checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" "checksum rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effa3fcaa47e18db002bdde6060944b6d2f9cfd8db471c30e873448ad9187be3" @@ -3159,7 +3366,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3d8c9f33201f46669484bacc312b00e7541bed6aaf296dffe2bb4e0ac6b8ce2a" "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" "checksum regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1ac0f60d675cc6cf13a20ec076568254472551051ad5dd050364d70671bf6b" -"checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum reqwest 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ab52e462d1e15891441aeefadff68bdea005174328ce3da0a314f2ad313ec837" "checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" @@ -3177,23 +3383,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339" "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" "checksum secp256k1 0.6.0 (git+https://github.com/CodeChain-io/rust-secp256k1.git)" = "" "checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2" "checksum security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum sendgrid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe878bd1389c4f4609fa4adb0ade9e1bf60334abaef7df63033f01eb3935228" -"checksum serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)" = "de4dee3b122edad92d80c66cac8d967ec7f8bf16a3b452247d6eb1dbf83c8f22" +"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" "checksum serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)" = "7149ef7af607b09e0e7df38b1fd74264f08a29a67f604d5cb09d3fbdb1e256bc" "checksum serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f3ad6d546e765177cf3dded3c2e424a8040f870083a0e64064746b958ece9cb1" "checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" -"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c" +"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" "checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" "checksum skeptic 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24ebf8a06f5f8bae61ae5bbc7af7aac4ef6907ae975130faba1199e5fe82256a" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" -"checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" -"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" +"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f90c5e5fe535e48807ab94fc611d323935f39d4660c52b26b96446a7b33aef10" "checksum smallvec 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "211a489e65e94b103926d2054ae515a1cdb5d515ea0ef414fee23b7e043ce748" "checksum snap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "174451758f7045084ae92070f18e5d8e5c53a716f4172a9c6b17ce03e7b82573" @@ -3209,7 +3415,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)" = "a1393e4a97a19c01e900df2aec855a29f71cf02c402e2f443b8d2747c25c5dbe" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" -"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "55c1195ef8513f3273d55ff59fe5da6940287a0d7a98331254397f464833675b" "checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83" @@ -3220,22 +3425,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" "checksum tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e9175261fbdb60781fcd388a4d6cc7e14764a2b629a7ad94abb439aed223a44f" "checksum token-generator 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e4069a8f845bbba2310f3c7c11a59fed768e74701afe2fc33883b06ed3b61462" -"checksum tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8ee337e5f4e501fc32966fec6fe0ca0cc1c237b0b1b14a335f8bfe3c5f06e286" +"checksum tokio 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "1021bb1f4150435ab8f222eb7ed37c60b2d57037def63ba43085a79f387512d7" +"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" -"checksum tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8cac2a7883ff3567e9d66bb09100d09b33d90311feca0206c7ca034bc0c55113" -"checksum tokio-fs 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76766830bbf9a2d5bfb50c95350d56a2e79e2c80f675967fff448bc615899708" +"checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" +"checksum tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f27ee0e6db01c5f0b2973824547ce7e637b2ed79b891a9677b0de9bd532b6ac" +"checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" "checksum tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "7392fe0a70d5ce0c882c4778116c519bd5dbaa8a7c3ae3d04578b3afafdcda21" -"checksum tokio-named-pipes 0.2.0 (git+https://github.com/nikvolf/tokio-named-pipes)" = "" -"checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" +"checksum tokio-named-pipes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d282d483052288b2308ba5ee795f5673b159c9bdf63c385a05609da782a5eae" "checksum tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3cedc8e5af5131dc3423ffa4f877cce78ad25259a9a62de0613735a13ebc64b" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" +"checksum tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" "checksum tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec9b094851aadd2caf83ba3ad8e8c4ce65a42104f7b94d9e6550023f0407853f" "checksum tokio-threadpool 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "17465013014410310f9f61fa10bf4724803c149ea1d51efece131c38efca93aa" -"checksum tokio-timer 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1c76b4e97a4f61030edff8bd272364e4f731b9f54c7307eb4eb733c3926eb96a" +"checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e" +"checksum tokio-trace-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "350c9edade9830dc185ae48ba45667a445ab59f6167ef6d0254ec9d2430d9dd3" "checksum tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "137bda266504893ac4774e0ec4c2108f7ccdbcb7ac8dced6305fe9e4e0b5041a" -"checksum tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "65ae5d255ce739e8537221ed2942e0445f4b3b813daebac1c0050ddaaa3587f9" +"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" "checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9" +"checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" +"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" "checksum uint 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "754ba11732b9161b94c41798e5197e5e75388d012f760c42adb5000353e98646" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" @@ -3248,6 +3458,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" "checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" @@ -3257,6 +3468,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" +"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" @@ -3265,7 +3477,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767" "checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" -"checksum ws 0.7.5 (git+https://github.com/tomusdrw/ws-rs)" = "" +"checksum ws 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6f5bb86663ff4d1639408410f50bf6050367a8525d644d49a6894cd618a631" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66b7c2281ebde13cf4391d70d4c7e5946c3c25e72a7b859ca8f677dcd0b0c61" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" From df1bb228bc075165021500803177a0b2d0a6683e Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Fri, 11 Oct 2019 19:34:38 +0900 Subject: [PATCH 064/105] Fix to wait jsonrpc-server closing --- codechain/run_node.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/codechain/run_node.rs b/codechain/run_node.rs index 5ec7eb7c02..9700313ce5 100644 --- a/codechain/run_node.rs +++ b/codechain/run_node.rs @@ -328,7 +328,7 @@ pub fn run_node(matches: &ArgMatches) -> Result<(), String> { block_sync: maybe_sync_sender, }); - let _rpc_server = { + let rpc_server = { if !config.rpc.disable.unwrap() { Some(rpc_http_start(config.rpc_http_config(), config.rpc.enable_devel_api, &*rpc_apis_deps)?) } else { @@ -336,7 +336,7 @@ pub fn run_node(matches: &ArgMatches) -> Result<(), String> { } }; - let _ipc_server = { + let ipc_server = { if !config.ipc.disable.unwrap() { Some(rpc_ipc_start(&config.rpc_ipc_config(), config.rpc.enable_devel_api, &*rpc_apis_deps)?) } else { @@ -344,7 +344,7 @@ pub fn run_node(matches: &ArgMatches) -> Result<(), String> { } }; - let _ws_server = { + let ws_server = { if !config.ws.disable.unwrap() { Some(rpc_ws_start(&config.rpc_ws_config(), config.rpc.enable_devel_api, &*rpc_apis_deps)?) } else { @@ -376,5 +376,18 @@ pub fn run_node(matches: &ArgMatches) -> Result<(), String> { wait_for_exit(); + if let Some(server) = rpc_server { + server.close_handle().close(); + server.wait(); + } + if let Some(server) = ipc_server { + server.close_handle().close(); + server.wait(); + } + if let Some(server) = ws_server { + server.close_handle().close(); + server.wait().map_err(|err| format!("Error while closing jsonrpc ws server: {}", err))?; + } + Ok(()) } From 2a1610caee79cd6eb3fd4d4f1e9f8b3f7d99acfe Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Tue, 15 Oct 2019 03:34:32 +0900 Subject: [PATCH 065/105] Update jsonrpc with the fixes on race condition on `wait()` The fix (https://github.com/paritytech/jsonrpc/pull/504) has been merged to `master`. It'll take times to relase, so use the merged master directly. --- Cargo.lock | 70 +++++++++++++++++++++++----------------------- rpc/Cargo.toml | 10 +++---- stratum/Cargo.toml | 6 ++-- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca5db3521b..b2d9aaec55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -463,11 +463,11 @@ dependencies = [ "codechain-sync 0.1.0", "codechain-types 0.1.0", "codechain-vm 0.1.0", - "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", - "jsonrpc-derive 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", - "jsonrpc-http-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", - "jsonrpc-ipc-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", - "jsonrpc-ws-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-derive 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-http-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-ipc-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-ws-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", "kvdb 0.1.0", "kvdb-rocksdb 0.1.0", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -517,9 +517,9 @@ dependencies = [ "codechain-json 0.1.0", "codechain-logger 0.1.0", "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", - "jsonrpc-derive 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", - "jsonrpc-tcp-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-derive 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-tcp-server 14.0.1 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)", @@ -1214,7 +1214,7 @@ dependencies = [ [[package]] name = "jsonrpc-core" version = "14.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0#7b94363c79c95f343b29fda362ed17b6d28319f1" +source = "git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8#d1993a80176afdcbae6949bbf73ebbaf5625e644" dependencies = [ "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1226,7 +1226,7 @@ dependencies = [ [[package]] name = "jsonrpc-derive" version = "14.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0#7b94363c79c95f343b29fda362ed17b6d28319f1" +source = "git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8#d1993a80176afdcbae6949bbf73ebbaf5625e644" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1237,11 +1237,11 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" version = "14.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0#7b94363c79c95f343b29fda362ed17b6d28319f1" +source = "git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8#d1993a80176afdcbae6949bbf73ebbaf5625e644" dependencies = [ "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", - "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1251,10 +1251,10 @@ dependencies = [ [[package]] name = "jsonrpc-ipc-server" version = "14.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0#7b94363c79c95f343b29fda362ed17b6d28319f1" +source = "git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8#d1993a80176afdcbae6949bbf73ebbaf5625e644" dependencies = [ - "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", - "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-tokio-ipc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1264,11 +1264,11 @@ dependencies = [ [[package]] name = "jsonrpc-server-utils" version = "14.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0#7b94363c79c95f343b29fda362ed17b6d28319f1" +source = "git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8#d1993a80176afdcbae6949bbf73ebbaf5625e644" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1278,11 +1278,11 @@ dependencies = [ [[package]] name = "jsonrpc-tcp-server" -version = "14.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0#7b94363c79c95f343b29fda362ed17b6d28319f1" +version = "14.0.1" +source = "git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8#d1993a80176afdcbae6949bbf73ebbaf5625e644" dependencies = [ - "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", - "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1291,10 +1291,10 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" version = "14.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0#7b94363c79c95f343b29fda362ed17b6d28319f1" +source = "git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8#d1993a80176afdcbae6949bbf73ebbaf5625e644" dependencies = [ - "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", - "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)", + "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1987,7 +1987,7 @@ name = "rand_chacha" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2026,7 +2026,7 @@ name = "rand_hc" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2059,7 +2059,7 @@ name = "rand_xorshift" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3270,13 +3270,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" -"checksum jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)" = "" -"checksum jsonrpc-derive 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)" = "" -"checksum jsonrpc-http-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)" = "" -"checksum jsonrpc-ipc-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)" = "" -"checksum jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)" = "" -"checksum jsonrpc-tcp-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)" = "" -"checksum jsonrpc-ws-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.0)" = "" +"checksum jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)" = "" +"checksum jsonrpc-derive 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)" = "" +"checksum jsonrpc-http-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)" = "" +"checksum jsonrpc-ipc-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)" = "" +"checksum jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)" = "" +"checksum jsonrpc-tcp-server 14.0.1 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)" = "" +"checksum jsonrpc-ws-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)" = "" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 6a1cc5dabf..3aee4e1d14 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -33,8 +33,8 @@ rustc-hex = "1.0" rustc-serialize = "0.3" time = "0.1" tokio-core = "0.1.17" -jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", tag = "v14.0.0" } -jsonrpc-derive = { git = "https://github.com/paritytech/jsonrpc.git", tag = "v14.0.0" } -jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", tag = "v14.0.0" } -jsonrpc-ipc-server = { git = "https://github.com/paritytech/jsonrpc.git", tag = "v14.0.0" } -jsonrpc-ws-server = { git = "https://github.com/paritytech/jsonrpc.git", tag = "v14.0.0" } +jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", rev = "d1993a8" } +jsonrpc-derive = { git = "https://github.com/paritytech/jsonrpc.git", rev = "d1993a8" } +jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", rev = "d1993a8" } +jsonrpc-ipc-server = { git = "https://github.com/paritytech/jsonrpc.git", rev = "d1993a8" } +jsonrpc-ws-server = { git = "https://github.com/paritytech/jsonrpc.git", rev = "d1993a8" } diff --git a/stratum/Cargo.toml b/stratum/Cargo.toml index a280169bd5..e12ad3ad6b 100644 --- a/stratum/Cargo.toml +++ b/stratum/Cargo.toml @@ -9,9 +9,9 @@ authors = ["Parity Technologies ", "CodeChain Team Date: Tue, 22 Oct 2019 16:05:00 +0900 Subject: [PATCH 066/105] Add get_version and set_version When the data structure of data that is saved in the KVDB is changed, CodeChain should migrate the data. To identify the stored data structure, we need to keep a version number. This commit adds code to save and load a version number. To make the DB easier to manage, this code saves versions in the same column with the same prefix. --- core/src/db_version.rs | 40 ++++++++++++++++++++++++++++++++++++++++ core/src/lib.rs | 1 + 2 files changed, 41 insertions(+) create mode 100644 core/src/db_version.rs diff --git a/core/src/db_version.rs b/core/src/db_version.rs new file mode 100644 index 0000000000..dc46a95203 --- /dev/null +++ b/core/src/db_version.rs @@ -0,0 +1,40 @@ +// Copyright 2019 Kodebox, Inc. +// This file is part of CodeChain. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +use kvdb::{DBTransaction, KeyValueDB}; + +use crate::db; + +pub const VERSION_KEY_PREFIX: &[u8] = b"version_"; +/// Save the version of Tendermint backup where the key below is pointing +pub const VERSION_KEY_TENDERMINT_BACKUP: &[u8] = b"version_tendermint-backup"; + +/// To support data values that are saved before the version scheme return 0 if the version does not exist +pub fn get_version(db: &dyn KeyValueDB, key: &[u8]) -> u32 { + let value = db.get(db::COL_EXTRA, key).expect("Low level database error. Some issue with disk?"); + if let Some(bytes) = value { + rlp::decode(&bytes) + } else { + 0 + } +} + +pub fn set_version(batch: &mut DBTransaction, key: &[u8], value: u32) { + assert!( + key.starts_with(VERSION_KEY_PREFIX), + "Version keys should be prefixed with".to_owned() + std::str::from_utf8(VERSION_KEY_PREFIX).unwrap() + ); + batch.put(db::COL_EXTRA, key, &rlp::encode(&value).into_vec()); +} diff --git a/core/src/lib.rs b/core/src/lib.rs index 8c28839bdd..26cf864d8f 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -67,6 +67,7 @@ mod client; mod codechain_machine; mod consensus; mod db; +mod db_version; pub mod encoded; mod error; mod invoice; From 56f818edd06eeca613e03ab5ac9f80453b6c4752 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Tue, 22 Oct 2019 15:15:52 +0900 Subject: [PATCH 067/105] Save finalized_view_of_previous_block and finalized_view_of_current_block Tendermint worker's last_confirmed_view is used for two purposes. One is the previous height's finalized view, and the other one is the current height's finalized view. This commit is part of splitting the last_confirmed_view variable. --- core/src/consensus/tendermint/backup.rs | 138 +++++++++++++++++++++--- core/src/consensus/tendermint/worker.rs | 10 +- 2 files changed, 129 insertions(+), 19 deletions(-) diff --git a/core/src/consensus/tendermint/backup.rs b/core/src/consensus/tendermint/backup.rs index bc22a664f1..1f8c45b5c7 100644 --- a/core/src/consensus/tendermint/backup.rs +++ b/core/src/consensus/tendermint/backup.rs @@ -20,18 +20,21 @@ use primitives::H256; use super::message::ConsensusMessage; use super::types::{Height, Step, View}; use crate::db; +use crate::db_version; const BACKUP_KEY: &[u8] = b"tendermint-backup"; +const BACKUP_VERSION: u32 = 1; pub struct BackupView<'a> { pub height: &'a Height, pub view: &'a View, pub step: &'a Step, pub votes: &'a [ConsensusMessage], - pub last_confirmed_view: &'a View, + pub finalized_view_of_previous_block: &'a View, + pub finalized_view_of_current_block: &'a Option, } -pub struct BackupData { +pub struct BackupDataV0 { pub height: Height, pub view: View, pub step: Step, @@ -40,25 +43,111 @@ pub struct BackupData { pub last_confirmed_view: View, } +pub struct BackupDataV1 { + pub height: Height, + pub view: View, + pub step: Step, + pub votes: Vec, + pub proposal: Option, + pub finalized_view_of_previous_block: View, + pub finalized_view_of_current_block: Option, +} + pub fn backup(db: &dyn KeyValueDB, backup_data: BackupView) { let BackupView { height, view, step, votes, - last_confirmed_view, + finalized_view_of_previous_block, + finalized_view_of_current_block, } = backup_data; let mut s = rlp::RlpStream::new(); - s.begin_list(5); + s.begin_list(6); s.append(height).append(view).append(step).append_list(votes); - s.append(last_confirmed_view); + s.append(finalized_view_of_previous_block); + s.append(finalized_view_of_current_block); let mut batch = DBTransaction::new(); + debug_assert!( + db_version::VERSION_KEY_TENDERMINT_BACKUP.ends_with(BACKUP_KEY), + "version key should end with the backup key" + ); + db_version::set_version(&mut batch, db_version::VERSION_KEY_TENDERMINT_BACKUP, BACKUP_VERSION); batch.put(db::COL_EXTRA, BACKUP_KEY, &s.drain().into_vec()); db.write(batch).expect("Low level database error. Some issue with disk?"); } -pub fn restore(db: &dyn KeyValueDB) -> Option { +pub fn restore(db: &dyn KeyValueDB) -> Option { + let version = db_version::get_version(db, db_version::VERSION_KEY_TENDERMINT_BACKUP); + if version < BACKUP_VERSION { + migrate(db); + } + load_v1(db) +} + +fn find_proposal(votes: &[ConsensusMessage], height: Height, view: View) -> Option { + votes + .iter() + .rev() + .map(|vote| &vote.on) + .find(|vote_on| { + vote_on.step.step == Step::Propose && vote_on.step.view == view && vote_on.step.height == height + }) + .map(|vote_on| vote_on.block_hash) + .unwrap_or(None) +} + +fn migrate(db: &dyn KeyValueDB) { + let version = db_version::get_version(db, db_version::VERSION_KEY_TENDERMINT_BACKUP); + assert!( + version < BACKUP_VERSION, + "migrate function should be called when the saved version is less than BACKUP_VERSION" + ); + + match version { + 0 => { + migrate_from_0_to_1(db); + } + _ => panic!("Invalid migration version {}", version), + } +} + +fn migrate_from_0_to_1(db: &dyn KeyValueDB) { + let v0 = if let Some(v0) = load_v0(db) { + v0 + } else { + return + }; + let step = v0.step; + let v1 = BackupDataV1 { + height: v0.height, + view: v0.view, + step: v0.step, + votes: v0.votes, + proposal: v0.proposal, + // This is not a correct behavior if step == Step::Commit. + // In Commit state, the Tendermint module overwrote the last_confirmed_view to finalized_view_of_current_block. + // So we can't restore finalized_view_of_previous block. + // The code below maintain older code's behavior: + finalized_view_of_previous_block: v0.last_confirmed_view, + finalized_view_of_current_block: if step == Step::Commit { + Some(v0.last_confirmed_view) + } else { + None + }, + }; + backup(db, BackupView { + height: &v1.height, + view: &v1.view, + step: &v1.step, + votes: &v1.votes, + finalized_view_of_previous_block: &v1.finalized_view_of_previous_block, + finalized_view_of_current_block: &v1.finalized_view_of_current_block, + }) +} + +fn load_v0(db: &dyn KeyValueDB) -> Option { let value = db.get(db::COL_EXTRA, BACKUP_KEY).expect("Low level database error. Some issue with disk?"); let (height, view, step, votes, last_confirmed_view) = value.map(|bytes| { let bytes = bytes.into_vec(); @@ -68,7 +157,7 @@ pub fn restore(db: &dyn KeyValueDB) -> Option { let proposal = find_proposal(&votes, height, view); - Some(BackupData { + Some(BackupDataV0 { height, view, step, @@ -78,14 +167,29 @@ pub fn restore(db: &dyn KeyValueDB) -> Option { }) } -fn find_proposal(votes: &[ConsensusMessage], height: Height, view: View) -> Option { - votes - .iter() - .rev() - .map(|vote| &vote.on) - .find(|vote_on| { - vote_on.step.step == Step::Propose && vote_on.step.view == view && vote_on.step.height == height - }) - .map(|vote_on| vote_on.block_hash) - .unwrap_or(None) +fn load_v1(db: &dyn KeyValueDB) -> Option { + #[derive(RlpDecodable)] + struct Backup { + height: Height, + view: View, + step: Step, + votes: Vec, + finalized_view_of_previous_block: View, + finalized_view_of_current_block: Option, + } + + let value = db.get(db::COL_EXTRA, BACKUP_KEY).expect("Low level database error. Some issue with disk?")?; + let backup: Backup = rlp::decode(&value); + + let proposal = find_proposal(&backup.votes, backup.height, backup.view); + + Some(BackupDataV1 { + height: backup.height, + view: backup.view, + step: backup.step, + votes: backup.votes, + proposal, + finalized_view_of_previous_block: backup.finalized_view_of_previous_block, + finalized_view_of_current_block: backup.finalized_view_of_current_block, + }) } diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 95f9b3d3a3..0c7b1f4b0d 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -981,7 +981,8 @@ impl Worker { view: &self.view, step: &self.step.to_step(), votes: &self.votes.get_all(), - last_confirmed_view: &self.last_confirmed_view, + finalized_view_of_previous_block: &self.last_confirmed_view, + finalized_view_of_current_block: &Some(self.last_confirmed_view), }); } @@ -1001,7 +1002,12 @@ impl Worker { self.step = backup_step; self.height = backup.height; self.view = backup.view; - self.last_confirmed_view = backup.last_confirmed_view; + if backup.step == Step::Commit { + self.last_confirmed_view = + backup.finalized_view_of_current_block.expect("In commit step the finalized view exist") + } else { + self.last_confirmed_view = backup.finalized_view_of_previous_block; + } if let Some(proposal) = backup.proposal { if client.block(&BlockId::Hash(proposal)).is_some() { self.proposal = Proposal::ProposalImported(proposal); From 505854f085e82795d61a70109a1df22cde8c0494 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Tue, 22 Oct 2019 15:42:37 +0900 Subject: [PATCH 068/105] Split last_confirmed_view variable Tendermint worker's last_confirmed_view is used for two purposes. One is the previous height's finalized view, and the other one is the current height's finalized view. This commit is part of splitting the last_confirmed_view variable. --- core/src/consensus/tendermint/worker.rs | 90 ++++++++++++++++--------- 1 file changed, 59 insertions(+), 31 deletions(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 0c7b1f4b0d..1a8002be92 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -85,8 +85,11 @@ struct Worker { last_two_thirds_majority: TwoThirdsMajority, /// hash of the proposed block, used for seal submission. proposal: Proposal, - /// The last confirmed view from the commit step. - last_confirmed_view: View, + /// The finalized view of the previous height's block. + /// The signatures for the previous block is signed for the view below. + finalized_view_of_previous_block: View, + /// The finalized view of the current height's block. + finalized_view_of_current_block: Option, /// Set used to determine the current validators. validators: Arc, /// Channel to the network extension, must be set later. @@ -187,7 +190,8 @@ impl Worker { signer: Default::default(), last_two_thirds_majority: TwoThirdsMajority::Empty, proposal: Proposal::None, - last_confirmed_view: 0, + finalized_view_of_previous_block: 0, + finalized_view_of_current_block: None, validators, extension, votes_received: MutTrigger::new(BitSet::new()), @@ -418,7 +422,11 @@ impl Worker { return false } - let vote_step = VoteStep::new(self.height, self.last_confirmed_view, Step::Precommit); + let vote_step = VoteStep::new( + self.height, + self.finalized_view_of_current_block.expect("finalized_view_of_current_height is not None in Commit state"), + Step::Precommit, + ); if self.step.is_commit_timedout() && self.check_current_block_exists() { cinfo!(ENGINE, "Transition to Propose because best block is changed after commit timeout"); return true @@ -597,8 +605,10 @@ impl Worker { self.client().update_sealing(BlockId::Hash(parent_block_hash), true); } - fn save_last_confirmed_view(&mut self, view: View) { - self.last_confirmed_view = view; + /// Do we need this function? + fn set_finalized_view_in_current_height(&mut self, view: View) { + assert_eq!(self.finalized_view_of_current_block, None); + self.finalized_view_of_current_block = Some(view); } fn increment_view(&mut self, n: View) { @@ -608,7 +618,28 @@ impl Worker { self.votes_received = MutTrigger::new(BitSet::new()); } - fn move_to_height(&mut self, height: Height) { + /// Move to the next height. + fn move_to_the_next_height(&mut self) { + assert!( + self.step.is_commit(), + "move_to_the_next_height should be called in Commit state, but the current step is {:?}", + self.step + ); + cinfo!(ENGINE, "Transitioning to height {}.", self.height + 1); + self.last_two_thirds_majority = TwoThirdsMajority::Empty; + self.height += 1; + self.view = 0; + self.proposal = Proposal::None; + self.votes_received = MutTrigger::new(BitSet::new()); + self.finalized_view_of_previous_block = + self.finalized_view_of_current_block.expect("self.step == Step::Commit"); + self.finalized_view_of_current_block = None; + } + + /// Jump to the height. + /// This function is called when new blocks are received from block sync. + /// This function could be called at any state. + fn jump_to_height(&mut self, height: Height, finalized_view_of_previous_height: View) { assert!(height > self.height, "{} < {}", height, self.height); cinfo!(ENGINE, "Transitioning to height {}.", height); self.last_two_thirds_majority = TwoThirdsMajority::Empty; @@ -616,6 +647,8 @@ impl Worker { self.view = 0; self.proposal = Proposal::None; self.votes_received = MutTrigger::new(BitSet::new()); + self.finalized_view_of_previous_block = finalized_view_of_previous_height; + self.finalized_view_of_current_block = None; } #[allow(clippy::cognitive_complexity)] @@ -736,7 +769,7 @@ impl Worker { Step::Commit => { cinfo!(ENGINE, "move_to_step: Commit."); let (view, block_hash) = state.committed().expect("commit always has committed_view"); - self.save_last_confirmed_view(view); + self.set_finalized_view_in_current_height(view); let proposal_received = self.is_proposal_received(self.height, view, block_hash); let proposal_imported = self.client().block(&block_hash.into()).is_some(); @@ -850,8 +883,7 @@ impl Worker { && has_enough_aligned_votes { if self.can_move_from_commit_to_propose() { - let height = self.height; - self.move_to_height(height + 1); + self.move_to_the_next_height(); self.move_to_step(TendermintState::Propose, is_restoring); return } @@ -957,9 +989,11 @@ impl Worker { _ => {} }; } else if current_height < height { - self.move_to_height(height); - let prev_block_view = TendermintSealView::new(proposal.seal()).previous_block_view().unwrap(); - self.save_last_confirmed_view(prev_block_view); + let finalized_view_of_previous_height = + TendermintSealView::new(proposal.seal()).previous_block_view().unwrap(); + + self.jump_to_height(height, finalized_view_of_previous_height); + let proposal_is_for_view0 = self.votes.has_votes_for( &VoteStep { height, @@ -981,8 +1015,8 @@ impl Worker { view: &self.view, step: &self.step.to_step(), votes: &self.votes.get_all(), - finalized_view_of_previous_block: &self.last_confirmed_view, - finalized_view_of_current_block: &Some(self.last_confirmed_view), + finalized_view_of_previous_block: &self.finalized_view_of_previous_block, + finalized_view_of_current_block: &self.finalized_view_of_current_block, }); } @@ -1002,12 +1036,9 @@ impl Worker { self.step = backup_step; self.height = backup.height; self.view = backup.view; - if backup.step == Step::Commit { - self.last_confirmed_view = - backup.finalized_view_of_current_block.expect("In commit step the finalized view exist") - } else { - self.last_confirmed_view = backup.finalized_view_of_previous_block; - } + self.finalized_view_of_previous_block = backup.finalized_view_of_previous_block; + self.finalized_view_of_current_block = backup.finalized_view_of_current_block; + if let Some(proposal) = backup.proposal { if client.block(&BlockId::Hash(proposal)).is_some() { self.proposal = Proposal::ProposalImported(proposal); @@ -1045,7 +1076,7 @@ impl Worker { let view = self.view; - let last_block_view = &self.last_confirmed_view; + let last_block_view = &self.finalized_view_of_previous_block; assert_eq!(self.prev_block_hash(), parent_hash); let (precommits, precommit_indices) = self @@ -1305,8 +1336,7 @@ impl Worker { return } - let height = self.height; - self.move_to_height(height + 1); + self.move_to_the_next_height(); TendermintState::Propose } TendermintState::CommitTimedout { @@ -1374,7 +1404,7 @@ impl Worker { // the previous step. So, act as the last precommit step. VoteStep { height: self.height, - view: self.last_confirmed_view, + view: self.finalized_view_of_current_block.expect("self.step == Step::Commit"), step: Step::Precommit, } } else { @@ -1585,8 +1615,7 @@ impl Worker { if enacted.first() == Some(&committed_block_hash) { cdebug!(ENGINE, "Committed block {} is now the best block", committed_block_hash); if self.can_move_from_commit_to_propose() { - let new_height = self.height + 1; - self.move_to_height(new_height); + self.move_to_the_next_height(); self.move_to_step(TendermintState::Propose, false); return } @@ -1612,11 +1641,10 @@ impl Worker { let full_header = header.decode(); if self.height < header.number() { cinfo!(ENGINE, "Received a commit: {:?}.", header.number()); - let prev_block_view = TendermintSealView::new(full_header.seal()) + let finalized_view_of_previous_height = TendermintSealView::new(full_header.seal()) .previous_block_view() .expect("Imported block already checked"); - self.move_to_height(header.number()); - self.save_last_confirmed_view(prev_block_view); + self.jump_to_height(header.number(), finalized_view_of_previous_height); } } if height_at_begin != self.height { @@ -1809,7 +1837,7 @@ impl Worker { // the previous step. So, act as the last precommit step. VoteStep { height: self.height, - view: self.last_confirmed_view, + view: self.finalized_view_of_current_block.expect("self.step == Step::Commit"), step: Step::Precommit, } } else { From d70245e0eb131f0eb09b883d50b2a81e0b4b458c Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Fri, 18 Oct 2019 16:44:48 +0900 Subject: [PATCH 069/105] Rename views to author_view and finalized_view author_view: view when the block was created. finalized_view: view when the block was finalized. --- core/src/consensus/tendermint/types.rs | 8 +++- core/src/consensus/tendermint/worker.rs | 50 ++++++++++++------------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/core/src/consensus/tendermint/types.rs b/core/src/consensus/tendermint/types.rs index 7cf582ebfe..373c9e7d33 100644 --- a/core/src/consensus/tendermint/types.rs +++ b/core/src/consensus/tendermint/types.rs @@ -224,13 +224,17 @@ impl<'a> TendermintSealView<'a> { } } - pub fn previous_block_view(&self) -> Result { + /// The parent block is finalized at this view. + /// Signatures in the seal field is signed for this view. + pub fn parent_block_finalized_view(&self) -> Result { let view_rlp = self.seal.get(0).expect("block went through verify_block_basic; block has .seal_fields() fields; qed"); UntrustedRlp::new(view_rlp.as_slice()).as_val() } - pub fn consensus_view(&self) -> Result { + /// Block is created at auth_view. + /// Block verifier use other_view to verify the author + pub fn author_view(&self) -> Result { let view_rlp = self.seal.get(1).expect("block went through verify_block_basic; block has .seal_fields() fields; qed"); UntrustedRlp::new(view_rlp.as_slice()).as_val() diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 1a8002be92..a29a6fb552 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -928,9 +928,9 @@ impl Worker { let height = proposal.number() as Height; let seal_view = TendermintSealView::new(proposal.seal()); - let prev_block_view = seal_view.previous_block_view().expect("The proposal is verified"); + let parent_block_finalized_view = seal_view.parent_block_finalized_view().expect("The proposal is verified"); let on = VoteOn { - step: VoteStep::new(height - 1, prev_block_view, Step::Precommit), + step: VoteStep::new(height - 1, parent_block_finalized_view, Step::Precommit), block_hash: Some(*proposal.parent_hash()), }; for (index, signature) in seal_view.signatures().expect("The proposal is verified") { @@ -990,7 +990,7 @@ impl Worker { }; } else if current_height < height { let finalized_view_of_previous_height = - TendermintSealView::new(proposal.seal()).previous_block_view().unwrap(); + TendermintSealView::new(proposal.seal()).parent_block_finalized_view().unwrap(); self.jump_to_height(height, finalized_view_of_previous_height); @@ -1095,16 +1095,15 @@ impl Worker { fn proposal_generated(&mut self, sealed_block: &SealedBlock) { let proposal_height = sealed_block.header().number(); let proposal_seal = sealed_block.header().seal(); - let proposal_view = TendermintSealView::new(proposal_seal) - .consensus_view() - .expect("Generated proposal should have a valid seal"); + let proposal_author_view = + TendermintSealView::new(proposal_seal).author_view().expect("Generated proposal should have a valid seal"); assert!(proposal_height <= self.height, "A proposal cannot be generated on the future height"); - if proposal_height < self.height || (proposal_height == self.height && proposal_view != self.view) { + if proposal_height < self.height || (proposal_height == self.height && proposal_author_view != self.view) { ctrace!( ENGINE, "Proposal is generated on the height {} and view {}. Current height is {} and view is {}", proposal_height, - proposal_view, + proposal_author_view, self.height, self.view, ); @@ -1131,7 +1130,7 @@ impl Worker { ); return } - debug_assert_eq!(Ok(self.view), TendermintSealView::new(header.seal()).consensus_view()); + debug_assert_eq!(Ok(self.view), TendermintSealView::new(header.seal()).author_view()); self.vote_on_header_for_proposal(&header).expect("I'm a proposer"); @@ -1152,8 +1151,8 @@ impl Worker { } let height = header.number(); - let view = TendermintSealView::new(header.seal()).consensus_view().unwrap(); - let score = calculate_score(height, view); + let author_view = TendermintSealView::new(header.seal()).author_view().unwrap(); + let score = calculate_score(height, author_view); if *header.score() != score { return Err(BlockError::InvalidScore(Mismatch { @@ -1168,13 +1167,13 @@ impl Worker { fn verify_block_external(&self, header: &Header) -> Result<(), Error> { let height = header.number() as usize; - let view = TendermintSealView::new(header.seal()).consensus_view()?; - ctrace!(ENGINE, "Verify external at {}-{}, {:?}", height, view, header); + let author_view = TendermintSealView::new(header.seal()).author_view()?; + ctrace!(ENGINE, "Verify external at {}-{}, {:?}", height, author_view, header); let proposer = header.author(); if !self.is_authority(header.parent_hash(), proposer) { return Err(EngineError::BlockNotAuthorized(*proposer).into()) } - self.check_view_proposer(header.parent_hash(), header.number(), view, &proposer)?; + self.check_view_proposer(header.parent_hash(), header.number(), author_view, &proposer)?; let seal_view = TendermintSealView::new(header.seal()); let bitset_count = seal_view.bitset()?.count(); let precommits_count = seal_view.precommits().item_count()?; @@ -1197,9 +1196,9 @@ impl Worker { return Err(BlockError::InvalidSeal.into()) } - let previous_block_view = TendermintSealView::new(header.seal()).previous_block_view()?; + let parent_block_finalized_view = TendermintSealView::new(header.seal()).parent_block_finalized_view()?; let precommit_vote_on = VoteOn { - step: VoteStep::new(header.number() - 1, previous_block_view, Step::Precommit), + step: VoteStep::new(header.number() - 1, parent_block_finalized_view, Step::Precommit), block_hash: Some(*header.parent_hash()), }; @@ -1642,7 +1641,7 @@ impl Worker { if self.height < header.number() { cinfo!(ENGINE, "Received a commit: {:?}.", header.number()); let finalized_view_of_previous_height = TendermintSealView::new(full_header.seal()) - .previous_block_view() + .parent_block_finalized_view() .expect("Imported block already checked"); self.jump_to_height(header.number(), finalized_view_of_previous_height); } @@ -1791,15 +1790,14 @@ impl Worker { // The proposer re-proposed its locked proposal. // If we already imported the proposal, we should set `proposal` here. if c.block(&BlockId::Hash(header_view.hash())).is_some() { - let generated_view = TendermintSealView::new(header_view.seal()) - .consensus_view() - .expect("Imported block is verified"); + let author_view = + TendermintSealView::new(header_view.seal()).author_view().expect("Imported block is verified"); cdebug!( ENGINE, "Received a proposal({}) by a locked proposer. current view: {}, original proposal's view: {}", header_view.hash(), proposed_view, - generated_view + author_view ); self.proposal = Proposal::new_imported(header_view.hash()); } else { @@ -1975,13 +1973,14 @@ impl Worker { let block = self.client().block(&height.into()).expect("Parent block should exist"); let block_hash = block.hash(); let seal = block.seal(); - let view = TendermintSealView::new(&seal).consensus_view().expect("Block is already verified and imported"); + let author_view = + TendermintSealView::new(&seal).author_view().expect("Block is already verified and imported"); let votes = self .votes .get_all_votes_in_round(&VoteStep { height, - view, + view: author_view, step: Step::Precommit, }) .into_iter() @@ -1994,9 +1993,10 @@ impl Worker { let child_block = self.client().block(&(height + 1).into()).expect("Parent block should exist"); let child_block_header_seal = child_block.header().seal(); let child_block_seal_view = TendermintSealView::new(&child_block_header_seal); - let view = child_block_seal_view.previous_block_view().expect("Verified block"); + let parent_block_finalized_view = + child_block_seal_view.parent_block_finalized_view().expect("Verified block"); let on = VoteOn { - step: VoteStep::new(height, view, Step::Precommit), + step: VoteStep::new(height, parent_block_finalized_view, Step::Precommit), block_hash: Some(block.hash()), }; let mut votes = Vec::new(); From 71e94d64ea525ad47a18e242581f886ff2d78b21 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Fri, 18 Oct 2019 16:57:34 +0900 Subject: [PATCH 070/105] Use correct view when creating a Commit message --- core/src/consensus/tendermint/worker.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index a29a6fb552..eed20ebe84 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -1972,15 +1972,13 @@ impl Worker { if height == self.height - 1 { let block = self.client().block(&height.into()).expect("Parent block should exist"); let block_hash = block.hash(); - let seal = block.seal(); - let author_view = - TendermintSealView::new(&seal).author_view().expect("Block is already verified and imported"); + let finalized_view = self.finalized_view_of_previous_block; let votes = self .votes .get_all_votes_in_round(&VoteStep { height, - view: author_view, + view: finalized_view, step: Step::Precommit, }) .into_iter() From f18f510ebaf51eaba001eec9799e6fbe4b4d3895 Mon Sep 17 00:00:00 2001 From: Seulgi Kim Date: Mon, 21 Oct 2019 11:26:17 +0900 Subject: [PATCH 071/105] Update clippy and rustfmt This patch * prefers to use cmp * makes code return early * removes redundant cloning * removes redundant lifetime annotation * changes some other miscellaneous changes to follow clippy update. --- .github/workflows/cargo-test.yml | 4 +- core/src/blockchain/extras.rs | 4 +- core/src/blockchain/headerchain.rs | 4 +- core/src/client/importer.rs | 2 +- core/src/consensus/bit_set.rs | 22 +-- core/src/consensus/stake/action_data.rs | 17 ++- core/src/consensus/tendermint/worker.rs | 172 ++++++++++++------------ core/src/miner/mem_pool.rs | 6 +- keystore/src/accounts_dir/disk.rs | 2 +- keystore/src/json/crypto.rs | 2 +- keystore/src/keystore.rs | 2 +- network/src/client.rs | 2 +- network/src/p2p/listener.rs | 2 +- network/src/stream.rs | 2 +- rpc/src/v1/types/mod.rs | 12 +- rustfmt.toml | 2 +- state/src/impls/shard_level.rs | 44 +++--- state/src/impls/top_level.rs | 29 ++-- state/src/item/account.rs | 1 - state/src/item/asset.rs | 1 - sync/src/block/downloader/header.rs | 27 ++-- sync/src/snapshot/snapshot.rs | 2 +- types/src/util/tag.rs | 2 +- util/kvdb-rocksdb/src/lib.rs | 6 +- util/memorydb/src/lib.rs | 58 ++++---- util/merkle/src/nibbleslice.rs | 2 +- util/merkle/src/triedb.rs | 14 +- util/rlp/src/common.rs | 6 +- util/rlp_compress/src/common.rs | 6 +- vm/tests/chk_sig.rs | 20 +-- 30 files changed, 237 insertions(+), 238 deletions(-) diff --git a/.github/workflows/cargo-test.yml b/.github/workflows/cargo-test.yml index 2eb39694dc..8c2acbc265 100644 --- a/.github/workflows/cargo-test.yml +++ b/.github/workflows/cargo-test.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - toolchain: nightly-2019-05-17 + toolchain: nightly-2019-10-13 override: true - run: rustup component add clippy - run: cargo fetch --verbose @@ -23,7 +23,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - toolchain: nightly-2019-05-17 + toolchain: nightly-2019-10-13 override: true - run: rustup component add rustfmt - run: cargo fmt -- --check diff --git a/core/src/blockchain/extras.rs b/core/src/blockchain/extras.rs index 7ef5aea063..8f86d1919c 100644 --- a/core/src/blockchain/extras.rs +++ b/core/src/blockchain/extras.rs @@ -150,7 +150,7 @@ impl Add for TransactionAddresses { type Output = Self; fn add(self, rhs: Self) -> ::Output { - let mut s = self.clone(); + let mut s = self; s += rhs; s } @@ -168,7 +168,7 @@ impl Sub for TransactionAddresses { type Output = Self; fn sub(self, rhs: Self) -> ::Output { - let mut s = self.clone(); + let mut s = self; s -= rhs; s } diff --git a/core/src/blockchain/headerchain.rs b/core/src/blockchain/headerchain.rs index 25dffc4178..31831893c5 100644 --- a/core/src/blockchain/headerchain.rs +++ b/core/src/blockchain/headerchain.rs @@ -276,11 +276,11 @@ impl HeaderChain { }; match route.retracted.len() { 0 => BestHeaderChanged::CanonChainAppended { - best_header: new_best_header.clone(), + best_header: new_best_header, }, _ => BestHeaderChanged::BranchBecomingCanonChain { tree_route: route, - best_header: new_best_header.clone(), + best_header: new_best_header, }, } } else { diff --git a/core/src/client/importer.rs b/core/src/client/importer.rs index e2cca86c7a..d4cd457afc 100644 --- a/core/src/client/importer.rs +++ b/core/src/client/importer.rs @@ -199,7 +199,7 @@ impl Importer { let mut batch = DBTransaction::new(); block.state().journal_under(&mut batch, number).expect("DB commit failed"); - let route = chain.insert_block(&mut batch, block_data, invoices.clone(), self.engine.borrow()); + let route = chain.insert_block(&mut batch, block_data, invoices, self.engine.borrow()); // Final commit to the DB client.db().write_buffered(batch); diff --git a/core/src/consensus/bit_set.rs b/core/src/consensus/bit_set.rs index 4cf096e135..6b552fa20e 100644 --- a/core/src/consensus/bit_set.rs +++ b/core/src/consensus/bit_set.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use std::cmp::PartialEq; +use std::cmp::{Ordering, PartialEq}; use std::convert::TryFrom; use std::fmt; use std::ops::Sub; @@ -126,20 +126,20 @@ impl Decodable for BitSet { rlp.decoder().decode_value(|bytes| { let expected = BITSET_SIZE; let got = bytes.len(); - if got > expected { - Err(DecoderError::RlpIsTooBig { + match got.cmp(&expected) { + Ordering::Greater => Err(DecoderError::RlpIsTooBig { expected, got, - }) - } else if got < expected { - Err(DecoderError::RlpIsTooShort { + }), + Ordering::Less => Err(DecoderError::RlpIsTooShort { expected, got, - }) - } else { - let mut bit_set = BitSet::new(); - bit_set.0.copy_from_slice(bytes); - Ok(bit_set) + }), + Ordering::Equal => { + let mut bit_set = BitSet::new(); + bit_set.0.copy_from_slice(bytes); + Ok(bit_set) + } } }) } diff --git a/core/src/consensus/stake/action_data.rs b/core/src/consensus/stake/action_data.rs index 312e2cbc31..9588f9153b 100644 --- a/core/src/consensus/stake/action_data.rs +++ b/core/src/consensus/stake/action_data.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +use std::cmp::Ordering; use std::collections::btree_map::{BTreeMap, Entry}; use std::collections::btree_set::{self, BTreeSet}; use std::collections::{btree_map, HashMap, HashSet}; @@ -203,12 +204,16 @@ impl<'a> Delegation<'a> { } if let Entry::Occupied(mut entry) = self.delegatees.entry(delegatee) { - if *entry.get() > quantity { - *entry.get_mut() -= quantity; - return Ok(()) - } else if *entry.get() == quantity { - entry.remove(); - return Ok(()) + match entry.get().cmp(&quantity) { + Ordering::Greater => { + *entry.get_mut() -= quantity; + return Ok(()) + } + Ordering::Equal => { + entry.remove(); + return Ok(()) + } + Ordering::Less => {} } } diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index eed20ebe84..c881cc443e 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +use std::cmp::Ordering; use std::iter::Iterator; use std::mem; use std::sync::{Arc, Weak}; @@ -690,34 +691,33 @@ impl Worker { cinfo!(ENGINE, "move_to_step: Propose."); // If there are multiple proposals, use the first proposal. if let Some(hash) = self.votes.get_block_hashes(&vote_step).first() { - if self.client().block(&BlockId::Hash(*hash)).is_some() { - self.proposal = Proposal::new_imported(*hash); - self.move_to_step(TendermintState::Prevote, is_restoring); - } else { + if self.client().block(&BlockId::Hash(*hash)).is_none() { cwarn!(ENGINE, "Proposal is received but not imported"); // Proposal is received but is not verified yet. // Wait for verification. return } - } else { - let parent_block_hash = self.prev_block_hash(); - if self.is_signer_proposer(&parent_block_hash) { - if let TwoThirdsMajority::Lock(lock_view, locked_block_hash) = self.last_two_thirds_majority { - cinfo!(ENGINE, "I am a proposer, I'll re-propose a locked block"); - match self.locked_proposal_block(lock_view, locked_block_hash) { - Ok(block) => self.repropose_block(block), - Err(error_msg) => cwarn!(ENGINE, "{}", error_msg), - } - } else { - cinfo!(ENGINE, "I am a proposer, I'll create a block"); - self.update_sealing(parent_block_hash); - self.step = TendermintState::ProposeWaitBlockGeneration { - parent_hash: parent_block_hash, - }; - } - } else { - self.request_proposal_to_any(vote_step.height, vote_step.view); + self.proposal = Proposal::new_imported(*hash); + self.move_to_step(TendermintState::Prevote, is_restoring); + return + } + let parent_block_hash = self.prev_block_hash(); + if !self.is_signer_proposer(&parent_block_hash) { + self.request_proposal_to_any(vote_step.height, vote_step.view); + return + } + if let TwoThirdsMajority::Lock(lock_view, locked_block_hash) = self.last_two_thirds_majority { + cinfo!(ENGINE, "I am a proposer, I'll re-propose a locked block"); + match self.locked_proposal_block(lock_view, locked_block_hash) { + Ok(block) => self.repropose_block(block), + Err(error_msg) => cwarn!(ENGINE, "{}", error_msg), } + } else { + cinfo!(ENGINE, "I am a proposer, I'll create a block"); + self.update_sealing(parent_block_hash); + self.step = TendermintState::ProposeWaitBlockGeneration { + parent_hash: parent_block_hash, + }; } } Step::Prevote => { @@ -1562,7 +1562,7 @@ impl Worker { on, }; - self.votes.collect(vote.clone()).expect("Must not attempt double vote on proposal");; + self.votes.collect(vote.clone()).expect("Must not attempt double vote on proposal"); cinfo!(ENGINE, "Voted {:?} as {}th proposer.", vote, signer_index); Ok(vote) } @@ -1811,7 +1811,7 @@ impl Worker { ); } - if let Err(double) = self.votes.collect(message.clone()) { + if let Err(double) = self.votes.collect(message) { cerror!(ENGINE, "Double Vote found {:?}", double); self.report_double_vote(&double); return None @@ -1869,17 +1869,15 @@ impl Worker { let current_step = current_vote_step.step; if current_step == Step::Prevote || current_step == Step::Precommit { - let peer_known_votes = if current_vote_step == peer_vote_step { - peer_known_votes - } else if current_vote_step < peer_vote_step { + let peer_known_votes = match current_vote_step.cmp(&peer_vote_step) { + Ordering::Equal => peer_known_votes, // We don't know which votes peer has. // However the peer knows more than 2/3 of votes. // So request all votes. - BitSet::all_set() - } else { + Ordering::Less => BitSet::all_set(), // If peer's state is less than my state, // the peer does not know any useful votes. - BitSet::new() + Ordering::Greater => BitSet::new(), }; let difference = &peer_known_votes - &self.votes_received; @@ -1969,45 +1967,47 @@ impl Worker { return } - if height == self.height - 1 { - let block = self.client().block(&height.into()).expect("Parent block should exist"); - let block_hash = block.hash(); - let finalized_view = self.finalized_view_of_previous_block; - - let votes = self - .votes - .get_all_votes_in_round(&VoteStep { - height, - view: finalized_view, - step: Step::Precommit, - }) - .into_iter() - .filter(|vote| vote.on.block_hash == Some(block_hash)) - .collect(); - - self.send_commit(block, votes, &result); - } else if height < self.height - 1 { - let block = self.client().block(&height.into()).expect("Parent block should exist"); - let child_block = self.client().block(&(height + 1).into()).expect("Parent block should exist"); - let child_block_header_seal = child_block.header().seal(); - let child_block_seal_view = TendermintSealView::new(&child_block_header_seal); - let parent_block_finalized_view = - child_block_seal_view.parent_block_finalized_view().expect("Verified block"); - let on = VoteOn { - step: VoteStep::new(height, parent_block_finalized_view, Step::Precommit), - block_hash: Some(block.hash()), - }; - let mut votes = Vec::new(); - for (index, signature) in child_block_seal_view.signatures().expect("The block is verified") { - let message = ConsensusMessage { - signature, - signer_index: index, - on: on.clone(), + match height.cmp(&(self.height - 1)) { + Ordering::Equal => { + let block = self.client().block(&height.into()).expect("Parent block should exist"); + let block_hash = block.hash(); + let finalized_view = self.finalized_view_of_previous_block; + + let votes = self + .votes + .get_all_votes_in_round(&VoteStep { + height, + view: finalized_view, + step: Step::Precommit, + }) + .into_iter() + .filter(|vote| vote.on.block_hash == Some(block_hash)) + .collect(); + + self.send_commit(block, votes, &result); + } + Ordering::Less => { + let block = self.client().block(&height.into()).expect("Parent block should exist"); + let child_block = self.client().block(&(height + 1).into()).expect("Parent block should exist"); + let child_block_header_seal = child_block.header().seal(); + let child_block_seal_view = TendermintSealView::new(&child_block_header_seal); + let parent_block_finalized_view = + child_block_seal_view.parent_block_finalized_view().expect("Verified block"); + let on = VoteOn { + step: VoteStep::new(height, parent_block_finalized_view, Step::Precommit), + block_hash: Some(block.hash()), }; - votes.push(message); + let mut votes = Vec::new(); + for (index, signature) in child_block_seal_view.signatures().expect("The block is verified") { + let message = ConsensusMessage { + signature, + signer_index: index, + on: on.clone(), + }; + votes.push(message); + } } - - self.send_commit(block, votes, &result); + Ordering::Greater => {} } } @@ -2049,23 +2049,27 @@ impl Worker { return None } - if commit_height < self.height { - cdebug!( - ENGINE, - "Received commit message is old. Current height is {} but commit messages is for height {}", - self.height, - commit_height, - ); - return None - } else if commit_height > self.height { - cwarn!( - ENGINE, - "Invalid commit message received: precommit on height {} but current height is {}", - commit_height, - self.height - ); - return None - } + match commit_height.cmp(&self.height) { + Ordering::Less => { + cdebug!( + ENGINE, + "Received commit message is old. Current height is {} but commit messages is for height {}", + self.height, + commit_height, + ); + return None + } + Ordering::Greater => { + cwarn!( + ENGINE, + "Invalid commit message received: precommit on height {} but current height is {}", + commit_height, + self.height + ); + return None + } + Ordering::Equal => {} + }; let prev_block_hash = self .client() diff --git a/core/src/miner/mem_pool.rs b/core/src/miner/mem_pool.rs index 65e126388a..d513085a34 100644 --- a/core/src/miner/mem_pool.rs +++ b/core/src/miner/mem_pool.rs @@ -960,7 +960,7 @@ impl MemPool { /// Returns Some(true) if the given transaction is local and None for not found. pub fn is_local_transaction(&self, tx_hash: H256) -> Option { - self.by_hash.get(&tx_hash).and_then(|found_item| Some(found_item.origin.is_local())) + self.by_hash.get(&tx_hash).map(|found_item| found_item.origin.is_local()) } /// Checks the given timelock with the current time/timestamp. @@ -1479,7 +1479,7 @@ pub mod test { inputs.push(create_mempool_input_with_pay(7u64, keypair, no_timelock)); mem_pool.add(inputs, inserted_block_number, inserted_timestamp, &fetch_account); - let mut mem_pool_recovered = MemPool::with_limits(8192, usize::max_value(), 3, db.clone()); + let mut mem_pool_recovered = MemPool::with_limits(8192, usize::max_value(), 3, db); mem_pool_recovered.recover_from_db(&test_client); assert_eq!(mem_pool_recovered.first_seqs, mem_pool.first_seqs); @@ -1549,7 +1549,7 @@ pub mod test { let test_client = TestBlockChainClient::new(); let db = Arc::new(kvdb_memorydb::create(crate::db::NUM_COLUMNS.unwrap_or(0))); - let mut mem_pool = MemPool::with_limits(8192, usize::max_value(), 3, db.clone()); + let mut mem_pool = MemPool::with_limits(8192, usize::max_value(), 3, db); let fetch_account = |p: &Public| -> AccountDetails { let address = public_to_address(p); diff --git a/keystore/src/accounts_dir/disk.rs b/keystore/src/accounts_dir/disk.rs index 17e78c9ac8..8a4ab666be 100644 --- a/keystore/src/accounts_dir/disk.rs +++ b/keystore/src/accounts_dir/disk.rs @@ -329,7 +329,7 @@ mod test { directory.insert_with_filename(account.clone(), "foo".to_string(), dedup).unwrap(); let file1 = directory.insert_with_filename(account.clone(), filename.clone(), dedup).unwrap().filename.unwrap(); let file2 = directory.insert_with_filename(account.clone(), filename.clone(), dedup).unwrap().filename.unwrap(); - let file3 = directory.insert_with_filename(account.clone(), filename.clone(), dedup).unwrap().filename.unwrap(); + let file3 = directory.insert_with_filename(account, filename.clone(), dedup).unwrap().filename.unwrap(); // then // the first file should have the original names diff --git a/keystore/src/json/crypto.rs b/keystore/src/json/crypto.rs index 9585dfcd39..4115ce2b8a 100644 --- a/keystore/src/json/crypto.rs +++ b/keystore/src/json/crypto.rs @@ -88,7 +88,7 @@ impl<'a> Deserialize<'a> for Crypto { fn deserialize(deserializer: D) -> Result where D: Deserializer<'a>, { - static FIELDS: &'static [&'static str] = &["id", "version", "crypto", "Crypto", "address"]; + static FIELDS: &[&str] = &["id", "version", "crypto", "Crypto", "address"]; deserializer.deserialize_struct("Crypto", FIELDS, CryptoVisitor) } } diff --git a/keystore/src/keystore.rs b/keystore/src/keystore.rs index bc46604b7c..a0a9c08bf5 100644 --- a/keystore/src/keystore.rs +++ b/keystore/src/keystore.rs @@ -140,7 +140,7 @@ impl SecretStore for KeyStore { fn meta(&self, account: &Address) -> Result { let account = self.store.get_safe_account(account)?; - Ok(account.meta.clone()) + Ok(account.meta) } fn set_meta(&self, account_ref: &Address, meta: String) -> Result<(), Error> { diff --git a/network/src/client.rs b/network/src/client.rs index 8d94fb15a5..54d1ea81c2 100644 --- a/network/src/client.rs +++ b/network/src/client.rs @@ -119,7 +119,7 @@ impl Client { let cloned_timer = timer.clone(); let p2p_channel = self.p2p_channel.clone(); let (channel, rx) = crossbeam::unbounded(); - let sender = channel.clone().into(); + let sender = channel.into(); let (quit_sender, quit_receiver) = crossbeam::bounded(1); let (init_sender, init_receiver) = crossbeam::bounded(1); diff --git a/network/src/p2p/listener.rs b/network/src/p2p/listener.rs index 8184f4d771..7014464997 100644 --- a/network/src/p2p/listener.rs +++ b/network/src/p2p/listener.rs @@ -38,7 +38,7 @@ impl Listener { Ok(match self.listener.accept() { Ok((stream, socket_address)) => Some((From::from(stream), From::from(socket_address))), Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => None, - Err(e) => Err(e)?, + Err(e) => return Err(e), }) } } diff --git a/network/src/stream.rs b/network/src/stream.rs index d07c107bf3..d2f9ae5fc4 100644 --- a/network/src/stream.rs +++ b/network/src/stream.rs @@ -283,7 +283,7 @@ impl Stream { Ok(stream) => Some(Self::from(stream)), Err(ref e) if e.kind() == io::ErrorKind::NotConnected => None, Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => None, - Err(e) => Err(e)?, + Err(e) => return Err(e.into()), }) } diff --git a/rpc/src/v1/types/mod.rs b/rpc/src/v1/types/mod.rs index 59ab24ad1c..db0e1ceeb8 100644 --- a/rpc/src/v1/types/mod.rs +++ b/rpc/src/v1/types/mod.rs @@ -73,11 +73,13 @@ impl<'de> Deserialize<'de> for TPSTestOption { "transferSingle" => TPSTestOption::TransferSingle, "transferMultiple" => TPSTestOption::TransferMultiple, "payOrTransfer" => TPSTestOption::PayOrTransfer, - v => Err(de::Error::custom(format!( - "Invalid params: unknown variant `{}`, expected one of \ - `payOnly`, `transferSingle`, `transferMultiple`, `payOrTransfer`.", - v - )))?, + v => { + return Err(de::Error::custom(format!( + "Invalid params: unknown variant `{}`, expected one of \ + `payOnly`, `transferSingle`, `transferMultiple`, `payOrTransfer`.", + v + ))) + } }) } } diff --git a/rustfmt.toml b/rustfmt.toml index a3757b4391..f08e9b846b 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -8,7 +8,7 @@ control_brace_style = "AlwaysSameLine" # disable_all_formatting = false error_on_line_overflow = false # true # error_on_unformatted = false -fn_args_density = "Tall" +fn_args_layout = "Tall" brace_style = "PreferSameLine" # "SameLineWhere" empty_item_single_line = true enum_discrim_align_threshold = 0 diff --git a/state/src/impls/shard_level.rs b/state/src/impls/shard_level.rs index 07a9333445..06703628bd 100644 --- a/state/src/impls/shard_level.rs +++ b/state/src/impls/shard_level.rs @@ -821,11 +821,8 @@ mod tests { let parameters = vec![]; let amount = 100; let approver = Address::random(); - let transaction = asset_mint!( - asset_mint_output!(lock_script_hash, parameters.clone(), amount), - metadata.clone(), - approver: approver - ); + let transaction = + asset_mint!(asset_mint_output!(lock_script_hash, parameters, amount), metadata.clone(), approver: approver); let transaction_tracker = transaction.tracker(); let asset_type = Blake::blake(transaction_tracker); @@ -849,7 +846,7 @@ mod tests { let parameters = vec![]; let approver = Address::random(); let transaction = asset_mint!( - asset_mint_output!(lock_script_hash, parameters: parameters.clone()), + asset_mint_output!(lock_script_hash, parameters: parameters), metadata.clone(), approver: approver ); @@ -876,7 +873,7 @@ mod tests { let parameters = vec![]; let approver = Address::random(); let transaction = asset_mint!( - asset_mint_output!(lock_script_hash, parameters: parameters.clone()), + asset_mint_output!(lock_script_hash, parameters: parameters), metadata.clone(), approver: approver ); @@ -1527,7 +1524,7 @@ mod tests { assert_eq!(Ok(()), state.apply(&successful_transfer, &sender, &[sender], &[], &get_test_client(), 0, 0)); check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount }), + (scheme: (asset_type) => { metadata: metadata, supply: amount }), (asset: (mint_tracker, 0)), (asset: (failed_transfer_tracker, 0)), (asset: (successful_transfer_tracker, 0) => { asset_type: asset_type, quantity: 10 }), @@ -1548,7 +1545,7 @@ mod tests { let parameters = vec![]; let approver = Address::random(); let transaction = asset_mint!( - asset_mint_output!(lock_script_hash, parameters: parameters.clone()), + asset_mint_output!(lock_script_hash, parameters: parameters), metadata.clone(), approver: approver ); @@ -1558,7 +1555,7 @@ mod tests { assert_eq!(Ok(()), state.apply(&transaction, &sender, &[sender], &[], &get_test_client(), 0, 0)); check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: ::std::u64::MAX }), + (scheme: (asset_type) => { metadata: metadata, supply: ::std::u64::MAX }), (asset: (transaction_tracker, 0) => { asset_type: asset_type, quantity: ::std::u64::MAX }) ]); } @@ -1577,11 +1574,8 @@ mod tests { let lock_script_hash = H160::random(); let parameters = vec![]; let approver = Address::random(); - let transaction = asset_mint!( - asset_mint_output!(lock_script_hash, parameters: parameters.clone()), - metadata.clone(), - approver: approver - ); + let transaction = + asset_mint!(asset_mint_output!(lock_script_hash, parameters: parameters), metadata, approver: approver); let transaction_tracker = transaction.tracker(); let asset_type = Blake::blake(transaction_tracker); @@ -1612,7 +1606,7 @@ mod tests { let parameters = vec![]; let approver = Address::random(); let transaction = asset_mint!( - asset_mint_output!(lock_script_hash, parameters: parameters.clone()), + asset_mint_output!(lock_script_hash, parameters: parameters), metadata.clone(), approver: approver ); @@ -1628,7 +1622,7 @@ mod tests { assert_eq!(Ok(()), state.apply(&transaction, &sender, &shard_users, &approvers, &get_test_client(), 0, 0)); check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: ::std::u64::MAX }), + (scheme: (asset_type) => { metadata: metadata, supply: ::std::u64::MAX }), (asset: (transaction_tracker, 0) => { asset_type: asset_type, quantity: ::std::u64::MAX }) ]); } @@ -1648,7 +1642,7 @@ mod tests { let parameters = vec![]; let approver = Address::random(); let transaction = asset_mint!( - asset_mint_output!(lock_script_hash, parameters: parameters.clone()), + asset_mint_output!(lock_script_hash, parameters: parameters), metadata.clone(), approver: approver ); @@ -1664,7 +1658,7 @@ mod tests { assert_eq!(Ok(()), state.apply(&transaction, &sender, &shard_users, &approvers, &get_test_client(), 0, 0)); check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: ::std::u64::MAX }), + (scheme: (asset_type) => { metadata: metadata, supply: ::std::u64::MAX }), (asset: (transaction_tracker, 0) => { asset_type: asset_type, quantity: ::std::u64::MAX }) ]); } @@ -1681,7 +1675,7 @@ mod tests { let parameters = vec![]; let approver = Address::random(); let transaction = asset_mint!( - asset_mint_output!(lock_script_hash, parameters: parameters.clone()), + asset_mint_output!(lock_script_hash, parameters: parameters), metadata.clone(), approver: approver ); @@ -1692,7 +1686,7 @@ mod tests { assert_eq!(Ok(()), state.apply(&transaction, &sender, &[], &[], &get_test_client(), 0, 0)); check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: ::std::u64::MAX, approver: approver }), + (scheme: (asset_type) => { metadata: metadata, supply: ::std::u64::MAX, approver: approver }), (asset: (transaction_tracker, 0) => { asset_type: asset_type, quantity: ::std::u64::MAX }) ]); } @@ -1710,7 +1704,7 @@ mod tests { let amount = 100; let registrar = Address::random(); let mint = asset_mint!( - asset_mint_output!(lock_script_hash, parameters.clone(), amount), + asset_mint_output!(lock_script_hash, parameters, amount), metadata.clone(), registrar: registrar ); @@ -1721,7 +1715,7 @@ mod tests { assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount, approver, registrar: registrar }), + (scheme: (asset_type) => { metadata: metadata, supply: amount, approver, registrar: registrar }), (asset: (mint_tracker, 0) => { asset_type: asset_type, quantity: amount }) ]); @@ -1757,7 +1751,7 @@ mod tests { let amount = 100; let registrar = Address::random(); let mint = asset_mint!( - asset_mint_output!(lock_script_hash, parameters.clone(), amount), + asset_mint_output!(lock_script_hash, parameters, amount), metadata.clone(), registrar: registrar ); @@ -1768,7 +1762,7 @@ mod tests { assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); check_shard_level_state!(state, [ - (scheme: (asset_type) => { metadata: metadata.clone(), supply: amount, approver, registrar: registrar }), + (scheme: (asset_type) => { metadata: metadata, supply: amount, approver, registrar: registrar }), (asset: (mint_tracker, 0) => { asset_type: asset_type, quantity: amount }) ]); diff --git a/state/src/impls/top_level.rs b/state/src/impls/top_level.rs index 55cf04cc22..954c9ec527 100644 --- a/state/src/impls/top_level.rs +++ b/state/src/impls/top_level.rs @@ -1026,7 +1026,7 @@ mod tests_state { assert_eq!(Ok(1), state.seq(&a)); let root = state.commit(); assert!(root.is_ok(), "{:?}", root); - state.clone() + state }; assert_eq!(Ok(1), state.seq(&a)); assert_eq!(Ok(()), state.inc_seq(&a)); @@ -1045,7 +1045,7 @@ mod tests_state { assert_eq!(Ok(false), state.account_exists(&a)); assert_eq!(Ok(()), state.inc_seq(&a)); assert_eq!(Ok(1), state.seq(&a)); - state.clone() + state }; assert_eq!(Ok(1), state.seq(&a)); assert_eq!(Ok(()), state.inc_seq(&a)); @@ -1808,7 +1808,7 @@ mod tests_tx { let parameters = vec![]; let amount = 30; let transaction = mint_asset!( - Box::new(asset_mint_output!(lock_script_hash, parameters.clone(), amount)), + Box::new(asset_mint_output!(lock_script_hash, parameters, amount)), metadata.clone(), approver: approver ); @@ -1844,7 +1844,7 @@ mod tests_tx { let lock_script_hash = H160::random(); let parameters = vec![]; let transaction = mint_asset!( - Box::new(asset_mint_output!(lock_script_hash, parameters: parameters.clone())), + Box::new(asset_mint_output!(lock_script_hash, parameters: parameters)), metadata.clone(), approver: approver ); @@ -1909,7 +1909,7 @@ mod tests_tx { check_top_level_state!(state, [ (account: sender => (seq: 2, balance: 120 - 20 - 30)), - (scheme: (shard_id, asset_type) => { metadata: metadata.clone(), supply: 30 }), + (scheme: (shard_id, asset_type) => { metadata: metadata, supply: 30 }), (asset: (mint_tracker, 0, shard_id)), (asset: (transfer_tracker, 0, shard_id) => { asset_type: asset_type, quantity: 10 }), (asset: (transfer_tracker, 1, shard_id) => { asset_type: asset_type, quantity: 5 }), @@ -1937,8 +1937,8 @@ mod tests_tx { let parameters = vec![]; let amount = 30; let transaction = mint_asset!( - Box::new(asset_mint_output!(lock_script_hash, parameters.clone(), amount)), - metadata.clone(), + Box::new(asset_mint_output!(lock_script_hash, parameters, amount)), + metadata, approver: approver ); let tx = transaction!(fee: 11, transaction.clone()); @@ -2226,7 +2226,7 @@ mod tests_tx { let signature = sign(Random.generate().unwrap().private(), &content_hash).unwrap(); - let tx = transaction!(seq: 0, fee: 10, store!(content.clone(), sender, signature)); + let tx = transaction!(seq: 0, fee: 10, store!(content, sender, signature)); assert_eq!( Err(RuntimeError::TextVerificationFail("Certifier and signer are different".to_string()).into()), @@ -2454,8 +2454,8 @@ mod tests_tx { let parameters = vec![]; let amount = 30; let transaction = mint_asset!( - Box::new(asset_mint_output!(lock_script_hash, parameters.clone(), amount)), - metadata.clone(), + Box::new(asset_mint_output!(lock_script_hash, parameters, amount)), + metadata, approver: approver ); let tx = transaction!(fee: 11, transaction); @@ -2662,8 +2662,7 @@ mod tests_tx { let amount = 30; let parameters = vec![]; - let mint = - mint_asset!(Box::new(asset_mint_output!(lock_script_hash, parameters.clone(), amount)), metadata.clone()); + let mint = mint_asset!(Box::new(asset_mint_output!(lock_script_hash, parameters, amount)), metadata.clone()); let mint_tracker = mint.tracker().unwrap(); let asset_type = Blake::blake(mint_tracker); @@ -2673,7 +2672,7 @@ mod tests_tx { check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 100 - 20)), - (scheme: (shard_id, asset_type) => { metadata: metadata.clone(), supply: amount }), + (scheme: (shard_id, asset_type) => { metadata: metadata, supply: amount }), (asset: (mint_tracker, 0, shard_id) => { asset_type: asset_type, quantity: amount }) ]); } @@ -2697,7 +2696,7 @@ mod tests_tx { (metadata: shards: 1) ]); - let tx = transaction!(fee: 5, set_shard_users!(new_users.clone())); + let tx = transaction!(fee: 5, set_shard_users!(new_users)); assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ @@ -2727,7 +2726,7 @@ mod tests_tx { ]); let new_users = vec![Address::random(), Address::random(), sender]; - let tx = transaction!(fee: 5, set_shard_users!(new_users.clone())); + let tx = transaction!(fee: 5, set_shard_users!(new_users)); assert_eq!( Err(RuntimeError::InsufficientPermission.into()), diff --git a/state/src/item/account.rs b/state/src/item/account.rs index fbec298ad0..7a26d592e2 100644 --- a/state/src/item/account.rs +++ b/state/src/item/account.rs @@ -241,5 +241,4 @@ mod tests { a.inc_seq(); assert!(!a.is_null()); } - } diff --git a/state/src/item/asset.rs b/state/src/item/asset.rs index 70552d2805..3b7aabf824 100644 --- a/state/src/item/asset.rs +++ b/state/src/item/asset.rs @@ -256,5 +256,4 @@ mod tests { quantity: 0, }); } - } diff --git a/sync/src/block/downloader/header.rs b/sync/src/block/downloader/header.rs index d05a40074f..f1d2193ca6 100644 --- a/sync/src/block/downloader/header.rs +++ b/sync/src/block/downloader/header.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +use std::cmp::Ordering; use std::collections::HashMap; use std::sync::Arc; use std::time::Instant; @@ -77,21 +78,21 @@ impl HeaderDownloader { } pub fn update(&mut self, total_score: U256, best_hash: H256) -> bool { - if self.total_score == total_score { - true - } else if self.total_score < total_score { - self.total_score = total_score; - self.best_hash = best_hash; - - if self.client.block_header(&BlockId::Hash(best_hash)).is_some() { - self.pivot = Pivot { - hash: best_hash, - total_score, + match self.total_score.cmp(&total_score) { + Ordering::Equal => true, + Ordering::Less => { + self.total_score = total_score; + self.best_hash = best_hash; + + if self.client.block_header(&BlockId::Hash(best_hash)).is_some() { + self.pivot = Pivot { + hash: best_hash, + total_score, + } } + true } - true - } else { - false + Ordering::Greater => false, } } diff --git a/sync/src/snapshot/snapshot.rs b/sync/src/snapshot/snapshot.rs index d0e03eed00..6180afef59 100644 --- a/sync/src/snapshot/snapshot.rs +++ b/sync/src/snapshot/snapshot.rs @@ -365,7 +365,7 @@ mod tests { let kvdb = Arc::new(kvdb_memorydb::create(1)); snapshot.read_snapshot(kvdb.clone(), &root).unwrap(); - let mut jdb = journaldb::new(kvdb.clone(), Algorithm::Archive, COL_STATE); + let mut jdb = journaldb::new(kvdb, Algorithm::Archive, COL_STATE); let t = TrieDB::try_new(jdb.as_hashdb_mut(), &root).unwrap(); let mut inserted_keys = HashSet::new(); for &(ref key, ref value) in &x { diff --git a/types/src/util/tag.rs b/types/src/util/tag.rs index 9931e549f9..4599576ea2 100644 --- a/types/src/util/tag.rs +++ b/types/src/util/tag.rs @@ -78,7 +78,7 @@ mod tests { assert_eq!(tag.sign_all_inputs, true); assert_eq!(tag.sign_all_outputs, false); assert_eq!(tag.filter_len, 8); - assert_eq!(tag.filter.clone(), vec![ + assert_eq!(tag.filter, vec![ 0b1000_0000, 0b0100_0000, 0b0010_0000, diff --git a/util/kvdb-rocksdb/src/lib.rs b/util/kvdb-rocksdb/src/lib.rs index 3ad47fe882..7b1ba8822c 100644 --- a/util/kvdb-rocksdb/src/lib.rs +++ b/util/kvdb-rocksdb/src/lib.rs @@ -790,12 +790,12 @@ impl KeyValueDB for Database { fn iter(&self, col: Option) -> KeyValueDBIterator { let unboxed = Database::iter(self, col); - Box::new(unboxed.into_iter().flat_map(|inner| inner)) + Box::new(unboxed.into_iter().flatten()) } fn iter_from_prefix<'a>(&'a self, col: Option, prefix: &'a [u8]) -> KeyValueDBIterator { let unboxed = Database::iter_from_prefix(self, col, prefix); - Box::new(unboxed.into_iter().flat_map(|inner| inner)) + Box::new(unboxed.into_iter().flatten()) } fn restore(&self, new_db: &str) -> Result<()> { @@ -833,7 +833,7 @@ mod tests { assert_eq!(&*db.get(None, &key1).unwrap().unwrap(), b"cat"); - let contents: Vec<_> = db.iter(None).into_iter().flat_map(|inner| inner).collect(); + let contents: Vec<_> = db.iter(None).into_iter().flatten().collect(); assert_eq!(contents.len(), 2); assert_eq!(&*contents[0].0, &*key1); assert_eq!(&*contents[0].1, b"cat"); diff --git a/util/memorydb/src/lib.rs b/util/memorydb/src/lib.rs index 0699fb3995..65f3a02054 100644 --- a/util/memorydb/src/lib.rs +++ b/util/memorydb/src/lib.rs @@ -44,36 +44,35 @@ use std::mem; /// extern crate memorydb; /// use hashdb::*; /// use memorydb::*; -/// fn main() { -/// let mut m = MemoryDB::new(); -/// let d = "Hello world!".as_bytes(); /// -/// let k = m.insert(d); -/// assert!(m.contains(&k)); -/// assert_eq!(m.get(&k).unwrap(), d); +/// let mut m = MemoryDB::new(); +/// let d = "Hello world!".as_bytes(); /// -/// m.insert(d); -/// assert!(m.contains(&k)); +/// let k = m.insert(d); +/// assert!(m.contains(&k)); +/// assert_eq!(m.get(&k).unwrap(), d); /// -/// m.remove(&k); -/// assert!(m.contains(&k)); +/// m.insert(d); +/// assert!(m.contains(&k)); /// -/// m.remove(&k); -/// assert!(!m.contains(&k)); +/// m.remove(&k); +/// assert!(m.contains(&k)); /// -/// m.remove(&k); -/// assert!(!m.contains(&k)); +/// m.remove(&k); +/// assert!(!m.contains(&k)); /// -/// m.insert(d); -/// assert!(!m.contains(&k)); +/// m.remove(&k); +/// assert!(!m.contains(&k)); +/// +/// m.insert(d); +/// assert!(!m.contains(&k)); -/// m.insert(d); -/// assert!(m.contains(&k)); -/// assert_eq!(m.get(&k).unwrap(), d); +/// m.insert(d); +/// assert!(m.contains(&k)); +/// assert_eq!(m.get(&k).unwrap(), d); /// -/// m.remove(&k); -/// assert!(!m.contains(&k)); -/// } +/// m.remove(&k); +/// assert!(!m.contains(&k)); /// ``` #[derive(Default, Clone, PartialEq)] pub struct MemoryDB { @@ -96,14 +95,13 @@ impl MemoryDB { /// extern crate memorydb; /// use hashdb::*; /// use memorydb::*; - /// fn main() { - /// let mut m = MemoryDB::new(); - /// let hello_bytes = "Hello world!".as_bytes(); - /// let hash = m.insert(hello_bytes); - /// assert!(m.contains(&hash)); - /// m.clear(); - /// assert!(!m.contains(&hash)); - /// } + /// + /// let mut m = MemoryDB::new(); + /// let hello_bytes = "Hello world!".as_bytes(); + /// let hash = m.insert(hello_bytes); + /// assert!(m.contains(&hash)); + /// m.clear(); + /// assert!(!m.contains(&hash)); /// ``` pub fn clear(&mut self) { self.data.clear(); diff --git a/util/merkle/src/nibbleslice.rs b/util/merkle/src/nibbleslice.rs index 244714f004..77a9705111 100644 --- a/util/merkle/src/nibbleslice.rs +++ b/util/merkle/src/nibbleslice.rs @@ -197,7 +197,7 @@ mod tests { use super::NibbleSlice; use elastic_array::ElasticArray36; - static D: &'static [u8; 3] = &[0x01u8, 0x23, 0x45]; + static D: &[u8; 3] = &[0x01u8, 0x23, 0x45]; #[test] fn basics() { diff --git a/util/merkle/src/triedb.rs b/util/merkle/src/triedb.rs index 7ef72e31bb..c65ce58c6a 100644 --- a/util/merkle/src/triedb.rs +++ b/util/merkle/src/triedb.rs @@ -38,14 +38,12 @@ use crate::{Query, Trie, TrieError}; /// use memorydb::*; /// use primitives::H256; /// -/// fn main() { -/// let mut memdb = MemoryDB::new(); -/// let mut root = H256::new(); -/// TrieDBMut::new(&mut memdb, &mut root).insert(b"foo", b"bar").unwrap(); -/// let t = TrieDB::try_new(&memdb, &root).unwrap(); -/// assert!(t.contains(b"foo").unwrap()); -/// assert_eq!(t.get(b"foo").unwrap().unwrap(), DBValue::from_slice(b"bar")); -/// } +/// let mut memdb = MemoryDB::new(); +/// let mut root = H256::new(); +/// TrieDBMut::new(&mut memdb, &mut root).insert(b"foo", b"bar").unwrap(); +/// let t = TrieDB::try_new(&memdb, &root).unwrap(); +/// assert!(t.contains(b"foo").unwrap()); +/// assert_eq!(t.get(b"foo").unwrap().unwrap(), DBValue::from_slice(b"bar")); /// ``` pub struct TrieDB<'db> { db: &'db dyn HashDB, diff --git a/util/rlp/src/common.rs b/util/rlp/src/common.rs index c01de810a6..0056aa4f5c 100644 --- a/util/rlp/src/common.rs +++ b/util/rlp/src/common.rs @@ -20,7 +20,7 @@ lazy_static! { pub static ref BLOCKS_RLP_SWAPPER: InvalidRlpSwapper<'static> = InvalidRlpSwapper::new(COMMON_RLPS, INVALID_RLPS); } -static EMPTY_RLPS: &'static [&'static [u8]] = &[ +static EMPTY_RLPS: &[&[u8]] = &[ // RLP of KECCAK_NULL_RLP &[ 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, @@ -33,7 +33,7 @@ static EMPTY_RLPS: &'static [&'static [u8]] = &[ ], ]; -static COMMON_RLPS: &'static [&'static [u8]] = &[ +static COMMON_RLPS: &[&[u8]] = &[ // RLP of KECCAK_NULL_RLP &[ 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, @@ -62,7 +62,7 @@ static COMMON_RLPS: &'static [&'static [u8]] = &[ ], ]; -static INVALID_RLPS: &'static [&'static [u8]] = &[ +static INVALID_RLPS: &[&[u8]] = &[ &[0x81, 0x0], &[0x81, 0x1], &[0x81, 0x2], diff --git a/util/rlp_compress/src/common.rs b/util/rlp_compress/src/common.rs index 1d230e9c88..b3f83b8cfc 100644 --- a/util/rlp_compress/src/common.rs +++ b/util/rlp_compress/src/common.rs @@ -20,7 +20,7 @@ lazy_static! { pub static ref BLOCKS_SWAPPER: Swapper<'static> = Swapper::new(COMMON_RLPS, INVALID_RLPS); } -static EMPTY_RLPS: &'static [&'static [u8]] = &[ +static EMPTY_RLPS: &[&[u8]] = &[ // RLP of KECCAK_NULL_RLP &[ 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, @@ -33,7 +33,7 @@ static EMPTY_RLPS: &'static [&'static [u8]] = &[ ], ]; -static COMMON_RLPS: &'static [&'static [u8]] = &[ +static COMMON_RLPS: &[&[u8]] = &[ // RLP of KECCAK_NULL_RLP &[ 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, @@ -62,7 +62,7 @@ static COMMON_RLPS: &'static [&'static [u8]] = &[ ], ]; -static INVALID_RLPS: &'static [&'static [u8]] = &[ +static INVALID_RLPS: &[&[u8]] = &[ &[0x81, 0x0], &[0x81, 0x1], &[0x81, 0x2], diff --git a/vm/tests/chk_sig.rs b/vm/tests/chk_sig.rs index dae1a07757..227dee3ab8 100644 --- a/vm/tests/chk_sig.rs +++ b/vm/tests/chk_sig.rs @@ -136,7 +136,7 @@ fn sign_all_input_all_output() { quantity: 0, }; let input0 = AssetTransferInput { - prev_out: out0.clone(), + prev_out: out0, timelock: None, lock_script: Vec::new(), unlock_script: Vec::new(), @@ -214,7 +214,7 @@ fn sign_single_input_all_output() { quantity: 0, }; let input0 = AssetTransferInput { - prev_out: out0.clone(), + prev_out: out0, timelock: None, lock_script: Vec::new(), unlock_script: Vec::new(), @@ -252,7 +252,7 @@ fn sign_single_input_all_output() { let transaction = ShardTransaction::TransferAsset { network_id: NetworkId::default(), burns: Vec::new(), - inputs: vec![input0.clone(), input1.clone()], + inputs: vec![input0.clone(), input1], outputs: vec![output0.clone(), output1.clone()], }; @@ -291,7 +291,7 @@ fn sign_all_input_partial_output() { quantity: 0, }; let input0 = AssetTransferInput { - prev_out: out0.clone(), + prev_out: out0, timelock: None, lock_script: Vec::new(), unlock_script: Vec::new(), @@ -330,7 +330,7 @@ fn sign_all_input_partial_output() { network_id: NetworkId::default(), burns: Vec::new(), inputs: vec![input0.clone(), input1.clone()], - outputs: vec![output0.clone(), output1.clone()], + outputs: vec![output0.clone(), output1], }; // Execute sciprt in input0 @@ -368,7 +368,7 @@ fn sign_single_input_partial_output() { quantity: 0, }; let input0 = AssetTransferInput { - prev_out: out0.clone(), + prev_out: out0, timelock: None, lock_script: Vec::new(), unlock_script: Vec::new(), @@ -406,8 +406,8 @@ fn sign_single_input_partial_output() { let transaction = ShardTransaction::TransferAsset { network_id: NetworkId::default(), burns: Vec::new(), - inputs: vec![input0.clone(), input1.clone()], - outputs: vec![output0.clone(), output1.clone()], + inputs: vec![input0.clone(), input1], + outputs: vec![output0.clone(), output1], }; // Execute sciprt in input0 @@ -445,7 +445,7 @@ fn distinguish_sign_single_input_with_sign_all() { quantity: 0, }; let input0 = AssetTransferInput { - prev_out: out0.clone(), + prev_out: out0, timelock: None, lock_script: Vec::new(), unlock_script: Vec::new(), @@ -501,7 +501,7 @@ fn distinguish_sign_single_output_with_sign_all() { quantity: 0, }; let input0 = AssetTransferInput { - prev_out: out0.clone(), + prev_out: out0, timelock: None, lock_script: Vec::new(), unlock_script: Vec::new(), From 5a477d52b027e070493ce4ec7ea3afd2d1adf814 Mon Sep 17 00:00:00 2001 From: Seulgi Kim Date: Fri, 25 Oct 2019 11:12:07 +0900 Subject: [PATCH 072/105] Update README to correspond to rust toolchains --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b8e348df00..b4dae860fd 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ With the methods above, node organizers can manage their local persistent data u ### Building From Source #### Build Dependencies -CodeChain requires Rust version 1.34.0 to build. Using [rustup](https://rustup.rs/ "rustup URL") is recommended. +CodeChain requires Rust version 1.37.0 to build. Using [rustup](https://rustup.rs/ "rustup URL") is recommended. - For Linux Systems: - Ubuntu @@ -135,32 +135,32 @@ You can create a block by sending a parcel through [JSON-RPC](https://github.com Make sure you run `rustfmt` before creating a PR to the repo. You need to install the nightly-2018-12-06 version of `rustfmt`. ```sh -rustup toolchain install nightly-2019-05-17 -rustup component add rustfmt --toolchain nightly-2019-05-17 +rustup toolchain install nightly-2019-10-13 +rustup component add rustfmt --toolchain nightly-2019-10-13 ``` To run `rustfmt`, ```sh -cargo +nightly-2019-05-17 fmt +cargo +nightly-2019-10-13 fmt ``` ## Linting You should run `clippy` also. This is a lint tool for rust. It suggests more efficient/readable code. You can see [the clippy document](https://rust-lang.github.io/rust-clippy/master/index.html) for more information. -You need to install the nightly-2019-05-17 version of `clippy`. +You need to install the nightly-2019-10-13 version of `clippy`. ### Install ```sh -rustup toolchain install nightly-2019-05-17 -rustup component add clippy --toolchain nightly-2019-05-17 +rustup toolchain install nightly-2019-10-13 +rustup component add clippy --toolchain nightly-2019-10-13 ``` ### Run ```sh -cargo +nightly-2019-05-17 clippy --all --all-targets +cargo +nightly-2019-10-13 clippy --all --all-targets ``` ## Testing From 443754f6a6406eb60a4ae1d64f6061c1f99c5d2c Mon Sep 17 00:00:00 2001 From: Seulgi Kim Date: Sat, 26 Oct 2019 23:38:47 +0900 Subject: [PATCH 073/105] Distinguish BlockHash from H256 --- core/src/blockchain/block_info.rs | 8 +- core/src/blockchain/blockchain.rs | 38 +++--- core/src/blockchain/body_db.rs | 15 +-- core/src/blockchain/extras.rs | 50 ++++---- core/src/blockchain/headerchain.rs | 63 +++++----- core/src/blockchain/route.rs | 20 ++-- core/src/blockchain_info.rs | 10 +- core/src/client/chain_notify.rs | 23 ++-- core/src/client/client.rs | 42 +++---- core/src/client/importer.rs | 10 +- core/src/client/mod.rs | 16 +-- core/src/client/test_client.rs | 35 +++--- core/src/consensus/blake_pow/mod.rs | 2 +- core/src/consensus/cuckoo/mod.rs | 2 +- core/src/consensus/mod.rs | 14 +-- core/src/consensus/simple_poa/mod.rs | 3 +- core/src/consensus/stake/actions.rs | 31 ++--- core/src/consensus/tendermint/backup.rs | 8 +- core/src/consensus/tendermint/chain_notify.rs | 12 +- core/src/consensus/tendermint/engine.rs | 13 +-- core/src/consensus/tendermint/message.rs | 23 ++-- core/src/consensus/tendermint/mod.rs | 3 - core/src/consensus/tendermint/network.rs | 21 +++- core/src/consensus/tendermint/types.rs | 30 ++--- .../consensus/tendermint/vote_collector.rs | 16 +-- .../tendermint/vote_regression_checker.rs | 34 +++--- core/src/consensus/tendermint/worker.rs | 55 +++++---- .../validator_set/dynamic_validator.rs | 26 ++--- core/src/consensus/validator_set/mod.rs | 20 ++-- .../consensus/validator_set/validator_list.rs | 20 ++-- core/src/encoded.rs | 12 +- core/src/error.rs | 6 +- core/src/miner/miner.rs | 20 ++-- core/src/miner/mod.rs | 13 ++- core/src/miner/stratum.rs | 2 +- core/src/scheme/genesis.rs | 5 +- core/src/scheme/scheme.rs | 4 +- core/src/service.rs | 5 +- core/src/tests/helpers.rs | 6 +- core/src/transaction.rs | 4 +- core/src/types/ids.rs | 8 +- core/src/verification/queue/kind.rs | 27 ++--- core/src/verification/queue/mod.rs | 19 +-- core/src/views/block.rs | 4 +- core/src/views/body.rs | 10 +- core/src/views/header.rs | 10 +- rpc/src/v1/impls/chain.rs | 8 +- rpc/src/v1/impls/miner.rs | 4 +- rpc/src/v1/traits/chain.rs | 8 +- rpc/src/v1/traits/miner.rs | 4 +- rpc/src/v1/types/block.rs | 8 +- rpc/src/v1/types/transaction.rs | 3 +- sync/src/block/downloader/body.rs | 20 ++-- sync/src/block/downloader/header.rs | 19 +-- sync/src/block/extension.rs | 48 ++++---- sync/src/block/message/mod.rs | 14 ++- sync/src/block/message/request.rs | 14 +-- sync/src/snapshot/service.rs | 15 ++- types/src/block_hash.rs | 109 ++++++++++++++++++ types/src/header.rs | 16 +-- types/src/lib.rs | 4 + 61 files changed, 637 insertions(+), 475 deletions(-) create mode 100644 types/src/block_hash.rs diff --git a/core/src/blockchain/block_info.rs b/core/src/blockchain/block_info.rs index a91b5de88a..eac929b1f4 100644 --- a/core/src/blockchain/block_info.rs +++ b/core/src/blockchain/block_info.rs @@ -16,7 +16,9 @@ use super::route::TreeRoute; use crate::views::{BlockView, HeaderView}; -use primitives::{Bytes, H256}; + +use ctypes::BlockHash; +use primitives::Bytes; /// Describes how best block is changed #[derive(Debug, Clone, PartialEq)] @@ -37,7 +39,7 @@ pub enum BestBlockChanged { } impl BestBlockChanged { - pub fn new_best_hash(&self) -> Option { + pub fn new_best_hash(&self) -> Option { Some(self.best_block()?.hash()) } @@ -76,7 +78,7 @@ pub enum BestHeaderChanged { } impl BestHeaderChanged { - pub fn new_best_hash(&self) -> Option { + pub fn new_best_hash(&self) -> Option { Some(self.header()?.hash()) } diff --git a/core/src/blockchain/blockchain.rs b/core/src/blockchain/blockchain.rs index 948ee0c3b4..9e99ff4f9f 100644 --- a/core/src/blockchain/blockchain.rs +++ b/core/src/blockchain/blockchain.rs @@ -16,7 +16,7 @@ use std::sync::Arc; -use ctypes::BlockNumber; +use ctypes::{BlockHash, BlockNumber}; use kvdb::{DBTransaction, KeyValueDB}; use parking_lot::RwLock; use primitives::H256; @@ -44,16 +44,16 @@ const BEST_PROPOSAL_BLOCK_KEY: &[u8] = b"best-proposal-block"; /// **Does not do input data verification.** pub struct BlockChain { /// The hash of the best block of the canonical chain. - best_block_hash: RwLock, + best_block_hash: RwLock, /// The hash of the block which has the best score among the proposal blocks - best_proposal_block_hash: RwLock, + best_proposal_block_hash: RwLock, headerchain: HeaderChain, body_db: BodyDB, invoice_db: InvoiceDB, - pending_best_block_hash: RwLock>, - pending_best_proposal_block_hash: RwLock>, + pending_best_block_hash: RwLock>, + pending_best_proposal_block_hash: RwLock>, } impl BlockChain { @@ -63,7 +63,7 @@ impl BlockChain { // load best block let best_block_hash = match db.get(db::COL_EXTRA, BEST_BLOCK_KEY).unwrap() { - Some(hash) => H256::from_slice(&hash), + Some(hash) => H256::from_slice(&hash).into(), None => { let hash = genesis_block.hash(); @@ -75,7 +75,7 @@ impl BlockChain { }; let best_proposal_block_hash = match db.get(db::COL_EXTRA, BEST_PROPOSAL_BLOCK_KEY).unwrap() { - Some(hash) => H256::from_slice(&hash), + Some(hash) => H256::from_slice(&hash).into(), None => { let hash = genesis_block.hash(); let mut batch = DBTransaction::new(); @@ -235,7 +235,7 @@ impl BlockChain { /// The new best block should be a child of the current best block. /// This will not change the best proposal block chain. This means it is possible /// to have the best block and the best proposal block in different branches. - pub fn update_best_as_committed(&self, batch: &mut DBTransaction, block_hash: H256) -> ImportRoute { + pub fn update_best_as_committed(&self, batch: &mut DBTransaction, block_hash: BlockHash) -> ImportRoute { // FIXME: If it is possible, double check with the consensus engine. ctrace!(BLOCKCHAIN, "Update the best block to {}", block_hash); @@ -311,12 +311,12 @@ impl BlockChain { } /// Get best block hash. - pub fn best_block_hash(&self) -> H256 { + pub fn best_block_hash(&self) -> BlockHash { *self.best_block_hash.read() } /// Get best_proposal block hash. - pub fn best_proposal_block_hash(&self) -> H256 { + pub fn best_proposal_block_hash(&self) -> BlockHash { *self.best_proposal_block_hash.read() } @@ -349,12 +349,12 @@ impl BlockChain { pub trait BlockProvider: HeaderProvider + BodyProvider + InvoiceProvider { /// Returns true if the given block is known /// (though not necessarily a part of the canon chain). - fn is_known(&self, hash: &H256) -> bool { + fn is_known(&self, hash: &BlockHash) -> bool { self.is_known_header(hash) && self.is_known_body(hash) } /// Get raw block data - fn block(&self, hash: &H256) -> Option { + fn block(&self, hash: &BlockHash) -> Option { let header = self.block_header_data(hash)?; let body = self.block_body(hash)?; @@ -377,7 +377,7 @@ pub trait BlockProvider: HeaderProvider + BodyProvider + InvoiceProvider { /// Get a list of transactions for a given block. /// Returns None if block does not exist. - fn transactions(&self, block_hash: &H256) -> Option> { + fn transactions(&self, block_hash: &BlockHash) -> Option> { self.block_body(block_hash) .and_then(|body| self.block_number(block_hash).map(|n| body.view().localized_transactions(block_hash, n))) } @@ -386,28 +386,28 @@ pub trait BlockProvider: HeaderProvider + BodyProvider + InvoiceProvider { impl HeaderProvider for BlockChain { /// Returns true if the given block is known /// (though not necessarily a part of the canon chain). - fn is_known_header(&self, hash: &H256) -> bool { + fn is_known_header(&self, hash: &BlockHash) -> bool { self.headerchain.is_known_header(hash) } /// Get the familial details concerning a block. - fn block_details(&self, hash: &H256) -> Option { + fn block_details(&self, hash: &BlockHash) -> Option { self.headerchain.block_details(hash) } /// Get the hash of given block's number. - fn block_hash(&self, index: BlockNumber) -> Option { + fn block_hash(&self, index: BlockNumber) -> Option { self.headerchain.block_hash(index) } /// Get the header RLP of a block. - fn block_header_data(&self, hash: &H256) -> Option { + fn block_header_data(&self, hash: &BlockHash) -> Option { self.headerchain.block_header_data(hash) } } impl BodyProvider for BlockChain { - fn is_known_body(&self, hash: &H256) -> bool { + fn is_known_body(&self, hash: &BlockHash) -> bool { self.body_db.is_known_body(hash) } @@ -419,7 +419,7 @@ impl BodyProvider for BlockChain { self.body_db.transaction_address_by_tracker(tracker) } - fn block_body(&self, hash: &H256) -> Option { + fn block_body(&self, hash: &BlockHash) -> Option { self.body_db.block_body(hash) } } diff --git a/core/src/blockchain/body_db.rs b/core/src/blockchain/body_db.rs index a97a591989..6a016eba18 100644 --- a/core/src/blockchain/body_db.rs +++ b/core/src/blockchain/body_db.rs @@ -18,6 +18,7 @@ use std::collections::{HashMap, HashSet}; use std::mem; use std::sync::Arc; +use ctypes::BlockHash; use kvdb::{DBTransaction, KeyValueDB}; use lru_cache::LruCache; use parking_lot::{Mutex, RwLock}; @@ -35,7 +36,7 @@ const BODY_CACHE_SIZE: usize = 1000; pub struct BodyDB { // block cache - body_cache: Mutex>, + body_cache: Mutex>, parcel_address_cache: RwLock>, pending_parcel_addresses: RwLock>>, @@ -280,7 +281,7 @@ impl BodyDB { pub trait BodyProvider { /// Returns true if the given block is known /// (though not necessarily a part of the canon chain). - fn is_known_body(&self, hash: &H256) -> bool; + fn is_known_body(&self, hash: &BlockHash) -> bool; /// Get the address of parcel with given hash. fn transaction_address(&self, hash: &H256) -> Option; @@ -288,11 +289,11 @@ pub trait BodyProvider { fn transaction_address_by_tracker(&self, tracker: &H256) -> Option; /// Get the block body (uncles and parcels). - fn block_body(&self, hash: &H256) -> Option; + fn block_body(&self, hash: &BlockHash) -> Option; } impl BodyProvider for BodyDB { - fn is_known_body(&self, hash: &H256) -> bool { + fn is_known_body(&self, hash: &BlockHash) -> bool { self.block_body(hash).is_some() } @@ -308,7 +309,7 @@ impl BodyProvider for BodyDB { } /// Get block body data - fn block_body(&self, hash: &H256) -> Option { + fn block_body(&self, hash: &BlockHash) -> Option { // Check cache first { let mut lock = self.body_cache.lock(); @@ -330,7 +331,7 @@ impl BodyProvider for BodyDB { } fn parcel_address_entries( - block_hash: H256, + block_hash: BlockHash, parcel_hashes: impl IntoIterator, ) -> impl Iterator)> { parcel_hashes.into_iter().enumerate().map(move |(index, parcel_hash)| { @@ -345,7 +346,7 @@ fn parcel_address_entries( } fn transaction_address_entries( - block_hash: H256, + block_hash: BlockHash, parcel_hashes: impl IntoIterator, ) -> impl Iterator { parcel_hashes.into_iter().enumerate().filter_map(move |(parcel_index, parcel)| { diff --git a/core/src/blockchain/extras.rs b/core/src/blockchain/extras.rs index 8f86d1919c..a48555d33b 100644 --- a/core/src/blockchain/extras.rs +++ b/core/src/blockchain/extras.rs @@ -16,7 +16,7 @@ use std::ops::{Add, AddAssign, Deref, Sub, SubAssign}; -use ctypes::BlockNumber; +use ctypes::{BlockHash, BlockNumber}; use primitives::{H256, H264, U256}; use crate::db::Key; @@ -55,7 +55,7 @@ impl Deref for BlockNumberKey { } -impl Key for BlockNumber { +impl Key for BlockNumber { type Target = BlockNumberKey; fn key(&self) -> Self::Target { @@ -69,7 +69,7 @@ impl Key for BlockNumber { } } -impl Key for H256 { +impl Key for BlockHash { type Target = H264; fn key(&self) -> H264 { @@ -101,14 +101,14 @@ pub struct BlockDetails { /// Total score of the block and all its parents pub total_score: U256, /// Parent block hash - pub parent: H256, + pub parent: BlockHash, } /// Represents address of certain transaction within block #[derive(Debug, PartialEq, Clone, Copy, RlpEncodable, RlpDecodable)] pub struct TransactionAddress { /// Block hash - pub block_hash: H256, + pub block_hash: BlockHash, /// Parcel index within the block pub index: usize, } @@ -191,7 +191,7 @@ mod tests { #[test] fn encode_and_decode_transaction_address_with_single_address() { rlp_encode_and_decode_test!(TransactionAddresses::new(TransactionAddress { - block_hash: H256::random(), + block_hash: H256::random().into(), index: 0, })); } @@ -206,15 +206,15 @@ mod tests { rlp_encode_and_decode_test!(TransactionAddresses { addresses: vec![ TransactionAddress { - block_hash: H256::random(), + block_hash: H256::random().into(), index: 0, }, TransactionAddress { - block_hash: H256::random(), + block_hash: H256::random().into(), index: 3, }, TransactionAddress { - block_hash: H256::random(), + block_hash: H256::random().into(), index: 1, }, ], @@ -225,24 +225,24 @@ mod tests { fn add() { let t1 = TransactionAddresses { addresses: vec![TransactionAddress { - block_hash: 0.into(), + block_hash: H256::zero().into(), index: 0, }], }; let t2 = TransactionAddresses { addresses: vec![TransactionAddress { - block_hash: 1.into(), + block_hash: H256::from(1).into(), index: 0, }], }; assert_eq!( vec![ TransactionAddress { - block_hash: 0.into(), + block_hash: H256::zero().into(), index: 0, }, TransactionAddress { - block_hash: 1.into(), + block_hash: H256::from(1).into(), index: 0, } ], @@ -254,19 +254,19 @@ mod tests { fn do_not_add_duplicated_item() { let t1 = TransactionAddresses { addresses: vec![TransactionAddress { - block_hash: 0.into(), + block_hash: H256::zero().into(), index: 0, }], }; let t2 = TransactionAddresses { addresses: vec![TransactionAddress { - block_hash: 0.into(), + block_hash: H256::zero().into(), index: 0, }], }; assert_eq!( vec![TransactionAddress { - block_hash: 0.into(), + block_hash: H256::zero().into(), index: 0, },], (t1 + t2).addresses @@ -278,33 +278,33 @@ mod tests { let t1 = TransactionAddresses { addresses: vec![ TransactionAddress { - block_hash: 0.into(), + block_hash: H256::zero().into(), index: 0, }, TransactionAddress { - block_hash: 1.into(), + block_hash: H256::from(1).into(), index: 0, }, TransactionAddress { - block_hash: 2.into(), + block_hash: H256::from(2).into(), index: 0, }, ], }; let t2 = TransactionAddresses { addresses: vec![TransactionAddress { - block_hash: 1.into(), + block_hash: H256::from(1).into(), index: 0, }], }; assert_eq!( vec![ TransactionAddress { - block_hash: 0.into(), + block_hash: H256::zero().into(), index: 0, }, TransactionAddress { - block_hash: 2.into(), + block_hash: H256::from(2).into(), index: 0, } ], @@ -316,19 +316,19 @@ mod tests { fn remove_dont_touch_unmatched_item() { let t1 = TransactionAddresses { addresses: vec![TransactionAddress { - block_hash: 0.into(), + block_hash: H256::zero().into(), index: 0, }], }; let t2 = TransactionAddresses { addresses: vec![TransactionAddress { - block_hash: 1.into(), + block_hash: H256::from(1).into(), index: 0, }], }; assert_eq!( vec![TransactionAddress { - block_hash: 0.into(), + block_hash: H256::zero().into(), index: 0, },], (t1 - t2).addresses diff --git a/core/src/blockchain/headerchain.rs b/core/src/blockchain/headerchain.rs index 31831893c5..2451bfc0b6 100644 --- a/core/src/blockchain/headerchain.rs +++ b/core/src/blockchain/headerchain.rs @@ -19,7 +19,7 @@ use std::mem; use std::sync::Arc; use ctypes::header::{Header, Seal}; -use ctypes::BlockNumber; +use ctypes::{BlockHash, BlockNumber}; use kvdb::{DBTransaction, KeyValueDB}; use lru_cache::LruCache; use parking_lot::{Mutex, RwLock}; @@ -44,21 +44,21 @@ const HEADER_CACHE_SIZE: usize = 1000; pub struct HeaderChain { // All locks must be captured in the order declared here. /// The hash of the best block of the canonical chain. - best_header_hash: RwLock, + best_header_hash: RwLock, /// The hash of the block which has the best score among the proposal blocks - best_proposal_header_hash: RwLock, + best_proposal_header_hash: RwLock, // cache - header_cache: Mutex>, - detail_cache: RwLock>, - hash_cache: Mutex>, + header_cache: Mutex>, + detail_cache: RwLock>, + hash_cache: Mutex>, db: Arc, - pending_best_header_hash: RwLock>, - pending_best_proposal_block_hash: RwLock>, - pending_hashes: RwLock>, - pending_details: RwLock>, + pending_best_header_hash: RwLock>, + pending_best_proposal_block_hash: RwLock>, + pending_hashes: RwLock>, + pending_details: RwLock>, } impl HeaderChain { @@ -66,7 +66,7 @@ impl HeaderChain { pub fn new(genesis: &HeaderView, db: Arc) -> Self { // load best header let best_header_hash = match db.get(db::COL_EXTRA, BEST_HEADER_KEY).unwrap() { - Some(hash) => H256::from_slice(&hash), + Some(hash) => H256::from_slice(&hash).into(), None => { // best header does not exist // we need to insert genesis into the cache @@ -95,7 +95,8 @@ impl HeaderChain { &db.get(db::COL_EXTRA, BEST_PROPOSAL_HEADER_KEY) .unwrap() .expect("best proposal header is set by best header"), - ); + ) + .into(); Self { best_header_hash: RwLock::new(best_header_hash), @@ -189,7 +190,7 @@ impl HeaderChain { } /// This function returns modified block hashes. - fn new_hash_entries(&self, best_header_changed: &BestHeaderChanged) -> HashMap { + fn new_hash_entries(&self, best_header_changed: &BestHeaderChanged) -> HashMap { let mut hashes = HashMap::new(); match best_header_changed { @@ -221,7 +222,7 @@ impl HeaderChain { /// This function returns modified block details. /// Uses the given parent details or attempts to load them from the database. - fn new_detail_entries(&self, header: &HeaderView) -> HashMap { + fn new_detail_entries(&self, header: &HeaderView) -> HashMap { let parent_hash = header.parent_hash(); let parent_details = self.block_details(&parent_hash).expect("Invalid parent hash"); @@ -292,7 +293,7 @@ impl HeaderChain { /// in Tendermint. /// /// Used in BlockChain::update_best_as_committed(). - pub fn update_best_as_committed(&self, batch: &mut DBTransaction, block_hash: H256) { + pub fn update_best_as_committed(&self, batch: &mut DBTransaction, block_hash: BlockHash) { assert!(self.pending_best_header_hash.read().is_none()); let prev_best_header_number = self.best_header().number(); @@ -320,11 +321,11 @@ impl HeaderChain { } /// Get best block hash. - pub fn best_header_hash(&self) -> H256 { + pub fn best_header_hash(&self) -> BlockHash { *self.best_header_hash.read() } - pub fn best_proposal_header_hash(&self) -> H256 { + pub fn best_proposal_header_hash(&self) -> BlockHash { *self.best_proposal_header_hash.read() } @@ -345,29 +346,29 @@ impl HeaderChain { pub trait HeaderProvider { /// Returns true if the given block is known /// (though not necessarily a part of the canon chain). - fn is_known_header(&self, hash: &H256) -> bool; + fn is_known_header(&self, hash: &BlockHash) -> bool; /// Get the familial details concerning a block. - fn block_details(&self, hash: &H256) -> Option; + fn block_details(&self, hash: &BlockHash) -> Option; /// Get the hash of given block's number. - fn block_hash(&self, index: BlockNumber) -> Option; + fn block_hash(&self, index: BlockNumber) -> Option; /// Get the partial-header of a block. - fn block_header(&self, hash: &H256) -> Option
{ + fn block_header(&self, hash: &BlockHash) -> Option
{ self.block_header_data(hash).map(|header| header.decode()) } /// Get the header RLP of a block. - fn block_header_data(&self, hash: &H256) -> Option; + fn block_header_data(&self, hash: &BlockHash) -> Option; /// Get the number of given block's hash. - fn block_number(&self, hash: &H256) -> Option { + fn block_number(&self, hash: &BlockHash) -> Option { self.block_details(hash).map(|details| details.number) } /// Returns reference to genesis hash. - fn genesis_hash(&self) -> H256 { + fn genesis_hash(&self) -> BlockHash { self.block_hash(0).expect("Genesis hash should always exist") } @@ -378,18 +379,18 @@ pub trait HeaderProvider { } impl HeaderProvider for HeaderChain { - fn is_known_header(&self, hash: &H256) -> bool { + fn is_known_header(&self, hash: &BlockHash) -> bool { self.db.exists_with_cache(db::COL_EXTRA, &self.detail_cache, hash) } /// Get the familial details concerning a block. - fn block_details(&self, hash: &H256) -> Option { + fn block_details(&self, hash: &BlockHash) -> Option { let result = self.db.read_with_cache(db::COL_EXTRA, &mut *self.detail_cache.write(), hash)?; Some(result) } /// Get the hash of given block's number. - fn block_hash(&self, index: BlockNumber) -> Option { + fn block_hash(&self, index: BlockNumber) -> Option { // Highest block should not be accessed by block number. if self.best_header().number() < index { return None @@ -399,7 +400,7 @@ impl HeaderProvider for HeaderChain { } /// Get block header data - fn block_header_data(&self, hash: &H256) -> Option { + fn block_header_data(&self, hash: &BlockHash) -> Option { let result = block_header_data(hash, &self.header_cache, &*self.db).map(encoded::Header::new); if let Some(header) = &result { debug_assert_eq!(*hash, header.hash()); @@ -409,7 +410,11 @@ impl HeaderProvider for HeaderChain { } /// Get block header data -fn block_header_data(hash: &H256, header_cache: &Mutex>, db: &dyn KeyValueDB) -> Option> { +fn block_header_data( + hash: &BlockHash, + header_cache: &Mutex>, + db: &dyn KeyValueDB, +) -> Option> { // Check cache first { let mut lock = header_cache.lock(); diff --git a/core/src/blockchain/route.rs b/core/src/blockchain/route.rs index 553680bb60..7d7d7aa9ef 100644 --- a/core/src/blockchain/route.rs +++ b/core/src/blockchain/route.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use primitives::H256; +use ctypes::BlockHash; use super::block_info::{BestBlockChanged, BestHeaderChanged}; use super::headerchain::HeaderProvider; @@ -23,13 +23,13 @@ use super::headerchain::HeaderProvider; #[derive(Clone, Debug, PartialEq)] pub struct TreeRoute { /// Best common ancestor of these blocks. - pub ancestor: H256, + pub ancestor: BlockHash, /// A vector of enacted block hashes /// First item of list must be child of ancestor - pub enacted: Vec, + pub enacted: Vec, /// A vector of retracted block hashes /// Last item of list must be child of ancestor - pub retracted: Vec, + pub retracted: Vec, } /// Returns a tree route between `from` and `to`, which is a tuple of: @@ -71,7 +71,7 @@ pub struct TreeRoute { /// /// If the tree route verges into pruned or unknown blocks, /// `None` is returned. -pub fn tree_route(db: &dyn HeaderProvider, from: H256, to: H256) -> Option { +pub fn tree_route(db: &dyn HeaderProvider, from: BlockHash, to: BlockHash) -> Option { let mut retracted = vec![]; let mut enacted = vec![]; @@ -112,15 +112,15 @@ pub fn tree_route(db: &dyn HeaderProvider, from: H256, to: H256) -> Option, + pub retracted: Vec, /// Blocks that were validated by new block. - pub enacted: Vec, + pub enacted: Vec, /// Blocks which are neither retracted nor enacted. - pub omitted: Vec, + pub omitted: Vec, } impl ImportRoute { - pub fn new(new_block_hash: H256, best_block_changed: &BestBlockChanged) -> Self { + pub fn new(new_block_hash: BlockHash, best_block_changed: &BestBlockChanged) -> Self { let mut omitted = Vec::new(); if best_block_changed.new_best_hash() != Some(new_block_hash) { omitted.push(new_block_hash); @@ -159,7 +159,7 @@ impl ImportRoute { } } - pub fn new_from_best_header_changed(new_block_hash: H256, best_header_changed: &BestHeaderChanged) -> Self { + pub fn new_from_best_header_changed(new_block_hash: BlockHash, best_header_changed: &BestHeaderChanged) -> Self { let mut omitted = Vec::new(); if best_header_changed.new_best_hash() != Some(new_block_hash) { omitted.push(new_block_hash); diff --git a/core/src/blockchain_info.rs b/core/src/blockchain_info.rs index 32c620d087..065605543b 100644 --- a/core/src/blockchain_info.rs +++ b/core/src/blockchain_info.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use ctypes::BlockNumber; -use primitives::{H256, U256}; +use ctypes::{BlockHash, BlockNumber}; +use primitives::U256; /// Information about the blockchain gathered together. #[derive(Clone, Debug)] @@ -27,11 +27,11 @@ pub struct BlockChainInfo { /// Block queue score. pub pending_total_score: U256, /// Genesis block hash. - pub genesis_hash: H256, + pub genesis_hash: BlockHash, /// Best blockchain block hash. - pub best_block_hash: H256, + pub best_block_hash: BlockHash, /// Best blockchain proposal block hash. - pub best_proposal_block_hash: H256, + pub best_proposal_block_hash: BlockHash, /// Best blockchain block number. pub best_block_number: BlockNumber, /// Best blockchain block timestamp. diff --git a/core/src/client/chain_notify.rs b/core/src/client/chain_notify.rs index 03ce1f6ae3..dfbdba5d56 100644 --- a/core/src/client/chain_notify.rs +++ b/core/src/client/chain_notify.rs @@ -15,6 +15,7 @@ // along with this program. If not, see . use cnetwork::NodeId; +use ctypes::BlockHash; use primitives::H256; /// Represents what has to be handled by actor listening to chain events @@ -22,13 +23,13 @@ pub trait ChainNotify: Send + Sync { /// fires when chain has new headers. fn new_headers( &self, - _imported: Vec, - _invalid: Vec, - _enacted: Vec, - _retracted: Vec, - _sealed: Vec, + _imported: Vec, + _invalid: Vec, + _enacted: Vec, + _retracted: Vec, + _sealed: Vec, _duration: u64, - _new_best_proposal: Option, + _new_best_proposal: Option, ) { // does nothing by default } @@ -36,11 +37,11 @@ pub trait ChainNotify: Send + Sync { /// fires when chain has new blocks. fn new_blocks( &self, - _imported: Vec, - _invalid: Vec, - _enacted: Vec, - _retracted: Vec, - _sealed: Vec, + _imported: Vec, + _invalid: Vec, + _enacted: Vec, + _retracted: Vec, + _sealed: Vec, _duration: u64, ) { // does nothing by default diff --git a/core/src/client/client.rs b/core/src/client/client.rs index 9c3fb6824c..846a031ec4 100644 --- a/core/src/client/client.rs +++ b/core/src/client/client.rs @@ -28,7 +28,7 @@ use cstate::{ }; use ctimer::{TimeoutHandler, TimerApi, TimerScheduleError, TimerToken}; use ctypes::transaction::{AssetTransferInput, PartialHashing, ShardTransaction}; -use ctypes::{BlockNumber, CommonParams, ShardId}; +use ctypes::{BlockHash, BlockNumber, CommonParams, ShardId}; use cvm::{decode, execute, ChainTimeInfo, ScriptResult, VMConfig}; use hashdb::AsHashDB; use journaldb; @@ -101,7 +101,7 @@ impl Client { // Sets the correct state root. state_db = scheme.ensure_genesis_state(state_db)?; let mut batch = DBTransaction::new(); - state_db.journal_under(&mut batch, 0, scheme.genesis_header().hash())?; + state_db.journal_under(&mut batch, 0, *scheme.genesis_header().hash())?; db.write(batch).map_err(ClientError::Database)?; } @@ -150,11 +150,11 @@ impl Client { pub fn new_blocks( &self, - imported: &[H256], - invalid: &[H256], - enacted: &[H256], - retracted: &[H256], - sealed: &[H256], + imported: &[BlockHash], + invalid: &[BlockHash], + enacted: &[BlockHash], + retracted: &[BlockHash], + sealed: &[BlockHash], duration: u64, ) { self.notify(|notify| { @@ -171,13 +171,13 @@ impl Client { pub fn new_headers( &self, - imported: &[H256], - invalid: &[H256], - enacted: &[H256], - retracted: &[H256], - sealed: &[H256], + imported: &[BlockHash], + invalid: &[BlockHash], + enacted: &[BlockHash], + retracted: &[BlockHash], + sealed: &[BlockHash], duration: u64, - new_best_proposal: Option, + new_best_proposal: Option, ) { self.notify(|notify| { notify.new_headers( @@ -217,7 +217,7 @@ impl Client { self.importer.miner.update_sealing(self, parent_block, allow_empty_block); } - fn block_hash(chain: &BlockChain, id: &BlockId) -> Option { + fn block_hash(chain: &BlockChain, id: &BlockId) -> Option { match id { BlockId::Hash(hash) => Some(*hash), BlockId::Number(number) => chain.block_hash(*number), @@ -257,7 +257,7 @@ impl Client { /// This is triggered by a message coming from the Tendermint engine when a block is committed. /// See EngineClient::update_best_as_committed() for details. - pub fn update_best_as_committed(&self, block_hash: H256) { + pub fn update_best_as_committed(&self, block_hash: BlockHash) { ctrace!(CLIENT, "Update the best block to the hash({}), as requested", block_hash); let start = Instant::now(); let route = { @@ -557,7 +557,7 @@ impl EngineClient for Client { } /// Submit a seal for a block in the mining queue. - fn submit_seal(&self, block_hash: H256, seal: Vec) { + fn submit_seal(&self, block_hash: BlockHash, seal: Vec) { if self.importer.miner.submit_seal(self, block_hash, seal).is_err() { cwarn!(CLIENT, "Wrong internal seal submission!") } @@ -571,7 +571,7 @@ impl EngineClient for Client { /// Update the best block as the given block hash. /// /// Used in Tendermint, when going to the commit step. - fn update_best_as_committed(&self, block_hash: H256) { + fn update_best_as_committed(&self, block_hash: BlockHash) { ctrace!(ENGINE, "Requesting a best block update (block hash: {})", block_hash); match self.io_channel.lock().send(ClientIoMessage::UpdateBestAsCommitted(block_hash)) { Ok(_) => {} @@ -625,7 +625,7 @@ impl BlockChainTrait for Client { Self::block_hash(&chain, id).and_then(|hash| chain.block(&hash)) } - fn transaction_block(&self, id: &TransactionId) -> Option { + fn transaction_block(&self, id: &TransactionId) -> Option { self.transaction_address(id).map(|addr| addr.block_hash) } @@ -635,7 +635,7 @@ impl BlockChainTrait for Client { } impl ImportBlock for Client { - fn import_block(&self, bytes: Bytes) -> Result { + fn import_block(&self, bytes: Bytes) -> Result { use crate::verification::queue::kind::blocks::Unverified; use crate::verification::queue::kind::BlockLike; @@ -648,7 +648,7 @@ impl ImportBlock for Client { Ok(self.importer.block_queue.import(unverified)?) } - fn import_header(&self, bytes: Bytes) -> Result { + fn import_header(&self, bytes: Bytes) -> Result { let unverified = ::encoded::Header::new(bytes).decode(); { if self.block_chain().is_known_header(&unverified.hash()) { @@ -781,7 +781,7 @@ impl BlockChainClient for Client { Self::block_hash(&chain, id).and_then(|hash| chain.block_details(&hash)).map(|d| d.total_score) } - fn block_hash(&self, id: &BlockId) -> Option { + fn block_hash(&self, id: &BlockId) -> Option { let chain = self.block_chain(); Self::block_hash(&chain, id) } diff --git a/core/src/client/importer.rs b/core/src/client/importer.rs index d4cd457afc..b9bf9479a5 100644 --- a/core/src/client/importer.rs +++ b/core/src/client/importer.rs @@ -21,9 +21,9 @@ use std::time::Instant; use cio::IoChannel; use ctypes::header::Header; +use ctypes::BlockHash; use kvdb::DBTransaction; use parking_lot::{Mutex, MutexGuard}; -use primitives::H256; use rlp::Encodable; use super::{BlockChainTrait, Client, ClientConfig}; @@ -125,7 +125,7 @@ impl Importer { } let imported = imported_blocks.len(); - let invalid_blocks = invalid_blocks.into_iter().collect::>(); + let invalid_blocks = invalid_blocks.into_iter().collect::>(); if !invalid_blocks.is_empty() { self.block_queue.mark_as_bad(&invalid_blocks); @@ -153,8 +153,8 @@ impl Importer { imported } - pub fn calculate_enacted_retracted(&self, import_results: &[ImportRoute]) -> (Vec, Vec) { - fn map_to_vec(map: Vec<(H256, bool)>) -> Vec { + pub fn calculate_enacted_retracted(&self, import_results: &[ImportRoute]) -> (Vec, Vec) { + fn map_to_vec(map: Vec<(BlockHash, bool)>) -> Vec { map.into_iter().map(|(k, _v)| k).collect() } @@ -332,7 +332,7 @@ impl Importer { } let parent_header = client - .block_header(&BlockId::Hash(*header.parent_hash())) + .block_header(&(*header.parent_hash()).into()) .unwrap_or_else(|| panic!("Parent of importing header must exist {:?}", header.parent_hash())) .decode(); if client.block_header(&BlockId::Hash(hash)).is_some() { diff --git a/core/src/client/mod.rs b/core/src/client/mod.rs index d80f5b0301..bdbd712716 100644 --- a/core/src/client/mod.rs +++ b/core/src/client/mod.rs @@ -37,7 +37,7 @@ use cmerkle::Result as TrieResult; use cnetwork::NodeId; use cstate::{AssetScheme, FindActionHandler, OwnedAsset, StateResult, Text, TopLevelState, TopStateView}; use ctypes::transaction::{AssetTransferInput, PartialHashing, ShardTransaction}; -use ctypes::{BlockNumber, CommonParams, ShardId}; +use ctypes::{BlockHash, BlockNumber, CommonParams, ShardId}; use cvm::ChainTimeInfo; use kvdb::KeyValueDB; use primitives::{Bytes, H160, H256, U256}; @@ -73,7 +73,7 @@ pub trait BlockChainTrait { fn block(&self, id: &BlockId) -> Option; /// Get the hash of block that contains the transaction, if any. - fn transaction_block(&self, id: &TransactionId) -> Option; + fn transaction_block(&self, id: &TransactionId) -> Option; fn transaction_header(&self, tracker: &H256) -> Option<::encoded::Header>; @@ -101,7 +101,7 @@ pub trait EngineClient: Sync + Send + BlockChainTrait + ImportBlock { fn update_sealing(&self, parent_block: BlockId, allow_empty_block: bool); /// Submit a seal for a block in the mining queue. - fn submit_seal(&self, block_hash: H256, seal: Vec); + fn submit_seal(&self, block_hash: BlockHash, seal: Vec); /// Convert PoW difficulty to target. fn score_to_target(&self, score: &U256) -> U256; @@ -109,7 +109,7 @@ pub trait EngineClient: Sync + Send + BlockChainTrait + ImportBlock { /// Update the best block as the given block hash /// /// Used in Tendermint, when going to the commit step. - fn update_best_as_committed(&self, block_hash: H256); + fn update_best_as_committed(&self, block_hash: BlockHash); fn get_kvdb(&self) -> Arc; } @@ -195,10 +195,10 @@ pub trait Shard { /// Provides methods to import block into blockchain pub trait ImportBlock { /// Import a block into the blockchain. - fn import_block(&self, bytes: Bytes) -> Result; + fn import_block(&self, bytes: Bytes) -> Result; /// Import a header into the blockchain - fn import_header(&self, bytes: Bytes) -> Result; + fn import_header(&self, bytes: Bytes) -> Result; /// Import sealed block. Skips all verifications. fn import_sealed_block(&self, block: &SealedBlock) -> ImportResult; @@ -244,7 +244,7 @@ pub trait BlockChainClient: Sync + Send + AccountData + BlockChainTrait + Import fn block_total_score(&self, id: &BlockId) -> Option; /// Get block hash. - fn block_hash(&self, id: &BlockId) -> Option; + fn block_hash(&self, id: &BlockId) -> Option; /// Get transaction with given hash. fn transaction(&self, id: &TransactionId) -> Option; @@ -259,7 +259,7 @@ pub trait BlockChainClient: Sync + Send + AccountData + BlockChainTrait + Import } /// Result of import block operation. -pub type ImportResult = Result; +pub type ImportResult = Result; /// Provides methods used for sealing new state pub trait BlockProducer { diff --git a/core/src/client/test_client.rs b/core/src/client/test_client.rs index af2791e459..2afaaba3b4 100644 --- a/core/src/client/test_client.rs +++ b/core/src/client/test_client.rs @@ -43,7 +43,7 @@ use cstate::tests::helpers::empty_top_state; use cstate::{FindActionHandler, StateDB, TopLevelState}; use ctimer::{TimeoutHandler, TimerToken}; use ctypes::transaction::{Action, Transaction}; -use ctypes::{BlockNumber, CommonParams, Header as BlockHeader}; +use ctypes::{BlockHash, BlockNumber, CommonParams, Header as BlockHeader}; use cvm::ChainTimeInfo; use journaldb; use kvdb::KeyValueDB; @@ -73,13 +73,13 @@ use client::ConsensusClient; /// Test client. pub struct TestBlockChainClient { /// Blocks. - pub blocks: RwLock>, + pub blocks: RwLock>, /// Mapping of numbers to hashes. - pub numbers: RwLock>, + pub numbers: RwLock>, /// Genesis block hash. - pub genesis_hash: H256, + pub genesis_hash: BlockHash, /// Last block hash. - pub last_hash: RwLock, + pub last_hash: RwLock, /// Last transactions_root pub last_transactions_root: RwLock, /// Extra data do set for each block @@ -203,7 +203,7 @@ impl TestBlockChainClient { } } /// Add a block to test client with designated author. - pub fn add_block_with_author(&self, author: Option
, n: usize, transaction_length: usize) -> H256 { + pub fn add_block_with_author(&self, author: Option
, n: usize, transaction_length: usize) -> BlockHash { let mut header = BlockHeader::new(); header.set_score(From::from(n)); header.set_parent_hash(*self.last_hash.read()); @@ -257,7 +257,7 @@ impl TestBlockChainClient { let block_id = n.into(); let hash = self.block_hash(&block_id).unwrap(); let mut header: BlockHeader = self.block_header(&block_id).unwrap().decode(); - header.set_parent_hash(H256::from(42)); + header.set_parent_hash(H256::from(42).into()); let mut rlp = RlpStream::new_list(3); rlp.append(&header); rlp.append_raw(&::rlp::NULL_RLP, 1); @@ -266,13 +266,13 @@ impl TestBlockChainClient { } /// TODO: - pub fn block_hash_delta_minus(&mut self, delta: usize) -> H256 { + pub fn block_hash_delta_minus(&mut self, delta: usize) -> BlockHash { let blocks_read = self.numbers.read(); let index = blocks_read.len() - delta; blocks_read[&index] } - fn block_hash(&self, id: &BlockId) -> Option { + fn block_hash(&self, id: &BlockId) -> Option { match id { BlockId::Hash(hash) => Some(*hash), BlockId::Number(n) => self.numbers.read().get(&(*n as usize)).cloned(), @@ -455,7 +455,7 @@ impl BlockChainTrait for TestBlockChainClient { self.block_hash(id).and_then(|hash| self.blocks.read().get(&hash).cloned()).map(encoded::Block::new) } - fn transaction_block(&self, _id: &TransactionId) -> Option { + fn transaction_block(&self, _id: &TransactionId) -> Option { None // Simple default. } @@ -465,7 +465,7 @@ impl BlockChainTrait for TestBlockChainClient { } impl ImportBlock for TestBlockChainClient { - fn import_block(&self, b: Bytes) -> Result { + fn import_block(&self, b: Bytes) -> Result { let header = Rlp::new(&b).val_at::(0); let h = header.hash(); let number: usize = header.number() as usize; @@ -487,7 +487,8 @@ impl ImportBlock for TestBlockChainClient { *score += *header.score(); } mem::replace(&mut *self.last_hash.write(), h); - mem::replace(&mut *self.last_transactions_root.write(), h); + // FIXME: The transactions root is not related to block hash. + mem::replace(&mut *self.last_transactions_root.write(), *h); self.blocks.write().insert(h, b); self.numbers.write().insert(number, h); let mut parent_hash = *header.parent_hash(); @@ -505,12 +506,12 @@ impl ImportBlock for TestBlockChainClient { Ok(h) } - fn import_header(&self, _bytes: Bytes) -> Result { + fn import_header(&self, _bytes: Bytes) -> Result { unimplemented!() } fn import_sealed_block(&self, _block: &SealedBlock) -> ImportResult { - Ok(H256::default()) + Ok(H256::default().into()) } fn set_min_timer(&self) {} @@ -584,7 +585,7 @@ impl BlockChainClient for TestBlockChainClient { Some(U256::zero()) } - fn block_hash(&self, id: &BlockId) -> Option { + fn block_hash(&self, id: &BlockId) -> Option { Self::block_hash(self, id) } @@ -626,7 +627,7 @@ impl super::EngineClient for TestBlockChainClient { self.miner.update_sealing(self, parent_block, allow_empty_block) } - fn submit_seal(&self, block_hash: H256, seal: Vec) { + fn submit_seal(&self, block_hash: BlockHash, seal: Vec) { if self.miner.submit_seal(self, block_hash, seal).is_err() { cwarn!(CLIENT, "Wrong internal seal submission!") } @@ -636,7 +637,7 @@ impl super::EngineClient for TestBlockChainClient { U256::zero() } - fn update_best_as_committed(&self, _block_hash: H256) {} + fn update_best_as_committed(&self, _block_hash: BlockHash) {} fn get_kvdb(&self) -> Arc { let db = kvdb_memorydb::create(NUM_COLUMNS.unwrap_or(0)); diff --git a/core/src/consensus/blake_pow/mod.rs b/core/src/consensus/blake_pow/mod.rs index 52ef3056d1..0f20eb2455 100644 --- a/core/src/consensus/blake_pow/mod.rs +++ b/core/src/consensus/blake_pow/mod.rs @@ -148,7 +148,7 @@ impl ConsensusEngine for BlakePoW { if header.score() != &expected_score { return Err(From::from(BlockError::InvalidScore(Mismatch { expected: expected_score, - found: U256::from(header.hash()), + found: U256::from(*header.hash()), }))) } diff --git a/core/src/consensus/cuckoo/mod.rs b/core/src/consensus/cuckoo/mod.rs index d2c49f04e4..14bcc29780 100644 --- a/core/src/consensus/cuckoo/mod.rs +++ b/core/src/consensus/cuckoo/mod.rs @@ -158,7 +158,7 @@ impl ConsensusEngine for Cuckoo { if header.score() != &expected_score { return Err(From::from(BlockError::InvalidScore(Mismatch { expected: expected_score, - found: U256::from(header.hash()), + found: U256::from(*header.hash()), }))) } diff --git a/core/src/consensus/mod.rs b/core/src/consensus/mod.rs index bc8babf156..8ba08b2069 100644 --- a/core/src/consensus/mod.rs +++ b/core/src/consensus/mod.rs @@ -45,8 +45,8 @@ use cstate::ActionHandler; use ctypes::errors::SyntaxError; use ctypes::transaction::Action; use ctypes::util::unexpected::{Mismatch, OutOfBounds}; -use ctypes::{CommonParams, Header}; -use primitives::{Bytes, H256, U256}; +use ctypes::{BlockHash, CommonParams, Header}; +use primitives::{Bytes, U256}; use self::bit_set::BitSet; use crate::account_provider::AccountProvider; @@ -262,7 +262,7 @@ pub trait ConsensusEngine: Sync + Send { fn register_chain_notify(&self, _: &Client) {} - fn get_best_block_from_best_proposal_header(&self, header: &HeaderView) -> H256 { + fn get_best_block_from_best_proposal_header(&self, header: &HeaderView) -> BlockHash { header.hash() } @@ -271,10 +271,10 @@ pub trait ConsensusEngine: Sync + Send { /// Only the descendant of the current best block could be the next best block in Tendermint consensus. fn can_change_canon_chain( &self, - _new_block_hash: H256, - _parent_hash_of_new_header: H256, - _grandparent_hash_of_new_header: H256, - _previous_best_hash: H256, + _new_block_hash: BlockHash, + _parent_hash_of_new_header: BlockHash, + _grandparent_hash_of_new_header: BlockHash, + _previous_best_hash: BlockHash, ) -> bool { true } diff --git a/core/src/consensus/simple_poa/mod.rs b/core/src/consensus/simple_poa/mod.rs index d2a2633ef8..a06109ca33 100644 --- a/core/src/consensus/simple_poa/mod.rs +++ b/core/src/consensus/simple_poa/mod.rs @@ -21,6 +21,7 @@ use std::sync::{Arc, Weak}; use ckey::{public_to_address, recover, Address, Signature}; use ctypes::{CommonParams, Header}; use parking_lot::RwLock; +use primitives::H256; use self::params::SimplePoAParams; use super::signer::EngineSigner; @@ -149,7 +150,7 @@ impl ConsensusEngine for SimplePoA { fn possible_authors(&self, _block_number: Option) -> Result>, EngineError> { // TODO: It works because the round robin validator doesn't use the parent hash. - let parent = 0.into(); + let parent = H256::from(0).into(); Ok(Some(self.validators.addresses(&parent))) } } diff --git a/core/src/consensus/stake/actions.rs b/core/src/consensus/stake/actions.rs index 013bda7180..7290c8c54a 100644 --- a/core/src/consensus/stake/actions.rs +++ b/core/src/consensus/stake/actions.rs @@ -361,6 +361,7 @@ mod tests { use ckey::sign_schnorr; use client::TestBlockChainClient; use consensus::{ConsensusMessage, DynamicValidator, Step, VoteOn, VoteStep}; + use ctypes::BlockHash; use rlp::rlp_encode_and_decode_test; #[test] @@ -392,7 +393,7 @@ mod tests { pub height: u64, pub view: u64, pub step: Step, - pub block_hash: Option, + pub block_hash: Option, pub signer_index: usize, } @@ -404,7 +405,7 @@ mod tests { ) -> ConsensusMessage where F: Fn(VoteStep) -> VoteStep, - G: Fn(Option) -> Option, { + G: Fn(Option) -> Option, { let ConsensusMessageInfo { height, view, @@ -441,7 +442,7 @@ mod tests { ) -> Result<(), SyntaxError> where F: Fn(VoteStep) -> VoteStep, - G: Fn(Option) -> Option, { + G: Fn(Option) -> Option, { let mut test_client = TestBlockChainClient::default(); test_client.add_blocks(10, 1); test_client.set_random_validators(10); @@ -475,7 +476,7 @@ mod tests { height: 2, view: 0, step: Step::Precommit, - block_hash: Some(H256::random()), + block_hash: Some(H256::random().into()), signer_index: 0, }, &|v| v, @@ -486,7 +487,7 @@ mod tests { #[test] fn double_vote_verify_same_message() { - let block_hash = Some(H256::random()); + let block_hash = Some(H256::random().into()); let result = double_vote_verification_result( ConsensusMessageInfo { height: 3, @@ -511,7 +512,7 @@ mod tests { #[test] fn double_vote_verify_different_height() { - let block_hash = Some(H256::random()); + let block_hash = Some(H256::random().into()); let result = double_vote_verification_result( ConsensusMessageInfo { height: 3, @@ -549,7 +550,7 @@ mod tests { height: 2, view: 0, step: Step::Precommit, - block_hash: Some(H256::random()), + block_hash: Some(H256::random().into()), signer_index: 0, }, &|v| v, @@ -564,10 +565,10 @@ mod tests { #[test] fn double_vote_verify_different_message_and_signer() { - let hash1 = Some(H256::random()); - let mut hash2 = Some(H256::random()); + let hash1 = Some(H256::random().into()); + let mut hash2 = Some(H256::random().into()); while hash1 == hash2 { - hash2 = Some(H256::random()); + hash2 = Some(H256::random().into()); } let result = double_vote_verification_result( ConsensusMessageInfo { @@ -613,7 +614,7 @@ mod tests { height: 2, view: 0, step: Step::Precommit, - block_hash: Some(H256::random()), + block_hash: Some(H256::random().into()), signer_index: 0, }, &vote_step_twister, @@ -625,13 +626,13 @@ mod tests { #[test] fn double_vote_verify_strange_sig2() { - let block_hash_twister = |original: Option| { + let block_hash_twister = |original: Option| { original.map(|hash| { let mut twisted = H256::random(); - while twisted == hash { + while twisted == *hash { twisted = H256::random(); } - twisted + BlockHash::from(twisted) }) }; let result = double_vote_verification_result( @@ -646,7 +647,7 @@ mod tests { height: 2, view: 0, step: Step::Precommit, - block_hash: Some(H256::random()), + block_hash: Some(H256::random().into()), signer_index: 0, }, &|v| v, diff --git a/core/src/consensus/tendermint/backup.rs b/core/src/consensus/tendermint/backup.rs index 1f8c45b5c7..9dacf0a5dd 100644 --- a/core/src/consensus/tendermint/backup.rs +++ b/core/src/consensus/tendermint/backup.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +use ctypes::BlockHash; use kvdb::{DBTransaction, KeyValueDB}; -use primitives::H256; use super::message::ConsensusMessage; use super::types::{Height, Step, View}; @@ -39,7 +39,7 @@ pub struct BackupDataV0 { pub view: View, pub step: Step, pub votes: Vec, - pub proposal: Option, + pub proposal: Option, pub last_confirmed_view: View, } @@ -48,7 +48,7 @@ pub struct BackupDataV1 { pub view: View, pub step: Step, pub votes: Vec, - pub proposal: Option, + pub proposal: Option, pub finalized_view_of_previous_block: View, pub finalized_view_of_current_block: Option, } @@ -86,7 +86,7 @@ pub fn restore(db: &dyn KeyValueDB) -> Option { load_v1(db) } -fn find_proposal(votes: &[ConsensusMessage], height: Height, view: View) -> Option { +fn find_proposal(votes: &[ConsensusMessage], height: Height, view: View) -> Option { votes .iter() .rev() diff --git a/core/src/consensus/tendermint/chain_notify.rs b/core/src/consensus/tendermint/chain_notify.rs index 4d631ef632..b368510b5b 100644 --- a/core/src/consensus/tendermint/chain_notify.rs +++ b/core/src/consensus/tendermint/chain_notify.rs @@ -15,7 +15,7 @@ // along with this program. If not, see . use crossbeam_channel as crossbeam; -use primitives::H256; +use ctypes::BlockHash; use super::worker; use crate::client::ChainNotify; @@ -36,11 +36,11 @@ impl ChainNotify for TendermintChainNotify { /// fires when chain has new blocks. fn new_blocks( &self, - imported: Vec, - _invalid: Vec, - enacted: Vec, - _retracted: Vec, - _sealed: Vec, + imported: Vec, + _invalid: Vec, + enacted: Vec, + _retracted: Vec, + _sealed: Vec, _duration: u64, ) { self.inner diff --git a/core/src/consensus/tendermint/engine.rs b/core/src/consensus/tendermint/engine.rs index 63943bf72a..3261e087a5 100644 --- a/core/src/consensus/tendermint/engine.rs +++ b/core/src/consensus/tendermint/engine.rs @@ -25,9 +25,8 @@ use ckey::{public_to_address, Address}; use cnetwork::NetworkService; use crossbeam_channel as crossbeam; use cstate::{ActionHandler, TopStateView}; -use ctypes::{BlockNumber, CommonParams, Header}; +use ctypes::{BlockHash, BlockNumber, CommonParams, Header}; use num_rational::Ratio; -use primitives::H256; use super::super::stake; use super::super::{ConsensusEngine, EngineError, Seal}; @@ -304,17 +303,17 @@ impl ConsensusEngine for Tendermint { client.add_notify(Arc::downgrade(&self.chain_notify) as Weak); } - fn get_best_block_from_best_proposal_header(&self, header: &HeaderView) -> H256 { + fn get_best_block_from_best_proposal_header(&self, header: &HeaderView) -> BlockHash { header.parent_hash() } fn can_change_canon_chain( &self, - _new_header_hash: H256, - parent_hash_of_new_header: H256, - grandparent_hash_of_new_header: H256, - prev_best_hash: H256, + _new_header_hash: BlockHash, + parent_hash_of_new_header: BlockHash, + grandparent_hash_of_new_header: BlockHash, + prev_best_hash: BlockHash, ) -> bool { parent_hash_of_new_header == prev_best_hash || grandparent_hash_of_new_header == prev_best_hash } diff --git a/core/src/consensus/tendermint/message.rs b/core/src/consensus/tendermint/message.rs index 65cd5dfbcc..89b49f97f2 100644 --- a/core/src/consensus/tendermint/message.rs +++ b/core/src/consensus/tendermint/message.rs @@ -18,12 +18,13 @@ use std::cmp; use ccrypto::blake256; use ckey::{verify_schnorr, Error as KeyError, Public, SchnorrSignature}; +use ctypes::BlockHash; use primitives::{Bytes, H256}; use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; use snap; use super::super::BitSet; -use super::{BlockHash, Height, Step, View}; +use super::{Height, Step, View}; /// Complete step of the consensus process. #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, RlpDecodable, RlpEncodable)] @@ -89,7 +90,7 @@ pub enum TendermintMessage { }, StepState { vote_step: VoteStep, - proposal: Option, + proposal: Option, lock_view: Option, known_votes: BitSet, }, @@ -337,7 +338,7 @@ impl ConsensusMessage { self.signer_index } - pub fn block_hash(&self) -> Option { + pub fn block_hash(&self) -> Option { self.on.block_hash } @@ -434,9 +435,9 @@ mod tests { signer_index: 0x1234, on: VoteOn { step: VoteStep::new(2, 3, Step::Commit), - block_hash: Some(H256::from( - "07feab4c39250abf60b77d7589a5b61fdf409bd837e936376381d19db1e1f050" - )), + block_hash: Some( + H256::from("07feab4c39250abf60b77d7589a5b61fdf409bd837e936376381d19db1e1f050").into() + ), }, }, ConsensusMessage { @@ -444,9 +445,9 @@ mod tests { signer_index: 0x1235, on: VoteOn { step: VoteStep::new(2, 3, Step::Commit), - block_hash: Some(H256::from( - "07feab4c39250abf60b77d7589a5b61fdf409bd837e936376381d19db1e1f050" - )), + block_hash: Some( + H256::from("07feab4c39250abf60b77d7589a5b61fdf409bd837e936376381d19db1e1f050").into() + ), }, } ] @@ -466,7 +467,7 @@ mod tests { signer_index: 0x1234, on: VoteOn { step: VoteStep::new(2, 3, Step::Commit), - block_hash: Some(H256::from("07feab4c39250abf60b77d7589a5b61fdf409bd837e936376381d19db1e1f050")), + block_hash: Some(H256::from("07feab4c39250abf60b77d7589a5b61fdf409bd837e936376381d19db1e1f050").into()), }, }; rlp_encode_and_decode_test!(message); @@ -479,7 +480,7 @@ mod tests { let step = Step::Commit; let signature = SchnorrSignature::random(); let signer_index = 0x1234; - let block_hash = Some(H256::from("07feab4c39250abf60b77d7589a5b61fdf409bd837e936376381d19db1e1f050")); + let block_hash = Some(H256::from("07feab4c39250abf60b77d7589a5b61fdf409bd837e936376381d19db1e1f050").into()); let consensus_message = ConsensusMessage { signature, signer_index, diff --git a/core/src/consensus/tendermint/mod.rs b/core/src/consensus/tendermint/mod.rs index a5ca75668d..4e9ae0cd3a 100644 --- a/core/src/consensus/tendermint/mod.rs +++ b/core/src/consensus/tendermint/mod.rs @@ -33,7 +33,6 @@ use crossbeam_channel as crossbeam; use cstate::ActionHandler; use ctimer::TimerToken; use parking_lot::RwLock; -use primitives::H256; use self::chain_notify::TendermintChainNotify; pub use self::message::{ConsensusMessage, VoteOn, VoteStep}; @@ -54,8 +53,6 @@ const ENGINE_TIMEOUT_BROADCAST_STEP_STATE: TimerToken = 21; /// Unit: second const ENGINE_TIMEOUT_BROADCAT_STEP_STATE_INTERVAL: u64 = 1; -pub type BlockHash = H256; - /// ConsensusEngine using `Tendermint` consensus algorithm pub struct Tendermint { client: RwLock>>, diff --git a/core/src/consensus/tendermint/network.rs b/core/src/consensus/tendermint/network.rs index d1746d51fa..0dffd9495c 100644 --- a/core/src/consensus/tendermint/network.rs +++ b/core/src/consensus/tendermint/network.rs @@ -24,7 +24,8 @@ use ckey::SchnorrSignature; use cnetwork::{Api, NetworkExtension, NodeId}; use crossbeam_channel as crossbeam; use ctimer::TimerToken; -use primitives::{Bytes, H256}; +use ctypes::BlockHash; +use primitives::Bytes; use rand::prelude::SliceRandom; use rand::thread_rng; use rlp::{Encodable, UntrustedRlp}; @@ -69,7 +70,13 @@ impl TendermintExtension { } } - fn update_peer_state(&mut self, token: &NodeId, vote_step: VoteStep, proposal: Option, messages: BitSet) { + fn update_peer_state( + &mut self, + token: &NodeId, + vote_step: VoteStep, + proposal: Option, + messages: BitSet, + ) { let peer_state = match self.peers.get_mut(token) { Some(peer_state) => peer_state, // update_peer_state could be called after the peer is disconnected @@ -104,7 +111,13 @@ impl TendermintExtension { self.api.send(token, message); } - fn broadcast_state(&self, vote_step: VoteStep, proposal: Option, lock_view: Option, votes: BitSet) { + fn broadcast_state( + &self, + vote_step: VoteStep, + proposal: Option, + lock_view: Option, + votes: BitSet, + ) { ctrace!(ENGINE, "Broadcast state {:?} {:?} {:?}", vote_step, proposal, votes); let tokens = self.select_random_peers(); let message = Arc::new( @@ -456,7 +469,7 @@ pub enum Event { }, BroadcastState { vote_step: VoteStep, - proposal: Option, + proposal: Option, lock_view: Option, votes: BitSet, }, diff --git a/core/src/consensus/tendermint/types.rs b/core/src/consensus/tendermint/types.rs index 373c9e7d33..83e4524afd 100644 --- a/core/src/consensus/tendermint/types.rs +++ b/core/src/consensus/tendermint/types.rs @@ -17,13 +17,13 @@ use std::fmt; use ckey::SchnorrSignature; -use primitives::{Bytes, H256}; +use ctypes::BlockHash; +use primitives::Bytes; use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; use super::super::BitSet; use super::message::VoteStep; use crate::block::{IsBlock, SealedBlock}; -use consensus::tendermint::BlockHash; pub type Height = u64; pub type View = u64; @@ -32,7 +32,7 @@ pub type View = u64; pub enum TendermintState { Propose, ProposeWaitBlockGeneration { - parent_hash: H256, + parent_hash: BlockHash, }, ProposeWaitImported { block: Box, @@ -44,11 +44,11 @@ pub enum TendermintState { Precommit, Commit { view: View, - block_hash: H256, + block_hash: BlockHash, }, CommitTimedout { view: View, - block_hash: H256, + block_hash: BlockHash, }, } @@ -199,7 +199,7 @@ impl Encodable for Step { pub struct PeerState { pub vote_step: VoteStep, - pub proposal: Option, + pub proposal: Option, pub messages: BitSet, } @@ -270,12 +270,12 @@ impl<'a> TendermintSealView<'a> { #[derive(Copy, Clone)] pub enum TwoThirdsMajority { Empty, - Lock(View, H256), + Lock(View, BlockHash), Unlock(View), } impl TwoThirdsMajority { - pub fn from_message(view: View, block_hash: Option) -> Self { + pub fn from_message(view: View, block_hash: Option) -> Self { match block_hash { Some(block_hash) => TwoThirdsMajority::Lock(view, block_hash), None => TwoThirdsMajority::Unlock(view), @@ -290,7 +290,7 @@ impl TwoThirdsMajority { } } - pub fn block_hash(&self) -> Option { + pub fn block_hash(&self) -> Option { match self { TwoThirdsMajority::Empty => None, TwoThirdsMajority::Lock(_, block_hash) => Some(*block_hash), @@ -301,21 +301,21 @@ impl TwoThirdsMajority { #[derive(Debug, PartialEq)] pub enum Proposal { - ProposalReceived(H256, Bytes, SchnorrSignature), - ProposalImported(H256), + ProposalReceived(BlockHash, Bytes, SchnorrSignature), + ProposalImported(BlockHash), None, } impl Proposal { - pub fn new_received(hash: H256, block: Bytes, signature: SchnorrSignature) -> Self { + pub fn new_received(hash: BlockHash, block: Bytes, signature: SchnorrSignature) -> Self { Proposal::ProposalReceived(hash, block, signature) } - pub fn new_imported(hash: H256) -> Self { + pub fn new_imported(hash: BlockHash) -> Self { Proposal::ProposalImported(hash) } - pub fn block_hash(&self) -> Option { + pub fn block_hash(&self) -> Option { match self { Proposal::ProposalReceived(hash, ..) => Some(*hash), Proposal::ProposalImported(hash) => Some(*hash), @@ -323,7 +323,7 @@ impl Proposal { } } - pub fn imported_block_hash(&self) -> Option { + pub fn imported_block_hash(&self) -> Option { match self { Proposal::ProposalReceived(..) => None, Proposal::ProposalImported(hash) => Some(*hash), diff --git a/core/src/consensus/tendermint/vote_collector.rs b/core/src/consensus/tendermint/vote_collector.rs index d93fef2e86..f96216fa66 100644 --- a/core/src/consensus/tendermint/vote_collector.rs +++ b/core/src/consensus/tendermint/vote_collector.rs @@ -18,7 +18,7 @@ use std::collections::{BTreeMap, HashMap}; use std::iter::Iterator; use ckey::SchnorrSignature; -use primitives::H256; +use ctypes::BlockHash; use rlp::{Encodable, RlpStream}; use super::stake::Action; @@ -34,7 +34,7 @@ pub struct VoteCollector { #[derive(Debug, Default)] struct StepCollector { voted: HashMap, - block_votes: HashMap, BTreeMap>, + block_votes: HashMap, BTreeMap>, messages: Vec, } @@ -87,7 +87,7 @@ impl StepCollector { } /// Count all votes for the given block hash at this round. - fn count_block(&self, block_hash: &Option) -> BitSet { + fn count_block(&self, block_hash: &Option) -> BitSet { let mut result = BitSet::new(); if let Some(votes) = self.block_votes.get(block_hash) { for index in votes.keys() { @@ -157,7 +157,7 @@ impl VoteCollector { pub fn round_signatures_and_indices( &self, round: &VoteStep, - block_hash: &H256, + block_hash: &BlockHash, ) -> (Vec, Vec) { self.votes .get(round) @@ -171,7 +171,7 @@ impl VoteCollector { /// Returns the first signature and the index of its signer for a given round and hash if exists. - pub fn round_signature(&self, round: &VoteStep, block_hash: &H256) -> Option { + pub fn round_signature(&self, round: &VoteStep, block_hash: &BlockHash) -> Option { self.votes .get(round) .and_then(|c| c.block_votes.get(&Some(*block_hash))) @@ -187,7 +187,7 @@ impl VoteCollector { } } - pub fn block_round_votes(&self, round: &VoteStep, block_hash: &Option) -> BitSet { + pub fn block_round_votes(&self, round: &VoteStep, block_hash: &Option) -> BitSet { if let Some(votes) = self.votes.get(round) { votes.count_block(block_hash) } else { @@ -204,14 +204,14 @@ impl VoteCollector { } } - pub fn get_block_hashes(&self, round: &VoteStep) -> Vec { + pub fn get_block_hashes(&self, round: &VoteStep) -> Vec { self.votes .get(round) .map(|c| c.block_votes.keys().cloned().filter_map(|x| x).collect()) .unwrap_or_else(Vec::new) } - pub fn has_votes_for(&self, round: &VoteStep, block_hash: H256) -> bool { + pub fn has_votes_for(&self, round: &VoteStep, block_hash: BlockHash) -> bool { let votes = self .votes .get(round) diff --git a/core/src/consensus/tendermint/vote_regression_checker.rs b/core/src/consensus/tendermint/vote_regression_checker.rs index 5538c9ea45..c9aea69563 100644 --- a/core/src/consensus/tendermint/vote_regression_checker.rs +++ b/core/src/consensus/tendermint/vote_regression_checker.rs @@ -49,7 +49,7 @@ mod tests { let mut checker = VoteRegressionChecker::new(); let random_step = VoteStep::new(100, 10, Step::Prevote); - let random_hash = Some(H256::random()); + let random_hash = Some(H256::random().into()); assert!(checker.check(&VoteOn { step: random_step, block_hash: random_hash @@ -62,7 +62,7 @@ mod tests { let mut checker = VoteRegressionChecker::new(); let random_commit_step = VoteStep::new(100, 10, Step::Commit); - let random_hash = Some(H256::random()); + let random_hash = Some(H256::random().into()); checker.check(&VoteOn { step: random_commit_step, block_hash: random_hash, @@ -75,12 +75,12 @@ mod tests { checker.check(&VoteOn { step: VoteStep::new(100, 10, Step::Prevote), - block_hash: Some(H256::from(1)), + block_hash: Some(H256::from(1).into()), }); assert!(checker.check(&VoteOn { step: VoteStep::new(101, 10, Step::Prevote), - block_hash: Some(H256::from(2)) + block_hash: Some(H256::from(2).into()) })) } @@ -90,12 +90,12 @@ mod tests { checker.check(&VoteOn { step: VoteStep::new(100, 10, Step::Prevote), - block_hash: Some(H256::from(1)), + block_hash: Some(H256::from(1).into()), }); assert!(!checker.check(&VoteOn { step: VoteStep::new(99, 10, Step::Prevote), - block_hash: Some(H256::from(2)) + block_hash: Some(H256::from(2).into()) })) } @@ -105,12 +105,12 @@ mod tests { checker.check(&VoteOn { step: VoteStep::new(100, 10, Step::Prevote), - block_hash: Some(H256::from(1)), + block_hash: Some(H256::from(1).into()), }); assert!(checker.check(&VoteOn { step: VoteStep::new(100, 11, Step::Prevote), - block_hash: Some(H256::from(2)) + block_hash: Some(H256::from(2).into()) })) } @@ -120,12 +120,12 @@ mod tests { checker.check(&VoteOn { step: VoteStep::new(100, 10, Step::Prevote), - block_hash: Some(H256::from(1)), + block_hash: Some(H256::from(1).into()), }); assert!(!checker.check(&VoteOn { step: VoteStep::new(100, 9, Step::Prevote), - block_hash: Some(H256::from(2)) + block_hash: Some(H256::from(2).into()) })) } @@ -135,12 +135,12 @@ mod tests { checker.check(&VoteOn { step: VoteStep::new(100, 10, Step::Prevote), - block_hash: Some(H256::from(1)), + block_hash: Some(H256::from(1).into()), }); assert!(checker.check(&VoteOn { step: VoteStep::new(100, 10, Step::Precommit), - block_hash: Some(H256::from(2)) + block_hash: Some(H256::from(2).into()) })) } @@ -150,12 +150,12 @@ mod tests { checker.check(&VoteOn { step: VoteStep::new(100, 10, Step::Prevote), - block_hash: Some(H256::from(1)), + block_hash: Some(H256::from(1).into()), }); assert!(!checker.check(&VoteOn { step: VoteStep::new(100, 10, Step::Propose), - block_hash: Some(H256::from(2)) + block_hash: Some(H256::from(2).into()) })) } @@ -163,7 +163,7 @@ mod tests { fn test_allow_same_hash() { let mut checker = VoteRegressionChecker::new(); - let block_hash = Some(H256::random()); + let block_hash = Some(H256::random().into()); checker.check(&VoteOn { step: VoteStep::new(100, 10, Step::Prevote), block_hash, @@ -181,12 +181,12 @@ mod tests { checker.check(&VoteOn { step: VoteStep::new(100, 10, Step::Prevote), - block_hash: Some(H256::from(1)), + block_hash: Some(H256::from(1).into()), }); assert!(!checker.check(&VoteOn { step: VoteStep::new(100, 10, Step::Prevote), - block_hash: Some(H256::from(2)) + block_hash: Some(H256::from(2).into()) })) } } diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index c881cc443e..d2b7da7ef2 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -26,8 +26,8 @@ use cnetwork::{EventSender, NodeId}; use crossbeam_channel as crossbeam; use ctypes::transaction::{Action, Transaction}; use ctypes::util::unexpected::Mismatch; -use ctypes::{BlockNumber, Header}; -use primitives::{u256_from_u128, Bytes, H256, U256}; +use ctypes::{BlockHash, BlockNumber, Header}; +use primitives::{u256_from_u128, Bytes, U256}; use rlp::{Encodable, UntrustedRlp}; use super::super::BitSet; @@ -40,8 +40,7 @@ use super::types::{Height, Proposal, Step, TendermintSealView, TendermintState, use super::vote_collector::{DoubleVote, VoteCollector}; use super::vote_regression_checker::VoteRegressionChecker; use super::{ - BlockHash, ENGINE_TIMEOUT_BROADCAST_STEP_STATE, ENGINE_TIMEOUT_EMPTY_PROPOSAL, ENGINE_TIMEOUT_TOKEN_NONCE_BASE, - SEAL_FIELDS, + ENGINE_TIMEOUT_BROADCAST_STEP_STATE, ENGINE_TIMEOUT_EMPTY_PROPOSAL, ENGINE_TIMEOUT_TOKEN_NONCE_BASE, SEAL_FIELDS, }; use crate::account_provider::AccountProvider; use crate::block::*; @@ -102,12 +101,12 @@ struct Worker { pub enum Event { NewBlocks { - imported: Vec, - enacted: Vec, + imported: Vec, + enacted: Vec, }, GenerateSeal { block_number: Height, - parent_hash: H256, + parent_hash: BlockHash, result: crossbeam::Sender, }, ProposalGenerated(Box), @@ -130,7 +129,7 @@ pub enum Event { }, IsProposal { block_number: BlockNumber, - block_hash: H256, + block_hash: BlockHash, result: crossbeam::Sender, }, SetSigner { @@ -147,7 +146,7 @@ pub enum Event { StepState { token: NodeId, vote_step: VoteStep, - proposal: Option, + proposal: Option, lock_view: Option, known_votes: Box, result: crossbeam::Sender, @@ -384,14 +383,14 @@ impl Worker { } /// Get previous block hash to determine validator set - fn prev_block_hash(&self) -> H256 { + fn prev_block_hash(&self) -> BlockHash { self.prev_block_header_of_height(self.height) .expect("Height is increased when previous block is imported") .hash() } /// Get the index of the proposer of a block to check the new proposer is valid. - fn block_proposer_idx(&self, block_hash: H256) -> Option { + fn block_proposer_idx(&self, block_hash: BlockHash) -> Option { self.client().block_header(&BlockId::Hash(block_hash)).map(|header| { let proposer = header.author(); let parent = if header.number() == 0 { @@ -445,7 +444,7 @@ impl Worker { } /// Find the designated for the given view. - fn view_proposer(&self, prev_block_hash: &H256, view: View) -> Option
{ + fn view_proposer(&self, prev_block_hash: &BlockHash, view: View) -> Option
{ self.validators.next_block_proposer(prev_block_hash, view) } @@ -507,7 +506,7 @@ impl Worker { /// Check if address is a proposer for given view. fn check_view_proposer( &self, - parent: &H256, + parent: &BlockHash, height: Height, view: View, address: &Address, @@ -526,7 +525,7 @@ impl Worker { } /// Check if current signer is the current proposer. - fn is_signer_proposer(&self, bh: &H256) -> bool { + fn is_signer_proposer(&self, bh: &BlockHash) -> bool { self.view_proposer(bh, self.view).map_or(false, |proposer| self.signer.is_address(&proposer)) } @@ -534,7 +533,7 @@ impl Worker { message.on.step.is_step(self.height, self.view, self.step.to_step()) } - fn is_authority(&self, prev_hash: &H256, address: &Address) -> bool { + fn is_authority(&self, prev_hash: &BlockHash, address: &Address) -> bool { self.validators.contains_address(&prev_hash, address) } @@ -558,7 +557,7 @@ impl Worker { self.validators.check_enough_votes(&parent_hash, &aligned_votes).is_ok() } - fn has_enough_precommit_votes(&self, block_hash: H256) -> bool { + fn has_enough_precommit_votes(&self, block_hash: BlockHash) -> bool { let vote_step = VoteStep::new(self.height, self.view, Step::Precommit); let votes = self.votes.block_round_votes(&vote_step, &Some(block_hash)); self.validators.check_enough_votes(&self.prev_block_hash(), &votes).is_ok() @@ -573,7 +572,13 @@ impl Worker { .unwrap(); } - fn broadcast_state(&self, vote_step: VoteStep, proposal: Option, lock_view: Option, votes: &BitSet) { + fn broadcast_state( + &self, + vote_step: VoteStep, + proposal: Option, + lock_view: Option, + votes: &BitSet, + ) { self.extension .send(network::Event::BroadcastState { vote_step, @@ -602,7 +607,7 @@ impl Worker { .unwrap(); } - fn update_sealing(&self, parent_block_hash: H256) { + fn update_sealing(&self, parent_block_hash: BlockHash) { self.client().update_sealing(BlockId::Hash(parent_block_hash), true); } @@ -815,7 +820,11 @@ impl Worker { } } - fn locked_proposal_block(&self, locked_view: View, locked_proposal_hash: H256) -> Result { + fn locked_proposal_block( + &self, + locked_view: View, + locked_proposal_hash: BlockHash, + ) -> Result { let vote_step = VoteStep::new(self.height, locked_view, Step::Propose); let received_locked_block = self.votes.has_votes_for(&vote_step, locked_proposal_hash); @@ -1058,7 +1067,7 @@ impl Worker { SEAL_FIELDS } - fn generate_seal(&self, height: Height, parent_hash: H256) -> Seal { + fn generate_seal(&self, height: Height, parent_hash: BlockHash) -> Seal { // Block is received from other nodes while creating a block if height < self.height { return Seal::None @@ -1466,7 +1475,7 @@ impl Worker { } } - fn is_proposal(&self, block_number: BlockNumber, block_hash: H256) -> bool { + fn is_proposal(&self, block_number: BlockNumber, block_hash: BlockHash) -> bool { if self.height > block_number { return false } @@ -1595,7 +1604,7 @@ impl Worker { self.signer.public().and_then(|public| self.validators.get_index(&parent, public)) } - fn new_blocks(&mut self, imported: Vec, enacted: Vec) { + fn new_blocks(&mut self, imported: Vec, enacted: Vec) { let c = match self.client.upgrade() { Some(client) => client, None => { @@ -1825,7 +1834,7 @@ impl Worker { &self, token: &NodeId, peer_vote_step: VoteStep, - peer_proposal: Option, + peer_proposal: Option, peer_lock_view: Option, peer_known_votes: BitSet, result: crossbeam::Sender, diff --git a/core/src/consensus/validator_set/dynamic_validator.rs b/core/src/consensus/validator_set/dynamic_validator.rs index b9b95a09c4..c440295365 100644 --- a/core/src/consensus/validator_set/dynamic_validator.rs +++ b/core/src/consensus/validator_set/dynamic_validator.rs @@ -18,8 +18,8 @@ use std::sync::{Arc, Weak}; use ckey::{public_to_address, Address, Public}; use ctypes::util::unexpected::OutOfBounds; +use ctypes::BlockHash; use parking_lot::RwLock; -use primitives::H256; use super::{RoundRobinValidator, ValidatorSet}; use crate::client::ConsensusClient; @@ -41,7 +41,7 @@ impl DynamicValidator { } } - fn validators(&self, parent: H256) -> Option> { + fn validators(&self, parent: BlockHash) -> Option> { let client: Arc = self.client.read().as_ref().and_then(Weak::upgrade).expect("Client is not initialized"); let block_id = parent.into(); @@ -64,11 +64,11 @@ impl DynamicValidator { } } - fn validators_pubkey(&self, parent: H256) -> Option> { + fn validators_pubkey(&self, parent: BlockHash) -> Option> { self.validators(parent).map(|validators| validators.into_iter().map(|val| *val.pubkey()).collect()) } - pub fn proposer_index(&self, parent: H256, prev_proposer_index: usize, proposed_view: usize) -> usize { + pub fn proposer_index(&self, parent: BlockHash, prev_proposer_index: usize, proposed_view: usize) -> usize { if let Some(validators) = self.validators(parent) { let num_validators = validators.len(); proposed_view % num_validators @@ -80,7 +80,7 @@ impl DynamicValidator { } impl ValidatorSet for DynamicValidator { - fn contains(&self, parent: &H256, public: &Public) -> bool { + fn contains(&self, parent: &BlockHash, public: &Public) -> bool { if let Some(validators) = self.validators_pubkey(*parent) { validators.into_iter().any(|pubkey| pubkey == *public) } else { @@ -88,7 +88,7 @@ impl ValidatorSet for DynamicValidator { } } - fn contains_address(&self, parent: &H256, address: &Address) -> bool { + fn contains_address(&self, parent: &BlockHash, address: &Address) -> bool { if let Some(validators) = self.validators_pubkey(*parent) { validators.into_iter().any(|pubkey| public_to_address(&pubkey) == *address) } else { @@ -96,7 +96,7 @@ impl ValidatorSet for DynamicValidator { } } - fn get(&self, parent: &H256, index: usize) -> Public { + fn get(&self, parent: &BlockHash, index: usize) -> Public { if let Some(validators) = self.validators_pubkey(*parent) { let n_validators = validators.len(); *validators.get(index % n_validators).unwrap() @@ -105,7 +105,7 @@ impl ValidatorSet for DynamicValidator { } } - fn get_index(&self, parent: &H256, public: &Public) -> Option { + fn get_index(&self, parent: &BlockHash, public: &Public) -> Option { if let Some(validators) = self.validators_pubkey(*parent) { validators.into_iter().enumerate().find(|(_index, pubkey)| pubkey == public).map(|(index, _)| index) } else { @@ -113,7 +113,7 @@ impl ValidatorSet for DynamicValidator { } } - fn get_index_by_address(&self, parent: &H256, address: &Address) -> Option { + fn get_index_by_address(&self, parent: &BlockHash, address: &Address) -> Option { if let Some(validators) = self.validators_pubkey(*parent) { validators .into_iter() @@ -125,7 +125,7 @@ impl ValidatorSet for DynamicValidator { } } - fn next_block_proposer(&self, parent: &H256, view: u64) -> Option
{ + fn next_block_proposer(&self, parent: &BlockHash, view: u64) -> Option
{ if let Some(validators) = self.validators_pubkey(*parent) { let n_validators = validators.len(); let index = view as usize % n_validators; @@ -135,7 +135,7 @@ impl ValidatorSet for DynamicValidator { } } - fn count(&self, parent: &H256) -> usize { + fn count(&self, parent: &BlockHash) -> usize { if let Some(validators) = self.validators(*parent) { validators.len() } else { @@ -143,7 +143,7 @@ impl ValidatorSet for DynamicValidator { } } - fn check_enough_votes(&self, parent: &H256, votes: &BitSet) -> Result<(), EngineError> { + fn check_enough_votes(&self, parent: &BlockHash, votes: &BitSet) -> Result<(), EngineError> { if let Some(validators) = self.validators(*parent) { let mut voted_delegation = 0u64; let n_validators = validators.len(); @@ -181,7 +181,7 @@ impl ValidatorSet for DynamicValidator { *client_lock = Some(client); } - fn addresses(&self, parent: &H256) -> Vec
{ + fn addresses(&self, parent: &BlockHash) -> Vec
{ if let Some(validators) = self.validators_pubkey(*parent) { validators.iter().map(public_to_address).collect() } else { diff --git a/core/src/consensus/validator_set/mod.rs b/core/src/consensus/validator_set/mod.rs index b86f8d9d14..ba8127fac3 100644 --- a/core/src/consensus/validator_set/mod.rs +++ b/core/src/consensus/validator_set/mod.rs @@ -17,7 +17,7 @@ use std::sync::Weak; use ckey::{Address, Public}; -use primitives::H256; +use ctypes::BlockHash; use self::validator_list::RoundRobinValidator; use super::BitSet; @@ -33,29 +33,29 @@ pub use self::dynamic_validator::DynamicValidator; pub trait ValidatorSet: Send + Sync { /// Checks if a given public key is a validator, /// using underlying, default call mechanism. - fn contains(&self, parent: &H256, public: &Public) -> bool; + fn contains(&self, parent: &BlockHash, public: &Public) -> bool; /// Checks if a given address is a validator. - fn contains_address(&self, parent: &H256, address: &Address) -> bool; + fn contains_address(&self, parent: &BlockHash, address: &Address) -> bool; /// Draws a validator from index modulo number of validators. - fn get(&self, parent: &H256, index: usize) -> Public; + fn get(&self, parent: &BlockHash, index: usize) -> Public; /// Draws a validator from nonce modulo number of validators. - fn get_index(&self, parent: &H256, public: &Public) -> Option; + fn get_index(&self, parent: &BlockHash, public: &Public) -> Option; /// Draws a validator index from validator address. - fn get_index_by_address(&self, parent: &H256, address: &Address) -> Option; + fn get_index_by_address(&self, parent: &BlockHash, address: &Address) -> Option; - fn next_block_proposer(&self, parent: &H256, view: u64) -> Option
; + fn next_block_proposer(&self, parent: &BlockHash, view: u64) -> Option
; /// Returns the current number of validators. - fn count(&self, parent: &H256) -> usize; + fn count(&self, parent: &BlockHash) -> usize; - fn check_enough_votes(&self, parent: &H256, votes: &BitSet) -> Result<(), EngineError>; + fn check_enough_votes(&self, parent: &BlockHash, votes: &BitSet) -> Result<(), EngineError>; /// Allows blockchain state access. fn register_client(&self, _client: Weak) {} - fn addresses(&self, _parent: &H256) -> Vec
; + fn addresses(&self, _parent: &BlockHash) -> Vec
; } diff --git a/core/src/consensus/validator_set/validator_list.rs b/core/src/consensus/validator_set/validator_list.rs index cdec5664e5..2c56efd72b 100644 --- a/core/src/consensus/validator_set/validator_list.rs +++ b/core/src/consensus/validator_set/validator_list.rs @@ -19,8 +19,8 @@ use std::sync::{Arc, Weak}; use ckey::{public_to_address, Address, Public}; use ctypes::util::unexpected::OutOfBounds; +use ctypes::BlockHash; use parking_lot::RwLock; -use primitives::H256; use super::super::BitSet; use super::ValidatorSet; @@ -47,29 +47,29 @@ impl RoundRobinValidator { } impl ValidatorSet for RoundRobinValidator { - fn contains(&self, _bh: &H256, public: &Public) -> bool { + fn contains(&self, _bh: &BlockHash, public: &Public) -> bool { self.validators.contains(public) } - fn contains_address(&self, _bh: &H256, address: &Address) -> bool { + fn contains_address(&self, _bh: &BlockHash, address: &Address) -> bool { self.addresses.contains(address) } - fn get(&self, _bh: &H256, index: usize) -> Public { + fn get(&self, _bh: &BlockHash, index: usize) -> Public { let validator_n = self.validators.len(); assert_ne!(0, validator_n, "Cannot operate with an empty validator set."); *self.validators.get(index % validator_n).expect("There are validator_n authorities; taking number modulo validator_n gives number in validator_n range; qed") } - fn get_index(&self, _bh: &H256, public: &Public) -> Option { + fn get_index(&self, _bh: &BlockHash, public: &Public) -> Option { self.validators.iter().position(|v| v == public) } - fn get_index_by_address(&self, _bh: &H256, address: &Address) -> Option { + fn get_index_by_address(&self, _bh: &BlockHash, address: &Address) -> Option { self.validators.iter().position(|v| public_to_address(v) == *address) } - fn next_block_proposer(&self, parent: &H256, view: u64) -> Option
{ + fn next_block_proposer(&self, parent: &BlockHash, view: u64) -> Option
{ let client: Arc = self.client.read().as_ref().and_then(Weak::upgrade)?; client.block_header(&BlockId::from(*parent)).map(|header| { let proposer = header.author(); @@ -82,11 +82,11 @@ impl ValidatorSet for RoundRobinValidator { }) } - fn count(&self, _bh: &H256) -> usize { + fn count(&self, _bh: &BlockHash) -> usize { self.validators.len() } - fn check_enough_votes(&self, parent: &H256, votes: &BitSet) -> Result<(), EngineError> { + fn check_enough_votes(&self, parent: &BlockHash, votes: &BitSet) -> Result<(), EngineError> { let validator_count = self.count(parent); let voted = votes.count(); if voted * 3 > validator_count * 2 { @@ -105,7 +105,7 @@ impl ValidatorSet for RoundRobinValidator { *self.client.write() = Some(client); } - fn addresses(&self, _parent: &H256) -> Vec
{ + fn addresses(&self, _parent: &BlockHash) -> Vec
{ self.validators.iter().map(public_to_address).collect() } } diff --git a/core/src/encoded.rs b/core/src/encoded.rs index 06f592c0fe..375a6505fd 100644 --- a/core/src/encoded.rs +++ b/core/src/encoded.rs @@ -25,7 +25,7 @@ use ccrypto::blake256; use ckey::Address; -use ctypes::{BlockNumber, Header as FullHeader}; +use ctypes::{BlockHash, BlockNumber, Header as FullHeader}; use primitives::{H256, U256}; use rlp::Rlp; @@ -71,12 +71,12 @@ impl Header { // forwarders to borrowed view. impl Header { /// Returns the header hash. - pub fn hash(&self) -> H256 { - blake256(&self.0) + pub fn hash(&self) -> BlockHash { + blake256(&self.0).into() } /// Returns the parent hash. - pub fn parent_hash(&self) -> H256 { + pub fn parent_hash(&self) -> BlockHash { self.view().parent_hash() } @@ -230,12 +230,12 @@ impl Block { // forwarders to borrowed header view. impl Block { /// Returns the header hash. - pub fn hash(&self) -> H256 { + pub fn hash(&self) -> BlockHash { self.header_view().hash() } /// Returns the parent hash. - pub fn parent_hash(&self) -> H256 { + pub fn parent_hash(&self) -> BlockHash { self.header_view().parent_hash() } diff --git a/core/src/error.rs b/core/src/error.rs index 47458b2d52..77ff4486d6 100644 --- a/core/src/error.rs +++ b/core/src/error.rs @@ -22,7 +22,7 @@ use cmerkle::TrieError; use cstate::StateError; use ctypes::errors::{HistoryError, RuntimeError, SyntaxError}; use ctypes::util::unexpected::{Mismatch, OutOfBounds}; -use ctypes::BlockNumber; +use ctypes::{BlockHash, BlockNumber}; use primitives::{H256, U256}; use util_error::UtilError; @@ -104,7 +104,7 @@ pub enum BlockError { TemporarilyInvalid(OutOfBounds), /// Parent hash field of header is invalid; this is an invalid error indicating a logic flaw in the codebase. /// TODO: remove and favour an assert!/panic!. - InvalidParentHash(Mismatch), + InvalidParentHash(Mismatch), /// Number field of header is invalid. InvalidNumber(Mismatch), /// Block number isn't sensible. @@ -112,7 +112,7 @@ pub enum BlockError { /// Too many transactions from a particular address. TooManyTransactions(Address), /// Parent given is unknown. - UnknownParent(H256), + UnknownParent(BlockHash), /// Body size limit is exceeded. BodySizeIsTooBig, } diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index 09a8b5ee63..f4795b50ff 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -26,7 +26,7 @@ use ckey::{public_to_address, Address, Password, PlatformAddress, Public}; use cstate::{FindActionHandler, TopLevelState}; use ctypes::errors::{HistoryError, RuntimeError}; use ctypes::transaction::{Action, IncompleteTransaction, Timelock}; -use ctypes::{BlockNumber, Header}; +use ctypes::{BlockHash, BlockNumber, Header}; use cvm::ChainTimeInfo; use kvdb::KeyValueDB; use parking_lot::{Mutex, RwLock}; @@ -442,10 +442,10 @@ impl Miner { "prepare_work: Pushing a new, refreshed or borrowed pending {}...", block.block().header().hash() ); - let pow_hash = block.block().header().hash(); + let pow_hash = *block.block().header().hash(); let number = block.block().header().number(); let score = *block.block().header().score(); - let is_new = original_work_hash.map_or(true, |h| block.block().header().hash() != h); + let is_new = original_work_hash.map_or(true, |h| *block.block().header().hash() != h); sealing_work.queue.push(block); // If push notifications are enabled we assume all work items are used. if !self.notifiers.read().is_empty() && is_new { @@ -483,7 +483,7 @@ impl Miner { let (transactions, mut open_block, original_work_hash, block_number) = { let sealing_work = self.sealing_work.lock(); - let last_work_hash = sealing_work.queue.peek_last_ref().map(|pb| pb.block().header().hash()); + let last_work_hash = sealing_work.queue.peek_last_ref().map(|pb| *pb.block().header().hash()); ctrace!(MINER, "prepare_block: No existing work - making new block"); let params = self.params.read().clone(); let open_block = chain.prepare_open_block(parent_block_id, params.author, params.extra_data); @@ -774,10 +774,10 @@ impl MinerService for Miner { fn chain_new_blocks( &self, chain: &C, - _imported: &[H256], - _invalid: &[H256], - _enacted: &[H256], - retracted: &[H256], + _imported: &[BlockHash], + _invalid: &[BlockHash], + _enacted: &[BlockHash], + retracted: &[BlockHash], ) where C: AccountData + BlockChainTrait + BlockProducer + EngineInfo + ImportBlock, { ctrace!(MINER, "chain_new_blocks"); @@ -937,8 +937,8 @@ impl MinerService for Miner { } } - fn submit_seal(&self, chain: &C, block_hash: H256, seal: Vec) -> Result<(), Error> { - let result = if let Some(b) = self.sealing_work.lock().queue.take_used_if(|b| b.hash() == block_hash) { + fn submit_seal(&self, chain: &C, block_hash: BlockHash, seal: Vec) -> Result<(), Error> { + let result = if let Some(b) = self.sealing_work.lock().queue.take_used_if(|b| b.hash() == *block_hash) { ctrace!( MINER, "Submitted block {}={}={} with seal {:?}", diff --git a/core/src/miner/mod.rs b/core/src/miner/mod.rs index 1922977013..867ec2a4eb 100644 --- a/core/src/miner/mod.rs +++ b/core/src/miner/mod.rs @@ -28,6 +28,7 @@ use std::ops::Range; use ckey::{Address, Password, PlatformAddress}; use cstate::{FindActionHandler, TopStateView}; use ctypes::transaction::IncompleteTransaction; +use ctypes::BlockHash; use cvm::ChainTimeInfo; use primitives::{Bytes, H256}; @@ -73,8 +74,14 @@ pub trait MinerService: Send + Sync { fn set_transactions_limit(&self, limit: usize); /// Called when blocks are imported to chain, updates transactions queue. - fn chain_new_blocks(&self, chain: &C, imported: &[H256], invalid: &[H256], enacted: &[H256], retracted: &[H256]) - where + fn chain_new_blocks( + &self, + chain: &C, + imported: &[BlockHash], + invalid: &[BlockHash], + enacted: &[BlockHash], + retracted: &[BlockHash], + ) where C: AccountData + BlockChainTrait + BlockProducer + EngineInfo + ImportBlock; /// PoW chain - can produce work package @@ -102,7 +109,7 @@ pub trait MinerService: Send + Sync { /// Submit `seal` as a valid solution for the header of `pow_hash`. /// Will check the seal, but not actually insert the block into the chain. - fn submit_seal(&self, chain: &C, pow_hash: H256, seal: Vec) -> Result<(), Error>; + fn submit_seal(&self, chain: &C, pow_hash: BlockHash, seal: Vec) -> Result<(), Error>; /// Get the sealing work package and if `Some`, apply some transform. fn map_sealing_work(&self, client: &C, f: F) -> Option diff --git a/core/src/miner/stratum.rs b/core/src/miner/stratum.rs index 167c9525d4..ce61e49240 100644 --- a/core/src/miner/stratum.rs +++ b/core/src/miner/stratum.rs @@ -60,7 +60,7 @@ impl JobDispatcher for StratumJobDispatcher { return Err(StratumServiceError::InternalError) } - match self.miner.submit_seal(&*self.client, pow_hash, seal) { + match self.miner.submit_seal(&*self.client, pow_hash.into(), seal) { Ok(_) => Ok(()), Err(e) => { cwarn!(STRATUM, "submit_seal error: {:?}", e); diff --git a/core/src/scheme/genesis.rs b/core/src/scheme/genesis.rs index 30623f00d9..cb03c27d5a 100644 --- a/core/src/scheme/genesis.rs +++ b/core/src/scheme/genesis.rs @@ -17,6 +17,7 @@ use ccrypto::BLAKE_NULL_RLP; use cjson; use ckey::{Address, PlatformAddress}; +use ctypes::BlockHash; use primitives::{Bytes, H256, U256}; use super::seal::Seal; @@ -32,7 +33,7 @@ pub struct Genesis { /// Timestamp. pub timestamp: u64, /// Parent hash. - pub parent_hash: H256, + pub parent_hash: BlockHash, /// Transactions root. pub transactions_root: H256, /// State root. @@ -48,7 +49,7 @@ impl From for Genesis { score: g.score.into(), author: g.author.map_or_else(Address::default, PlatformAddress::into_address), timestamp: g.timestamp.map_or(0, Into::into), - parent_hash: g.parent_hash.map_or_else(H256::zero, Into::into), + parent_hash: g.parent_hash.map_or_else(H256::zero, Into::into).into(), transactions_root: g.transactions_root.map_or_else(|| BLAKE_NULL_RLP, Into::into), state_root: g.state_root.map(Into::into), extra_data: g.extra_data.map_or_else(Vec::new, Into::into), diff --git a/core/src/scheme/scheme.rs b/core/src/scheme/scheme.rs index 69a425a5a5..68d8aefe8d 100644 --- a/core/src/scheme/scheme.rs +++ b/core/src/scheme/scheme.rs @@ -23,7 +23,7 @@ use ckey::Address; use cmerkle::TrieFactory; use cstate::{Metadata, MetadataAddress, Shard, ShardAddress, StateDB, StateResult, StateWithCache, TopLevelState}; use ctypes::errors::SyntaxError; -use ctypes::{CommonParams, Header, ShardId}; +use ctypes::{BlockHash, CommonParams, Header, ShardId}; use hashdb::{AsHashDB, HashDB}; use parking_lot::RwLock; use primitives::{Bytes, H256, U256}; @@ -52,7 +52,7 @@ pub struct Scheme { pub nodes: Vec, /// The genesis block's parent hash field. - pub parent_hash: H256, + pub parent_hash: BlockHash, /// The genesis block's author field. pub author: Address, /// The genesis block's score field. diff --git a/core/src/service.rs b/core/src/service.rs index 78e3a1e4ef..52e956d522 100644 --- a/core/src/service.rs +++ b/core/src/service.rs @@ -19,8 +19,9 @@ use std::sync::Arc; use cio::{IoContext, IoHandler, IoHandlerResult, IoService}; use cnetwork::NodeId; use ctimer::TimerApi; +use ctypes::BlockHash; use kvdb::KeyValueDB; -use primitives::{Bytes, H256}; +use primitives::Bytes; use crate::client::{Client, ClientConfig}; use crate::error::Error; @@ -80,7 +81,7 @@ pub enum ClientIoMessage { }, /// Update the best block by the given hash /// Only used in Tendermint - UpdateBestAsCommitted(H256), + UpdateBestAsCommitted(BlockHash), } /// IO interface for the Client handler diff --git a/core/src/tests/helpers.rs b/core/src/tests/helpers.rs index 003c0d45dc..31e79a43c9 100644 --- a/core/src/tests/helpers.rs +++ b/core/src/tests/helpers.rs @@ -15,8 +15,8 @@ // along with this program. If not, see . use cstate::StateDB; -use ctypes::Header; -use primitives::{Bytes, H256, U256}; +use ctypes::{BlockHash, Header}; +use primitives::{Bytes, U256}; use rlp::{self, RlpStream}; use crate::scheme::Scheme; @@ -46,7 +46,7 @@ pub fn get_good_dummy_block() -> Bytes { bytes } -pub fn get_good_dummy_block_hash() -> (H256, Bytes) { +pub fn get_good_dummy_block_hash() -> (BlockHash, Bytes) { let mut block_header = Header::new(); let test_scheme = Scheme::new_test(); block_header.set_score(U256::from(0x20000)); diff --git a/core/src/transaction.rs b/core/src/transaction.rs index 5820a3ff5f..2749e12955 100644 --- a/core/src/transaction.rs +++ b/core/src/transaction.rs @@ -20,7 +20,7 @@ use ccrypto::blake256; use ckey::{self, public_to_address, recover, sign, Private, Public, Signature}; use ctypes::errors::SyntaxError; use ctypes::transaction::Transaction; -use ctypes::{BlockNumber, CommonParams}; +use ctypes::{BlockHash, BlockNumber, CommonParams}; use primitives::H256; use rlp::{self, DecoderError, Encodable, RlpStream, UntrustedRlp}; @@ -231,7 +231,7 @@ pub struct LocalizedTransaction { /// Block number. pub block_number: BlockNumber, /// Block hash. - pub block_hash: H256, + pub block_hash: BlockHash, /// Transaction index within block. pub transaction_index: usize, /// Cached public diff --git a/core/src/types/ids.rs b/core/src/types/ids.rs index 66b4e5b22f..1aa6ca8f5d 100644 --- a/core/src/types/ids.rs +++ b/core/src/types/ids.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use ctypes::BlockNumber; +use ctypes::{BlockHash, BlockNumber}; use primitives::H256; /// Uniquely identifies block. @@ -22,7 +22,7 @@ use primitives::H256; pub enum BlockId { /// Block's blake256. /// Querying by hash is always faster. - Hash(H256), + Hash(BlockHash), /// Block number within canon blockchain. Number(BlockNumber), /// Earliest block (genesis). @@ -33,8 +33,8 @@ pub enum BlockId { ParentOfLatest, } -impl From for BlockId { - fn from(hash: H256) -> Self { +impl From for BlockId { + fn from(hash: BlockHash) -> Self { BlockId::Hash(hash) } } diff --git a/core/src/verification/queue/kind.rs b/core/src/verification/queue/kind.rs index 7140d38a5b..5e42af309a 100644 --- a/core/src/verification/queue/kind.rs +++ b/core/src/verification/queue/kind.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use primitives::{H256, U256}; +use ctypes::BlockHash; +use primitives::U256; use rlp::*; pub use self::blocks::Blocks; @@ -27,10 +28,10 @@ use crate::service::ClientIoMessage; /// Something which can produce a hash and a parent hash. pub trait BlockLike { /// Get the hash of this item. - fn hash(&self) -> H256; + fn hash(&self) -> BlockHash; /// Get the hash of this item's parent. - fn parent_hash(&self) -> H256; + fn parent_hash(&self) -> BlockHash; /// Get the score of this item. fn score(&self) -> U256; @@ -84,8 +85,8 @@ pub trait Kind: 'static + Sized + Send + Sync { /// Verification for headers. pub mod headers { - use ctypes::Header; - use primitives::{H256, U256}; + use ctypes::{BlockHash, Header}; + use primitives::U256; use super::super::super::verification::verify_header_basic; use super::{BlockLike, Kind}; @@ -95,11 +96,11 @@ pub mod headers { use verification::verify_header_with_engine; impl BlockLike for Header { - fn hash(&self) -> H256 { + fn hash(&self) -> BlockHash { self.hash() } - fn parent_hash(&self) -> H256 { + fn parent_hash(&self) -> BlockHash { *self.parent_hash() } @@ -147,8 +148,8 @@ pub mod headers { /// The blocks verification module. pub mod blocks { - use ctypes::Header; - use primitives::{Bytes, H256, U256}; + use ctypes::{BlockHash, Header}; + use primitives::{Bytes, U256}; use super::super::super::verification::{ verify_block_basic, verify_block_seal, verify_header_with_engine, PreverifiedBlock, @@ -225,11 +226,11 @@ pub mod blocks { } impl BlockLike for Unverified { - fn hash(&self) -> H256 { + fn hash(&self) -> BlockHash { self.header.hash() } - fn parent_hash(&self) -> H256 { + fn parent_hash(&self) -> BlockHash { *self.header.parent_hash() } @@ -239,11 +240,11 @@ pub mod blocks { } impl BlockLike for PreverifiedBlock { - fn hash(&self) -> H256 { + fn hash(&self) -> BlockHash { self.header.hash() } - fn parent_hash(&self) -> H256 { + fn parent_hash(&self) -> BlockHash { *self.header.parent_hash() } diff --git a/core/src/verification/queue/mod.rs b/core/src/verification/queue/mod.rs index 451c51c787..dc8cdccb5b 100644 --- a/core/src/verification/queue/mod.rs +++ b/core/src/verification/queue/mod.rs @@ -23,8 +23,9 @@ use std::sync::{Arc, Condvar as SCondvar, Mutex as SMutex}; use std::thread::{self, JoinHandle}; use cio::IoChannel; +use ctypes::BlockHash; use parking_lot::{Mutex, RwLock}; -use primitives::{H256, U256}; +use primitives::U256; use self::kind::{BlockLike, Kind, MemUsage}; use crate::consensus::CodeChainEngine; @@ -65,7 +66,7 @@ impl Default for Config { pub struct VerificationQueue { engine: Arc, verification: Arc>, - processing: RwLock>, // hash to score + processing: RwLock>, // hash to score deleting: Arc, ready_signal: Arc, total_score: RwLock, @@ -300,7 +301,7 @@ impl VerificationQueue { fn drain_verifying( verifying: &mut VecDeque>, verified: &mut VecDeque, - bad: &mut HashSet, + bad: &mut HashSet, sizes: &Sizes, ) { let mut removed_size = 0; @@ -324,7 +325,7 @@ impl VerificationQueue { } /// Check if the item is currently in the queue - pub fn status(&self, hash: &H256) -> Status { + pub fn status(&self, hash: &BlockHash) -> Status { if self.processing.read().contains_key(hash) { return Status::Queued } @@ -335,7 +336,7 @@ impl VerificationQueue { } /// Add a block to the queue. - pub fn import(&self, input: K::Input) -> Result { + pub fn import(&self, input: K::Input) -> Result { let h = input.hash(); { if self.processing.read().contains_key(&h) { @@ -397,7 +398,7 @@ impl VerificationQueue { /// Mark given item as processed. /// Returns true if the queue becomes empty. - pub fn mark_as_good(&self, hashes: &[H256]) -> bool { + pub fn mark_as_good(&self, hashes: &[BlockHash]) -> bool { if hashes.is_empty() { return self.processing.read().is_empty() } @@ -414,7 +415,7 @@ impl VerificationQueue { /// Mark given item and all its children as bad. pauses verification /// until complete. - pub fn mark_as_bad(&self, hashes: &[H256]) { + pub fn mark_as_bad(&self, hashes: &[BlockHash]) { if hashes.is_empty() { return } @@ -509,7 +510,7 @@ struct Verification { unverified: Mutex>, verifying: Mutex>>, verified: Mutex>, - bad: Mutex>, + bad: Mutex>, sizes: Sizes, check_seal: bool, #[allow(dead_code)] @@ -519,7 +520,7 @@ struct Verification { /// An item which is in the process of being verified. pub struct Verifying { - hash: H256, + hash: BlockHash, output: Option, } diff --git a/core/src/views/block.rs b/core/src/views/block.rs index e4f93b4950..c10ee7e188 100644 --- a/core/src/views/block.rs +++ b/core/src/views/block.rs @@ -15,7 +15,7 @@ // along with this program. If not, see . use ccrypto::blake256; -use ctypes::Header; +use ctypes::{BlockHash, Header}; use primitives::H256; use rlp::Rlp; @@ -43,7 +43,7 @@ impl<'a> BlockView<'a> { } /// Block header hash. - pub fn hash(&self) -> H256 { + pub fn hash(&self) -> BlockHash { self.header_view().hash() } diff --git a/core/src/views/body.rs b/core/src/views/body.rs index e733f1e457..b6454cb28f 100644 --- a/core/src/views/body.rs +++ b/core/src/views/body.rs @@ -15,7 +15,7 @@ // along with this program. If not, see . use ccrypto::blake256; -use ctypes::BlockNumber; +use ctypes::{BlockHash, BlockNumber}; use primitives::H256; use rlp::Rlp; @@ -53,7 +53,11 @@ impl<'a> BodyView<'a> { } /// Return List of transactions with additional localization info. - pub fn localized_transactions(&self, block_hash: &H256, block_number: BlockNumber) -> Vec { + pub fn localized_transactions( + &self, + block_hash: &BlockHash, + block_number: BlockNumber, + ) -> Vec { self.transactions() .into_iter() .enumerate() @@ -90,7 +94,7 @@ impl<'a> BodyView<'a> { /// Returns localized transaction at given index. pub fn localized_transaction_at( &self, - block_hash: &H256, + block_hash: &BlockHash, block_number: BlockNumber, transaction_index: usize, ) -> Option { diff --git a/core/src/views/header.rs b/core/src/views/header.rs index 7cfb74057f..d5f23b47d2 100644 --- a/core/src/views/header.rs +++ b/core/src/views/header.rs @@ -16,7 +16,7 @@ use ccrypto::blake256; use ckey::Address; -use ctypes::BlockNumber; +use ctypes::{BlockHash, BlockNumber}; use primitives::{Bytes, H256, U256}; use rlp::{self, Rlp}; @@ -41,8 +41,8 @@ impl<'a> HeaderView<'a> { } /// Returns header hash. - pub fn hash(&self) -> H256 { - blake256(self.rlp.as_raw()) + pub fn hash(&self) -> BlockHash { + blake256(self.rlp.as_raw()).into() } /// Returns raw rlp. @@ -51,8 +51,8 @@ impl<'a> HeaderView<'a> { } /// Returns parent hash. - pub fn parent_hash(&self) -> H256 { - self.rlp.val_at(0) + pub fn parent_hash(&self) -> BlockHash { + self.rlp.val_at::(0) } /// Returns author. diff --git a/rpc/src/v1/impls/chain.rs b/rpc/src/v1/impls/chain.rs index addac3d980..414b44bf47 100644 --- a/rpc/src/v1/impls/chain.rs +++ b/rpc/src/v1/impls/chain.rs @@ -26,7 +26,7 @@ use cjson::uint::Uint; use ckey::{public_to_address, NetworkId, PlatformAddress, Public}; use cstate::FindActionHandler; use ctypes::transaction::{Action, ShardTransaction as ShardTransactionType}; -use ctypes::{BlockNumber, ShardId}; +use ctypes::{BlockHash, BlockNumber, ShardId}; use primitives::{Bytes as BytesArray, H160, H256}; use jsonrpc_core::Result; @@ -233,7 +233,7 @@ where }) } - fn get_block_hash(&self, block_number: u64) -> Result> { + fn get_block_hash(&self, block_number: u64) -> Result> { Ok(self.client.block_hash(&BlockId::Number(block_number))) } @@ -249,7 +249,7 @@ where })) } - fn get_block_by_hash(&self, block_hash: H256) -> Result> { + fn get_block_by_hash(&self, block_hash: BlockHash) -> Result> { let id = BlockId::Hash(block_hash); Ok(self.client.block(&id).map(|block| { let block = block.decode(); @@ -262,7 +262,7 @@ where })) } - fn get_block_transaction_count_by_hash(&self, block_hash: H256) -> Result> { + fn get_block_transaction_count_by_hash(&self, block_hash: BlockHash) -> Result> { Ok(self.client.block(&BlockId::Hash(block_hash)).map(|block| block.transactions_count())) } diff --git a/rpc/src/v1/impls/miner.rs b/rpc/src/v1/impls/miner.rs index 5278593fa5..bee179060d 100644 --- a/rpc/src/v1/impls/miner.rs +++ b/rpc/src/v1/impls/miner.rs @@ -19,8 +19,8 @@ use std::sync::Arc; use ccore::block::IsBlock; use ccore::{EngineClient, EngineInfo, MinerService, MiningBlockChainClient, TermInfo}; use cjson::bytes::Bytes; +use ctypes::BlockHash; use jsonrpc_core::Result; -use primitives::H256; use super::super::errors; use super::super::traits::Miner; @@ -67,7 +67,7 @@ where .unwrap_or_else(|| Err(errors::internal("No work found.", ""))) } - fn submit_work(&self, pow_hash: H256, seal: Vec) -> Result { + fn submit_work(&self, pow_hash: BlockHash, seal: Vec) -> Result { if !self.miner.can_produce_work_package() { cwarn!(MINER, "Cannot give work package - engine seals internally."); return Err(errors::no_work_required()) diff --git a/rpc/src/v1/traits/chain.rs b/rpc/src/v1/traits/chain.rs index 268d13b193..09b45fc621 100644 --- a/rpc/src/v1/traits/chain.rs +++ b/rpc/src/v1/traits/chain.rs @@ -17,7 +17,7 @@ use cjson::scheme::Params; use cjson::uint::Uint; use ckey::{NetworkId, PlatformAddress, Public}; -use ctypes::{BlockNumber, ShardId}; +use ctypes::{BlockHash, BlockNumber, ShardId}; use primitives::{Bytes as BytesArray, H160, H256}; use jsonrpc_core::Result; @@ -137,7 +137,7 @@ pub trait Chain { /// Gets the hash of the block with given number. #[rpc(name = "chain_getBlockHash")] - fn get_block_hash(&self, block_number: u64) -> Result>; + fn get_block_hash(&self, block_number: u64) -> Result>; /// Gets block with given number. #[rpc(name = "chain_getBlockByNumber")] @@ -145,11 +145,11 @@ pub trait Chain { /// Gets block with given hash. #[rpc(name = "chain_getBlockByHash")] - fn get_block_by_hash(&self, block_hash: H256) -> Result>; + fn get_block_by_hash(&self, block_hash: BlockHash) -> Result>; ///Gets the count of transactions in a block with given hash. #[rpc(name = "chain_getBlockTransactionCountByHash")] - fn get_block_transaction_count_by_hash(&self, block_hash: H256) -> Result>; + fn get_block_transaction_count_by_hash(&self, block_hash: BlockHash) -> Result>; ///Gets the minimum transaction fee of the given name. #[rpc(name = "chain_getMinTransactionFee")] diff --git a/rpc/src/v1/traits/miner.rs b/rpc/src/v1/traits/miner.rs index 79965bd450..ea204c4549 100644 --- a/rpc/src/v1/traits/miner.rs +++ b/rpc/src/v1/traits/miner.rs @@ -15,8 +15,8 @@ // along with this program. If not, see . use cjson::bytes::Bytes; +use ctypes::BlockHash; use jsonrpc_core::Result; -use primitives::H256; use super::super::types::Work; @@ -26,5 +26,5 @@ pub trait Miner { fn get_work(&self) -> Result; #[rpc(name = "miner_submitWork")] - fn submit_work(&self, pow_hash: H256, seal: Vec) -> Result; + fn submit_work(&self, pow_hash: BlockHash, seal: Vec) -> Result; } diff --git a/rpc/src/v1/types/block.rs b/rpc/src/v1/types/block.rs index 34655e059f..8798e753c1 100644 --- a/rpc/src/v1/types/block.rs +++ b/rpc/src/v1/types/block.rs @@ -16,7 +16,7 @@ use ccore::{Block as CoreBlock, LocalizedTransaction}; use ckey::{NetworkId, PlatformAddress}; -use ctypes::BlockNumber; +use ctypes::{BlockHash, BlockNumber}; use primitives::{H256, U256}; use super::Transaction; @@ -24,7 +24,7 @@ use super::Transaction; #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Block { - parent_hash: H256, + parent_hash: BlockHash, timestamp: u64, number: u64, author: PlatformAddress, @@ -37,7 +37,7 @@ pub struct Block { score: U256, seal: Vec>, - hash: H256, + hash: BlockHash, transactions: Vec, } @@ -77,5 +77,5 @@ impl Block { #[serde(rename_all = "camelCase")] pub struct BlockNumberAndHash { pub number: BlockNumber, - pub hash: H256, + pub hash: BlockHash, } diff --git a/rpc/src/v1/types/transaction.rs b/rpc/src/v1/types/transaction.rs index 6e0c25dbba..eabd150a8f 100644 --- a/rpc/src/v1/types/transaction.rs +++ b/rpc/src/v1/types/transaction.rs @@ -17,6 +17,7 @@ use ccore::{LocalizedTransaction, PendingSignedTransactions, SignedTransaction}; use cjson::uint::Uint; use ckey::{NetworkId, Signature}; +use ctypes::BlockHash; use primitives::H256; use super::ActionWithTracker; @@ -25,7 +26,7 @@ use super::ActionWithTracker; #[serde(rename_all = "camelCase")] pub struct Transaction { pub block_number: Option, - pub block_hash: Option, + pub block_hash: Option, pub transaction_index: Option, pub result: Option, pub seq: u64, diff --git a/sync/src/block/downloader/body.rs b/sync/src/block/downloader/body.rs index e9c1885f76..96a99f6b7d 100644 --- a/sync/src/block/downloader/body.rs +++ b/sync/src/block/downloader/body.rs @@ -17,15 +17,15 @@ use std::collections::{HashMap, HashSet}; use ccore::UnverifiedTransaction; -use ctypes::Header; +use ctypes::{BlockHash, Header}; use primitives::H256; use super::super::message::RequestMessage; #[derive(Clone)] struct Target { - hash: H256, - transaction_hash: H256, + hash: BlockHash, + parent_hash: BlockHash, transactions_root: H256, transaction_root: H256, } @@ -33,8 +33,8 @@ struct Target { #[derive(Default)] pub struct BodyDownloader { targets: Vec, - downloading: HashSet, - downloaded: HashMap>, + downloading: HashSet, + downloaded: HashMap>, } impl BodyDownloader { @@ -57,7 +57,7 @@ impl BodyDownloader { } } - pub fn import_bodies(&mut self, hashes: Vec, bodies: Vec>) { + pub fn import_bodies(&mut self, hashes: Vec, bodies: Vec>) { for (hash, body) in hashes.into_iter().zip(bodies) { if self.downloading.remove(&hash) { if body.is_empty() { @@ -76,13 +76,13 @@ impl BodyDownloader { cdebug!(SYNC, "Add download target: {}", header.hash()); self.targets.push(Target { hash: header.hash(), - transaction_hash: parent.hash(), + parent_hash: parent.hash(), transactions_root: *header.transactions_root(), transaction_root: *parent.transactions_root(), }); } - pub fn remove_target(&mut self, targets: &[H256]) { + pub fn remove_target(&mut self, targets: &[BlockHash]) { if targets.is_empty() { return } @@ -99,7 +99,7 @@ impl BodyDownloader { self.downloaded.shrink_to_fit(); } - pub fn reset_downloading(&mut self, hashes: &[H256]) { + pub fn reset_downloading(&mut self, hashes: &[BlockHash]) { cdebug!(SYNC, "Remove downloading by timeout {:?}", hashes); for hash in hashes { self.downloading.remove(&hash); @@ -107,7 +107,7 @@ impl BodyDownloader { self.downloading.shrink_to_fit(); } - pub fn drain(&mut self) -> Vec<(H256, Vec)> { + pub fn drain(&mut self) -> Vec<(BlockHash, Vec)> { let mut result = Vec::new(); for t in &self.targets { if let Some(body) = self.downloaded.remove(&t.hash) { diff --git a/sync/src/block/downloader/header.rs b/sync/src/block/downloader/header.rs index f1d2193ca6..963c2135e5 100644 --- a/sync/src/block/downloader/header.rs +++ b/sync/src/block/downloader/header.rs @@ -21,7 +21,8 @@ use std::time::Instant; use ccore::encoded::Header; use ccore::{BlockChainClient, BlockId}; -use primitives::{H256, U256}; +use ctypes::BlockHash; +use primitives::U256; use super::super::message::RequestMessage; @@ -32,7 +33,7 @@ const MAX_WAIT: u64 = 15; #[derive(Clone)] struct Pivot { - hash: H256, + hash: BlockHash, total_score: U256, } @@ -42,12 +43,12 @@ pub struct HeaderDownloader { client: Arc, total_score: U256, - best_hash: H256, + best_hash: BlockHash, pivot: Pivot, request_time: Option, - downloaded: HashMap, - queued: HashMap, + downloaded: HashMap, + queued: HashMap, trial: usize, } @@ -56,7 +57,7 @@ impl HeaderDownloader { self.total_score } - pub fn new(client: Arc, total_score: U256, best_hash: H256) -> Self { + pub fn new(client: Arc, total_score: U256, best_hash: BlockHash) -> Self { let best_header_hash = client.best_block_header().hash(); let best_score = client.block_total_score(&BlockId::Latest).expect("Best block always exist"); @@ -77,7 +78,7 @@ impl HeaderDownloader { } } - pub fn update(&mut self, total_score: U256, best_hash: H256) -> bool { + pub fn update(&mut self, total_score: U256, best_hash: BlockHash) -> bool { match self.total_score.cmp(&total_score) { Ordering::Equal => true, Ordering::Less => { @@ -196,7 +197,7 @@ impl HeaderDownloader { self.downloaded.values().cloned().collect() } - pub fn mark_as_imported(&mut self, hashes: Vec) { + pub fn mark_as_imported(&mut self, hashes: Vec) { for hash in hashes { self.queued.remove(&hash); self.downloaded.remove(&hash); @@ -212,7 +213,7 @@ impl HeaderDownloader { self.downloaded.shrink_to_fit(); } - pub fn mark_as_queued(&mut self, hashes: Vec) { + pub fn mark_as_queued(&mut self, hashes: Vec) { for hash in hashes { if let Some(header) = self.downloaded.remove(&hash) { self.queued.insert(hash, header); diff --git a/sync/src/block/extension.rs b/sync/src/block/extension.rs index 32927c4fab..f089980c29 100644 --- a/sync/src/block/extension.rs +++ b/sync/src/block/extension.rs @@ -29,7 +29,7 @@ use cstate::FindActionHandler; use ctimer::TimerToken; use ctypes::header::{Header, Seal}; use ctypes::transaction::Action; -use ctypes::BlockNumber; +use ctypes::{BlockHash, BlockNumber}; use primitives::{H256, U256}; use rand::prelude::SliceRandom; use rand::thread_rng; @@ -374,18 +374,18 @@ impl NetworkExtension for Extension { pub enum Event { GetPeers(EventSender), NewHeaders { - imported: Vec, - enacted: Vec, - retracted: Vec, + imported: Vec, + enacted: Vec, + retracted: Vec, }, NewBlocks { - imported: Vec, - invalid: Vec, + imported: Vec, + invalid: Vec, }, } impl Extension { - fn new_headers(&mut self, imported: Vec, enacted: Vec, retracted: Vec) { + fn new_headers(&mut self, imported: Vec, enacted: Vec, retracted: Vec) { let peer_ids: Vec<_> = self.header_downloaders.keys().cloned().collect(); for id in peer_ids { if let Some(peer) = self.header_downloaders.get_mut(&id) { @@ -415,7 +415,7 @@ impl Extension { self.body_downloader.remove_target(&retracted); } - fn new_blocks(&mut self, imported: Vec, invalid: Vec) { + fn new_blocks(&mut self, imported: Vec, invalid: Vec) { self.body_downloader.remove_target(&imported); self.body_downloader.remove_target(&invalid); @@ -440,7 +440,7 @@ impl Extension { } impl Extension { - fn on_peer_status(&mut self, from: &NodeId, total_score: U256, best_hash: H256, genesis_hash: H256) { + fn on_peer_status(&mut self, from: &NodeId, total_score: U256, best_hash: BlockHash, genesis_hash: BlockHash) { // Validity check if genesis_hash != self.client.chain_info().genesis_hash { cinfo!(SYNC, "Genesis hash mismatch with peer {}", from); @@ -543,7 +543,7 @@ impl Extension { ResponseMessage::Headers(headers) } - fn create_bodies_response(&self, hashes: Vec) -> ResponseMessage { + fn create_bodies_response(&self, hashes: Vec) -> ResponseMessage { let bodies = hashes .into_iter() .map(|hash| { @@ -553,11 +553,11 @@ impl Extension { ResponseMessage::Bodies(bodies) } - fn create_state_head_response(&self, _hash: H256) -> ResponseMessage { + fn create_state_head_response(&self, _hash: BlockHash) -> ResponseMessage { unimplemented!() } - fn create_state_chunk_response(&self, _hash: H256, _tree_root: H256) -> ResponseMessage { + fn create_state_chunk_response(&self, _hash: BlockHash, _tree_root: H256) -> ResponseMessage { unimplemented!() } @@ -708,7 +708,7 @@ impl Extension { } } - fn on_body_response(&mut self, hashes: Vec, bodies: Vec>) { + fn on_body_response(&mut self, hashes: Vec, bodies: Vec>) { ctrace!(SYNC, "Received body response with lenth({}) {:?}", hashes.len(), hashes); { self.body_downloader.import_bodies(hashes, bodies); @@ -770,13 +770,13 @@ impl From> for BlockSyncSender { impl ChainNotify for BlockSyncSender { fn new_headers( &self, - imported: Vec, - _invalid: Vec, - enacted: Vec, - retracted: Vec, - _sealed: Vec, + imported: Vec, + _invalid: Vec, + enacted: Vec, + retracted: Vec, + _sealed: Vec, _duration: u64, - _new_best_proposal: Option, + _new_best_proposal: Option, ) { self.0 .send(Event::NewHeaders { @@ -789,11 +789,11 @@ impl ChainNotify for BlockSyncSender { fn new_blocks( &self, - imported: Vec, - invalid: Vec, - _enacted: Vec, - _retracted: Vec, - _sealed: Vec, + imported: Vec, + invalid: Vec, + _enacted: Vec, + _retracted: Vec, + _sealed: Vec, _duration: u64, ) { self.0 diff --git a/sync/src/block/message/mod.rs b/sync/src/block/message/mod.rs index e1abe31f5f..1abffe9b30 100644 --- a/sync/src/block/message/mod.rs +++ b/sync/src/block/message/mod.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use primitives::{H256, U256}; +use ctypes::BlockHash; +use primitives::U256; use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; mod request; @@ -37,8 +38,8 @@ const MESSAGE_ID_STATE_CHUNK: u8 = 0x09; pub enum Message { Status { total_score: U256, - best_hash: H256, - genesis_hash: H256, + best_hash: BlockHash, + genesis_hash: BlockHash, }, Request(u64, RequestMessage), Response(u64, ResponseMessage), @@ -128,6 +129,7 @@ impl Decodable for Message { #[cfg(test)] mod tests { + use primitives::H256; use rlp::rlp_encode_and_decode_test; use super::*; @@ -136,8 +138,8 @@ mod tests { fn status_message_rlp() { rlp_encode_and_decode_test!(Message::Status { total_score: U256::default(), - best_hash: H256::default(), - genesis_hash: H256::default(), + best_hash: H256::default().into(), + genesis_hash: H256::default().into(), }); } @@ -150,6 +152,6 @@ mod tests { #[test] fn request_state_head_rlp() { let request_id = 10; - rlp_encode_and_decode_test!(Message::Request(request_id, RequestMessage::StateHead(H256::random()))); + rlp_encode_and_decode_test!(Message::Request(request_id, RequestMessage::StateHead(H256::random().into()))); } } diff --git a/sync/src/block/message/request.rs b/sync/src/block/message/request.rs index 63d1617d84..e1ad626192 100644 --- a/sync/src/block/message/request.rs +++ b/sync/src/block/message/request.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use ctypes::BlockNumber; +use ctypes::{BlockHash, BlockNumber}; use primitives::H256; use rlp::{DecoderError, Encodable, RlpStream, UntrustedRlp}; @@ -24,10 +24,10 @@ pub enum RequestMessage { start_number: BlockNumber, max_count: u64, }, - Bodies(Vec), - StateHead(H256), + Bodies(Vec), + StateHead(BlockHash), StateChunk { - block_hash: H256, + block_hash: BlockHash, tree_root: H256, }, } @@ -145,20 +145,20 @@ mod tests { #[test] fn request_bodies_message_rlp() { - let message = RequestMessage::Bodies(vec![H256::default()]); + let message = RequestMessage::Bodies(vec![H256::default().into()]); assert_eq!(message, decode_bytes(message.message_id(), message.rlp_bytes().as_ref())); } #[test] fn request_state_head_message_rlp() { - let message = RequestMessage::StateHead(H256::default()); + let message = RequestMessage::StateHead(H256::default().into()); assert_eq!(message, decode_bytes(message.message_id(), message.rlp_bytes().as_ref())); } #[test] fn request_state_chunk_message_rlp() { let message = RequestMessage::StateChunk { - block_hash: H256::default(), + block_hash: H256::default().into(), tree_root: H256::default(), }; assert_eq!(message, decode_bytes(message.message_id(), message.rlp_bytes().as_ref())); diff --git a/sync/src/snapshot/service.rs b/sync/src/snapshot/service.rs index 3b708f43d0..a9cdcf4fab 100644 --- a/sync/src/snapshot/service.rs +++ b/sync/src/snapshot/service.rs @@ -20,8 +20,7 @@ use std::sync::Arc; use std::thread::spawn; use ccore::{BlockChainClient, BlockChainTrait, BlockId, ChainNotify, Client, DatabaseClient}; - -use primitives::H256; +use ctypes::BlockHash; use super::error::Error; use super::snapshot::{Snapshot, WriteSnapshot}; @@ -48,11 +47,11 @@ impl ChainNotify for Service { /// fires when chain has new blocks. fn new_blocks( &self, - _imported: Vec, - _invalid: Vec, - enacted: Vec, - _retracted: Vec, - _sealed: Vec, + _imported: Vec, + _invalid: Vec, + enacted: Vec, + _retracted: Vec, + _sealed: Vec, _duration: u64, ) { let best_number = self.client.chain_info().best_block_number; @@ -65,7 +64,7 @@ impl ChainNotify for Service { let header = self.client.block_header(&BlockId::Number(number)).expect("Snapshot target must exist"); let db = self.client.database(); - let path: PathBuf = [self.root_dir.clone(), format!("{:x}", header.hash())].iter().collect(); + let path: PathBuf = [self.root_dir.clone(), format!("{:x}", *header.hash())].iter().collect(); let root = header.state_root(); // FIXME: The db can be corrupted because the CodeChain doesn't wait child threads end on exit. spawn(move || match Snapshot::try_new(path).map(|s| s.write_snapshot(db.as_ref(), &root)) { diff --git a/types/src/block_hash.rs b/types/src/block_hash.rs new file mode 100644 index 0000000000..08d7610c3a --- /dev/null +++ b/types/src/block_hash.rs @@ -0,0 +1,109 @@ +// Copyright 2019 Kodebox, Inc. +// This file is part of CodeChain. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +use std::fmt::{self, Display, Formatter}; +use std::ops::Deref; + +use primitives::H256; +use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; + + +#[derive(Clone, Copy, Default, Eq, Hash, PartialEq, Debug, Deserialize, Serialize)] +pub struct BlockHash(H256); + +impl From for BlockHash { + fn from(h: H256) -> Self { + Self(h) + } +} + +impl Deref for BlockHash { + type Target = H256; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Display for BlockHash { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> { + self.0.fmt(f) + } +} + +impl Encodable for BlockHash { + fn rlp_append(&self, s: &mut RlpStream) { + self.0.rlp_append(s); + } +} + +impl Decodable for BlockHash { + fn decode(rlp: &UntrustedRlp) -> Result { + Ok(H256::decode(rlp)?.into()) + } +} + +#[cfg(test)] +mod tests { + use std::collections::hash_map::DefaultHasher; + use std::hash::{Hash, Hasher}; + + use rlp::{self, rlp_encode_and_decode_test}; + + use super::*; + + #[test] + fn hash_of_block_hash_and_h256_are_the_same() { + let h256 = H256::random(); + let block_hash = BlockHash(h256); + + let mut hasher_of_h256 = DefaultHasher::new(); + let mut hasher_of_tracker = DefaultHasher::new(); + + h256.hash(&mut hasher_of_h256); + block_hash.hash(&mut hasher_of_tracker); + + assert_eq!(hasher_of_h256.finish(), hasher_of_tracker.finish()); + } + + #[test] + fn rlp_of_block_hash_can_be_decoded_to_h256() { + let h256 = H256::random(); + let block_hash = BlockHash(h256); + + let encoded = rlp::encode(&block_hash); + let decoded = rlp::decode(&*encoded); + + assert_eq!(h256, decoded); + } + + #[test] + fn rlp_of_h256_can_be_decoded_to_block_hash() { + let h256 = H256::random(); + + let encoded = rlp::encode(&h256); + let decoded = rlp::decode(&*encoded); + + let block_hash = BlockHash(h256); + assert_eq!(block_hash, decoded); + } + + #[test] + fn rlp() { + rlp_encode_and_decode_test!(BlockHash(H256::random())); + } +} diff --git a/types/src/header.rs b/types/src/header.rs index 8fb730f4bf..6c2ca453b5 100644 --- a/types/src/header.rs +++ b/types/src/header.rs @@ -23,7 +23,7 @@ use ckey::Address; use primitives::{Bytes, H256, U256}; use rlp::*; -use crate::BlockNumber; +use crate::{BlockHash, BlockNumber}; /// Semantic boolean for when a seal/signature is included. pub enum Seal { @@ -37,7 +37,7 @@ pub enum Seal { #[derive(Debug, Clone, PartialEq)] pub struct Header { /// Parent hash. - parent_hash: H256, + parent_hash: BlockHash, /// Block timestamp. timestamp: u64, /// Block number. @@ -68,7 +68,7 @@ impl Default for Header { /// Create a new, default-valued, header. fn default() -> Self { Header { - parent_hash: H256::default(), + parent_hash: H256::default().into(), timestamp: 0, number: 0, author: Default::default(), @@ -94,7 +94,7 @@ impl Header { } /// Get the parent_hash field of the header. - pub fn parent_hash(&self) -> &H256 { + pub fn parent_hash(&self) -> &BlockHash { &self.parent_hash } /// Get the timestamp field of the header. @@ -140,7 +140,7 @@ impl Header { } /// Set the number field of the header. - pub fn set_parent_hash(&mut self, a: H256) { + pub fn set_parent_hash(&mut self, a: BlockHash) { self.parent_hash = a; self.note_dirty(); } @@ -199,14 +199,14 @@ impl Header { } /// Get the hash of this header (blake of the RLP). - pub fn hash(&self) -> H256 { + pub fn hash(&self) -> BlockHash { let mut hash = self.hash.borrow_mut(); match &mut *hash { - Some(h) => *h, + Some(h) => (*h).into(), hash @ &mut None => { let h = self.rlp_blake(&Seal::With); *hash = Some(h); - h + h.into() } } } diff --git a/types/src/lib.rs b/types/src/lib.rs index c46d27d181..95d5b2ae2c 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -27,7 +27,9 @@ extern crate serde_derive; #[cfg(test)] extern crate serde_json; +mod block_hash; mod common_params; + pub mod errors; pub mod header; pub mod transaction; @@ -35,5 +37,7 @@ pub mod util; pub type BlockNumber = u64; pub type ShardId = u16; + +pub use block_hash::BlockHash; pub use common_params::CommonParams; pub use header::Header; From af890973d615ea44bc7c83491baa3ee6718b72f7 Mon Sep 17 00:00:00 2001 From: Seulgi Kim Date: Sun, 27 Oct 2019 01:34:04 +0900 Subject: [PATCH 074/105] Distinguish Tracker from H256 And rename some variables that was misnamed as tx_hash. --- core/src/blockchain/blockchain.rs | 6 +- core/src/blockchain/body_db.rs | 54 +++++------ core/src/blockchain/extras.rs | 10 +-- core/src/blockchain/invoice_db.rs | 11 +-- core/src/client/client.rs | 24 +++-- core/src/client/mod.rs | 22 +++-- core/src/client/test_client.rs | 12 +-- core/src/invoice.rs | 3 +- rpc/src/v1/impls/chain.rs | 14 +-- rpc/src/v1/impls/devel.rs | 11 +-- rpc/src/v1/impls/mempool.rs | 3 +- rpc/src/v1/traits/chain.rs | 10 +-- rpc/src/v1/traits/mempool.rs | 6 +- rpc/src/v1/types/action.rs | 12 +-- rpc/src/v1/types/asset_input.rs | 6 +- spec/JSON-RPC.md | 2 +- state/src/impls/shard_level.rs | 66 +++++++------- state/src/impls/test_helper.rs | 36 ++++---- state/src/impls/top_level.rs | 101 +++++++++++---------- state/src/item/asset.rs | 16 ++-- state/src/item/asset_scheme.rs | 6 +- state/src/tests.rs | 6 +- state/src/traits.rs | 6 +- types/src/errors/runtime_error.rs | 12 +-- types/src/errors/syntax_error.rs | 6 +- types/src/lib.rs | 2 + types/src/tracker.rs | 109 +++++++++++++++++++++++ types/src/transaction/action.rs | 4 +- types/src/transaction/asset_out_point.rs | 5 +- types/src/transaction/shard.rs | 26 +++--- types/src/transaction/transaction.rs | 3 +- vm/src/executor.rs | 6 +- vm/tests/common/mod.rs | 7 +- 33 files changed, 379 insertions(+), 244 deletions(-) create mode 100644 types/src/tracker.rs diff --git a/core/src/blockchain/blockchain.rs b/core/src/blockchain/blockchain.rs index 9e99ff4f9f..3495d1fa2b 100644 --- a/core/src/blockchain/blockchain.rs +++ b/core/src/blockchain/blockchain.rs @@ -16,7 +16,7 @@ use std::sync::Arc; -use ctypes::{BlockHash, BlockNumber}; +use ctypes::{BlockHash, BlockNumber, Tracker}; use kvdb::{DBTransaction, KeyValueDB}; use parking_lot::RwLock; use primitives::H256; @@ -415,7 +415,7 @@ impl BodyProvider for BlockChain { self.body_db.transaction_address(hash) } - fn transaction_address_by_tracker(&self, tracker: &H256) -> Option { + fn transaction_address_by_tracker(&self, tracker: &Tracker) -> Option { self.body_db.transaction_address_by_tracker(tracker) } @@ -430,7 +430,7 @@ impl InvoiceProvider for BlockChain { self.invoice_db.is_known_error_hint(hash) } - fn error_hints_by_tracker(&self, tracker: &H256) -> Vec<(H256, Option)> { + fn error_hints_by_tracker(&self, tracker: &Tracker) -> Vec<(H256, Option)> { self.invoice_db.error_hints_by_tracker(tracker) } diff --git a/core/src/blockchain/body_db.rs b/core/src/blockchain/body_db.rs index 6a016eba18..726091b9b4 100644 --- a/core/src/blockchain/body_db.rs +++ b/core/src/blockchain/body_db.rs @@ -18,7 +18,7 @@ use std::collections::{HashMap, HashSet}; use std::mem; use std::sync::Arc; -use ctypes::BlockHash; +use ctypes::{BlockHash, Tracker}; use kvdb::{DBTransaction, KeyValueDB}; use lru_cache::LruCache; use parking_lot::{Mutex, RwLock}; @@ -40,13 +40,13 @@ pub struct BodyDB { parcel_address_cache: RwLock>, pending_parcel_addresses: RwLock>>, - transaction_address_cache: Mutex>, - pending_transaction_addresses: Mutex>>, + transaction_address_cache: Mutex>, + pending_transaction_addresses: Mutex>>, db: Arc, } -type TransactionHashAndAddress = (H256, TransactionAddresses); +type TrackerAndAddress = (Tracker, TransactionAddresses); impl BodyDB { /// Create new instance of blockchain from given Genesis. @@ -185,7 +185,7 @@ impl BodyDB { fn new_transaction_address_entries( &self, best_block_changed: &BestBlockChanged, - ) -> HashMap> { + ) -> HashMap> { let block_hash = if let Some(best_block_hash) = best_block_changed.new_best_hash() { best_block_hash } else { @@ -197,8 +197,8 @@ impl BodyDB { }; let (removed, added): ( - Box>, - Box>, + Box>, + Box>, ) = match best_block_changed { BestBlockChanged::CanonChainAppended { .. @@ -229,31 +229,31 @@ impl BodyDB { BestBlockChanged::None => return Default::default(), }; - let mut added_addresses: HashMap = Default::default(); - let mut removed_addresses: HashMap = Default::default(); - let mut hashes: HashSet = Default::default(); - for (hash, address) in added { - hashes.insert(hash); - *added_addresses.entry(hash).or_insert_with(Default::default) += address; + let mut added_addresses: HashMap = Default::default(); + let mut removed_addresses: HashMap = Default::default(); + let mut trackers: HashSet = Default::default(); + for (tracker, address) in added { + trackers.insert(tracker); + *added_addresses.entry(tracker).or_insert_with(Default::default) += address; } - for (hash, address) in removed { - hashes.insert(hash); - *removed_addresses.entry(hash).or_insert_with(Default::default) += address; + for (tracker, address) in removed { + trackers.insert(tracker); + *removed_addresses.entry(tracker).or_insert_with(Default::default) += address; } - let mut inserted_address: HashMap = Default::default(); - for hash in hashes.into_iter() { - let address: TransactionAddresses = self.db.read(db::COL_EXTRA, &hash).unwrap_or_default(); - inserted_address.insert(hash, address); + let mut inserted_address: HashMap = Default::default(); + for tracker in trackers.into_iter() { + let address: TransactionAddresses = self.db.read(db::COL_EXTRA, &tracker).unwrap_or_default(); + inserted_address.insert(tracker, address); } - for (hash, removed_address) in removed_addresses.into_iter() { + for (tracker, removed_address) in removed_addresses.into_iter() { *inserted_address - .get_mut(&hash) + .get_mut(&tracker) .expect("inserted addresses are sum of added_addresses and removed_addresses") -= removed_address; } - for (hash, added_address) in added_addresses.into_iter() { + for (tracker, added_address) in added_addresses.into_iter() { *inserted_address - .get_mut(&hash) + .get_mut(&tracker) .expect("inserted addresses are sum of added_addresses and removed_addresses") += added_address; } @@ -286,7 +286,7 @@ pub trait BodyProvider { /// Get the address of parcel with given hash. fn transaction_address(&self, hash: &H256) -> Option; - fn transaction_address_by_tracker(&self, tracker: &H256) -> Option; + fn transaction_address_by_tracker(&self, tracker: &Tracker) -> Option; /// Get the block body (uncles and parcels). fn block_body(&self, hash: &BlockHash) -> Option; @@ -303,7 +303,7 @@ impl BodyProvider for BodyDB { Some(result) } - fn transaction_address_by_tracker(&self, tracker: &H256) -> Option { + fn transaction_address_by_tracker(&self, tracker: &Tracker) -> Option { let addresses = self.db.read_with_cache(db::COL_EXTRA, &mut *self.transaction_address_cache.lock(), tracker)?; addresses.into_iter().next() } @@ -348,7 +348,7 @@ fn parcel_address_entries( fn transaction_address_entries( block_hash: BlockHash, parcel_hashes: impl IntoIterator, -) -> impl Iterator { +) -> impl Iterator { parcel_hashes.into_iter().enumerate().filter_map(move |(parcel_index, parcel)| { parcel.tracker().map(|tracker| { ( diff --git a/core/src/blockchain/extras.rs b/core/src/blockchain/extras.rs index a48555d33b..f016b50b55 100644 --- a/core/src/blockchain/extras.rs +++ b/core/src/blockchain/extras.rs @@ -16,7 +16,7 @@ use std::ops::{Add, AddAssign, Deref, Sub, SubAssign}; -use ctypes::{BlockHash, BlockNumber}; +use ctypes::{BlockHash, BlockNumber, Tracker}; use primitives::{H256, H264, U256}; use crate::db::Key; @@ -31,8 +31,8 @@ enum ExtrasIndex { BlockHash = 1, /// Parcel address index ParcelAddress = 2, - /// Transaction address index - TransactionAddress = 3, + /// Transaction addresses index + TransactionAddresses = 3, // (Reserved) = 4, // (Reserved) = 5, } @@ -85,11 +85,11 @@ impl Key for H256 { } } -impl Key for H256 { +impl Key for Tracker { type Target = H264; fn key(&self) -> H264 { - with_index(self, ExtrasIndex::TransactionAddress) + with_index(self, ExtrasIndex::TransactionAddresses) } } diff --git a/core/src/blockchain/invoice_db.rs b/core/src/blockchain/invoice_db.rs index 8c14499d90..eb5b82d694 100644 --- a/core/src/blockchain/invoice_db.rs +++ b/core/src/blockchain/invoice_db.rs @@ -18,6 +18,7 @@ use std::collections::HashMap; use std::ops::{Deref, DerefMut}; use std::sync::Arc; +use ctypes::Tracker; use kvdb::{DBTransaction, KeyValueDB}; use parking_lot::RwLock; use primitives::{H256, H264}; @@ -30,7 +31,7 @@ use crate::db::{self, CacheUpdatePolicy, Key, Readable, Writable}; /// **Does not do input data verification.** pub struct InvoiceDB { // tracker -> transaction hashe + error hint - tracker_cache: RwLock>, + tracker_cache: RwLock>, // transaction hash -> error hint hash_cache: RwLock>>, @@ -55,7 +56,7 @@ impl InvoiceDB { &self, batch: &mut DBTransaction, hash: H256, - tracker: Option, + tracker: Option, error_hint: Option, ) { if self.is_known_error_hint(&hash) { @@ -82,7 +83,7 @@ pub trait InvoiceProvider { fn is_known_error_hint(&self, hash: &H256) -> bool; /// Get error hints - fn error_hints_by_tracker(&self, tracker: &H256) -> Vec<(H256, Option)>; + fn error_hints_by_tracker(&self, tracker: &Tracker) -> Vec<(H256, Option)>; /// Get error hint fn error_hint(&self, hash: &H256) -> Option; @@ -93,7 +94,7 @@ impl InvoiceProvider for InvoiceDB { self.db.exists_with_cache(db::COL_ERROR_HINT, &self.hash_cache, hash) } - fn error_hints_by_tracker(&self, tracker: &H256) -> Vec<(H256, Option)> { + fn error_hints_by_tracker(&self, tracker: &Tracker) -> Vec<(H256, Option)> { self.db .read_with_cache(db::COL_ERROR_HINT, &mut *self.tracker_cache.write(), tracker) .map(|hashes| (*hashes).clone()) @@ -175,7 +176,7 @@ impl Key> for H256 { } } -impl Key for H256 { +impl Key for Tracker { type Target = H264; fn key(&self) -> H264 { diff --git a/core/src/client/client.rs b/core/src/client/client.rs index 846a031ec4..6ea56f56b8 100644 --- a/core/src/client/client.rs +++ b/core/src/client/client.rs @@ -28,7 +28,7 @@ use cstate::{ }; use ctimer::{TimeoutHandler, TimerApi, TimerScheduleError, TimerToken}; use ctypes::transaction::{AssetTransferInput, PartialHashing, ShardTransaction}; -use ctypes::{BlockHash, BlockNumber, CommonParams, ShardId}; +use ctypes::{BlockHash, BlockNumber, CommonParams, ShardId, Tracker}; use cvm::{decode, execute, ChainTimeInfo, ScriptResult, VMConfig}; use hashdb::AsHashDB; use journaldb; @@ -239,7 +239,7 @@ impl Client { } } - fn transaction_addresses(&self, tracker: &H256) -> Option { + fn transaction_addresses(&self, tracker: &Tracker) -> Option { self.block_chain().transaction_address_by_tracker(tracker) } @@ -366,7 +366,13 @@ impl AssetClient for Client { } } - fn get_asset(&self, tracker: H256, index: usize, shard_id: ShardId, id: BlockId) -> TrieResult> { + fn get_asset( + &self, + tracker: Tracker, + index: usize, + shard_id: ShardId, + id: BlockId, + ) -> TrieResult> { if let Some(state) = Client::state_at(&self, id) { Ok(state.asset(shard_id, tracker, index)?) } else { @@ -379,7 +385,7 @@ impl AssetClient for Client { /// It returns None if such an asset never existed in the shard at the given block. fn is_asset_spent( &self, - tracker: H256, + tracker: Tracker, index: usize, shard_id: ShardId, block_id: BlockId, @@ -629,7 +635,7 @@ impl BlockChainTrait for Client { self.transaction_address(id).map(|addr| addr.block_hash) } - fn transaction_header(&self, tracker: &H256) -> Option<::encoded::Header> { + fn transaction_header(&self, tracker: &Tracker) -> Option<::encoded::Header> { self.transaction_addresses(tracker).map(|addr| addr.block_hash).and_then(|hash| self.block_header(&hash.into())) } } @@ -796,13 +802,13 @@ impl BlockChainClient for Client { chain.error_hint(hash) } - fn transaction_by_tracker(&self, tracker: &H256) -> Option { + fn transaction_by_tracker(&self, tracker: &Tracker) -> Option { let chain = self.block_chain(); let address = self.transaction_addresses(tracker); address.and_then(|address| chain.transaction(&address)) } - fn error_hints_by_tracker(&self, tracker: &H256) -> Vec<(H256, Option)> { + fn error_hints_by_tracker(&self, tracker: &Tracker) -> Vec<(H256, Option)> { let chain = self.block_chain(); chain.error_hints_by_tracker(tracker) } @@ -919,11 +925,11 @@ impl MiningBlockChainClient for Client { } impl ChainTimeInfo for Client { - fn transaction_block_age(&self, tracker: &H256, parent_block_number: BlockNumber) -> Option { + fn transaction_block_age(&self, tracker: &Tracker, parent_block_number: BlockNumber) -> Option { self.transaction_block_number(tracker).map(|block_number| parent_block_number - block_number) } - fn transaction_time_age(&self, tracker: &H256, parent_timestamp: u64) -> Option { + fn transaction_time_age(&self, tracker: &Tracker, parent_timestamp: u64) -> Option { self.transaction_block_timestamp(tracker).map(|block_timestamp| parent_timestamp - block_timestamp) } } diff --git a/core/src/client/mod.rs b/core/src/client/mod.rs index bdbd712716..a9f6520a24 100644 --- a/core/src/client/mod.rs +++ b/core/src/client/mod.rs @@ -37,7 +37,7 @@ use cmerkle::Result as TrieResult; use cnetwork::NodeId; use cstate::{AssetScheme, FindActionHandler, OwnedAsset, StateResult, Text, TopLevelState, TopStateView}; use ctypes::transaction::{AssetTransferInput, PartialHashing, ShardTransaction}; -use ctypes::{BlockHash, BlockNumber, CommonParams, ShardId}; +use ctypes::{BlockHash, BlockNumber, CommonParams, ShardId, Tracker}; use cvm::ChainTimeInfo; use kvdb::KeyValueDB; use primitives::{Bytes, H160, H256, U256}; @@ -75,13 +75,13 @@ pub trait BlockChainTrait { /// Get the hash of block that contains the transaction, if any. fn transaction_block(&self, id: &TransactionId) -> Option; - fn transaction_header(&self, tracker: &H256) -> Option<::encoded::Header>; + fn transaction_header(&self, tracker: &Tracker) -> Option<::encoded::Header>; - fn transaction_block_number(&self, tracker: &H256) -> Option { + fn transaction_block_number(&self, tracker: &Tracker) -> Option { self.transaction_header(tracker).map(|header| header.number()) } - fn transaction_block_timestamp(&self, tracker: &H256) -> Option { + fn transaction_block_timestamp(&self, tracker: &Tracker) -> Option { self.transaction_header(tracker).map(|header| header.timestamp()) } } @@ -253,9 +253,9 @@ pub trait BlockChainClient: Sync + Send + AccountData + BlockChainTrait + Import fn error_hint(&self, hash: &H256) -> Option; /// Get the transaction with given tracker. - fn transaction_by_tracker(&self, tracker: &H256) -> Option; + fn transaction_by_tracker(&self, tracker: &Tracker) -> Option; - fn error_hints_by_tracker(&self, tracker: &H256) -> Vec<(H256, Option)>; + fn error_hints_by_tracker(&self, tracker: &Tracker) -> Vec<(H256, Option)>; } /// Result of import block operation. @@ -300,11 +300,17 @@ pub trait DatabaseClient { pub trait AssetClient { fn get_asset_scheme(&self, asset_type: H160, shard_id: ShardId, id: BlockId) -> TrieResult>; - fn get_asset(&self, tracker: H256, index: usize, shard_id: ShardId, id: BlockId) -> TrieResult>; + fn get_asset( + &self, + tracker: Tracker, + index: usize, + shard_id: ShardId, + id: BlockId, + ) -> TrieResult>; fn is_asset_spent( &self, - tracker: H256, + tracker: Tracker, index: usize, shard_id: ShardId, block_id: BlockId, diff --git a/core/src/client/test_client.rs b/core/src/client/test_client.rs index 2afaaba3b4..b8f5b9789d 100644 --- a/core/src/client/test_client.rs +++ b/core/src/client/test_client.rs @@ -43,7 +43,7 @@ use cstate::tests::helpers::empty_top_state; use cstate::{FindActionHandler, StateDB, TopLevelState}; use ctimer::{TimeoutHandler, TimerToken}; use ctypes::transaction::{Action, Transaction}; -use ctypes::{BlockHash, BlockNumber, CommonParams, Header as BlockHeader}; +use ctypes::{BlockHash, BlockNumber, CommonParams, Header as BlockHeader, Tracker}; use cvm::ChainTimeInfo; use journaldb; use kvdb::KeyValueDB; @@ -459,7 +459,7 @@ impl BlockChainTrait for TestBlockChainClient { None // Simple default. } - fn transaction_header(&self, _tracker: &H256) -> Option<::encoded::Header> { + fn transaction_header(&self, _tracker: &Tracker) -> Option<::encoded::Header> { None } } @@ -597,11 +597,11 @@ impl BlockChainClient for TestBlockChainClient { unimplemented!(); } - fn transaction_by_tracker(&self, _: &H256) -> Option { + fn transaction_by_tracker(&self, _: &Tracker) -> Option { unimplemented!(); } - fn error_hints_by_tracker(&self, _: &H256) -> Vec<(H256, Option)> { + fn error_hints_by_tracker(&self, _: &Tracker) -> Vec<(H256, Option)> { unimplemented!(); } } @@ -611,11 +611,11 @@ impl TimeoutHandler for TestBlockChainClient { } impl ChainTimeInfo for TestBlockChainClient { - fn transaction_block_age(&self, _: &H256, _parent_block_number: BlockNumber) -> Option { + fn transaction_block_age(&self, _: &Tracker, _parent_block_number: BlockNumber) -> Option { Some(0) } - fn transaction_time_age(&self, _: &H256, _parent_timestamp: u64) -> Option { + fn transaction_time_age(&self, _: &Tracker, _parent_timestamp: u64) -> Option { Some(0) } } diff --git a/core/src/invoice.rs b/core/src/invoice.rs index dcfd3d5fc1..ed3d96bc69 100644 --- a/core/src/invoice.rs +++ b/core/src/invoice.rs @@ -14,11 +14,12 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +use ctypes::Tracker; use primitives::H256; #[derive(Clone, Debug, PartialEq)] pub struct Invoice { - pub tracker: Option, + pub tracker: Option, pub hash: H256, pub error: Option, } diff --git a/rpc/src/v1/impls/chain.rs b/rpc/src/v1/impls/chain.rs index 414b44bf47..a7669a32d0 100644 --- a/rpc/src/v1/impls/chain.rs +++ b/rpc/src/v1/impls/chain.rs @@ -26,7 +26,7 @@ use cjson::uint::Uint; use ckey::{public_to_address, NetworkId, PlatformAddress, Public}; use cstate::FindActionHandler; use ctypes::transaction::{Action, ShardTransaction as ShardTransactionType}; -use ctypes::{BlockHash, BlockNumber, ShardId}; +use ctypes::{BlockHash, BlockNumber, ShardId, Tracker}; use primitives::{Bytes as BytesArray, H160, H256}; use jsonrpc_core::Result; @@ -86,17 +86,17 @@ where self.contains_transaction(transaction_hash) } - fn get_transaction_by_tracker(&self, tracker: H256) -> Result> { + fn get_transaction_by_tracker(&self, tracker: Tracker) -> Result> { Ok(self.client.transaction_by_tracker(&tracker).map(From::from)) } fn get_asset_scheme_by_tracker( &self, - tracker: H256, + tracker: Tracker, shard_id: ShardId, block_number: Option, ) -> Result> { - let asset_type = Blake::blake(tracker); + let asset_type = Blake::blake(*tracker); self.get_asset_scheme_by_type(asset_type, shard_id, block_number) } @@ -136,7 +136,7 @@ where fn get_asset( &self, - tracker: H256, + tracker: Tracker, index: usize, shard_id: ShardId, block_number: Option, @@ -148,13 +148,13 @@ where fn is_asset_spent( &self, - transaction_hash: H256, + tracker: Tracker, index: usize, shard_id: ShardId, block_number: Option, ) -> Result> { let block_id = block_number.map(BlockId::Number).unwrap_or(BlockId::Latest); - self.client.is_asset_spent(transaction_hash, index, shard_id, block_id).map_err(errors::transaction_state) + self.client.is_asset_spent(tracker, index, shard_id, block_id).map_err(errors::transaction_state) } fn get_seq(&self, address: PlatformAddress, block_number: Option) -> Result> { diff --git a/rpc/src/v1/impls/devel.rs b/rpc/src/v1/impls/devel.rs index 51e96aa71d..39843ef3ca 100644 --- a/rpc/src/v1/impls/devel.rs +++ b/rpc/src/v1/impls/devel.rs @@ -33,6 +33,7 @@ use csync::BlockSyncEvent; use ctypes::transaction::{ Action, AssetMintOutput, AssetOutPoint, AssetTransferInput, AssetTransferOutput, Transaction, }; +use ctypes::Tracker; use jsonrpc_core::Result; use kvdb::KeyValueDB; use primitives::{H160, H256}; @@ -183,10 +184,10 @@ where } macro_rules! transfer_input { - ($hash:expr, $index:expr, $asset_type:expr, $quantity:expr) => { + ($tracker:expr, $index:expr, $asset_type:expr, $quantity:expr) => { AssetTransferInput { prev_out: AssetOutPoint { - tracker: $hash, + tracker: $tracker, index: $index, asset_type: $asset_type, shard_id: 0, @@ -226,7 +227,7 @@ where } fn asset_type(tx: &Transaction) -> H160 { - Blake::blake(tx.tracker().unwrap()) + Blake::blake(*tx.tracker().unwrap()) } fn tps(count: u64, start_time: PreciseTime, end_time: PreciseTime) -> f64 { @@ -276,7 +277,7 @@ where send_tx(mint_tx, &*self.client, &genesis_keypair)?; fn create_inputs( - transaction_hash: H256, + tracker: Tracker, asset_type: H160, total_amount: u64, count: usize, @@ -284,7 +285,7 @@ where let mut inputs = Vec::new(); let amount = total_amount / (count as u64); for i in 0..(count as usize) { - let input = transfer_input!(transaction_hash, i, asset_type, amount); + let input = transfer_input!(tracker, i, asset_type, amount); inputs.push(input); } inputs diff --git a/rpc/src/v1/impls/mempool.rs b/rpc/src/v1/impls/mempool.rs index e61f9d6928..99cdc5f2af 100644 --- a/rpc/src/v1/impls/mempool.rs +++ b/rpc/src/v1/impls/mempool.rs @@ -19,6 +19,7 @@ use std::sync::Arc; use ccore::{BlockChainClient, MiningBlockChainClient, SignedTransaction}; use cjson::bytes::Bytes; use ckey::{Address, PlatformAddress}; +use ctypes::Tracker; use primitives::H256; use rlp::UntrustedRlp; @@ -59,7 +60,7 @@ where .map(Into::into) } - fn get_transaction_results_by_tracker(&self, tracker: H256) -> Result> { + fn get_transaction_results_by_tracker(&self, tracker: Tracker) -> Result> { Ok(self .client .error_hints_by_tracker(&tracker) diff --git a/rpc/src/v1/traits/chain.rs b/rpc/src/v1/traits/chain.rs index 09b45fc621..3eeb48a230 100644 --- a/rpc/src/v1/traits/chain.rs +++ b/rpc/src/v1/traits/chain.rs @@ -17,7 +17,7 @@ use cjson::scheme::Params; use cjson::uint::Uint; use ckey::{NetworkId, PlatformAddress, Public}; -use ctypes::{BlockHash, BlockNumber, ShardId}; +use ctypes::{BlockHash, BlockNumber, ShardId, Tracker}; use primitives::{Bytes as BytesArray, H160, H256}; use jsonrpc_core::Result; @@ -43,13 +43,13 @@ pub trait Chain { /// Gets transaction with given transaction tracker. #[rpc(name = "chain_getTransactionByTracker")] - fn get_transaction_by_tracker(&self, tracker: H256) -> Result>; + fn get_transaction_by_tracker(&self, tracker: Tracker) -> Result>; /// Gets asset scheme with given transaction tracker. #[rpc(name = "chain_getAssetSchemeByTracker")] fn get_asset_scheme_by_tracker( &self, - tracker: H256, + tracker: Tracker, shard_id: ShardId, block_number: Option, ) -> Result>; @@ -71,7 +71,7 @@ pub trait Chain { #[rpc(name = "chain_getAsset")] fn get_asset( &self, - tracker: H256, + tracker: Tracker, index: usize, shard_id: ShardId, block_number: Option, @@ -81,7 +81,7 @@ pub trait Chain { #[rpc(name = "chain_isAssetSpent")] fn is_asset_spent( &self, - transaction_hash: H256, + tracker: Tracker, index: usize, shard_id: ShardId, block_number: Option, diff --git a/rpc/src/v1/traits/mempool.rs b/rpc/src/v1/traits/mempool.rs index a7094210e4..dc329f3d07 100644 --- a/rpc/src/v1/traits/mempool.rs +++ b/rpc/src/v1/traits/mempool.rs @@ -15,10 +15,10 @@ // along with this program. If not, see . use cjson::bytes::Bytes; -use primitives::H256; - use ckey::PlatformAddress; +use ctypes::Tracker; use jsonrpc_core::Result; +use primitives::H256; use super::super::types::PendingTransactions; @@ -30,7 +30,7 @@ pub trait Mempool { /// Gets transaction results with given transaction tracker. #[rpc(name = "mempool_getTransactionResultsByTracker")] - fn get_transaction_results_by_tracker(&self, tracker: H256) -> Result>; + fn get_transaction_results_by_tracker(&self, tracker: Tracker) -> Result>; /// Gets a hint to find out why the transaction failed. #[rpc(name = "mempool_getErrorHint")] diff --git a/rpc/src/v1/types/action.rs b/rpc/src/v1/types/action.rs index 02160c57d5..48797bcd0c 100644 --- a/rpc/src/v1/types/action.rs +++ b/rpc/src/v1/types/action.rs @@ -19,7 +19,7 @@ use std::convert::TryFrom; use cjson::uint::Uint; use ckey::{NetworkId, PlatformAddress, Public, Signature}; use ctypes::transaction::{Action as ActionType, AssetMintOutput as AssetMintOutputType}; -use ctypes::ShardId; +use ctypes::{ShardId, Tracker}; use primitives::{Bytes, H160, H256}; use rustc_serialize::hex::{FromHex, ToHex}; @@ -142,7 +142,7 @@ pub enum ActionWithTracker { approvals: Vec, - tracker: H256, + tracker: Tracker, }, #[serde(rename_all = "camelCase")] TransferAsset { @@ -158,7 +158,7 @@ pub enum ActionWithTracker { approvals: Vec, expiration: Option, - tracker: H256, + tracker: Tracker, }, #[serde(rename_all = "camelCase")] ChangeAssetScheme { @@ -173,7 +173,7 @@ pub enum ActionWithTracker { approvals: Vec, - tracker: H256, + tracker: Tracker, }, #[serde(rename_all = "camelCase")] IncreaseAssetSupply { @@ -185,7 +185,7 @@ pub enum ActionWithTracker { approvals: Vec, - tracker: H256, + tracker: Tracker, }, #[serde(rename_all = "camelCase")] @@ -194,7 +194,7 @@ pub enum ActionWithTracker { burn: Box, receiver: PlatformAddress, - tracker: H256, + tracker: Tracker, }, Pay { receiver: PlatformAddress, diff --git a/rpc/src/v1/types/asset_input.rs b/rpc/src/v1/types/asset_input.rs index 0199173600..65fba8832c 100644 --- a/rpc/src/v1/types/asset_input.rs +++ b/rpc/src/v1/types/asset_input.rs @@ -16,13 +16,13 @@ use cjson::uint::Uint; use ctypes::transaction::{AssetOutPoint as AssetOutPointType, AssetTransferInput as AssetTransferInputType, Timelock}; -use ctypes::ShardId; -use primitives::{Bytes, H160, H256}; +use ctypes::{ShardId, Tracker}; +use primitives::{Bytes, H160}; #[derive(Debug, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct AssetOutPoint { - pub tracker: H256, + pub tracker: Tracker, pub index: usize, pub asset_type: H160, pub shard_id: ShardId, diff --git a/spec/JSON-RPC.md b/spec/JSON-RPC.md index 61e2375710..cefee266dc 100644 --- a/spec/JSON-RPC.md +++ b/spec/JSON-RPC.md @@ -994,7 +994,7 @@ Gets the text with given transaction hash. Checks whether an asset is spent or not. ### Params - 1. transaction id: `H256` + 1. tracker: `H256` 2. index: `number` 3. shard id: `number` 4. block number: `number` | `null` diff --git a/state/src/impls/shard_level.rs b/state/src/impls/shard_level.rs index 06703628bd..829c610ffb 100644 --- a/state/src/impls/shard_level.rs +++ b/state/src/impls/shard_level.rs @@ -27,7 +27,7 @@ use ctypes::transaction::{ ShardTransaction, }; use ctypes::util::unexpected::Mismatch; -use ctypes::{BlockNumber, ShardId}; +use ctypes::{BlockNumber, ShardId, Tracker}; use cvm::{decode, execute, ChainTimeInfo, ScriptResult, VMConfig}; use hashdb::AsHashDB; use primitives::{Bytes, H160, H256}; @@ -212,7 +212,7 @@ impl<'db> ShardLevelState<'db> { #[cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))] fn mint_asset( &mut self, - transaction_tracker: H256, + transaction_tracker: Tracker, metadata: &str, output: &AssetMintOutput, approver: &Option
, @@ -231,7 +231,7 @@ impl<'db> ShardLevelState<'db> { } } - let asset_type = Blake::blake(transaction_tracker); + let asset_type = Blake::blake(*transaction_tracker); if self.asset_scheme(asset_type)?.is_some() { return Err(RuntimeError::AssetSchemeDuplicated { tracker: transaction_tracker, @@ -395,7 +395,7 @@ impl<'db> ShardLevelState<'db> { fn increase_asset_supply( &mut self, - transaction_tracker: H256, + transaction_tracker: Tracker, seq: usize, sender: &Address, approvers: &[Address], @@ -605,7 +605,7 @@ impl<'db> ShardLevelState<'db> { let mut asset_scheme = self.get_asset_scheme_mut(self.shard_id, asset_type)?; asset_scheme.increase_supply(quantity)?; - self.create_asset(*tx_hash, 0, asset_type, *lock_script_hash, parameters.to_vec(), quantity)?; + self.create_asset((*tx_hash).into(), 0, asset_type, *lock_script_hash, parameters.to_vec(), quantity)?; ctrace!(TX, "Created Wrapped CCC on {}:{}:{}", self.shard_id, tx_hash, 0); Ok(()) } @@ -647,7 +647,7 @@ impl<'db> ShardLevelState<'db> { Ok(()) } - fn kill_asset(&mut self, tracker: H256, index: usize) { + fn kill_asset(&mut self, tracker: Tracker, index: usize) { self.cache.remove_asset(&OwnedAssetAddress::new(tracker, index, self.shard_id)); } @@ -675,7 +675,7 @@ impl<'db> ShardLevelState<'db> { pub fn create_asset( &self, - tracker: H256, + tracker: Tracker, index: usize, asset_type: H160, lock_script_hash: H160, @@ -700,7 +700,7 @@ impl<'db> ShardStateView for ShardLevelState<'db> { self.cache.asset_scheme(&AssetSchemeAddress::new(asset_type, self.shard_id), &trie) } - fn asset(&self, tracker: H256, index: usize) -> Result, TrieError> { + fn asset(&self, tracker: Tracker, index: usize) -> Result, TrieError> { let db = self.db.borrow(); let trie = TrieFactory::readonly(db.as_hashdb(), &self.root)?; self.cache.asset(&OwnedAssetAddress::new(tracker, index, self.shard_id), &trie) @@ -783,7 +783,7 @@ impl<'db> ShardStateView for ReadOnlyShardLevelState<'db> { self.cache.asset_scheme(&AssetSchemeAddress::new(asset_type, self.shard_id), &trie) } - fn asset(&self, tracker: H256, index: usize) -> Result, TrieError> { + fn asset(&self, tracker: Tracker, index: usize) -> Result, TrieError> { let db = self.db.borrow(); let trie = TrieFactory::readonly(db.as_hashdb(), &self.root)?; self.cache.asset(&OwnedAssetAddress::new(tracker, index, self.shard_id), &trie) @@ -825,7 +825,7 @@ mod tests { asset_mint!(asset_mint_output!(lock_script_hash, parameters, amount), metadata.clone(), approver: approver); let transaction_tracker = transaction.tracker(); - let asset_type = Blake::blake(transaction_tracker); + let asset_type = Blake::blake(*transaction_tracker); assert_eq!(Ok(()), state.apply(&transaction, &sender, &[sender], &[], &get_test_client(), 0, 0)); check_shard_level_state!(state, [ @@ -851,7 +851,7 @@ mod tests { approver: approver ); let transaction_tracker = transaction.tracker(); - let asset_type = Blake::blake(transaction_tracker); + let asset_type = Blake::blake(*transaction_tracker); assert_eq!(Ok(()), state.apply(&transaction, &sender, &[sender], &[], &get_test_client(), 0, 0)); @@ -879,7 +879,7 @@ mod tests { ); let transaction_tracker = transaction.tracker(); - let asset_type = Blake::blake(transaction_tracker); + let asset_type = Blake::blake(*transaction_tracker); assert_eq!(Ok(()), state.apply(&transaction, &sender, &[sender], &[], &get_test_client(), 0, 0)); assert_eq!( @@ -910,7 +910,7 @@ mod tests { let mint = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata.clone(), approver: approver); let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); @@ -949,7 +949,7 @@ mod tests { let amount = 30; let mint = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata.clone()); let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); @@ -999,7 +999,7 @@ mod tests { allowed_script_hashes: allowed_script_hashes.clone() ); let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); @@ -1047,7 +1047,7 @@ mod tests { allowed_script_hashes: allowed_script_hashes.clone() ); let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); @@ -1087,7 +1087,7 @@ mod tests { let amount = 30; let mint = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata.clone()); let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); @@ -1124,7 +1124,7 @@ mod tests { let amount = 30; let mint = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata.clone()); let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); @@ -1188,7 +1188,7 @@ mod tests { let mint = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata.clone(), registrar: registrar); let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); @@ -1235,7 +1235,7 @@ mod tests { let mint = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata.clone(), registrar: registrar); let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); @@ -1269,7 +1269,7 @@ mod tests { let amount = 30; let mint = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata.clone()); let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); @@ -1316,12 +1316,12 @@ mod tests { let metadata1 = "metadata".to_string(); let mint1 = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata1.clone()); let mint_tracker1 = mint1.tracker(); - let asset_type1 = Blake::blake(mint_tracker1); + let asset_type1 = Blake::blake(*mint_tracker1); let metadata2 = "metadata2".to_string(); let mint2 = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata2.clone()); let mint_tracker2 = mint2.tracker(); - let asset_type2 = Blake::blake(mint_tracker2); + let asset_type2 = Blake::blake(*mint_tracker2); assert_eq!(Ok(()), state.apply(&mint1, &sender, &[sender], &[], &get_test_client(), 0, 0)); @@ -1381,7 +1381,7 @@ mod tests { let wrap_ccc_tracker = wrap_ccc.tracker(); let asset_type = H160::zero(); - assert_eq!(wrap_ccc_tracker, tx_hash); + assert_eq!(*wrap_ccc_tracker, tx_hash); assert_eq!(Ok(()), state.apply(&wrap_ccc, &sender, &[sender], &[], &get_test_client(), 0, 0)); check_shard_level_state!(state, [ @@ -1417,7 +1417,7 @@ mod tests { let wrap_ccc = asset_wrap_ccc!(tx_hash, asset_wrap_ccc_output!(lock_script_hash, amount)); let wrap_ccc_tracker = wrap_ccc.tracker(); - assert_eq!(wrap_ccc_tracker, tx_hash); + assert_eq!(*wrap_ccc_tracker, tx_hash); assert_eq!(Ok(()), state.apply(&wrap_ccc, &sender, &[sender], &[], &get_test_client(), 0, 0)); let asset_type = H160::zero(); @@ -1478,7 +1478,7 @@ mod tests { let amount = 30; let mint = asset_mint!(asset_mint_output!(lock_script_hash, supply: amount), metadata.clone()); let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); @@ -1550,7 +1550,7 @@ mod tests { approver: approver ); let transaction_tracker = transaction.tracker(); - let asset_type = Blake::blake(transaction_tracker); + let asset_type = Blake::blake(*transaction_tracker); assert_eq!(Ok(()), state.apply(&transaction, &sender, &[sender], &[], &get_test_client(), 0, 0)); @@ -1578,7 +1578,7 @@ mod tests { asset_mint!(asset_mint_output!(lock_script_hash, parameters: parameters), metadata, approver: approver); let transaction_tracker = transaction.tracker(); - let asset_type = Blake::blake(transaction_tracker); + let asset_type = Blake::blake(*transaction_tracker); assert_eq!( Err(StateError::Runtime(RuntimeError::InsufficientPermission)), @@ -1612,7 +1612,7 @@ mod tests { ); let transaction_tracker = transaction.tracker(); - let asset_type = Blake::blake(transaction_tracker); + let asset_type = Blake::blake(*transaction_tracker); check_shard_level_state!(state, [ (scheme: (asset_type)), @@ -1648,7 +1648,7 @@ mod tests { ); let transaction_tracker = transaction.tracker(); - let asset_type = Blake::blake(transaction_tracker); + let asset_type = Blake::blake(*transaction_tracker); check_shard_level_state!(state, [ (scheme: (asset_type)), @@ -1681,7 +1681,7 @@ mod tests { ); let transaction_tracker = transaction.tracker(); - let asset_type = Blake::blake(transaction_tracker); + let asset_type = Blake::blake(*transaction_tracker); assert_eq!(Ok(()), state.apply(&transaction, &sender, &[], &[], &get_test_client(), 0, 0)); @@ -1710,7 +1710,7 @@ mod tests { ); let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); @@ -1757,7 +1757,7 @@ mod tests { ); let mint_tracker = mint.tracker(); - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); assert_eq!(Ok(()), state.apply(&mint, &sender, &[sender], &[], &get_test_client(), 0, 0)); diff --git a/state/src/impls/test_helper.rs b/state/src/impls/test_helper.rs index 78544c9b71..a05729e7c2 100644 --- a/state/src/impls/test_helper.rs +++ b/state/src/impls/test_helper.rs @@ -641,45 +641,45 @@ macro_rules! check_shard_level_state { check_shard_level_state!($state, [$($x),*]); }; - ($state:expr, [(asset: ($tx_hash:expr, $index:expr) => { asset_type: $asset_type:expr, quantity: $quantity:expr }) $(,$x:tt)*]) => { - let asset = $state.asset($tx_hash, $index) - .expect(&format!("Cannot read Asset from {}:{}:{}", $state.shard_id(), $tx_hash, $index)) - .expect(&format!("Asset for {}:{}:{} not exist", $state.shard_id(), $tx_hash, $index)); + ($state:expr, [(asset: ($tracker:expr, $index:expr) => { asset_type: $asset_type:expr, quantity: $quantity:expr }) $(,$x:tt)*]) => { + let asset = $state.asset($tracker, $index) + .expect(&format!("Cannot read Asset from {}:{}:{}", $state.shard_id(), $tracker, $index)) + .expect(&format!("Asset for {}:{}:{} not exist", $state.shard_id(), $tracker, $index)); assert_eq!(&$asset_type, asset.asset_type()); assert_eq!($quantity, asset.quantity()); check_shard_level_state!($state, [$($x),*]); }; - ($state:expr, [(asset: ($tx_hash:expr, $index:expr) => { asset_type: $asset_type:expr, quantity: $quantity:expr }) $(,$x:tt)*]) => { - let asset = $state.asset($tx_hash, $index) - .expect(&format!("Cannot read Asset from {}:{}:{}", $state.shard_id(), $tx_hash, $index)) - .expect(&format!("Asset for {}:{}:{} not exist", $state.shard_id(), $tx_hash, $index)); + ($state:expr, [(asset: ($tracker:expr, $index:expr) => { asset_type: $asset_type:expr, quantity: $quantity:expr }) $(,$x:tt)*]) => { + let asset = $state.asset($tracker, $index) + .expect(&format!("Cannot read Asset from {}:{}:{}", $state.shard_id(), $tracker, $index)) + .expect(&format!("Asset for {}:{}:{} not exist", $state.shard_id(), $tracker, $index)); assert_eq!(&$asset_type, asset.asset_type()); assert_eq!($quantity, asset.quantity()); check_shard_level_state!($state, [$($x),*]); }; - ($state:expr, [(asset: ($tx_hash:expr, $index:expr) => { asset_type: $asset_type:expr, quantity: $quantity:expr }) $(,$x:tt)*]) => { - let asset = $state.asset($tx_hash, $index) - .expect(&format!("Cannot read Asset from {}:{}:{}", $state.shard_id(), $tx_hash, $index)) - .expect(&format!("Asset for {}:{}:{} not exist", $state.shard_id(), $tx_hash, $index)); + ($state:expr, [(asset: ($tracker:expr, $index:expr) => { asset_type: $asset_type:expr, quantity: $quantity:expr }) $(,$x:tt)*]) => { + let asset = $state.asset($tracker, $index) + .expect(&format!("Cannot read Asset from {}:{}:{}", $state.shard_id(), $tracker, $index)) + .expect(&format!("Asset for {}:{}:{} not exist", $state.shard_id(), $tracker, $index)); assert_eq!(&$asset_type, asset.asset_type()); assert_eq!($quantity, asset.quantity()); check_shard_level_state!($state, [$($x),*]); }; - ($state:expr, [(asset: ($tx_hash:expr, $index:expr) => { asset_type: $asset_type:expr, quantity: $quantity:expr, lock_script_hash: $lock_script_hash:expr }) $(,$x:tt)*]) => { - let asset = $state.asset($tx_hash, $index) - .expect(&format!("Cannot read Asset from {}:{}:{}", $state.shard_id(), $tx_hash, $index)) - .expect(&format!("Asset for {}:{}:{} not exist", $state.shard_id(), $tx_hash, $index)); + ($state:expr, [(asset: ($tracker:expr, $index:expr) => { asset_type: $asset_type:expr, quantity: $quantity:expr, lock_script_hash: $lock_script_hash:expr }) $(,$x:tt)*]) => { + let asset = $state.asset($tracker, $index) + .expect(&format!("Cannot read Asset from {}:{}:{}", $state.shard_id(), $tracker, $index)) + .expect(&format!("Asset for {}:{}:{} not exist", $state.shard_id(), $tracker, $index)); assert_eq!(&$asset_type, asset.asset_type()); assert_eq!($quantity, asset.quantity()); assert_eq!(&$lock_script_hash, asset.lock_script_hash()); check_shard_level_state!($state, [$($x),*]); }; - ($state:expr, [(asset: ($tx_hash:expr, $index:expr)) $(,$x:tt)*]) => { - assert_eq!(Ok(None), $state.asset($tx_hash, $index)); + ($state:expr, [(asset: ($tracker:expr, $index:expr)) $(,$x:tt)*]) => { + assert_eq!(Ok(None), $state.asset($tracker, $index)); check_shard_level_state!($state, [$($x),*]); }; diff --git a/state/src/impls/top_level.rs b/state/src/impls/top_level.rs index 954c9ec527..50bdc9befc 100644 --- a/state/src/impls/top_level.rs +++ b/state/src/impls/top_level.rs @@ -46,6 +46,8 @@ use ctypes::transaction::{ Action, AssetOutPoint, AssetTransferInput, AssetWrapCCCOutput, ShardTransaction, Transaction, }; use ctypes::util::unexpected::Mismatch; +#[cfg(test)] +use ctypes::Tracker; use ctypes::{BlockNumber, CommonParams, ShardId}; use cvm::ChainTimeInfo; use hashdb::AsHashDB; @@ -745,7 +747,7 @@ impl TopLevelState { fn create_asset( &mut self, shard_id: ShardId, - tx_hash: H256, + tracker: Tracker, index: usize, asset_type: H160, lock_script_hash: H160, @@ -756,7 +758,7 @@ impl TopLevelState { Some(shard_root) => { let mut shard_cache = self.shard_caches.entry(shard_id).or_default(); let state = ShardLevelState::from_existing(shard_id, &mut self.db, shard_root, &mut shard_cache)?; - state.create_asset(tx_hash, index, asset_type, lock_script_hash, parameters, amount)?; + state.create_asset(tracker, index, asset_type, lock_script_hash, parameters, amount)?; Ok(true) } None => Ok(false), @@ -1477,7 +1479,7 @@ mod tests_tx { let (master_account, master_public, _) = address(); let (regular_account, regular_public, _) = address(); let type_of_wccc = H160::zero(); - let tracker = H256::random(); + let tracker = H256::random().into(); let lock_script_hash = H160::from("0xb042ad154a3359d276835c903587ebafefea22af"); let shard_id = 0; set_top_level_state!(state, [ @@ -1617,13 +1619,13 @@ mod tests_tx { let (_, regular_public, _) = address(); let shard_id = 0x0; - let mint_tracker = H256::random(); + let mint_tracker = Tracker::from(H256::random()); let mut state = get_temp_state(); let metadata = "metadata".to_string(); let lock_script_hash = H160::from("0xb042ad154a3359d276835c903587ebafefea22af"); let amount = 30; - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); set_top_level_state!(state, [ (account: sender => balance: 25), @@ -1653,13 +1655,13 @@ mod tests_tx { let (_, regular_public, regular_private) = address(); let shard_id = 0x0; - let mint_tracker = H256::random(); + let mint_tracker = Tracker::from(H256::random()); let mut state = get_temp_state(); let metadata = "metadata".to_string(); let lock_script_hash = H160::from("0xb042ad154a3359d276835c903587ebafefea22af"); let amount = 30; - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); set_top_level_state!(state, [ (account: sender => balance: 25), @@ -1813,7 +1815,7 @@ mod tests_tx { approver: approver ); let transaction_tracker = transaction.tracker().unwrap(); - let asset_type = Blake::blake(transaction_tracker); + let asset_type = Blake::blake(*transaction_tracker); let tx = transaction!(fee: 11, transaction); assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); @@ -1849,7 +1851,7 @@ mod tests_tx { approver: approver ); let transaction_tracker = transaction.tracker().unwrap(); - let asset_type = Blake::blake(transaction_tracker); + let asset_type = Blake::blake(*transaction_tracker); let tx = transaction!(fee: 5, transaction); assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); @@ -1880,7 +1882,7 @@ mod tests_tx { let mint = mint_asset!(Box::new(asset_mint_output!(lock_script_hash, supply: amount)), metadata.clone()); let mint_tracker = mint.tracker().unwrap(); let mint_tx = transaction!(fee: 20, mint); - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); assert_eq!(Ok(()), state.apply(&mint_tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); @@ -1991,11 +1993,13 @@ mod tests_tx { check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 100 - 11 - 30)), (account: receiver), - (asset: (tx_hash, 0, 0) => { asset_type: asset_type, quantity: quantity }) + (asset: (Tracker::from(tx_hash), 0, 0) => { asset_type: asset_type, quantity: quantity }) ]); - let unwrap_ccc_tx = - unwrap_ccc!(asset_transfer_input!(asset_out_point!(tx_hash, 0, asset_type, 30), vec![0x01]), receiver); + let unwrap_ccc_tx = unwrap_ccc!( + asset_transfer_input!(asset_out_point!(Tracker::from(tx_hash), 0, asset_type, 30), vec![0x01]), + receiver + ); let tx = transaction!(seq: 1, fee: 11, unwrap_ccc_tx); assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); @@ -2003,7 +2007,7 @@ mod tests_tx { check_top_level_state!(state, [ (account: sender => (seq: 2, balance: 100 - 11 - 30 - 11)), (account: receiver => (seq: 0, balance: 30)), - (asset: (tx_hash, 0, 0)) + (asset: (Tracker::from(tx_hash), 0, 0)) ]); } @@ -2033,12 +2037,15 @@ mod tests_tx { check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 100 - 11 - 30)), (account: receiver), - (asset: (tx_hash, 0, 0) => { asset_type: asset_type, quantity: quantity }) + (asset: (Tracker::from(tx_hash), 0, 0) => { asset_type: asset_type, quantity: quantity }) ]); let failed_lock_script = vec![0x02]; let unwrap_ccc_tx = unwrap_ccc!( - asset_transfer_input!(asset_out_point!(tx_hash, 0, asset_type, 30), failed_lock_script.clone()), + asset_transfer_input!( + asset_out_point!(Tracker::from(tx_hash), 0, asset_type, 30), + failed_lock_script.clone() + ), receiver ); let tx = transaction!(seq: 1, fee: 11, unwrap_ccc_tx); @@ -2055,7 +2062,7 @@ mod tests_tx { check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 100 - 11 - 30)), (account: receiver), - (asset: (tx_hash, 0, 0) => { asset_type: asset_type, quantity: quantity }) + (asset: (Tracker::from(tx_hash), 0, 0) => { asset_type: asset_type, quantity: quantity }) ]); } @@ -2116,13 +2123,13 @@ mod tests_tx { let asset_type = H160::zero(); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 100 - 30 - 11)), - (asset: (tx_hash, 0, 0) => { asset_type: asset_type, quantity: quantity }) + (asset: (Tracker::from(tx_hash), 0, 0) => { asset_type: asset_type, quantity: quantity }) ]); let lock_script_hash_burn = H160::from("ca5d3fa0a6887285ef6aa85cb12960a2b6706e00"); let random_lock_script_hash = H160::random(); let transfer_tx = transfer_asset!( - inputs: asset_transfer_inputs![(asset_out_point!(tx_hash, 0, asset_type, 30), vec![0x30, 0x01])], + inputs: asset_transfer_inputs![(asset_out_point!(Tracker::from(tx_hash), 0, asset_type, 30), vec![0x30, 0x01])], asset_transfer_outputs![ (lock_script_hash, vec![vec![1]], asset_type, 10), (lock_script_hash_burn, asset_type, 5), @@ -2137,7 +2144,7 @@ mod tests_tx { check_top_level_state!(state, [ (account: sender => (seq: 2, balance: 100 - 30 - 11 - 11)), - (asset: (tx_hash, 0, 0)), + (asset: (Tracker::from(tx_hash), 0, 0)), (asset: (transfer_tx_tracker, 0, 0) => { asset_type: asset_type, quantity: 10 }), (asset: (transfer_tx_tracker, 1, 0) => { asset_type: asset_type, quantity: 5 }), (asset: (transfer_tx_tracker, 2, 0) => { asset_type: asset_type, quantity: 15 }) @@ -2279,7 +2286,7 @@ mod tests_tx { let shard_id = 3; check_top_level_state!(state, [ - (asset: (H256::random(), 0, shard_id)) + (asset: (Tracker::from(H256::random()), 0, shard_id)) ]); } @@ -2413,7 +2420,7 @@ mod tests_tx { check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 20 - 5)), (shard: 0 => owners: vec![sender], users: vec![]), - (asset: (H256::random(), 0, invalid_shard_id)) + (asset: (Tracker::from(H256::random()), 0, invalid_shard_id)) ]); } @@ -2435,7 +2442,7 @@ mod tests_tx { check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 20 - 5)), (shard: 0 => owners: vec![sender], users: users), - (asset: (H256::random(), 0, invalid_shard_id)) + (asset: (Tracker::from(H256::random()), 0, invalid_shard_id)) ]); } @@ -2484,7 +2491,7 @@ mod tests_tx { let asset_type = H160::zero(); let transfer = transfer_asset!( inputs: - asset_transfer_inputs![(asset_out_point!(H256::random(), 0, asset_type, shard_id, 30), vec![ + asset_transfer_inputs![(asset_out_point!(Tracker::from(H256::random()), 0, asset_type, shard_id, 30), vec![ 0x30, 0x01 ])], asset_transfer_outputs![ @@ -2664,7 +2671,7 @@ mod tests_tx { let mint = mint_asset!(Box::new(asset_mint_output!(lock_script_hash, parameters, amount)), metadata.clone()); let mint_tracker = mint.tracker().unwrap(); - let asset_type = Blake::blake(mint_tracker); + let asset_type = Blake::blake(*mint_tracker); let tx = transaction!(fee: 20, mint); @@ -2742,10 +2749,10 @@ mod tests_tx { fn transfer_failed_if_the_input_amount_is_not_valid() { let shard_id = 0; - let mint_tracker1 = H256::random(); - let mint_tracker2 = H256::random(); - let asset_type1 = Blake::blake(mint_tracker1); - let asset_type2 = Blake::blake(mint_tracker2); + let mint_tracker1 = Tracker::from(H256::random()); + let mint_tracker2 = Tracker::from(H256::random()); + let asset_type1 = Blake::blake(*mint_tracker1); + let asset_type2 = Blake::blake(*mint_tracker2); let lock_script_hash = H160::from("0xb042ad154a3359d276835c903587ebafefea22af"); @@ -2806,10 +2813,10 @@ mod tests_tx { let shard3 = 3; let shard4 = 4; - let mint_tracker3 = H256::random(); - let mint_tracker4 = H256::random(); - let asset_type3 = Blake::blake(mint_tracker3); - let asset_type4 = Blake::blake(mint_tracker4); + let mint_tracker3 = Tracker::from(H256::random()); + let mint_tracker4 = Tracker::from(H256::random()); + let asset_type3 = Blake::blake(*mint_tracker3); + let asset_type4 = Blake::blake(*mint_tracker4); let lock_script_hash = H160::from("0xb042ad154a3359d276835c903587ebafefea22af"); let (sender, signer_public, _) = address(); @@ -2873,10 +2880,10 @@ mod tests_tx { let shard3 = 3; let shard4 = 4; - let mint_tracker3 = H256::random(); - let mint_tracker4 = H256::random(); - let asset_type3 = Blake::blake(mint_tracker3); - let asset_type4 = Blake::blake(mint_tracker4); + let mint_tracker3 = Tracker::from(H256::random()); + let mint_tracker4 = Tracker::from(H256::random()); + let asset_type3 = Blake::blake(*mint_tracker3); + let asset_type4 = Blake::blake(*mint_tracker4); let lock_script_hash = H160::from("0xb042ad154a3359d276835c903587ebafefea22af"); let (sender, signer_public, _) = address(); @@ -2940,10 +2947,10 @@ mod tests_tx { let shard3 = 3; let shard4 = 4; - let mint_tracker3 = H256::random(); - let mint_tracker4 = H256::random(); - let asset_type3 = Blake::blake(mint_tracker3); - let asset_type4 = Blake::blake(mint_tracker4); + let mint_tracker3 = Tracker::from(H256::random()); + let mint_tracker4 = Tracker::from(H256::random()); + let asset_type3 = Blake::blake(*mint_tracker3); + let asset_type4 = Blake::blake(*mint_tracker4); let lock_script_hash = H160::from("0xb042ad154a3359d276835c903587ebafefea22af"); let (sender, signer_public, _) = address(); @@ -3014,10 +3021,10 @@ mod tests_tx { let shard3 = 3; let shard4 = 4; - let mint_tracker3 = H256::random(); - let mint_tracker4 = H256::random(); - let asset_type3 = Blake::blake(mint_tracker3); - let asset_type4 = Blake::blake(mint_tracker4); + let mint_tracker3 = Tracker::from(H256::random()); + let mint_tracker4 = Tracker::from(H256::random()); + let asset_type3 = Blake::blake(*mint_tracker3); + let asset_type4 = Blake::blake(*mint_tracker4); let lock_script_hash = H160::from("0xb042ad154a3359d276835c903587ebafefea22af"); let (sender, signer_public, _) = address(); @@ -3193,7 +3200,7 @@ mod tests_tx { approver: regular_account ); let transaction_tracker = transaction.tracker().unwrap(); - let asset_type = Blake::blake(transaction_tracker); + let asset_type = Blake::blake(*transaction_tracker); let tx = transaction!(fee: 11, transaction); assert_eq!( @@ -3236,7 +3243,7 @@ mod tests_tx { registrar: regular_account ); let transaction_tracker = transaction.tracker().unwrap(); - let asset_type = Blake::blake(transaction_tracker); + let asset_type = Blake::blake(*transaction_tracker); let tx = transaction!(fee: 11, transaction); assert_eq!( diff --git a/state/src/item/asset.rs b/state/src/item/asset.rs index 3b7aabf824..1f1cbd8954 100644 --- a/state/src/item/asset.rs +++ b/state/src/item/asset.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use ctypes::ShardId; +use ctypes::{ShardId, Tracker}; use primitives::{Bytes, H160, H256}; use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; @@ -152,11 +152,11 @@ pub struct OwnedAssetAddress(H256); impl_address!(SHARD, OwnedAssetAddress, PREFIX); impl OwnedAssetAddress { - pub fn new(transaction_tracker: H256, index: usize, shard_id: ShardId) -> Self { + pub fn new(tracker: Tracker, index: usize, shard_id: ShardId) -> Self { debug_assert_eq!(::std::mem::size_of::(), ::std::mem::size_of::()); let index = index as u64; - Self::from_hash_with_shard_id(transaction_tracker, index, shard_id) + Self::from_hash_with_shard_id(*tracker, index, shard_id) } } @@ -168,7 +168,7 @@ mod tests { #[test] fn asset_from_address() { - let tx_id = { + let tracker = { let mut address; 'address: loop { address = H256::random(); @@ -182,11 +182,11 @@ mod tests { } break } - address + address.into() }; let shard_id = 0xBEEF; - let address1 = OwnedAssetAddress::new(tx_id, 0, shard_id); - let address2 = OwnedAssetAddress::new(tx_id, 1, shard_id); + let address1 = OwnedAssetAddress::new(tracker, 0, shard_id); + let address2 = OwnedAssetAddress::new(tracker, 1, shard_id); assert_ne!(address1, address2); assert_eq!(address1[0..2], [PREFIX, 0]); assert_eq!(address1[2..4], [0xBE, 0xEF]); // shard id @@ -229,7 +229,7 @@ mod tests { #[test] fn shard_id() { - let origin = H256::random(); + let origin = H256::random().into(); let shard_id = 0xCAA; let asset_address = OwnedAssetAddress::new(origin, 2, shard_id); assert_eq!(shard_id, asset_address.shard_id()); diff --git a/state/src/item/asset_scheme.rs b/state/src/item/asset_scheme.rs index 80fdb7972d..d1194f4a38 100644 --- a/state/src/item/asset_scheme.rs +++ b/state/src/item/asset_scheme.rs @@ -17,7 +17,7 @@ use ccrypto::Blake; use ckey::Address; use ctypes::errors::RuntimeError; -use ctypes::ShardId; +use ctypes::{ShardId, Tracker}; use primitives::{H160, H256}; use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; @@ -219,8 +219,8 @@ impl AssetSchemeAddress { Self::from_hash_with_shard_id(asset_type, index, shard_id) } - pub fn new_from_tracker(tracker: H256, shard_id: ShardId) -> Self { - let asset_type = Blake::blake(tracker); + pub fn new_from_tracker(tracker: Tracker, shard_id: ShardId) -> Self { + let asset_type = Blake::blake(*tracker); Self::new(asset_type, shard_id) } } diff --git a/state/src/tests.rs b/state/src/tests.rs index 3de024e8e2..a911ab9248 100644 --- a/state/src/tests.rs +++ b/state/src/tests.rs @@ -18,7 +18,7 @@ pub mod helpers { use std::sync::Arc; use cmerkle::TrieFactory; - use ctypes::BlockNumber; + use ctypes::{BlockNumber, Tracker}; use cvm::ChainTimeInfo; use hashdb::AsHashDB; use kvdb::KeyValueDB; @@ -33,11 +33,11 @@ pub mod helpers { pub struct TestClient {} impl ChainTimeInfo for TestClient { - fn transaction_block_age(&self, _: &H256, _parent_block_number: BlockNumber) -> Option { + fn transaction_block_age(&self, _: &Tracker, _parent_block_number: BlockNumber) -> Option { Some(0) } - fn transaction_time_age(&self, _: &H256, _parent_block_timestamp: u64) -> Option { + fn transaction_time_age(&self, _: &Tracker, _parent_block_timestamp: u64) -> Option { Some(0) } } diff --git a/state/src/traits.rs b/state/src/traits.rs index 164e2e53fa..f54448e4c1 100644 --- a/state/src/traits.rs +++ b/state/src/traits.rs @@ -17,7 +17,7 @@ use ckey::{public_to_address, Address, Public, Signature}; use cmerkle::Result as TrieResult; use ctypes::transaction::ShardTransaction; -use ctypes::{BlockNumber, CommonParams, ShardId}; +use ctypes::{BlockNumber, CommonParams, ShardId, Tracker}; use cvm::ChainTimeInfo; use primitives::{Bytes, H160, H256}; @@ -116,7 +116,7 @@ pub trait TopStateView { } /// Get the asset. - fn asset(&self, shard_id: ShardId, tracker: H256, index: usize) -> TrieResult> { + fn asset(&self, shard_id: ShardId, tracker: Tracker, index: usize) -> TrieResult> { match self.shard_state(shard_id)? { None => Ok(None), Some(state) => state.asset(tracker, index), @@ -132,7 +132,7 @@ pub trait ShardStateView { /// Get the asset scheme. fn asset_scheme(&self, asset_type: H160) -> TrieResult>; /// Get the asset. - fn asset(&self, tracker: H256, index: usize) -> TrieResult>; + fn asset(&self, tracker: Tracker, index: usize) -> TrieResult>; } pub trait ShardState { diff --git a/types/src/errors/runtime_error.rs b/types/src/errors/runtime_error.rs index 63d0fc34de..2368a95fa0 100644 --- a/types/src/errors/runtime_error.rs +++ b/types/src/errors/runtime_error.rs @@ -17,12 +17,12 @@ use std::fmt::{Display, Formatter, Result as FormatResult}; use ckey::Address; -use primitives::{H160, H256}; +use primitives::H160; use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; use super::TaggedRlp; use crate::util::unexpected::Mismatch; -use crate::ShardId; +use crate::{ShardId, Tracker}; #[derive(Debug, PartialEq, Clone, Eq, Serialize)] #[serde(tag = "type", content = "content")] @@ -30,11 +30,11 @@ pub enum Error { /// Desired input asset not found AssetNotFound { shard_id: ShardId, - tracker: H256, + tracker: Tracker, index: usize, }, AssetSchemeDuplicated { - tracker: H256, + tracker: Tracker, shard_id: ShardId, }, /// Desired input asset scheme not found @@ -54,7 +54,7 @@ pub enum Error { /// Script execution result is `Fail` FailedToUnlock { shard_id: ShardId, - tracker: H256, + tracker: Tracker, index: usize, reason: UnlockFailureReason, }, @@ -69,7 +69,7 @@ pub enum Error { InsufficientPermission, InvalidAssetQuantity { shard_id: ShardId, - tracker: H256, + tracker: Tracker, index: usize, expected: u64, got: u64, diff --git a/types/src/errors/syntax_error.rs b/types/src/errors/syntax_error.rs index 6f8c246f00..c9924737f7 100644 --- a/types/src/errors/syntax_error.rs +++ b/types/src/errors/syntax_error.rs @@ -17,18 +17,18 @@ use std::fmt::{Display, Formatter, Result as FormatResult}; use ckey::NetworkId; -use primitives::{H160, H256}; +use primitives::H160; use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; use super::TaggedRlp; -use crate::ShardId; +use crate::{ShardId, Tracker}; #[derive(Debug, PartialEq, Clone, Eq, Serialize)] #[serde(tag = "type", content = "content")] pub enum Error { /// There are burn/inputs that shares same previous output DuplicatedPreviousOutput { - tracker: H256, + tracker: Tracker, index: usize, }, EmptyShardOwners(ShardId), diff --git a/types/src/lib.rs b/types/src/lib.rs index 95d5b2ae2c..cb3229e222 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -29,6 +29,7 @@ extern crate serde_json; mod block_hash; mod common_params; +mod tracker; pub mod errors; pub mod header; @@ -41,3 +42,4 @@ pub type ShardId = u16; pub use block_hash::BlockHash; pub use common_params::CommonParams; pub use header::Header; +pub use tracker::Tracker; diff --git a/types/src/tracker.rs b/types/src/tracker.rs new file mode 100644 index 0000000000..ac59019a67 --- /dev/null +++ b/types/src/tracker.rs @@ -0,0 +1,109 @@ +// Copyright 2019 Kodebox, Inc. +// This file is part of CodeChain. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +use std::fmt::{self, Display, Formatter}; +use std::ops::Deref; + +use primitives::H256; +use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; + + +#[derive(Clone, Copy, Default, Eq, Hash, PartialEq, Debug, Deserialize, Serialize)] +pub struct Tracker(H256); + +impl From for Tracker { + fn from(h: H256) -> Self { + Self(h) + } +} + +impl Deref for Tracker { + type Target = H256; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Display for Tracker { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> { + self.0.fmt(f) + } +} + +impl Encodable for Tracker { + fn rlp_append(&self, s: &mut RlpStream) { + self.0.rlp_append(s); + } +} + +impl Decodable for Tracker { + fn decode(rlp: &UntrustedRlp) -> Result { + Ok(H256::decode(rlp)?.into()) + } +} + +#[cfg(test)] +mod tests { + use std::collections::hash_map::DefaultHasher; + use std::hash::{Hash, Hasher}; + + use rlp::{self, rlp_encode_and_decode_test}; + + use super::*; + + #[test] + fn hash_of_tracker_and_h256_are_the_same() { + let h256 = H256::random(); + let tracker = Tracker(h256); + + let mut hasher_of_h256 = DefaultHasher::new(); + let mut hasher_of_tracker = DefaultHasher::new(); + + h256.hash(&mut hasher_of_h256); + tracker.hash(&mut hasher_of_tracker); + + assert_eq!(hasher_of_h256.finish(), hasher_of_tracker.finish()); + } + + #[test] + fn rlp_of_tracker_can_be_decoded_to_h256() { + let h256 = H256::random(); + let tracker = Tracker(h256); + + let encoded = rlp::encode(&tracker); + let decoded = rlp::decode(&*encoded); + + assert_eq!(h256, decoded); + } + + #[test] + fn rlp_of_h256_can_be_decoded_to_tracker() { + let h256 = H256::random(); + + let encoded = rlp::encode(&h256); + let decoded = rlp::decode(&*encoded); + + let tracker = Tracker(h256); + assert_eq!(tracker, decoded); + } + + #[test] + fn rlp() { + rlp_encode_and_decode_test!(Tracker(H256::random())); + } +} diff --git a/types/src/transaction/action.rs b/types/src/transaction/action.rs index 22e321af63..66884afdc2 100644 --- a/types/src/transaction/action.rs +++ b/types/src/transaction/action.rs @@ -23,7 +23,7 @@ use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; use crate::errors::SyntaxError; use crate::transaction::{AssetMintOutput, AssetTransferInput, AssetTransferOutput, ShardTransaction}; -use crate::{CommonParams, ShardId}; +use crate::{CommonParams, ShardId, Tracker}; const PAY: u8 = 0x02; const SET_REGULAR_KEY: u8 = 0x03; @@ -158,7 +158,7 @@ impl Action { } } - pub fn tracker(&self) -> Option { + pub fn tracker(&self) -> Option { self.asset_transaction().map(|tx| tx.tracker()) } diff --git a/types/src/transaction/asset_out_point.rs b/types/src/transaction/asset_out_point.rs index b11c6d2244..be72d0ce14 100644 --- a/types/src/transaction/asset_out_point.rs +++ b/types/src/transaction/asset_out_point.rs @@ -14,13 +14,14 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use primitives::{H160, H256}; +use primitives::H160; use crate::ShardId; +use crate::Tracker; #[derive(Debug, Clone, Eq, PartialEq, RlpDecodable, RlpEncodable)] pub struct AssetOutPoint { - pub tracker: H256, + pub tracker: Tracker, pub index: usize, pub asset_type: H160, pub shard_id: ShardId, diff --git a/types/src/transaction/shard.rs b/types/src/transaction/shard.rs index b417d49fe4..f10032c9a0 100644 --- a/types/src/transaction/shard.rs +++ b/types/src/transaction/shard.rs @@ -21,7 +21,7 @@ use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; use super::{AssetMintOutput, AssetTransferInput, AssetTransferOutput, HashingError, PartialHashing}; use crate::util::tag::Tag; -use crate::ShardId; +use crate::{ShardId, Tracker}; /// Shard Transaction type. #[derive(Debug, Clone, PartialEq, Eq)] @@ -79,15 +79,15 @@ pub struct AssetWrapCCCOutput { } impl ShardTransaction { - pub fn tracker(&self) -> H256 { + pub fn tracker(&self) -> Tracker { if let ShardTransaction::WrapCCC { tx_hash, .. } = self { - return *tx_hash + return (*tx_hash).into() } - blake256(&*self.rlp_bytes()) + blake256(&*self.rlp_bytes()).into() } pub fn network_id(&self) -> NetworkId { @@ -561,7 +561,7 @@ mod tests { assert!(is_input_and_output_consistent( &[AssetTransferInput { prev_out: AssetOutPoint { - tracker: H256::random(), + tracker: H256::random().into(), index: 0, asset_type, shard_id: 0, @@ -598,7 +598,7 @@ mod tests { &[ AssetTransferInput { prev_out: AssetOutPoint { - tracker: H256::random(), + tracker: H256::random().into(), index: 0, asset_type: asset_type1, shard_id: 0, @@ -610,7 +610,7 @@ mod tests { }, AssetTransferInput { prev_out: AssetOutPoint { - tracker: H256::random(), + tracker: H256::random().into(), index: 0, asset_type: asset_type2, shard_id: 0, @@ -657,7 +657,7 @@ mod tests { &[ AssetTransferInput { prev_out: AssetOutPoint { - tracker: H256::random(), + tracker: H256::random().into(), index: 0, asset_type: asset_type1, shard_id: 0, @@ -669,7 +669,7 @@ mod tests { }, AssetTransferInput { prev_out: AssetOutPoint { - tracker: H256::random(), + tracker: H256::random().into(), index: 0, asset_type: asset_type2, shard_id: 0, @@ -725,7 +725,7 @@ mod tests { assert!(!is_input_and_output_consistent( &[AssetTransferInput { prev_out: AssetOutPoint { - tracker: H256::random(), + tracker: H256::random().into(), index: 0, asset_type, shard_id: 0, @@ -748,7 +748,7 @@ mod tests { assert!(!is_input_and_output_consistent( &[AssetTransferInput { prev_out: AssetOutPoint { - tracker: H256::random(), + tracker: H256::random().into(), index: 0, asset_type, shard_id: 0, @@ -777,7 +777,7 @@ mod tests { assert!(!is_input_and_output_consistent( &[AssetTransferInput { prev_out: AssetOutPoint { - tracker: H256::random(), + tracker: H256::random().into(), index: 0, asset_type, shard_id: 0, @@ -825,7 +825,7 @@ mod tests { burns: vec![], inputs: vec![AssetTransferInput { prev_out: AssetOutPoint { - tracker: H256::random(), + tracker: H256::random().into(), index: 0, asset_type: H160::random(), shard_id: 0, diff --git a/types/src/transaction/transaction.rs b/types/src/transaction/transaction.rs index c3cc26e3ba..c5a9c54aab 100644 --- a/types/src/transaction/transaction.rs +++ b/types/src/transaction/transaction.rs @@ -21,6 +21,7 @@ use rlp::RlpStream; use super::Action; use super::{AssetWrapCCCOutput, ShardTransaction}; +use crate::Tracker; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Transaction { @@ -51,7 +52,7 @@ impl Transaction { blake256(stream.as_raw()) } - pub fn tracker(&self) -> Option { + pub fn tracker(&self) -> Option { let shard_tx = match self.action.clone() { Action::WrapCCC { shard_id, diff --git a/vm/src/executor.rs b/vm/src/executor.rs index ab03140cd7..22a192fdfe 100644 --- a/vm/src/executor.rs +++ b/vm/src/executor.rs @@ -18,7 +18,7 @@ use ccrypto::{blake256, keccak256, ripemd160, sha256, Blake}; use ckey::{verify, Public, Signature, SIGNATURE_LENGTH}; use ctypes::transaction::{AssetTransferInput, HashingError, PartialHashing}; use ctypes::util::tag::Tag; -use ctypes::BlockNumber; +use ctypes::{BlockNumber, Tracker}; use primitives::{H160, H256}; @@ -371,10 +371,10 @@ fn check_multi_sig(tx_hash: &H256, mut pubkey: Vec, mut signatures: Vec< pub trait ChainTimeInfo { /// Get the block height of the transaction. - fn transaction_block_age(&self, tracker: &H256, parent_block_number: BlockNumber) -> Option; + fn transaction_block_age(&self, tracker: &Tracker, parent_block_number: BlockNumber) -> Option; /// Get the how many seconds elapsed since transaction is confirmed, according to block timestamp. - fn transaction_time_age(&self, tracker: &H256, parent_timestamp: u64) -> Option; + fn transaction_time_age(&self, tracker: &Tracker, parent_timestamp: u64) -> Option; } #[cfg(test)] diff --git a/vm/tests/common/mod.rs b/vm/tests/common/mod.rs index 400480733a..2ddc5dc9be 100644 --- a/vm/tests/common/mod.rs +++ b/vm/tests/common/mod.rs @@ -14,9 +14,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use ctypes::BlockNumber; +use ctypes::{BlockNumber, Tracker}; use cvm::ChainTimeInfo; -use primitives::H256; pub struct TestClient { block_age: Option, @@ -39,11 +38,11 @@ impl Default for TestClient { } impl ChainTimeInfo for TestClient { - fn transaction_block_age(&self, _: &H256, _parent_block_number: BlockNumber) -> Option { + fn transaction_block_age(&self, _: &Tracker, _parent_block_number: BlockNumber) -> Option { self.block_age } - fn transaction_time_age(&self, _: &H256, _parent_timestamp: u64) -> Option { + fn transaction_time_age(&self, _: &Tracker, _parent_timestamp: u64) -> Option { self.time_age } } From 1b1d9cf6f106c8cf2b6fa299f7ff82acd97c8ead Mon Sep 17 00:00:00 2001 From: Seulgi Kim Date: Sun, 27 Oct 2019 02:20:03 +0900 Subject: [PATCH 075/105] Distinguish TxHash from H256 --- core/src/block.rs | 6 +- core/src/blockchain/blockchain.rs | 10 +- core/src/blockchain/body_db.rs | 22 +-- core/src/blockchain/extras.rs | 10 +- core/src/blockchain/invoice_db.rs | 28 ++-- core/src/client/chain_notify.rs | 5 +- core/src/client/client.rs | 12 +- core/src/client/mod.rs | 10 +- core/src/client/test_client.rs | 8 +- core/src/consensus/tendermint/worker.rs | 2 +- core/src/encoded.rs | 6 +- core/src/invoice.rs | 5 +- core/src/miner/mem_pool.rs | 13 +- core/src/miner/mem_pool_types.rs | 7 +- core/src/miner/miner.rs | 8 +- core/src/miner/mod.rs | 6 +- core/src/transaction.rs | 21 ++- core/src/types/ids.rs | 9 +- core/src/views/block.rs | 7 +- core/src/views/body.rs | 7 +- rpc/src/v1/impls/chain.rs | 14 +- rpc/src/v1/impls/devel.rs | 4 +- rpc/src/v1/impls/mempool.rs | 7 +- rpc/src/v1/traits/chain.rs | 14 +- rpc/src/v1/traits/mempool.rs | 7 +- rpc/src/v1/types/action.rs | 8 +- rpc/src/v1/types/mod.rs | 5 +- rpc/src/v1/types/transaction.rs | 5 +- state/src/impls/shard_level.rs | 10 +- state/src/impls/top_level.rs | 191 +++++++++++++----------- state/src/item/metadata.rs | 8 +- state/src/traits.rs | 10 +- sync/src/transaction/extension.rs | 10 +- types/src/lib.rs | 2 + types/src/transaction/action.rs | 6 +- types/src/transaction/shard.rs | 6 +- types/src/transaction/transaction.rs | 9 +- types/src/tx_hash.rs | 109 ++++++++++++++ 38 files changed, 374 insertions(+), 253 deletions(-) create mode 100644 types/src/tx_hash.rs diff --git a/core/src/block.rs b/core/src/block.rs index 6b9e218aa5..9498ef9337 100644 --- a/core/src/block.rs +++ b/core/src/block.rs @@ -23,7 +23,7 @@ use cstate::{FindActionHandler, StateDB, StateError, StateWithCache, TopLevelSta use ctypes::errors::HistoryError; use ctypes::header::{Header, Seal}; use ctypes::util::unexpected::Mismatch; -use ctypes::{BlockNumber, CommonParams}; +use ctypes::{BlockNumber, CommonParams, TxHash}; use cvm::ChainTimeInfo; use primitives::{Bytes, H256}; use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; @@ -90,7 +90,7 @@ pub struct ExecutedBlock { state: TopLevelState, transactions: Vec, invoices: Vec, - transactions_set: HashSet, + transactions_set: HashSet, } impl ExecutedBlock { @@ -153,7 +153,7 @@ impl<'x> OpenBlock<'x> { pub fn push_transaction( &mut self, tx: SignedTransaction, - h: Option, + h: Option, client: &C, parent_block_number: BlockNumber, parent_block_timestamp: u64, diff --git a/core/src/blockchain/blockchain.rs b/core/src/blockchain/blockchain.rs index 3495d1fa2b..4d7ee18845 100644 --- a/core/src/blockchain/blockchain.rs +++ b/core/src/blockchain/blockchain.rs @@ -16,7 +16,7 @@ use std::sync::Arc; -use ctypes::{BlockHash, BlockNumber, Tracker}; +use ctypes::{BlockHash, BlockNumber, Tracker, TxHash}; use kvdb::{DBTransaction, KeyValueDB}; use parking_lot::RwLock; use primitives::H256; @@ -411,7 +411,7 @@ impl BodyProvider for BlockChain { self.body_db.is_known_body(hash) } - fn transaction_address(&self, hash: &H256) -> Option { + fn transaction_address(&self, hash: &TxHash) -> Option { self.body_db.transaction_address(hash) } @@ -426,15 +426,15 @@ impl BodyProvider for BlockChain { impl InvoiceProvider for BlockChain { /// Returns true if invoices for given hash is known - fn is_known_error_hint(&self, hash: &H256) -> bool { + fn is_known_error_hint(&self, hash: &TxHash) -> bool { self.invoice_db.is_known_error_hint(hash) } - fn error_hints_by_tracker(&self, tracker: &Tracker) -> Vec<(H256, Option)> { + fn error_hints_by_tracker(&self, tracker: &Tracker) -> Vec<(TxHash, Option)> { self.invoice_db.error_hints_by_tracker(tracker) } - fn error_hint(&self, hash: &H256) -> Option { + fn error_hint(&self, hash: &TxHash) -> Option { self.invoice_db.error_hint(hash) } } diff --git a/core/src/blockchain/body_db.rs b/core/src/blockchain/body_db.rs index 726091b9b4..997cc6b035 100644 --- a/core/src/blockchain/body_db.rs +++ b/core/src/blockchain/body_db.rs @@ -18,11 +18,11 @@ use std::collections::{HashMap, HashSet}; use std::mem; use std::sync::Arc; -use ctypes::{BlockHash, Tracker}; +use ctypes::{BlockHash, Tracker, TxHash}; use kvdb::{DBTransaction, KeyValueDB}; use lru_cache::LruCache; use parking_lot::{Mutex, RwLock}; -use primitives::{Bytes, H256}; +use primitives::Bytes; use rlp::RlpStream; use rlp_compress::{blocks_swapper, compress, decompress}; @@ -37,8 +37,8 @@ const BODY_CACHE_SIZE: usize = 1000; pub struct BodyDB { // block cache body_cache: Mutex>, - parcel_address_cache: RwLock>, - pending_parcel_addresses: RwLock>>, + parcel_address_cache: RwLock>, + pending_parcel_addresses: RwLock>>, transaction_address_cache: Mutex>, pending_transaction_addresses: Mutex>>, @@ -141,7 +141,7 @@ impl BodyDB { fn new_parcel_address_entries( &self, best_block_changed: &BestBlockChanged, - ) -> HashMap> { + ) -> HashMap> { let block_hash = if let Some(best_block_hash) = best_block_changed.new_best_hash() { best_block_hash } else { @@ -284,7 +284,7 @@ pub trait BodyProvider { fn is_known_body(&self, hash: &BlockHash) -> bool; /// Get the address of parcel with given hash. - fn transaction_address(&self, hash: &H256) -> Option; + fn transaction_address(&self, hash: &TxHash) -> Option; fn transaction_address_by_tracker(&self, tracker: &Tracker) -> Option; @@ -298,7 +298,7 @@ impl BodyProvider for BodyDB { } /// Get the address of parcel with given hash. - fn transaction_address(&self, hash: &H256) -> Option { + fn transaction_address(&self, hash: &TxHash) -> Option { let result = self.db.read_with_cache(db::COL_EXTRA, &mut *self.parcel_address_cache.write(), hash)?; Some(result) } @@ -332,11 +332,11 @@ impl BodyProvider for BodyDB { fn parcel_address_entries( block_hash: BlockHash, - parcel_hashes: impl IntoIterator, -) -> impl Iterator)> { - parcel_hashes.into_iter().enumerate().map(move |(index, parcel_hash)| { + tx_hashes: impl IntoIterator, +) -> impl Iterator)> { + tx_hashes.into_iter().enumerate().map(move |(index, tx_hash)| { ( - parcel_hash, + tx_hash, Some(TransactionAddress { block_hash, index, diff --git a/core/src/blockchain/extras.rs b/core/src/blockchain/extras.rs index f016b50b55..4a62ac5a1d 100644 --- a/core/src/blockchain/extras.rs +++ b/core/src/blockchain/extras.rs @@ -16,7 +16,7 @@ use std::ops::{Add, AddAssign, Deref, Sub, SubAssign}; -use ctypes::{BlockHash, BlockNumber, Tracker}; +use ctypes::{BlockHash, BlockNumber, Tracker, TxHash}; use primitives::{H256, H264, U256}; use crate::db::Key; @@ -29,8 +29,8 @@ enum ExtrasIndex { BlockDetails = 0, /// Block hash index BlockHash = 1, - /// Parcel address index - ParcelAddress = 2, + /// Transaction address index + TransactionAddress = 2, /// Transaction addresses index TransactionAddresses = 3, // (Reserved) = 4, @@ -77,11 +77,11 @@ impl Key for BlockHash { } } -impl Key for H256 { +impl Key for TxHash { type Target = H264; fn key(&self) -> H264 { - with_index(self, ExtrasIndex::ParcelAddress) + with_index(self, ExtrasIndex::TransactionAddress) } } diff --git a/core/src/blockchain/invoice_db.rs b/core/src/blockchain/invoice_db.rs index eb5b82d694..b5fb9e3993 100644 --- a/core/src/blockchain/invoice_db.rs +++ b/core/src/blockchain/invoice_db.rs @@ -18,7 +18,7 @@ use std::collections::HashMap; use std::ops::{Deref, DerefMut}; use std::sync::Arc; -use ctypes::Tracker; +use ctypes::{Tracker, TxHash}; use kvdb::{DBTransaction, KeyValueDB}; use parking_lot::RwLock; use primitives::{H256, H264}; @@ -33,7 +33,7 @@ pub struct InvoiceDB { // tracker -> transaction hashe + error hint tracker_cache: RwLock>, // transaction hash -> error hint - hash_cache: RwLock>>, + hash_cache: RwLock>>, db: Arc, } @@ -55,7 +55,7 @@ impl InvoiceDB { pub fn insert_invoice( &self, batch: &mut DBTransaction, - hash: H256, + hash: TxHash, tracker: Option, error_hint: Option, ) { @@ -80,34 +80,34 @@ impl InvoiceDB { /// Interface for querying invoices. pub trait InvoiceProvider { /// Returns true if invoices for given hash is known - fn is_known_error_hint(&self, hash: &H256) -> bool; + fn is_known_error_hint(&self, hash: &TxHash) -> bool; /// Get error hints - fn error_hints_by_tracker(&self, tracker: &Tracker) -> Vec<(H256, Option)>; + fn error_hints_by_tracker(&self, tracker: &Tracker) -> Vec<(TxHash, Option)>; /// Get error hint - fn error_hint(&self, hash: &H256) -> Option; + fn error_hint(&self, hash: &TxHash) -> Option; } impl InvoiceProvider for InvoiceDB { - fn is_known_error_hint(&self, hash: &H256) -> bool { + fn is_known_error_hint(&self, hash: &TxHash) -> bool { self.db.exists_with_cache(db::COL_ERROR_HINT, &self.hash_cache, hash) } - fn error_hints_by_tracker(&self, tracker: &Tracker) -> Vec<(H256, Option)> { + fn error_hints_by_tracker(&self, tracker: &Tracker) -> Vec<(TxHash, Option)> { self.db .read_with_cache(db::COL_ERROR_HINT, &mut *self.tracker_cache.write(), tracker) .map(|hashes| (*hashes).clone()) .unwrap_or_default() } - fn error_hint(&self, hash: &H256) -> Option { + fn error_hint(&self, hash: &TxHash) -> Option { self.db.read_with_cache(db::COL_ERROR_HINT, &mut *self.hash_cache.write(), hash)? } } #[derive(Clone, Default)] -pub struct TrackerInvoices(Vec<(H256, Option)>); +pub struct TrackerInvoices(Vec<(TxHash, Option)>); impl Encodable for TrackerInvoices { fn rlp_append(&self, s: &mut RlpStream) { @@ -137,14 +137,14 @@ impl Decodable for TrackerInvoices { } } -impl From)>> for TrackerInvoices { - fn from(f: Vec<(H256, Option)>) -> Self { +impl From)>> for TrackerInvoices { + fn from(f: Vec<(TxHash, Option)>) -> Self { TrackerInvoices(f) } } impl Deref for TrackerInvoices { - type Target = Vec<(H256, Option)>; + type Target = Vec<(TxHash, Option)>; fn deref(&self) -> &Self::Target { &self.0 @@ -168,7 +168,7 @@ impl From for u8 { } } -impl Key> for H256 { +impl Key> for TxHash { type Target = H264; fn key(&self) -> H264 { diff --git a/core/src/client/chain_notify.rs b/core/src/client/chain_notify.rs index dfbdba5d56..ffe0c4f547 100644 --- a/core/src/client/chain_notify.rs +++ b/core/src/client/chain_notify.rs @@ -15,8 +15,7 @@ // along with this program. If not, see . use cnetwork::NodeId; -use ctypes::BlockHash; -use primitives::H256; +use ctypes::{BlockHash, TxHash}; /// Represents what has to be handled by actor listening to chain events pub trait ChainNotify: Send + Sync { @@ -48,7 +47,7 @@ pub trait ChainNotify: Send + Sync { } /// fires when new transactions are received from a peer - fn transactions_received(&self, _hashes: Vec, _peer_id: NodeId) { + fn transactions_received(&self, _hashes: Vec, _peer_id: NodeId) { // does nothing by default } } diff --git a/core/src/client/client.rs b/core/src/client/client.rs index 6ea56f56b8..add839f9fb 100644 --- a/core/src/client/client.rs +++ b/core/src/client/client.rs @@ -28,7 +28,7 @@ use cstate::{ }; use ctimer::{TimeoutHandler, TimerApi, TimerScheduleError, TimerToken}; use ctypes::transaction::{AssetTransferInput, PartialHashing, ShardTransaction}; -use ctypes::{BlockHash, BlockNumber, CommonParams, ShardId, Tracker}; +use ctypes::{BlockHash, BlockNumber, CommonParams, ShardId, Tracker, TxHash}; use cvm::{decode, execute, ChainTimeInfo, ScriptResult, VMConfig}; use hashdb::AsHashDB; use journaldb; @@ -142,7 +142,7 @@ impl Client { self.notify.write().push(target); } - pub fn transactions_received(&self, hashes: &[H256], peer_id: NodeId) { + pub fn transactions_received(&self, hashes: &[TxHash], peer_id: NodeId) { self.notify(|notify| { notify.transactions_received(hashes.to_vec(), peer_id); }); @@ -422,7 +422,7 @@ impl AssetClient for Client { } impl TextClient for Client { - fn get_text(&self, tx_hash: H256, id: BlockId) -> TrieResult> { + fn get_text(&self, tx_hash: TxHash, id: BlockId) -> TrieResult> { if let Some(state) = Client::state_at(&self, id) { Ok(state.text(&tx_hash)?) } else { @@ -797,7 +797,7 @@ impl BlockChainClient for Client { self.transaction_address(id).and_then(|address| chain.transaction(&address)) } - fn error_hint(&self, hash: &H256) -> Option { + fn error_hint(&self, hash: &TxHash) -> Option { let chain = self.block_chain(); chain.error_hint(hash) } @@ -808,7 +808,7 @@ impl BlockChainClient for Client { address.and_then(|address| chain.transaction(&address)) } - fn error_hints_by_tracker(&self, tracker: &Tracker) -> Vec<(H256, Option)> { + fn error_hints_by_tracker(&self, tracker: &Tracker) -> Vec<(TxHash, Option)> { let chain = self.block_chain(); chain.error_hints_by_tracker(tracker) } @@ -855,7 +855,7 @@ impl Shard for Client { state.number_of_shards().ok() } - fn shard_id_by_hash(&self, create_shard_tx_hash: &H256, state: StateOrBlock) -> Option { + fn shard_id_by_hash(&self, create_shard_tx_hash: &TxHash, state: StateOrBlock) -> Option { let state = self.state_info(state)?; state.shard_id_by_hash(&create_shard_tx_hash).ok()? } diff --git a/core/src/client/mod.rs b/core/src/client/mod.rs index a9f6520a24..6b565e903a 100644 --- a/core/src/client/mod.rs +++ b/core/src/client/mod.rs @@ -37,7 +37,7 @@ use cmerkle::Result as TrieResult; use cnetwork::NodeId; use cstate::{AssetScheme, FindActionHandler, OwnedAsset, StateResult, Text, TopLevelState, TopStateView}; use ctypes::transaction::{AssetTransferInput, PartialHashing, ShardTransaction}; -use ctypes::{BlockHash, BlockNumber, CommonParams, ShardId, Tracker}; +use ctypes::{BlockHash, BlockNumber, CommonParams, ShardId, Tracker, TxHash}; use cvm::ChainTimeInfo; use kvdb::KeyValueDB; use primitives::{Bytes, H160, H256, U256}; @@ -185,7 +185,7 @@ impl From for StateOrBlock { pub trait Shard { fn number_of_shards(&self, state: StateOrBlock) -> Option; - fn shard_id_by_hash(&self, create_shard_tx_hash: &H256, state: StateOrBlock) -> Option; + fn shard_id_by_hash(&self, create_shard_tx_hash: &TxHash, state: StateOrBlock) -> Option; fn shard_root(&self, shard_id: ShardId, state: StateOrBlock) -> Option; fn shard_owners(&self, shard_id: ShardId, state: StateOrBlock) -> Option>; @@ -250,12 +250,12 @@ pub trait BlockChainClient: Sync + Send + AccountData + BlockChainTrait + Import fn transaction(&self, id: &TransactionId) -> Option; /// Get invoice with given hash. - fn error_hint(&self, hash: &H256) -> Option; + fn error_hint(&self, hash: &TxHash) -> Option; /// Get the transaction with given tracker. fn transaction_by_tracker(&self, tracker: &Tracker) -> Option; - fn error_hints_by_tracker(&self, tracker: &Tracker) -> Vec<(H256, Option)>; + fn error_hints_by_tracker(&self, tracker: &Tracker) -> Vec<(TxHash, Option)>; } /// Result of import block operation. @@ -319,7 +319,7 @@ pub trait AssetClient { /// Provides methods to texts pub trait TextClient { - fn get_text(&self, tx_hash: H256, id: BlockId) -> TrieResult>; + fn get_text(&self, tx_hash: TxHash, id: BlockId) -> TrieResult>; } pub trait ExecuteClient: ChainTimeInfo { diff --git a/core/src/client/test_client.rs b/core/src/client/test_client.rs index b8f5b9789d..8b61a8f443 100644 --- a/core/src/client/test_client.rs +++ b/core/src/client/test_client.rs @@ -43,7 +43,7 @@ use cstate::tests::helpers::empty_top_state; use cstate::{FindActionHandler, StateDB, TopLevelState}; use ctimer::{TimeoutHandler, TimerToken}; use ctypes::transaction::{Action, Transaction}; -use ctypes::{BlockHash, BlockNumber, CommonParams, Header as BlockHeader, Tracker}; +use ctypes::{BlockHash, BlockNumber, CommonParams, Header as BlockHeader, Tracker, TxHash}; use cvm::ChainTimeInfo; use journaldb; use kvdb::KeyValueDB; @@ -291,7 +291,7 @@ impl TestBlockChainClient { } /// Inserts a transaction to miners mem pool. - pub fn insert_transaction_to_pool(&self) -> H256 { + pub fn insert_transaction_to_pool(&self) -> TxHash { let keypair = Random.generate().unwrap(); let tx = Transaction { seq: 0, @@ -593,7 +593,7 @@ impl BlockChainClient for TestBlockChainClient { unimplemented!(); } - fn error_hint(&self, _hash: &H256) -> Option { + fn error_hint(&self, _hash: &TxHash) -> Option { unimplemented!(); } @@ -601,7 +601,7 @@ impl BlockChainClient for TestBlockChainClient { unimplemented!(); } - fn error_hints_by_tracker(&self, _: &Tracker) -> Vec<(H256, Option)> { + fn error_hints_by_tracker(&self, _: &Tracker) -> Vec<(TxHash, Option)> { unimplemented!(); } } diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index d2b7da7ef2..93386a0df5 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -1457,7 +1457,7 @@ impl Worker { bytes: double.to_action().rlp_bytes().into_vec(), }, }; - let signature = match self.signer.sign_ecdsa(tx.hash()) { + let signature = match self.signer.sign_ecdsa(*tx.hash()) { Ok(signature) => signature, Err(e) => { cerror!(ENGINE, "Found double vote, but could not sign the message: {}", e); diff --git a/core/src/encoded.rs b/core/src/encoded.rs index 375a6505fd..0e77876b5b 100644 --- a/core/src/encoded.rs +++ b/core/src/encoded.rs @@ -25,7 +25,7 @@ use ccrypto::blake256; use ckey::Address; -use ctypes::{BlockHash, BlockNumber, Header as FullHeader}; +use ctypes::{BlockHash, BlockNumber, Header as FullHeader, TxHash}; use primitives::{H256, U256}; use rlp::Rlp; @@ -173,7 +173,7 @@ impl Body { } /// The hash of each transaction in the block. - pub fn transaction_hashes(&self) -> Vec { + pub fn transaction_hashes(&self) -> Vec { self.view().transaction_hashes() } } @@ -298,7 +298,7 @@ impl Block { } /// The hash of each transaction in the block. - pub fn transaction_hashes(&self) -> Vec { + pub fn transaction_hashes(&self) -> Vec { self.view().transaction_hashes() } } diff --git a/core/src/invoice.rs b/core/src/invoice.rs index ed3d96bc69..c36e1303ae 100644 --- a/core/src/invoice.rs +++ b/core/src/invoice.rs @@ -14,12 +14,11 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use ctypes::Tracker; -use primitives::H256; +use ctypes::{Tracker, TxHash}; #[derive(Clone, Debug, PartialEq)] pub struct Invoice { pub tracker: Option, - pub hash: H256, + pub hash: TxHash, pub error: Option, } diff --git a/core/src/miner/mem_pool.rs b/core/src/miner/mem_pool.rs index d513085a34..8729639c0e 100644 --- a/core/src/miner/mem_pool.rs +++ b/core/src/miner/mem_pool.rs @@ -20,9 +20,8 @@ use std::sync::Arc; use ckey::{public_to_address, Public}; use ctypes::errors::{HistoryError, RuntimeError, SyntaxError}; -use ctypes::BlockNumber; +use ctypes::{BlockNumber, TxHash}; use kvdb::{DBTransaction, KeyValueDB}; -use primitives::H256; use rlp; use table::Table; @@ -96,7 +95,7 @@ pub struct MemPool { /// The memory limit of each queue queue_memory_limit: usize, /// All transactions managed by pool indexed by hash - by_hash: HashMap, + by_hash: HashMap, /// Current seq of each public key (fee payer) first_seqs: HashMap, /// Next seq of transaction in current (to quickly check next expected transaction) @@ -279,7 +278,7 @@ impl MemPool { let order = TransactionOrder::for_transaction(&item, client_account.seq); let order_with_tag = TransactionOrderWithTag::new(order, QueueTag::New); - backup::backup_item(&mut batch, hash, &item); + backup::backup_item(&mut batch, *hash, &item); self.by_hash.insert(hash, item); if let Some(old_order_with_tag) = self.by_signer_public.insert(signer_public, seq, order_with_tag) { @@ -458,7 +457,7 @@ impl MemPool { let order = TransactionOrder::for_transaction(&item, client_account.seq); let order_with_tag = TransactionOrderWithTag::new(order, QueueTag::New); - self.by_hash.insert(*hash, item.clone()); + self.by_hash.insert((*hash).into(), item.clone()); self.by_signer_public.insert(signer_public, seq, order_with_tag); if item.origin == TxOrigin::Local { @@ -508,7 +507,7 @@ impl MemPool { /// If gap is introduced marks subsequent transactions as future pub fn remove( &mut self, - transaction_hashes: &[H256], + transaction_hashes: &[TxHash], fetch_seq: &F, current_block_number: PoolingInstant, current_timestamp: u64, @@ -959,7 +958,7 @@ impl MemPool { } /// Returns Some(true) if the given transaction is local and None for not found. - pub fn is_local_transaction(&self, tx_hash: H256) -> Option { + pub fn is_local_transaction(&self, tx_hash: TxHash) -> Option { self.by_hash.get(&tx_hash).map(|found_item| found_item.origin.is_local()) } diff --git a/core/src/miner/mem_pool_types.rs b/core/src/miner/mem_pool_types.rs index 3b9709b041..d69433c24c 100644 --- a/core/src/miner/mem_pool_types.rs +++ b/core/src/miner/mem_pool_types.rs @@ -19,8 +19,7 @@ use std::collections::{BTreeMap, BTreeSet}; use ckey::Public; use ctypes::transaction::Action; -use ctypes::BlockNumber; -use primitives::H256; +use ctypes::{BlockNumber, TxHash}; use rlp; use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; @@ -122,7 +121,7 @@ pub struct TransactionOrder { /// Currently using the RLP byte length of the transaction as the mem usage. pub mem_usage: usize, /// Hash to identify associated transaction - pub hash: H256, + pub hash: TxHash, /// Incremental id assigned when transaction is inserted to the pool. pub insertion_id: u64, /// Origin of the transaction @@ -238,7 +237,7 @@ impl MemPoolItem { } } - pub fn hash(&self) -> H256 { + pub fn hash(&self) -> TxHash { self.tx.hash() } diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index f4795b50ff..0278715cff 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -26,7 +26,7 @@ use ckey::{public_to_address, Address, Password, PlatformAddress, Public}; use cstate::{FindActionHandler, TopLevelState}; use ctypes::errors::{HistoryError, RuntimeError}; use ctypes::transaction::{Action, IncompleteTransaction, Timelock}; -use ctypes::{BlockHash, BlockNumber, Header}; +use ctypes::{BlockHash, BlockNumber, Header, TxHash}; use cvm::ChainTimeInfo; use kvdb::KeyValueDB; use parking_lot::{Mutex, RwLock}; @@ -111,7 +111,7 @@ struct SealingWork { enabled: bool, } -type TransactionListener = Box; +type TransactionListener = Box; pub struct Miner { mem_pool: Arc>, @@ -197,7 +197,7 @@ impl Miner { } /// Set a callback to be notified about imported transactions' hashes. - pub fn add_transactions_listener(&self, f: Box) { + pub fn add_transactions_listener(&self, f: Box) { self.transaction_listener.write().push(f); } @@ -1055,7 +1055,7 @@ impl MinerService for Miner { platform_address: PlatformAddress, passphrase: Option, seq: Option, - ) -> Result<(H256, u64), Error> { + ) -> Result<(TxHash, u64), Error> { let address = platform_address.try_into_address()?; let seq = match seq { Some(seq) => seq, diff --git a/core/src/miner/mod.rs b/core/src/miner/mod.rs index 867ec2a4eb..0eea957edf 100644 --- a/core/src/miner/mod.rs +++ b/core/src/miner/mod.rs @@ -28,9 +28,9 @@ use std::ops::Range; use ckey::{Address, Password, PlatformAddress}; use cstate::{FindActionHandler, TopStateView}; use ctypes::transaction::IncompleteTransaction; -use ctypes::BlockHash; +use ctypes::{BlockHash, TxHash}; use cvm::ChainTimeInfo; -use primitives::{Bytes, H256}; +use primitives::Bytes; pub use self::miner::{AuthoringParams, Miner, MinerOptions}; pub use self::stratum::{Config as StratumConfig, Error as StratumError, Stratum}; @@ -141,7 +141,7 @@ pub trait MinerService: Send + Sync { platform_address: PlatformAddress, passphrase: Option, seq: Option, - ) -> Result<(H256, u64), Error>; + ) -> Result<(TxHash, u64), Error>; /// Get a list of all pending transactions in the mem pool. fn ready_transactions(&self, range: Range) -> PendingSignedTransactions; diff --git a/core/src/transaction.rs b/core/src/transaction.rs index 2749e12955..118564ed3e 100644 --- a/core/src/transaction.rs +++ b/core/src/transaction.rs @@ -20,8 +20,7 @@ use ccrypto::blake256; use ckey::{self, public_to_address, recover, sign, Private, Public, Signature}; use ctypes::errors::SyntaxError; use ctypes::transaction::Transaction; -use ctypes::{BlockHash, BlockNumber, CommonParams}; -use primitives::H256; +use ctypes::{BlockHash, BlockNumber, CommonParams, TxHash}; use rlp::{self, DecoderError, Encodable, RlpStream, UntrustedRlp}; use crate::error::Error; @@ -34,7 +33,7 @@ pub struct UnverifiedTransaction { /// Signature. sig: Signature, /// Hash of the transaction - hash: H256, + hash: TxHash, } impl Deref for UnverifiedTransaction { @@ -60,7 +59,7 @@ impl rlp::Decodable for UnverifiedTransaction { got: item_count, }) } - let hash = blake256(d.as_raw()); + let hash = blake256(d.as_raw()).into(); Ok(UnverifiedTransaction { unsigned: Transaction { seq: d.val_at(0)?, @@ -85,14 +84,14 @@ impl UnverifiedTransaction { UnverifiedTransaction { unsigned, sig, - hash: 0.into(), + hash: Default::default(), } .compute_hash() } /// Used to compute hash of created transactions fn compute_hash(mut self) -> UnverifiedTransaction { - let hash = blake256(&*self.rlp_bytes()); + let hash = blake256(&*self.rlp_bytes()).into(); self.hash = hash; self } @@ -108,7 +107,7 @@ impl UnverifiedTransaction { } /// Get the hash of this header (blake256 of the RLP). - pub fn hash(&self) -> H256 { + pub fn hash(&self) -> TxHash { self.hash } @@ -287,7 +286,7 @@ mod tests { network_id: "tc".into(), }, sig: Signature::default(), - hash: H256::default(), + hash: H256::default().into(), } .compute_hash()); } @@ -305,7 +304,7 @@ mod tests { }, }, sig: Signature::default(), - hash: H256::default(), + hash: H256::default().into(), } .compute_hash()); } @@ -322,7 +321,7 @@ mod tests { }, }, sig: Signature::default(), - hash: H256::default(), + hash: H256::default().into(), } .compute_hash()); } @@ -339,7 +338,7 @@ mod tests { }, }, sig: Signature::default(), - hash: H256::default(), + hash: H256::default().into(), } .compute_hash()); } diff --git a/core/src/types/ids.rs b/core/src/types/ids.rs index 1aa6ca8f5d..aeb0934e27 100644 --- a/core/src/types/ids.rs +++ b/core/src/types/ids.rs @@ -14,8 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use ctypes::{BlockHash, BlockNumber}; -use primitives::H256; +use ctypes::{BlockHash, BlockNumber, TxHash}; /// Uniquely identifies block. #[derive(Debug, PartialEq, Copy, Clone, Hash, Eq)] @@ -48,14 +47,14 @@ impl From for BlockId { #[derive(Debug, PartialEq, Clone, Hash, Eq)] pub enum TransactionId { /// Transaction's blake256. - Hash(H256), + Hash(TxHash), /// Block id and transaction index within this block. /// Querying by block position is always faster. Location(BlockId, usize), } -impl From for TransactionId { - fn from(hash: H256) -> Self { +impl From for TransactionId { + fn from(hash: TxHash) -> Self { TransactionId::Hash(hash) } } diff --git a/core/src/views/block.rs b/core/src/views/block.rs index c10ee7e188..be58df491c 100644 --- a/core/src/views/block.rs +++ b/core/src/views/block.rs @@ -15,8 +15,7 @@ // along with this program. If not, see . use ccrypto::blake256; -use ctypes::{BlockHash, Header}; -use primitives::H256; +use ctypes::{BlockHash, Header, TxHash}; use rlp::Rlp; use super::{HeaderView, TransactionView}; @@ -101,8 +100,8 @@ impl<'a> BlockView<'a> { } /// Return transaction hashes. - pub fn transaction_hashes(&self) -> Vec { - self.rlp.at(1).iter().map(|rlp| blake256(rlp.as_raw())).collect() + pub fn transaction_hashes(&self) -> Vec { + self.rlp.at(1).iter().map(|rlp| blake256(rlp.as_raw()).into()).collect() } /// Returns transaction at given index without deserializing unnecessary data. diff --git a/core/src/views/body.rs b/core/src/views/body.rs index b6454cb28f..e9b6681b76 100644 --- a/core/src/views/body.rs +++ b/core/src/views/body.rs @@ -15,8 +15,7 @@ // along with this program. If not, see . use ccrypto::blake256; -use ctypes::{BlockHash, BlockNumber}; -use primitives::H256; +use ctypes::{BlockHash, BlockNumber, TxHash}; use rlp::Rlp; use super::TransactionView; @@ -82,8 +81,8 @@ impl<'a> BodyView<'a> { } /// Return transaction hashes. - pub fn transaction_hashes(&self) -> Vec { - self.rlp.at(0).iter().map(|rlp| blake256(rlp.as_raw())).collect() + pub fn transaction_hashes(&self) -> Vec { + self.rlp.at(0).iter().map(|rlp| blake256(rlp.as_raw()).into()).collect() } /// Returns transaction at given index without deserializing unnecessary data. diff --git a/rpc/src/v1/impls/chain.rs b/rpc/src/v1/impls/chain.rs index a7669a32d0..576e571d00 100644 --- a/rpc/src/v1/impls/chain.rs +++ b/rpc/src/v1/impls/chain.rs @@ -26,7 +26,7 @@ use cjson::uint::Uint; use ckey::{public_to_address, NetworkId, PlatformAddress, Public}; use cstate::FindActionHandler; use ctypes::transaction::{Action, ShardTransaction as ShardTransactionType}; -use ctypes::{BlockHash, BlockNumber, ShardId, Tracker}; +use ctypes::{BlockHash, BlockNumber, ShardId, Tracker, TxHash}; use primitives::{Bytes as BytesArray, H160, H256}; use jsonrpc_core::Result; @@ -65,12 +65,12 @@ where + TermInfo + 'static, { - fn get_transaction(&self, transaction_hash: H256) -> Result> { + fn get_transaction(&self, transaction_hash: TxHash) -> Result> { let id = transaction_hash.into(); Ok(self.client.transaction(&id).map(From::from)) } - fn get_transaction_signer(&self, transaction_hash: H256) -> Result> { + fn get_transaction_signer(&self, transaction_hash: TxHash) -> Result> { let id = transaction_hash.into(); Ok(self.client.transaction(&id).map(|mut tx| { let address = public_to_address(&tx.signer()); @@ -78,11 +78,11 @@ where })) } - fn contains_transaction(&self, transaction_hash: H256) -> Result { + fn contains_transaction(&self, transaction_hash: TxHash) -> Result { Ok(self.client.transaction_block(&transaction_hash.into()).is_some()) } - fn contain_transaction(&self, transaction_hash: H256) -> Result { + fn contain_transaction(&self, transaction_hash: TxHash) -> Result { self.contains_transaction(transaction_hash) } @@ -123,7 +123,7 @@ where } } - fn get_text(&self, transaction_hash: H256, block_number: Option) -> Result> { + fn get_text(&self, transaction_hash: TxHash, block_number: Option) -> Result> { if block_number == Some(0) { return Ok(None) } @@ -193,7 +193,7 @@ where Ok(self.client.number_of_shards(block_id.into())) } - fn get_shard_id_by_hash(&self, create_shard_tx_hash: H256, block_number: Option) -> Result> { + fn get_shard_id_by_hash(&self, create_shard_tx_hash: TxHash, block_number: Option) -> Result> { let block_id = block_number.map(BlockId::Number).unwrap_or(BlockId::Latest); Ok(self.client.shard_id_by_hash(&create_shard_tx_hash, block_id.into())) } diff --git a/rpc/src/v1/impls/devel.rs b/rpc/src/v1/impls/devel.rs index 39843ef3ca..0fa2e47a05 100644 --- a/rpc/src/v1/impls/devel.rs +++ b/rpc/src/v1/impls/devel.rs @@ -33,7 +33,7 @@ use csync::BlockSyncEvent; use ctypes::transaction::{ Action, AssetMintOutput, AssetOutPoint, AssetTransferInput, AssetTransferOutput, Transaction, }; -use ctypes::Tracker; +use ctypes::{Tracker, TxHash}; use jsonrpc_core::Result; use kvdb::KeyValueDB; use primitives::{H160, H256}; @@ -217,7 +217,7 @@ where SignedTransaction::new_with_sign(tx, key_pair.private()) } - fn send_tx(tx: Transaction, client: &C, key_pair: &KeyPair) -> Result + fn send_tx(tx: Transaction, client: &C, key_pair: &KeyPair) -> Result where C: MiningBlockChainClient + EngineInfo + TermInfo, { let signed = SignedTransaction::new_with_sign(tx, key_pair.private()); diff --git a/rpc/src/v1/impls/mempool.rs b/rpc/src/v1/impls/mempool.rs index 99cdc5f2af..efa92bdb38 100644 --- a/rpc/src/v1/impls/mempool.rs +++ b/rpc/src/v1/impls/mempool.rs @@ -19,8 +19,7 @@ use std::sync::Arc; use ccore::{BlockChainClient, MiningBlockChainClient, SignedTransaction}; use cjson::bytes::Bytes; use ckey::{Address, PlatformAddress}; -use ctypes::Tracker; -use primitives::H256; +use ctypes::{Tracker, TxHash}; use rlp::UntrustedRlp; use jsonrpc_core::Result; @@ -45,7 +44,7 @@ impl Mempool for MempoolClient where C: BlockChainClient + MiningBlockChainClient + 'static, { - fn send_signed_transaction(&self, raw: Bytes) -> Result { + fn send_signed_transaction(&self, raw: Bytes) -> Result { UntrustedRlp::new(&raw.into_vec()) .as_val() .map_err(|e| errors::rlp(&e)) @@ -69,7 +68,7 @@ where .collect()) } - fn get_error_hint(&self, transaction_hash: H256) -> Result> { + fn get_error_hint(&self, transaction_hash: TxHash) -> Result> { Ok(self.client.error_hint(&transaction_hash)) } diff --git a/rpc/src/v1/traits/chain.rs b/rpc/src/v1/traits/chain.rs index 3eeb48a230..d9dc27b3d8 100644 --- a/rpc/src/v1/traits/chain.rs +++ b/rpc/src/v1/traits/chain.rs @@ -17,7 +17,7 @@ use cjson::scheme::Params; use cjson::uint::Uint; use ckey::{NetworkId, PlatformAddress, Public}; -use ctypes::{BlockHash, BlockNumber, ShardId, Tracker}; +use ctypes::{BlockHash, BlockNumber, ShardId, Tracker, TxHash}; use primitives::{Bytes as BytesArray, H160, H256}; use jsonrpc_core::Result; @@ -28,18 +28,18 @@ use super::super::types::{AssetScheme, Block, BlockNumberAndHash, OwnedAsset, Te pub trait Chain { /// Gets transaction with given hash. #[rpc(name = "chain_getTransaction")] - fn get_transaction(&self, transaction_hash: H256) -> Result>; + fn get_transaction(&self, transaction_hash: TxHash) -> Result>; /// Gets the signer of transaction with given hash. #[rpc(name = "chain_getTransactionSigner")] - fn get_transaction_signer(&self, transaction_hash: H256) -> Result>; + fn get_transaction_signer(&self, transaction_hash: TxHash) -> Result>; /// Query whether the chain has the transaction with given transaction hash. #[rpc(name = "chain_containsTransaction")] - fn contains_transaction(&self, transaction_hash: H256) -> Result; + fn contains_transaction(&self, transaction_hash: TxHash) -> Result; #[rpc(name = "chain_containTransaction")] - fn contain_transaction(&self, transaction_hash: H256) -> Result; + fn contain_transaction(&self, transaction_hash: TxHash) -> Result; /// Gets transaction with given transaction tracker. #[rpc(name = "chain_getTransactionByTracker")] @@ -65,7 +65,7 @@ pub trait Chain { /// Gets text with given transaction hash. #[rpc(name = "chain_getText")] - fn get_text(&self, transaction_hash: H256, block_number: Option) -> Result>; + fn get_text(&self, transaction_hash: TxHash, block_number: Option) -> Result>; /// Gets asset with given asset type. #[rpc(name = "chain_getAsset")] @@ -113,7 +113,7 @@ pub trait Chain { /// Gets shard id #[rpc(name = "chain_getShardIdByHash")] - fn get_shard_id_by_hash(&self, create_shard_tx_hash: H256, block_number: Option) -> Result>; + fn get_shard_id_by_hash(&self, create_shard_tx_hash: TxHash, block_number: Option) -> Result>; /// Gets shard root #[rpc(name = "chain_getShardRoot")] diff --git a/rpc/src/v1/traits/mempool.rs b/rpc/src/v1/traits/mempool.rs index dc329f3d07..b7726306b0 100644 --- a/rpc/src/v1/traits/mempool.rs +++ b/rpc/src/v1/traits/mempool.rs @@ -16,9 +16,8 @@ use cjson::bytes::Bytes; use ckey::PlatformAddress; -use ctypes::Tracker; +use ctypes::{Tracker, TxHash}; use jsonrpc_core::Result; -use primitives::H256; use super::super::types::PendingTransactions; @@ -26,7 +25,7 @@ use super::super::types::PendingTransactions; pub trait Mempool { /// Sends signed transaction, returning its hash. #[rpc(name = "mempool_sendSignedTransaction")] - fn send_signed_transaction(&self, raw: Bytes) -> Result; + fn send_signed_transaction(&self, raw: Bytes) -> Result; /// Gets transaction results with given transaction tracker. #[rpc(name = "mempool_getTransactionResultsByTracker")] @@ -34,7 +33,7 @@ pub trait Mempool { /// Gets a hint to find out why the transaction failed. #[rpc(name = "mempool_getErrorHint")] - fn get_error_hint(&self, transaction_hash: H256) -> Result>; + fn get_error_hint(&self, transaction_hash: TxHash) -> Result>; /// Gets transactions in the current mem pool. #[rpc(name = "mempool_getPendingTransactions")] diff --git a/rpc/src/v1/types/action.rs b/rpc/src/v1/types/action.rs index 48797bcd0c..25343e937a 100644 --- a/rpc/src/v1/types/action.rs +++ b/rpc/src/v1/types/action.rs @@ -19,8 +19,8 @@ use std::convert::TryFrom; use cjson::uint::Uint; use ckey::{NetworkId, PlatformAddress, Public, Signature}; use ctypes::transaction::{Action as ActionType, AssetMintOutput as AssetMintOutputType}; -use ctypes::{ShardId, Tracker}; -use primitives::{Bytes, H160, H256}; +use ctypes::{ShardId, Tracker, TxHash}; +use primitives::{Bytes, H160}; use rustc_serialize::hex::{FromHex, ToHex}; use super::super::errors::ConversionError; @@ -116,7 +116,7 @@ pub enum Action { signature: Signature, }, Remove { - hash: H256, + hash: TxHash, signature: Signature, }, #[serde(rename_all = "camelCase")] @@ -230,7 +230,7 @@ pub enum ActionWithTracker { signature: Signature, }, Remove { - hash: H256, + hash: TxHash, signature: Signature, }, #[serde(rename_all = "camelCase")] diff --git a/rpc/src/v1/types/mod.rs b/rpc/src/v1/types/mod.rs index db0e1ceeb8..66d9b30ba5 100644 --- a/rpc/src/v1/types/mod.rs +++ b/rpc/src/v1/types/mod.rs @@ -25,8 +25,6 @@ mod transaction; mod unsigned_transaction; mod work; -use primitives::H256; - use self::asset::Asset; use self::asset_input::AssetTransferInput; use self::asset_output::{AssetMintOutput, AssetTransferOutput}; @@ -41,6 +39,7 @@ pub use self::transaction::{PendingTransactions, Transaction}; pub use self::unsigned_transaction::UnsignedTransaction; pub use self::work::Work; +use ctypes::TxHash; use serde::de::{self, Deserialize, Deserializer}; #[derive(Debug, Serialize, Deserialize)] @@ -51,7 +50,7 @@ pub struct FilterStatus { #[derive(Debug, Serialize, Deserialize)] pub struct SendTransactionResult { - pub hash: H256, + pub hash: TxHash, pub seq: u64, } diff --git a/rpc/src/v1/types/transaction.rs b/rpc/src/v1/types/transaction.rs index eabd150a8f..1586d256f9 100644 --- a/rpc/src/v1/types/transaction.rs +++ b/rpc/src/v1/types/transaction.rs @@ -17,8 +17,7 @@ use ccore::{LocalizedTransaction, PendingSignedTransactions, SignedTransaction}; use cjson::uint::Uint; use ckey::{NetworkId, Signature}; -use ctypes::BlockHash; -use primitives::H256; +use ctypes::{BlockHash, TxHash}; use super::ActionWithTracker; @@ -33,7 +32,7 @@ pub struct Transaction { pub fee: Uint, pub network_id: NetworkId, pub action: ActionWithTracker, - pub hash: H256, + pub hash: TxHash, pub sig: Signature, } diff --git a/state/src/impls/shard_level.rs b/state/src/impls/shard_level.rs index 829c610ffb..261b861f7a 100644 --- a/state/src/impls/shard_level.rs +++ b/state/src/impls/shard_level.rs @@ -792,6 +792,8 @@ impl<'db> ShardStateView for ReadOnlyShardLevelState<'db> { #[cfg(test)] mod tests { + use ctypes::TxHash; + use super::super::super::StateError; use super::super::test_helper::SHARD_ID; use super::*; @@ -1374,14 +1376,14 @@ mod tests { let mut state = get_temp_shard_state(&mut state_db, SHARD_ID, &mut shard_cache); let lock_script_hash = H160::from("ca5d3fa0a6887285ef6aa85cb12960a2b6706e00"); - let tx_hash = H256::random(); + let tx_hash = TxHash::from(H256::random()); let amount = 30; let wrap_ccc = asset_wrap_ccc!(tx_hash, asset_wrap_ccc_output!(lock_script_hash, amount)); let wrap_ccc_tracker = wrap_ccc.tracker(); let asset_type = H160::zero(); - assert_eq!(*wrap_ccc_tracker, tx_hash); + assert_eq!(*wrap_ccc_tracker, *tx_hash); assert_eq!(Ok(()), state.apply(&wrap_ccc, &sender, &[sender], &[], &get_test_client(), 0, 0)); check_shard_level_state!(state, [ @@ -1411,13 +1413,13 @@ mod tests { let mut state = get_temp_shard_state(&mut state_db, SHARD_ID, &mut shard_cache); let lock_script_hash = H160::from("b042ad154a3359d276835c903587ebafefea22af"); - let tx_hash = H256::random(); + let tx_hash = TxHash::from(H256::random()); let amount = 30; let wrap_ccc = asset_wrap_ccc!(tx_hash, asset_wrap_ccc_output!(lock_script_hash, amount)); let wrap_ccc_tracker = wrap_ccc.tracker(); - assert_eq!(*wrap_ccc_tracker, tx_hash); + assert_eq!(*wrap_ccc_tracker, *tx_hash); assert_eq!(Ok(()), state.apply(&wrap_ccc, &sender, &[sender], &[], &get_test_client(), 0, 0)); let asset_type = H160::zero(); diff --git a/state/src/impls/top_level.rs b/state/src/impls/top_level.rs index 50bdc9befc..b871efaa58 100644 --- a/state/src/impls/top_level.rs +++ b/state/src/impls/top_level.rs @@ -48,7 +48,7 @@ use ctypes::transaction::{ use ctypes::util::unexpected::Mismatch; #[cfg(test)] use ctypes::Tracker; -use ctypes::{BlockNumber, CommonParams, ShardId}; +use ctypes::{BlockNumber, CommonParams, ShardId, TxHash}; use cvm::ChainTimeInfo; use hashdb::AsHashDB; use kvdb::DBTransaction; @@ -256,7 +256,7 @@ impl TopLevelState { pub fn apply( &mut self, tx: &Transaction, - signed_hash: &H256, + signed_hash: &TxHash, signer_public: &Public, client: &C, parent_block_number: BlockNumber, @@ -297,7 +297,7 @@ impl TopLevelState { fn apply_internal( &mut self, tx: &Transaction, - signed_hash: &H256, + signed_hash: &TxHash, signer_public: &Public, client: &C, parent_block_number: BlockNumber, @@ -363,8 +363,8 @@ impl TopLevelState { &mut self, action: &Action, network_id: NetworkId, - tx_hash: H256, - signed_hash: &H256, + tx_hash: TxHash, + signed_hash: &TxHash, fee_payer: &Address, signer_public: &Public, client: &C, @@ -660,13 +660,13 @@ impl TopLevelState { self.top_cache.shard_mut(&shard_address, &trie) } - fn get_text(&self, key: &H256) -> TrieResult> { + fn get_text(&self, key: &TxHash) -> TrieResult> { let db = self.db.borrow(); let trie = TrieFactory::readonly(db.as_hashdb(), &self.root)?; self.top_cache.text(key, &trie) } - fn get_text_mut(&self, key: &H256) -> TrieResult> { + fn get_text_mut(&self, key: &TxHash) -> TrieResult> { let db = self.db.borrow(); let trie = TrieFactory::readonly(db.as_hashdb(), &self.root)?; self.top_cache.text_mut(key, &trie) @@ -876,7 +876,7 @@ impl TopState for TopLevelState { Ok(()) } - fn create_shard(&mut self, fee_payer: &Address, tx_hash: H256, users: Vec
) -> StateResult<()> { + fn create_shard(&mut self, fee_payer: &Address, tx_hash: TxHash, users: Vec
) -> StateResult<()> { let shard_id = { let mut metadata = self.get_metadata_mut()?; metadata.add_shard(tx_hash) @@ -943,7 +943,7 @@ impl TopState for TopLevelState { Ok(()) } - fn store_text(&mut self, key: &H256, text: Text, sig: &Signature) -> StateResult<()> { + fn store_text(&mut self, key: &TxHash, text: Text, sig: &Signature) -> StateResult<()> { match verify_address(text.certifier(), sig, &text.content_hash()) { Ok(false) => { return Err(RuntimeError::TextVerificationFail("Certifier and signer are different".to_string()).into()) @@ -956,7 +956,7 @@ impl TopState for TopLevelState { Ok(()) } - fn remove_text(&mut self, key: &H256, sig: &Signature) -> StateResult<()> { + fn remove_text(&mut self, key: &TxHash, sig: &Signature) -> StateResult<()> { let text = self.get_text(key)?.ok_or_else(|| RuntimeError::TextNotExist)?; match verify_address(text.certifier(), sig, key) { Ok(false) => { @@ -1382,7 +1382,7 @@ mod tests_tx { expected: 0, found: 2 }))), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -1405,7 +1405,7 @@ mod tests_tx { cost: 5, } .into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -1422,7 +1422,7 @@ mod tests_tx { let receiver = 1u64.into(); let tx = transaction!(fee: 5, pay!(receiver, 10)); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 5)), @@ -1439,7 +1439,7 @@ mod tests_tx { set_top_level_state!(state, [(account: sender => balance: 5)]); let tx = transaction!(fee: 5, set_regular_key!(key)); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 0, key: key)) @@ -1462,7 +1462,7 @@ mod tests_tx { let tx = transaction!(fee: 5, pay!(regular_account, 10)); assert_eq!( Err(RuntimeError::InvalidTransferDestination.into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -1498,7 +1498,7 @@ mod tests_tx { let tx = transaction!(seq: 0, fee: 11, unwrap_ccc_tx); assert_eq!( Err(RuntimeError::InvalidTransferDestination.into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -1518,7 +1518,7 @@ mod tests_tx { let key = regular_keypair.public(); let tx = transaction!(fee: 5, set_regular_key!(*key)); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 10, key: *key)) @@ -1526,7 +1526,10 @@ mod tests_tx { let tx = transaction!(seq: 1, fee: 5, Action::CreateShard { users: vec![] }); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), regular_keypair.public(), &get_test_client(), 0, 0, 0)); + assert_eq!( + Ok(()), + state.apply(&tx, &H256::random().into(), regular_keypair.public(), &get_test_client(), 0, 0, 0) + ); check_top_level_state!(state, [ (account: sender => (seq: 2, balance: 15 - 5 - 5)), @@ -1549,7 +1552,7 @@ mod tests_tx { let key = regular_keypair.public(); let tx = transaction!(fee: 5, set_regular_key!(*key)); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 10, key: *key)), @@ -1559,7 +1562,7 @@ mod tests_tx { let tx = transaction!(fee: 5, set_regular_key!(*key)); assert_eq!( Err(RuntimeError::RegularKeyAlreadyInUse.into()), - state.apply(&tx, &H256::random(), &sender_public2, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public2, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -1582,7 +1585,7 @@ mod tests_tx { let tx = transaction! (fee: 5, set_regular_key!(sender_public2)); assert_eq!( Err(RuntimeError::RegularKeyAlreadyInUseAsPlatformAccount.into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -1605,7 +1608,7 @@ mod tests_tx { let (_, regular_public2, _) = address(); let tx = transaction! (fee: 5, set_regular_key!(regular_public2)); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), ®ular_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), ®ular_public, &get_test_client(), 0, 0, 0)); assert_eq!(Ok(false), state.regular_account_exists_and_not_null(®ular_public)); check_top_level_state!(state, [ @@ -1642,7 +1645,10 @@ mod tests_tx { ); let transfer_tx = transaction!(seq: 0, fee: 11, transfer); - assert_eq!(Ok(()), state.apply(&transfer_tx, &H256::random(), ®ular_public, &get_test_client(), 0, 0, 0)); + assert_eq!( + Ok(()), + state.apply(&transfer_tx, &H256::random().into(), ®ular_public, &get_test_client(), 0, 0, 0) + ); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 25 - 11)) ]); @@ -1684,7 +1690,10 @@ mod tests_tx { ); let transfer_tx = transaction!(seq: 0, fee: 11, transfer); - assert_eq!(Ok(()), state.apply(&transfer_tx, &H256::random(), ®ular_public, &get_test_client(), 0, 0, 0)); + assert_eq!( + Ok(()), + state.apply(&transfer_tx, &H256::random().into(), ®ular_public, &get_test_client(), 0, 0, 0) + ); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 25 - 11)) ]); @@ -1707,7 +1716,7 @@ mod tests_tx { assert_eq!(Ok(false), state.regular_account_exists_and_not_null(®ular_public)); let tx = transaction!(fee: 5, Action::CreateShard { users: vec![] }); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), ®ular_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), ®ular_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ (account: sender => (seq: 0, balance: 20)), (account: regular_address => (seq: 1, balance: 20 - 5)), @@ -1730,7 +1739,7 @@ mod tests_tx { let tx = transaction!(fee: 5, pay!(regular_address, 5)); assert_eq!( Err(RuntimeError::InvalidTransferDestination.into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -1754,7 +1763,7 @@ mod tests_tx { let tx = transaction!(fee: 5, pay!(receiver_address, 5)); assert_eq!( Err(RuntimeError::CannotUseMasterKey.into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -1781,7 +1790,7 @@ mod tests_tx { cost: 30, } .into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -1818,7 +1827,7 @@ mod tests_tx { let asset_type = Blake::blake(*transaction_tracker); let tx = transaction!(fee: 11, transaction); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 100 - 11)), @@ -1854,7 +1863,7 @@ mod tests_tx { let asset_type = Blake::blake(*transaction_tracker); let tx = transaction!(fee: 5, transaction); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 100 - 5)), @@ -1884,7 +1893,7 @@ mod tests_tx { let mint_tx = transaction!(fee: 20, mint); let asset_type = Blake::blake(*mint_tracker); - assert_eq!(Ok(()), state.apply(&mint_tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&mint_tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 120 - 20)), @@ -1907,7 +1916,10 @@ mod tests_tx { let transfer_tx = transaction!(seq: 1, fee: 30, transfer); - assert_eq!(Ok(()), state.apply(&transfer_tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!( + Ok(()), + state.apply(&transfer_tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) + ); check_top_level_state!(state, [ (account: sender => (seq: 2, balance: 120 - 20 - 30)), @@ -1945,7 +1957,7 @@ mod tests_tx { ); let tx = transaction!(fee: 11, transaction.clone()); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 100 - 11)) @@ -1959,7 +1971,7 @@ mod tests_tx { shard_id } .into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -1987,27 +1999,27 @@ mod tests_tx { let tx = transaction!(fee: 11, wrap_ccc!(lock_script_hash, quantity)); let tx_hash = tx.hash(); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); let asset_type = H160::zero(); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 100 - 11 - 30)), (account: receiver), - (asset: (Tracker::from(tx_hash), 0, 0) => { asset_type: asset_type, quantity: quantity }) + (asset: (Tracker::from(*tx_hash), 0, 0) => { asset_type: asset_type, quantity: quantity }) ]); let unwrap_ccc_tx = unwrap_ccc!( - asset_transfer_input!(asset_out_point!(Tracker::from(tx_hash), 0, asset_type, 30), vec![0x01]), + asset_transfer_input!(asset_out_point!(Tracker::from(*tx_hash), 0, asset_type, 30), vec![0x01]), receiver ); let tx = transaction!(seq: 1, fee: 11, unwrap_ccc_tx); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ (account: sender => (seq: 2, balance: 100 - 11 - 30 - 11)), (account: receiver => (seq: 0, balance: 30)), - (asset: (Tracker::from(tx_hash), 0, 0)) + (asset: (Tracker::from(*tx_hash), 0, 0)) ]); } @@ -2031,19 +2043,19 @@ mod tests_tx { let tx = transaction!(fee: 11, wrap_ccc!(lock_script_hash, quantity)); let tx_hash = tx.hash(); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); let asset_type = H160::zero(); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 100 - 11 - 30)), (account: receiver), - (asset: (Tracker::from(tx_hash), 0, 0) => { asset_type: asset_type, quantity: quantity }) + (asset: (Tracker::from(*tx_hash), 0, 0) => { asset_type: asset_type, quantity: quantity }) ]); let failed_lock_script = vec![0x02]; let unwrap_ccc_tx = unwrap_ccc!( asset_transfer_input!( - asset_out_point!(Tracker::from(tx_hash), 0, asset_type, 30), + asset_out_point!(Tracker::from(*tx_hash), 0, asset_type, 30), failed_lock_script.clone() ), receiver @@ -2056,13 +2068,13 @@ mod tests_tx { found: Blake::blake(&failed_lock_script), }) .into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 100 - 11 - 30)), (account: receiver), - (asset: (Tracker::from(tx_hash), 0, 0) => { asset_type: asset_type, quantity: quantity }) + (asset: (Tracker::from(*tx_hash), 0, 0) => { asset_type: asset_type, quantity: quantity }) ]); } @@ -2090,7 +2102,7 @@ mod tests_tx { cost: 30, } .into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -2118,18 +2130,18 @@ mod tests_tx { let tx = transaction!(fee: 11, wrap_ccc!(lock_script_hash, quantity)); let tx_hash = tx.hash(); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); let asset_type = H160::zero(); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 100 - 30 - 11)), - (asset: (Tracker::from(tx_hash), 0, 0) => { asset_type: asset_type, quantity: quantity }) + (asset: (Tracker::from(*tx_hash), 0, 0) => { asset_type: asset_type, quantity: quantity }) ]); let lock_script_hash_burn = H160::from("ca5d3fa0a6887285ef6aa85cb12960a2b6706e00"); let random_lock_script_hash = H160::random(); let transfer_tx = transfer_asset!( - inputs: asset_transfer_inputs![(asset_out_point!(Tracker::from(tx_hash), 0, asset_type, 30), vec![0x30, 0x01])], + inputs: asset_transfer_inputs![(asset_out_point!(Tracker::from(*tx_hash), 0, asset_type, 30), vec![0x30, 0x01])], asset_transfer_outputs![ (lock_script_hash, vec![vec![1]], asset_type, 10), (lock_script_hash_burn, asset_type, 5), @@ -2140,11 +2152,11 @@ mod tests_tx { let tx = transaction!(seq: 1, fee: 11, transfer_tx); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ (account: sender => (seq: 2, balance: 100 - 30 - 11 - 11)), - (asset: (Tracker::from(tx_hash), 0, 0)), + (asset: (Tracker::from(*tx_hash), 0, 0)), (asset: (transfer_tx_tracker, 0, 0) => { asset_type: asset_type, quantity: 10 }), (asset: (transfer_tx_tracker, 1, 0) => { asset_type: asset_type, quantity: 5 }), (asset: (transfer_tx_tracker, 2, 0) => { asset_type: asset_type, quantity: 15 }) @@ -2156,7 +2168,7 @@ mod tests_tx { ); let tx = transaction!(seq: 2, fee: 11, unwrap_ccc_tx); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ (account: sender => (seq: 3, balance: 100 - 30 - 11 - 11 - 11 + 5)), @@ -2183,7 +2195,7 @@ mod tests_tx { let signature = sign(&sender_private, &content_hash).unwrap(); let store_tx = transaction!(fee: 10, store!(content.clone(), sender, signature)); - let dummy_signed_hash = H256::random(); + let dummy_signed_hash = TxHash::from(H256::random()); assert_eq!(Ok(()), state.apply(&store_tx, &dummy_signed_hash, &sender_public, &get_test_client(), 0, 0, 0)); @@ -2195,7 +2207,10 @@ mod tests_tx { let signature = sign(&sender_private, &dummy_signed_hash).unwrap(); let remove_tx = transaction!(seq: 1, fee: 10, remove!(dummy_signed_hash, signature)); - assert_eq!(Ok(()), state.apply(&remove_tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!( + Ok(()), + state.apply(&remove_tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) + ); check_top_level_state!(state, [ (account: sender => (seq: 2, balance: 0)), @@ -2221,7 +2236,7 @@ mod tests_tx { let tx = transaction!(fee: 10, store!(content.clone(), sender, signature)); - match state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) { + match state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) { Err(StateError::Runtime(RuntimeError::TextVerificationFail(_))) => {} err => panic!("The transaction must fail with text verification failure, but {:?}", err), } @@ -2237,7 +2252,7 @@ mod tests_tx { assert_eq!( Err(RuntimeError::TextVerificationFail("Certifier and signer are different".to_string()).into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -2258,13 +2273,13 @@ mod tests_tx { (metadata: shards: 1) ]); - let hash = H256::random(); + let hash = TxHash::from(H256::random()); let signature = sign(&sender_private, &hash).unwrap(); let remove_tx = transaction!(fee: 10, remove!(hash, signature)); assert_eq!( Err(RuntimeError::TextNotExist.into()), - state.apply(&remove_tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&remove_tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -2314,9 +2329,9 @@ mod tests_tx { let tx1 = transaction!(fee: 5, Action::CreateShard { users: vec![] }); let tx2 = transaction!(seq: 1, fee: 5, Action::CreateShard { users: users.clone() }); - let invalid_hash = H256::random(); - let signed_hash1 = H256::random(); - let signed_hash2 = H256::random(); + let invalid_hash = TxHash::from(H256::random()); + let signed_hash1 = TxHash::from(H256::random()); + let signed_hash2 = TxHash::from(H256::random()); assert_eq!(Ok(None), state.shard_id_by_hash(&invalid_hash)); assert_eq!(Ok(None), state.shard_id_by_hash(&signed_hash1)); @@ -2367,9 +2382,9 @@ mod tests_tx { ]); let tx1 = transaction!(fee: 5, Action::CreateShard { users: vec![shard_user] }); - let invalid_hash = H256::random(); - let signed_hash1 = H256::random(); - let signed_hash2 = H256::random(); + let invalid_hash = TxHash::from(H256::random()); + let signed_hash1 = TxHash::from(H256::random()); + let signed_hash2 = TxHash::from(H256::random()); assert_eq!(Ok(None), state.shard_id_by_hash(&invalid_hash)); assert_eq!(Ok(None), state.shard_id_by_hash(&signed_hash1)); @@ -2414,7 +2429,7 @@ mod tests_tx { ]); let tx = transaction!(fee: 5, Action::CreateShard { users: vec![] }); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); let invalid_shard_id = 3; check_top_level_state!(state, [ @@ -2436,7 +2451,7 @@ mod tests_tx { ]); let tx = transaction!(fee: 5, Action::CreateShard { users: users.clone() }); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); let invalid_shard_id = 3; check_top_level_state!(state, [ @@ -2469,7 +2484,7 @@ mod tests_tx { assert_eq!( Err(RuntimeError::InvalidShardId(0).into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -2505,7 +2520,7 @@ mod tests_tx { assert_eq!( Err(RuntimeError::InvalidShardId(100).into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ (account: sender => (seq: 0, balance: 120)) @@ -2529,7 +2544,7 @@ mod tests_tx { ]); let tx = transaction!(fee: 5, set_shard_owners!(owners.clone())); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 100 - 5)), @@ -2556,7 +2571,7 @@ mod tests_tx { let tx = transaction!(fee: 5, set_shard_owners!(owners)); assert_eq!( Err(RuntimeError::NewOwnersMustContainSender.into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ (account: sender => (seq: 0, balance: 100)), @@ -2584,7 +2599,7 @@ mod tests_tx { assert_eq!( Err(RuntimeError::InsufficientPermission.into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -2611,7 +2626,7 @@ mod tests_tx { assert_eq!( Err(RuntimeError::InvalidShardId(invalid_shard_id).into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -2640,7 +2655,7 @@ mod tests_tx { let tx = transaction!(fee: 5, set_shard_owners!(owners)); assert_eq!( Err(StateError::Runtime(RuntimeError::InsufficientPermission)), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -2675,7 +2690,7 @@ mod tests_tx { let tx = transaction!(fee: 20, mint); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 100 - 20)), @@ -2705,7 +2720,7 @@ mod tests_tx { let tx = transaction!(fee: 5, set_shard_users!(new_users)); - assert_eq!(Ok(()), state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0)); + assert_eq!(Ok(()), state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0)); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 100 - 5)) ]); @@ -2737,7 +2752,7 @@ mod tests_tx { assert_eq!( Err(RuntimeError::InsufficientPermission.into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ (account: sender => (seq: 0, balance: 100)), @@ -2794,7 +2809,7 @@ mod tests_tx { got: 10, } .into()), - state.apply(&transfer_tx, &H256::random(), &signer_public, &get_test_client(), 0, 0, 0) + state.apply(&transfer_tx, &H256::random().into(), &signer_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ (account: sender => (seq: 0, balance: 25)), @@ -2860,7 +2875,10 @@ mod tests_tx { let transfer_tracker = transfer.tracker().unwrap(); let transfer_tx = transaction!(seq: 0, fee: 11, transfer); - assert_eq!(Ok(()), state.apply(&transfer_tx, &H256::random(), &signer_public, &get_test_client(), 0, 0, 0)); + assert_eq!( + Ok(()), + state.apply(&transfer_tx, &H256::random().into(), &signer_public, &get_test_client(), 0, 0, 0) + ); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 25 - 11)), (scheme: (shard3, asset_type3) => { supply: 10 }), @@ -2927,7 +2945,10 @@ mod tests_tx { let transfer_tracker = transfer.tracker().unwrap(); let transfer_tx = transaction!(seq: 0, fee: 11, transfer); - assert_eq!(Ok(()), state.apply(&transfer_tx, &H256::random(), &signer_public, &get_test_client(), 0, 0, 0)); + assert_eq!( + Ok(()), + state.apply(&transfer_tx, &H256::random().into(), &signer_public, &get_test_client(), 0, 0, 0) + ); check_top_level_state!(state, [ (account: sender => (seq: 1, balance: 25 - 11)), (scheme: (shard3, asset_type3) => { supply: 10 }), @@ -3000,7 +3021,7 @@ mod tests_tx { shard_id: shard3, } .into()), - state.apply(&transfer_tx, &H256::random(), &signer_public, &get_test_client(), 0, 0, 0) + state.apply(&transfer_tx, &H256::random().into(), &signer_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ (account: sender => (seq: 0, balance: 25)), @@ -3077,7 +3098,7 @@ mod tests_tx { got: 10, } .into()), - state.apply(&transfer_tx, &H256::random(), &signer_public, &get_test_client(), 0, 0, 0) + state.apply(&transfer_tx, &H256::random().into(), &signer_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ (account: sender => (seq: 0, balance: 25)), @@ -3112,7 +3133,7 @@ mod tests_tx { name: "shard user".to_string(), } .into()), - state.apply(&tx, &H256::random(), ®ular_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), ®ular_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ (account: sender => (seq: 0, balance: 25)) @@ -3141,7 +3162,7 @@ mod tests_tx { name: "shard user".to_string(), } .into()), - state.apply(&tx, &H256::random(), ®ular_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), ®ular_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ (account: sender => (seq: 0, balance: 25)) @@ -3170,7 +3191,7 @@ mod tests_tx { name: "shard owner".to_string(), } .into()), - state.apply(&tx, &H256::random(), ®ular_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), ®ular_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ (account: sender => (seq: 0, balance: 25)) @@ -3209,7 +3230,7 @@ mod tests_tx { name: "approver of asset".to_string(), } .into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ @@ -3252,7 +3273,7 @@ mod tests_tx { name: "registrar of asset".to_string(), } .into()), - state.apply(&tx, &H256::random(), &sender_public, &get_test_client(), 0, 0, 0) + state.apply(&tx, &H256::random().into(), &sender_public, &get_test_client(), 0, 0, 0) ); check_top_level_state!(state, [ diff --git a/state/src/item/metadata.rs b/state/src/item/metadata.rs index 25fa163cab..8b9f5a766e 100644 --- a/state/src/item/metadata.rs +++ b/state/src/item/metadata.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use ctypes::{CommonParams, ShardId}; +use ctypes::{CommonParams, ShardId, TxHash}; use primitives::H256; use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; @@ -30,7 +30,7 @@ struct TermMetadata { pub struct Metadata { number_of_shards: ShardId, number_of_initial_shards: ShardId, - hashes: Vec, + hashes: Vec, term: TermMetadata, seq: u64, params: Option, @@ -52,7 +52,7 @@ impl Metadata { &self.number_of_shards } - pub fn add_shard(&mut self, tx_hash: H256) -> ShardId { + pub fn add_shard(&mut self, tx_hash: TxHash) -> ShardId { let r = self.number_of_shards; self.number_of_shards += 1; self.hashes.push(tx_hash); @@ -67,7 +67,7 @@ impl Metadata { self.number_of_initial_shards = number_of_shards; } - pub fn shard_id_by_hash(&self, tx_hash: &H256) -> Option { + pub fn shard_id_by_hash(&self, tx_hash: &TxHash) -> Option { debug_assert_eq!(::std::mem::size_of::(), ::std::mem::size_of::<::ctypes::ShardId>()); assert!(self.hashes.len() < ::std::u16::MAX as usize); self.hashes.iter().enumerate().find(|(_index, hash)| tx_hash == *hash).map(|(index, _)| { diff --git a/state/src/traits.rs b/state/src/traits.rs index f54448e4c1..40d94688f7 100644 --- a/state/src/traits.rs +++ b/state/src/traits.rs @@ -17,7 +17,7 @@ use ckey::{public_to_address, Address, Public, Signature}; use cmerkle::Result as TrieResult; use ctypes::transaction::ShardTransaction; -use ctypes::{BlockNumber, CommonParams, ShardId, Tracker}; +use ctypes::{BlockNumber, CommonParams, ShardId, Tracker, TxHash}; use cvm::ChainTimeInfo; use primitives::{Bytes, H160, H256}; @@ -88,7 +88,7 @@ pub trait TopStateView { Ok(*self.metadata()?.expect("Metadata must exist").number_of_shards()) } - fn shard_id_by_hash(&self, tx_hash: &H256) -> TrieResult> { + fn shard_id_by_hash(&self, tx_hash: &TxHash) -> TrieResult> { Ok(self.metadata()?.and_then(|metadata| metadata.shard_id_by_hash(tx_hash))) } @@ -166,7 +166,7 @@ pub trait TopState { /// Set the regular key of account `owner_public` fn set_regular_key(&mut self, owner_public: &Public, key: &Public) -> StateResult<()>; - fn create_shard(&mut self, fee_payer: &Address, tx_hash: H256, users: Vec
) -> StateResult<()>; + fn create_shard(&mut self, fee_payer: &Address, tx_hash: TxHash, users: Vec
) -> StateResult<()>; fn change_shard_owners(&mut self, shard_id: ShardId, owners: &[Address], sender: &Address) -> StateResult<()>; fn change_shard_users(&mut self, shard_id: ShardId, users: &[Address], sender: &Address) -> StateResult<()>; @@ -174,8 +174,8 @@ pub trait TopState { fn set_shard_owners(&mut self, shard_id: ShardId, new_owners: Vec
) -> StateResult<()>; fn set_shard_users(&mut self, shard_id: ShardId, new_users: Vec
) -> StateResult<()>; - fn store_text(&mut self, key: &H256, text: Text, sig: &Signature) -> StateResult<()>; - fn remove_text(&mut self, key: &H256, sig: &Signature) -> StateResult<()>; + fn store_text(&mut self, key: &TxHash, text: Text, sig: &Signature) -> StateResult<()>; + fn remove_text(&mut self, key: &TxHash, sig: &Signature) -> StateResult<()>; fn increase_term_id(&mut self, last_term_finished_block_num: u64) -> StateResult<()>; diff --git a/sync/src/transaction/extension.rs b/sync/src/transaction/extension.rs index 4eb1aa912c..892f8f390b 100644 --- a/sync/src/transaction/extension.rs +++ b/sync/src/transaction/extension.rs @@ -21,8 +21,8 @@ use std::time::Duration; use ccore::{BlockChainClient, UnverifiedTransaction}; use cnetwork::{Api, NetworkExtension, NodeId}; use ctimer::TimerToken; +use ctypes::TxHash; use never_type::Never; -use primitives::H256; use rlp::{Encodable, UntrustedRlp}; use super::message::Message; @@ -33,12 +33,12 @@ const MAX_HISTORY_SIZE: usize = 100_000; #[derive(Default)] struct KnownTxs { - history_set: HashSet, - history_queue: VecDeque, + history_set: HashSet, + history_queue: VecDeque, } impl KnownTxs { - fn push(&mut self, hash: H256) { + fn push(&mut self, hash: TxHash) { debug_assert!(!self.history_set.contains(&hash)); self.history_set.insert(hash); self.history_queue.push_back(hash); @@ -47,7 +47,7 @@ impl KnownTxs { } } - fn contains(&mut self, hash: &H256) -> bool { + fn contains(&mut self, hash: &TxHash) -> bool { self.history_set.contains(hash) } } diff --git a/types/src/lib.rs b/types/src/lib.rs index cb3229e222..05e9fbf1c4 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -30,6 +30,7 @@ extern crate serde_json; mod block_hash; mod common_params; mod tracker; +mod tx_hash; pub mod errors; pub mod header; @@ -43,3 +44,4 @@ pub use block_hash::BlockHash; pub use common_params::CommonParams; pub use header::Header; pub use tracker::Tracker; +pub use tx_hash::TxHash; diff --git a/types/src/transaction/action.rs b/types/src/transaction/action.rs index 66884afdc2..cfe40405ee 100644 --- a/types/src/transaction/action.rs +++ b/types/src/transaction/action.rs @@ -23,7 +23,7 @@ use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; use crate::errors::SyntaxError; use crate::transaction::{AssetMintOutput, AssetTransferInput, AssetTransferOutput, ShardTransaction}; -use crate::{CommonParams, ShardId, Tracker}; +use crate::{CommonParams, ShardId, Tracker, TxHash}; const PAY: u8 = 0x02; const SET_REGULAR_KEY: u8 = 0x03; @@ -126,7 +126,7 @@ pub enum Action { signature: Signature, }, Remove { - hash: H256, + hash: TxHash, signature: Signature, }, } @@ -1037,7 +1037,7 @@ mod tests { #[test] fn encode_and_decode_remove() { rlp_encode_and_decode_test!(Action::Remove { - hash: H256::random(), + hash: H256::random().into(), signature: Signature::random(), }); } diff --git a/types/src/transaction/shard.rs b/types/src/transaction/shard.rs index f10032c9a0..f6cd0d4f88 100644 --- a/types/src/transaction/shard.rs +++ b/types/src/transaction/shard.rs @@ -21,7 +21,7 @@ use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; use super::{AssetMintOutput, AssetTransferInput, AssetTransferOutput, HashingError, PartialHashing}; use crate::util::tag::Tag; -use crate::{ShardId, Tracker}; +use crate::{ShardId, Tracker, TxHash}; /// Shard Transaction type. #[derive(Debug, Clone, PartialEq, Eq)] @@ -66,7 +66,7 @@ pub enum ShardTransaction { WrapCCC { network_id: NetworkId, shard_id: ShardId, - tx_hash: H256, + tx_hash: TxHash, output: AssetWrapCCCOutput, }, } @@ -85,7 +85,7 @@ impl ShardTransaction { .. } = self { - return (*tx_hash).into() + return (**tx_hash).into() } blake256(&*self.rlp_bytes()).into() } diff --git a/types/src/transaction/transaction.rs b/types/src/transaction/transaction.rs index c5a9c54aab..57f57275d3 100644 --- a/types/src/transaction/transaction.rs +++ b/types/src/transaction/transaction.rs @@ -16,12 +16,11 @@ use ccrypto::blake256; use ckey::NetworkId; -use primitives::H256; use rlp::RlpStream; use super::Action; use super::{AssetWrapCCCOutput, ShardTransaction}; -use crate::Tracker; +use crate::{Tracker, TxHash}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Transaction { @@ -45,11 +44,11 @@ impl Transaction { s.append(&self.action); } - /// The message hash of the tranasction. - pub fn hash(&self) -> H256 { + /// The message hash of the transaction. + pub fn hash(&self) -> TxHash { let mut stream = RlpStream::new(); self.rlp_append_unsigned(&mut stream); - blake256(stream.as_raw()) + blake256(stream.as_raw()).into() } pub fn tracker(&self) -> Option { diff --git a/types/src/tx_hash.rs b/types/src/tx_hash.rs new file mode 100644 index 0000000000..b674265f2b --- /dev/null +++ b/types/src/tx_hash.rs @@ -0,0 +1,109 @@ +// Copyright 2019 Kodebox, Inc. +// This file is part of CodeChain. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +use std::fmt::{self, Display, Formatter}; +use std::ops::Deref; + +use primitives::H256; +use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; + + +#[derive(Clone, Copy, Default, Eq, Hash, PartialEq, Debug, Deserialize, Serialize)] +pub struct TxHash(H256); + +impl From for TxHash { + fn from(h: H256) -> Self { + Self(h) + } +} + +impl Deref for TxHash { + type Target = H256; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Display for TxHash { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> { + self.0.fmt(f) + } +} + +impl Encodable for TxHash { + fn rlp_append(&self, s: &mut RlpStream) { + self.0.rlp_append(s); + } +} + +impl Decodable for TxHash { + fn decode(rlp: &UntrustedRlp) -> Result { + Ok(H256::decode(rlp)?.into()) + } +} + +#[cfg(test)] +mod tests { + use std::collections::hash_map::DefaultHasher; + use std::hash::{Hash, Hasher}; + + use rlp::{self, rlp_encode_and_decode_test}; + + use super::*; + + #[test] + fn hash_of_tx_hash_and_h256_are_the_same() { + let h256 = H256::random(); + let tx_hash = TxHash(h256); + + let mut hasher_of_h256 = DefaultHasher::new(); + let mut hasher_of_tracker = DefaultHasher::new(); + + h256.hash(&mut hasher_of_h256); + tx_hash.hash(&mut hasher_of_tracker); + + assert_eq!(hasher_of_h256.finish(), hasher_of_tracker.finish()); + } + + #[test] + fn rlp_of_tx_hash_can_be_decoded_to_h256() { + let h256 = H256::random(); + let tx_hash = TxHash(h256); + + let encoded = rlp::encode(&tx_hash); + let decoded = rlp::decode(&*encoded); + + assert_eq!(h256, decoded); + } + + #[test] + fn rlp_of_h256_can_be_decoded_to_tx_hash() { + let h256 = H256::random(); + + let encoded = rlp::encode(&h256); + let decoded = rlp::decode(&*encoded); + + let tx_hash = TxHash(h256); + assert_eq!(tx_hash, decoded); + } + + #[test] + fn rlp() { + rlp_encode_and_decode_test!(TxHash(H256::random())); + } +} From 74cec8bfdc8ea57e4821b3b5b99071c37c64288d Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Mon, 28 Oct 2019 15:17:15 +0900 Subject: [PATCH 076/105] Bump the jsonrpc version JSONRPC server 14.0.3 does not close HTTP server on connection error. --- Cargo.lock | 117 +++++++++++++++++++++++++++++---------------- rpc/Cargo.toml | 10 ++-- stratum/Cargo.toml | 6 +-- 3 files changed, 84 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b2d9aaec55..c1a75d95a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -463,11 +463,11 @@ dependencies = [ "codechain-sync 0.1.0", "codechain-types 0.1.0", "codechain-vm 0.1.0", - "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", - "jsonrpc-derive 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", - "jsonrpc-http-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", - "jsonrpc-ipc-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", - "jsonrpc-ws-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-core 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", + "jsonrpc-derive 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", + "jsonrpc-http-server 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", + "jsonrpc-ipc-server 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", + "jsonrpc-ws-server 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", "kvdb 0.1.0", "kvdb-rocksdb 0.1.0", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -517,9 +517,9 @@ dependencies = [ "codechain-json 0.1.0", "codechain-logger 0.1.0", "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", - "jsonrpc-derive 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", - "jsonrpc-tcp-server 14.0.1 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-core 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", + "jsonrpc-derive 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", + "jsonrpc-tcp-server 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)", @@ -1213,8 +1213,8 @@ dependencies = [ [[package]] name = "jsonrpc-core" -version = "14.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8#d1993a80176afdcbae6949bbf73ebbaf5625e644" +version = "14.0.3" +source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3#2135c25df57715238f1709365e3ea3bedc88e030" dependencies = [ "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1225,23 +1225,23 @@ dependencies = [ [[package]] name = "jsonrpc-derive" -version = "14.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8#d1993a80176afdcbae6949bbf73ebbaf5625e644" +version = "14.0.3" +source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3#2135c25df57715238f1709365e3ea3bedc88e030" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-http-server" -version = "14.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8#d1993a80176afdcbae6949bbf73ebbaf5625e644" +version = "14.0.3" +source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3#2135c25df57715238f1709365e3ea3bedc88e030" dependencies = [ "hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", - "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-core 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", + "jsonrpc-server-utils 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1250,11 +1250,11 @@ dependencies = [ [[package]] name = "jsonrpc-ipc-server" -version = "14.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8#d1993a80176afdcbae6949bbf73ebbaf5625e644" +version = "14.0.3" +source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3#2135c25df57715238f1709365e3ea3bedc88e030" dependencies = [ - "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", - "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-core 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", + "jsonrpc-server-utils 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-tokio-ipc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1263,12 +1263,12 @@ dependencies = [ [[package]] name = "jsonrpc-server-utils" -version = "14.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8#d1993a80176afdcbae6949bbf73ebbaf5625e644" +version = "14.0.3" +source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3#2135c25df57715238f1709365e3ea3bedc88e030" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-core 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1278,11 +1278,11 @@ dependencies = [ [[package]] name = "jsonrpc-tcp-server" -version = "14.0.1" -source = "git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8#d1993a80176afdcbae6949bbf73ebbaf5625e644" +version = "14.0.3" +source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3#2135c25df57715238f1709365e3ea3bedc88e030" dependencies = [ - "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", - "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-core 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", + "jsonrpc-server-utils 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1290,11 +1290,11 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" -version = "14.0.0" -source = "git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8#d1993a80176afdcbae6949bbf73ebbaf5625e644" +version = "14.0.3" +source = "git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3#2135c25df57715238f1709365e3ea3bedc88e030" dependencies = [ - "jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", - "jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)", + "jsonrpc-core 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", + "jsonrpc-server-utils 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1886,6 +1886,14 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro2" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pulldown-cmark" version = "0.0.3" @@ -1920,6 +1928,14 @@ dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.3.22" @@ -2558,6 +2574,16 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "syn" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "synom" version = "0.11.3" @@ -2975,6 +3001,11 @@ name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unreachable" version = "1.0.0" @@ -3270,13 +3301,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" -"checksum jsonrpc-core 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)" = "" -"checksum jsonrpc-derive 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)" = "" -"checksum jsonrpc-http-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)" = "" -"checksum jsonrpc-ipc-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)" = "" -"checksum jsonrpc-server-utils 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)" = "" -"checksum jsonrpc-tcp-server 14.0.1 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)" = "" -"checksum jsonrpc-ws-server 14.0.0 (git+https://github.com/paritytech/jsonrpc.git?rev=d1993a8)" = "" +"checksum jsonrpc-core 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)" = "" +"checksum jsonrpc-derive 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)" = "" +"checksum jsonrpc-http-server 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)" = "" +"checksum jsonrpc-ipc-server 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)" = "" +"checksum jsonrpc-server-utils 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)" = "" +"checksum jsonrpc-tcp-server 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)" = "" +"checksum jsonrpc-ws-server 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)" = "" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" @@ -3338,11 +3369,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" "checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" "checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" "checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" @@ -3413,6 +3446,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b" "checksum syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)" = "a1393e4a97a19c01e900df2aec855a29f71cf02c402e2f443b8d2747c25c5dbe" +"checksum syn 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7bedb3320d0f3035594b0b723c8a28d7d336a3eda3881db79e61d676fb644c" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" @@ -3455,6 +3489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 3aee4e1d14..fb690e203b 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -33,8 +33,8 @@ rustc-hex = "1.0" rustc-serialize = "0.3" time = "0.1" tokio-core = "0.1.17" -jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", rev = "d1993a8" } -jsonrpc-derive = { git = "https://github.com/paritytech/jsonrpc.git", rev = "d1993a8" } -jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", rev = "d1993a8" } -jsonrpc-ipc-server = { git = "https://github.com/paritytech/jsonrpc.git", rev = "d1993a8" } -jsonrpc-ws-server = { git = "https://github.com/paritytech/jsonrpc.git", rev = "d1993a8" } +jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", tag = "v14.0.3" } +jsonrpc-derive = { git = "https://github.com/paritytech/jsonrpc.git", tag = "v14.0.3" } +jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git", tag = "v14.0.3" } +jsonrpc-ipc-server = { git = "https://github.com/paritytech/jsonrpc.git", tag = "v14.0.3" } +jsonrpc-ws-server = { git = "https://github.com/paritytech/jsonrpc.git", tag = "v14.0.3" } diff --git a/stratum/Cargo.toml b/stratum/Cargo.toml index e12ad3ad6b..114ecaa173 100644 --- a/stratum/Cargo.toml +++ b/stratum/Cargo.toml @@ -9,9 +9,9 @@ authors = ["Parity Technologies ", "CodeChain Team Date: Fri, 8 Nov 2019 19:29:20 +0900 Subject: [PATCH 077/105] Remove CHANGELOG.md file You can see the changelog here: https://github.com/CodeChain-io/codechain/releases --- CHANGELOG.md | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index d015acb0e1..0000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,29 +0,0 @@ -# 1.0.0 2019-04-01 -* Initial release - -# 1.1.0 - 2019-04-04 -* Removed stakeholders who don't have stakes from trie ([#1439](https://github.com/CodeChain-io/codechain/pull/1439)) -* Fixed the bug in AssetScheme related transactions ([#1442](https://github.com/CodeChain-io/codechain/pull/1442)) - -# 1.2.0 - 2019-04-19 -* Fixed the bug of version flag. -* Added "commit-hash" command -* Added "net_recentNetworkUsage" RPC -* Added "chain_getMinTransactionFee" RPC -* Reduced network traffic - * Request the header only it need - * Send new header to random peer instead of all. -* Disabled Order and stake delegation by default -* Enhanced unit tests and e2e tests - -# 1.3.0 - 2019-05-13 -* Fixed the broken commitHash RPC in a docker image #1443 -* Fixed the crash in Tendermint #1514 -* Added base-path option #236 -* Fixed the crash on exit #348 -* Reduced the booting time #1513 - -# 1.4.0 - 2019-06-17 -* Do not prevote to the block with irrelevant generation time #1512 -* Change the name of verification threads -* Add email alarm feature #1561 #1571 From 6419957471239cb619d3df293d583c588eee5836 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Fri, 8 Nov 2019 19:31:33 +0900 Subject: [PATCH 078/105] Bump the version 2.2.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c1a75d95a8..03e029e5e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -209,7 +209,7 @@ dependencies = [ [[package]] name = "codechain" -version = "2.1.0" +version = "2.2.0" dependencies = [ "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cidr 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 29d41a3ed9..d58ec13776 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "codechain" -version = "2.1.0" +version = "2.2.0" license = "AGPL-3.0" authors = ["CodeChain Team "] exclude = [ From d85ed13b90b8c8b3a827e1891a20eb2768339749 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Mon, 28 Oct 2019 19:17:13 +0900 Subject: [PATCH 079/105] Reformat Github Actions workflows --- .editorconfig | 11 ++++++++++- .github/workflows/cargo-test.yml | 8 ++++---- .github/workflows/yarn-lint.yml | 18 +++++++++--------- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/.editorconfig b/.editorconfig index b462114869..abc5af6856 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,7 +11,16 @@ insert_final_newline=true [*.yml] indent_style=space -indent_size=4 +indent_size=2 +tab_width=8 +end_of_line=lf +charset=utf-8 +trim_trailing_whitespace=true +insert_final_newline=true + +[.github/**/*.yml] +indent_style=space +indent_size=2 tab_width=8 end_of_line=lf charset=utf-8 diff --git a/.github/workflows/cargo-test.yml b/.github/workflows/cargo-test.yml index 8c2acbc265..7e62e73fba 100644 --- a/.github/workflows/cargo-test.yml +++ b/.github/workflows/cargo-test.yml @@ -10,8 +10,8 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - toolchain: nightly-2019-10-13 - override: true + toolchain: nightly-2019-10-13 + override: true - run: rustup component add clippy - run: cargo fetch --verbose - run: cargo clippy --all --all-targets -- -D warnings @@ -23,8 +23,8 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - toolchain: nightly-2019-10-13 - override: true + toolchain: nightly-2019-10-13 + override: true - run: rustup component add rustfmt - run: cargo fmt -- --check diff --git a/.github/workflows/yarn-lint.yml b/.github/workflows/yarn-lint.yml index 0edf2821ad..97dee7fcb4 100644 --- a/.github/workflows/yarn-lint.yml +++ b/.github/workflows/yarn-lint.yml @@ -7,12 +7,12 @@ jobs: name: lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: actions/setup-node@v1 - with: - node-version: '10.x' - - run: npm install yarn - - working-directory: ./test - run: yarn - - working-directory: ./test - run: yarn lint + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + with: + node-version: '10.x' + - run: npm install yarn + - working-directory: ./test + run: yarn + - working-directory: ./test + run: yarn lint From 4eae0972447d45a934f26c16bf9cb64237997e87 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Mon, 28 Oct 2019 17:47:51 +0900 Subject: [PATCH 080/105] Add GitHub Actions for build artifacts --- .github/workflows/build.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000..519560df53 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,30 @@ +on: [push, pull_request] + +name: Actions - build + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macOS-10.14, ubuntu-18.04] + fail-fast: false + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: 1.37.0 + override: true + - run: cargo fetch --verbose + - run: cargo build --release + - name: Archive + working-directory: target/release + run: | + echo ${{github.sha}} ${{github.ref}} | tee git-ref + shasum -a 256 codechain | tee sha256sums + mkdir codechain-${{matrix.os}}-${{github.sha}} + mv codechain git-ref sha256sums codechain-${{matrix.os}}-${{github.sha}} + - uses: actions/upload-artifact@v1 + with: + name: codechain-${{matrix.os}}-${{github.sha}} + path: target/release/codechain-${{matrix.os}}-${{github.sha}} From cc9754e8146e4b5120e32bd8ba5e02fb848a07e2 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Mon, 28 Oct 2019 22:45:35 +0900 Subject: [PATCH 081/105] Make Action names filterable --- .github/workflows/build.yml | 3 ++- .github/workflows/cargo-test.yml | 10 +++++----- .github/workflows/yarn-lint.yml | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 519560df53..20ac63245a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,9 +1,10 @@ on: [push, pull_request] -name: Actions - build +name: build jobs: build: + name: Actions - build runs-on: ${{ matrix.os }} strategy: matrix: diff --git a/.github/workflows/cargo-test.yml b/.github/workflows/cargo-test.yml index 7e62e73fba..9be1a6ee78 100644 --- a/.github/workflows/cargo-test.yml +++ b/.github/workflows/cargo-test.yml @@ -1,10 +1,10 @@ on: [push, pull_request] -name: Actions - cargo +name: cargo-test jobs: clippy: - name: clippy + name: Actions - clippy runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 @@ -17,7 +17,7 @@ jobs: - run: cargo clippy --all --all-targets -- -D warnings rustfmt: - name: rustfmt + name: Actions - rustfmt runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 @@ -28,8 +28,8 @@ jobs: - run: rustup component add rustfmt - run: cargo fmt -- --check - build: - name: unit test + unit-test: + name: Actions - unit test runs-on: ${{ matrix.os }} strategy: matrix: diff --git a/.github/workflows/yarn-lint.yml b/.github/workflows/yarn-lint.yml index 97dee7fcb4..f2673dced4 100644 --- a/.github/workflows/yarn-lint.yml +++ b/.github/workflows/yarn-lint.yml @@ -1,10 +1,10 @@ on: [push, pull_request] -name: Actions - yarn +name: yarn-lint jobs: lint: - name: lint + name: Actions - lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 From 59e9ebd0bbf93ff0eeac9e9e93ad302ab4a45ce0 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Fri, 15 Nov 2019 18:07:52 +0900 Subject: [PATCH 082/105] Set finalized_view to None when restoring in the Commit step In the Tendermint restoring process, if the backup state is the Commit step, CodeChain set the step to the Precommit step and handles the votes. The purpose of the behavior is that calling functions that are called when enters the Commit state. After we introduce the `finalized_view_of_current_block` variable, the variable should be changed to `None` when CodeChain sets the state to Precommit in the restoring process. --- core/src/consensus/tendermint/worker.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 93386a0df5..19b12e96c0 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -1033,6 +1033,11 @@ impl Worker { let client = self.client(); let backup = restore(client.get_kvdb().as_ref()); if let Some(backup) = backup { + if backup.step == Step::Commit { + self.finalized_view_of_current_block = None; + } else { + self.finalized_view_of_current_block = backup.finalized_view_of_current_block; + } let backup_step = match backup.step { Step::Propose => TendermintState::Propose, Step::Prevote => TendermintState::Prevote, @@ -1046,7 +1051,6 @@ impl Worker { self.height = backup.height; self.view = backup.view; self.finalized_view_of_previous_block = backup.finalized_view_of_previous_block; - self.finalized_view_of_current_block = backup.finalized_view_of_current_block; if let Some(proposal) = backup.proposal { if client.block(&BlockId::Hash(proposal)).is_some() { From 0fd2cadf33eb9483dfb085f838aa632dc2b322b3 Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Tue, 19 Nov 2019 17:09:37 +0900 Subject: [PATCH 083/105] Revert "Set finalized_view to None when restoring in the Commit step" This reverts commit 59e9ebd0bbf93ff0eeac9e9e93ad302ab4a45ce0. --- core/src/consensus/tendermint/worker.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 19b12e96c0..93386a0df5 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -1033,11 +1033,6 @@ impl Worker { let client = self.client(); let backup = restore(client.get_kvdb().as_ref()); if let Some(backup) = backup { - if backup.step == Step::Commit { - self.finalized_view_of_current_block = None; - } else { - self.finalized_view_of_current_block = backup.finalized_view_of_current_block; - } let backup_step = match backup.step { Step::Propose => TendermintState::Propose, Step::Prevote => TendermintState::Prevote, @@ -1051,6 +1046,7 @@ impl Worker { self.height = backup.height; self.view = backup.view; self.finalized_view_of_previous_block = backup.finalized_view_of_previous_block; + self.finalized_view_of_current_block = backup.finalized_view_of_current_block; if let Some(proposal) = backup.proposal { if client.block(&BlockId::Hash(proposal)).is_some() { From 1b3bd9eba4fa21d2413c2e6195df3e334326da14 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Mon, 18 Nov 2019 13:45:52 +0900 Subject: [PATCH 084/105] Do not assert the finalized_view while restoring In the Tendermint restoring process, if the backup state is the Commit step, CodeChain set the step to the Precommit step and handles the votes. The purpose of the behavior is that calling functions that are called when enters the Commit state. Changing the "step" in the restoring process is fragile. It is easy to miss to set some variables. The `finalized_view_of_current_block` variable should be changed when the step is changed. It was lost before. This commit fixes the problem by ignoring the assertion check in the restore process. Although it is not a perfect solution, it is consistent. There is some code already do differently in the restore process. --- core/src/consensus/tendermint/worker.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 93386a0df5..5f3aa0ead7 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -612,8 +612,11 @@ impl Worker { } /// Do we need this function? - fn set_finalized_view_in_current_height(&mut self, view: View) { - assert_eq!(self.finalized_view_of_current_block, None); + fn set_finalized_view_in_current_height(&mut self, view: View, is_restoring: bool) { + if !is_restoring { + assert_eq!(self.finalized_view_of_current_block, None); + } + self.finalized_view_of_current_block = Some(view); } @@ -774,7 +777,7 @@ impl Worker { Step::Commit => { cinfo!(ENGINE, "move_to_step: Commit."); let (view, block_hash) = state.committed().expect("commit always has committed_view"); - self.set_finalized_view_in_current_height(view); + self.set_finalized_view_in_current_height(view, is_restoring); let proposal_received = self.is_proposal_received(self.height, view, block_hash); let proposal_imported = self.client().block(&block_hash.into()).is_some(); From 9deef2a29a919446e9c975f723b8ca455ad0651d Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Fri, 15 Nov 2019 19:05:46 +0900 Subject: [PATCH 085/105] Bump the version 2.2.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03e029e5e9..d5c0f5c708 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -209,7 +209,7 @@ dependencies = [ [[package]] name = "codechain" -version = "2.2.0" +version = "2.2.1" dependencies = [ "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cidr 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index d58ec13776..aad3f3e977 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "codechain" -version = "2.2.0" +version = "2.2.1" license = "AGPL-3.0" authors = ["CodeChain Team "] exclude = [ From 63714bdc0cb9373390932062995c21e67bb3321c Mon Sep 17 00:00:00 2001 From: SeongChan Lee Date: Mon, 11 Nov 2019 23:43:53 +0900 Subject: [PATCH 086/105] Update build task to follow the release process --- .github/workflows/build.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 20ac63245a..376bd39784 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,11 +21,12 @@ jobs: - name: Archive working-directory: target/release run: | - echo ${{github.sha}} ${{github.ref}} | tee git-ref - shasum -a 256 codechain | tee sha256sums - mkdir codechain-${{matrix.os}}-${{github.sha}} - mv codechain git-ref sha256sums codechain-${{matrix.os}}-${{github.sha}} + mkdir artifacts + echo ${{github.sha}} ${{github.ref}} | tee artifacts/git-ref + shasum -a 256 codechain | tee artifacts/sha256sums + CODECHAIN_VERSION="$(./codechain --version | cut -d ' ' -f 2)" + tar cvfz artifacts/codechain-${CODECHAIN_VERSION}-$(uname -m)-$(echo $(uname) | tr '[:upper:]' '[:lower:]').tar.gz codechain - uses: actions/upload-artifact@v1 with: - name: codechain-${{matrix.os}}-${{github.sha}} - path: target/release/codechain-${{matrix.os}}-${{github.sha}} + name: codechain-${{ matrix.os }} + path: target/release/artifacts From 5d24400baeb8a59394b1eba9d4ea3085edb10b71 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Mon, 20 Apr 2020 15:08:03 +0900 Subject: [PATCH 087/105] Format corgi.json --- core/res/corgi.json | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/core/res/corgi.json b/core/res/corgi.json index e581a30593..fcc6371fb0 100644 --- a/core/res/corgi.json +++ b/core/res/corgi.json @@ -57,22 +57,22 @@ "maxTransferMetadataSize": "0x0100", "maxTextContentSize": "0x0200", "networkID": "wc", - "minPayCost" : 100, - "minSetRegularKeyCost" : 10000, - "minCreateShardCost" : 1000000, - "minSetShardOwnersCost" : 100000, - "minSetShardUsersCost" : 10000, - "minWrapCccCost" : 100000, - "minCustomCost" : 0, - "minStoreCost" : 5000, - "minRemoveCost" : 5000, - "minMintAssetCost" : 100000, - "minTransferAssetCost" : 100, - "minChangeAssetSchemeCost" : 100000, - "minIncreaseAssetSupplyCost" : 100000, - "minComposeAssetCost" : 100000, - "minDecomposeAssetCost" : 100000, - "minUnwrapCccCost" : 100, + "minPayCost": 100, + "minSetRegularKeyCost": 10000, + "minCreateShardCost": 1000000, + "minSetShardOwnersCost": 100000, + "minSetShardUsersCost": 10000, + "minWrapCccCost": 100000, + "minCustomCost": 0, + "minStoreCost": 5000, + "minRemoveCost": 5000, + "minMintAssetCost": 100000, + "minTransferAssetCost": 100, + "minChangeAssetSchemeCost": 100000, + "minIncreaseAssetSupplyCost": 100000, + "minComposeAssetCost": 100000, + "minDecomposeAssetCost": 100000, + "minUnwrapCccCost": 100, "maxBodySize": 4194304, "snapshotPeriod": 16384 }, @@ -93,12 +93,17 @@ "extraData": "0x" }, "accounts": { - "wccqx6n79wgvye8l8rx49xuqvm3vtwkffz28sff8axv": { "balance": "2100000000000000000", "seq": "0" } + "wccqx6n79wgvye8l8rx49xuqvm3vtwkffz28sff8axv": { + "balance": "2100000000000000000", + "seq": "0" + } }, "shards": { "0": { "seq": 0, - "owners": ["wccqx6n79wgvye8l8rx49xuqvm3vtwkffz28sff8axv"], + "owners": [ + "wccqx6n79wgvye8l8rx49xuqvm3vtwkffz28sff8axv" + ], "users": [] } } From 22f2520c992f5fce019e9201d276ef6676b271cb Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Mon, 20 Apr 2020 15:08:54 +0900 Subject: [PATCH 088/105] Update Corgi's genesis block hash --- core/res/corgi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/res/corgi.json b/core/res/corgi.json index fcc6371fb0..db850afc13 100644 --- a/core/res/corgi.json +++ b/core/res/corgi.json @@ -88,7 +88,7 @@ }, "score": "0x20000", "author": "wccq959puf2uj2587x86am0ycxeqjqgnrm9uy7qyjhr", - "timestamp": "0x02", + "timestamp": "0x03", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "0x" }, From 2c1b2817f393edf499309a77e84af60f7d2c0342 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Mon, 20 Apr 2020 15:14:14 +0900 Subject: [PATCH 089/105] Bump the version 2.2.2 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d5c0f5c708..643b10ab17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -209,7 +209,7 @@ dependencies = [ [[package]] name = "codechain" -version = "2.2.1" +version = "2.2.2" dependencies = [ "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cidr 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index aad3f3e977..ebd28abf08 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "codechain" -version = "2.2.1" +version = "2.2.2" license = "AGPL-3.0" authors = ["CodeChain Team "] exclude = [ From d7d8c048245c181cb48159349458bacd976bdb90 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 22 Apr 2020 15:06:20 +0900 Subject: [PATCH 090/105] Change initial validators in Corgi --- core/res/corgi.json | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/core/res/corgi.json b/core/res/corgi.json index db850afc13..5c7a8d2b1f 100644 --- a/core/res/corgi.json +++ b/core/res/corgi.json @@ -12,29 +12,7 @@ "0x7f4c4ea931d5b235a8aff5fe7da030d2112d564c6d856cb09fee30f701fcc67972a5f5feffad1f04d0162c4ce069a7659dd88961e21aa692ab9faf5e4167c923", "0xdde065a94d48fdabc5012a60e8086e5419b2e1ff2ee8cd8ffee6ce272fe7b4e41b7dd30f932b5313c082d6370a361d96aee87142df1822bf08f46d98a6710f3c", "0x59bba94026bbed60595eb9bb5d2e9be657fe8eb113f6eae739da22bc516065fffbe9bf17231af1cb6f423c26de6b8748f4f0e414ffeda010d1963cf4f3355acc", - "0x902e16a84fe7df003a0af5e4e50cc5bbdd0b9ca2c3f9f22361e5a86e7401065cdd1b886906c6080affe38e0d07fea8229d07b4be3df7689e0ef8755b2baeef22", - "0x3594efb706993f03ffb027a95720aa2547f977ed8e6b7b0d7928ac3d8ff4529a440e83281e1729384281842d88e8be8f8e06b2bb3aea30513adce5af1b9a580a", - "0x41392b0e8d499e7ab93af92bbd5ab69efbbf67480714bc4d67766e3b64ec21207346139544226cde991cdd914e3d2bdd3d3e6db281e1d4d5432d2f8e0413ef18", - "0xfd1eb32dd7286fb6e48e9ab69b5de09f21b7e3b29ed1d535365490928e4bab906f8b5ea7a7f5e6ed35f91de8aa6b236d2805a12cbd501a4e0377f100333e2ecb", - "0xbc08f2384189929f002ffba6b29298e6dbe95c2775b069d786ce2d2b233bb259a3c1625c7cf048bc34cf1bf2a0baf477782e5d2a7592259e9189435ee055165b", - "0xb094d0cc8595602d1ca839e25cf5bc285113f6888093db14778887e7842fd2ca406ef4e882ecd4334e2ff3e17e60de28e8f82ec69b4e166aa81cd12b53614354", - "0x9bb39b1b64450d26f804c8b186a175eaf5014ae8c45a0ea30b0db4c19f38001ad633dd78e34aec7e395095c316d3f7e21b346c74854c26649ca99bce3eec1d4a", - "0x642eb2f2427680e11cf8f1f98b131892eb88d0448987f96aa6fddcd7f52268de3bde2b1f5d290974be7bd96e7ad158c4dd70d0203a0dd9c524fc821eab8625a5", - "0xa6bcdc73774790ba21fb044a6e0a5b3c5c668e39e3f6e10417ecda687ec3dc1eb0a11e0e3dc164f61fd7ac946e69504facf54b59921ded4e47e9016d4de2d047", - "0xa3281bd5d3a1070ee703a83a6fb56ca78a7fd38f89ff2f92a15e7f706907b688b3dc32a4df2cd7c87f4db9246f9f9e30e38220327658719cd6556348b419cad4", - "0x434ec2603dfe30f7cde9fdf1f823c6cfeea240dcf71428ed28aee4f17ea8b6cebfb64a0a47c6e2aecff7df7a345fcd88c86e9182e6b7a4dcea222d75f2809cc3", - "0x3d5eebb4c5365c447bed8a1b12bbba285a74799af24518aff473915c3536dc66d14c7fe5d1a05975c12eb625c5ebbb838d38942c7708c3ca0f6204b0e5309c14", - "0x2ec6eef39b6010aed3cc4952dc4eee691b8c529be960ab01c2f5d007f9c3324604bee5ed17e99bb89bc8b9b5623db9bbafd72e1eb996cea220d90ab44bc53247", - "0xbe14dd1b62792b3dc2eeeb2da1796dc025c199f221245fe7845a86855431cf1ee73cd9527116f3b2a1c83cdbbac8b063368c380e661248f94a9a31ed81c3fbf0", - "0x2baffa614675725f22a1444d083f438d274736dfd6c881e407e277b5b80a14c093bab0eda13fd56bcac11cfaab7973689956bd4d71ac563c2ca8e47dae0dda7d", - "0x069b7e4b0fa102653f353498e566c5039253b0462257e16128c666594a71c5bb04fe2335bdf2ed87ae67d6b6ea02aed8ad9e1b7363d991cac16a898695500b4a", - "0xcdfd88687ee6a7e7a83a31c856bcd903ea66f9dd2a0418eafddca1bd472ad9b0502dcebaaed3ad1dd14a8f0ca8eac59a19b3f007a7f5ec63d1159708ec8ffd0d", - "0x0a728e6115d61054e8b29c8314675474b9dac4153616fdd7287c5c62a0b45c0220ce1088e6e8fe87ad8919f06220ad10eb1ac14fd337b9e229f4cdefa493a4b6", - "0xf337044224165d994061cdb1d3f429a656712b938f5dfe563991b63470845b4e379f8be1b3cd8a6d81c6662eb029946e5d3fc8665f94afb2b7ce8f02b3c8b476", - "0x2754f7166be6108386ed12565fad0ea733e48bcd48da3f31b24274b4a66d98b380cab4b1fbb05488c51a1172bc5dd0120d04be096b49604c3b02e8a12fa9c6b8", - "0xcbc1561cb3c2ebbde921edfa39d4c51a539a1dd6e1d1372f14868777c58f21260deb2a7a2785ac14df5400d41a7b14d5db02d86e74183974a6a90038924757cf", - "0x9cbf38a58ef634b22e9fac4dea7f279eb9c715cd0f055fb6f19f2019bc83b74d5194f8c757d247ae839c264ea2bca061f163359937f05685465e4149d551b2fb", - "0xbc754c113bd70e7e59cc5b317d8067dc5da45345aaa74e97af1e07d25d28696af3bc54c1e7b429998b3856d4f360a3e823b0a3cd85db3f4899f0ab5dfc62053a" + "0x902e16a84fe7df003a0af5e4e50cc5bbdd0b9ca2c3f9f22361e5a86e7401065cdd1b886906c6080affe38e0d07fea8229d07b4be3df7689e0ef8755b2baeef22" ], "timeoutPropose": 3000, "timeoutProposeDelta": 500, From fa617d6a5c7499488ad2e795f9c9da3294b6e431 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 22 Apr 2020 15:06:49 +0900 Subject: [PATCH 091/105] Bump the version 2.2.3 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 643b10ab17..32267da791 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -209,7 +209,7 @@ dependencies = [ [[package]] name = "codechain" -version = "2.2.2" +version = "2.2.3" dependencies = [ "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cidr 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index ebd28abf08..9119a7323c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "codechain" -version = "2.2.2" +version = "2.2.3" license = "AGPL-3.0" authors = ["CodeChain Team "] exclude = [ From 9bbaf19aa32d1506e3b6ec5d8d0351c6fc2bc295 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 3 Jun 2020 14:01:53 +0900 Subject: [PATCH 092/105] Remove unused TransactionListener --- core/src/miner/miner.rs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index 0278715cff..bc1281badb 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -111,11 +111,8 @@ struct SealingWork { enabled: bool, } -type TransactionListener = Box; - pub struct Miner { mem_pool: Arc>, - transaction_listener: RwLock>, next_allowed_reseal: Mutex, next_mandatory_reseal: RwLock, sealing_block_last_request: Mutex, @@ -173,7 +170,6 @@ impl Miner { Self { mem_pool, - transaction_listener: RwLock::new(vec![]), next_allowed_reseal: Mutex::new(Instant::now()), next_mandatory_reseal: RwLock::new(Instant::now() + options.reseal_max_period), params: RwLock::new(AuthoringParams::default()), @@ -196,11 +192,6 @@ impl Miner { self.mem_pool.write().recover_from_db(client); } - /// Set a callback to be notified about imported transactions' hashes. - pub fn add_transactions_listener(&self, f: Box) { - self.transaction_listener.write().push(f); - } - /// Get `Some` `clone()` of the current pending block's state or `None` if we're not sealing. pub fn pending_state(&self, latest_block_number: BlockNumber) -> Option { self.map_pending_block(|b| b.state().clone(), latest_block_number) @@ -355,7 +346,7 @@ impl Miner { debug_assert_eq!(insertion_results.len(), intermediate_results.iter().filter(|r| r.is_ok()).count()); let mut insertion_results_index = 0; - let results = intermediate_results + intermediate_results .into_iter() .map(|res| match res { Err(e) => Err(e), @@ -367,13 +358,7 @@ impl Miner { Ok(result) } }) - .collect(); - - for listener in &*self.transaction_listener.read() { - listener(&inserted); - } - - results + .collect() } fn calculate_timelock(&self, tx: &SignedTransaction, client: &C) -> Result { From 9e44a1d5342f4df272e28a280fcf50ce473746e3 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 3 Jun 2020 12:19:13 +0900 Subject: [PATCH 093/105] Introduce NextMandatoryReseal in miner.rs NextMandatoryReseal limits the lifetime of the inner lock. --- core/src/miner/miner.rs | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index bc1281badb..bc33281aff 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -114,7 +114,7 @@ struct SealingWork { pub struct Miner { mem_pool: Arc>, next_allowed_reseal: Mutex, - next_mandatory_reseal: RwLock, + next_mandatory_reseal: NextMandatoryReseal, sealing_block_last_request: Mutex, sealing_work: Mutex, params: RwLock, @@ -129,6 +129,26 @@ pub struct Miner { immune_users: RwLock>, } +struct NextMandatoryReseal { + instant: RwLock, +} + +impl NextMandatoryReseal { + pub fn new(instant: Instant) -> Self { + Self { + instant: RwLock::new(instant), + } + } + + pub fn get(&self) -> Instant { + *self.instant.read() + } + + pub fn set(&self, instant: Instant) { + *self.instant.write() = instant; + } +} + impl Miner { /// Push listener that will handle new jobs pub fn add_work_listener(&self, notifier: Box) { @@ -171,7 +191,7 @@ impl Miner { Self { mem_pool, next_allowed_reseal: Mutex::new(Instant::now()), - next_mandatory_reseal: RwLock::new(Instant::now() + options.reseal_max_period), + next_mandatory_reseal: NextMandatoryReseal::new(Instant::now() + options.reseal_max_period), params: RwLock::new(AuthoringParams::default()), sealing_block_last_request: Mutex::new(0), sealing_work: Mutex::new(SealingWork { @@ -620,7 +640,7 @@ impl Miner { C: BlockChainTrait + ImportBlock, { if block.transactions().is_empty() && !self.options.force_sealing - && Instant::now() <= *self.next_mandatory_reseal.read() + && Instant::now() <= self.next_mandatory_reseal.get() { cdebug!(MINER, "seal_block_internally: no sealing."); return false @@ -637,7 +657,7 @@ impl Miner { return false } - *self.next_mandatory_reseal.write() = Instant::now() + self.options.reseal_max_period; + self.next_mandatory_reseal.set(Instant::now() + self.options.reseal_max_period); let sealed = if self.engine_type().is_seal_first() { block.lock().already_sealed() } else { From 81d6218eaff65bb758d4379c729dae26b5980e57 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 3 Jun 2020 13:59:26 +0900 Subject: [PATCH 094/105] Introduce NextAllowedReseal type NextAllowedReseal limits the lifetime of the inner lock. --- core/src/miner/miner.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index bc33281aff..b5b4939aee 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -113,7 +113,7 @@ struct SealingWork { pub struct Miner { mem_pool: Arc>, - next_allowed_reseal: Mutex, + next_allowed_reseal: NextAllowedReseal, next_mandatory_reseal: NextMandatoryReseal, sealing_block_last_request: Mutex, sealing_work: Mutex, @@ -129,6 +129,8 @@ pub struct Miner { immune_users: RwLock>, } +type NextAllowedReseal = NextMandatoryReseal; + struct NextMandatoryReseal { instant: RwLock, } @@ -190,7 +192,7 @@ impl Miner { Self { mem_pool, - next_allowed_reseal: Mutex::new(Instant::now()), + next_allowed_reseal: NextAllowedReseal::new(Instant::now()), next_mandatory_reseal: NextMandatoryReseal::new(Instant::now() + options.reseal_max_period), params: RwLock::new(AuthoringParams::default()), sealing_block_last_request: Mutex::new(0), @@ -684,7 +686,7 @@ impl Miner { /// Are we allowed to do a non-mandatory reseal? fn transaction_reseal_allowed(&self) -> bool { - self.sealing_enabled.load(Ordering::Relaxed) && (Instant::now() > *self.next_allowed_reseal.lock()) + self.sealing_enabled.load(Ordering::Relaxed) && (Instant::now() > self.next_allowed_reseal.get()) } fn map_pending_block(&self, f: F, latest_block_number: BlockNumber) -> Option @@ -935,7 +937,7 @@ impl MinerService for Miner { } // Sealing successful - *self.next_allowed_reseal.lock() = Instant::now() + self.options.reseal_min_period; + self.next_allowed_reseal.set(Instant::now() + self.options.reseal_min_period); if !self.options.no_reseal_timer { chain.set_min_timer(); } From 8a75c5e2a1981f31d873b69b6106ac072b87c4e5 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 3 Jun 2020 13:52:05 +0900 Subject: [PATCH 095/105] Introduce Params struct Params limits the lifetime of the inner lock. --- core/src/miner/miner.rs | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index b5b4939aee..d20e777aa8 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -117,7 +117,7 @@ pub struct Miner { next_mandatory_reseal: NextMandatoryReseal, sealing_block_last_request: Mutex, sealing_work: Mutex, - params: RwLock, + params: Params, engine: Arc, options: MinerOptions, @@ -151,6 +151,29 @@ impl NextMandatoryReseal { } } +struct Params { + params: RwLock, +} + +impl Params { + pub fn new(params: AuthoringParams) -> Self { + Self { + params: RwLock::new(params), + } + } + + pub fn get(&self) -> AuthoringParams { + self.params.read().clone() + } + + pub fn apply(&self, f: F) + where + F: FnOnce(&mut AuthoringParams) -> (), { + let mut params = self.params.write(); + f(&mut params); + } +} + impl Miner { /// Push listener that will handle new jobs pub fn add_work_listener(&self, notifier: Box) { @@ -194,7 +217,7 @@ impl Miner { mem_pool, next_allowed_reseal: NextAllowedReseal::new(Instant::now()), next_mandatory_reseal: NextMandatoryReseal::new(Instant::now() + options.reseal_max_period), - params: RwLock::new(AuthoringParams::default()), + params: Params::new(AuthoringParams::default()), sealing_block_last_request: Mutex::new(0), sealing_work: Mutex::new(SealingWork { queue: SealingQueue::new(options.work_queue_size), @@ -492,7 +515,7 @@ impl Miner { let last_work_hash = sealing_work.queue.peek_last_ref().map(|pb| *pb.block().header().hash()); ctrace!(MINER, "prepare_block: No existing work - making new block"); - let params = self.params.read().clone(); + let params = self.params.get(); let open_block = chain.prepare_open_block(parent_block_id, params.author, params.extra_data); let (block_number, parent_hash) = { let header = open_block.block().header(); @@ -731,11 +754,11 @@ impl MinerService for Miner { } fn authoring_params(&self) -> AuthoringParams { - self.params.read().clone() + self.params.get() } fn set_author(&self, address: Address) -> Result<(), AccountProviderError> { - self.params.write().author = address; + self.params.apply(|params| params.author = address); if self.engine_type().need_signer_key() && self.engine.seals_internally().is_some() { if let Some(ref ap) = self.accounts { @@ -759,7 +782,7 @@ impl MinerService for Miner { } fn set_extra_data(&self, extra_data: Bytes) { - self.params.write().extra_data = extra_data; + self.params.apply(|params| params.extra_data = extra_data); } fn minimal_fee(&self) -> u64 { From 2d875b66a870be8fc0964bbf0960072bca4ab201 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 3 Jun 2020 14:28:05 +0900 Subject: [PATCH 096/105] Introduce SealingBlockLastRequest SealingBlockLastRequest limits the lifetime of the inner lock. --- core/src/miner/miner.rs | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index d20e777aa8..0d86692dad 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -115,7 +115,7 @@ pub struct Miner { mem_pool: Arc>, next_allowed_reseal: NextAllowedReseal, next_mandatory_reseal: NextMandatoryReseal, - sealing_block_last_request: Mutex, + sealing_block_last_request: SealingBlockLastRequest, sealing_work: Mutex, params: Params, engine: Arc, @@ -129,6 +129,30 @@ pub struct Miner { immune_users: RwLock>, } +struct SealingBlockLastRequest { + block_number: Mutex, +} + +impl SealingBlockLastRequest { + pub fn new() -> Self { + Self { + block_number: Mutex::new(0), + } + } + + pub fn get(&self) -> u64 { + *self.block_number.lock() + } + + /// Returns previous value + pub fn set(&self, block_number: u64) -> u64 { + let mut guard = self.block_number.lock(); + let prev = *guard; + *guard = block_number; + prev + } +} + type NextAllowedReseal = NextMandatoryReseal; struct NextMandatoryReseal { @@ -218,7 +242,7 @@ impl Miner { next_allowed_reseal: NextAllowedReseal::new(Instant::now()), next_mandatory_reseal: NextMandatoryReseal::new(Instant::now() + options.reseal_max_period), params: Params::new(AuthoringParams::default()), - sealing_block_last_request: Mutex::new(0), + sealing_block_last_request: SealingBlockLastRequest::new(), sealing_work: Mutex::new(SealingWork { queue: SealingQueue::new(options.work_queue_size), enabled: options.force_sealing || scheme.engine.seals_internally().is_some(), @@ -262,7 +286,7 @@ impl Miner { let mut sealing_work = self.sealing_work.lock(); if sealing_work.enabled { ctrace!(MINER, "requires_reseal: sealing enabled"); - let last_request = *self.sealing_block_last_request.lock(); + let last_request = self.sealing_block_last_request.get(); let should_disable_sealing = !self.options.force_sealing && !has_local_transactions && self.engine.seals_internally().is_none() @@ -889,16 +913,16 @@ impl MinerService for Miner { } } } - let mut sealing_block_last_request = self.sealing_block_last_request.lock(); + let best_number = client.chain_info().best_block_number; - if *sealing_block_last_request != best_number { + let prev_request = self.sealing_block_last_request.set(best_number); + if prev_request != best_number { ctrace!( MINER, "prepare_work_sealing: Miner received request (was {}, now {}) - waking up.", - *sealing_block_last_request, + prev_request, best_number ); - *sealing_block_last_request = best_number; } // Return if we restarted From 89d9eddff4a8a8b70a4770ff7a8c0117337c7a75 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 3 Jun 2020 15:33:53 +0900 Subject: [PATCH 097/105] Introduce Notifiers Nrtofiers limits the lifetime of the inner lock. --- core/src/miner/miner.rs | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index 0d86692dad..319f20332f 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -30,7 +30,7 @@ use ctypes::{BlockHash, BlockNumber, Header, TxHash}; use cvm::ChainTimeInfo; use kvdb::KeyValueDB; use parking_lot::{Mutex, RwLock}; -use primitives::{Bytes, H256}; +use primitives::{Bytes, H256, U256}; use super::mem_pool::{Error as MemPoolError, MemPool}; use super::mem_pool_types::{AccountDetails, MemPoolInput, TxOrigin, TxTimelock}; @@ -124,11 +124,38 @@ pub struct Miner { sealing_enabled: AtomicBool, accounts: Option>, - notifiers: RwLock>>, + notifiers: Notifiers, malicious_users: RwLock>, immune_users: RwLock>, } +struct Notifiers { + notifiers: RwLock>>, +} + +impl Notifiers { + pub fn new(notifiers: Vec>) -> Self { + Self { + notifiers: RwLock::new(notifiers), + } + } + + pub fn push(&self, notifier: Box) { + self.notifiers.write().push(notifier); + } + + pub fn is_empty(&self) -> bool { + self.notifiers.read().is_empty() + } + + pub fn notify(&self, pow_hash: H256, target: U256) { + // FIXME: Calling callbacks inside of lock lifetime may cause a deadlock. + for notifier in self.notifiers.read().iter() { + notifier.notify(pow_hash, target) + } + } +} + struct SealingBlockLastRequest { block_number: Mutex, } @@ -201,7 +228,7 @@ impl Params { impl Miner { /// Push listener that will handle new jobs pub fn add_work_listener(&self, notifier: Box) { - self.notifiers.write().push(notifier); + self.notifiers.push(notifier); } pub fn new( @@ -251,7 +278,7 @@ impl Miner { options, sealing_enabled: AtomicBool::new(true), accounts, - notifiers: RwLock::new(notifiers), + notifiers: Notifiers::new(notifiers), malicious_users: RwLock::new(HashSet::new()), immune_users: RwLock::new(HashSet::new()), } @@ -502,7 +529,7 @@ impl Miner { let is_new = original_work_hash.map_or(true, |h| *block.block().header().hash() != h); sealing_work.queue.push(block); // If push notifications are enabled we assume all work items are used. - if !self.notifiers.read().is_empty() && is_new { + if !self.notifiers.is_empty() && is_new { sealing_work.queue.use_last_ref(); } (Some((pow_hash, score, number)), is_new) @@ -519,9 +546,7 @@ impl Miner { if is_new { if let Some((pow_hash, score, _number)) = work { let target = self.engine.score_to_target(&score); - for notifier in self.notifiers.read().iter() { - notifier.notify(pow_hash, target) - } + self.notifiers.notify(pow_hash, target); } } } From 65a007205080e0129338c4e095965eac6bc31ecb Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 3 Jun 2020 15:53:00 +0900 Subject: [PATCH 098/105] Introduce Users struct Users limits the lifetime of the inner lock. --- core/src/miner/miner.rs | 79 +++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index 319f20332f..ccf5b791f9 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -16,7 +16,6 @@ use std::collections::HashSet; use std::iter::once; -use std::iter::FromIterator; use std::ops::Range; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; @@ -125,8 +124,39 @@ pub struct Miner { accounts: Option>, notifiers: Notifiers, - malicious_users: RwLock>, - immune_users: RwLock>, + malicious_users: Users, + immune_users: Users, +} + +struct Users { + users: RwLock>, +} + +impl Users { + pub fn new() -> Self { + Self { + users: RwLock::new(HashSet::new()), + } + } + + pub fn cloned(&self) -> Vec
{ + self.users.read().iter().map(Clone::clone).collect() + } + + pub fn contains(&self, address: &Address) -> bool { + self.users.read().contains(address) + } + + pub fn insert(&self, address: Address) -> bool { + self.users.write().insert(address) + } + + pub fn remove_users<'a>(&self, addresses: impl Iterator) { + let mut users = self.users.write(); + for address in addresses { + users.remove(address); + } + } } struct Notifiers { @@ -279,8 +309,8 @@ impl Miner { sealing_enabled: AtomicBool::new(true), accounts, notifiers: Notifiers::new(notifiers), - malicious_users: RwLock::new(HashSet::new()), - immune_users: RwLock::new(HashSet::new()), + malicious_users: Users::new(), + immune_users: Users::new(), } } @@ -365,7 +395,7 @@ impl Miner { let signer_public = tx.recover_public()?; let signer_address = public_to_address(&signer_public); if default_origin.is_local() { - self.immune_users.write().insert(signer_address); + self.immune_users.insert(signer_address); } let origin = self @@ -378,7 +408,7 @@ impl Miner { }) .unwrap_or(default_origin); - if self.malicious_users.read().contains(&signer_address) { + if self.malicious_users.contains(&signer_address) { // FIXME: just to skip, think about another way. return Ok(()) } @@ -389,7 +419,6 @@ impl Miner { if !self.is_allowed_transaction(&tx.action) { cdebug!(MINER, "Rejected transaction {:?}: {:?} is not allowed transaction", hash, tx.action); } - let immune_users = self.immune_users.read(); let tx = tx .verify_basic() .map_err(From::from) @@ -400,8 +429,8 @@ impl Miner { .and_then(|_| CodeChainMachine::verify_transaction_seal(tx, &fake_header)) .map_err(|e| { match e { - Error::Syntax(_) if !origin.is_local() && !immune_users.contains(&signer_address) => { - self.malicious_users.write().insert(signer_address); + Error::Syntax(_) if !origin.is_local() && !self.immune_users.contains(&signer_address) => { + self.malicious_users.insert(signer_address); } _ => {} } @@ -412,8 +441,8 @@ impl Miner { // This check goes here because verify_transaction takes SignedTransaction parameter self.engine.machine().verify_transaction(&tx, &fake_header, client, false).map_err(|e| { match e { - Error::Syntax(_) if !origin.is_local() && !immune_users.contains(&signer_address) => { - self.malicious_users.write().insert(signer_address); + Error::Syntax(_) if !origin.is_local() && !self.immune_users.contains(&signer_address) => { + self.malicious_users.insert(signer_address); } _ => {} } @@ -608,11 +637,10 @@ impl Miner { let tx_total = transactions.len(); let mut invalid_tx_users = HashSet::new(); - let immune_users = self.immune_users.read(); for tx in transactions { let signer_public = tx.signer_public(); let signer_address = public_to_address(&signer_public); - if self.malicious_users.read().contains(&signer_address) { + if self.malicious_users.contains(&signer_address) { invalid_transactions.push(tx.hash()); continue } @@ -646,9 +674,9 @@ impl Miner { .read() .is_local_transaction(hash) .expect("The tx is clearly fetched from the mempool") - && !immune_users.contains(&signer_address) + && !self.immune_users.contains(&signer_address) { - self.malicious_users.write().insert(signer_address); + self.malicious_users.insert(signer_address); } } _ => {} @@ -1205,32 +1233,23 @@ impl MinerService for Miner { } fn get_malicious_users(&self) -> Vec
{ - Vec::from_iter(self.malicious_users.read().iter().map(Clone::clone)) + self.malicious_users.cloned() } fn release_malicious_users(&self, prisoner_vec: Vec
) { - let mut malicious_users = self.malicious_users.write(); - for address in prisoner_vec { - malicious_users.remove(&address); - } + self.malicious_users.remove_users(prisoner_vec.iter()); } fn imprison_malicious_users(&self, prisoner_vec: Vec
) { - let mut malicious_users = self.malicious_users.write(); - for address in prisoner_vec { - malicious_users.insert(address); - } + self.malicious_users.remove_users(prisoner_vec.iter()); } fn get_immune_users(&self) -> Vec
{ - Vec::from_iter(self.immune_users.read().iter().map(Clone::clone)) + self.immune_users.cloned() } fn register_immune_users(&self, immune_user_vec: Vec
) { - let mut immune_users = self.immune_users.write(); - for address in immune_user_vec { - immune_users.insert(address); - } + self.immune_users.remove_users(immune_user_vec.iter()) } } From cd542de72495fd3ef6e1028f72338bca0c1559be Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Thu, 28 May 2020 16:36:52 +0900 Subject: [PATCH 099/105] Fetch consistent state in mempool functions We found that mempool mis-calculates sequence in the TPS test. After fixing the mempool to read consistent state, mempool calculates sequence well. --- core/src/client/test_client.rs | 6 ++++++ core/src/miner/mem_pool.rs | 10 ++++++---- core/src/miner/miner.rs | 20 ++++++++++++-------- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/core/src/client/test_client.rs b/core/src/client/test_client.rs index 8b61a8f443..a33eddedd4 100644 --- a/core/src/client/test_client.rs +++ b/core/src/client/test_client.rs @@ -392,6 +392,9 @@ impl AccountData for TestBlockChainClient { fn seq(&self, address: &Address, id: BlockId) -> Option { match id { BlockId::Latest => Some(self.seqs.read().get(address).cloned().unwrap_or(0)), + BlockId::Hash(hash) if hash == *self.last_hash.read() => { + Some(self.seqs.read().get(address).cloned().unwrap_or(0)) + } _ => None, } } @@ -401,6 +404,9 @@ impl AccountData for TestBlockChainClient { StateOrBlock::Block(BlockId::Latest) | StateOrBlock::State(_) => { Some(self.balances.read().get(address).cloned().unwrap_or(0)) } + StateOrBlock::Block(BlockId::Hash(hash)) if hash == *self.last_hash.read() => { + Some(self.balances.read().get(address).cloned().unwrap_or(0)) + } _ => None, } } diff --git a/core/src/miner/mem_pool.rs b/core/src/miner/mem_pool.rs index 8729639c0e..880171ab11 100644 --- a/core/src/miner/mem_pool.rs +++ b/core/src/miner/mem_pool.rs @@ -33,7 +33,7 @@ use super::mem_pool_types::{ use super::TransactionImportResult; use crate::client::{AccountData, BlockChainTrait}; use crate::transaction::{PendingSignedTransactions, SignedTransaction}; -use crate::Error as CoreError; +use crate::{BlockId, Error as CoreError}; const DEFAULT_POOLING_PERIOD: BlockNumber = 128; @@ -429,12 +429,14 @@ impl MemPool { // Recover MemPool state from db stored data pub fn recover_from_db(&mut self, client: &C) { + let recover_block_hash = client.chain_info().best_block_hash; + let recover_block_id = BlockId::Hash(recover_block_hash); let fetch_account = |p: &Public| -> AccountDetails { let address = public_to_address(p); - let a = client.latest_regular_key_owner(&address).unwrap_or(address); + let a = client.regular_key_owner(&address, recover_block_id.into()).unwrap_or(address); AccountDetails { - seq: client.latest_seq(&a), - balance: client.latest_balance(&a), + seq: client.seq(&a, recover_block_id).expect("Read from best block"), + balance: client.balance(&a, recover_block_id.into()).expect("Read from best block"), } }; let by_hash = backup::recover_to_data(self.db.as_ref()); diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index ccf5b791f9..270deb29f0 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -460,10 +460,10 @@ impl Miner { let fetch_account = |p: &Public| -> AccountDetails { let address = public_to_address(p); - let a = client.latest_regular_key_owner(&address).unwrap_or(address); + let a = client.regular_key_owner(&address, BlockId::Hash(best_header.hash()).into()).unwrap_or(address); AccountDetails { - seq: client.latest_seq(&a), - balance: client.latest_balance(&a), + seq: client.seq(&a, BlockId::Hash(best_header.hash())).expect("Read from best block"), + balance: client.balance(&a, BlockId::Hash(best_header.hash()).into()).expect("Read from best block"), } }; @@ -718,10 +718,12 @@ impl Miner { }; let block = open_block.close(&parent_header, &parent_common_params, term_common_params.as_ref())?; + let best_block_hash = chain.chain_info().best_block_hash; + let block_id = BlockId::Hash(best_block_hash); let fetch_seq = |p: &Public| { let address = public_to_address(p); - let a = chain.latest_regular_key_owner(&address).unwrap_or(address); - chain.latest_seq(&a) + let a = chain.regular_key_owner(&address, block_id.into()).unwrap_or(address); + chain.seq(&a, block_id).expect("Read from best block") }; { @@ -903,13 +905,15 @@ impl MinerService for Miner { // ...and at the end remove the old ones { + let current_block_hash = chain.chain_info().best_block_hash; + let block_id = BlockId::Hash(current_block_hash); let fetch_account = |p: &Public| { let address = public_to_address(p); - let a = chain.latest_regular_key_owner(&address).unwrap_or(address); + let a = chain.regular_key_owner(&address, block_id.into()).unwrap_or(address); AccountDetails { - seq: chain.latest_seq(&a), - balance: chain.latest_balance(&a), + seq: chain.seq(&a, block_id).expect("Read from best block"), + balance: chain.balance(&a, block_id.into()).expect("Read from best block"), } }; let current_block_number = chain.chain_info().best_block_number; From b13bd2ad252b6c06291df0c79bd6f47d9ebad9ff Mon Sep 17 00:00:00 2001 From: Byeongjee Kang Date: Tue, 18 Feb 2020 10:49:04 +0900 Subject: [PATCH 100/105] Rename double vote variable Some DoubleVote type variables should be renamed for consistency. --- core/src/consensus/tendermint/worker.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 5f3aa0ead7..854d5db4c4 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -1430,9 +1430,9 @@ impl Worker { self.votes_received.set(vote_index); } - if let Err(double) = self.votes.collect(message.clone()) { - cerror!(ENGINE, "Double vote found {:?}", double); - self.report_double_vote(&double); + if let Err(double_vote) = self.votes.collect(message.clone()) { + cerror!(ENGINE, "Double vote found {:?}", double_vote); + self.report_double_vote(&double_vote); return Err(EngineError::DoubleVote(sender)) } ctrace!(ENGINE, "Handling a valid {:?} from {}.", message, sender); @@ -1823,9 +1823,9 @@ impl Worker { ); } - if let Err(double) = self.votes.collect(message) { - cerror!(ENGINE, "Double Vote found {:?}", double); - self.report_double_vote(&double); + if let Err(double_vote) = self.votes.collect(message) { + cerror!(ENGINE, "Double Vote found {:?}", double_vote); + self.report_double_vote(&double_vote); return None } } From ef5383307ad64028b93543f67458f94b21072358 Mon Sep 17 00:00:00 2001 From: Byeongjee Kang Date: Tue, 18 Feb 2020 10:55:03 +0900 Subject: [PATCH 101/105] Report double votes found in commit messages --- core/src/consensus/tendermint/worker.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 854d5db4c4..81e8644a18 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -954,6 +954,7 @@ impl Worker { if !self.votes.is_old_or_known(&message) { if let Err(double_vote) = self.votes.collect(message) { cerror!(ENGINE, "Double vote found on_commit_message: {:?}", double_vote); + self.report_double_vote(&double_vote); } } } @@ -2163,6 +2164,7 @@ impl Worker { if !self.votes.is_old_or_known(&vote) { if let Err(double_vote) = self.votes.collect(vote) { cerror!(ENGINE, "Double vote found on_commit_message: {:?}", double_vote); + self.report_double_vote(&double_vote); } } } From 34e4885ffe15f7e03e0bc7b12f8503d23c03982e Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Tue, 18 Aug 2020 15:54:32 +0900 Subject: [PATCH 102/105] Bump the version 2.2.4 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 32267da791..f5826e8306 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -209,7 +209,7 @@ dependencies = [ [[package]] name = "codechain" -version = "2.2.3" +version = "2.2.4" dependencies = [ "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cidr 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 9119a7323c..0a5ba08425 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "codechain" -version = "2.2.3" +version = "2.2.4" license = "AGPL-3.0" authors = ["CodeChain Team "] exclude = [ From 140515b970b399960617ddc9cca44324dc14f489 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Mon, 21 Sep 2020 18:57:11 +0900 Subject: [PATCH 103/105] Add Dockerfile for CentOS --- docker/centos/Dockerfile | 63 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 docker/centos/Dockerfile diff --git a/docker/centos/Dockerfile b/docker/centos/Dockerfile new file mode 100644 index 0000000000..eb17ced7c7 --- /dev/null +++ b/docker/centos/Dockerfile @@ -0,0 +1,63 @@ +FROM centos:7.8.2003 as builder +WORKDIR /build + +# install tools and dependencies +# RUN apt-get update && \ +# apt-get install -y \ +# g++ \ +# build-essential \ +# curl \ +# git \ +# file \ +# binutils \ +# libssl-dev \ +# pkg-config \ +# libudev-dev + +RUN yum update -y && \ + yum install -y \ + git \ + gcc-c++ \ + make \ + curl \ + file \ + openssl-devel + +# install rustup +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + +# rustup directory +ENV PATH /root/.cargo/bin:$PATH + +# show backtraces +ENV RUST_BACKTRACE 1 + +# show tools +RUN rustc -vV && \ +cargo -V && \ +gcc -v &&\ +g++ -v + +# build codechain +ADD . /build/codechain +RUN cd codechain && \ + cargo build --release --verbose && \ + ls /build/codechain/target/release/codechain && \ + strip /build/codechain/target/release/codechain + +RUN file /build/codechain/target/release/codechain + + +FROM centos:7.8.2003 +WORKDIR /app/codechain +RUN yum update -y && \ + yum install -y \ + openssl-libs +COPY --from=builder /build/codechain/target/release/codechain ./target/release/codechain +COPY --from=builder /build/codechain/codechain/config/presets/ ./codechain/config/presets + +# show backtraces +ENV RUST_BACKTRACE 1 + +EXPOSE 3485 8080 +ENTRYPOINT ["target/release/codechain"] From 81199555cec1b41374a626dea8a443eaebbf41b1 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 21 Oct 2020 19:10:21 +0900 Subject: [PATCH 104/105] Create generate txs script --- Cargo.lock | 128 ++++++++++++++++++++++++++++++++++ Cargo.toml | 8 +++ codechain/bin/generate_txs.rs | 90 ++++++++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 codechain/bin/generate_txs.rs diff --git a/Cargo.lock b/Cargo.lock index f5826e8306..b481466eef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -234,6 +234,8 @@ dependencies = [ "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "finally-block 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-client-core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-client-http 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.1.0", "kvdb-rocksdb 0.1.0", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -241,7 +243,9 @@ dependencies = [ "panic_hook 0.1.0", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)", + "rlp 0.2.1", "rpassword 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1115,6 +1119,32 @@ dependencies = [ "vecio 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hyper" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hyper" version = "0.12.19" @@ -1211,6 +1241,44 @@ dependencies = [ "util-error 0.1.0", ] +[[package]] +name = "jsonrpc-client-core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "jsonrpc-client-http" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-client-core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "jsonrpc-core" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "jsonrpc-core" version = "14.0.3" @@ -2152,6 +2220,14 @@ dependencies = [ "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "relay" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "remove_dir_all" version = "0.5.1" @@ -2477,6 +2553,11 @@ name = "slab" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "smallvec" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "smallvec" version = "0.4.5" @@ -2607,6 +2688,11 @@ dependencies = [ name = "table" version = "0.1.0" +[[package]] +name = "take" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "tempdir" version = "0.3.7" @@ -2799,6 +2885,23 @@ dependencies = [ "tokio 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-proto" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-reactor" version = "0.1.1" @@ -2931,6 +3034,11 @@ dependencies = [ "rlp 0.2.1", ] +[[package]] +name = "try-lock" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "try-lock" version = "0.2.2" @@ -3103,6 +3211,16 @@ name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "want" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "want" version = "0.0.6" @@ -3293,6 +3411,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" "checksum hyper 0.10.0-a.0 (git+https://github.com/paritytech/hyper)" = "" +"checksum hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)" = "34a590ca09d341e94cddf8e5af0bbccde205d5fbc2fa3c09dd67c7f85cea59d7" "checksum hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)" = "f1ebec079129e43af5e234ef36ee3d7e6085687d145b7ea653b262d16c6b65f1" "checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" @@ -3301,7 +3420,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" +"checksum jsonrpc-client-core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f29cb249837420fb0cee7fb0fbf1d22679e121b160e71bb5e0d90b9df241c23e" +"checksum jsonrpc-client-http 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e642eb74423b9dfcb4512fda167148746b76f788a823cd712fadf409f31d302" "checksum jsonrpc-core 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)" = "" +"checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c" "checksum jsonrpc-derive 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)" = "" "checksum jsonrpc-http-server 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)" = "" "checksum jsonrpc-ipc-server 14.0.3 (git+https://github.com/paritytech/jsonrpc.git?tag=v14.0.3)" = "" @@ -3399,6 +3521,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3d8c9f33201f46669484bacc312b00e7541bed6aaf296dffe2bb4e0ac6b8ce2a" "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" "checksum regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1ac0f60d675cc6cf13a20ec076568254472551051ad5dd050364d70671bf6b" +"checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum reqwest 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ab52e462d1e15891441aeefadff68bdea005174328ce3da0a314f2ad313ec837" "checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" @@ -3433,6 +3556,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum skeptic 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24ebf8a06f5f8bae61ae5bbc7af7aac4ef6907ae975130faba1199e5fe82256a" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" "checksum smallvec 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f90c5e5fe535e48807ab94fc611d323935f39d4660c52b26b96446a7b33aef10" "checksum smallvec 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "211a489e65e94b103926d2054ae515a1cdb5d515ea0ef414fee23b7e043ce748" "checksum snap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "174451758f7045084ae92070f18e5d8e5c53a716f4172a9c6b17ce03e7b82573" @@ -3449,6 +3573,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum syn 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7bedb3320d0f3035594b0b723c8a28d7d336a3eda3881db79e61d676fb644c" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" +"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "55c1195ef8513f3273d55ff59fe5da6940287a0d7a98331254397f464833675b" "checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83" @@ -3467,6 +3592,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" "checksum tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "7392fe0a70d5ce0c882c4778116c519bd5dbaa8a7c3ae3d04578b3afafdcda21" "checksum tokio-named-pipes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d282d483052288b2308ba5ee795f5673b159c9bdf63c385a05609da782a5eae" +"checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" "checksum tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3cedc8e5af5131dc3423ffa4f877cce78ad25259a9a62de0613735a13ebc64b" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" "checksum tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" @@ -3478,6 +3604,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" "checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9" "checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" +"checksum try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee2aa4715743892880f70885373966c83d73ef1b0838a664ef0c76fffd35e7c2" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" "checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" @@ -3502,6 +3629,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum vergen 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9a16834fc61e1492c07dae49b6c14b55f8b1d43a5f5f9e9a2ecc063f47b9f93c" "checksum version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a05d9d966753fa4b5c8db73fcab5eed4549cfe0e1e4e66911e5564a0085c35d1" "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" diff --git a/Cargo.toml b/Cargo.toml index 0a5ba08425..35691ff32e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,8 @@ exclude = [ [dependencies] app_dirs = "^1.2.1" +rlp = { path = "./util/rlp" } +rustc-hex = "1.0" clap = { version = "2", features = ["yaml"] } codechain-core = { path = "core" } codechain-crypto = { git = "https://github.com/CodeChain-io/rust-codechain-crypto.git", version = "0.1" } @@ -48,6 +50,8 @@ rustc-serialize = "0.3" serde = "1.0" serde_derive = "1.0" serde_json = "1.0" +jsonrpc-client-core = "0.5.0" +jsonrpc-client-http = "0.5.0" tokio-core = "0.1.17" toml = "0.4" cidr = "0.0.4" @@ -59,6 +63,10 @@ vergen = "2" path = "codechain/main.rs" name = "codechain" +[[bin]] +path = "codechain/bin/generate_txs.rs" +name = "generate-tx" + [profile.release] lto = true diff --git a/codechain/bin/generate_txs.rs b/codechain/bin/generate_txs.rs new file mode 100644 index 0000000000..3cf060929a --- /dev/null +++ b/codechain/bin/generate_txs.rs @@ -0,0 +1,90 @@ +extern crate codechain_core as ccore; +extern crate codechain_crypto as ccrypto; +extern crate codechain_key as ckey; +extern crate codechain_types as ctypes; +extern crate rlp; +extern crate rustc_hex; +#[macro_use] +extern crate jsonrpc_client_core; +extern crate clap; +extern crate jsonrpc_client_http; + +use ccore::SignedTransaction; +use ccrypto::blake256; +use ckey::{sign, KeyPair, NetworkId, PlatformAddress, Private}; +use clap::clap_app; +use ctypes::transaction::{Action, Transaction}; +use jsonrpc_client_http::HttpTransport; +use rustc_hex::ToHex; + +jsonrpc_client!(pub struct RpcClient { + pub fn chain_getSeq(&mut self, address: PlatformAddress) -> RpcRequest; +}); + +fn main() { + let matches = clap_app!(txGenerator => + (version: "1.0") + (about: "Generate store transactions") + (@arg RPC_URL: -u --rpcurl +takes_value "CodeChain RPC address like http://127.0.0.1:7070") + (@arg SECRET: -s --secret +takes_value "Secret key of sender") + (@arg CONTENT: -c --content +takes_value "Content of store tx") + (@arg NETWORK_ID: --networkid +takes_value "network id") + (@arg TX_COUNT: -n --txcount +takes_value "transaction count") + ) + .get_matches(); + + let rpc_url = matches.value_of("RPC_URL").unwrap_or("http://127.0.0.1:7070/").to_string(); + let secret: Private = { + let secret_string = matches + .value_of("SECRET") + .unwrap_or("eeec7e5fc8af6fcfbd728de615d8a79b1b0bbcaabd8b9bae0a842c6f708e2c0c") + .to_string(); + secret_string.parse().expect("parse private key") + }; + let content = matches.value_of("CONTENT").unwrap_or("dummy_content").to_string(); + let network_id: NetworkId = { + let network_id_str = matches.value_of("NETWORK_ID").unwrap_or("bw"); + network_id_str.parse().expect("parse network id") + }; + let tx_count: u64 = { + let tx_count_str = matches.value_of("TX_COUNT").unwrap_or("10000"); + tx_count_str.parse().expect("parse tx count") + }; + + let keypair = KeyPair::from_private(secret).expect("create private key"); + let address = keypair.address(); + let platform_address = PlatformAddress::new_v1(network_id, address); + eprintln!("platform address {}", platform_address); + + let transport = HttpTransport::new().standalone().unwrap(); + let transport_handle = transport.handle(&rpc_url).unwrap(); + let mut client = RpcClient::new(transport_handle); + + let seq = client.chain_getSeq(platform_address).call().expect("getseq"); + eprintln!("seq {}", seq); + + let message = blake256(&rlp::encode(&content)); + let signature = sign(keypair.private(), &message).expect("sign"); + + let mut txs = Vec::new(); + for i in 0..tx_count { + let tx = Transaction { + seq: seq + i, + fee: 0, + network_id, + action: Action::Store { + content: content.clone(), + certifier: keypair.address(), + signature, + }, + }; + let signed_tx = SignedTransaction::new_with_sign(tx, keypair.private()); + let serialized = rlp::encode(&signed_tx); + let hex_tx = serialized.to_hex(); + txs.push(hex_tx); + } + + let serialized_txs = serde_json::to_string(&txs).expect("json serialize"); + println!("{}", serialized_txs); + eprintln!("{} transaction created", tx_count); +} From c99ed83a27601af4f015ee2fc02b284d4a13a8f0 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Wed, 21 Oct 2020 19:12:16 +0900 Subject: [PATCH 105/105] Create a script that sends store transactions --- tps-busan/.gitignore | 1 + tps-busan/package.json | 10 + tps-busan/src/generate-txs.js | 41 ++ tps-busan/src/index.js | 35 ++ tps-busan/src/load-and-send.js | 41 ++ tps-busan/yarn.lock | 688 +++++++++++++++++++++++++++++++++ 6 files changed, 816 insertions(+) create mode 100644 tps-busan/.gitignore create mode 100644 tps-busan/package.json create mode 100644 tps-busan/src/generate-txs.js create mode 100644 tps-busan/src/index.js create mode 100644 tps-busan/src/load-and-send.js create mode 100644 tps-busan/yarn.lock diff --git a/tps-busan/.gitignore b/tps-busan/.gitignore new file mode 100644 index 0000000000..3c3629e647 --- /dev/null +++ b/tps-busan/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/tps-busan/package.json b/tps-busan/package.json new file mode 100644 index 0000000000..82006691fb --- /dev/null +++ b/tps-busan/package.json @@ -0,0 +1,10 @@ +{ + "name": "tps-busan", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "dependencies": { + "codechain-primitives": "^1.0.4", + "codechain-sdk": "^2.0.1" + } +} diff --git a/tps-busan/src/generate-txs.js b/tps-busan/src/generate-txs.js new file mode 100644 index 0000000000..5eae2ad99d --- /dev/null +++ b/tps-busan/src/generate-txs.js @@ -0,0 +1,41 @@ +const SDK = require("codechain-sdk"); +const { generatePrivateKey } = require("codechain-primitives"); +const sdk = new SDK({ server: "http://localhost:7070/", networkId: "bw" }); +const txSender = "bwcqxcr6rjs8545ywp5pgw98qcg2aruxftg7yaaywmr"; +const fs = require("fs"); + +async function main() { + const data = "hi"; + const content = JSON.stringify(data); + const randomKey = generatePrivateKey(); + + const seq = await sdk.rpc.chain.getSeq(txSender); + + const txs = []; + + const n = 1000; + for (let i = 0; i < n; i += 1) { + console.time("generate"); + const tx = await sdk.core.createStoreTransaction({ + content, + secret: randomKey, + }); + console.timeLog("generate", "createTx"); + + const signedTx = await sdk.key.signTransaction(tx, { + account: txSender, + fee: 0, + seq: seq + i, + }); + const hexTx = signedTx.rlpBytes().toString("hex"); + txs.push(hexTx); + console.timeLog("generate", "sign"); + console.timeEnd("generate"); + } + + fs.writeFileSync("./txs", JSON.stringify(txs)); + + cnosole.log(`Generated ${n} txs`); +} + +main().catch(console.error); diff --git a/tps-busan/src/index.js b/tps-busan/src/index.js new file mode 100644 index 0000000000..c7172373dc --- /dev/null +++ b/tps-busan/src/index.js @@ -0,0 +1,35 @@ +const SDK = require("codechain-sdk"); +const { generatePrivateKey } = require("codechain-primitives"); +const sdk = new SDK({ server: "http://localhost:7070/", networkId: "bw" }); +const txSender = "bwcqxcr6rjs8545ywp5pgw98qcg2aruxftg7yaaywmr"; + +async function main() { + const data = "hi"; + const content = JSON.stringify(data); + const randomKey = generatePrivateKey(); + + const seq = await sdk.rpc.chain.getSeq(txSender); + + for (let i = 0; i < 100; i += 1) { + console.time("send"); + const tx = await sdk.core.createStoreTransaction({ + content, + secret: randomKey, + }); + console.timeLog("send", "createTx"); + + const signedTx = await sdk.key.signTransaction(tx, { + account: txSender, + fee: 0, + seq: seq + i, + }); + console.timeLog("send", "sign"); + await sdk.rpc.chain.sendSignedTransaction(signedTx); + console.timeLog("send", "send"); + console.timeEnd("send"); + } + + console.log("Sent 100 transactions"); +} + +main().catch(console.error); diff --git a/tps-busan/src/load-and-send.js b/tps-busan/src/load-and-send.js new file mode 100644 index 0000000000..8a1ee82507 --- /dev/null +++ b/tps-busan/src/load-and-send.js @@ -0,0 +1,41 @@ +const SDK = require("codechain-sdk"); +const { generatePrivateKey } = require("codechain-primitives"); +const sdk = new SDK({ server: "http://localhost:7070/", networkId: "bw" }); +const txSender = "bwcqxcr6rjs8545ywp5pgw98qcg2aruxftg7yaaywmr"; +const fs = require("fs"); + +const consoleKey = "load and send tx"; +async function main() { + let txs = JSON.parse(fs.readFileSync("./txs.json")); + + console.time(consoleKey); + + let lastHash = ""; + for (let i = 0; i < txs.length; i += 1) { + lastHash = await sdk.rpc.sendRpcRequest("mempool_sendSignedTransaction", [ + "0x" + txs[i], + ]); + } + + console.timeLog(consoleKey, `Sent ${txs.length} txs`); + + while (true) { + const contain = await sdk.rpc.chain.containsTransaction(lastHash); + if (contain) { + break; + } + await sleep(100); + } + + console.timeLog(consoleKey, "All txs mined"); + + console.timeEnd(consoleKey); +} + +main().catch(console.error); + +async function sleep(millis) { + return new Promise((resolve) => { + setTimeout(resolve, millis); + }); +} diff --git a/tps-busan/yarn.lock b/tps-busan/yarn.lock new file mode 100644 index 0000000000..d69f7b5d73 --- /dev/null +++ b/tps-busan/yarn.lock @@ -0,0 +1,688 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/node@^10.3.5": + version "10.17.40" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.40.tgz#8a50e47daff15fd4a89dc56f5221b3729e506be6" + integrity sha512-3hZT2z2/531A5pc8hYhn1gU5Qb1SIRSgMLQ6zuHA5xtt16lWAxUGprtr8lJuc9zNJMXEIIBWfSnzqBP/4mglpA== + +JSONStream@^1.3.1: + version "1.3.5" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + +ajv@^6.12.3: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.10.1" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.1.tgz#e1e82e4f3e999e2cfd61b161280d16a111f86428" + integrity sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA== + +base-x@^3.0.2: + version "3.0.8" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d" + integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA== + dependencies: + safe-buffer "^5.0.1" + +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +bech32@=1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.3.tgz#bd47a8986bbb3eec34a56a097a84b8d3e9a2dfcd" + integrity sha512-yuVFUvrNcoJi0sv5phmqc6P+Fl1HjRDRNOOkHY2X/3LBy2bIGNSFx4fZ95HMaXHupuS7cZR15AsvtmCIF4UEyg== + +bignumber.js@^7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" + integrity sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ== + +bitcore-lib@^8.22.2: + version "8.22.2" + resolved "https://registry.yarnpkg.com/bitcore-lib/-/bitcore-lib-8.22.2.tgz#d3aaafac117e6cfff1ed53af7c6fdd2a0d005431" + integrity sha512-atl/RN7x2R/JQMaIgUzX0EQZ+I/d7fTaOoS2/5k+H5POGc2vygWZ9MWpGJi3T9Yb5jM/cT5aFsrDq8s8l6lqgQ== + dependencies: + bech32 "=1.1.3" + bn.js "=4.11.8" + bs58 "^4.0.1" + buffer-compare "=1.1.1" + elliptic "^6.5.3" + inherits "=2.0.1" + lodash "^4.17.20" + +bitcore-mnemonic@^8.6.0: + version "8.22.2" + resolved "https://registry.yarnpkg.com/bitcore-mnemonic/-/bitcore-mnemonic-8.22.2.tgz#5720ca71a73c92fc8169c6567802c5661823b9ec" + integrity sha512-K+xgOfTXGsIe+xk0fgg+qk4qSDDSaiGA41ahLhlQVPxwKkSlK8DEokCilkseoEUPalmGweSB0pOM9eT9PYQNew== + dependencies: + bitcore-lib "^8.22.2" + unorm "^1.4.1" + +blakejs@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.0.tgz#69df92ef953aa88ca51a32df6ab1c54a155fc7a5" + integrity sha1-ad+S75U6qIylGjLfarHFShVfx6U= + +bluebird@^3.5.0: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@=4.11.8: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +bn.js@^4.11.1, bn.js@^4.11.8, bn.js@^4.4.0: + version "4.11.9" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" + integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +bs58@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= + dependencies: + base-x "^3.0.2" + +buffer-compare@=1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-compare/-/buffer-compare-1.1.1.tgz#5be7be853af89198d1f4ddc090d1d66a48aef596" + integrity sha1-W+e+hTr4kZjR9N3AkNHWakiu9ZY= + +buffer@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.1.0.tgz#c913e43678c7cb7c8bd16afbcddb6c5505e8f9fe" + integrity sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +buffer@^5.2.1: + version "5.6.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" + integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +codechain-keystore@^0.6.0: + version "0.6.3" + resolved "https://registry.yarnpkg.com/codechain-keystore/-/codechain-keystore-0.6.3.tgz#9042169dd03c9b67ff8e73253a009515dd1e58a5" + integrity sha512-bSUhuv9UIXoAKwSWhnylIhnU+BOypd7aqL0E8rPumS5qmsqUZgwMoKCfQBasCVpH+Hm+4fR0CSfVK/J7s/Hvfw== + dependencies: + bitcore-mnemonic "^8.6.0" + codechain-primitives "^1.0.0" + config "^2.0.1" + lodash "^4.17.10" + lowdb "^1.0.0" + lowdb-session-storage-adapter "^1.0.0" + uuid "^3.3.2" + +codechain-primitives@^1.0.0, codechain-primitives@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/codechain-primitives/-/codechain-primitives-1.0.4.tgz#26918fc5229c3fa0cc8c2d6ecda1ad3740292a4a" + integrity sha512-BOA+NL/iHuzp05DC8vLxC2vIMvIHPzREH4sgwcrQKKsnvTMf5frVdBQKBWl6Me2A4M7aa6T+wDe6pAD3WEoJ3w== + dependencies: + bignumber.js "^7.2.1" + blakejs "^1.1.0" + bn.js "^4.11.8" + buffer "^5.2.1" + crypto-js "^3.1.9-1" + elliptic "^6.4.1" + hmac-drbg "^1.0.1" + lodash "^4.17.14" + node-forge "^0.7.6" + rlp "^2.1.0" + +codechain-sdk@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/codechain-sdk/-/codechain-sdk-2.0.1.tgz#c557d95be870d7b0f97617dbfabccabe67e297d1" + integrity sha512-pT2GJYvHd5ZwK6r9iWamtGXt18EBx/V8W7SxoOpD9Irg4y3g3Y7RzhEPTbjdju4ezBDARXcobwGC35qLbuYeXA== + dependencies: + buffer "5.1.0" + codechain-keystore "^0.6.0" + codechain-primitives "^1.0.0" + jayson "^2.0.6" + lodash "^4.17.14" + node-fetch "^2.1.2" + request "^2.88.0" + request-promise "^4.2.2" + rlp "^2.0.0" + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.12.2: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +config@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/config/-/config-2.0.2.tgz#b81c8f4e05203e1da7752864c19a11604ca923d7" + integrity sha512-duIbkKb0gls0bOtGwd1vaD4236MwepQlZcrMheOGrn3/9Px7oYFh8G4LB3ylGOlPr5wGoJRm8Grb2RihJZxuHQ== + dependencies: + json5 "^1.0.1" + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +crypto-js@^3.1.9-1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b" + integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q== + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +elliptic@^6.4.1, elliptic@^6.5.3: + version "6.5.3" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" + integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +eyes@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A= + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +graceful-fs@^4.1.3: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hmac-drbg@^1.0.0, hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +inherits@=2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +inherits@^2.0.1, inherits@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-promise@^2.1.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" + integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +jayson@^2.0.6: + version "2.1.2" + resolved "https://registry.yarnpkg.com/jayson/-/jayson-2.1.2.tgz#3612f578529b5cc84301f098f29cd1612119e53d" + integrity sha512-2GejcQnEV35KYTXoBvzALIDdO/1oyEIoJHBnaJFhJhcurv0x2JqUXQW6xlDUhcNOpN9t+d2w+JGA6vOphb+5mg== + dependencies: + "@types/node" "^10.3.5" + JSONStream "^1.3.1" + commander "^2.12.2" + es6-promisify "^5.0.0" + eyes "^0.1.8" + json-stringify-safe "^5.0.1" + lodash "^4.17.11" + uuid "^3.2.1" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +lodash@4, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.20: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + +lowdb-session-storage-adapter@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowdb-session-storage-adapter/-/lowdb-session-storage-adapter-1.0.0.tgz#6f5e563adbf482ac39c6937f55db6757eb01c0f3" + integrity sha512-mcS4LC3pJ4Vtp3iebm6gZ5069lPq+dEk2RxQ8+N9Y23bEjGjN+WFbjxYIoEpTNVmihwW6vGuRq/MH5zIyruQYA== + dependencies: + lowdb "^1.0.0" + +lowdb@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowdb/-/lowdb-1.0.0.tgz#5243be6b22786ccce30e50c9a33eac36b20c8064" + integrity sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ== + dependencies: + graceful-fs "^4.1.3" + is-promise "^2.1.0" + lodash "4" + pify "^3.0.0" + steno "^0.4.1" + +mime-db@1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== + +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + dependencies: + mime-db "1.44.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimist@^1.2.0: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +node-fetch@^2.1.2: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + +node-forge@^0.7.6: + version "0.7.6" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.6.tgz#fdf3b418aee1f94f0ef642cd63486c77ca9724ac" + integrity sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw== + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +request-promise-core@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" + integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== + dependencies: + lodash "^4.17.19" + +request-promise@^4.2.2: + version "4.2.6" + resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-4.2.6.tgz#7e7e5b9578630e6f598e3813c0f8eb342a27f0a2" + integrity sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ== + dependencies: + bluebird "^3.5.0" + request-promise-core "1.1.4" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + +request@^2.88.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +rlp@^2.0.0, rlp@^2.1.0: + version "2.2.6" + resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.6.tgz#c80ba6266ac7a483ef1e69e8e2f056656de2fb2c" + integrity sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg== + dependencies: + bn.js "^4.11.1" + +safe-buffer@^5.0.1, safe-buffer@^5.1.2: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +stealthy-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + +steno@^0.4.1: + version "0.4.4" + resolved "https://registry.yarnpkg.com/steno/-/steno-0.4.4.tgz#071105bdfc286e6615c0403c27e9d7b5dcb855cb" + integrity sha1-BxEFvfwobmYVwEA8J+nXtdy4Vcs= + dependencies: + graceful-fs "^4.1.3" + +"through@>=2.2.7 <3": + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +tough-cookie@^2.3.3, tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +unorm@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.6.0.tgz#029b289661fba714f1a9af439eb51d9b16c205af" + integrity sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA== + +uri-js@^4.2.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" + integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== + dependencies: + punycode "^2.1.0" + +uuid@^3.2.1, uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0"