github.com/decred/dcrlnd@v0.7.6/watchtower/wtwire/init.go (about)

     1  package wtwire
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  
     7  	"github.com/decred/dcrd/chaincfg/chainhash"
     8  	"github.com/decred/dcrlnd/feature"
     9  	"github.com/decred/dcrlnd/lnwire"
    10  )
    11  
    12  // Init is the first message sent over the watchtower wire protocol, and
    13  // specifies connection features bits and level of requiredness maintained by
    14  // the sending node. The Init message also sends the chain hash identifying the
    15  // network that the sender is on.
    16  type Init struct {
    17  	// ConnFeatures are the feature bits being advertised for the duration
    18  	// of a single connection with a peer.
    19  	ConnFeatures *lnwire.RawFeatureVector
    20  
    21  	// ChainHash is the genesis hash of the chain that the advertiser claims
    22  	// to be on.
    23  	ChainHash chainhash.Hash
    24  }
    25  
    26  // NewInitMessage generates a new Init message from a raw connection feature
    27  // vector and chain hash.
    28  func NewInitMessage(connFeatures *lnwire.RawFeatureVector,
    29  	chainHash chainhash.Hash) *Init {
    30  
    31  	return &Init{
    32  		ConnFeatures: connFeatures,
    33  		ChainHash:    chainHash,
    34  	}
    35  }
    36  
    37  // Encode serializes the target Init into the passed io.Writer observing the
    38  // protocol version specified.
    39  //
    40  // This is part of the wtwire.Message interface.
    41  func (msg *Init) Encode(w io.Writer, pver uint32) error {
    42  	return WriteElements(w,
    43  		msg.ConnFeatures,
    44  		msg.ChainHash,
    45  	)
    46  }
    47  
    48  // Decode deserializes a serialized Init message stored in the passed io.Reader
    49  // observing the specified protocol version.
    50  //
    51  // This is part of the wtwire.Message interface.
    52  func (msg *Init) Decode(r io.Reader, pver uint32) error {
    53  	return ReadElements(r,
    54  		&msg.ConnFeatures,
    55  		&msg.ChainHash,
    56  	)
    57  }
    58  
    59  // MsgType returns the integer uniquely identifying this message type on the
    60  // wire.
    61  //
    62  // This is part of the wtwire.Message interface.
    63  func (msg *Init) MsgType() MessageType {
    64  	return MsgInit
    65  }
    66  
    67  // MaxPayloadLength returns the maximum allowed payload size for an Init
    68  // complete message observing the specified protocol version.
    69  //
    70  // This is part of the wtwire.Message interface.
    71  func (msg *Init) MaxPayloadLength(uint32) uint32 {
    72  	return MaxMessagePayload
    73  }
    74  
    75  // A compile-time constraint to ensure Init implements the Message interface.
    76  var _ Message = (*Init)(nil)
    77  
    78  // CheckRemoteInit performs basic validation of the remote party's Init message.
    79  // This method checks that the remote Init's chain hash matches our advertised
    80  // chain hash and that the remote Init does not contain any required feature
    81  // bits that we don't understand.
    82  func (msg *Init) CheckRemoteInit(remoteInit *Init,
    83  	featureNames map[lnwire.FeatureBit]string) error {
    84  
    85  	// Check that the remote peer is on the same chain.
    86  	if msg.ChainHash != remoteInit.ChainHash {
    87  		return NewErrUnknownChainHash(remoteInit.ChainHash)
    88  	}
    89  
    90  	remoteConnFeatures := lnwire.NewFeatureVector(
    91  		remoteInit.ConnFeatures, featureNames,
    92  	)
    93  
    94  	// Check that the remote peer doesn't have any required connection
    95  	// feature bits that we ourselves are unaware of.
    96  	return feature.ValidateRequired(remoteConnFeatures)
    97  }
    98  
    99  // ErrUnknownChainHash signals that the remote Init has a different chain hash
   100  // from the one we advertised.
   101  type ErrUnknownChainHash struct {
   102  	hash chainhash.Hash
   103  }
   104  
   105  // NewErrUnknownChainHash creates an ErrUnknownChainHash using the remote Init's
   106  // chain hash.
   107  func NewErrUnknownChainHash(hash chainhash.Hash) *ErrUnknownChainHash {
   108  	return &ErrUnknownChainHash{hash}
   109  }
   110  
   111  // Error returns a human-readable error displaying the unknown chain hash.
   112  func (e *ErrUnknownChainHash) Error() string {
   113  	return fmt.Sprintf("remote init has unknown chain hash: %s", e.hash)
   114  }