Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add KIP-10 Mutual Transaction Opcodes and Hard Fork Support #487

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0e6e748
implement new opcodes
biryukovmaxim Jun 14, 2024
2076757
example of mutual tx
biryukovmaxim Jun 16, 2024
50fd953
add docs describing scenario
biryukovmaxim Jun 16, 2024
7afb955
introduce feature gate for new features
biryukovmaxim Jun 16, 2024
993e91e
introduce hf feature that enables txscript hf feature
biryukovmaxim Jun 16, 2024
a0be8af
style: fmt and clippy fix
biryukovmaxim Jun 16, 2024
f1eed92
implement new opcodes
biryukovmaxim Jun 14, 2024
7b02bb2
example of mutual tx
biryukovmaxim Jun 16, 2024
a679525
add docs describing scenario
biryukovmaxim Jun 16, 2024
2e61b44
introduce feature gate for new features
biryukovmaxim Jun 16, 2024
f7a3f77
style: fmt and clippy fix
biryukovmaxim Jun 16, 2024
4afb1dc
remove unused feature
biryukovmaxim Jun 16, 2024
cd5c169
fmt
biryukovmaxim Jun 16, 2024
96cfd54
make opcode invalid in case of feature disabled
biryukovmaxim Jun 16, 2024
399fcd7
feature gate test
biryukovmaxim Jun 16, 2024
8cff7fe
change test set based on feature
biryukovmaxim Jun 16, 2024
c882d32
rename InputSPK -> InputSpk
biryukovmaxim Jun 16, 2024
1c19ae1
enable kip10 opcodes based on daa_score in runtime
biryukovmaxim Jun 16, 2024
4147473
use dummy kip10 activation daa score in params
biryukovmaxim Jun 16, 2024
c32c34b
use dummy kip10 activation daa score in params
biryukovmaxim Jun 16, 2024
915b5d3
suppress clippy lint
biryukovmaxim Jun 16, 2024
7294020
add example with shared key
biryukovmaxim Jun 17, 2024
3c4e029
Merge branch 'master' into kip-10-mutual-tx
biryukovmaxim Sep 28, 2024
8b4d0be
fix clippy
biryukovmaxim Sep 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion consensus/core/src/config/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ pub struct Params {
/// DAA score from which storage mass calculation and transaction mass field are activated as a consensus rule
pub storage_mass_activation_daa_score: u64,

/// DAA score from which tx engine supports kip10 opcodes: OpInputAmount, OpInputSpk, OpOutputAmount, OpOutputSpk
pub kip10_activation_daa_score: u64,

/// DAA score after which the pre-deflationary period switches to the deflationary period
pub deflationary_phase_daa_score: u64,

Expand Down Expand Up @@ -353,6 +356,7 @@ pub const MAINNET_PARAMS: Params = Params {

storage_mass_parameter: STORAGE_MASS_PARAMETER,
storage_mass_activation_daa_score: u64::MAX,
kip10_activation_daa_score: u64::MAX,

// deflationary_phase_daa_score is the DAA score after which the pre-deflationary period
// switches to the deflationary period. This number is calculated as follows:
Expand Down Expand Up @@ -416,7 +420,7 @@ pub const TESTNET_PARAMS: Params = Params {

storage_mass_parameter: STORAGE_MASS_PARAMETER,
storage_mass_activation_daa_score: u64::MAX,

kip10_activation_daa_score: u64::MAX,
// deflationary_phase_daa_score is the DAA score after which the pre-deflationary period
// switches to the deflationary period. This number is calculated as follows:
// We define a year as 365.25 days
Expand Down Expand Up @@ -486,6 +490,7 @@ pub const TESTNET11_PARAMS: Params = Params {

storage_mass_parameter: STORAGE_MASS_PARAMETER,
storage_mass_activation_daa_score: 0,
kip10_activation_daa_score: u64::MAX,

skip_proof_of_work: false,
max_block_level: 250,
Expand Down Expand Up @@ -539,6 +544,7 @@ pub const SIMNET_PARAMS: Params = Params {

storage_mass_parameter: STORAGE_MASS_PARAMETER,
storage_mass_activation_daa_score: 0,
kip10_activation_daa_score: u64::MAX,

skip_proof_of_work: true, // For simnet only, PoW can be simulated by default
max_block_level: 250,
Expand Down Expand Up @@ -585,6 +591,7 @@ pub const DEVNET_PARAMS: Params = Params {

storage_mass_parameter: STORAGE_MASS_PARAMETER,
storage_mass_activation_daa_score: u64::MAX,
kip10_activation_daa_score: u64::MAX,

// deflationary_phase_daa_score is the DAA score after which the pre-deflationary period
// switches to the deflationary period. This number is calculated as follows:
Expand Down
1 change: 1 addition & 0 deletions consensus/src/consensus/services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ impl ConsensusServices {
tx_script_cache_counters,
mass_calculator.clone(),
params.storage_mass_activation_daa_score,
params.kip10_activation_daa_score,
);

let pruning_point_manager = PruningPointManager::new(
Expand Down
6 changes: 6 additions & 0 deletions consensus/src/processes/transaction_validator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ pub struct TransactionValidator {

/// Storage mass hardfork DAA score
storage_mass_activation_daa_score: u64,
/// KIP-10 hardfork DAA score
kip10_activation_daa_score: u64,
}

impl TransactionValidator {
#[allow(clippy::too_many_arguments)]
pub fn new(
max_tx_inputs: usize,
max_tx_outputs: usize,
Expand All @@ -42,6 +45,7 @@ impl TransactionValidator {
counters: Arc<TxScriptCacheCounters>,
mass_calculator: MassCalculator,
storage_mass_activation_daa_score: u64,
kip10_activation_daa_score: u64,
) -> Self {
Self {
max_tx_inputs,
Expand All @@ -54,6 +58,7 @@ impl TransactionValidator {
sig_cache: Cache::with_counters(10_000, counters),
mass_calculator,
storage_mass_activation_daa_score,
kip10_activation_daa_score,
}
}

Expand All @@ -78,6 +83,7 @@ impl TransactionValidator {
sig_cache: Cache::with_counters(10_000, counters),
mass_calculator: MassCalculator::new(0, 0, 0, 0),
storage_mass_activation_daa_score: u64::MAX,
kip10_activation_daa_score: u64::MAX,
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl TransactionValidator {
match flags {
TxValidationFlags::Full | TxValidationFlags::SkipMassCheck => {
Self::check_sig_op_counts(tx)?;
self.check_scripts(tx)?;
self.check_scripts(tx, pov_daa_score)?;
}
TxValidationFlags::SkipScriptChecks => {}
}
Expand Down Expand Up @@ -166,11 +166,19 @@ impl TransactionValidator {
Ok(())
}

pub fn check_scripts(&self, tx: &impl VerifiableTransaction) -> TxResult<()> {
pub fn check_scripts(&self, tx: &impl VerifiableTransaction, pov_daa_score: u64) -> TxResult<()> {
let mut reused_values = SigHashReusedValues::new();
for (i, (input, entry)) in tx.populated_inputs().enumerate() {
let mut engine = TxScriptEngine::from_transaction_input(tx, input, i, entry, &mut reused_values, &self.sig_cache)
.map_err(|err| map_script_err(err, input))?;
let mut engine = TxScriptEngine::from_transaction_input(
tx,
input,
i,
entry,
&mut reused_values,
&self.sig_cache,
pov_daa_score > self.kip10_activation_daa_score,
)
.map_err(|err| map_script_err(err, input))?;
engine.execute().map_err(|err| map_script_err(err, input))?;
}

Expand Down Expand Up @@ -260,7 +268,7 @@ mod tests {
}],
);

tv.check_scripts(&populated_tx).expect("Signature check failed");
tv.check_scripts(&populated_tx, u64::MAX).expect("Signature check failed");
}

#[test]
Expand Down Expand Up @@ -322,7 +330,7 @@ mod tests {
}],
);

assert!(tv.check_scripts(&populated_tx).is_err(), "Failing Signature Test Failed");
assert!(tv.check_scripts(&populated_tx, u64::MAX).is_err(), "Failing Signature Test Failed");
}

#[test]
Expand Down Expand Up @@ -384,7 +392,7 @@ mod tests {
is_coinbase: false,
}],
);
tv.check_scripts(&populated_tx).expect("Signature check failed");
tv.check_scripts(&populated_tx, u64::MAX).expect("Signature check failed");
}

#[test]
Expand Down Expand Up @@ -447,7 +455,7 @@ mod tests {
}],
);

assert!(tv.check_scripts(&populated_tx) == Err(TxRuleError::SignatureInvalid(TxScriptError::NullFail)));
assert!(tv.check_scripts(&populated_tx, u64::MAX) == Err(TxRuleError::SignatureInvalid(TxScriptError::NullFail)));
}

#[test]
Expand Down Expand Up @@ -510,7 +518,7 @@ mod tests {
}],
);

