github.com/decred/dcrlnd@v0.7.6/netann/channel_update_test.go (about) 1 package netann_test 2 3 import ( 4 "errors" 5 "testing" 6 "time" 7 8 "github.com/decred/dcrd/dcrec/secp256k1/v4" 9 "github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa" 10 "github.com/decred/dcrlnd/keychain" 11 "github.com/decred/dcrlnd/lnwallet" 12 "github.com/decred/dcrlnd/lnwire" 13 "github.com/decred/dcrlnd/netann" 14 "github.com/decred/dcrlnd/routing" 15 ) 16 17 type mockSigner struct { 18 err error 19 } 20 21 func (m *mockSigner) SignMessage(_ keychain.KeyLocator, 22 _ []byte, _ bool) (*ecdsa.Signature, error) { 23 24 if m.err != nil { 25 return nil, m.err 26 } 27 28 return nil, nil 29 } 30 31 var _ lnwallet.MessageSigner = (*mockSigner)(nil) 32 33 var ( 34 privKey, _ = secp256k1.GeneratePrivateKey() 35 privKeySigner = keychain.NewPrivKeyMessageSigner(privKey, testKeyLoc) 36 37 pubKey = privKey.PubKey() 38 39 errFailedToSign = errors.New("unable to sign message") 40 ) 41 42 type updateDisableTest struct { 43 name string 44 startEnabled bool 45 disable bool 46 startTime time.Time 47 signer lnwallet.MessageSigner 48 expErr error 49 } 50 51 var updateDisableTests = []updateDisableTest{ 52 { 53 name: "working signer enabled to disabled", 54 startEnabled: true, 55 disable: true, 56 startTime: time.Now(), 57 signer: netann.NewNodeSigner(privKeySigner), 58 }, 59 { 60 name: "working signer enabled to enabled", 61 startEnabled: true, 62 disable: false, 63 startTime: time.Now(), 64 signer: netann.NewNodeSigner(privKeySigner), 65 }, 66 { 67 name: "working signer disabled to enabled", 68 startEnabled: false, 69 disable: false, 70 startTime: time.Now(), 71 signer: netann.NewNodeSigner(privKeySigner), 72 }, 73 { 74 name: "working signer disabled to disabled", 75 startEnabled: false, 76 disable: true, 77 startTime: time.Now(), 78 signer: netann.NewNodeSigner(privKeySigner), 79 }, 80 { 81 name: "working signer future monotonicity", 82 startEnabled: true, 83 disable: true, 84 startTime: time.Now().Add(time.Hour), // must increment 85 signer: netann.NewNodeSigner(privKeySigner), 86 }, 87 { 88 name: "failing signer", 89 startTime: time.Now(), 90 signer: &mockSigner{err: errFailedToSign}, 91 expErr: errFailedToSign, 92 }, 93 { 94 name: "invalid sig from signer", 95 startTime: time.Now(), 96 signer: &mockSigner{}, // returns a nil signature 97 expErr: errors.New("cannot decode empty signature"), 98 }, 99 } 100 101 // TestUpdateDisableFlag checks the behavior of UpdateDisableFlag, asserting 102 // that the proper channel flags are set, the timestamp always increases 103 // monotonically, and that the correct errors are returned in the event that the 104 // signer is unable to produce a signature. 105 func TestUpdateDisableFlag(t *testing.T) { 106 t.Parallel() 107 108 for _, tc := range updateDisableTests { 109 tc := tc 110 t.Run(tc.name, func(t *testing.T) { 111 // Create the initial update, the only fields we are 112 // concerned with in this test are the timestamp and the 113 // channel flags. 114 ogUpdate := &lnwire.ChannelUpdate{ 115 Timestamp: uint32(tc.startTime.Unix()), 116 } 117 if !tc.startEnabled { 118 ogUpdate.ChannelFlags |= lnwire.ChanUpdateDisabled 119 } 120 121 // Create new update to sign using the same fields as 122 // the original. UpdateDisableFlag will mutate the 123 // passed channel update, so we keep the old one to test 124 // against. 125 newUpdate := &lnwire.ChannelUpdate{ 126 Timestamp: ogUpdate.Timestamp, 127 ChannelFlags: ogUpdate.ChannelFlags, 128 } 129 130 // Attempt to update and sign the new update, specifying 131 // disabled or enabled as prescribed in the test case. 132 err := netann.SignChannelUpdate( 133 tc.signer, testKeyLoc, newUpdate, 134 netann.ChanUpdSetDisable(tc.disable), 135 netann.ChanUpdSetTimestamp, 136 ) 137 138 var fail bool 139 switch { 140 141 // Both nil, pass. 142 case tc.expErr == nil && err == nil: 143 144 // Both non-nil, compare error strings since some 145 // methods don't return concrete error types. 146 case tc.expErr != nil && err != nil: 147 if err.Error() != tc.expErr.Error() { 148 fail = true 149 } 150 151 // Otherwise, one is nil and one is non-nil. 152 default: 153 fail = true 154 } 155 156 if fail { 157 t.Fatalf("expected error: %v, got %v", 158 tc.expErr, err) 159 } 160 161 // Exit early if the test expected a failure. 162 if tc.expErr != nil { 163 return 164 } 165 166 // Verify that the timestamp has increased from the 167 // original update. 168 if newUpdate.Timestamp <= ogUpdate.Timestamp { 169 t.Fatalf("update timestamp should be "+ 170 "monotonically increasing, "+ 171 "original: %d, new %d", 172 ogUpdate.Timestamp, newUpdate.Timestamp) 173 } 174 175 // Verify that the disabled flag is properly set. 176 disabled := newUpdate.ChannelFlags& 177 lnwire.ChanUpdateDisabled != 0 178 if disabled != tc.disable { 179 t.Fatalf("expected disable:%v, found:%v", 180 tc.disable, disabled) 181 } 182 183 // Finally, validate the signature using the router's 184 // verification logic. 185 err = routing.ValidateChannelUpdateAnn( 186 pubKey, 0, newUpdate, 187 ) 188 if err != nil { 189 t.Fatalf("channel update failed to "+ 190 "validate: %v", err) 191 } 192 }) 193 } 194 }