From f0aa186a56e10a56b95a0924384d6055b20def6d Mon Sep 17 00:00:00 2001 From: Philip Hayes Date: Sun, 7 May 2017 03:34:00 -0700 Subject: [PATCH] channeldb+utxonursery+lnwire: use lnwire's OutPoint,TxOut serialization --- chainntnfs/btcdnotify/btcd.go | 2 +- channeldb/channel.go | 76 ++++++++++------------------------- channeldb/db.go | 6 +-- channeldb/graph.go | 14 +++---- lnwire/lnwire.go | 41 +------------------ lnwire/outpoint.go | 59 +++++++++++++++++++++++++++ lnwire/outpoint_test.go | 40 ++++++++++++++++++ lnwire/txout.go | 46 +++++++++++++++++++++ lnwire/txout_test.go | 46 +++++++++++++++++++++ utxonursery.go | 76 +++-------------------------------- 10 files changed, 232 insertions(+), 174 deletions(-) create mode 100644 lnwire/outpoint.go create mode 100644 lnwire/outpoint_test.go create mode 100644 lnwire/txout.go create mode 100644 lnwire/txout_test.go diff --git a/chainntnfs/btcdnotify/btcd.go b/chainntnfs/btcdnotify/btcd.go index 365c05f9..70fdc186 100644 --- a/chainntnfs/btcdnotify/btcd.go +++ b/chainntnfs/btcdnotify/btcd.go @@ -567,7 +567,7 @@ func (b *BtcdNotifier) checkConfirmationTrigger(txSha *chainhash.Hash, if confClients, ok := b.confNotifications[*txSha]; ok { // Either all of the registered confirmations will be // dispatched due to a single confirmation, or added to the - // conf head. Therefor we unconditionally delete the registered + // conf head. Therefore we unconditionally delete the registered // confirmations from the staging zone. defer func() { delete(b.confNotifications, *txSha) diff --git a/channeldb/channel.go b/channeldb/channel.go index 6640db30..b44375ca 100644 --- a/channeldb/channel.go +++ b/channeldb/channel.go @@ -380,7 +380,7 @@ func (c *OpenChannel) fullSync(tx *bolt.Tx) error { return err } var b bytes.Buffer - if err := writeOutpoint(&b, &c.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, c.ChanID); err != nil { return err } if chanIndexBucket.Get(b.Bytes()) == nil { @@ -871,7 +871,7 @@ func (c *OpenChannel) CloseChannel(summary *ChannelCloseSummary) error { } var b bytes.Buffer - if err := writeOutpoint(&b, &c.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, c.ChanID); err != nil { return err } @@ -982,7 +982,7 @@ func serializeChannelCloseSummary(w io.Writer, cs *ChannelCloseSummary) error { return err } - if err := writeOutpoint(w, &cs.ChanPoint); err != nil { + if err := lnwire.WriteOutPoint(w, &cs.ChanPoint); err != nil { return err } if _, err := w.Write(cs.ClosingTXID[:]); err != nil { @@ -1037,7 +1037,7 @@ func deserializeCloseChannelSummary(r io.Reader) (*ChannelCloseSummary, error) { return nil, err } - if err := readOutpoint(r, &c.ChanPoint); err != nil { + if err := lnwire.ReadOutPoint(r, &c.ChanPoint); err != nil { return nil, err } if _, err := io.ReadFull(r, c.ClosingTXID[:]); err != nil { @@ -1245,7 +1245,7 @@ func putChanCapacity(openChanBucket *bolt.Bucket, channel *OpenChannel) error { scratch3 := make([]byte, 8) var b bytes.Buffer - if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, channel.ChanID); err != nil { return err } @@ -1290,7 +1290,7 @@ func deleteChanCapacity(openChanBucket *bolt.Bucket, chanID []byte) error { func fetchChanCapacity(openChanBucket *bolt.Bucket, channel *OpenChannel) error { // A byte slice re-used to compute each key prefix below. var b bytes.Buffer - if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, channel.ChanID); err != nil { return err } @@ -1317,7 +1317,7 @@ func putChanFeePerKw(openChanBucket *bolt.Bucket, channel *OpenChannel) error { byteOrder.PutUint64(scratch, uint64(channel.FeePerKw)) var b bytes.Buffer - if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, channel.ChanID); err != nil { return err } @@ -1337,7 +1337,7 @@ func deleteChanMinFeePerKw(openChanBucket *bolt.Bucket, chanID []byte) error { func fetchChanMinFeePerKw(openChanBucket *bolt.Bucket, channel *OpenChannel) error { var b bytes.Buffer - if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, channel.ChanID); err != nil { return err } @@ -1356,7 +1356,7 @@ func putChanNumUpdates(openChanBucket *bolt.Bucket, channel *OpenChannel) error byteOrder.PutUint64(scratch, channel.NumUpdates) var b bytes.Buffer - if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, channel.ChanID); err != nil { return err } @@ -1376,7 +1376,7 @@ func deleteChanNumUpdates(openChanBucket *bolt.Bucket, chanID []byte) error { func fetchChanNumUpdates(openChanBucket *bolt.Bucket, channel *OpenChannel) error { var b bytes.Buffer - if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, channel.ChanID); err != nil { return err } @@ -1395,7 +1395,7 @@ func putChanAmountsTransferred(openChanBucket *bolt.Bucket, channel *OpenChannel scratch2 := make([]byte, 8) var b bytes.Buffer - if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, channel.ChanID); err != nil { return err } @@ -1428,7 +1428,7 @@ func deleteChanAmountsTransferred(openChanBucket *bolt.Bucket, chanID []byte) er func fetchChanAmountsTransferred(openChanBucket *bolt.Bucket, channel *OpenChannel) error { var b bytes.Buffer - if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, channel.ChanID); err != nil { return err } @@ -1450,7 +1450,7 @@ func putChanIsPending(openChanBucket *bolt.Bucket, channel *OpenChannel) error { scratch := make([]byte, 2) var b bytes.Buffer - if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, channel.ChanID); err != nil { return err } @@ -1476,7 +1476,7 @@ func deleteChanIsPending(openChanBucket *bolt.Bucket, chanID []byte) error { func fetchChanIsPending(openChanBucket *bolt.Bucket, channel *OpenChannel) error { var b bytes.Buffer - if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, channel.ChanID); err != nil { return err } @@ -1541,7 +1541,7 @@ func deleteChanConfInfo(openChanBucket *bolt.Bucket, chanID []byte) error { func putChannelIDs(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error { // TODO(roasbeef): just pass in chanID everywhere for puts var b bytes.Buffer - if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, channel.ChanID); err != nil { return err } @@ -1568,7 +1568,7 @@ func fetchChannelIDs(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error { b bytes.Buffer ) - if err = writeOutpoint(&b, &channel.FundingOutpoint); err != nil { + if err = lnwire.WriteOutPoint(&b, channel.ChanID); err != nil { return err } @@ -1604,7 +1604,7 @@ func putChanCommitFee(openChanBucket *bolt.Bucket, channel *OpenChannel) error { func fetchChanCommitFee(openChanBucket *bolt.Bucket, channel *OpenChannel) error { var b bytes.Buffer - if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutpoint(&b, &channel.FundingOutpoint); err != nil { return err } @@ -1628,7 +1628,7 @@ func deleteChanCommitFee(openChanBucket *bolt.Bucket, chanID []byte) error { func putChanCommitTxns(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error { var bc bytes.Buffer - if err := writeOutpoint(&bc, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutpoint(&bc, &channel.FundingOutpoint); err != nil { return err } txnsKey := make([]byte, len(commitTxnsKey)+bc.Len()) @@ -1658,7 +1658,7 @@ func deleteChanCommitTxns(nodeChanBucket *bolt.Bucket, chanID []byte) error { func fetchChanCommitTxns(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error { var bc bytes.Buffer var err error - if err = writeOutpoint(&bc, &channel.FundingOutpoint); err != nil { + if err = lnwire.WriteOutPoint(&bc, channel.ChanID); err != nil { return err } txnsKey := make([]byte, len(commitTxnsKey)+bc.Len()) @@ -1745,7 +1745,7 @@ func putChanConfigs(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error { func fetchChanConfigs(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error { var bc bytes.Buffer - if err := writeOutpoint(&bc, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&bc, channel.ChanID); err != nil { return err } configKey := make([]byte, len(chanConfigPrefix)+len(bc.Bytes())) @@ -1885,7 +1885,7 @@ func deleteChanFundingInfo(nodeChanBucket *bolt.Bucket, chanID []byte) error { func fetchChanFundingInfo(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error { var b bytes.Buffer - if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, channel.ChanID); err != nil { return err } fundTxnKey := make([]byte, len(fundingTxnKey)+b.Len()) @@ -1971,7 +1971,7 @@ func deleteChanRevocationState(nodeChanBucket *bolt.Bucket, chanID []byte) error func fetchChanRevocationState(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error { var b bytes.Buffer - if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, channel.ChanID); err != nil { return err } preimageKey := make([]byte, len(revocationStateKey)+b.Len()) @@ -2316,38 +2316,6 @@ func wipeChannelLogEntries(log *bolt.Bucket, o *wire.OutPoint) error { return nil } -func writeOutpoint(w io.Writer, o *wire.OutPoint) error { - // TODO(roasbeef): make all scratch buffers on the stack - scratch := make([]byte, 4) - - // TODO(roasbeef): write raw 32 bytes instead of wasting the extra - // byte. - if err := wire.WriteVarBytes(w, 0, o.Hash[:]); err != nil { - return err - } - - byteOrder.PutUint32(scratch, o.Index) - _, err := w.Write(scratch) - return err -} - -func readOutpoint(r io.Reader, o *wire.OutPoint) error { - scratch := make([]byte, 4) - - txid, err := wire.ReadVarBytes(r, 0, 32, "prevout") - if err != nil { - return err - } - copy(o.Hash[:], txid) - - if _, err := r.Read(scratch); err != nil { - return err - } - o.Index = byteOrder.Uint32(scratch) - - return nil -} - func writeBool(w io.Writer, b bool) error { boolByte := byte(0x01) if !b { diff --git a/channeldb/db.go b/channeldb/db.go index 59c77f04..8a3c84d3 100644 --- a/channeldb/db.go +++ b/channeldb/db.go @@ -269,7 +269,7 @@ func (d *DB) fetchNodeChannels(openChanBucket, outBytes := bytes.NewReader(k) chanID := &wire.OutPoint{} - if err := readOutpoint(outBytes, chanID); err != nil { + if err := lnwire.ReadOutPoint(outBytes, chanID); err != nil { return err } @@ -373,7 +373,7 @@ func (d *DB) MarkChannelAsOpen(outpoint *wire.OutPoint, // Generate the database key, which will consist of the // IsPending prefix followed by the channel's outpoint. var b bytes.Buffer - if err := writeOutpoint(&b, outpoint); err != nil { + if err := lnwire.WriteOutPoint(&b, outpoint); err != nil { return err } keyPrefix := make([]byte, 3+b.Len()) @@ -455,7 +455,7 @@ func (d *DB) FetchClosedChannels(pendingOnly bool) ([]*ChannelCloseSummary, erro func (d *DB) MarkChanFullyClosed(chanPoint *wire.OutPoint) error { return d.Update(func(tx *bolt.Tx) error { var b bytes.Buffer - if err := writeOutpoint(&b, chanPoint); err != nil { + if err := lnwire.WriteOutPoint(&b, chanPoint); err != nil { return err } diff --git a/channeldb/graph.go b/channeldb/graph.go index 711f817f..a8e95364 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -456,7 +456,7 @@ func (c *ChannelGraph) AddChannelEdge(edge *ChannelEdgeInfo) error { // Finally we add it to the channel index which maps channel // points (outpoints) to the shorter channel ID's. var b bytes.Buffer - if err := writeOutpoint(&b, &edge.ChannelPoint); err != nil { + if err := lnwire.WriteOutPoint(&b, &edge.ChannelPoint); err != nil { return err } return chanIndex.Put(b.Bytes(), chanKey[:]) @@ -600,7 +600,7 @@ func (c *ChannelGraph) PruneGraph(spentOutputs []*wire.OutPoint, // if NOT if filter var opBytes bytes.Buffer - if err := writeOutpoint(&opBytes, chanPoint); err != nil { + if err := lnwire.WriteOutPoint(&opBytes, chanPoint); err != nil { return nil } @@ -724,7 +724,7 @@ func (c *ChannelGraph) ChannelID(chanPoint *wire.OutPoint) (uint64, error) { var chanID uint64 var b bytes.Buffer - if err := writeOutpoint(&b, chanPoint); err != nil { + if err := lnwire.WriteOutPoint(&b, chanPoint); err != nil { return 0, nil } @@ -756,7 +756,7 @@ func (c *ChannelGraph) ChannelID(chanPoint *wire.OutPoint) (uint64, error) { func delChannelByEdge(edges *bolt.Bucket, edgeIndex *bolt.Bucket, chanIndex *bolt.Bucket, chanPoint *wire.OutPoint) error { var b bytes.Buffer - if err := writeOutpoint(&b, chanPoint); err != nil { + if err := lnwire.WriteOutPoint(&b, chanPoint); err != nil { return err } @@ -1271,7 +1271,7 @@ func (c *ChannelGraph) FetchChannelEdgesByOutpoint(op *wire.OutPoint) (*ChannelE return err } var b bytes.Buffer - if err := writeOutpoint(&b, op); err != nil { + if err := lnwire.WriteOutPoint(&b, op); err != nil { return err } chanID := chanIndex.Get(b.Bytes()) @@ -1692,7 +1692,7 @@ func putChanEdgeInfo(edgeIndex *bolt.Bucket, edgeInfo *ChannelEdgeInfo, chanID [ return err } - if err := writeOutpoint(&b, &edgeInfo.ChannelPoint); err != nil { + if err := lnwire.WriteOutPoint(&b, &edgeInfo.ChannelPoint); err != nil { return err } if err := binary.Write(&b, byteOrder, uint64(edgeInfo.Capacity)); err != nil { @@ -1794,7 +1794,7 @@ func deserializeChanEdgeInfo(r io.Reader) (*ChannelEdgeInfo, error) { } edgeInfo.ChannelPoint = wire.OutPoint{} - if err := readOutpoint(r, &edgeInfo.ChannelPoint); err != nil { + if err := lnwire.ReadOutPoint(r, &edgeInfo.ChannelPoint); err != nil { return nil, err } if err := binary.Read(r, byteOrder, &edgeInfo.Capacity); err != nil { diff --git a/lnwire/lnwire.go b/lnwire/lnwire.go index 8cf8b07c..98bc1042 100644 --- a/lnwire/lnwire.go +++ b/lnwire/lnwire.go @@ -4,13 +4,11 @@ import ( "encoding/binary" "fmt" "io" - "math" "net" "github.com/go-errors/errors" "github.com/roasbeef/btcd/btcec" - "github.com/roasbeef/btcd/chaincfg/chainhash" "github.com/roasbeef/btcd/wire" "github.com/roasbeef/btcutil" ) @@ -189,21 +187,7 @@ func writeElement(w io.Writer, element interface{}) error { } case wire.OutPoint: - var h [32]byte - copy(h[:], e.Hash[:]) - if _, err := w.Write(h[:]); err != nil { - return err - } - - if e.Index > math.MaxUint16 { - return fmt.Errorf("index for outpoint (%v) is "+ - "greater than max index of %v", e.Index, - math.MaxUint16) - } - - var idx [2]byte - binary.BigEndian.PutUint16(idx[:], uint16(e.Index)) - if _, err := w.Write(idx[:]); err != nil { + if err := WriteOutPoint(w, &e); err != nil { return err } @@ -479,28 +463,7 @@ func readElement(r io.Reader, element interface{}) error { } *e = pkScript case *wire.OutPoint: - var h [32]byte - if _, err = io.ReadFull(r, h[:]); err != nil { - return err - } - hash, err := chainhash.NewHash(h[:]) - if err != nil { - return err - } - - var idxBytes [2]byte - _, err = io.ReadFull(r, idxBytes[:]) - if err != nil { - return err - } - index := binary.BigEndian.Uint16(idxBytes[:]) - - *e = wire.OutPoint{ - Hash: *hash, - Index: uint32(index), - } - case *FailCode: - if err := readElement(r, (*uint16)(e)); err != nil { + if err := ReadOutPoint(r, e); err != nil { return err } diff --git a/lnwire/outpoint.go b/lnwire/outpoint.go new file mode 100644 index 00000000..b990f7f0 --- /dev/null +++ b/lnwire/outpoint.go @@ -0,0 +1,59 @@ +package lnwire + +import ( + "encoding/binary" + "fmt" + "io" + "math" + + "github.com/roasbeef/btcd/chaincfg/chainhash" + "github.com/roasbeef/btcd/wire" +) + +// WriteOutPoint serializes a wire.OutPoint struct into the passed io.Writer +// stream. +func WriteOutPoint(w io.Writer, o *wire.OutPoint) error { + if _, err := w.Write(o.Hash[:chainhash.HashSize]); err != nil { + return err + } + + if o.Index > math.MaxUint16 { + return fmt.Errorf("index for outpoint (%v) is "+ + "greater than max index of %v", o.Index, math.MaxUint16) + } + + var idx [2]byte + binary.BigEndian.PutUint16(idx[:], uint16(o.Index)) + if _, err := w.Write(idx[:]); err != nil { + return err + } + + return nil +} + +// ReadOutPoint deserializes a wire.OutPoint struct from the passed io.Reader +// stream. +func ReadOutPoint(r io.Reader, o *wire.OutPoint) error { + var h [chainhash.HashSize]byte + if _, err := io.ReadFull(r, h[:]); err != nil { + return err + } + hash, err := chainhash.NewHash(h[:]) + if err != nil { + return err + } + + var idxBytes [2]byte + _, err = io.ReadFull(r, idxBytes[:]) + if err != nil { + return err + } + index := binary.BigEndian.Uint16(idxBytes[:]) + + *o = wire.OutPoint{ + Hash: *hash, + Index: uint32(index), + } + + return nil +} diff --git a/lnwire/outpoint_test.go b/lnwire/outpoint_test.go new file mode 100644 index 00000000..9e33e9d2 --- /dev/null +++ b/lnwire/outpoint_test.go @@ -0,0 +1,40 @@ +package lnwire + +import ( + "bytes" + "reflect" + "testing" + + "github.com/roasbeef/btcd/chaincfg/chainhash" + "github.com/roasbeef/btcd/wire" +) + +func TestOutpointSerialization(t *testing.T) { + outpoint := wire.OutPoint{ + Hash: [chainhash.HashSize]byte{ + 0x51, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda, + 0x48, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17, + 0x2d, 0xe7, 0x93, 0xe4, 0xb7, 0x25, 0xb8, 0x4d, + 0x1f, 0xb, 0x4c, 0xf9, 0x9e, 0xc5, 0x8c, 0xe9, + }, + Index: 9, + } + + var buf bytes.Buffer + + if err := WriteOutPoint(&buf, &outpoint); err != nil { + t.Fatalf("unable to serialize outpoint: %v", err) + } + + var deserializedOutpoint wire.OutPoint + if err := ReadOutPoint(&buf, &deserializedOutpoint); err != nil { + t.Fatalf("unable to deserialize outpoint: %v", err) + } + + if !reflect.DeepEqual(outpoint, deserializedOutpoint) { + t.Fatalf("original and deserialized outpoints are different:\n"+ + "original : %+v\n"+ + "deserialized : %+v\n", + outpoint, deserializedOutpoint) + } +} diff --git a/lnwire/txout.go b/lnwire/txout.go new file mode 100644 index 00000000..f75f51a8 --- /dev/null +++ b/lnwire/txout.go @@ -0,0 +1,46 @@ +package lnwire + +import ( + "encoding/binary" + "io" + + "github.com/roasbeef/btcd/wire" +) + +// WriteTxOut serializes a wire.TxOut struct into the passed io.Writer stream. +func WriteTxOut(w io.Writer, txo *wire.TxOut) error { + var scratch [8]byte + + binary.BigEndian.PutUint64(scratch[:], uint64(txo.Value)) + if _, err := w.Write(scratch[:]); err != nil { + return err + } + + if err := wire.WriteVarBytes(w, 0, txo.PkScript); err != nil { + return err + } + + return nil +} + +// ReadTxOut deserializes a wire.TxOut struct from the passed io.Reader stream. +func ReadTxOut(r io.Reader, txo *wire.TxOut) error { + var scratch [8]byte + + if _, err := io.ReadFull(r, scratch[:]); err != nil { + return err + } + value := int64(binary.BigEndian.Uint64(scratch[:])) + + pkScript, err := wire.ReadVarBytes(r, 0, 80, "pkScript") + if err != nil { + return err + } + + *txo = wire.TxOut{ + Value: value, + PkScript: pkScript, + } + + return nil +} diff --git a/lnwire/txout_test.go b/lnwire/txout_test.go new file mode 100644 index 00000000..4fcd9d13 --- /dev/null +++ b/lnwire/txout_test.go @@ -0,0 +1,46 @@ +package lnwire + +import ( + "bytes" + "reflect" + "testing" + + "github.com/roasbeef/btcd/wire" +) + +func TestTxOutSerialization(t *testing.T) { + txo := wire.TxOut{ + Value: 1e7, + PkScript: []byte{ + 0x41, // OP_DATA_65 + 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5, + 0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42, + 0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1, + 0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24, + 0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97, + 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78, + 0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20, + 0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63, + 0xa6, // 65-byte signature + 0xac, // OP_CHECKSIG + }, + } + + var buf bytes.Buffer + + if err := WriteTxOut(&buf, &txo); err != nil { + t.Fatalf("unable to serialize txout: %v", err) + } + + var deserializedTxo wire.TxOut + if err := ReadTxOut(&buf, &deserializedTxo); err != nil { + t.Fatalf("unable to deserialize txout: %v", err) + } + + if !reflect.DeepEqual(txo, deserializedTxo) { + t.Fatalf("original and deserialized txouts are different:\n"+ + "original : %+v\n"+ + "deserialized : %+v\n", + txo, deserializedTxo) + } +} diff --git a/utxonursery.go b/utxonursery.go index 911ef651..17780cd6 100644 --- a/utxonursery.go +++ b/utxonursery.go @@ -15,6 +15,7 @@ import ( "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/lnwallet" "github.com/roasbeef/btcd/btcec" + "github.com/lightningnetwork/lnd/lnwire" "github.com/roasbeef/btcd/txscript" "github.com/roasbeef/btcd/wire" "github.com/roasbeef/btcutil" @@ -584,7 +585,7 @@ func (k *kidOutput) enterPreschool(db *channeldb.DB) error { // Once we have the buckets we can insert the raw bytes of the // immature outpoint into the preschool bucket. var outpointBytes bytes.Buffer - if err := writeOutpoint(&outpointBytes, &k.outPoint); err != nil { + if err := lnwire.WriteOutPoint(&outpointBytes, &k.outPoint); err != nil { return err } var kidBytes bytes.Buffer @@ -658,7 +659,7 @@ func (k *kidOutput) waitForPromotion(db *channeldb.DB, confChan *chainntnfs.Conf // along in the maturity pipeline we first delete the entry // from the preschool bucket, as well as the secondary index. var outpointBytes bytes.Buffer - if err := writeOutpoint(&outpointBytes, &k.outPoint); err != nil { + if err := lnwire.WriteOutPoint(&outpointBytes, &k.outPoint); err != nil { return err } if err := psclBucket.Delete(outpointBytes.Bytes()); err != nil { @@ -1027,7 +1028,7 @@ func serializeKidOutput(w io.Writer, kid *kidOutput) error { return err } - if err := writeOutpoint(w, &kid.outPoint); err != nil { + if err := lnwire.WriteOutPoint(w, &kid.outPoint); err != nil { return err } if err := writeOutpoint(w, &kid.originChanPoint); err != nil { @@ -1085,7 +1086,8 @@ func deserializeKidOutput(r io.Reader) (*kidOutput, error) { } kid.amt = btcutil.Amount(byteOrder.Uint64(scratch[:])) - if err := readOutpoint(io.LimitReader(r, 40), &kid.outPoint); err != nil { + err := lnwire.ReadOutPoint(io.LimitReader(r, 40), &kid.outPoint) + if err != nil { return nil, err } if err := readOutpoint(io.LimitReader(r, 40), &kid.originChanPoint); err != nil { @@ -1145,69 +1147,3 @@ func deserializeKidOutput(r io.Reader) (*kidOutput, error) { return kid, nil } - -// TODO(bvu): copied from channeldb, remove repetition -func writeOutpoint(w io.Writer, o *wire.OutPoint) error { - // TODO(roasbeef): make all scratch buffers on the stack - scratch := make([]byte, 4) - - // TODO(roasbeef): write raw 32 bytes instead of wasting the extra - // byte. - if err := wire.WriteVarBytes(w, 0, o.Hash[:]); err != nil { - return err - } - - byteOrder.PutUint32(scratch, o.Index) - _, err := w.Write(scratch) - return err -} - -// TODO(bvu): copied from channeldb, remove repetition -func readOutpoint(r io.Reader, o *wire.OutPoint) error { - scratch := make([]byte, 4) - - txid, err := wire.ReadVarBytes(r, 0, 32, "prevout") - if err != nil { - return err - } - copy(o.Hash[:], txid) - - if _, err := r.Read(scratch); err != nil { - return err - } - o.Index = byteOrder.Uint32(scratch) - - return nil -} - -func writeTxOut(w io.Writer, txo *wire.TxOut) error { - scratch := make([]byte, 8) - - byteOrder.PutUint64(scratch, uint64(txo.Value)) - if _, err := w.Write(scratch); err != nil { - return err - } - - if err := wire.WriteVarBytes(w, 0, txo.PkScript); err != nil { - return err - } - - return nil -} - -func readTxOut(r io.Reader, txo *wire.TxOut) error { - scratch := make([]byte, 8) - - if _, err := r.Read(scratch); err != nil { - return err - } - txo.Value = int64(byteOrder.Uint64(scratch)) - - pkScript, err := wire.ReadVarBytes(r, 0, 80, "pkScript") - if err != nil { - return err - } - txo.PkScript = pkScript - - return nil -}