Skip to content
Merged
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
74 changes: 74 additions & 0 deletions pkg/tbtc/marshaling_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,22 @@ func TestCoordinationMessage_MarshalingRoundtrip(t *testing.T) {
SweepTxFee: big.NewInt(8000),
},
},
"with reservation anchor proposal": {
proposal: &ReservationAnchorProposal{
DepositFundingTxHash: parseHash("709b55bd3da0f5a838125bd0ee20c5bfdd7caba173912d4281cae816b79a201b"),
DepositFundingOutputIndex: 2,
RequestNonce: 7,
AnchorTxFee: big.NewInt(1500),
},
},
"with reservation reanchor proposal": {
proposal: &ReservationReanchorProposal{
ReservationKey: big.NewInt(424242),
RequestNonce: 4,
TargetWalletPublicKeyHash: toByte20("f87eb7ec3b15a3fdd7b57754d765694b3e0b4bf4"),
ReanchorTxFee: big.NewInt(1200),
},
},
}

walletPublicKeyHash := toByte20("aa768412ceed10bd423c025542ca90071f9fb62d")
Expand Down Expand Up @@ -402,6 +418,64 @@ func TestFuzzCoordinationMessage_MarshalingRoundtrip_WithMovedFundsSweepProposal
}
}

func TestFuzzCoordinationMessage_MarshalingRoundtrip_WithReservationAnchorProposal(t *testing.T) {
for i := 0; i < 10; i++ {
var (
senderID group.MemberIndex
coordinationBlock uint64
walletPublicKeyHash [20]byte
proposal ReservationAnchorProposal
)

f := fuzz.New().NilChance(0.1).
NumElements(0, 512).
Funcs(pbutils.FuzzFuncs()...)

f.Fuzz(&senderID)
f.Fuzz(&coordinationBlock)
f.Fuzz(&walletPublicKeyHash)
f.Fuzz(&proposal)

coordinationMsg := &coordinationMessage{
senderID: senderID,
coordinationBlock: coordinationBlock,
walletPublicKeyHash: walletPublicKeyHash,
proposal: &proposal,
}

_ = pbutils.RoundTrip(coordinationMsg, &coordinationMessage{})
}
}

func TestFuzzCoordinationMessage_MarshalingRoundtrip_WithReservationReanchorProposal(t *testing.T) {
for i := 0; i < 10; i++ {
var (
senderID group.MemberIndex
coordinationBlock uint64
walletPublicKeyHash [20]byte
proposal ReservationReanchorProposal
)

f := fuzz.New().NilChance(0.1).
NumElements(0, 512).
Funcs(pbutils.FuzzFuncs()...)

f.Fuzz(&senderID)
f.Fuzz(&coordinationBlock)
f.Fuzz(&walletPublicKeyHash)
f.Fuzz(&proposal)

coordinationMsg := &coordinationMessage{
senderID: senderID,
coordinationBlock: coordinationBlock,
walletPublicKeyHash: walletPublicKeyHash,
proposal: &proposal,
}

_ = pbutils.RoundTrip(coordinationMsg, &coordinationMessage{})
}
}

func TestFuzzCoordinationMessage_MarshalingRoundtrip_WithNoopProposal(t *testing.T) {
for i := 0; i < 10; i++ {
var (
Expand Down
45 changes: 44 additions & 1 deletion pkg/tbtc/reservation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func TestReservationProposals_MarshalingRoundtrip(t *testing.T) {
roundtrip(reanchorProposal, &ReservationReanchorProposal{})
}

func TestReservationProposals_UnmarshalRejectsMissingIntegers(t *testing.T) {
func TestReservationProposals_UnmarshalRejectsInvalidFields(t *testing.T) {
tests := map[string]struct {
actionType WalletActionType
payload []byte
Expand Down Expand Up @@ -201,6 +201,36 @@ func TestReservationProposals_UnmarshalRejectsMissingIntegers(t *testing.T) {
}),
expectedError: "cannot unmarshal proposal payload: [invalid re-anchor transaction fee byte length: [9]]",
},
"anchor zero fee marshaled through Marshal is rejected as missing": {
actionType: ActionReservationAnchor,
payload: marshalThroughProposal(t, &ReservationAnchorProposal{
DepositFundingTxHash: bitcoin.Hash{0x01, 0x02},
DepositFundingOutputIndex: 3,
RequestNonce: 1,
AnchorTxFee: big.NewInt(0),
}),
expectedError: "cannot unmarshal proposal payload: [anchor transaction fee is required]",
},
"re-anchor zero reservation key marshaled through Marshal is rejected as missing": {
actionType: ActionReservationReanchor,
payload: marshalThroughProposal(t, &ReservationReanchorProposal{
ReservationKey: big.NewInt(0),
RequestNonce: 3,
TargetWalletPublicKeyHash: [20]byte{0xaa, 0xbb},
ReanchorTxFee: big.NewInt(1700),
}),
expectedError: "cannot unmarshal proposal payload: [reservation key is required]",
},
"re-anchor zero fee marshaled through Marshal is rejected as missing": {
actionType: ActionReservationReanchor,
payload: marshalThroughProposal(t, &ReservationReanchorProposal{
ReservationKey: big.NewInt(54321),
RequestNonce: 3,
TargetWalletPublicKeyHash: [20]byte{0xaa, 0xbb},
ReanchorTxFee: big.NewInt(0),
}),
expectedError: "cannot unmarshal proposal payload: [re-anchor transaction fee is required]",
},
}

for testName, test := range tests {
Expand Down Expand Up @@ -230,6 +260,19 @@ func marshalPb(t *testing.T, msg proto.Message) []byte {
return data
}

// marshalThroughProposal marshals a CoordinationProposal via its own Marshal
// method, for use as a test fixture payload. Unlike marshalPb, this exercises
// the proposal's real wire-encoding path (e.g. *big.Int.Bytes()) rather than
// hand-constructing the protobuf message directly.
func marshalThroughProposal(t *testing.T, proposal CoordinationProposal) []byte {
t.Helper()
data, err := proposal.Marshal()
if err != nil {
t.Fatal(err)
}
return data
}

func signReservationTransaction(
t *testing.T,
builder *bitcoin.TransactionBuilder,
Expand Down
Loading