1515package client
1616
1717import (
18+ "crypto/rand"
1819 "hash"
1920 "io"
2021
9394
9495 // Valid checks whether a channel proposal is valid.
9596 Valid () error
96-
97- // ProposalID calculates the proposal's unique identifier.
98- ProposalID () ProposalID
9997 }
10098
10199 // BaseChannelProposal contains all data necessary to propose a new
@@ -104,6 +102,7 @@ type (
104102 // BaseChannelProposal implements the channel proposal messages from the
105103 // Multi-Party Channel Proposal Protocol (MPCPP).
106104 BaseChannelProposal struct {
105+ ProposalID ProposalID // Unique ID for the proposal.
107106 ChallengeDuration uint64 // Dispute challenge duration.
108107 NonceShare NonceShare // Proposer's channel nonce share.
109108 App channel.App // App definition, or nil.
@@ -165,8 +164,14 @@ func makeBaseChannelProposal(
165164 }
166165 }
167166
167+ var proposalID ProposalID
168+ if _ , err := io .ReadFull (rand .Reader , proposalID [:]); err != nil {
169+ return BaseChannelProposal {}, errors .Wrap (err , "generating proposal ID" )
170+ }
171+
168172 return BaseChannelProposal {
169173 ChallengeDuration : challengeDuration ,
174+ ProposalID : proposalID ,
170175 NonceShare : opt .nonce (),
171176 App : opt .App (),
172177 InitData : opt .AppData (),
@@ -188,7 +193,7 @@ func (p BaseChannelProposal) NumPeers() int {
188193// Encode encodes the BaseChannelProposal into an io.Writer.
189194func (p BaseChannelProposal ) Encode (w io.Writer ) error {
190195 optAppAndDataEnc := channel.OptAppAndDataEnc {App : p .App , Data : p .InitData }
191- return perunio .Encode (w , p .ChallengeDuration , p .NonceShare ,
196+ return perunio .Encode (w , p .ProposalID , p . ChallengeDuration , p .NonceShare ,
192197 optAppAndDataEnc , p .InitBals , p .FundingAgreement )
193198}
194199
@@ -198,7 +203,7 @@ func (p *BaseChannelProposal) Decode(r io.Reader) (err error) {
198203 p .InitBals = new (channel.Allocation )
199204 }
200205 optAppAndDataDec := channel.OptAppAndDataDec {App : & p .App , Data : & p .InitData }
201- return perunio .Decode (r , & p .ChallengeDuration , & p .NonceShare ,
206+ return perunio .Decode (r , & p .ProposalID , & p . ChallengeDuration , & p .NonceShare ,
202207 optAppAndDataDec , p .InitBals , & p .FundingAgreement )
203208}
204209
@@ -229,12 +234,12 @@ func (p LedgerChannelProposalMsg) Accept(
229234 nonceShare ProposalOpts ,
230235) * LedgerChannelProposalAccMsg {
231236 if ! nonceShare .isNonce () {
232- log .WithField ("proposal" , p .ProposalID () ).
237+ log .WithField ("proposal" , p .ProposalID ).
233238 Panic ("LedgerChannelProposal.Accept: nonceShare has no configured nonce" )
234239 }
235240 return & LedgerChannelProposalAccMsg {
236241 BaseChannelProposalAcc : makeBaseChannelProposalAcc (
237- p .ProposalID () , nonceShare .nonce ()),
242+ p .ProposalID , nonceShare .nonce ()),
238243 Participant : participant ,
239244 }
240245}
@@ -275,16 +280,6 @@ func (LedgerChannelProposalMsg) Type() wire.Type {
275280 return wire .LedgerChannelProposal
276281}
277282
278- // ProposalID returns the identifier of this channel proposal request.
279- func (p LedgerChannelProposalMsg ) ProposalID () (propID ProposalID ) {
280- hasher := newHasher ()
281- if err := perunio .Encode (hasher , p ); err != nil {
282- log .Panicf ("proposal ID nonce encoding: %v" , err )
283- }
284- copy (propID [:], hasher .Sum (nil ))
285- return
286- }
287-
288283// Encode encodes a ledger channel proposal.
289284func (p LedgerChannelProposalMsg ) Encode (w io.Writer ) error {
290285 if err := p .assertValidNumParts (); err != nil {
@@ -347,16 +342,6 @@ func NewSubChannelProposal(
347342 return
348343}
349344
350- // ProposalID returns the identifier of this channel proposal request.
351- func (p SubChannelProposalMsg ) ProposalID () (propID ProposalID ) {
352- hasher := newHasher ()
353- if err := perunio .Encode (hasher , p ); err != nil {
354- log .Panicf ("proposal ID nonce encoding: %v" , err )
355- }
356- copy (propID [:], hasher .Sum (nil ))
357- return
358- }
359-
360345// Encode encodes the SubChannelProposal into an io.Writer.
361346func (p SubChannelProposalMsg ) Encode (w io.Writer ) error {
362347 return perunio .Encode (w , p .BaseChannelProposal , p .Parent )
@@ -377,14 +362,13 @@ func (SubChannelProposalMsg) Type() wire.Type {
377362func (p SubChannelProposalMsg ) Accept (
378363 nonceShare ProposalOpts ,
379364) * SubChannelProposalAccMsg {
380- propID := p .ProposalID ()
381365 if ! nonceShare .isNonce () {
382- log .WithField ("proposal" , propID ).
366+ log .WithField ("proposal" , p . ProposalID ).
383367 Panic ("SubChannelProposal.Accept: nonceShare has no configured nonce" )
384368 }
385369 return & SubChannelProposalAccMsg {
386370 BaseChannelProposalAcc : makeBaseChannelProposalAcc (
387- propID , nonceShare .nonce ()),
371+ p . ProposalID , nonceShare .nonce ()),
388372 }
389373}
390374
@@ -602,25 +586,14 @@ func (VirtualChannelProposalMsg) Type() wire.Type {
602586 return wire .VirtualChannelProposal
603587}
604588
605- // ProposalID returns the identifier of this channel proposal.
606- func (p VirtualChannelProposalMsg ) ProposalID () (propID ProposalID ) {
607- hasher := newHasher ()
608- if err := perunio .Encode (hasher , p ); err != nil {
609- log .Panicf ("proposal ID base encoding: %v" , err )
610- }
611- copy (propID [:], hasher .Sum (nil ))
612- return
613- }
614-
615589// Accept constructs an accept message that belongs to a proposal message.
616590func (p VirtualChannelProposalMsg ) Accept (
617591 responder wallet.Address ,
618592 opts ... ProposalOpts ,
619593) * VirtualChannelProposalAccMsg {
620- propID := p .ProposalID ()
621594 _opts := union (opts ... )
622595 return & VirtualChannelProposalAccMsg {
623- BaseChannelProposalAcc : makeBaseChannelProposalAcc (propID , _opts .nonce ()),
596+ BaseChannelProposalAcc : makeBaseChannelProposalAcc (p . ProposalID , _opts .nonce ()),
624597 Responder : responder ,
625598 }
626599}
0 commit comments