Allow transaction inputs to be validated individually
This commit is contained in:
parent
7eadf72a1a
commit
6e6da2a756
|
@ -130,18 +130,20 @@ pub struct TransactionTrace {
|
||||||
|
|
||||||
impl_json!(TransactionTrace, txid, inputs)
|
impl_json!(TransactionTrace, txid, inputs)
|
||||||
|
|
||||||
impl Transaction {
|
impl TxIn {
|
||||||
/// Check a transaction for validity
|
/// Check an input's script for validity
|
||||||
pub fn validate(&self, utxoset: &UtxoSet) -> Result<(), TransactionError> {
|
pub fn validate(&self,
|
||||||
for (n, input) in self.input.iter().enumerate() {
|
utxoset: &UtxoSet,
|
||||||
let txo = utxoset.get_utxo(input.prev_hash, input.prev_index);
|
txn: &Transaction,
|
||||||
|
index: uint) -> Result<(), TransactionError> {
|
||||||
|
let txo = utxoset.get_utxo(self.prev_hash, self.prev_index);
|
||||||
match txo {
|
match txo {
|
||||||
Some(txo) => {
|
Some(txo) => {
|
||||||
let mut p2sh_stack = Vec::new();
|
let mut p2sh_stack = Vec::new();
|
||||||
let mut p2sh_script = Script::new();
|
let mut p2sh_script = Script::new();
|
||||||
|
|
||||||
let mut stack = Vec::with_capacity(6);
|
let mut stack = Vec::with_capacity(6);
|
||||||
match input.script_sig.evaluate(&mut stack, Some((self, n)), None) {
|
match self.script_sig.evaluate(&mut stack, Some((txn, index)), None) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => { return Err(InputScriptFailure(e)); }
|
Err(e) => { return Err(InputScriptFailure(e)); }
|
||||||
}
|
}
|
||||||
|
@ -153,7 +155,7 @@ impl Transaction {
|
||||||
None => unreachable!()
|
None => unreachable!()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
match txo.script_pubkey.evaluate(&mut stack, Some((self, n)), None) {
|
match txo.script_pubkey.evaluate(&mut stack, Some((txn, index)), None) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => { return Err(OutputScriptFailure(e)); }
|
Err(e) => { return Err(OutputScriptFailure(e)); }
|
||||||
}
|
}
|
||||||
|
@ -166,7 +168,7 @@ impl Transaction {
|
||||||
None => { return Err(ScriptReturnedEmptyStack); }
|
None => { return Err(ScriptReturnedEmptyStack); }
|
||||||
}
|
}
|
||||||
if txo.script_pubkey.is_p2sh() {
|
if txo.script_pubkey.is_p2sh() {
|
||||||
match p2sh_script.evaluate(&mut p2sh_stack, Some((self, n)), None) {
|
match p2sh_script.evaluate(&mut p2sh_stack, Some((txn, index)), None) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => { return Err(P2shScriptFailure(e)); }
|
Err(e) => { return Err(P2shScriptFailure(e)); }
|
||||||
}
|
}
|
||||||
|
@ -180,8 +182,17 @@ impl Transaction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => { return Err(InputNotFound(input.prev_hash, input.prev_index)); }
|
None => { return Err(InputNotFound(self.prev_hash, self.prev_index)); }
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Transaction {
|
||||||
|
/// Check a transaction for validity
|
||||||
|
pub fn validate(&self, utxoset: &UtxoSet) -> Result<(), TransactionError> {
|
||||||
|
for (n, input) in self.input.iter().enumerate() {
|
||||||
|
try!(input.validate(utxoset, self, n));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue