Merge pull request #130 from ethcore/sigop-accurate

Don't count signature operations accurately on regular scripts
This commit is contained in:
Svyatoslav Nikolsky 2016-11-16 09:05:39 +03:00 committed by GitHub
commit d6549849d5
2 changed files with 34 additions and 29 deletions

View File

@ -313,7 +313,7 @@ impl Script {
Opcodes { position: 0, script: self }
}
pub fn sigop_count(&self) -> Result<usize, Error> {
pub fn sigop_count(&self, accurate: bool) -> Result<usize, Error> {
let mut last_opcode = Opcode::OP_0;
let mut result = 0;
for opcode in self.opcodes() {
@ -322,30 +322,34 @@ impl Script {
match opcode {
Opcode::OP_CHECKSIG | Opcode::OP_CHECKSIGVERIFY => { result += 1; },
Opcode::OP_CHECKMULTISIG | Opcode::OP_CHECKMULTISIGVERIFY => {
match last_opcode {
Opcode::OP_1 |
Opcode::OP_2 |
Opcode::OP_3 |
Opcode::OP_4 |
Opcode::OP_5 |
Opcode::OP_6 |
Opcode::OP_7 |
Opcode::OP_8 |
Opcode::OP_9 |
Opcode::OP_10 |
Opcode::OP_11 |
Opcode::OP_12 |
Opcode::OP_13 |
Opcode::OP_14 |
Opcode::OP_15 |
Opcode::OP_16 => {
result += (last_opcode as u8 - (Opcode::OP_1 as u8 - 1)) as usize;
},
_ => {
result += MAX_PUBKEYS_PER_MULTISIG;
if accurate {
match last_opcode {
Opcode::OP_1 |
Opcode::OP_2 |
Opcode::OP_3 |
Opcode::OP_4 |
Opcode::OP_5 |
Opcode::OP_6 |
Opcode::OP_7 |
Opcode::OP_8 |
Opcode::OP_9 |
Opcode::OP_10 |
Opcode::OP_11 |
Opcode::OP_12 |
Opcode::OP_13 |
Opcode::OP_14 |
Opcode::OP_15 |
Opcode::OP_16 => {
result += (last_opcode as u8 - (Opcode::OP_1 as u8 - 1)) as usize;
},
_ => {
result += MAX_PUBKEYS_PER_MULTISIG;
}
}
}
else {
result += MAX_PUBKEYS_PER_MULTISIG;
}
},
_ => { }
};
@ -529,9 +533,10 @@ OP_ADD
#[test]
fn test_sigops_count() {
assert_eq!(1usize, Script::from("76a914aab76ba4877d696590d94ea3e02948b55294815188ac").sigop_count().unwrap());
assert_eq!(2usize, Script::from("522102004525da5546e7603eefad5ef971e82f7dad2272b34e6b3036ab1fe3d299c22f21037d7f2227e6c646707d1c61ecceb821794124363a2cf2c1d2a6f28cf01e5d6abe52ae").sigop_count().unwrap());
assert_eq!(0usize, Script::from("a9146262b64aec1f4a4c1d21b32e9c2811dd2171fd7587").sigop_count().unwrap());
assert_eq!(1usize, Script::from("4104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac").sigop_count().unwrap());
assert_eq!(1usize, Script::from("76a914aab76ba4877d696590d94ea3e02948b55294815188ac").sigop_count(false).unwrap());
assert_eq!(2usize, Script::from("522102004525da5546e7603eefad5ef971e82f7dad2272b34e6b3036ab1fe3d299c22f21037d7f2227e6c646707d1c61ecceb821794124363a2cf2c1d2a6f28cf01e5d6abe52ae").sigop_count(true).unwrap());
assert_eq!(20usize, Script::from("522102004525da5546e7603eefad5ef971e82f7dad2272b34e6b3036ab1fe3d299c22f21037d7f2227e6c646707d1c61ecceb821794124363a2cf2c1d2a6f28cf01e5d6abe52ae").sigop_count(false).unwrap());
assert_eq!(0usize, Script::from("a9146262b64aec1f4a4c1d21b32e9c2811dd2171fd7587").sigop_count(false).unwrap());
assert_eq!(1usize, Script::from("4104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac").sigop_count(false).unwrap());
}
}

View File

@ -60,14 +60,14 @@ pub fn transaction_sigops(transaction: &chain::Transaction) -> Result<usize, scr
for output in transaction.outputs.iter() {
let output_script: Script = output.script_pubkey.to_vec().into();
// todo: not always allow malformed output?
result += output_script.sigop_count().unwrap_or(0);
result += output_script.sigop_count(false).unwrap_or(0);
}
if transaction.is_coinbase() { return Ok(result); }
for input in transaction.inputs.iter() {
let input_script: Script = input.script_sig().to_vec().into();
result += try!(input_script.sigop_count());
result += try!(input_script.sigop_count(false));
}
Ok(result)