Skip to content

Commit

Permalink
Convert []byte slices to chainhash.Hash for all hashes
Browse files Browse the repository at this point in the history
  • Loading branch information
ordishs committed Mar 8, 2023
1 parent 9a7c859 commit 7b47812
Show file tree
Hide file tree
Showing 14 changed files with 151 additions and 110 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"cSpell.words": [
"chainhash",
"errcheck",
"linters"
]
Expand Down
9 changes: 5 additions & 4 deletions BlockMessage.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ package p2p
import (
"io"

"github.com/libsv/go-p2p/chaincfg/chainhash"
"github.com/libsv/go-p2p/wire"
)

// BlockMessage only stores the transaction IDs of the block, not the full transactions
type BlockMessage struct {
Header *wire.BlockHeader
Height uint64
TransactionIDs [][]byte
Size uint64
Header *wire.BlockHeader
Height uint64
TransactionHashes []*chainhash.Hash
Size uint64
}

func (bm *BlockMessage) Bsvdecode(io.Reader, uint32, wire.MessageEncoding) error {
Expand Down
79 changes: 27 additions & 52 deletions Peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"sync/atomic"
"time"

"github.com/libsv/go-bt/v2"
"github.com/libsv/go-p2p/bsvutil"
"github.com/libsv/go-p2p/chaincfg/chainhash"
"github.com/libsv/go-p2p/wire"
Expand All @@ -32,12 +31,12 @@ var (
)

type Block struct {
Hash []byte `json:"hash,omitempty"` // Little endian
PreviousHash []byte `json:"previous_hash,omitempty"` // Little endian
MerkleRoot []byte `json:"merkle_root,omitempty"` // Little endian
Height uint64 `json:"height,omitempty"`
Size uint64 `json:"size,omitempty"`
TxCount uint64 `json:"tx_count,omitempty"`
Hash *chainhash.Hash `json:"hash,omitempty"` // Little endian
PreviousHash *chainhash.Hash `json:"previous_hash,omitempty"` // Little endian
MerkleRoot *chainhash.Hash `json:"merkle_root,omitempty"` // Little endian
Height uint64 `json:"height,omitempty"`
Size uint64 `json:"size,omitempty"`
TxCount uint64 `json:"tx_count,omitempty"`
}

type Peer struct {
Expand All @@ -55,8 +54,8 @@ type Peer struct {
sentVerAck atomic.Bool
receivedVerAck atomic.Bool
batchDelay time.Duration
invBatcher *batcher.Batcher[[]byte]
dataBatcher *batcher.Batcher[[]byte]
invBatcher *batcher.Batcher[chainhash.Hash]
dataBatcher *batcher.Batcher[chainhash.Hash]
}

// NewPeer returns a new bitcoin peer for the provided address and configuration.
Expand Down Expand Up @@ -371,90 +370,66 @@ func (p *Peer) handleGetDataMsg(dataMsg *wire.MsgGetData) {
}
}

func (p *Peer) AnnounceTransaction(txid []byte) {
p.invBatcher.Put(&txid)
func (p *Peer) AnnounceTransaction(hash *chainhash.Hash) {
p.invBatcher.Put(hash)
}

func (p *Peer) RequestTransaction(txID []byte) {
p.dataBatcher.Put(&txID)
func (p *Peer) RequestTransaction(hash *chainhash.Hash) {
p.dataBatcher.Put(hash)
}

func (p *Peer) AnnounceBlock(blockHash []byte) {
func (p *Peer) AnnounceBlock(blockHash *chainhash.Hash) {
invMsg := wire.NewMsgInv()

hash, err := chainhash.NewHash(blockHash)
if err != nil {
p.logger.Infof("ERROR announcing new tx [%s]: %v", hash.String(), err)
return
}

iv := wire.NewInvVect(wire.InvTypeBlock, hash)
if err = invMsg.AddInvVect(iv); err != nil {
iv := wire.NewInvVect(wire.InvTypeBlock, blockHash)
if err := invMsg.AddInvVect(iv); err != nil {
p.logger.Infof("ERROR adding invVect to INV message: %v", err)
return
}

if err = p.WriteMsg(invMsg); err != nil {
if err := p.WriteMsg(invMsg); err != nil {
p.logger.Infof("[%s] ERROR sending INV for block: %v", p.String(), err)
} else {
p.logger.Infof("[%s] Sent INV for block %s", p.String(), hash.String())
p.logger.Infof("[%s] Sent INV for block %v", p.String(), blockHash)
}
}

func (p *Peer) RequestBlock(blockHash []byte) {
func (p *Peer) RequestBlock(blockHash *chainhash.Hash) {
dataMsg := wire.NewMsgGetData()

hash, err := chainhash.NewHash(blockHash)
if err != nil {
p.logger.Infof("ERROR getting tx [%s]: %v", hash.String(), err)
return
}

iv := wire.NewInvVect(wire.InvTypeTx, hash)
if err = dataMsg.AddInvVect(iv); err != nil {
iv := wire.NewInvVect(wire.InvTypeTx, blockHash)
if err := dataMsg.AddInvVect(iv); err != nil {
p.logger.Infof("ERROR adding invVect to GETDATA message: %v", err)
return
}

if err := p.WriteMsg(dataMsg); err != nil {
p.logger.Infof("[%s] ERROR sending block data message: %v", p.String(), err)
} else {
p.logger.Infof("[%s] Sent GETDATA for block %s", p.String(), hash.String())
p.logger.Infof("[%s] Sent GETDATA for block %v", p.String(), blockHash)
}
}

func (p *Peer) sendInvBatch(batch []*[]byte) {
func (p *Peer) sendInvBatch(batch []*chainhash.Hash) {
invMsg := wire.NewMsgInvSizeHint(uint(len(batch)))

for _, txid := range batch {
hash, err := chainhash.NewHash(*txid)
if err != nil {
p.logger.Infof("ERROR announcing new tx [%s]: %v", hash.String(), err)
continue
}

for _, hash := range batch {
iv := wire.NewInvVect(wire.InvTypeTx, hash)
_ = invMsg.AddInvVect(iv)
}

p.writeChan <- invMsg

p.logger.Infof("[%s] Sent INV (%d items)", p.String(), len(batch))
for _, txid := range batch {
p.logger.Debugf(" %x", bt.ReverseBytes(*txid))
for _, hash := range batch {
p.logger.Debugf(" %v", hash)
}
}

func (p *Peer) sendDataBatch(batch []*[]byte) {
func (p *Peer) sendDataBatch(batch []*chainhash.Hash) {
dataMsg := wire.NewMsgGetData()

for _, txid := range batch {
hash, err := chainhash.NewHash(*txid)
if err != nil {
p.logger.Infof("ERROR getting tx [%x]: %v", txid, err)
continue
}

for _, hash := range batch {
iv := wire.NewInvVect(wire.InvTypeTx, hash)
_ = dataMsg.AddInvVect(iv)
}
Expand Down
8 changes: 7 additions & 1 deletion PeerBlockHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"

"github.com/libsv/go-bt/v2"
"github.com/libsv/go-p2p/chaincfg/chainhash"
"github.com/libsv/go-p2p/wire"
)

Expand Down Expand Up @@ -36,7 +37,12 @@ func setPeerBlockHandler() {
}
bytesRead += int(read)
txBytes := tx.TxIDBytes() // this returns the bytes in BigEndian
blockMessage.TransactionIDs = append(blockMessage.TransactionIDs, bt.ReverseBytes(txBytes))
hash, err := chainhash.NewHash(bt.ReverseBytes(txBytes))
if err != nil {
return 0, nil, nil, err
}

blockMessage.TransactionHashes = append(blockMessage.TransactionHashes, hash)

if i == 0 {
blockMessage.Height = extractHeightFromCoinbaseTx(tx)
Expand Down
13 changes: 7 additions & 6 deletions PeerHandler_Mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"sync"

"github.com/libsv/go-p2p/chaincfg/chainhash"
"github.com/libsv/go-p2p/wire"
)

Expand All @@ -17,12 +18,12 @@ type MockPeerHandler struct {
transaction []wire.MsgTx
blockAnnouncements []wire.InvVect
block []BlockMessage
blockTransactionIDs [][][]byte
blockTransactionHashes [][]*chainhash.Hash
}

func NewMockPeerHandler() *MockPeerHandler {
return &MockPeerHandler{
blockTransactionIDs: make([][][]byte, 0),
blockTransactionHashes: make([][]*chainhash.Hash, 0),
}
}

Expand Down Expand Up @@ -127,8 +128,8 @@ func (m *MockPeerHandler) HandleBlock(msg *BlockMessage, _ PeerI) error {

blockIdx := len(m.block)
m.block = append(m.block, *msg)
m.blockTransactionIDs = append(m.blockTransactionIDs, make([][]byte, 0))
m.blockTransactionIDs[blockIdx] = msg.TransactionIDs
m.blockTransactionHashes = append(m.blockTransactionHashes, make([]*chainhash.Hash, 0))
m.blockTransactionHashes[blockIdx] = msg.TransactionHashes

return nil
}
Expand All @@ -140,9 +141,9 @@ func (m *MockPeerHandler) GetBlock() []BlockMessage {
return m.block
}

func (m *MockPeerHandler) GetBlockTransactions(index int) [][]byte {
func (m *MockPeerHandler) GetBlockTransactions(index int) []*chainhash.Hash {
m.mu.RLock()
defer m.mu.RUnlock()

return m.blockTransactionIDs[index]
return m.blockTransactionHashes[index]
}
9 changes: 5 additions & 4 deletions PeerManager.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"sync"
"time"

"github.com/libsv/go-p2p/chaincfg/chainhash"
"github.com/libsv/go-p2p/wire"
"github.com/ordishs/go-utils"
"github.com/ordishs/gocore"
Expand Down Expand Up @@ -81,7 +82,7 @@ func (pm *PeerManager) GetPeers() []PeerI {

// AnnounceTransaction will send an INV message to the provided peers or to selected peers if peers is nil
// it will return the peers that the transaction was actually announced to
func (pm *PeerManager) AnnounceTransaction(txHash []byte, peers []PeerI) []PeerI {
func (pm *PeerManager) AnnounceTransaction(txHash *chainhash.Hash, peers []PeerI) []PeerI {
if len(peers) == 0 {
peers = pm.GetAnnouncedPeers()
}
Expand All @@ -93,7 +94,7 @@ func (pm *PeerManager) AnnounceTransaction(txHash []byte, peers []PeerI) []PeerI
return peers
}

func (pm *PeerManager) RequestTransaction(txHash []byte) PeerI {
func (pm *PeerManager) RequestTransaction(txHash *chainhash.Hash) PeerI {
// send to the first found peer that is connected
var sendToPeer PeerI
for _, peer := range pm.GetAnnouncedPeers() {
Expand All @@ -113,7 +114,7 @@ func (pm *PeerManager) RequestTransaction(txHash []byte) PeerI {
return sendToPeer
}

func (pm *PeerManager) AnnounceBlock(blockHash []byte, peers []PeerI) []PeerI {
func (pm *PeerManager) AnnounceBlock(blockHash *chainhash.Hash, peers []PeerI) []PeerI {
if len(peers) == 0 {
peers = pm.GetAnnouncedPeers()
}
Expand All @@ -125,7 +126,7 @@ func (pm *PeerManager) AnnounceBlock(blockHash []byte, peers []PeerI) []PeerI {
return peers
}

func (pm *PeerManager) RequestBlock(blockHash []byte) PeerI {
func (pm *PeerManager) RequestBlock(blockHash *chainhash.Hash) PeerI {
// send to the first found peer that is connected
var sendToPeer PeerI
for _, peer := range pm.GetAnnouncedPeers() {
Expand Down
22 changes: 12 additions & 10 deletions PeerManager_Mock.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package p2p

import "github.com/libsv/go-p2p/chaincfg/chainhash"

type TestLogger struct{}

func (l TestLogger) LogLevel() int {
Expand All @@ -13,10 +15,10 @@ func (l TestLogger) Fatalf(format string, args ...interface{}) {}

type PeerManagerMock struct {
Peers map[string]PeerI
AnnouncedTransactions [][]byte
RequestTransactions [][]byte
AnnouncedBlocks [][]byte
RequestBlocks [][]byte
AnnouncedTransactions []*chainhash.Hash
RequestTransactions []*chainhash.Hash
AnnouncedBlocks []*chainhash.Hash
RequestBlocks []*chainhash.Hash
peerCreator func(peerAddress string, peerHandler PeerHandlerI) (PeerI, error)
}

Expand All @@ -26,22 +28,22 @@ func NewPeerManagerMock() *PeerManagerMock {
}
}

func (p *PeerManagerMock) RequestTransaction(txID []byte) PeerI {
p.RequestTransactions = append(p.RequestTransactions, txID)
func (p *PeerManagerMock) RequestTransaction(hash *chainhash.Hash) PeerI {
p.RequestTransactions = append(p.RequestTransactions, hash)
return nil
}

func (p *PeerManagerMock) AnnounceTransaction(txID []byte, _ []PeerI) []PeerI {
p.AnnouncedTransactions = append(p.AnnouncedTransactions, txID)
func (p *PeerManagerMock) AnnounceTransaction(hash *chainhash.Hash, _ []PeerI) []PeerI {
p.AnnouncedTransactions = append(p.AnnouncedTransactions, hash)
return nil
}

func (p *PeerManagerMock) AnnounceBlock(blockHash []byte, _ []PeerI) []PeerI {
func (p *PeerManagerMock) AnnounceBlock(blockHash *chainhash.Hash, _ []PeerI) []PeerI {
p.AnnouncedBlocks = append(p.AnnouncedBlocks, blockHash)
return nil
}

func (p *PeerManagerMock) RequestBlock(blockHash []byte) PeerI {
func (p *PeerManagerMock) RequestBlock(blockHash *chainhash.Hash) PeerI {
p.RequestBlocks = append(p.RequestBlocks, blockHash)
return nil
}
Expand Down
16 changes: 8 additions & 8 deletions PeerManager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ import (
"testing"
"time"

"github.com/libsv/go-p2p/chaincfg/chainhash"
"github.com/libsv/go-p2p/wire"
"github.com/ordishs/go-utils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

var (
tx1 = "b042f298deabcebbf15355aa3a13c7d7cfe96c44ac4f492735f936f8e50d06f6"
tx1Bytes, _ = utils.DecodeAndReverseHexString(tx1)
logger = TestLogger{}
tx1 = "b042f298deabcebbf15355aa3a13c7d7cfe96c44ac4f492735f936f8e50d06f6"
tx1Hash, _ = chainhash.NewHashFromStr(tx1)
logger = TestLogger{}
)

func TestNewPeerManager(t *testing.T) {
Expand Down Expand Up @@ -71,14 +71,14 @@ func TestAnnounceNewTransaction(t *testing.T) {
err := pm.AddPeer(peer)
require.NoError(t, err)

pm.AnnounceTransaction(tx1Bytes, nil)
pm.AnnounceTransaction(tx1Hash, nil)

// we need to wait for the batcher to send the inv
time.Sleep(5 * time.Millisecond)

announcements := peer.GetAnnouncements()
require.Len(t, announcements, 1)
assert.Equal(t, tx1Bytes, announcements[0])
assert.Equal(t, tx1Hash, announcements[0])
})

t.Run("announce tx - multiple peers", func(t *testing.T) {
Expand All @@ -95,7 +95,7 @@ func TestAnnounceNewTransaction(t *testing.T) {
require.NoError(t, err)
}

pm.AnnounceTransaction(tx1Bytes, nil)
pm.AnnounceTransaction(tx1Hash, nil)

// we need to wait for the batcher to send the inv
time.Sleep(5 * time.Millisecond)
Expand All @@ -108,7 +108,7 @@ func TestAnnounceNewTransaction(t *testing.T) {
}

require.Len(t, announcements, 1)
assert.Equal(t, tx1Bytes, announcements[0])
assert.Equal(t, tx1Hash, announcements[0])
peersMessaged++
}
assert.GreaterOrEqual(t, peersMessaged, len(peers)/2)
Expand Down
Loading

0 comments on commit 7b47812

Please sign in to comment.