Skip to content

Commit 5010fbe

Browse files
committed
Sighash input commitments v1
1 parent 6ab6dff commit 5010fbe

63 files changed

Lines changed: 3904 additions & 481 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 43 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,11 @@ hickory-client = "0.24"
246246
hickory-server = "0.24"
247247
zeroize = "1.5"
248248

249+
[workspace.dependencies.trezor-client]
250+
git = "https://github.com/mintlayer/mintlayer-trezor-firmware"
251+
rev = "967023d82f33984961c8f8fd221672c233b22220" # sighash_input_commitments branch
252+
features = ["bitcoin", "mintlayer"]
253+
249254
[workspace.metadata.dist.dependencies.apt]
250255
"libatk1.0-0" = "*"
251256
"libatk1.0-dev" = "*"

api-server/scanner-lib/src/sync/tests/mod.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ mod simulation;
1717

1818
use std::{
1919
borrow::Cow,
20+
collections::BTreeMap,
2021
convert::Infallible,
2122
sync::{Arc, Mutex},
2223
time::Duration,
@@ -45,17 +46,17 @@ use common::{
4546
},
4647
sighash::{
4748
input_commitments::{
48-
make_sighash_input_commitments_for_transaction_inputs, SighashInputCommitment,
49-
TrivialUtxoProvider,
49+
make_sighash_input_commitments_for_transaction_inputs_at_height, OrderInfo,
50+
PoolInfo, SighashInputCommitment, TrivialUtxoProvider,
5051
},
5152
sighashtype::SigHashType,
5253
signature_hash,
5354
},
5455
},
5556
stakelock::StakePoolData,
5657
timelock::OutputTimeLock,
57-
CoinUnit, Destination, OutPointSourceId, PoolId, SignedTransaction, TxInput, TxOutput,
58-
UtxoOutPoint,
58+
CoinUnit, Destination, OrderId, OutPointSourceId, PoolId, SignedTransaction, TxInput,
59+
TxOutput, UtxoOutPoint,
5960
},
6061
primitives::{per_thousand::PerThousand, Amount, CoinOrTokenId, Idable, H256},
6162
};
@@ -567,9 +568,29 @@ async fn compare_pool_rewards_with_chainstate_real_state(#[case] seed: Seed) {
567568
.build();
568569

569570
let utxos = [Some(coin_tx_out), Some(from_block_output)];
570-
let input_commitments = make_sighash_input_commitments_for_transaction_inputs(
571+
let decommissioned_pool_staker_balance = local_state
572+
.storage()
573+
.transaction_ro()
574+
.await
575+
.unwrap()
576+
.get_pool_data(pool_id)
577+
.await
578+
.unwrap()
579+
.unwrap()
580+
.staker_balance()
581+
.unwrap();
582+
let input_commitments = make_sighash_input_commitments_for_transaction_inputs_at_height(
571583
&[input1, input2],
572584
&TrivialUtxoProvider(&utxos),
585+
&BTreeMap::<PoolId, PoolInfo>::from([(
586+
pool_id,
587+
PoolInfo {
588+
staker_balance: decommissioned_pool_staker_balance,
589+
},
590+
)]),
591+
&BTreeMap::<OrderId, OrderInfo>::new(),
592+
&chain_config,
593+
tf.next_block_height(),
573594
)
574595
.unwrap();
575596
let sighash = signature_hash(

chainstate/src/detail/ban_score.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,13 @@ impl BanScore for tx_verifier::error::InputCheckErrorPayload {
170170
fn ban_score(&self) -> u32 {
171171
match self {
172172
Self::MissingUtxo(_) => 100,
173+
Self::PoolNotFound(_) => 100,
174+
Self::OrderNotFound(_) => 100,
173175
Self::NonUtxoKernelInput(_) => 100,
174176
Self::UtxoView(e) => e.ban_score(),
175177
Self::UtxoInfoProvider(e) => e.ban_score(),
178+
Self::PoolInfoProvider(e) => e.ban_score(),
179+
Self::OrderInfoProvider(e) => e.ban_score(),
176180
Self::Translation(e) => e.ban_score(),
177181
Self::Verification(e) => e.ban_score(),
178182
}

chainstate/src/detail/error_classification.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,11 +346,14 @@ impl BlockProcessingErrorClassification for tx_verifier::error::InputCheckError
346346
impl BlockProcessingErrorClassification for tx_verifier::error::InputCheckErrorPayload {
347347
fn classify(&self) -> BlockProcessingErrorClass {
348348
match self {
349-
Self::MissingUtxo(_) | Self::NonUtxoKernelInput(_) => {
350-
BlockProcessingErrorClass::BadBlock
351-
}
349+
Self::MissingUtxo(_)
350+
| Self::PoolNotFound(_)
351+
| Self::OrderNotFound(_)
352+
| Self::NonUtxoKernelInput(_) => BlockProcessingErrorClass::BadBlock,
352353
Self::UtxoView(e) => e.classify(),
353354
Self::UtxoInfoProvider(e) => e.classify(),
355+
Self::PoolInfoProvider(e) => e.classify(),
356+
Self::OrderInfoProvider(e) => e.classify(),
354357
Self::Translation(e) => e.classify(),
355358
Self::Verification(e) => e.classify(),
356359
}

chainstate/test-framework/src/block_builder.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,13 +185,21 @@ impl<'f> BlockBuilder<'f> {
185185
let destination_getter = SignatureDestinationGetter::new_for_transaction(
186186
&tokens_db, &pos_db, &orders_db, &utxo_set,
187187
);
188+
let block_height = self
189+
.framework
190+
.gen_block_index(&self.prev_block_hash)
191+
.block_height()
192+
.next_height();
188193
let witnesses = sign_witnesses(
189194
rng,
190195
&self.framework.key_manager,
191196
self.framework.chainstate.get_chain_config(),
192197
&tx,
193198
&utxo_set,
199+
&pos_db,
200+
&orders_db,
194201
destination_getter,
202+
block_height,
195203
);
196204
let tx = SignedTransaction::new(tx, witnesses).expect("invalid witness count");
197205

chainstate/test-framework/src/framework.rs

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,15 @@
1515

1616
use std::{collections::BTreeMap, sync::Arc};
1717

18-
use chainstate_storage::{
19-
BlockchainStorageRead, BlockchainStorageWrite, TransactionRw, Transactional,
20-
};
2118
use rstest::rstest;
2219

23-
use crate::{
24-
framework_builder::TestFrameworkBuilderValue,
25-
get_output_value,
26-
key_manager::KeyManager,
27-
pos_block_builder::PoSBlockBuilder,
28-
random_tx_maker::StakingPoolsObserver,
29-
staking_pools::StakingPools,
30-
utils::{
31-
assert_block_index_opt_identical_to, assert_gen_block_index_identical_to,
32-
assert_gen_block_index_opt_identical_to, find_create_pool_tx_in_genesis,
33-
outputs_from_block, outputs_from_genesis, SighashInputCommitmentInfoProvider,
34-
},
35-
BlockBuilder, TestChainstate, TestFrameworkBuilder, TestStore, TxVerificationStrategy,
36-
};
3720
use chainstate::{chainstate_interface::ChainstateInterface, BlockSource, ChainstateError};
21+
use chainstate_storage::{
22+
BlockchainStorageRead, BlockchainStorageWrite, TransactionRw, Transactional,
23+
};
3824
use chainstate_types::{
3925
pos_randomness::PoSRandomness, BlockIndex, BlockStatus, EpochStorageRead as _, GenBlockIndex,
26+
TipStorageTag,
4027
};
4128
use common::{
4229
chain::{
@@ -48,10 +35,27 @@ use common::{
4835
time_getter::TimeGetter,
4936
};
5037
use crypto::{key::PrivateKey, vrf::VRFPrivateKey};
38+
use orders_accounting::OrdersAccountingDB;
39+
use pos_accounting::{PoSAccountingDB, PoSAccountingData};
5140
use randomness::{CryptoRng, Rng};
5241
use utils::atomics::SeqCstAtomicU64;
5342
use utxo::{Utxo, UtxosDB};
5443

44+
use crate::{
45+
framework_builder::TestFrameworkBuilderValue,
46+
get_output_value,
47+
key_manager::KeyManager,
48+
pos_block_builder::PoSBlockBuilder,
49+
random_tx_maker::StakingPoolsObserver,
50+
staking_pools::StakingPools,
51+
utils::{
52+
assert_block_index_opt_identical_to, assert_gen_block_index_identical_to,
53+
assert_gen_block_index_opt_identical_to, find_create_pool_tx_in_genesis,
54+
outputs_from_block, outputs_from_genesis, SighashInputCommitmentInfoProvider,
55+
},
56+
BlockBuilder, TestChainstate, TestFrameworkBuilder, TestStore, TxVerificationStrategy,
57+
};
58+
5559
/// The `Chainstate` wrapper that simplifies operations and checks in the tests.
5660
#[must_use]
5761
pub struct TestFramework {
@@ -587,13 +591,20 @@ impl TestFramework {
587591
pub fn make_sighash_input_commitments_for_transaction_inputs(
588592
&self,
589593
inputs: &[TxInput],
594+
block_height: BlockHeight,
590595
) -> Vec<SighashInputCommitment<'static>> {
591596
let storage_tx = self.storage.transaction_ro().unwrap();
592597
let utxo_db = UtxosDB::new(&storage_tx);
598+
let pos_db = PoSAccountingDB::<_, TipStorageTag>::new(&storage_tx);
599+
let orders_db = OrdersAccountingDB::new(&storage_tx);
593600

594-
sighash::input_commitments::make_sighash_input_commitments_for_transaction_inputs(
601+
sighash::input_commitments::make_sighash_input_commitments_for_transaction_inputs_at_height(
595602
inputs,
596603
&SighashInputCommitmentInfoProvider(&utxo_db),
604+
&SighashInputCommitmentInfoProvider(&pos_db),
605+
&SighashInputCommitmentInfoProvider(&orders_db),
606+
self.chain_config(),
607+
block_height,
597608
)
598609
.unwrap()
599610
}
@@ -613,6 +624,38 @@ impl TestFramework {
613624
pub fn coin_amount_from_utxo(&self, outpoint: &UtxoOutPoint) -> Amount {
614625
get_output_value(self.utxo(outpoint).output()).unwrap().coin_amount().unwrap()
615626
}
627+
628+
pub fn pos_accounting_data_at_tip(&self) -> PoSAccountingData {
629+
self.storage.transaction_ro().unwrap().read_pos_accounting_data_tip().unwrap()
630+
}
631+
632+
pub fn find_kernel_outpoint_for_pool(&self, pool_id: &PoolId) -> Option<UtxoOutPoint> {
633+
let utxos = self.storage.transaction_ro().unwrap().read_utxo_set().unwrap();
634+
635+
let mut outpoints_iter =
636+
utxos.into_iter().filter_map(|(outpoint, utxo)| match utxo.output() {
637+
TxOutput::ProduceBlockFromStake(_, used_pool_id)
638+
| TxOutput::CreateStakePool(used_pool_id, _) => {
639+
(used_pool_id == pool_id).then_some(outpoint)
640+
}
641+
642+
TxOutput::Transfer(_, _)
643+
| TxOutput::LockThenTransfer(_, _, _)
644+
| TxOutput::Burn(_)
645+
| TxOutput::CreateDelegationId(_, _)
646+
| TxOutput::DelegateStaking(_, _)
647+
| TxOutput::IssueFungibleToken(_)
648+
| TxOutput::IssueNft(_, _, _)
649+
| TxOutput::DataDeposit(_)
650+
| TxOutput::Htlc(_, _)
651+
| TxOutput::CreateOrder(_) => None,
652+
});
653+
654+
let result = outpoints_iter.next();
655+
assert!(outpoints_iter.next().is_none());
656+
657+
result
658+
}
616659
}
617660

618661
#[rstest]

chainstate/test-framework/src/pos_block_builder.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,13 +411,21 @@ impl<'f> PoSBlockBuilder<'f> {
411411
let destination_getter = SignatureDestinationGetter::new_for_transaction(
412412
&tokens_db, &pos_db, &orders_db, &utxo_set,
413413
);
414+
let block_height = self
415+
.framework
416+
.gen_block_index(&self.prev_block_hash)
417+
.block_height()
418+
.next_height();
414419
let witnesses = sign_witnesses(
415420
rng,
416421
&self.framework.key_manager,
417422
self.framework.chainstate.get_chain_config(),
418423
&tx,
419424
&utxo_set,
425+
&pos_db,
426+
&orders_db,
420427
destination_getter,
428+
block_height,
421429
);
422430
let tx = SignedTransaction::new(tx, witnesses).expect("invalid witness count");
423431

0 commit comments

Comments
 (0)