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

DRY changes and adding support for BIP-239 Extended Transaction Format #130

Merged
merged 14 commits into from Nov 16, 2022
5 changes: 3 additions & 2 deletions bscript/address.go
@@ -1,3 +1,4 @@
// Package bscript comment
package bscript

import (
Expand Down Expand Up @@ -83,7 +84,7 @@ func NewAddressFromPublicKeyHash(hash []byte, mainnet bool) (*Address, error) {
if !mainnet {
bb[0] = 111
}
// nolint: makezero // we need to set up the array with 1
//nolint: makezero // we need to set up the array with 1
bb = append(bb, hash...)

return &Address{
Expand All @@ -105,7 +106,7 @@ func NewAddressFromPublicKey(pubKey *bec.PublicKey, mainnet bool) (*Address, err
if !mainnet {
bb[0] = 111
}
// nolint: makezero // we need to set up the array with 1
//nolint: makezero // we need to set up the array with 1
bb = append(bb, hash...)

return &Address{
Expand Down
18 changes: 10 additions & 8 deletions bscript/interpreter/debug/debugger.go
@@ -1,3 +1,4 @@
// Package debug comment
package debug

import "github.com/libsv/go-bt/v2/bscript/interpreter"
Expand Down Expand Up @@ -66,14 +67,15 @@ type debugger struct {
// functions.
//
// Example usage:
// debugger := debug.NewDebugger()
// debugger.AttachBeforeExecuteOpcode(func (state *interpreter.State) {
// fmt.Println(state.DataStack)
// })
// debugger.AttachAfterStackPush(func (state *interpreter.State, data []byte) {
// fmt.Println(hex.EncodeToString(data))
// })
// engine.Execute(interpreter.WithDebugger(debugger))
//
// debugger := debug.NewDebugger()
// debugger.AttachBeforeExecuteOpcode(func (state *interpreter.State) {
// fmt.Println(state.DataStack)
// })
// debugger.AttachAfterStackPush(func (state *interpreter.State, data []byte) {
// fmt.Println(hex.EncodeToString(data))
// })
// engine.Execute(interpreter.WithDebugger(debugger))
func NewDebugger(oo ...DebuggerOptionFunc) DefaultDebugger {
opts := &debugOpts{}
for _, o := range oo {
Expand Down
16 changes: 8 additions & 8 deletions bscript/interpreter/engine_test.go
Expand Up @@ -122,7 +122,7 @@ func TestCheckErrorCondition(t *testing.T) {
tx: tx,
})
if err != nil {
t.Errorf("failed to configure thread %w", err)
t.Errorf("failed to configure thread %v", err)
}

var done bool
Expand All @@ -132,7 +132,7 @@ func TestCheckErrorCondition(t *testing.T) {
t.Fatalf("failed to step %dth time: %v", i, err)
}
if done && i != len(*lscript)-1 {
t.Fatalf("finshed early on %dth time", i)
t.Fatalf("finished early on %dth time", i)
}
}
err = vm.CheckErrorCondition(false)
Expand Down Expand Up @@ -289,7 +289,7 @@ func TestValidateParams(t *testing.T) {
},
expErr: errors.New("tx and previous output must be supplied for checksig"),
},
"provided locking script that differs from previoustxout's errors": {
"provided locking script that differs from previous txout's errors": {
params: execOpts{
lockingScript: func() *bscript.Script {
script, err := bscript.NewFromHexString("52529387")
Expand Down Expand Up @@ -322,7 +322,7 @@ func TestValidateParams(t *testing.T) {
},
expErr: errors.New("locking script does not match the previous outputs locking script"),
},
"provided unlocking scropt that differs from tx input's errors": {
"provided unlocking script that differs from tx input's errors": {
params: execOpts{
lockingScript: func() *bscript.Script {
script, err := bscript.NewFromHexString("76a91454807ccc44c0eec0b0e187b3ce0e137e9c6cd65d88ac")
Expand Down Expand Up @@ -501,7 +501,7 @@ func TestCheckPubKeyEncoding(t *testing.T) {
"when it should have succeeded: %v", test.name,
err)
} else if err == nil && !test.isValid {
t.Errorf("checkSignatureEncooding test '%s' succeeded "+
t.Errorf("checkSignatureEncoding test '%s' succeeded "+
"when it should have failed", test.name)
}
}
Expand Down Expand Up @@ -673,7 +673,7 @@ func TestCheckSignatureEncoding(t *testing.T) {
"when it should have succeeded: %v", test.name,
err)
} else if err == nil && !test.isValid {
t.Errorf("checkSignatureEncooding test '%s' succeeded "+
t.Errorf("checkSignatureEncoding test '%s' succeeded "+
"when it should have failed", test.name)
}
}
Expand Down Expand Up @@ -845,7 +845,7 @@ func TestEngine_WithState(t *testing.T) {
CondStack: []int{},
ElseStack: [][]byte{},
Flags: scriptflag.UTXOAfterGenesis | scriptflag.EnableSighashForkID,
LastCodeSeperatorIdx: 0,
LastCodeSeparatorIdx: 0,
NumOps: 3,
SavedFirstStack: [][]byte{},
Scripts: func() []ParsedScript {
Expand Down Expand Up @@ -884,7 +884,7 @@ func TestEngine_WithState(t *testing.T) {
CondStack: []int{},
ElseStack: [][]byte{},
Flags: scriptflag.UTXOAfterGenesis | scriptflag.EnableSighashForkID,
LastCodeSeperatorIdx: 0,
LastCodeSeparatorIdx: 0,
NumOps: 8,
SavedFirstStack: [][]byte{},
Scripts: func() []ParsedScript {
Expand Down
9 changes: 5 additions & 4 deletions bscript/interpreter/errs/error.go
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

// Package errs comment
package errs

import (
Expand Down Expand Up @@ -405,10 +406,10 @@ func (e ErrorCode) String() string {

// Error identifies a script-related error. It is used to indicate three
// classes of errors:
// 1) Script execution failures due to violating one of the many requirements
// imposed by the script engine or evaluating to false
// 2) Improper API usage by callers
// 3) Internal consistency check failures
// 1. Script execution failures due to violating one of the many requirements
// imposed by the script engine or evaluating to false
// 2. Improper API usage by callers
// 3. Internal consistency check failures
//
// The caller can use type assertions on the returned errors to access the
// ErrorCode field to ascertain the specific reason for the error. As an
Expand Down
2 changes: 1 addition & 1 deletion bscript/interpreter/operations.go
Expand Up @@ -1836,7 +1836,7 @@ func opcodeSha1(op *ParsedOpcode, t *thread) error {
return err
}

hash := sha1.Sum(buf) // nolint:gosec // operation is for sha1
hash := sha1.Sum(buf) //nolint:gosec // operation is for sha1
t.dstack.PushByteArray(hash[:])
return nil
}
Expand Down
1 change: 1 addition & 0 deletions bscript/interpreter/scriptflag/scriptflag.go
@@ -1,3 +1,4 @@
// Package scriptflag comment
package scriptflag

// Flag is a bitmask defining additional operations or tests that will be
Expand Down
6 changes: 3 additions & 3 deletions bscript/interpreter/state.go
Expand Up @@ -12,7 +12,7 @@ type State struct {
Scripts []ParsedScript
ScriptIdx int
OpcodeIdx int
LastCodeSeperatorIdx int
LastCodeSeparatorIdx int
NumOps int
Flags scriptflag.Flag
IsFinished bool
Expand Down Expand Up @@ -66,7 +66,7 @@ func (t *thread) State() *State {
Scripts: make([]ParsedScript, len(t.scripts)),
ScriptIdx: scriptIdx,
OpcodeIdx: offsetIdx,
LastCodeSeperatorIdx: t.lastCodeSep,
LastCodeSeparatorIdx: t.lastCodeSep,
NumOps: t.numOps,
Flags: t.flags,
IsFinished: t.scriptIdx > scriptIdx,
Expand Down Expand Up @@ -127,7 +127,7 @@ func (t *thread) SetState(state *State) {
t.scripts = state.Scripts
t.scriptIdx = state.ScriptIdx
t.scriptOff = state.OpcodeIdx
t.lastCodeSep = state.LastCodeSeperatorIdx
t.lastCodeSep = state.LastCodeSeparatorIdx
t.numOps = state.NumOps
t.flags = state.Flags
t.afterGenesis = state.Genesis.AfterGenesis
Expand Down
23 changes: 21 additions & 2 deletions bscript/script.go
Expand Up @@ -233,13 +233,32 @@ func (s *Script) ToASM() (string, error) {
parts, err := DecodeParts(*s)
// if err != nil, we will append [error] to the ASM script below (as done in the node).

data := false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
data := false
data := len(*s) > 1 && ((*s)[0] == OpRETURN || ((*s)[0] == OpFALSE && (*s)[1] == OpRETURN))

if len(*s) > 1 && ((*s)[0] == 0x6a || ((*s)[0] == 0x00 && (*s)[1] == 0x6a)) {
ordishs marked this conversation as resolved.
Show resolved Hide resolved
data = true
}

var asm strings.Builder

for _, p := range parts {
asm.WriteRune(' ')
if len(p) == 1 {
asm.WriteString(opCodeValues[p[0]])
if data && p[0] != 0x6a {
asm.WriteString(fmt.Sprintf("%d", p[0]))
} else {
asm.WriteString(opCodeValues[p[0]])
}
} else {
asm.WriteString(hex.EncodeToString(p))
if data && len(p) <= 4 {
b := make([]byte, 0)
b = append(b, p...)
for i := 0; i < 4-len(p); i++ {
b = append(b, 0)
}
asm.WriteString(fmt.Sprintf("%d", binary.LittleEndian.Uint32(b)))
} else {
asm.WriteString(hex.EncodeToString(p))
}
}
}

Expand Down
50 changes: 50 additions & 0 deletions bscript/script_test.go
Expand Up @@ -514,3 +514,53 @@ func TestScript_UnmarshalJSON(t *testing.T) {
})
}
}

func TestRunScriptExample1(t *testing.T) {
ordishs marked this conversation as resolved.
Show resolved Hide resolved
script, _ := hex.DecodeString("006a2231394878696756345179427633744870515663554551797131707a5a56646f4175744d7301e4b8bbe381aa54574954544552e381a8425356e381ae547765746368e381a7e381aee98195e381840a547765746368e381a7e381afe887aae58886e381aee69bb8e38184e3819fe38384e382a8e383bce38388e381afe4b880e795aae69c80e5889de381bee381a70ae38195e3818be381aee381bce381a3e381a6e38184e381a4e381a7e38282e7a2bae8aa8de58fafe883bde381a7e8aaade381bfe8bebce381bfe381a7e995b7e69982e996930ae5819ce6ada2e381afe38182e3828ae381bee3819be38293e380825954e383aae383b3e382afe381aee58b95e794bbe38292e8a696e881b4e38197e3819fe5a0b4e590880ae99fb3e6a5bde381afe382b9e382afe383ade383bce383abe38197e381a6e38282e98094e58887e3828ce3819ae881b4e38193e38188e3819fe381bee381be0ae38384e382a4e38383e382bfe383bce381afe69c80e5889de381aee383ace382b9e381bee381a7e8a18ce38191e381aae38184e381a7e38197e38287e380820a746578742f706c61696e04746578741f7477657463685f7477746578745f313634343834393439353138332e747874017c223150755161374b36324d694b43747373534c4b79316b683536575755374d74555235035345540b7477646174615f6a736f6e046e756c6c0375726c046e756c6c07636f6d6d656e74046e756c6c076d625f757365720439373038057265706c794035366462363536376363306230663539316265363561396135313731663533396635316334333165643837356464326136373431643733353061353539363762047479706504706f73740974696d657374616d70046e756c6c036170700674776574636807696e766f6963652461366637336133312d336334342d346164612d393937352d386537386261666661623765017c22313550636948473232534e4c514a584d6f53556157566937575371633768436676610d424954434f494e5f454344534122314c6970354b335671677743415662674d7842536547434d344355364e344e6b75744c58494b4b554a35765a7753336b4c456e353749356a36485a2b43325733393834314e543532334a4c374534387655706d6f57306b4677613767392b51703246434f4d42776a556a7a76454150624252784d496a746c6b476b3d")
s := bscript.Script(script)

asm, err := s.ToASM()
if err != nil {
t.Error(err)
t.FailNow()
}

expected := "0 OP_RETURN 31394878696756345179427633744870515663554551797131707a5a56646f417574 e4b8bbe381aa54574954544552e381a8425356e381ae547765746368e381a7e381aee98195e381840a547765746368e381a7e381afe887aae58886e381aee69bb8e38184e3819fe38384e382a8e383bce38388e381afe4b880e795aae69c80e5889de381bee381a70ae38195e3818be381aee381bce381a3e381a6e38184e381a4e381a7e38282e7a2bae8aa8de58fafe883bde381a7e8aaade381bfe8bebce381bfe381a7e995b7e69982e996930ae5819ce6ada2e381afe38182e3828ae381bee3819be38293e380825954e383aae383b3e382afe381aee58b95e794bbe38292e8a696e881b4e38197e3819fe5a0b4e590880ae99fb3e6a5bde381afe382b9e382afe383ade383bce383abe38197e381a6e38282e98094e58887e3828ce3819ae881b4e38193e38188e3819fe381bee381be0ae38384e382a4e38383e382bfe383bce381afe69c80e5889de381aee383ace382b9e381bee381a7e8a18ce38191e381aae38184e381a7e38197e38287e38082 746578742f706c61696e 1954047348 7477657463685f7477746578745f313634343834393439353138332e747874 124 3150755161374b36324d694b43747373534c4b79316b683536575755374d74555235 5522771 7477646174615f6a736f6e 1819047278 7107189 1819047278 636f6d6d656e74 1819047278 6d625f75736572 942683961 7265706c79 35366462363536376363306230663539316265363561396135313731663533396635316334333165643837356464326136373431643733353061353539363762 1701869940 1953722224 74696d657374616d70 1819047278 7368801 747765746368 696e766f696365 61366637336133312d336334342d346164612d393937352d386537386261666661623765 124 313550636948473232534e4c514a584d6f5355615756693757537163376843667661 424954434f494e5f4543445341 314c6970354b335671677743415662674d7842536547434d344355364e344e6b7574 494b4b554a35765a7753336b4c456e353749356a36485a2b43325733393834314e543532334a4c374534387655706d6f57306b4677613767392b51703246434f4d42776a556a7a76454150624252784d496a746c6b476b3d"

if asm != expected {
t.Errorf("\nExpected %q\ngot %q", expected, asm)
}

}

func TestRunScriptExample2(t *testing.T) {
script, _ := hex.DecodeString("006a0372756e01050c63727970746f6669676874734d16057b22696e223a312c22726566223a5b22343561666530303862396634393663333130356663396132636234373234316565643566646531333531303532616339353938323531636666623939376136385f6f31222c22643335343933633964313266656538363134313663333366653336346662336566373531363234373532313833316264623232303933333731303330383663325f6f31222c22306338623636326339363862316537376164626535666161653566666436633033653537353965373833376132353534653438643561356535326335346634385f6f31222c22336136376365633363313662646238343762393732626565326663316330373137633539656463616537626635663438633931666563636661363335616633335f6f31222c22313465323738633638666635323165303931366164376337313361653461303135366537363336316462643362326233353764666236303238653064636137615f6f31222c22613738663561366437326637383731316536366336323131666262643061306266643135616439316264643030343034393238613966616363363364613664395f6f31222c22373535633932326336366363656533353766356265656437383164323631336634313739346230323839333963333435316466653438393032303238343263355f6f31222c22316661333532383030333363343534663465313263323134383333343436643335313734663031666565373064346639653633366664393462363237316436325f6f31222c22636233356534656361336635616334303561636261636464383632346366303835636333626535336639323633663531616565373037393234616265316237385f6f31222c22373166626133383633343162393332333830656335626665646333613430626365343364343937346465636463393463343139613934613863653564666332335f6f31222c22363161653132323165646438626431646438336332326461326232616237643131346139313239363439366365336664306562613737333236623638613238335f6f31222c22386462643166643638373934353131636364616338333938333136393638306662616338356233613961626439636166366361326666343839633862313633385f6f31222c22386564316564633665656439386135326635373234396333353032663266333764623561336666356233643135613930363732353063383465363035366531315f6f31222c22343062396534373865333766383733636532386364383162666635323532346631383063623538353837376331656139383636343933383039363363646237385f6f31225d2c226f7574223a5b2262633038643265323932623036313031323463313337656361356566393632383464363534363139616162366630313461333932353532613066336339666162225d2c2264656c223a5b5d2c22637265223a5b5d2c2265786563223a5b7b226f70223a2243414c4c222c2264617461223a5b7b22246a6967223a307d2c227265736f6c7665222c5b2263633031363466343332613563383635306331393731376430373161656561646261393065643761303939386234396464656535663537316430323139373032222c313634373630333734373833342c302c2230336339386161663266623237393930613130356364336362616462656461383536613064363238343262666564633430353730343966636232343163333563222c5b302c302c305d5d5d7d5d7d")
s := bscript.Script(script)

asm, err := s.ToASM()
if err != nil {
t.Error(err)
t.FailNow()
}

expected := "0 OP_RETURN 7239026 5 63727970746f666967687473 7b22696e223a312c22726566223a5b22343561666530303862396634393663333130356663396132636234373234316565643566646531333531303532616339353938323531636666623939376136385f6f31222c22643335343933633964313266656538363134313663333366653336346662336566373531363234373532313833316264623232303933333731303330383663325f6f31222c22306338623636326339363862316537376164626535666161653566666436633033653537353965373833376132353534653438643561356535326335346634385f6f31222c22336136376365633363313662646238343762393732626565326663316330373137633539656463616537626635663438633931666563636661363335616633335f6f31222c22313465323738633638666635323165303931366164376337313361653461303135366537363336316462643362326233353764666236303238653064636137615f6f31222c22613738663561366437326637383731316536366336323131666262643061306266643135616439316264643030343034393238613966616363363364613664395f6f31222c22373535633932326336366363656533353766356265656437383164323631336634313739346230323839333963333435316466653438393032303238343263355f6f31222c22316661333532383030333363343534663465313263323134383333343436643335313734663031666565373064346639653633366664393462363237316436325f6f31222c22636233356534656361336635616334303561636261636464383632346366303835636333626535336639323633663531616565373037393234616265316237385f6f31222c22373166626133383633343162393332333830656335626665646333613430626365343364343937346465636463393463343139613934613863653564666332335f6f31222c22363161653132323165646438626431646438336332326461326232616237643131346139313239363439366365336664306562613737333236623638613238335f6f31222c22386462643166643638373934353131636364616338333938333136393638306662616338356233613961626439636166366361326666343839633862313633385f6f31222c22386564316564633665656439386135326635373234396333353032663266333764623561336666356233643135613930363732353063383465363035366531315f6f31222c22343062396534373865333766383733636532386364383162666635323532346631383063623538353837376331656139383636343933383039363363646237385f6f31225d2c226f7574223a5b2262633038643265323932623036313031323463313337656361356566393632383464363534363139616162366630313461333932353532613066336339666162225d2c2264656c223a5b5d2c22637265223a5b5d2c2265786563223a5b7b226f70223a2243414c4c222c2264617461223a5b7b22246a6967223a307d2c227265736f6c7665222c5b2263633031363466343332613563383635306331393731376430373161656561646261393065643761303939386234396464656535663537316430323139373032222c313634373630333734373833342c302c2230336339386161663266623237393930613130356364336362616462656461383536613064363238343262666564633430353730343966636232343163333563222c5b302c302c305d5d5d7d5d7d"
if asm != expected {
t.Errorf("\nExpected %q\ngot %q", expected, asm)
}
}

func TestRunScriptExample3(t *testing.T) {
script, _ := hex.DecodeString("006a223139694733575459537362796f7333754a373333794b347a45696f69314665734e55010042666166383166326364346433663239383061623162363564616166656231656631333561626339643534386461633466366134656361623230653033656365362d300274780134")
s := bscript.Script(script)

asm, err := s.ToASM()
if err != nil {
t.Error(err)
t.FailNow()
}

expected := "0 OP_RETURN 3139694733575459537362796f7333754a373333794b347a45696f69314665734e55 0 666166383166326364346433663239383061623162363564616166656231656631333561626339643534386461633466366134656361623230653033656365362d30 30836 52"
if asm != expected {
t.Errorf("\nExpected %q\ngot %q", expected, asm)
}
}
4 changes: 2 additions & 2 deletions examples/read_txs_from_block/read_txs_from_block.go
Expand Up @@ -12,7 +12,7 @@ import (
// In this example, all txs from a block are being read in via chunking, so at no point
// does the entire block have to be held in memory, and instead can be streamed.
//
// We represent the block by interatively reading a file, however it could be any data
// We represent the block by interactively reading a file, however it could be any data
// stream that satisfies the io.Reader interface.

func main() {
Expand All @@ -27,7 +27,7 @@ func main() {
r := bufio.NewReader(f)

// Read file header. This step is specific to file reading and
// may need omitted or modified for other implentations.
// may need omitted or modified for other implementations.
_, err = io.ReadFull(f, make([]byte, 80))
if err != nil {
panic(err)
Expand Down