Skip to content
This repository has been archived by the owner on Apr 3, 2019. It is now read-only.

Commit

Permalink
fix flag setting for witness program
Browse files Browse the repository at this point in the history
  • Loading branch information
matiu committed Apr 23, 2018
1 parent 231b787 commit 50b4b32
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 33 deletions.
53 changes: 20 additions & 33 deletions lib/script/interpreter.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ Interpreter.prototype.verifyWitnessProgram = function(version, program, witness,
}

var scriptPubKeyBuffer = witness[witness.length - 1];
console.log('[interpreter.js.46:scriptPubKeyBuffer:]',scriptPubKeyBuffer); //TODO
scriptPubKey = new Script(scriptPubKeyBuffer);
console.log('[interpreter.js.47:scriptPubKey:]',scriptPubKey); //TODO
var hash = Hash.sha256(scriptPubKeyBuffer);
if (hash.toString('hex') !== program.toString('hex')) {
this.errstr = 'SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH';
Expand Down Expand Up @@ -85,7 +83,8 @@ console.log('[interpreter.js.47:scriptPubKey:]',scriptPubKey); //TODO
script: scriptPubKey,
stack: stack,
sigversion: 1,
satoshis: satoshis
satoshis: satoshis,
flags: flags,
});

if (!this.evaluate()) {
Expand Down Expand Up @@ -124,7 +123,6 @@ console.log('[interpreter.js.47:scriptPubKey:]',scriptPubKey); //TODO
* Translated from bitcoind's VerifyScript
*/
Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, witness, satoshis) {
console.log('[interpreter.js.126:witness:]',witness); //TODO

var Transaction = require('../transaction');
if (_.isUndefined(tx)) {
Expand Down Expand Up @@ -194,44 +192,34 @@ console.log('[interpreter.js.126:witness:]',witness); //TODO
}

var hadWitness = false;
console.log('[interpreter.js.195:hadWitness:]',hadWitness); //TODO

if ((flags & Interpreter.SCRIPT_VERIFY_WITNESS)) {
var witnessValues = {};
if (scriptPubkey.isWitnessProgram(witnessValues)) {
hadWitness = true;
if (scriptSig.toBuffer().length !== 0) {
return false;
}
console.log('[interpreter.js.206:witnessValues:]',witnessValues); //TODO

if (!this.verifyWitnessProgram(witnessValues.version, witnessValues.program, witness, satoshis, flags)) {
if (!this.verifyWitnessProgram(witnessValues.version, witnessValues.program, witness, satoshis, this.flags)) {
return false;
}
}
}

console.log('[interpreter.js.213]', scriptPubkey.isScriptHashOut()); //TODO
console.log('[interpreter.js.214:scriptPubkey:]',scriptPubkey); //TODO
// Additional validation for spend-to-script-hash transactions:
if ((flags & Interpreter.SCRIPT_VERIFY_P2SH) && scriptPubkey.isScriptHashOut()) {

console.log('[interpreter.js.217]'); //TODO
// scriptSig must be literals-only or validation fails
if (!scriptSig.isPushOnly()) {
this.errstr = 'SCRIPT_ERR_SIG_PUSHONLY';
return false;
}

console.log('[interpreter.js.222]'); //TODO
// stackCopy cannot be empty here, because if it was the
// P2SH HASH <> EQUAL scriptPubKey would be evaluated with
// an empty stack and the EvalScript above would return false.
if (stackCopy.length === 0) {
throw new Error('internal error - stack copy empty');
}

console.log('[interpreter.js.229]'); //TODO
var redeemScriptSerialized = stackCopy[stackCopy.length - 1];
var redeemScript = Script.fromBuffer(redeemScriptSerialized);
stackCopy.pop();
Expand Down Expand Up @@ -270,7 +258,7 @@ console.log('[interpreter.js.229]'); //TODO
return false;
}

if (!this.verifyWitnessProgram(p2shWitnessValues.version, p2shWitnessValues.program, witness, satoshis, flags)) {
if (!this.verifyWitnessProgram(p2shWitnessValues.version, p2shWitnessValues.program, witness, satoshis, this.flags)) {
return false;
}
// Bypass the cleanstack check at the end. The actual stack is obviously not clean
Expand All @@ -280,19 +268,15 @@ console.log('[interpreter.js.229]'); //TODO
}
}

console.log('[interpreter.js.282]'); //TODO



// The CLEANSTACK check is only performed after potential P2SH evaluation,
// as the non-P2SH evaluation of a P2SH script will obviously not result in
// a clean stack (the P2SH inputs remain). The same holds for witness
// evaluation.
if ((flags & Interpreter.SCRIPT_VERIFY_CLEANSTACK) != 0) {
if ((this.flags & Interpreter.SCRIPT_VERIFY_CLEANSTACK) != 0) {
// Disallow CLEANSTACK without P2SH, as otherwise a switch
// CLEANSTACK->P2SH+CLEANSTACK would be possible, which is not a
// softfork (and P2SH should be one).
if ((flags & Interpreter.SCRIPT_VERIFY_P2SH) == 0)
if ((this.flags & Interpreter.SCRIPT_VERIFY_P2SH) == 0)
throw 'flags & SCRIPT_VERIFY_P2SH';

if (stackCopy.length != 1) {
Expand All @@ -301,15 +285,13 @@ console.log('[interpreter.js.282]'); //TODO
}
}

if ((flags & Interpreter.SCRIPT_VERIFY_WITNESS)) {
if ((this.flags & Interpreter.SCRIPT_VERIFY_WITNESS)) {
if (!hadWitness && witness.length > 0) {
this.errstr = 'SCRIPT_ERR_WITNESS_UNEXPECTED';
return false;
}
}



return true;
};

Expand Down Expand Up @@ -415,27 +397,27 @@ Interpreter.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1 << 11);
// support CHECKSEQUENCEVERIFY opcode
//
// See BIP112 for details
Interpreter.SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = (1 << 10),
Interpreter.SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = (1 << 10);

// Signature(s) must be empty vector if an CHECK(MULTI)SIG operation failed
//
Interpreter.SCRIPT_VERIFY_NULLFAIL = (1 << 14),
Interpreter.SCRIPT_VERIFY_NULLFAIL = (1 << 14);

// Public keys in scripts must be compressed
//
Interpreter.SCRIPT_VERIFY_COMPRESSED_PUBKEYTYPE = (1 << 15),
Interpreter.SCRIPT_VERIFY_WITNESS_PUBKEYTYPE = (1 << 15);

// Do we accept signature using SIGHASH_FORKID
//
Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID = (1 << 16),
Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID = (1 << 16);

// Do we accept activate replay protection using a different fork id.
//
Interpreter.SCRIPT_ENABLE_REPLAY_PROTECTION = (1 << 17),
Interpreter.SCRIPT_ENABLE_REPLAY_PROTECTION = (1 << 17);

// Enable new opcodes.
//
Interpreter.SCRIPT_ENABLE_MONOLITH_OPCODES = (1 << 18),
Interpreter.SCRIPT_ENABLE_MONOLITH_OPCODES = (1 << 18);



Expand Down Expand Up @@ -513,6 +495,13 @@ Interpreter.prototype.checkPubkeyEncoding = function(buf) {
this.errstr = 'SCRIPT_ERR_PUBKEYTYPE';
return false;
}

// Only compressed keys are accepted in segwit
if ((this.flags & Interpreter.SCRIPT_VERIFY_WITNESS_PUBKEYTYPE) != 0 && this.sigversion == 1 && !PublicKey.fromBuffer(buf).compressed) {
this.errstr = 'SCRIPT_ERR_WITNESS_PUBKEYTYPE';
return false;
}

return true;
};

