refactor: use sort_unstable instead of sort, more efficient with_* methods for TransactionBody (#2564)

This commit is contained in:
Jeremy Rubin 2019-02-14 03:01:54 -08:00 committed by Antioch Peverell
parent 41ed10940d
commit d4540f32a3
4 changed files with 35 additions and 43 deletions

View file

@ -62,9 +62,9 @@ impl CompactBlockBody {
/// Sort everything. /// Sort everything.
fn sort(&mut self) { fn sort(&mut self) {
self.out_full.sort(); self.out_full.sort_unstable();
self.kern_full.sort(); self.kern_full.sort_unstable();
self.kern_ids.sort(); self.kern_ids.sort_unstable();
} }
/// "Lightweight" validation. /// "Lightweight" validation.

View file

@ -487,9 +487,9 @@ impl TransactionBody {
/// Sort the inputs|outputs|kernels. /// Sort the inputs|outputs|kernels.
pub fn sort(&mut self) { pub fn sort(&mut self) {
self.inputs.sort(); self.inputs.sort_unstable();
self.outputs.sort(); self.outputs.sort_unstable();
self.kernels.sort(); self.kernels.sort_unstable();
} }
/// Creates a new transaction body initialized with /// Creates a new transaction body initialized with
@ -501,7 +501,7 @@ impl TransactionBody {
kernels: Vec<TxKernel>, kernels: Vec<TxKernel>,
verify_sorted: bool, verify_sorted: bool,
) -> Result<TransactionBody, Error> { ) -> Result<TransactionBody, Error> {
let body = TransactionBody { let mut body = TransactionBody {
inputs, inputs,
outputs, outputs,
kernels, kernels,
@ -511,52 +511,44 @@ impl TransactionBody {
// If we are verifying sort order then verify and // If we are verifying sort order then verify and
// return an error if not sorted lexicographically. // return an error if not sorted lexicographically.
body.verify_sorted()?; body.verify_sorted()?;
Ok(body)
} else { } else {
// If we are not verifying sort order then sort in place and return. // If we are not verifying sort order then sort in place and return.
let mut body = body;
body.sort(); body.sort();
Ok(body)
} }
Ok(body)
} }
/// Builds a new body with the provided inputs added. Existing /// Builds a new body with the provided inputs added. Existing
/// inputs, if any, are kept intact. /// inputs, if any, are kept intact.
/// Sort order is maintained. /// Sort order is maintained.
pub fn with_input(self, input: Input) -> TransactionBody { pub fn with_input(mut self, input: Input) -> TransactionBody {
let mut new_ins = self.inputs; self.inputs
new_ins.push(input); .binary_search(&input)
new_ins.sort(); .err()
TransactionBody { .map(|e| self.inputs.insert(e, input));
inputs: new_ins, self
..self
}
} }
/// Builds a new TransactionBody with the provided output added. Existing /// Builds a new TransactionBody with the provided output added. Existing
/// outputs, if any, are kept intact. /// outputs, if any, are kept intact.
/// Sort order is maintained. /// Sort order is maintained.
pub fn with_output(self, output: Output) -> TransactionBody { pub fn with_output(mut self, output: Output) -> TransactionBody {
let mut new_outs = self.outputs; self.outputs
new_outs.push(output); .binary_search(&output)
new_outs.sort(); .err()
TransactionBody { .map(|e| self.outputs.insert(e, output));
outputs: new_outs, self
..self
}
} }
/// Builds a new TransactionBody with the provided kernel added. Existing /// Builds a new TransactionBody with the provided kernel added. Existing
/// kernels, if any, are kept intact. /// kernels, if any, are kept intact.
/// Sort order is maintained. /// Sort order is maintained.
pub fn with_kernel(self, kernel: TxKernel) -> TransactionBody { pub fn with_kernel(mut self, kernel: TxKernel) -> TransactionBody {
let mut new_kerns = self.kernels; self.kernels
new_kerns.push(kernel); .binary_search(&kernel)
new_kerns.sort(); .err()
TransactionBody { .map(|e| self.kernels.insert(e, kernel));
kernels: new_kerns, self
..self
}
} }
/// Total fee for a TransactionBody is the sum of fees of all kernels. /// Total fee for a TransactionBody is the sum of fees of all kernels.
@ -987,8 +979,8 @@ pub fn cut_through(inputs: &mut Vec<Input>, outputs: &mut Vec<Output>) -> Result
// filter and sort // filter and sort
inputs.retain(|inp| !to_cut_through.contains(&inp.commitment())); inputs.retain(|inp| !to_cut_through.contains(&inp.commitment()));
outputs.retain(|out| !to_cut_through.contains(&out.commitment())); outputs.retain(|out| !to_cut_through.contains(&out.commitment()));
inputs.sort(); inputs.sort_unstable();
outputs.sort(); outputs.sort_unstable();
Ok(()) Ok(())
} }
@ -1029,7 +1021,7 @@ pub fn aggregate(mut txs: Vec<Transaction>) -> Result<Transaction, Error> {
cut_through(&mut inputs, &mut outputs)?; cut_through(&mut inputs, &mut outputs)?;
// Now sort kernels. // Now sort kernels.
kernels.sort(); kernels.sort_unstable();
// now sum the kernel_offsets up to give us an aggregate offset for the // now sum the kernel_offsets up to give us an aggregate offset for the
// transaction // transaction
@ -1100,9 +1092,9 @@ pub fn deaggregate(mk_tx: Transaction, txs: Vec<Transaction>) -> Result<Transact
}; };
// Sorting them lexicographically // Sorting them lexicographically
inputs.sort(); inputs.sort_unstable();
outputs.sort(); outputs.sort_unstable();
kernels.sort(); kernels.sort_unstable();
// Build a new tx from the above data. // Build a new tx from the above data.
let tx = Transaction::new(inputs, outputs, kernels).with_offset(total_kernel_offset); let tx = Transaction::new(inputs, outputs, kernels).with_offset(total_kernel_offset);

View file

@ -265,7 +265,7 @@ where
self.graph.solutions.pop(); self.graph.solutions.pop();
for s in &mut self.graph.solutions { for s in &mut self.graph.solutions {
s.nonces = map_vec!(s.nonces, |n| val[*n as usize]); s.nonces = map_vec!(s.nonces, |n| val[*n as usize]);
s.nonces.sort(); s.nonces.sort_unstable();
} }
for s in &self.graph.solutions { for s in &self.graph.solutions {
self.verify_impl(&s)?; self.verify_impl(&s)?;

View file

@ -342,7 +342,7 @@ impl Eq for Proof {}
impl Proof { impl Proof {
/// Builds a proof with provided nonces at default edge_bits /// Builds a proof with provided nonces at default edge_bits
pub fn new(mut in_nonces: Vec<u64>) -> Proof { pub fn new(mut in_nonces: Vec<u64>) -> Proof {
in_nonces.sort(); in_nonces.sort_unstable();
Proof { Proof {
edge_bits: global::min_edge_bits(), edge_bits: global::min_edge_bits(),
nonces: in_nonces, nonces: in_nonces,
@ -369,7 +369,7 @@ impl Proof {
.map(|()| (rng.gen::<u32>() & nonce_mask) as u64) .map(|()| (rng.gen::<u32>() & nonce_mask) as u64)
.take(proof_size) .take(proof_size)
.collect(); .collect();
v.sort(); v.sort_unstable();
Proof { Proof {
edge_bits: global::min_edge_bits(), edge_bits: global::min_edge_bits(),
nonces: v, nonces: v,