Skip to content

Commit ed13c22

Browse files
committedSep 21, 2021
refactor: implement breaking consensus for block v2
Block v1 (compatible with weatherwax at all heights): - Kernel ordering using every kernel field - Input MR commits to empty serialization of bitmap Block v2 (Igor, breaking change) - Kernel ordering (#3193) - Input MR uses input hashes only without extaneous empty bitmap bytes (#3195)
1 parent 885a39c commit ed13c22

File tree

15 files changed

+202
-121
lines changed

15 files changed

+202
-121
lines changed
 

‎base_layer/core/src/blocks/block.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ impl Block {
8181
Self { header, body }
8282
}
8383

84+
pub fn version(&self) -> u16 {
85+
self.header.version
86+
}
87+
8488
/// This function will calculate the total fees contained in a block
8589
pub fn calculate_fees(&self) -> MicroTari {
8690
self.body.kernels().iter().fold(0.into(), |sum, x| sum + x.fee)
@@ -239,7 +243,7 @@ impl BlockBuilder {
239243
header: self.header,
240244
body: AggregateBody::new(self.inputs, self.outputs, self.kernels),
241245
};
242-
block.body.sort();
246+
block.body.sort(block.header.version);
243247
block
244248
}
245249
}

‎base_layer/core/src/blocks/genesis_block.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ pub fn get_stibbons_genesis_block_raw() -> Block {
159159
excess_sig: sig,
160160
}],
161161
);
162-
body.sort();
162+
body.sort(1);
163163
Block {
164164
header: BlockHeader {
165165
version: 0,
@@ -226,7 +226,7 @@ pub fn get_weatherwax_genesis_block_raw() -> Block {
226226
excess_sig: sig,
227227
}],
228228
);
229-
body.sort();
229+
body.sort(1);
230230
// set genesis timestamp
231231
let genesis = DateTime::parse_from_rfc2822("07 Jul 2021 06:00:00 +0200").unwrap();
232232
let timestamp = genesis.timestamp() as u64;
@@ -336,7 +336,7 @@ pub fn get_ridcully_genesis_block_raw() -> Block {
336336
excess_sig: sig,
337337
}],
338338
);
339-
body.sort();
339+
body.sort(1);
340340
Block {
341341
header: BlockHeader {
342342
version: 0,
@@ -419,7 +419,7 @@ pub fn get_igor_genesis_block_raw() -> Block {
419419
excess_sig: sig,
420420
}],
421421
);
422-
body.sort();
422+
body.sort(2);
423423
// set genesis timestamp
424424
let genesis = DateTime::parse_from_rfc2822("27 Aug 2021 06:00:00 +0200").unwrap();
425425
let timestamp = genesis.timestamp() as u64;

‎base_layer/core/src/chain_storage/blockchain_database.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ where B: BlockchainBackend
228228
/// Returns a reference to the consensus cosntants at the current height
229229
pub fn consensus_constants(&self) -> Result<&ConsensusConstants, ChainStorageError> {
230230
let height = self.get_height()?;
231-
232231
Ok(self.consensus_manager.consensus_constants(height))
233232
}
234233

@@ -648,7 +647,7 @@ where B: BlockchainBackend
648647

