Save the pkScript for each Utxo. This is needed to create transactions.
This commit is contained in:
parent
24d6168709
commit
fa85e586fc
2 changed files with 79 additions and 29 deletions
72
tx/tx.go
72
tx/tx.go
|
@ -44,19 +44,22 @@ type UtxoStore struct {
|
|||
|
||||
type Utxo struct {
|
||||
Addr [ripemd160.Size]byte
|
||||
Out OutPoint
|
||||
Amt int64 // Measured in Satoshis
|
||||
Out OutPoint
|
||||
Subscript PKScript
|
||||
Amt uint64 // Measured in Satoshis
|
||||
Height int64
|
||||
}
|
||||
|
||||
type OutPoint btcwire.OutPoint
|
||||
|
||||
type PKScript []byte
|
||||
|
||||
// TxStore is a slice holding RecvTx and SendTx pointers.
|
||||
type TxStore []interface{}
|
||||
|
||||
type RecvTx struct {
|
||||
TxHash btcwire.ShaHash
|
||||
Amt int64 // Measured in Satoshis
|
||||
Amt uint64 // Measured in Satoshis
|
||||
SenderAddr [ripemd160.Size]byte
|
||||
ReceiverAddr [ripemd160.Size]byte
|
||||
}
|
||||
|
@ -67,7 +70,7 @@ type SendTx struct {
|
|||
SenderAddr [ripemd160.Size]byte
|
||||
ReceiverAddrs []struct {
|
||||
Addr [ripemd160.Size]byte
|
||||
Amt int64 // Measured in Satoshis
|
||||
Amt uint64 // Measured in Satoshis
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,13 +181,14 @@ func (u *UtxoStore) WriteTo(w io.Writer) (n int64, err error) {
|
|||
// ReadFrom satisifies the io.ReaderFrom interface. A Utxo is read
|
||||
// from r with the format:
|
||||
//
|
||||
// [Addr (20 bytes), Out (36 bytes), Amt (8 bytes), Height (8 bytes)]
|
||||
// [Addr (20 bytes), Out (36 bytes), Subscript (varies), Amt (8 bytes), Height (8 bytes)]
|
||||
//
|
||||
// Each field is read little endian.
|
||||
func (u *Utxo) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
datas := []interface{}{
|
||||
&u.Addr,
|
||||
&u.Out,
|
||||
&u.Subscript,
|
||||
&u.Amt,
|
||||
&u.Height,
|
||||
}
|
||||
|
@ -206,13 +210,14 @@ func (u *Utxo) ReadFrom(r io.Reader) (n int64, err error) {
|
|||
// WriteTo satisifies the io.WriterTo interface. A Utxo is written to
|
||||
// w in the format:
|
||||
//
|
||||
// [Addr (20 bytes), Out (36 bytes), Amt (8 bytes), Height (8 bytes)]
|
||||
// [Addr (20 bytes), Out (36 bytes), Subscript (varies), Amt (8 bytes), Height (8 bytes)]
|
||||
//
|
||||
// Each field is written little endian.
|
||||
func (u *Utxo) WriteTo(w io.Writer) (n int64, err error) {
|
||||
datas := []interface{}{
|
||||
&u.Addr,
|
||||
&u.Out,
|
||||
&u.Subscript,
|
||||
&u.Amt,
|
||||
&u.Height,
|
||||
}
|
||||
|
@ -231,7 +236,7 @@ func (u *Utxo) WriteTo(w io.Writer) (n int64, err error) {
|
|||
return n, nil
|
||||
}
|
||||
|
||||
// ReadFrom satisifies the io.ReaderFrom interface. A OutPoint is read
|
||||
// ReadFrom satisifies the io.ReaderFrom interface. An OutPoint is read
|
||||
// from r with the format:
|
||||
//
|
||||
// [Hash (32 bytes), Index (4 bytes)]
|
||||
|
@ -253,7 +258,7 @@ func (o *OutPoint) ReadFrom(r io.Reader) (n int64, err error) {
|
|||
return n, nil
|
||||
}
|
||||
|
||||
// WriteTo satisifies the io.WriterTo interface. A OutPoit is written
|
||||
// WriteTo satisifies the io.WriterTo interface. An OutPoint is written
|
||||
// to w in the format:
|
||||
//
|
||||
// [Hash (32 bytes), Index (4 bytes)]
|
||||
|
@ -275,6 +280,55 @@ func (o *OutPoint) WriteTo(w io.Writer) (n int64, err error) {
|
|||
return n, nil
|
||||
}
|
||||
|
||||
// ReadFrom satisifies the io.ReaderFrom interface. A PKScript is read
|
||||
// from r with the format:
|
||||
//
|
||||
// [Length (4 byte unsigned integer), ScriptBytes (Length bytes)]
|
||||
//
|
||||
// Length is read little endian.
|
||||
func (s *PKScript) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
var scriptlen uint32
|
||||
var read int64
|
||||
read, err = binaryRead(r, binary.LittleEndian, &scriptlen)
|
||||
if err != nil {
|
||||
return n + read, err
|
||||
}
|
||||
n += read
|
||||
|
||||
scriptbuf := new(bytes.Buffer)
|
||||
read, err = scriptbuf.ReadFrom(io.LimitReader(r, int64(scriptlen)))
|
||||
if err != nil {
|
||||
return n + read, err
|
||||
}
|
||||
n += read
|
||||
*s = scriptbuf.Bytes()
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// WriteTo satisifies the io.WriterTo interface. A PKScript is written
|
||||
// to w in the format:
|
||||
//
|
||||
// [Length (4 byte unsigned integer), ScriptBytes (Length bytes)]
|
||||
//
|
||||
// Length is written little endian.
|
||||
func (s *PKScript) WriteTo(w io.Writer) (n int64, err error) {
|
||||
var written int64
|
||||
written, err = binaryWrite(w, binary.LittleEndian, uint32(len(*s)))
|
||||
if err != nil {
|
||||
return n + written, nil
|
||||
}
|
||||
n += written
|
||||
|
||||
written, err = bytes.NewBuffer(*s).WriteTo(w)
|
||||
if err != nil {
|
||||
return n + written, nil
|
||||
}
|
||||
n += written
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// ReadFrom satisifies the io.ReaderFrom interface. A TxStore is read
|
||||
// in from r with the format:
|
||||
//
|
||||
|
@ -430,7 +484,7 @@ func (tx *SendTx) ReadFrom(r io.Reader) (n int64, err error) {
|
|||
|
||||
tx.ReceiverAddrs = make([]struct {
|
||||
Addr [ripemd160.Size]byte
|
||||
Amt int64
|
||||
Amt uint64
|
||||
},
|
||||
nReceivers)
|
||||
for i := uint32(0); i < nReceivers; i++ {
|
||||
|
|
|
@ -28,8 +28,6 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
utxoByteSize = binary.Size(Utxo{})
|
||||
|
||||
recvtx = &RecvTx{
|
||||
TxHash: [btcwire.HashSize]byte{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
|
@ -59,11 +57,11 @@ var (
|
|||
},
|
||||
ReceiverAddrs: []struct {
|
||||
Addr [ripemd160.Size]byte
|
||||
Amt int64
|
||||
Amt uint64
|
||||
}{
|
||||
struct {
|
||||
Addr [ripemd160.Size]byte
|
||||
Amt int64
|
||||
Amt uint64
|
||||
}{
|
||||
Amt: 69,
|
||||
Addr: [ripemd160.Size]byte{
|
||||
|
@ -73,7 +71,7 @@ var (
|
|||
},
|
||||
struct {
|
||||
Addr [ripemd160.Size]byte
|
||||
Amt int64
|
||||
Amt uint64
|
||||
}{
|
||||
Amt: 96,
|
||||
Addr: [ripemd160.Size]byte{
|
||||
|
@ -99,26 +97,24 @@ func TestUtxoWriteRead(t *testing.T) {
|
|||
},
|
||||
Index: 1,
|
||||
},
|
||||
Subscript: []byte{},
|
||||
Amt: 69,
|
||||
Height: 1337,
|
||||
}
|
||||
bufWriter := &bytes.Buffer{}
|
||||
n, err := utxo1.WriteTo(bufWriter)
|
||||
written, err := utxo1.WriteTo(bufWriter)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if int(n) != binary.Size(utxo1) {
|
||||
t.Error("Writing Utxo: Size Mismatch")
|
||||
}
|
||||
utxoBytes := bufWriter.Bytes()
|
||||
|
||||
utxo2 := new(Utxo)
|
||||
n, err = utxo2.ReadFrom(bytes.NewBuffer(utxoBytes))
|
||||
read, err := utxo2.ReadFrom(bytes.NewBuffer(utxoBytes))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if int(n) != binary.Size(utxo2) {
|
||||
t.Error("Reading Utxo: Size Mismatch")
|
||||
if written != read {
|
||||
t.Error("Reading and Writing Utxo: Size Mismatch")
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(utxo1, utxo2) {
|
||||
|
@ -129,7 +125,7 @@ func TestUtxoWriteRead(t *testing.T) {
|
|||
truncatedReadBuf := bytes.NewBuffer(utxoBytes)
|
||||
truncatedReadBuf.Truncate(btcwire.HashSize)
|
||||
utxo3 := new(Utxo)
|
||||
n, err = utxo3.ReadFrom(truncatedReadBuf)
|
||||
n, err := utxo3.ReadFrom(truncatedReadBuf)
|
||||
if err != io.EOF {
|
||||
t.Error("Expected err = io.EOF reading from truncated buffer.")
|
||||
}
|
||||
|
@ -146,7 +142,8 @@ func TestUtxoStoreWriteRead(t *testing.T) {
|
|||
utxo.Out.Hash[j] = byte(i)
|
||||
}
|
||||
utxo.Out.Index = uint32(i + 1)
|
||||
utxo.Amt = int64(i + 2)
|
||||
utxo.Subscript = []byte{}
|
||||
utxo.Amt = uint64(i + 2)
|
||||
utxo.Height = int64(i + 3)
|
||||
store1.Confirmed = append(store1.Confirmed, utxo)
|
||||
}
|
||||
|
@ -156,7 +153,8 @@ func TestUtxoStoreWriteRead(t *testing.T) {
|
|||
utxo.Out.Hash[j] = byte(i)
|
||||
}
|
||||
utxo.Out.Index = uint32(i + 1)
|
||||
utxo.Amt = int64(i + 2)
|
||||
utxo.Subscript = []byte{}
|
||||
utxo.Amt = uint64(i + 2)
|
||||
utxo.Height = int64(i + 3)
|
||||
store1.Unconfirmed = append(store1.Unconfirmed, utxo)
|
||||
}
|
||||
|
@ -166,9 +164,6 @@ func TestUtxoStoreWriteRead(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if n != 20*(1+int64(utxoByteSize)) {
|
||||
t.Error("Incorrect number of bytes written.")
|
||||
}
|
||||
|
||||
storeBytes := bufWriter.Bytes()
|
||||
|
||||
|
@ -182,17 +177,18 @@ func TestUtxoStoreWriteRead(t *testing.T) {
|
|||
}
|
||||
|
||||
if !reflect.DeepEqual(store1, store2) {
|
||||
spew.Dump(store1, store2)
|
||||
t.Error("Stores do not match.")
|
||||
}
|
||||
|
||||
truncatedReadBuf := bytes.NewBuffer(storeBytes)
|
||||
truncatedReadBuf.Truncate(10*(1+utxoByteSize) + btcwire.HashSize)
|
||||
truncatedReadBuf.Truncate(100)
|
||||
store3 := new(UtxoStore)
|
||||
n, err = store3.ReadFrom(truncatedReadBuf)
|
||||
if err != io.EOF {
|
||||
t.Error("Expected err = io.EOF reading from truncated buffer.")
|
||||
}
|
||||
if n != 10*(1+int64(utxoByteSize))+btcwire.HashSize {
|
||||
if n != 100 {
|
||||
t.Error("Incorrect number of bytes read from truncated buffer.")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue