mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 03:21:08 +03:00
Order block elements when block is built
This commit is contained in:
parent
5b462ee2fc
commit
dbaba8aed5
2 changed files with 45 additions and 11 deletions
|
@ -293,7 +293,7 @@ impl Block {
|
|||
// build vectors with all inputs and all outputs, ordering them by hash
|
||||
// needs to be a fold so we don't end up with a vector of vectors and we
|
||||
// want to fully own the refs (not just a pointer like flat_map).
|
||||
let inputs = txs.iter().fold(vec![], |mut acc, ref tx| {
|
||||
let mut inputs = txs.iter().fold(vec![], |mut acc, ref tx| {
|
||||
let mut inputs = tx.inputs.clone();
|
||||
acc.append(&mut inputs);
|
||||
acc
|
||||
|
@ -305,6 +305,10 @@ impl Block {
|
|||
});
|
||||
outputs.push(reward_out);
|
||||
|
||||
inputs.sort();
|
||||
outputs.sort();
|
||||
kernels.sort();
|
||||
|
||||
// calculate the overall Merkle tree and fees
|
||||
|
||||
Ok(
|
||||
|
|
|
@ -16,11 +16,13 @@
|
|||
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
use blake2::blake2b::blake2b;
|
||||
use util::secp::{self, Secp256k1, Message, Signature};
|
||||
use util::secp::pedersen::{RangeProof, Commitment};
|
||||
use util::secp::{self, Message, Secp256k1, Signature};
|
||||
use util::secp::pedersen::{Commitment, RangeProof};
|
||||
use std::cmp::Ordering;
|
||||
use std::ops;
|
||||
|
||||
use core::Committed;
|
||||
use core::hash::Hashed;
|
||||
use core::pmmr::Summable;
|
||||
use keychain::{Identifier, Keychain};
|
||||
use ser::{self, read_and_verify_sorted, Readable, Reader, Writeable, WriteableSorted, Writer};
|
||||
|
@ -39,6 +41,29 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
// don't seem to be able to define an Ord implementation for Hash due to
|
||||
// Ord being defined on all pointers, resorting to a macro instead
|
||||
macro_rules! hashable_ord {
|
||||
($hashable: ident) => {
|
||||
impl Ord for $hashable {
|
||||
fn cmp(&self, other: &$hashable) -> Ordering {
|
||||
self.hash().cmp(&other.hash())
|
||||
}
|
||||
}
|
||||
impl PartialOrd for $hashable {
|
||||
fn partial_cmp(&self, other: &$hashable) -> Option<Ordering> {
|
||||
Some(self.hash().cmp(&other.hash()))
|
||||
}
|
||||
}
|
||||
impl PartialEq for $hashable {
|
||||
fn eq(&self, other: &$hashable) -> bool {
|
||||
self.hash() == other.hash()
|
||||
}
|
||||
}
|
||||
impl Eq for $hashable {}
|
||||
}
|
||||
}
|
||||
|
||||
/// Errors thrown by Block validation
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Error {
|
||||
|
@ -68,7 +93,7 @@ pub fn kernel_sig_msg(fee: u64, lock_height: u64) -> [u8; 32] {
|
|||
/// amount to zero.
|
||||
/// The signature signs the fee and the lock_height, which are retained for
|
||||
/// signature validation.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TxKernel {
|
||||
/// Options for a kernel's structure or use
|
||||
pub features: KernelFeatures,
|
||||
|
@ -86,6 +111,8 @@ pub struct TxKernel {
|
|||
pub excess_sig: Vec<u8>,
|
||||
}
|
||||
|
||||
hashable_ord!(TxKernel);
|
||||
|
||||
impl Writeable for TxKernel {
|
||||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
|
||||
ser_multiwrite!(
|
||||
|
@ -169,7 +196,6 @@ impl Writeable for Transaction {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// Implementation of Readable for a transaction, defines how to read a full
|
||||
/// transaction from a binary stream.
|
||||
impl Readable for Transaction {
|
||||
|
@ -327,9 +353,11 @@ impl Transaction {
|
|||
|
||||
/// A transaction input, mostly a reference to an output being spent by the
|
||||
/// transaction.
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Input(pub Commitment);
|
||||
|
||||
hashable_ord!(Input);
|
||||
|
||||
/// Implementation of Writeable for a transaction Input, defines how to write
|
||||
/// an Input as binary.
|
||||
impl Writeable for Input {
|
||||
|
@ -423,7 +451,7 @@ impl SwitchCommitHash {
|
|||
/// The hash of an output only covers its features, lock_height, commitment,
|
||||
/// and switch commitment. The range proof is expected to have its own hash
|
||||
/// and is stored and committed to separately.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
|
||||
pub struct Output {
|
||||
/// Options for an output's structure or use
|
||||
pub features: OutputFeatures,
|
||||
|
@ -435,6 +463,8 @@ pub struct Output {
|
|||
pub proof: RangeProof,
|
||||
}
|
||||
|
||||
hashable_ord!(Output);
|
||||
|
||||
/// Implementation of Writeable for a transaction Output, defines how to write
|
||||
/// an Output as binary.
|
||||
impl Writeable for Output {
|
||||
|
@ -672,8 +702,8 @@ mod test {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn commit_consistency(){
|
||||
let keychain = Keychain::from_seed(&[0;32]).unwrap();
|
||||
fn commit_consistency() {
|
||||
let keychain = Keychain::from_seed(&[0; 32]).unwrap();
|
||||
let key_id = keychain.derive_key_id(1).unwrap();
|
||||
|
||||
let commit = keychain.commit(1003, &key_id).unwrap();
|
||||
|
@ -687,7 +717,7 @@ mod test {
|
|||
println!("Switch commit 2: {:?}", switch_commit_2);
|
||||
println!("commit2 : {:?}", commit_2);
|
||||
|
||||
assert!(commit==commit_2);
|
||||
assert!(switch_commit==switch_commit_2);
|
||||
assert!(commit == commit_2);
|
||||
assert!(switch_commit == switch_commit_2);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue