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

Add wire.Outpoint parser from string #1879

Merged
merged 2 commits into from
May 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions wire/msgtx.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ package wire

import (
"bytes"
"errors"
"fmt"
"io"
"strconv"
"strings"

"github.com/btcsuite/btcd/chaincfg/chainhash"
)
Expand Down Expand Up @@ -215,6 +217,29 @@ func NewOutPoint(hash *chainhash.Hash, index uint32) *OutPoint {
}
}

// NewOutPointFromString returns a new bitcoin transaction outpoint parsed from
// the provided string, which should be in the format "hash:index".
func NewOutPointFromString(outpoint string) (*OutPoint, error) {
parts := strings.Split(outpoint, ":")
if len(parts) != 2 {
return nil, errors.New("outpoint should be of the form txid:index")
}
hash, err := chainhash.NewHashFromStr(parts[0])
if err != nil {
return nil, err
}

outputIndex, err := strconv.ParseUint(parts[1], 10, 32)
if err != nil {
return nil, fmt.Errorf("invalid output index: %v", err)
}

return &OutPoint{
Hash: *hash,
Index: uint32(outputIndex),
}, nil
}

// String returns the OutPoint in the human-readable form "hash:index".
func (o OutPoint) String() string {
// Allocate enough for hash string, colon, and 10 digits. Although
Expand Down
71 changes: 71 additions & 0 deletions wire/msgtx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/davecgh/go-spew/spew"
"github.com/stretchr/testify/require"
)

// TestTx tests the MsgTx API.
Expand Down Expand Up @@ -778,6 +779,76 @@ func TestTxWitnessSize(t *testing.T) {
}
}

// TestTxOutPointFromString performs tests to ensure that the outpoint string
// parser works as expected.
func TestTxOutPointFromString(t *testing.T) {
hashFromStr := func(hash string) chainhash.Hash {
h, _ := chainhash.NewHashFromStr(hash)
return *h
}

tests := []struct {
name string
input string
result *OutPoint
err bool
}{
{
name: "normal outpoint 1",
input: "2ebd15a7e758d5f4c7c74181b99e5b8586f88e0682dc13e09d92612a2b2bb0a2:1",
result: &OutPoint{
Hash: hashFromStr("2ebd15a7e758d5f4c7c74181b99e5b8586f88e0682dc13e09d92612a2b2bb0a2"),
Index: 1,
},
err: false,
},
{
name: "normal outpoint 2",
input: "94c7762a68ff164352bd31fd95fa875204e811c09acef40ba781787eb28e3b55:42",
result: &OutPoint{
Hash: hashFromStr("94c7762a68ff164352bd31fd95fa875204e811c09acef40ba781787eb28e3b55"),
Index: 42,
},
err: false,
},
{
name: "big index outpoint",
input: "94c7762a68ff164352bd31fd95fa875204e811c09acef40ba781787eb28e3b55:2147484242",
result: &OutPoint{
Hash: hashFromStr("94c7762a68ff164352bd31fd95fa875204e811c09acef40ba781787eb28e3b55"),
Index: 2147484242,
},
err: false,
},
{
name: "bad string",
input: "not_outpoint_not_outpoint_not_outpoint",
result: nil,
err: true,
},
{
name: "empty string",
input: "",
result: nil,
err: true,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
outpoint, err := NewOutPointFromString(test.input)

isErr := (err != nil)
require.Equal(t, isErr, test.err)

if !isErr {
require.Equal(t, test.result, outpoint)
}
})

}
}

// multiTx is a MsgTx with an input and output and used in various tests.
var multiTx = &MsgTx{
Version: 1,
Expand Down