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 }