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

tapfreighter: validate proof courier address before commencing send #497

Merged
merged 1 commit into from
Sep 12, 2023
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
4 changes: 2 additions & 2 deletions proof/courier.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ func ParseCourierAddrUrl(addr url.URL) (CourierAddr, error) {
return NewHashMailCourierAddr(addr)
}

return nil, fmt.Errorf("unknown courier address protocol: %v",
addr.Scheme)
return nil, fmt.Errorf("unknown courier address protocol "+
"(consider updating tapd): %v", addr.Scheme)
}

// HashMailCourierAddr is a hashmail protocol specific implementation of the
Expand Down
9 changes: 9 additions & 0 deletions tapfreighter/chain_porter.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,15 @@ func (p *ChainPorter) Stop() error {
// RequestShipment is the main external entry point to the porter. This request
// a new transfer take place.
func (p *ChainPorter) RequestShipment(req Parcel) (*OutboundParcel, error) {
// Perform validation on the parcel before we continue. This is a good
// point to perform validation because it is at the external entry point
// to the porter. We will therefore catch invalid parcels before locking
// coins or broadcasting.
err := req.Validate()
if err != nil {
return nil, fmt.Errorf("failed to validate parcel: %w", err)
}

if !fn.SendOrQuit(p.exportReqs, req, p.Quit) {
return nil, fmt.Errorf("ChainPorter shutting down")
}
Expand Down
37 changes: 37 additions & 0 deletions tapfreighter/parcel.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ type Parcel interface {

// kit returns the parcel kit used for delivery.
kit() *parcelKit

// Validate validates the parcel.
Validate() error
}

// parcelKit is a struct that contains the channels that are used to deliver
Expand Down Expand Up @@ -160,6 +163,28 @@ func (p *AddressParcel) kit() *parcelKit {
return p.parcelKit
}

// Validate validates the parcel.
func (p *AddressParcel) Validate() error {
// We need at least one address to send to in an address parcel.
if len(p.destAddrs) < 1 {
return fmt.Errorf("at least one Tap address must be " +
"specified in address parcel")
}

for idx := range p.destAddrs {
tapAddr := p.destAddrs[idx]

// Validate proof courier addresses.
_, err := proof.ParseCourierAddrUrl(tapAddr.ProofCourierAddr)
if err != nil {
return fmt.Errorf("invalid proof courier address: %w",
err)
}
}

return nil
}

// PendingParcel is a parcel that has not yet completed delivery.
type PendingParcel struct {
*parcelKit
Expand Down Expand Up @@ -194,6 +219,12 @@ func (p *PendingParcel) kit() *parcelKit {
return p.parcelKit
}

// Validate validates the parcel.
func (p *PendingParcel) Validate() error {
// A pending parcel should have already been validated.
return nil
}

// PreSignedParcel is a request to issue an asset transfer of a pre-signed
// parcel. This packages a virtual transaction, the input commitment, and also
// the response context.
Expand Down Expand Up @@ -246,6 +277,12 @@ func (p *PreSignedParcel) kit() *parcelKit {
return p.parcelKit
}

// Validate validates the parcel.
func (p *PreSignedParcel) Validate() error {
// TODO(ffranr): Add validation where appropriate.
return nil
}

// sendPackage houses the information we need to complete a package transfer.
type sendPackage struct {
// SendState is the current send state of this parcel.
Expand Down