Save the pkScript for each Utxo. This is needed to create transactions.

This commit is contained in:
Josh Rickmar 2013-09-09 13:31:37 -04:00
parent 24d6168709
commit fa85e586fc
2 changed files with 79 additions and 29 deletions

View file

@ -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++ {

View file

@ -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.")
}
}