Browse Source

parser: implement whole-block parsing and publicize constructors

v2_protobufs
George Tankersley 6 years ago
parent
commit
58e5f3e78b
  1. 47
      parser/block.go
  2. 2
      parser/block_header.go
  3. 2
      parser/block_header_test.go
  4. 42
      parser/block_test.go
  5. 2
      parser/transaction.go
  6. 4
      parser/transaction_test.go

47
parser/block.go

@ -0,0 +1,47 @@
package parser
import (
"fmt"
"github.com/gtank/ctxd/parser/internal/bytestring"
"github.com/pkg/errors"
)
type block struct {
hdr *blockHeader
vtx []*transaction
}
func NewBlock() *block {
return &block{}
}
func (b *block) ParseFromSlice(data []byte) (rest []byte, err error) {
hdr := NewBlockHeader()
data, err = hdr.ParseFromSlice(data)
if err != nil {
return nil, errors.Wrap(err, "parsing block header")
}
s := bytestring.String(data)
var txCount int
if ok := s.ReadCompactSize(&txCount); !ok {
return nil, errors.New("could not read tx_count")
}
data = []byte(s)
vtx := make([]*transaction, 0, txCount)
for i := 0; len(data) > 0; i++ {
tx := NewTransaction()
data, err = tx.ParseFromSlice(data)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("parsing transaction %d", i))
}
vtx = append(vtx, tx)
}
b.hdr = hdr
b.vtx = vtx
return data, nil
}

2
parser/block_header.go

@ -79,7 +79,7 @@ func (hdr *rawBlockHeader) MarshalBinary() ([]byte, error) {
return backing[:SER_BLOCK_HEADER_SIZE], nil
}
func newBlockHeader() *blockHeader {
func NewBlockHeader() *blockHeader {
return &blockHeader{
rawBlockHeader: new(rawBlockHeader),
}

2
parser/block_header_test.go

@ -72,7 +72,7 @@ func TestBlockHeader(t *testing.T) {
continue
}
blockHeader := newBlockHeader()
blockHeader := NewBlockHeader()
_, err = blockHeader.ParseFromSlice(blockData)
if err != nil {
t.Error(err)

42
parser/block_test.go

@ -0,0 +1,42 @@
package parser
import (
"bufio"
"encoding/hex"
"fmt"
"os"
"testing"
"github.com/pkg/errors"
)
func TestBlockParser(t *testing.T) {
testBlocks, err := os.Open("testdata/blocks")
if err != nil {
t.Fatal(err)
}
defer testBlocks.Close()
scan := bufio.NewScanner(testBlocks)
for i := 0; scan.Scan(); i++ {
blockDataHex := scan.Text()
blockData, err := hex.DecodeString(blockDataHex)
if err != nil {
t.Error(err)
continue
}
block := NewBlock()
blockData, err = block.ParseFromSlice(blockData)
if err != nil {
t.Error(errors.Wrap(err, fmt.Sprintf("parsing block %d", i)))
continue
}
// Some basic sanity checks
if block.hdr.Version != 4 {
t.Error("Read wrong version in a test block.")
break
}
}
}

2
parser/transaction.go

@ -394,7 +394,7 @@ func (tx *transaction) ParseFromSlice(data []byte) ([]byte, error) {
return []byte(s), nil
}
func newTransaction() *transaction {
func NewTransaction() *transaction {
return &transaction{
rawTransaction: new(rawTransaction),
}

4
parser/transaction_test.go

@ -179,7 +179,7 @@ func TestSproutTransactionParser(t *testing.T) {
}
for i, tt := range zip143tests {
tx := newTransaction()
tx := NewTransaction()
rest, err := tx.ParseFromSlice(rawTxData[i])
if err != nil {
@ -685,7 +685,7 @@ func TestSaplingTransactionParser(t *testing.T) {
}
for i, tt := range zip243tests {
tx := newTransaction()
tx := NewTransaction()
rest, err := tx.ParseFromSlice(rawTxData[i])
if err != nil {

Loading…
Cancel
Save