649648
pub fn prepare_new_block(&self, template: NewBlockTemplate) -> Result<Block, ChainStorageError> {
650649
let NewBlockTemplate { header, mut body, .. } = template;
651-
body.sort();
650+
body.sort(header.version);
652651
let mut header = BlockHeader::from(header);
653652
// If someone advanced the median timestamp such that the local time is less than the median timestamp, we need
654653
// to increase the timestamp to be greater than the median timestamp
@@ -1051,10 +1050,17 @@ pub fn calculate_mmr_roots<T: BlockchainBackend>(db: &T, block: &Block) -> Resul
10511050

10521051
output_mmr.compress();
10531052

1053+
// TODO: #testnetreset clean up this code
1054+
let input_mr = if header.version == 1 {
1055+
MutableMmr::<HashDigest, _>::new(input_mmr.get_pruned_hash_set()?, Bitmap::create())?.get_merkle_root()?
1056+
} else {
1057+
input_mmr.get_merkle_root()?
1058+
};
1059+
10541060
let mmr_roots = MmrRoots {
10551061
kernel_mr: kernel_mmr.get_merkle_root()?,
10561062
kernel_mmr_size: kernel_mmr.get_leaf_count()? as u64,
1057-
input_mr: input_mmr.get_merkle_root()?,
1063+
input_mr,
10581064
output_mr: output_mmr.get_merkle_root()?,
10591065
output_mmr_size: output_mmr.get_leaf_count() as u64,
10601066
witness_mr: witness_mmr.get_merkle_root()?,

‎base_layer/core/src/consensus/consensus_constants.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ impl ConsensusConstants {
209209
emission_initial: 5_538_846_115 * uT,
210210
emission_decay: &EMISSION_DECAY,
211211
emission_tail: 100.into(),
212-
max_randomx_seed_height: std::u64::MAX,
212+
max_randomx_seed_height: u64::MAX,
213213
proof_of_work: algos,
214214
faucet_value: (5000 * 4000) * T,
215215
}]
@@ -218,7 +218,7 @@ impl ConsensusConstants {
218218
pub fn ridcully() -> Vec<Self> {
219219
let difficulty_block_window = 90;
220220
let mut algos = HashMap::new();
221-
// seting sha3/monero to 40/60 split
221+
// setting sha3/monero to 40/60 split
222222
algos.insert(PowAlgorithm::Sha3, PowAlgorithmConstants {
223223
max_target_time: 1800,
224224
min_difficulty: 60_000_000.into(),
@@ -242,7 +242,7 @@ impl ConsensusConstants {
242242
emission_initial: 5_538_846_115 * uT,
243243
emission_decay: &EMISSION_DECAY,
244244
emission_tail: 100.into(),
245-
max_randomx_seed_height: std::u64::MAX,
245+
max_randomx_seed_height: u64::MAX,
246246
proof_of_work: algos,
247247
faucet_value: (5000 * 4000) * T,
248248
}]
@@ -277,7 +277,7 @@ impl ConsensusConstants {
277277
target_time: 200,
278278
});
279279
let mut algos2 = HashMap::new();
280-
// seting sha3/monero to 40/60 split
280+
// setting sha3/monero to 40/60 split
281281
algos2.insert(PowAlgorithm::Sha3, PowAlgorithmConstants {
282282
max_target_time: 1800,
283283
min_difficulty: 60_000_000.into(),
@@ -302,7 +302,7 @@ impl ConsensusConstants {
302302
emission_initial: 5_538_846_115 * uT,
303303
emission_decay: &EMISSION_DECAY,
304304
emission_tail: 100.into(),
305-
max_randomx_seed_height: std::u64::MAX,
305+
max_randomx_seed_height: u64::MAX,
306306
proof_of_work: algos,
307307
faucet_value: (5000 * 4000) * T,
308308
},
@@ -317,7 +317,7 @@ impl ConsensusConstants {
317317
emission_initial: 5_538_846_115 * uT,
318318
emission_decay: &EMISSION_DECAY,
319319
emission_tail: 100.into(),
320-
max_randomx_seed_height: std::u64::MAX,
320+
max_randomx_seed_height: u64::MAX,
321321
proof_of_work: algos2,
322322
faucet_value: (5000 * 4000) * T,
323323
},
@@ -326,7 +326,7 @@ impl ConsensusConstants {
326326

327327
pub fn weatherwax() -> Vec<Self> {
328328
let mut algos = HashMap::new();
329-
// seting sha3/monero to 40/60 split
329+
// setting sha3/monero to 40/60 split
330330
algos.insert(PowAlgorithm::Sha3, PowAlgorithmConstants {
331331
max_target_time: 1800,
332332
min_difficulty: 60_000_000.into(),
@@ -350,15 +350,15 @@ impl ConsensusConstants {
350350
emission_initial: 5_538_846_115 * uT,
351351
emission_decay: &EMISSION_DECAY,
352352
emission_tail: 100.into(),
353-
max_randomx_seed_height: std::u64::MAX,
353+
max_randomx_seed_height: u64::MAX,
354354
proof_of_work: algos,
355355
faucet_value: (5000 * 4000) * T,
356356
}]
357357
}
358358

359359
pub fn igor() -> Vec<Self> {
360360
let mut algos = HashMap::new();
361-
// seting sha3/monero to 40/60 split
361+
// setting sha3/monero to 40/60 split
362362
algos.insert(PowAlgorithm::Sha3, PowAlgorithmConstants {
363363
max_target_time: 1800,
364364
min_difficulty: 60_000_000.into(),
@@ -374,15 +374,15 @@ impl ConsensusConstants {
374374
vec![ConsensusConstants {
375375
effective_from_height: 0,
376376
coinbase_lock_height: 6,
377-
blockchain_version: 1,
377+
blockchain_version: 2,
378378
future_time_limit: 540,
379379
difficulty_block_window: 90,
380380
max_block_transaction_weight: 19500,
381381
median_timestamp_count: 11,
382382
emission_initial: 5_538_846_115 * uT,
383383
emission_decay: &EMISSION_DECAY,
384384
emission_tail: 100.into(),
385-
max_randomx_seed_height: std::u64::MAX,
385+
max_randomx_seed_height: u64::MAX,
386386
proof_of_work: algos,
387387
faucet_value: (5000 * 4000) * T,
388388
}]
@@ -415,7 +415,7 @@ impl ConsensusConstants {
415415
emission_initial: 10_000_000.into(),
416416
emission_decay: &EMISSION_DECAY,
417417
emission_tail: 100.into(),
418-
max_randomx_seed_height: std::u64::MAX,
418+
max_randomx_seed_height: u64::MAX,
419419
proof_of_work: algos,
420420
faucet_value: MicroTari::from(0),
421421
}]

‎base_layer/core/src/proto/transaction.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,7 @@ impl TryFrom<proto::types::AggregateBody> for AggregateBody {
223223
let inputs = try_convert_all(body.inputs)?;
224224
let outputs = try_convert_all(body.outputs)?;
225225
let kernels = try_convert_all(body.kernels)?;
226-
let mut body = AggregateBody::new(inputs, outputs, kernels);
227-
body.sort();
226+
let body = AggregateBody::new(inputs, outputs, kernels);
228227
Ok(body)
229228
}
230229
}

‎base_layer/core/src/transactions/aggregated_body.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub const LOG_TARGET: &str = "c::tx::aggregated_body";
4545

4646
/// The components of the block or transaction. The same struct can be used for either, since in Mimblewimble,
4747
/// cut-through means that blocks and transactions have the same structure.
48-
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
48+
#[derive(Clone, Debug, Serialize, Deserialize)]
4949
pub struct AggregateBody {
5050
sorted: bool,
5151
/// List of inputs spent by the transaction.
@@ -198,13 +198,18 @@ impl AggregateBody {
198198
}
199199

200200
/// Sort the component lists of the aggregate body
201-
pub fn sort(&mut self) {
201+
pub fn sort(&mut self, version: u16) {
202202
if self.sorted {
203203
return;
204204
}
205205
self.inputs.sort();
206206
self.outputs.sort();
207-
self.kernels.sort();
207+
// TODO: #testnetreset clean up this code
208+
if version <= 1 {
209+
self.kernels.sort_by(|a, b| a.deprecated_cmp(b));
210+
} else {
211+
self.kernels.sort();
212+
}
208213
self.sorted = true;
209214
}
210215

@@ -471,6 +476,14 @@ impl AggregateBody {
471476
}
472477
}
473478

479+
impl PartialEq for AggregateBody {
480+
fn eq(&self, other: &Self) -> bool {
481+
self.kernels == other.kernels && self.inputs == other.inputs && self.outputs == other.outputs
482+
}
483+
}
484+
485+
impl Eq for AggregateBody {}
486+
474487
/// This will strip away the offset of the transaction returning a pure aggregate body
475488
impl From<Transaction> for AggregateBody {
476489
fn from(transaction: Transaction) -> Self {

0 commit comments

Comments
 (0)