diff --git a/breacharbiter.go b/breacharbiter.go index 040c3afb..4fa713e6 100644 --- a/breacharbiter.go +++ b/breacharbiter.go @@ -15,7 +15,6 @@ import ( "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/lnwallet" - "github.com/lightningnetwork/lnd/lnwire" "github.com/roasbeef/btcd/chaincfg/chainhash" "github.com/roasbeef/btcd/txscript" "github.com/roasbeef/btcd/wire" @@ -676,7 +675,6 @@ type retributionInfo struct { // the channel's contract by the counterparty. This function returns a *fully* // signed transaction with the witness for each input fully in place. func (b *breachArbiter) createJusticeTx(r *retributionInfo) (*wire.MsgTx, error) { - // First, we obtain a new public key script from the wallet which we'll // sweep the funds to. // TODO(roasbeef): possibly create many outputs to minimize change in @@ -854,7 +852,7 @@ func (rs *retributionStore) Add(ret *retributionInfo) error { } var outBuf bytes.Buffer - if err := lnwire.WriteOutPoint(&outBuf, &ret.chanPoint); err != nil { + if err := writeOutpoint(&outBuf, &ret.chanPoint); err != nil { return err } @@ -885,7 +883,7 @@ func (rs *retributionStore) Remove(key *wire.OutPoint) error { } var outBuf bytes.Buffer - if err := lnwire.WriteOutPoint(&outBuf, key); err != nil { + if err := writeOutpoint(&outBuf, key); err != nil { return err } @@ -926,7 +924,7 @@ func (ret *retributionInfo) Encode(w io.Writer) error { return err } - if err := lnwire.WriteOutPoint(w, &ret.chanPoint); err != nil { + if err := writeOutpoint(w, &ret.chanPoint); err != nil { return err } @@ -965,7 +963,7 @@ func (ret *retributionInfo) Decode(r io.Reader) error { } ret.commitHash = *hash - if err := lnwire.ReadOutPoint(r, &ret.chanPoint); err != nil { + if err := readOutpoint(r, &ret.chanPoint); err != nil { return err } @@ -1005,7 +1003,7 @@ func (bo *breachedOutput) Encode(w io.Writer) error { return err } - if err := lnwire.WriteOutPoint(w, &bo.outpoint); err != nil { + if err := writeOutpoint(w, &bo.outpoint); err != nil { return err } @@ -1039,7 +1037,7 @@ func (bo *breachedOutput) Decode(r io.Reader) error { } bo.amt = btcutil.Amount(binary.BigEndian.Uint64(scratch[:8])) - if err := lnwire.ReadOutPoint(r, &bo.outpoint); err != nil { + if err := readOutpoint(r, &bo.outpoint); err != nil { return err } diff --git a/channeldb/channel.go b/channeldb/channel.go index 47d63414..6640db30 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.ChanID); err != nil { + if err := writeOutpoint(&b, &c.FundingOutpoint); 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.ChanID); err != nil { + if err := writeOutpoint(&b, &c.FundingOutpoint); err != nil { return err } @@ -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.ChanID); err != nil { + if err := writeOutpoint(&b, &channel.FundingOutpoint); 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.ChanID); err != nil { + if err := writeOutpoint(&b, &channel.FundingOutpoint); 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.ChanID); err != nil { + if err := writeOutpoint(&b, &channel.FundingOutpoint); 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.ChanID); err != nil { + if err := writeOutpoint(&b, &channel.FundingOutpoint); 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.ChanID); err != nil { + if err := writeOutpoint(&b, &channel.FundingOutpoint); 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.ChanID); err != nil { + if err := writeOutpoint(&b, &channel.FundingOutpoint); 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.ChanID); err != nil { + if err := writeOutpoint(&b, &channel.FundingOutpoint); 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.ChanID); err != nil { + if err := writeOutpoint(&b, &channel.FundingOutpoint); 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.ChanID); err != nil { + if err := writeOutpoint(&b, &channel.FundingOutpoint); 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.ChanID); err != nil { + if err := writeOutpoint(&b, &channel.FundingOutpoint); 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.ChanID); err != nil { + if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { return err } @@ -1568,7 +1568,7 @@ func fetchChannelIDs(nodeChanBucket *bolt.Bucket, channel *OpenChannel) error { b bytes.Buffer ) - if err = writeOutpoint(&b, channel.ChanID); err != nil { + if err = writeOutpoint(&b, &channel.FundingOutpoint); err != nil { return err } @@ -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.ChanID); err != nil { + if err = writeOutpoint(&bc, &channel.FundingOutpoint); 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.ChanID); err != nil { + if err := writeOutpoint(&bc, &channel.FundingOutpoint); 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.ChanID); err != nil { + if err := writeOutpoint(&b, &channel.FundingOutpoint); 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.ChanID); err != nil { + if err := writeOutpoint(&b, &channel.FundingOutpoint); err != nil { return err } preimageKey := make([]byte, len(revocationStateKey)+b.Len()) diff --git a/channeldb/db.go b/channeldb/db.go index 8a3c84d3..59c77f04 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 := lnwire.ReadOutPoint(outBytes, chanID); err != nil { + if err := 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 := lnwire.WriteOutPoint(&b, outpoint); err != nil { + if err := 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 := lnwire.WriteOutPoint(&b, chanPoint); err != nil { + if err := writeOutpoint(&b, chanPoint); err != nil { return err } diff --git a/channeldb/graph.go b/channeldb/graph.go index a8e95364..711f817f 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 := lnwire.WriteOutPoint(&b, &edge.ChannelPoint); err != nil { + if err := 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 := lnwire.WriteOutPoint(&opBytes, chanPoint); err != nil { + if err := 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 := lnwire.WriteOutPoint(&b, chanPoint); err != nil { + if err := 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 := lnwire.WriteOutPoint(&b, chanPoint); err != nil { + if err := 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 := lnwire.WriteOutPoint(&b, op); err != nil { + if err := 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 := lnwire.WriteOutPoint(&b, &edgeInfo.ChannelPoint); err != nil { + if err := 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 := lnwire.ReadOutPoint(r, &edgeInfo.ChannelPoint); err != nil { + if err := 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 98bc1042..529e8782 100644 --- a/lnwire/lnwire.go +++ b/lnwire/lnwire.go @@ -4,11 +4,13 @@ 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" ) @@ -187,7 +189,21 @@ func writeElement(w io.Writer, element interface{}) error { } case wire.OutPoint: - if err := WriteOutPoint(w, &e); err != nil { + 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 { return err } @@ -463,10 +479,30 @@ func readElement(r io.Reader, element interface{}) error { } *e = pkScript case *wire.OutPoint: - if err := ReadOutPoint(r, e); err != nil { + 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 { + return err + } case *ChannelID: if _, err := io.ReadFull(r, e[:]); err != nil { return err diff --git a/lnwire/outpoint.go b/lnwire/outpoint.go deleted file mode 100644 index b990f7f0..00000000 --- a/lnwire/outpoint.go +++ /dev/null @@ -1,59 +0,0 @@ -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 deleted file mode 100644 index 9e33e9d2..00000000 --- a/lnwire/outpoint_test.go +++ /dev/null @@ -1,40 +0,0 @@ -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/utxonursery.go b/utxonursery.go index 63baaba8..b4a1b196 100644 --- a/utxonursery.go +++ b/utxonursery.go @@ -14,7 +14,6 @@ import ( "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/lnwallet" - "github.com/lightningnetwork/lnd/lnwire" "github.com/roasbeef/btcd/txscript" "github.com/roasbeef/btcd/wire" "github.com/roasbeef/btcutil" @@ -441,7 +440,7 @@ func (u *utxoNursery) NurseryReport(chanPoint *wire.OutPoint) (*contractMaturity } var b bytes.Buffer - if err := lnwire.WriteOutPoint(&b, chanPoint); err != nil { + if err := writeOutpoint(&b, chanPoint); err != nil { return err } chanPointBytes := b.Bytes() @@ -547,7 +546,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 := lnwire.WriteOutPoint(&outpointBytes, &k.outPoint); err != nil { + if err := writeOutpoint(&outpointBytes, &k.outPoint); err != nil { return err } var kidBytes bytes.Buffer @@ -563,7 +562,7 @@ func (k *kidOutput) enterPreschool(db *channeldb.DB) error { // track all the immature outpoints for a particular channel's // chanPoint. var b bytes.Buffer - err = lnwire.WriteOutPoint(&b, &k.originChanPoint) + err = writeOutpoint(&b, &k.originChanPoint) if err != nil { return err } @@ -604,7 +603,7 @@ func (k *kidOutput) waitForPromotion(db *channeldb.DB, confChan *chainntnfs.Conf // array form prior to database insertion. err := db.Update(func(tx *bolt.Tx) error { var originPoint bytes.Buffer - if err := lnwire.WriteOutPoint(&originPoint, &k.originChanPoint); err != nil { + if err := writeOutpoint(&originPoint, &k.originChanPoint); err != nil { return err } @@ -621,7 +620,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 := lnwire.WriteOutPoint(&outpointBytes, &k.outPoint); err != nil { + if err := writeOutpoint(&outpointBytes, &k.outPoint); err != nil { return err } if err := psclBucket.Delete(outpointBytes.Bytes()); err != nil { @@ -916,7 +915,7 @@ func deleteGraduatedOutputs(db *channeldb.DB, deleteHeight uint32) error { } for _, sweptOutput := range sweptOutputs { var chanPoint bytes.Buffer - err := lnwire.WriteOutPoint(&chanPoint, &sweptOutput.originChanPoint) + err := writeOutpoint(&chanPoint, &sweptOutput.originChanPoint) if err != nil { return err } @@ -990,10 +989,10 @@ func serializeKidOutput(w io.Writer, kid *kidOutput) error { return err } - if err := lnwire.WriteOutPoint(w, &kid.outPoint); err != nil { + if err := writeOutpoint(w, &kid.outPoint); err != nil { return err } - if err := lnwire.WriteOutPoint(w, &kid.originChanPoint); err != nil { + if err := writeOutpoint(w, &kid.originChanPoint); err != nil { return err } @@ -1047,12 +1046,12 @@ func deserializeKidOutput(r io.Reader) (*kidOutput, error) { } kid.amt = btcutil.Amount(byteOrder.Uint64(scratch[:])) - err := lnwire.ReadOutPoint(io.LimitReader(r, 40), &kid.outPoint) + err := readOutpoint(io.LimitReader(r, 40), &kid.outPoint) if err != nil { return nil, err } - err = lnwire.ReadOutPoint(io.LimitReader(r, 40), &kid.originChanPoint) + err = readOutpoint(io.LimitReader(r, 40), &kid.originChanPoint) if err != nil { return nil, err } @@ -1109,3 +1108,69 @@ 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 +}