Save index as well as tx hash for outputs.

This commit is contained in:
Josh Rickmar 2013-09-04 16:16:20 -04:00
parent 34dc33d48c
commit a6ad4cf48c
2 changed files with 101 additions and 23 deletions

View file

@ -44,11 +44,13 @@ type UtxoStore struct {
type Utxo struct { type Utxo struct {
Addr [ripemd160.Size]byte Addr [ripemd160.Size]byte
TxHash btcwire.ShaHash Out OutPoint
Amt int64 // Measured in Satoshis Amt int64 // Measured in Satoshis
Height int64 Height int64
} }
type OutPoint btcwire.OutPoint
// TxStore is a slice holding RecvTx and SendTx pointers. // TxStore is a slice holding RecvTx and SendTx pointers.
type TxStore []interface{} type TxStore []interface{}
@ -176,17 +178,71 @@ func (u *UtxoStore) WriteTo(w io.Writer) (n int64, err error) {
// ReadFrom satisifies the io.ReaderFrom interface. A Utxo is read // ReadFrom satisifies the io.ReaderFrom interface. A Utxo is read
// from r with the format: // from r with the format:
// //
// [TxHash (32 bytes), Amt (8 bytes), Height (8 bytes)] // [Addr (20 bytes), Out (36 bytes), Amt (8 bytes), Height (8 bytes)]
// //
// Each field is read little endian. // Each field is read little endian.
func (u *Utxo) ReadFrom(r io.Reader) (n int64, err error) { func (u *Utxo) ReadFrom(r io.Reader) (n int64, err error) {
datas := []interface{}{ datas := []interface{}{
&u.Addr, &u.Addr,
&u.TxHash, &u.Out,
&u.Amt, &u.Amt,
&u.Height, &u.Height,
} }
var read int64 var read int64
for _, data := range datas {
if rf, ok := data.(io.ReaderFrom); ok {
read, err = rf.ReadFrom(r)
} else {
read, err = binaryRead(r, binary.LittleEndian, data)
}
if err != nil {
return n + read, err
}
n += read
}
return n, nil
}
// 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)]
//
// Each field is written little endian.
func (u *Utxo) WriteTo(w io.Writer) (n int64, err error) {
datas := []interface{}{
&u.Addr,
&u.Out,
&u.Amt,
&u.Height,
}
var written int64
for _, data := range datas {
if wt, ok := data.(io.WriterTo); ok {
written, err = wt.WriteTo(w)
} else {
written, err = binaryWrite(w, binary.LittleEndian, data)
}
if err != nil {
return n + written, err
}
n += written
}
return n, nil
}
// ReadFrom satisifies the io.ReaderFrom interface. A OutPoint is read
// from r with the format:
//
// [Hash (32 bytes), Index (4 bytes)]
//
// Each field is read little endian.
func (o *OutPoint) ReadFrom(r io.Reader) (n int64, err error) {
datas := []interface{}{
&o.Hash,
&o.Index,
}
var read int64
for _, data := range datas { for _, data := range datas {
read, err = binaryRead(r, binary.LittleEndian, data) read, err = binaryRead(r, binary.LittleEndian, data)
if err != nil { if err != nil {
@ -197,18 +253,16 @@ func (u *Utxo) ReadFrom(r io.Reader) (n int64, err error) {
return n, nil return n, nil
} }
// WriteTo satisifies the io.WriterTo interface. A Utxo is written to // WriteTo satisifies the io.WriterTo interface. A OutPoit is written
// w in the format: // to w in the format:
// //
// [TxHash (32 bytes), Amt (8 bytes), Height (8 bytes)] // [Hash (32 bytes), Index (4 bytes)]
// //
// Each field is written little endian. // Each field is written little endian.
func (u *Utxo) WriteTo(w io.Writer) (n int64, err error) { func (o *OutPoint) WriteTo(w io.Writer) (n int64, err error) {
datas := []interface{}{ datas := []interface{}{
&u.Addr, &o.Hash,
&u.TxHash, &o.Index,
&u.Amt,
&u.Height,
} }
var written int64 var written int64
for _, data := range datas { for _, data := range datas {

View file

@ -91,11 +91,14 @@ func TestUtxoWriteRead(t *testing.T) {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 16, 17, 18, 19,
}, },
TxHash: [btcwire.HashSize]byte{ Out: OutPoint{
Hash: [btcwire.HashSize]byte{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 30, 31,
}, },
Index: 1,
},
Amt: 69, Amt: 69,
Height: 1337, Height: 1337,
} }
@ -139,20 +142,22 @@ func TestUtxoStoreWriteRead(t *testing.T) {
store1 := new(UtxoStore) store1 := new(UtxoStore)
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
utxo := new(Utxo) utxo := new(Utxo)
for j, _ := range utxo.TxHash[:] { for j, _ := range utxo.Out.Hash[:] {
utxo.TxHash[j] = byte(i) utxo.Out.Hash[j] = byte(i)
} }
utxo.Amt = int64(i + 1) utxo.Out.Index = uint32(i + 1)
utxo.Height = int64(i + 2) utxo.Amt = int64(i + 2)
utxo.Height = int64(i + 3)
store1.Confirmed = append(store1.Confirmed, utxo) store1.Confirmed = append(store1.Confirmed, utxo)
} }
for i := 10; i < 20; i++ { for i := 10; i < 20; i++ {
utxo := new(Utxo) utxo := new(Utxo)
for j, _ := range utxo.TxHash[:] { for j, _ := range utxo.Out.Hash[:] {
utxo.TxHash[j] = byte(i) utxo.Out.Hash[j] = byte(i)
} }
utxo.Amt = int64(i + 1) utxo.Out.Index = uint32(i + 1)
utxo.Height = int64(i + 2) utxo.Amt = int64(i + 2)
utxo.Height = int64(i + 3)
store1.Unconfirmed = append(store1.Unconfirmed, utxo) store1.Unconfirmed = append(store1.Unconfirmed, utxo)
} }
@ -197,9 +202,11 @@ func TestRecvTxWriteRead(t *testing.T) {
n, err := recvtx.WriteTo(bufWriter) n, err := recvtx.WriteTo(bufWriter)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return
} }
if int(n) != binary.Size(recvtx) { if int(n) != binary.Size(recvtx) {
t.Error("Writing Tx: Size Mismatch") t.Error("Writing Tx: Size Mismatch")
return
} }
txBytes := bufWriter.Bytes() txBytes := bufWriter.Bytes()
@ -207,13 +214,16 @@ func TestRecvTxWriteRead(t *testing.T) {
n, err = tx.ReadFrom(bytes.NewBuffer(txBytes)) n, err = tx.ReadFrom(bytes.NewBuffer(txBytes))
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return
} }
if int(n) != binary.Size(tx) { if int(n) != binary.Size(tx) {
t.Error("Reading Tx: Size Mismatch") t.Error("Reading Tx: Size Mismatch")
return
} }
if !reflect.DeepEqual(recvtx, tx) { if !reflect.DeepEqual(recvtx, tx) {
t.Error("Txs do not match.") t.Error("Txs do not match.")
return
} }
truncatedReadBuf := bytes.NewBuffer(txBytes) truncatedReadBuf := bytes.NewBuffer(txBytes)
@ -221,9 +231,11 @@ func TestRecvTxWriteRead(t *testing.T) {
n, err = tx.ReadFrom(truncatedReadBuf) n, err = tx.ReadFrom(truncatedReadBuf)
if err != io.EOF { if err != io.EOF {
t.Error("Expected err = io.EOF reading from truncated buffer.") t.Error("Expected err = io.EOF reading from truncated buffer.")
return
} }
if n != btcwire.HashSize { if n != btcwire.HashSize {
t.Error("Incorrect number of bytes read from truncated buffer.") t.Error("Incorrect number of bytes read from truncated buffer.")
return
} }
} }
@ -232,6 +244,7 @@ func TestSendTxWriteRead(t *testing.T) {
n1, err := sendtx.WriteTo(bufWriter) n1, err := sendtx.WriteTo(bufWriter)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return
} }
txBytes := bufWriter.Bytes() txBytes := bufWriter.Bytes()
@ -239,13 +252,16 @@ func TestSendTxWriteRead(t *testing.T) {
n2, err := tx.ReadFrom(bytes.NewBuffer(txBytes)) n2, err := tx.ReadFrom(bytes.NewBuffer(txBytes))
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return
} }
if n1 != n2 { if n1 != n2 {
t.Error("Number of bytes written and read mismatch.") t.Error("Number of bytes written and read mismatch.")
return
} }
if !reflect.DeepEqual(sendtx, tx) { if !reflect.DeepEqual(sendtx, tx) {
t.Error("Txs do not match.") t.Error("Txs do not match.")
return
} }
truncatedReadBuf := bytes.NewBuffer(txBytes) truncatedReadBuf := bytes.NewBuffer(txBytes)
@ -253,9 +269,11 @@ func TestSendTxWriteRead(t *testing.T) {
n, err := tx.ReadFrom(truncatedReadBuf) n, err := tx.ReadFrom(truncatedReadBuf)
if err != io.EOF { if err != io.EOF {
t.Error("Expected err = io.EOF reading from truncated buffer.") t.Error("Expected err = io.EOF reading from truncated buffer.")
return
} }
if n != btcwire.HashSize { if n != btcwire.HashSize {
t.Error("Incorrect number of bytes read from truncated buffer.") t.Error("Incorrect number of bytes read from truncated buffer.")
return
} }
} }
@ -267,6 +285,7 @@ func TestTxStoreWriteRead(t *testing.T) {
n1, err := store.WriteTo(bufWriter) n1, err := store.WriteTo(bufWriter)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return
} }
txsBytes := bufWriter.Bytes() txsBytes := bufWriter.Bytes()
@ -274,14 +293,17 @@ func TestTxStoreWriteRead(t *testing.T) {
n2, err := txs.ReadFrom(bytes.NewBuffer(txsBytes)) n2, err := txs.ReadFrom(bytes.NewBuffer(txsBytes))
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return
} }
if n1 != n2 { if n1 != n2 {
t.Error("Number of bytes written and read mismatch.") t.Error("Number of bytes written and read mismatch.")
return
} }
if !reflect.DeepEqual(store, txs) { if !reflect.DeepEqual(store, txs) {
spew.Dump(store, txs) spew.Dump(store, txs)
t.Error("TxStores do not match.") t.Error("TxStores do not match.")
return
} }
truncatedReadBuf := bytes.NewBuffer(txsBytes) truncatedReadBuf := bytes.NewBuffer(txsBytes)
@ -289,8 +311,10 @@ func TestTxStoreWriteRead(t *testing.T) {
n, err := txs.ReadFrom(truncatedReadBuf) n, err := txs.ReadFrom(truncatedReadBuf)
if err != io.EOF { if err != io.EOF {
t.Error("Expected err = io.EOF reading from truncated buffer.") t.Error("Expected err = io.EOF reading from truncated buffer.")
return
} }
if n != 50 { if n != 50 {
t.Error("Incorrect number of bytes read from truncated buffer.") t.Error("Incorrect number of bytes read from truncated buffer.")
return
} }
} }