txscript: Expose AddOps on ScriptBuilder. (#734)
This exposes a new function on the ScriptBuilder type named AddOps that allows multiple opcodes to be added via a single call and adds tests to exercise the new function. Finally, it updates a couple of places in the signing code that were abusing the interface by setting its private script directly to use the new public function instead.
This commit is contained in:
parent
fb9b640ef2
commit
cee207c64c
3 changed files with 44 additions and 4 deletions
|
@ -73,6 +73,27 @@ func (b *ScriptBuilder) AddOp(opcode byte) *ScriptBuilder {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddOps pushes the passed opcodes to the end of the script. The script will
|
||||||
|
// not be modified if pushing the opcodes would cause the script to exceed the
|
||||||
|
// maximum allowed script engine size.
|
||||||
|
func (b *ScriptBuilder) AddOps(opcodes []byte) *ScriptBuilder {
|
||||||
|
if b.err != nil {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pushes that would cause the script to exceed the largest allowed
|
||||||
|
// script size would result in a non-canonical script.
|
||||||
|
if len(b.script)+len(opcodes) > maxScriptSize {
|
||||||
|
str := fmt.Sprintf("adding opcodes would exceed the maximum "+
|
||||||
|
"allowed canonical script length of %d", maxScriptSize)
|
||||||
|
b.err = ErrScriptNotCanonical(str)
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
b.script = append(b.script, opcodes...)
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
// canonicalDataSize returns the number of bytes the canonical encoding of the
|
// canonicalDataSize returns the number of bytes the canonical encoding of the
|
||||||
// data will take.
|
// data will take.
|
||||||
func canonicalDataSize(data []byte) int {
|
func canonicalDataSize(data []byte) int {
|
||||||
|
|
|
@ -38,6 +38,7 @@ func TestScriptBuilderAddOp(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run tests and individually add each op via AddOp.
|
||||||
builder := txscript.NewScriptBuilder()
|
builder := txscript.NewScriptBuilder()
|
||||||
t.Logf("Running %d tests", len(tests))
|
t.Logf("Running %d tests", len(tests))
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
|
@ -58,6 +59,25 @@ func TestScriptBuilderAddOp(t *testing.T) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run tests and bulk add ops via AddOps.
|
||||||
|
t.Logf("Running %d tests", len(tests))
|
||||||
|
for i, test := range tests {
|
||||||
|
builder.Reset()
|
||||||
|
result, err := builder.AddOps(test.opcodes).Script()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("ScriptBuilder.AddOps #%d (%s) unexpected "+
|
||||||
|
"error: %v", i, test.name, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !bytes.Equal(result, test.expected) {
|
||||||
|
t.Errorf("ScriptBuilder.AddOps #%d (%s) wrong result\n"+
|
||||||
|
"got: %x\nwant: %x", i, test.name, result,
|
||||||
|
test.expected)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestScriptBuilderAddInt64 tests that pushing signed integers to a script via
|
// TestScriptBuilderAddInt64 tests that pushing signed integers to a script via
|
||||||
|
|
|
@ -203,7 +203,7 @@ func mergeScripts(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int,
|
||||||
|
|
||||||
// Reappend the script and return the result.
|
// Reappend the script and return the result.
|
||||||
builder := NewScriptBuilder()
|
builder := NewScriptBuilder()
|
||||||
builder.script = mergedScript
|
builder.AddOps(mergedScript)
|
||||||
builder.AddData(script)
|
builder.AddData(script)
|
||||||
finalScript, _ := builder.Script()
|
finalScript, _ := builder.Script()
|
||||||
return finalScript
|
return finalScript
|
||||||
|
@ -394,10 +394,9 @@ func SignTxOutput(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int,
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a bad thing. Append the p2sh script as the last
|
// Append the p2sh script as the last push in the script.
|
||||||
// push in the script.
|
|
||||||
builder := NewScriptBuilder()
|
builder := NewScriptBuilder()
|
||||||
builder.script = realSigScript
|
builder.AddOps(realSigScript)
|
||||||
builder.AddData(sigScript)
|
builder.AddData(sigScript)
|
||||||
|
|
||||||
sigScript, _ = builder.Script()
|
sigScript, _ = builder.Script()
|
||||||
|
|
Loading…
Reference in a new issue