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 input signature_script checking to submitTransaction RPC #479

Merged
merged 12 commits into from
Jul 26, 2024
1 change: 1 addition & 0 deletions consensus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ kaspa-muhash.workspace = true
kaspa-notify.workspace = true
kaspa-pow.workspace = true
kaspa-txscript.workspace = true
kaspa-txscript-errors.workspace = true
kaspa-utils.workspace = true
log.workspace = true
once_cell.workspace = true
Expand Down
3 changes: 3 additions & 0 deletions consensus/core/src/errors/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ pub enum TxRuleError {
#[error("failed to verify the signature script: {0}")]
SignatureInvalid(TxScriptError),

#[error("failed to verify empty signature script. Inner error: {0}")]
SignatureEmpty(TxScriptError),

#[error("input {0} sig op count is {1}, but the calculated value is {2}")]
WrongSigOpCount(usize, u64, u64),

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::constants::{MAX_SOMPI, SEQUENCE_LOCK_TIME_DISABLED, SEQUENCE_LOCK_TIME_MASK};
use kaspa_consensus_core::{hashing::sighash::SigHashReusedValues, tx::VerifiableTransaction};
use kaspa_consensus_core::{hashing::sighash::SigHashReusedValues, tx::{TransactionInput, VerifiableTransaction}};
use kaspa_core::warn;
use kaspa_txscript::{get_sig_op_count, TxScriptEngine};
use kaspa_txscript_errors::TxScriptError;

use super::{
errors::{TxResult, TxRuleError},
Expand Down Expand Up @@ -167,14 +168,22 @@ impl TransactionValidator {
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(TxRuleError::SignatureInvalid)?;
engine.execute().map_err(TxRuleError::SignatureInvalid)?;
.map_err(|err| map_script_err(err, input))?;
engine.execute().map_err(|err| map_script_err(err, input))?;
}

Ok(())
}
}

fn map_script_err(script_err: TxScriptError, input: &TransactionInput) -> TxRuleError {
if input.signature_script.is_empty() {
TxRuleError::SignatureEmpty(script_err)
} else {
TxRuleError::SignatureInvalid(script_err)
}
}

#[cfg(test)]
mod tests {
use super::super::errors::TxRuleError;
Expand Down
8 changes: 4 additions & 4 deletions rpc/core/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use kaspa_consensus_core::{subnets::SubnetworkConversionError, tx::TransactionId};
use kaspa_consensus_core::{subnets::SubnetworkConversionError, tx::TransactionId};
use kaspa_utils::networking::IpAddress;
use std::{net::AddrParseError, num::TryFromIntError};
use thiserror::Error;
Expand Down Expand Up @@ -116,9 +116,9 @@ pub enum RpcError {
#[error("transaction query must either not filter transactions or include orphans")]
InconsistentMempoolTxQuery,

#[error(transparent)]
SubnetParsingError(#[from] SubnetworkConversionError),
#[error(transparent)]
SubnetParsingError(#[from] SubnetworkConversionError),

#[error(transparent)]
WasmError(#[from] workflow_wasm::error::Error),

Expand Down
2 changes: 1 addition & 1 deletion rpc/service/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -992,4 +992,4 @@ impl AsyncService for RpcCoreService {
Ok(())
})
}
}
}
Loading