assert!(tv.check_scripts(&populated_tx) == Err(TxRuleError::SignatureInvalid(TxScriptError::NullFail)));
assert!(tv.check_scripts(&populated_tx, u64::MAX) == Err(TxRuleError::SignatureInvalid(TxScriptError::NullFail)));
}

#[test]
Expand Down Expand Up @@ -573,7 +581,7 @@ mod tests {
}],
);

let result = tv.check_scripts(&populated_tx);
let result = tv.check_scripts(&populated_tx, u64::MAX);
assert!(result == Err(TxRuleError::SignatureInvalid(TxScriptError::EvalFalse)));
}

Expand Down Expand Up @@ -628,7 +636,7 @@ mod tests {
}],
);

let result = tv.check_scripts(&populated_tx);
let result = tv.check_scripts(&populated_tx, u64::MAX);
assert!(result == Err(TxRuleError::SignatureInvalid(TxScriptError::SignatureScriptNotPushOnly)));
}

Expand Down Expand Up @@ -708,7 +716,7 @@ mod tests {
let schnorr_key = secp256k1::Keypair::from_seckey_slice(secp256k1::SECP256K1, &secret_key.secret_bytes()).unwrap();
let signed_tx = sign(MutableTransaction::with_entries(unsigned_tx, entries), schnorr_key);
let populated_tx = signed_tx.as_verifiable();
assert_eq!(tv.check_scripts(&populated_tx), Ok(()));
assert_eq!(tv.check_scripts(&populated_tx, u64::MAX), Ok(()));
assert_eq!(TransactionValidator::check_sig_op_counts(&populated_tx), Ok(()));
}
}
3 changes: 3 additions & 0 deletions crypto/txscript/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ include.workspace = true
license.workspace = true
repository.workspace = true

[[example]]
name = "kip-10"

[features]
wasm32-core = []
wasm32-sdk = []
Expand Down
Loading