Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wire: More tests for p2p mixing messages. #1

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions wire/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"time"

"github.com/decred/dcrd/chaincfg/chainhash"
"github.com/decred/dcrd/crypto/blake256"
)

const (
Expand Down Expand Up @@ -322,6 +323,38 @@ func readElement(r io.Reader, element interface{}) error {
}
return nil

// Mix identity
case *[33]byte:
_, err := io.ReadFull(r, e[:])
if err != nil {
return err
}
return nil

// Mix signature
case *[64]byte:
_, err := io.ReadFull(r, e[:])
if err != nil {
return err
}
return nil

// sntrup4591651 ciphertext
case *[1047]byte:
_, err := io.ReadFull(r, e[:])
if err != nil {
return err
}
return nil

// sntrup4591651 public key
case *[1218]byte:
_, err := io.ReadFull(r, e[:])
if err != nil {
return err
}
return nil

case *ServiceFlag:
rv, err := binarySerializer.Uint64(r, littleEndian)
if err != nil {
Expand Down Expand Up @@ -377,6 +410,20 @@ func writeElement(w io.Writer, element interface{}) error {
// Attempt to write the element based on the concrete type via fast
// type assertions first.
switch e := element.(type) {
case uint8:
err := binarySerializer.PutUint8(w, e)
if err != nil {
return err
}
return nil

case uint16:
err := binarySerializer.PutUint16(w, littleEndian, e)
if err != nil {
return err
}
return nil

case int32:
err := binarySerializer.PutUint32(w, littleEndian, uint32(e))
if err != nil {
Expand Down Expand Up @@ -441,13 +488,44 @@ func writeElement(w io.Writer, element interface{}) error {
}
return nil

case *[32]byte:
_, err := w.Write(e[:])
if err != nil {
return err
}
return nil

case *chainhash.Hash:
_, err := w.Write(e[:])
if err != nil {
return err
}
return nil

// Mix signature
case *[64]byte:
_, err := w.Write(e[:])
if err != nil {
return err
}
return nil

// sntrup4591761 ciphertext
case *[1047]byte:
_, err := w.Write(e[:])
if err != nil {
return err
}
return nil

// sntrup4591761 public key
case *[1218]byte:
_, err := w.Write(e[:])
if err != nil {
return err
}
return nil

case ServiceFlag:
err := binarySerializer.PutUint64(w, littleEndian, uint64(e))
if err != nil {
Expand Down Expand Up @@ -765,3 +843,16 @@ func isStrictAscii(s string) bool {

return true
}

// mustHash returns the hash of the serialized message. If message
// serialization errors, it panics with a wrapped error.
func mustHash(msg Message, pver uint32) chainhash.Hash {
h := blake256.New()
err := msg.BtcEncode(h, pver)
if err != nil {
err := fmt.Errorf("hash of %T failed due to serialization "+
"error: %w", msg, err)
panic(err)
}
return *(*chainhash.Hash)(h.Sum(nil))
}
15 changes: 15 additions & 0 deletions wire/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,18 @@ const (
// ErrTooManyTSpends is returned when the number of tspend hashes
// exceeds the maximum allowed.
ErrTooManyTSpends

// ErrMixPRScriptClassTooLong is returned when a mixing script class
// type string is longer than allowed by the protocol.
ErrMixPRScriptClassTooLong

// ErrTooManyMixPRUTXOs is returned when a MixPR message contains
// more UTXOs than allowed by the protocol.
ErrTooManyMixPRUTXOs

// ErrTooManyPrevMixMsgs is returned when too many previous messages of
// a mix run are referenced by a message.
ErrTooManyPrevMixMsgs
)

// Map of ErrorCode values back to their constant names for pretty printing.
Expand Down Expand Up @@ -168,6 +180,9 @@ var errorCodeStrings = map[ErrorCode]string{
ErrTooManyInitStateTypes: "ErrTooManyInitStateTypes",
ErrInitStateTypeTooLong: "ErrInitStateTypeTooLong",
ErrTooManyTSpends: "ErrTooManyTSpends",
ErrMixPRScriptClassTooLong: "ErrMixPRScriptClassTooLong",
ErrTooManyMixPRUTXOs: "ErrTooManyMixPRUTXOs",
ErrTooManyPrevMixMsgs: "ErrTooManyPrevMixMsgs",
}

// String returns the ErrorCode as a human-readable name.
Expand Down
5 changes: 4 additions & 1 deletion wire/error_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2017 The btcsuite developers
// Copyright (c) 2015-2020 The Decred developers
// Copyright (c) 2015-2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

Expand Down Expand Up @@ -50,6 +50,9 @@ func TestMessageErrorCodeStringer(t *testing.T) {
{ErrTooManyInitStateTypes, "ErrTooManyInitStateTypes"},
{ErrInitStateTypeTooLong, "ErrInitStateTypeTooLong"},
{ErrTooManyTSpends, "ErrTooManyTSpends"},
{ErrMixPRScriptClassTooLong, "ErrMixPRScriptClassTooLong"},
{ErrTooManyMixPRUTXOs, "ErrTooManyMixPRUTXOs"},
{ErrTooManyPrevMixMsgs, "ErrTooManyPrevMixMsgs"},

{0xffff, "Unknown ErrorCode (65535)"},
}
Expand Down
6 changes: 2 additions & 4 deletions wire/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ go 1.17
require (
github.com/davecgh/go-spew v1.1.1
github.com/decred/dcrd/chaincfg/chainhash v1.0.4
github.com/decred/dcrd/crypto/blake256 v1.0.1
lukechampine.com/blake3 v1.2.1
)

require (
github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
)
require github.com/klauspost/cpuid/v2 v2.0.9 // indirect
2 changes: 2 additions & 0 deletions wire/invvect.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const (
InvTypeTx InvType = 1
InvTypeBlock InvType = 2
InvTypeFilteredBlock InvType = 3
InvTypeMix InvType = 4
)

// Map of service flags back to their constant names for pretty printing.
Expand All @@ -38,6 +39,7 @@ var ivStrings = map[InvType]string{
InvTypeTx: "MSG_TX",
InvTypeBlock: "MSG_BLOCK",
InvTypeFilteredBlock: "MSG_FILTERED_BLOCK",
InvTypeMix: "MSG_MIX",
}

// String returns the InvType in human-readable form.
Expand Down
3 changes: 2 additions & 1 deletion wire/invvect_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Copyright (c) 2015-2016 The Decred developers
// Copyright (c) 2015-2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

Expand All @@ -23,6 +23,7 @@ func TestInvTypeStringer(t *testing.T) {
{InvTypeError, "ERROR"},
{InvTypeTx, "MSG_TX"},
{InvTypeBlock, "MSG_BLOCK"},
{InvTypeMix, "MSG_MIX"},
{0xffffffff, "Unknown InvType (4294967295)"},
}

Expand Down
28 changes: 28 additions & 0 deletions wire/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ const (
CmdCFilterV2 = "cfilterv2"
CmdGetInitState = "getinitstate"
CmdInitState = "initstate"
CmdMixPR = "mixpr"
CmdMixKE = "mixke"
CmdMixCT = "mixct"
CmdMixSR = "mixsr"
CmdMixDC = "mixdc"
CmdMixCM = "mixcm"
CmdMixRS = "mixrs"
)

// Message is an interface that describes a Decred message. A type that
Expand Down Expand Up @@ -168,6 +175,27 @@ func makeEmptyMessage(command string) (Message, error) {
case CmdInitState:
msg = &MsgInitState{}

case CmdMixPR:
msg = &MsgMixPR{}

case CmdMixKE:
msg = &MsgMixKE{}

case CmdMixCT:
msg = &MsgMixCT{}

case CmdMixSR:
msg = &MsgMixSR{}

case CmdMixDC:
msg = &MsgMixDC{}

case CmdMixCM:
msg = &MsgMixCM{}

case CmdMixRS:
msg = &MsgMixRS{}

default:
str := fmt.Sprintf("unhandled command [%s]", command)
return nil, messageError(op, ErrUnknownCmd, str)
Expand Down
19 changes: 18 additions & 1 deletion wire/message_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Copyright (c) 2015-2021 The Decred developers
// Copyright (c) 2015-2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

Expand Down Expand Up @@ -80,6 +80,16 @@ func TestMessage(t *testing.T) {
msgReject := NewMsgReject("block", RejectDuplicate, "duplicate block")
msgGetInitState := NewMsgGetInitState()
msgInitState := NewMsgInitState()
msgMixPR, err := NewMsgMixPR([33]byte{}, 1, 1, "", 1, 1, 1, 1, []MixPRUTXO{}, NewTxOut(0, []byte{}))
if err != nil {
t.Errorf("NewMsgMixPR: %v", err)
}
msgMixKE := NewMsgMixKE([33]byte{}, [32]byte{}, 1, 1, [33]byte{}, [1218]byte{}, [32]byte{}, []chainhash.Hash{})
msgMixCT := NewMsgMixCT([33]byte{}, [32]byte{}, 1, 1, [][1047]byte{}, []chainhash.Hash{})
msgMixSR := NewMsgMixSR([33]byte{}, [32]byte{}, 1, 1, [][][]byte{{{}}}, []chainhash.Hash{})
msgMixDC := NewMsgMixDC([33]byte{}, [32]byte{}, 1, 1, []MixVec{*NewMixVec(1, 1)}, []chainhash.Hash{})
msgMixCM := NewMsgMixCM([33]byte{}, [32]byte{}, 1, 1, NewMsgTx(), []chainhash.Hash{})
msgMixRS := NewMsgMixRS([33]byte{}, [32]byte{}, 1, 1, [32]byte{}, [][]byte{}, [][]byte{})

tests := []struct {
in Message // Value to encode
Expand Down Expand Up @@ -112,6 +122,13 @@ func TestMessage(t *testing.T) {
{msgCFTypes, msgCFTypes, pver, MainNet, 26},
{msgGetInitState, msgGetInitState, pver, MainNet, 25},
{msgInitState, msgInitState, pver, MainNet, 27},
{msgMixPR, msgMixPR, pver, MainNet, 169},
{msgMixKE, msgMixKE, pver, MainNet, 1449},
{msgMixCT, msgMixCT, pver, MainNet, 166},
{msgMixSR, msgMixSR, pver, MainNet, 169},
{msgMixDC, msgMixDC, pver, MainNet, 171},
{msgMixCM, msgMixCM, pver, MainNet, 181},
{msgMixRS, msgMixRS, pver, MainNet, 213},
}

t.Logf("Running %d tests", len(tests))
Expand Down
45 changes: 45 additions & 0 deletions wire/mixvec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) 2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package wire

import (
"fmt"
"strings"
)

// MixVec is a N-element vector of Msize []byte messages.
type MixVec struct {
N uint32
Msize uint32
Data []byte
}

// NewMixVec returns a zero vector for holding n messages of msize length.
func NewMixVec(n, msize uint32) *MixVec {
return &MixVec{
N: n,
Msize: msize,
Data: make([]byte, n*msize),
}
}

func (v *MixVec) String() string {
m := func(i int) []byte {
off := uint32(i) * v.Msize
return v.Data[off : off+v.Msize]
}

b := new(strings.Builder)
b.Grow(2 + int(v.N*(2*v.Msize+1)))
b.WriteString("[")
for i := 0; uint32(i) < v.N; i++ {
if i != 0 {
b.WriteString(" ")
}
fmt.Fprintf(b, "%x", m(i))
}
b.WriteString("]")
return b.String()
}
4 changes: 4 additions & 0 deletions wire/msggetinitstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ const (
// InitStateTSpends is the init state type used to request tpends for
// voting.
InitStateTSpends = "tspends"

// InitStateMixPRs is the init state type used to request mixing pair
// request messages.
InitStateMixPRs = "mixprs"
)

// MsgGetInitState implements the Message interface and represents a
Expand Down
1 change: 1 addition & 0 deletions wire/msginitstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type MsgInitState struct {
BlockHashes []chainhash.Hash
VoteHashes []chainhash.Hash
TSpendHashes []chainhash.Hash
MixPRHashes []chainhash.Hash // XXX serialize this depending on the protocol version
}

// AddBlockHash adds a new block hash to the message. Up to
Expand Down
Loading