Expand Down Expand Up @@ -663,7 +652,6 @@ Interpreter.prototype.checkSequence = function(nSequence) {
* bitcoind commit: b5d1b1092998bc95313856d535c632ea5a8f9104
*/
Interpreter.prototype.step = function() {

var fRequireMinimal = (this.flags & Interpreter.SCRIPT_VERIFY_MINIMALDATA) !== 0;

//bool fExec = !count(vfExec.begin(), vfExec.end(), false);
Expand Down Expand Up @@ -1436,7 +1424,6 @@ Interpreter.prototype.step = function() {

bufSig = this.stack[this.stack.length - 2];
bufPubkey = this.stack[this.stack.length - 1];

if (!this.checkSignatureEncoding(bufSig) || !this.checkPubkeyEncoding(bufPubkey)) {
return false;
}
Expand Down
10 changes: 10 additions & 0 deletions test/script/interpreter.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,15 @@ describe('Interpreter', function() {
flags = flags | Interpreter.SCRIPT_VERIFY_CLEANSTACK;
}

console.log('[interpreter.js.311]', flagstr); //TODO
if (flagstr.indexOf('WITNESS_PUBKEYTYPE') !== -1) {

console.log('[interpreter.js.314] IN!'); //TODO
flags = flags | Interpreter.SCRIPT_VERIFY_WITNESS_PUBKEYTYPE;
}

console.log('ANTES XXX ', flags & Interpreter.SCRIPT_VERIFY_WITNESS_PUBKEYTYPE); //TODO
console.log('[interpreter.js.320:flags:]',flags); //TODO
return flags;
};

Expand Down Expand Up @@ -357,6 +366,7 @@ console.log('[interpreter.js.377:witness:]wit:',witness); //TODO
satoshis: amount,
}));

console.log('[interpreter.js.370:flags:]',flags); //TODO
var interp = new Interpreter();
var verified = interp.verify(scriptSig, scriptPubkey, spendtx, 0, flags, witness, amount);
verified.should.equal(expected);
Expand Down

0 comments on commit 50b4b32

Please sign in to comment.