github.com/decred/dcrlnd@v0.7.6/contractcourt/breacharbiter_test.go (about) 1 //go:build !rpctest 2 // +build !rpctest 3 4 package contractcourt 5 6 import ( 7 "bytes" 8 crand "crypto/rand" 9 "crypto/sha256" 10 "encoding/binary" 11 "fmt" 12 "io" 13 "io/ioutil" 14 "math/rand" 15 "net" 16 "os" 17 "reflect" 18 "sync" 19 "testing" 20 "time" 21 22 "github.com/decred/dcrd/chaincfg/chainhash" 23 "github.com/decred/dcrd/chaincfg/v3" 24 "github.com/decred/dcrd/dcrec/secp256k1/v4" 25 "github.com/decred/dcrd/dcrutil/v4" 26 "github.com/decred/dcrd/txscript/v4" 27 "github.com/decred/dcrd/wire" 28 "github.com/decred/dcrlnd/chainntnfs" 29 "github.com/decred/dcrlnd/channeldb" 30 "github.com/decred/dcrlnd/input" 31 "github.com/decred/dcrlnd/keychain" 32 "github.com/decred/dcrlnd/lntest/channels" 33 "github.com/decred/dcrlnd/lntest/mock" 34 "github.com/decred/dcrlnd/lntest/wait" 35 "github.com/decred/dcrlnd/lnwallet" 36 "github.com/decred/dcrlnd/lnwallet/chainfee" 37 "github.com/decred/dcrlnd/lnwire" 38 "github.com/decred/dcrlnd/shachain" 39 "github.com/go-errors/errors" 40 "github.com/stretchr/testify/require" 41 ) 42 43 var ( 44 breachOutPoints = []wire.OutPoint{ 45 { 46 Hash: [chainhash.HashSize]byte{ 47 0x51, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda, 48 0x48, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17, 49 0x2d, 0xe7, 0x93, 0xe4, 0xb7, 0x25, 0xb8, 0x4d, 50 0x1f, 0xb, 0x4c, 0xf9, 0x9e, 0xc5, 0x8c, 0xe9, 51 }, 52 Index: 9, 53 }, 54 { 55 Hash: [chainhash.HashSize]byte{ 56 0xb7, 0x94, 0x38, 0x5f, 0x2d, 0x1e, 0xf7, 0xab, 57 0x4d, 0x92, 0x73, 0xd1, 0x90, 0x63, 0x81, 0xb4, 58 0x4f, 0x2f, 0x6f, 0x25, 0x88, 0xa3, 0xef, 0xb9, 59 0x6a, 0x49, 0x18, 0x83, 0x31, 0x98, 0x47, 0x53, 60 }, 61 Index: 49, 62 }, 63 { 64 Hash: [chainhash.HashSize]byte{ 65 0x81, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda, 66 0x63, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17, 67 0xd, 0xe7, 0x95, 0xe4, 0xb7, 0x25, 0xb8, 0x4d, 68 0x1e, 0xb, 0x4c, 0xfd, 0x9e, 0xc5, 0x8c, 0xe9, 69 }, 70 Index: 23, 71 }, 72 } 73 74 breachKeys = [][]byte{ 75 {0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 76 0x01, 0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 77 0xb6, 0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 78 0xd7, 0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xb2, 0xe0, 79 0xea, 0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64, 80 0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9, 81 0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56, 82 0xb4, 0x12, 0xa3, 83 }, 84 {0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 85 0x01, 0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 86 0xb6, 0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 87 0xd7, 0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xb2, 0xe0, 88 0xea, 0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64, 89 0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9, 90 0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56, 91 0xb4, 0x12, 0xa3, 92 }, 93 {0x02, 0xce, 0x0b, 0x14, 0xfb, 0x84, 0x2b, 0x1b, 94 0xa5, 0x49, 0xfd, 0xd6, 0x75, 0xc9, 0x80, 0x75, 0xf1, 95 0x2e, 0x9c, 0x51, 0x0f, 0x8e, 0xf5, 0x2b, 0xd0, 0x21, 96 0xa9, 0xa1, 0xf4, 0x80, 0x9d, 0x3b, 0x4d, 97 }, 98 {0x02, 0xce, 0x0b, 0x14, 0xfb, 0x84, 0x2b, 0x1b, 99 0x2e, 0x9c, 0x51, 0x0f, 0x8e, 0xf5, 0x2b, 0xd0, 0x21, 100 0xa5, 0x49, 0xfd, 0xd6, 0x75, 0xc9, 0x80, 0x75, 0xf1, 101 0xa3, 0xa1, 0xf4, 0x80, 0x9d, 0x3b, 0x4d, 102 }, 103 } 104 105 breachedOutputs = []breachedOutput{ 106 { 107 amt: dcrutil.Amount(1e7), 108 outpoint: breachOutPoints[0], 109 witnessType: input.CommitmentNoDelay, 110 signDesc: input.SignDescriptor{ 111 SingleTweak: []byte{ 112 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 113 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 114 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 115 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 116 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 117 0x02, 0x02, 118 }, 119 WitnessScript: []byte{ 120 0x00, 0x14, 0xee, 0x91, 0x41, 0x7e, 121 0x85, 0x6c, 0xde, 0x10, 0xa2, 0x91, 122 0x1e, 0xdc, 0xbd, 0xbd, 0x69, 0xe2, 123 0xef, 0xb5, 0x71, 0x48, 124 }, 125 Output: &wire.TxOut{ 126 Value: 5000000000, 127 PkScript: []byte{ 128 0x41, // OP_DATA_65 129 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 130 0x9e, 0xb1, 0xc5, 0xfe, 0x29, 131 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 132 0x42, 0x81, 0xbe, 0x98, 0x8e, 133 0x2d, 0xa0, 0xb6, 0xc1, 0xc6, 134 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 135 0x86, 0x24, 0xe1, 0x81, 0x75, 136 0xe8, 0x51, 0xc9, 0x6b, 0x97, 137 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 138 0x1f, 0x04, 0x78, 0x34, 0xbc, 139 0x06, 0xd6, 0xd6, 0xed, 0xf6, 140 0x20, 0xd1, 0x84, 0x24, 0x1a, 141 0x6a, 0xed, 0x8b, 0x63, 142 0xa6, // 65-byte signature 143 0xac, // OP_CHECKSIG 144 }, 145 }, 146 HashType: txscript.SigHashAll, 147 }, 148 secondLevelWitnessScript: breachKeys[0], 149 }, 150 { 151 amt: dcrutil.Amount(1e7), 152 outpoint: breachOutPoints[0], 153 witnessType: input.CommitSpendNoDelayTweakless, 154 signDesc: input.SignDescriptor{ 155 WitnessScript: []byte{ 156 0x00, 0x14, 0xee, 0x91, 0x41, 0x7e, 157 0x85, 0x6c, 0xde, 0x10, 0xa2, 0x91, 158 0x1e, 0xdc, 0xbd, 0xbd, 0x69, 0xe2, 159 0xef, 0xb5, 0x71, 0x48, 160 }, 161 Output: &wire.TxOut{ 162 Value: 5000000000, 163 PkScript: []byte{ 164 0x41, // OP_DATA_65 165 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 166 0x9e, 0xb1, 0xc5, 0xfe, 0x29, 167 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 168 0x42, 0x81, 0xbe, 0x98, 0x8e, 169 0x2d, 0xa0, 0xb6, 0xc1, 0xc6, 170 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 171 0x86, 0x24, 0xe1, 0x81, 0x75, 172 0xe8, 0x51, 0xc9, 0x6b, 0x97, 173 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 174 0x1f, 0x04, 0x78, 0x34, 0xbc, 175 0x06, 0xd6, 0xd6, 0xed, 0xf6, 176 0x20, 0xd1, 0x84, 0x24, 0x1a, 177 0x6a, 0xed, 0x8b, 0x63, 178 0xa6, // 65-byte signature 179 0xac, // OP_CHECKSIG 180 }, 181 }, 182 HashType: txscript.SigHashAll, 183 }, 184 secondLevelWitnessScript: breachKeys[0], 185 }, 186 { 187 amt: dcrutil.Amount(2e9), 188 outpoint: breachOutPoints[1], 189 witnessType: input.CommitmentRevoke, 190 signDesc: input.SignDescriptor{ 191 SingleTweak: []byte{ 192 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 193 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 194 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 195 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 196 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 197 0x02, 0x02, 198 }, 199 WitnessScript: []byte{ 200 0x00, 0x14, 0xee, 0x91, 0x41, 0x7e, 201 0x85, 0x6c, 0xde, 0x10, 0xa2, 0x91, 202 0x1e, 0xdc, 0xbd, 0xbd, 0x69, 0xe2, 203 0xef, 0xb5, 0x71, 0x48, 204 }, 205 Output: &wire.TxOut{ 206 Value: 5000000000, 207 PkScript: []byte{ 208 0x41, // OP_DATA_65 209 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 210 0x9e, 0xb1, 0xc5, 0xfe, 0x29, 211 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 212 0x42, 0x81, 0xbe, 0x98, 0x8e, 213 0x2d, 0xa0, 0xb6, 0xc1, 0xc6, 214 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 215 0x86, 0x24, 0xe1, 0x81, 0x75, 216 0xe8, 0x51, 0xc9, 0x6b, 0x97, 217 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 218 0x1f, 0x04, 0x78, 0x34, 0xbc, 219 0x06, 0xd6, 0xd6, 0xed, 0xf6, 220 0x20, 0xd1, 0x84, 0x24, 0x1a, 221 0x6a, 0xed, 0x8b, 0x63, 222 0xa6, // 65-byte signature 223 0xac, // OP_CHECKSIG 224 }, 225 }, 226 HashType: txscript.SigHashAll, 227 }, 228 secondLevelWitnessScript: breachKeys[0], 229 }, 230 { 231 amt: dcrutil.Amount(3e4), 232 outpoint: breachOutPoints[2], 233 witnessType: input.CommitmentTimeLock, 234 signDesc: input.SignDescriptor{ 235 SingleTweak: []byte{ 236 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 237 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 238 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 239 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 240 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 241 0x02, 0x02, 242 }, 243 WitnessScript: []byte{ 244 0x00, 0x14, 0xee, 0x91, 0x41, 0x7e, 245 0x85, 0x6c, 0xde, 0x10, 0xa2, 0x91, 246 0x1e, 0xdc, 0xbd, 0xbd, 0x69, 0xe2, 247 0xef, 0xb5, 0x71, 0x48, 248 }, 249 Output: &wire.TxOut{ 250 Value: 5000000000, 251 PkScript: []byte{ 252 0x41, // OP_DATA_65 253 0x04, 0xd6, 0x4b, 0xdf, 0xd0, 254 0x9e, 0xb1, 0xc5, 0xfe, 0x29, 255 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 256 0x42, 0x81, 0xbe, 0x98, 0x8e, 257 0x2d, 0xa0, 0xb6, 0xc1, 0xc6, 258 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 259 0x86, 0x24, 0xe1, 0x81, 0x75, 260 0xe8, 0x51, 0xc9, 0x6b, 0x97, 261 0x3d, 0x81, 0xb0, 0x1c, 0xc3, 262 0x1f, 0x04, 0x78, 0x34, 0xbc, 263 0x06, 0xd6, 0xd6, 0xed, 0xf6, 264 0x20, 0xd1, 0x84, 0x24, 0x1a, 265 0x6a, 0xed, 0x8b, 0x63, 266 0xa6, // 65-byte signature 267 0xac, // OP_CHECKSIG 268 }, 269 }, 270 HashType: txscript.SigHashAll, 271 }, 272 secondLevelWitnessScript: breachKeys[0], 273 }, 274 } 275 276 retributionMap = make(map[wire.OutPoint]retributionInfo) 277 retributions = []retributionInfo{ 278 { 279 commitHash: [chainhash.HashSize]byte{ 280 0xb7, 0x94, 0x38, 0x5f, 0x2d, 0x1e, 0xf7, 0xab, 281 0x4d, 0x92, 0x73, 0xd1, 0x90, 0x63, 0x81, 0xb4, 282 0x4f, 0x2f, 0x6f, 0x25, 0x88, 0xa3, 0xef, 0xb9, 283 0x6a, 0x49, 0x18, 0x83, 0x31, 0x98, 0x47, 0x53, 284 }, 285 chainHash: [chainhash.HashSize]byte{ 286 0x4d, 0x92, 0x73, 0xd1, 0x90, 0x63, 0x81, 0xb4, 287 0x4f, 0x2f, 0x6f, 0x25, 0x88, 0xa3, 0xef, 0xb9, 288 0xb7, 0x94, 0x38, 0x5f, 0x2d, 0x1e, 0xf7, 0xab, 289 0x6b, 0x49, 0x18, 0x83, 0x31, 0x98, 0x47, 0x53, 290 }, 291 chanPoint: breachOutPoints[0], 292 breachHeight: 337, 293 // Set to breachedOutputs 0 and 1 in init() 294 breachedOutputs: []breachedOutput{{}, {}}, 295 }, 296 { 297 commitHash: [chainhash.HashSize]byte{ 298 0x51, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda, 299 0x48, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17, 300 0x2d, 0xe7, 0x93, 0xe4, 0xb7, 0x25, 0xb8, 0x4d, 301 0x1f, 0xb, 0x4c, 0xf9, 0x9e, 0xc5, 0x8c, 0xe9, 302 }, 303 chainHash: [chainhash.HashSize]byte{ 304 0x4f, 0x2f, 0x6f, 0x25, 0x88, 0xa3, 0xef, 0xb9, 305 0xb7, 0x94, 0x39, 0x5f, 0x2d, 0x1e, 0xf7, 0xab, 306 0x6b, 0x49, 0x18, 0x83, 0x31, 0x98, 0x47, 0x53, 307 0x4d, 0x92, 0x73, 0xd1, 0x90, 0x63, 0x81, 0xb4, 308 }, 309 chanPoint: breachOutPoints[1], 310 breachHeight: 420420, 311 // Set to breachedOutputs 1 and 2 in init() 312 breachedOutputs: []breachedOutput{{}, {}}, 313 }, 314 } 315 ) 316 317 func init() { 318 // Ensure that breached outputs are initialized before starting tests. 319 if err := initBreachedOutputs(); err != nil { 320 panic(err) 321 } 322 323 // Populate a retribution map to for convenience, to allow lookups by 324 // channel point. 325 for i := range retributions { 326 retInfo := &retributions[i] 327 retInfo.breachedOutputs[0] = breachedOutputs[i] 328 retInfo.breachedOutputs[1] = breachedOutputs[i+1] 329 330 retributionMap[retInfo.chanPoint] = *retInfo 331 332 } 333 } 334 335 // FailingRetributionStore wraps a RetributionStore and supports controlled 336 // restarts of the persistent instance. This allows us to test (1) that no 337 // modifications to the entries are made between calls or through side effects, 338 // and (2) that the database is actually being persisted between actions. 339 type FailingRetributionStore interface { 340 RetributionStorer 341 342 Restart() 343 } 344 345 // failingRetributionStore is a concrete implementation of a 346 // FailingRetributionStore. It wraps an underlying RetributionStore and is 347 // parameterized entirely by a restart function, which is intended to simulate a 348 // full stop/start of the store. 349 type failingRetributionStore struct { 350 mu sync.Mutex 351 352 rs RetributionStorer 353 354 nextAddErr error 355 356 restart func() RetributionStorer 357 } 358 359 // newFailingRetributionStore creates a new failing retribution store. The given 360 // restart closure should ensure that it is reloading its contents from the 361 // persistent source. 362 func newFailingRetributionStore( 363 restart func() RetributionStorer) *failingRetributionStore { 364 365 return &failingRetributionStore{ 366 mu: sync.Mutex{}, 367 rs: restart(), 368 restart: restart, 369 } 370 } 371 372 // FailNextAdd instructs the retribution store to return the provided error. If 373 // the error is nil, a generic default will be used. 374 func (frs *failingRetributionStore) FailNextAdd(err error) { 375 if err == nil { 376 err = errors.New("retribution store failed") 377 } 378 379 frs.mu.Lock() 380 frs.nextAddErr = err 381 frs.mu.Unlock() 382 } 383 384 func (frs *failingRetributionStore) Restart() { 385 frs.mu.Lock() 386 frs.rs = frs.restart() 387 frs.mu.Unlock() 388 } 389 390 // Add forwards the call to the underlying retribution store, unless this Add 391 // has been previously instructed to fail. 392 func (frs *failingRetributionStore) Add(retInfo *retributionInfo) error { 393 frs.mu.Lock() 394 defer frs.mu.Unlock() 395 396 if frs.nextAddErr != nil { 397 err := frs.nextAddErr 398 frs.nextAddErr = nil 399 return err 400 } 401 402 return frs.rs.Add(retInfo) 403 } 404 405 func (frs *failingRetributionStore) IsBreached(chanPoint *wire.OutPoint) (bool, error) { 406 frs.mu.Lock() 407 defer frs.mu.Unlock() 408 409 return frs.rs.IsBreached(chanPoint) 410 } 411 412 func (frs *failingRetributionStore) Remove(key *wire.OutPoint) error { 413 frs.mu.Lock() 414 defer frs.mu.Unlock() 415 416 return frs.rs.Remove(key) 417 } 418 419 func (frs *failingRetributionStore) ForAll(cb func(*retributionInfo) error, 420 reset func()) error { 421 422 frs.mu.Lock() 423 defer frs.mu.Unlock() 424 425 return frs.rs.ForAll(cb, reset) 426 } 427 428 // Parse the pubkeys in the breached outputs. 429 func initBreachedOutputs() error { 430 for i := range breachedOutputs { 431 bo := &breachedOutputs[i] 432 433 // Parse the sign descriptor's pubkey. 434 pubkey, err := secp256k1.ParsePubKey(breachKeys[i]) 435 if err != nil { 436 return fmt.Errorf("unable to parse pubkey: %v", 437 breachKeys[i]) 438 } 439 bo.signDesc.KeyDesc.PubKey = pubkey 440 } 441 442 return nil 443 } 444 445 // Test that breachedOutput Encode/Decode works. 446 func TestBreachedOutputSerialization(t *testing.T) { 447 for i := range breachedOutputs { 448 bo := &breachedOutputs[i] 449 450 var buf bytes.Buffer 451 452 if err := bo.Encode(&buf); err != nil { 453 t.Fatalf("unable to serialize breached output [%v]: %v", 454 i, err) 455 } 456 457 desBo := &breachedOutput{} 458 if err := desBo.Decode(&buf); err != nil { 459 t.Fatalf("unable to deserialize "+ 460 "breached output [%v]: %v", i, err) 461 } 462 463 if !reflect.DeepEqual(bo, desBo) { 464 t.Fatalf("original and deserialized "+ 465 "breached outputs not equal:\n"+ 466 "original : %+v\n"+ 467 "deserialized : %+v\n", 468 bo, desBo) 469 } 470 } 471 } 472 473 // Test that retribution Encode/Decode works. 474 func TestRetributionSerialization(t *testing.T) { 475 for i := range retributions { 476 ret := &retributions[i] 477 478 var buf bytes.Buffer 479 480 if err := ret.Encode(&buf); err != nil { 481 t.Fatalf("unable to serialize retribution [%v]: %v", 482 i, err) 483 } 484 485 desRet := &retributionInfo{} 486 if err := desRet.Decode(&buf); err != nil { 487 t.Fatalf("unable to deserialize retribution [%v]: %v", 488 i, err) 489 } 490 491 if !reflect.DeepEqual(ret, desRet) { 492 t.Fatalf("original and deserialized "+ 493 "retribution infos not equal:\n"+ 494 "original : %+v\n"+ 495 "deserialized : %+v\n", 496 ret, desRet) 497 } 498 } 499 } 500 501 // copyRetInfo creates a complete copy of the given retributionInfo. 502 func copyRetInfo(retInfo *retributionInfo) *retributionInfo { 503 nOutputs := len(retInfo.breachedOutputs) 504 505 ret := &retributionInfo{ 506 commitHash: retInfo.commitHash, 507 chainHash: retInfo.chainHash, 508 chanPoint: retInfo.chanPoint, 509 breachHeight: retInfo.breachHeight, 510 breachedOutputs: make([]breachedOutput, nOutputs), 511 } 512 513 copy(ret.breachedOutputs, retInfo.breachedOutputs) 514 515 return ret 516 } 517 518 // mockRetributionStore implements the RetributionStore interface and is backed 519 // by an in-memory map. Access to the internal state is provided by a mutex. 520 // TODO(cfromknecht) extend to support and test controlled failures. 521 type mockRetributionStore struct { 522 mu sync.Mutex 523 state map[wire.OutPoint]*retributionInfo 524 finalTxs map[wire.OutPoint]*wire.MsgTx 525 } 526 527 func newMockRetributionStore() *mockRetributionStore { 528 return &mockRetributionStore{ 529 mu: sync.Mutex{}, 530 state: make(map[wire.OutPoint]*retributionInfo), 531 finalTxs: make(map[wire.OutPoint]*wire.MsgTx), 532 } 533 } 534 535 func (rs *mockRetributionStore) Add(retInfo *retributionInfo) error { 536 rs.mu.Lock() 537 rs.state[retInfo.chanPoint] = copyRetInfo(retInfo) 538 rs.mu.Unlock() 539 540 return nil 541 } 542 543 func (rs *mockRetributionStore) IsBreached(chanPoint *wire.OutPoint) (bool, error) { 544 rs.mu.Lock() 545 _, ok := rs.state[*chanPoint] 546 rs.mu.Unlock() 547 548 return ok, nil 549 } 550 551 func (rs *mockRetributionStore) Finalize(chanPoint *wire.OutPoint, 552 finalTx *wire.MsgTx) error { 553 554 rs.mu.Lock() 555 rs.finalTxs[*chanPoint] = finalTx 556 rs.mu.Unlock() 557 558 return nil 559 } 560 561 func (rs *mockRetributionStore) GetFinalizedTxn( 562 chanPoint *wire.OutPoint) (*wire.MsgTx, error) { 563 564 rs.mu.Lock() 565 finalTx := rs.finalTxs[*chanPoint] 566 rs.mu.Unlock() 567 568 return finalTx, nil 569 } 570 571 func (rs *mockRetributionStore) Remove(key *wire.OutPoint) error { 572 rs.mu.Lock() 573 delete(rs.state, *key) 574 delete(rs.finalTxs, *key) 575 rs.mu.Unlock() 576 577 return nil 578 } 579 580 func (rs *mockRetributionStore) ForAll(cb func(*retributionInfo) error, 581 reset func()) error { 582 583 rs.mu.Lock() 584 defer rs.mu.Unlock() 585 586 reset() 587 for _, retInfo := range rs.state { 588 if err := cb(copyRetInfo(retInfo)); err != nil { 589 return err 590 } 591 } 592 593 return nil 594 } 595 596 var RetributionStoreTestSuite = []struct { 597 name string 598 test func(FailingRetributionStore, *testing.T) 599 }{ 600 { 601 "Initialization", 602 testRetributionStoreInit, 603 }, 604 { 605 "Add/Remove", 606 testRetributionStoreAddRemove, 607 }, 608 { 609 "Persistence", 610 testRetributionStorePersistence, 611 }, 612 { 613 "Overwrite", 614 testRetributionStoreOverwrite, 615 }, 616 { 617 "RemoveEmpty", 618 testRetributionStoreRemoveEmpty, 619 }, 620 } 621 622 // TestMockRetributionStore instantiates a mockRetributionStore and tests its 623 // behavior using the general RetributionStore test suite. 624 func TestMockRetributionStore(t *testing.T) { 625 for _, test := range RetributionStoreTestSuite { 626 t.Run( 627 "mockRetributionStore."+test.name, 628 func(tt *testing.T) { 629 mrs := newMockRetributionStore() 630 frs := newFailingRetributionStore( 631 func() RetributionStorer { return mrs }, 632 ) 633 test.test(frs, tt) 634 }, 635 ) 636 } 637 } 638 639 func makeTestChannelDB() (*channeldb.DB, func(), error) { 640 // First, create a temporary directory to be used for the duration of 641 // this test. 642 tempDirName, err := ioutil.TempDir("", "channeldb") 643 if err != nil { 644 return nil, nil, err 645 } 646 647 cleanUp := func() { 648 os.RemoveAll(tempDirName) 649 } 650 651 db, err := channeldb.Open(tempDirName) 652 if err != nil { 653 cleanUp() 654 return nil, nil, err 655 } 656 657 return db, cleanUp, nil 658 } 659 660 // TestChannelDBRetributionStore instantiates a RetributionStore backed by a 661 // channeldb.DB, and tests its behavior using the general RetributionStore test 662 // suite. 663 func TestChannelDBRetributionStore(t *testing.T) { 664 // Finally, instantiate retribution store and execute RetributionStore 665 // test suite. 666 for _, test := range RetributionStoreTestSuite { 667 t.Run( 668 "channeldbDBRetributionStore."+test.name, 669 func(tt *testing.T) { 670 db, cleanUp, err := makeTestChannelDB() 671 if err != nil { 672 t.Fatalf("unable to open channeldb: %v", err) 673 } 674 defer db.Close() 675 defer cleanUp() 676 677 restartDb := func() RetributionStorer { 678 // Close and reopen channeldb 679 if err = db.Close(); err != nil { 680 t.Fatalf("unable to close "+ 681 "channeldb during "+ 682 "restart: %v", 683 err) 684 } 685 db, err = channeldb.Open(db.Path()) 686 if err != nil { 687 t.Fatalf("unable to open "+ 688 "channeldb: %v", err) 689 } 690 691 return NewRetributionStore(db) 692 } 693 694 frs := newFailingRetributionStore(restartDb) 695 test.test(frs, tt) 696 }, 697 ) 698 } 699 } 700 701 // countRetributions uses a retribution store's ForAll to count the number of 702 // elements emitted from the store. 703 func countRetributions(t *testing.T, rs RetributionStorer) int { 704 count := 0 705 err := rs.ForAll(func(_ *retributionInfo) error { 706 count++ 707 return nil 708 }, func() { 709 count = 0 710 }) 711 if err != nil { 712 t.Fatalf("unable to list retributions in db: %v", err) 713 } 714 return count 715 } 716 717 // testRetributionStoreAddRemove executes a generic test suite for any concrete 718 // implementation of the RetributionStore interface. This test adds all 719 // retributions to the store, confirms that they are all present, and then 720 // removes each one individually. Between each addition or removal, the number 721 // of elements in the store is checked to ensure that it only changes by one. 722 func testRetributionStoreAddRemove(frs FailingRetributionStore, t *testing.T) { 723 // Make sure that a new retribution store is actually empty. 724 if count := countRetributions(t, frs); count != 0 { 725 t.Fatalf("expected 0 retributions, found %v", count) 726 } 727 728 // Add all retributions, check that ForAll returns the correct 729 // information, and then remove all retributions. 730 testRetributionStoreAdds(frs, t, false) 731 testRetributionStoreForAll(frs, t, false) 732 testRetributionStoreRemoves(frs, t, false) 733 } 734 735 // testRetributionStorePersistence executes the same general test as 736 // testRetributionStoreAddRemove, except that it also restarts the store between 737 // each operation to ensure that the results are properly persisted. 738 func testRetributionStorePersistence(frs FailingRetributionStore, t *testing.T) { 739 // Make sure that a new retribution store is still empty after failing 740 // right off the bat. 741 frs.Restart() 742 if count := countRetributions(t, frs); count != 0 { 743 t.Fatalf("expected 1 retributions, found %v", count) 744 } 745 746 // Insert all retributions into the database, restarting and checking 747 // between subsequent calls to test that each intermediate additions are 748 // persisted. 749 testRetributionStoreAdds(frs, t, true) 750 751 // After all retributions have been inserted, verify that the store 752 // emits a distinct set of retributions that are equivalent to the test 753 // vector. 754 testRetributionStoreForAll(frs, t, true) 755 756 // Remove all retributions from the database, restarting and checking 757 // between subsequent calls to test that each intermediate removals are 758 // persisted. 759 testRetributionStoreRemoves(frs, t, true) 760 } 761 762 // testRetributionStoreInit ensures that a retribution store is always 763 // initialized with no retributions. 764 func testRetributionStoreInit(frs FailingRetributionStore, t *testing.T) { 765 // Make sure that a new retribution store starts empty. 766 if count := countRetributions(t, frs); count != 0 { 767 t.Fatalf("expected 0 retributions, found %v", count) 768 } 769 } 770 771 // testRetributionStoreRemoveEmpty ensures that a retribution store will not 772 // fail or panic if it is instructed to remove an entry while empty. 773 func testRetributionStoreRemoveEmpty(frs FailingRetributionStore, t *testing.T) { 774 testRetributionStoreRemoves(frs, t, false) 775 } 776 777 // testRetributionStoreOverwrite ensures that attempts to write retribution 778 // information regarding a channel point that already exists does not change the 779 // total number of entries held by the retribution store. 780 func testRetributionStoreOverwrite(frs FailingRetributionStore, t *testing.T) { 781 // Initially, add all retributions to store. 782 testRetributionStoreAdds(frs, t, false) 783 784 // Overwrite the initial entries again. 785 for i, retInfo := range retributions { 786 if err := frs.Add(&retInfo); err != nil { 787 t.Fatalf("unable to add to retribution %v to store: %v", 788 i, err) 789 } 790 } 791 792 // Check that retribution store still has 2 entries. 793 if count := countRetributions(t, frs); count != 2 { 794 t.Fatalf("expected 2 retributions, found %v", count) 795 } 796 } 797 798 // testRetributionStoreAdds adds all of the test retributions to the database, 799 // ensuring that the total number of elements increases by exactly 1 after each 800 // operation. If the `failing` flag is provide, the test will restart the 801 // database and confirm that the delta is still 1. 802 func testRetributionStoreAdds( 803 frs FailingRetributionStore, 804 t *testing.T, 805 failing bool) { 806 807 // Iterate over retributions, adding each from the store. If we are 808 // testing the store under failures, we restart the store and verify 809 // that the contents are the same. 810 for i, retInfo := range retributions { 811 // Snapshot number of entries before and after the addition. 812 nbefore := countRetributions(t, frs) 813 if err := frs.Add(&retInfo); err != nil { 814 t.Fatalf("unable to add to retribution %v to store: %v", 815 i, err) 816 } 817 nafter := countRetributions(t, frs) 818 819 // Check that only one retribution was added. 820 if nafter-nbefore != 1 { 821 t.Fatalf("expected %v retributions, found %v", 822 nbefore+1, nafter) 823 } 824 825 if failing { 826 frs.Restart() 827 828 // Check that retribution store has persisted addition 829 // after restarting. 830 nrestart := countRetributions(t, frs) 831 if nrestart-nbefore != 1 { 832 t.Fatalf("expected %v retributions, found %v", 833 nbefore+1, nrestart) 834 } 835 } 836 } 837 } 838 839 // testRetributionStoreRemoves removes all of the test retributions to the 840 // database, ensuring that the total number of elements decreases by exactly 1 841 // after each operation. If the `failing` flag is provide, the test will 842 // restart the database and confirm that the delta is the same. 843 func testRetributionStoreRemoves( 844 frs FailingRetributionStore, 845 t *testing.T, 846 failing bool) { 847 848 // Iterate over retributions, removing each from the store. If we are 849 // testing the store under failures, we restart the store and verify 850 // that the contents are the same. 851 for i, retInfo := range retributions { 852 // Snapshot number of entries before and after the removal. 853 nbefore := countRetributions(t, frs) 854 err := frs.Remove(&retInfo.chanPoint) 855 switch { 856 case nbefore == 0 && err == nil: 857 858 case nbefore > 0 && err != nil: 859 t.Fatalf("unable to remove to retribution %v "+ 860 "from store: %v", i, err) 861 } 862 nafter := countRetributions(t, frs) 863 864 // If the store is empty, increment nbefore to simulate the 865 // removal of one element. 866 if nbefore == 0 { 867 nbefore++ 868 } 869 870 // Check that only one retribution was removed. 871 if nbefore-nafter != 1 { 872 t.Fatalf("expected %v retributions, found %v", 873 nbefore-1, nafter) 874 } 875 876 if failing { 877 frs.Restart() 878 879 // Check that retribution store has persisted removal 880 // after restarting. 881 nrestart := countRetributions(t, frs) 882 if nbefore-nrestart != 1 { 883 t.Fatalf("expected %v retributions, found %v", 884 nbefore-1, nrestart) 885 } 886 } 887 } 888 } 889 890 // testRetributionStoreForAll iterates over the current entries in the 891 // retribution store, ensuring that each entry in the database is unique, and 892 // corresponds to exactly one of the entries in the test vector. If the 893 // `failing` flag is provide, the test will restart the database and confirm 894 // that the entries again validate against the test vectors. 895 func testRetributionStoreForAll( 896 frs FailingRetributionStore, 897 t *testing.T, 898 failing bool) { 899 900 // nrets is the number of retributions in the test vector 901 nrets := len(retributions) 902 903 // isRestart indicates whether or not the database has been restarted. 904 // When testing for failures, this allows the test case to make a second 905 // attempt without causing a subsequent restart on the second pass. 906 var isRestart bool 907 908 restartCheck: 909 // Construct a set of all channel points presented by the store. Entries 910 // are only be added to the set if their corresponding retribution 911 // information matches the test vector. 912 var foundSet map[wire.OutPoint]struct{} 913 914 // Iterate through the stored retributions, checking to see if we have 915 // an equivalent retribution in the test vector. This will return an 916 // error unless all persisted retributions exist in the test vector. 917 if err := frs.ForAll(func(ret *retributionInfo) error { 918 // Fetch the retribution information from the test vector. If 919 // the entry does not exist, the test returns an error. 920 if exRetInfo, ok := retributionMap[ret.chanPoint]; ok { 921 // Compare the presented retribution information with 922 // the expected value, fail if they are inconsistent. 923 if !reflect.DeepEqual(ret, &exRetInfo) { 924 return fmt.Errorf("unexpected retribution "+ 925 "retrieved from db --\n"+ 926 "want: %#v\ngot: %#v", exRetInfo, ret, 927 ) 928 } 929 930 // Retribution information from database matches the 931 // test vector, record the channel point in the found 932 // map. 933 foundSet[ret.chanPoint] = struct{}{} 934 935 } else { 936 return fmt.Errorf("unknown retribution retrieved "+ 937 "from db: %v", ret) 938 } 939 940 return nil 941 }, func() { 942 foundSet = make(map[wire.OutPoint]struct{}) 943 }); err != nil { 944 t.Fatalf("failed to iterate over persistent retributions: %v", 945 err) 946 } 947 948 // Check that retribution store emits nrets entries 949 if count := countRetributions(t, frs); count != nrets { 950 t.Fatalf("expected %v retributions, found %v", nrets, count) 951 } 952 953 // Confirm that all of the retributions emitted from the iteration 954 // correspond to unique channel points. 955 nunique := len(foundSet) 956 if nunique != nrets { 957 t.Fatalf("expected %v unique retributions, only found %v", 958 nrets, nunique) 959 } 960 961 // If in failure mode on only on first pass, restart the database and 962 // rexecute the test. 963 if failing && !isRestart { 964 frs.Restart() 965 isRestart = true 966 967 goto restartCheck 968 } 969 } 970 971 func initBreachedState(t *testing.T) (*BreachArbiter, 972 *lnwallet.LightningChannel, *lnwallet.LightningChannel, 973 *lnwallet.LocalForceCloseSummary, chan *ContractBreachEvent, 974 func(), func()) { 975 // Create a pair of channels using a notifier that allows us to signal 976 // a spend of the funding transaction. Alice's channel will be the on 977 // observing a breach. 978 alice, bob, cleanUpChans, err := createInitChannels(1) 979 if err != nil { 980 t.Fatalf("unable to create test channels: %v", err) 981 } 982 983 // Instantiate a breach arbiter to handle the breach of alice's channel. 984 contractBreaches := make(chan *ContractBreachEvent) 985 986 brar, cleanUpArb, err := createTestArbiter( 987 t, contractBreaches, alice.State().Db.GetParentDB(), 988 ) 989 if err != nil { 990 t.Fatalf("unable to initialize test breach arbiter: %v", err) 991 } 992 993 // Send one HTLC to Bob and perform a state transition to lock it in. 994 htlcAmount := lnwire.NewMAtomsFromAtoms(20000) 995 htlc, _ := createHTLC(0, htlcAmount) 996 if _, err := alice.AddHTLC(htlc, nil); err != nil { 997 t.Fatalf("alice unable to add htlc: %v", err) 998 } 999 if _, err := bob.ReceiveHTLC(htlc); err != nil { 1000 t.Fatalf("bob unable to recv add htlc: %v", err) 1001 } 1002 if err := forceStateTransition(alice, bob); err != nil { 1003 t.Fatalf("Can't update the channel state: %v", err) 1004 } 1005 1006 // Generate the force close summary at this point in time, this will 1007 // serve as the old state bob will broadcast. 1008 bobClose, err := bob.ForceClose() 1009 if err != nil { 1010 t.Fatalf("unable to force close bob's channel: %v", err) 1011 } 1012 1013 // Now send another HTLC and perform a state transition, this ensures 1014 // Alice is ahead of the state Bob will broadcast. 1015 htlc2, _ := createHTLC(1, htlcAmount) 1016 if _, err := alice.AddHTLC(htlc2, nil); err != nil { 1017 t.Fatalf("alice unable to add htlc: %v", err) 1018 } 1019 if _, err := bob.ReceiveHTLC(htlc2); err != nil { 1020 t.Fatalf("bob unable to recv add htlc: %v", err) 1021 } 1022 if err := forceStateTransition(alice, bob); err != nil { 1023 t.Fatalf("Can't update the channel state: %v", err) 1024 } 1025 1026 return brar, alice, bob, bobClose, contractBreaches, cleanUpChans, 1027 cleanUpArb 1028 } 1029 1030 // TestBreachHandoffSuccess tests that a channel's close observer properly 1031 // delivers retribution information to the breach arbiter in response to a 1032 // breach close. This test verifies correctness in the event that the handoff 1033 // experiences no interruptions. 1034 func TestBreachHandoffSuccess(t *testing.T) { 1035 brar, alice, _, bobClose, contractBreaches, 1036 cleanUpChans, cleanUpArb := initBreachedState(t) 1037 defer cleanUpChans() 1038 defer cleanUpArb() 1039 1040 chanPoint := alice.ChanPoint 1041 1042 // Signal a spend of the funding transaction and wait for the close 1043 // observer to exit. 1044 processACK := make(chan error) 1045 breach := &ContractBreachEvent{ 1046 ChanPoint: *chanPoint, 1047 ProcessACK: func(brarErr error) { 1048 processACK <- brarErr 1049 }, 1050 BreachRetribution: &lnwallet.BreachRetribution{ 1051 BreachTransaction: bobClose.CloseTx, 1052 LocalOutputSignDesc: &input.SignDescriptor{ 1053 Output: &wire.TxOut{ 1054 PkScript: breachKeys[0], 1055 }, 1056 }, 1057 }, 1058 } 1059 contractBreaches <- breach 1060 1061 // We'll also wait to consume the ACK back from the breach arbiter. 1062 select { 1063 case err := <-processACK: 1064 if err != nil { 1065 t.Fatalf("handoff failed: %v", err) 1066 } 1067 case <-time.After(time.Second * 15): 1068 t.Fatalf("breach arbiter didn't send ack back") 1069 } 1070 1071 // After exiting, the breach arbiter should have persisted the 1072 // retribution information and the channel should be shown as pending 1073 // force closed. 1074 assertArbiterBreach(t, brar, chanPoint) 1075 1076 // Send another breach event. Since the handoff for this channel was 1077 // already ACKed, the breach arbiter should immediately ACK and ignore 1078 // this event. 1079 breach = &ContractBreachEvent{ 1080 ChanPoint: *chanPoint, 1081 ProcessACK: func(brarErr error) { 1082 processACK <- brarErr 1083 }, 1084 BreachRetribution: &lnwallet.BreachRetribution{ 1085 BreachTransaction: bobClose.CloseTx, 1086 LocalOutputSignDesc: &input.SignDescriptor{ 1087 Output: &wire.TxOut{ 1088 PkScript: breachKeys[0], 1089 }, 1090 }, 1091 }, 1092 } 1093 1094 contractBreaches <- breach 1095 1096 // We'll also wait to consume the ACK back from the breach arbiter. 1097 select { 1098 case err := <-processACK: 1099 if err != nil { 1100 t.Fatalf("handoff failed: %v", err) 1101 } 1102 case <-time.After(time.Second * 15): 1103 t.Fatalf("breach arbiter didn't send ack back") 1104 } 1105 1106 // State should not have changed. 1107 assertArbiterBreach(t, brar, chanPoint) 1108 } 1109 1110 // TestBreachHandoffFail tests that a channel's close observer properly 1111 // delivers retribution information to the breach arbiter in response to a 1112 // breach close. This test verifies correctness in the event that the breach 1113 // arbiter fails to write the information to disk, and that a subsequent attempt 1114 // at the handoff succeeds. 1115 func TestBreachHandoffFail(t *testing.T) { 1116 brar, alice, _, bobClose, contractBreaches, 1117 cleanUpChans, cleanUpArb := initBreachedState(t) 1118 defer cleanUpChans() 1119 defer cleanUpArb() 1120 1121 // Before alerting Alice of the breach, instruct our failing retribution 1122 // store to fail the next database operation, which we expect to write 1123 // the information handed off by the channel's close observer. 1124 fstore := brar.cfg.Store.(*failingRetributionStore) 1125 fstore.FailNextAdd(nil) 1126 1127 // Signal the notifier to dispatch spend notifications of the funding 1128 // transaction using the transaction from bob's closing summary. 1129 chanPoint := alice.ChanPoint 1130 processACK := make(chan error) 1131 breach := &ContractBreachEvent{ 1132 ChanPoint: *chanPoint, 1133 ProcessACK: func(brarErr error) { 1134 processACK <- brarErr 1135 }, 1136 BreachRetribution: &lnwallet.BreachRetribution{ 1137 BreachTransaction: bobClose.CloseTx, 1138 LocalOutputSignDesc: &input.SignDescriptor{ 1139 Output: &wire.TxOut{ 1140 PkScript: breachKeys[0], 1141 }, 1142 }, 1143 }, 1144 } 1145 contractBreaches <- breach 1146 1147 // We'll also wait to consume the ACK back from the breach arbiter. 1148 select { 1149 case err := <-processACK: 1150 if err == nil { 1151 t.Fatalf("breach write should have failed") 1152 } 1153 case <-time.After(time.Second * 15): 1154 t.Fatalf("breach arbiter didn't send ack back") 1155 } 1156 1157 // Since the handoff failed, the breach arbiter should not show the 1158 // channel as breached, and the channel should also not have been marked 1159 // pending closed. 1160 assertNoArbiterBreach(t, brar, chanPoint) 1161 assertNotPendingClosed(t, alice) 1162 1163 brar, cleanUpArb, err := createTestArbiter( 1164 t, contractBreaches, alice.State().Db.GetParentDB(), 1165 ) 1166 if err != nil { 1167 t.Fatalf("unable to initialize test breach arbiter: %v", err) 1168 } 1169 defer cleanUpArb() 1170 1171 // Signal a spend of the funding transaction and wait for the close 1172 // observer to exit. This time we are allowing the handoff to succeed. 1173 breach = &ContractBreachEvent{ 1174 ChanPoint: *chanPoint, 1175 ProcessACK: func(brarErr error) { 1176 processACK <- brarErr 1177 }, 1178 BreachRetribution: &lnwallet.BreachRetribution{ 1179 BreachTransaction: bobClose.CloseTx, 1180 LocalOutputSignDesc: &input.SignDescriptor{ 1181 Output: &wire.TxOut{ 1182 PkScript: breachKeys[0], 1183 }, 1184 }, 1185 }, 1186 } 1187 1188 contractBreaches <- breach 1189 1190 select { 1191 case err := <-processACK: 1192 if err != nil { 1193 t.Fatalf("handoff failed: %v", err) 1194 } 1195 case <-time.After(time.Second * 15): 1196 t.Fatalf("breach arbiter didn't send ack back") 1197 } 1198 1199 // Check that the breach was properly recorded in the breach arbiter, 1200 // and that the close observer marked the channel as pending closed 1201 // before exiting. 1202 assertArbiterBreach(t, brar, chanPoint) 1203 } 1204 1205 // TestBreachCreateJusticeTx tests that we create three different variants of 1206 // the justice tx. 1207 func TestBreachCreateJusticeTx(t *testing.T) { 1208 brar, _, _, _, _, cleanUpChans, cleanUpArb := initBreachedState(t) 1209 defer cleanUpChans() 1210 defer cleanUpArb() 1211 1212 // In this test we just want to check that the correct inputs are added 1213 // to the justice tx, not that we create a valid spend, so we just set 1214 // some params making the script generation succeed. 1215 aliceKeyPriv := secp256k1.PrivKeyFromBytes( 1216 channels.AlicesPrivKey, 1217 ) 1218 alicePubKey := aliceKeyPriv.PubKey() 1219 1220 signDesc := &breachedOutputs[0].signDesc 1221 signDesc.KeyDesc.PubKey = alicePubKey 1222 signDesc.DoubleTweak = aliceKeyPriv 1223 1224 // We'll test all the different types of outputs we'll sweep with the 1225 // justice tx. 1226 outputTypes := []input.StandardWitnessType{ 1227 input.CommitmentNoDelay, 1228 input.CommitSpendNoDelayTweakless, 1229 input.CommitmentToRemoteConfirmed, 1230 input.CommitmentRevoke, 1231 input.HtlcAcceptedRevoke, 1232 input.HtlcOfferedRevoke, 1233 input.HtlcSecondLevelRevoke, 1234 } 1235 1236 breachedOutputs := make([]breachedOutput, len(outputTypes)) 1237 for i, wt := range outputTypes { 1238 // Create a fake breached output for each type, ensuring they 1239 // have different outpoints for our logic to accept them. 1240 op := breachedOutputs[0].outpoint 1241 op.Index = uint32(i) 1242 breachedOutputs[i] = makeBreachedOutput( 1243 &op, 1244 wt, 1245 // Second level scripts doesn't matter in this test. 1246 nil, 1247 signDesc, 1248 1, 1249 ) 1250 } 1251 1252 // Create the justice transactions. 1253 justiceTxs, err := brar.createJusticeTx(breachedOutputs) 1254 require.NoError(t, err) 1255 require.NotNil(t, justiceTxs) 1256 1257 // The spendAll tx should be spending all the outputs. This is the 1258 // "regular" justice transaction type. 1259 require.Len(t, justiceTxs.spendAll.TxIn, len(breachedOutputs)) 1260 1261 // The spendCommitOuts tx should be spending the 4 typed of commit outs 1262 // (note that in practice there will be at most two commit outputs per 1263 // commmit, but we test all 4 types here). 1264 require.Len(t, justiceTxs.spendCommitOuts.TxIn, 4) 1265 1266 // Finally check that the spendHTLCs tx are spending the two revoked 1267 // HTLC types, and the second level type. 1268 require.Len(t, justiceTxs.spendHTLCs.TxIn, 3) 1269 } 1270 1271 type publAssertion func(*testing.T, map[wire.OutPoint]struct{}, 1272 chan *wire.MsgTx, chainhash.Hash) *wire.MsgTx 1273 1274 type breachTest struct { 1275 name string 1276 1277 // spend2ndLevel requests that second level htlcs be spent *again*, as 1278 // if by a remote party or watchtower. The outpoint of the second level 1279 // htlc is in effect "readded" to the set of inputs. 1280 spend2ndLevel bool 1281 1282 // sweepHtlc tests that the HTLC output is swept using the revocation 1283 // path in a separate tx. 1284 sweepHtlc bool 1285 1286 // sendFinalConf informs the test to send a confirmation for the justice 1287 // transaction before asserting the arbiter is cleaned up. 1288 sendFinalConf bool 1289 1290 // whenNonZeroInputs is called after spending an input but there are 1291 // further inputs to spend in the test. 1292 whenNonZeroInputs publAssertion 1293 1294 // whenZeroInputs is called after spending an input but there are no 1295 // further inputs to spend in the test. 1296 whenZeroInputs publAssertion 1297 } 1298 1299 type spendTxs struct { 1300 commitSpendTx *wire.MsgTx 1301 htlc2ndLevlTx *wire.MsgTx 1302 htlc2ndLevlSpend *wire.MsgTx 1303 htlcSweep *wire.MsgTx 1304 } 1305 1306 func getSpendTransactions(signer input.Signer, chanPoint *wire.OutPoint, 1307 retribution *lnwallet.BreachRetribution) (*spendTxs, error) { 1308 1309 localOutpoint := retribution.LocalOutpoint 1310 remoteOutpoint := retribution.RemoteOutpoint 1311 htlcOutpoint := retribution.HtlcRetributions[0].OutPoint 1312 1313 // commitSpendTx is used to spend commitment outputs. 1314 commitSpendTx := &wire.MsgTx{ 1315 TxIn: []*wire.TxIn{ 1316 { 1317 PreviousOutPoint: localOutpoint, 1318 }, 1319 { 1320 PreviousOutPoint: remoteOutpoint, 1321 }, 1322 }, 1323 TxOut: []*wire.TxOut{ 1324 {Value: 500000000}, 1325 }, 1326 } 1327 1328 // htlc2ndLevlTx is used to transition an htlc output on the commitment 1329 // transaction to a second level htlc. 1330 htlc2ndLevlTx := &wire.MsgTx{ 1331 TxIn: []*wire.TxIn{ 1332 { 1333 PreviousOutPoint: htlcOutpoint, 1334 }, 1335 }, 1336 TxOut: []*wire.TxOut{ 1337 {Value: 20000}, 1338 }, 1339 } 1340 1341 secondLvlOp := wire.OutPoint{ 1342 Hash: htlc2ndLevlTx.TxHash(), 1343 Index: 0, 1344 } 1345 1346 // htlcSpendTx is used to spend from a second level htlc. 1347 htlcSpendTx := &wire.MsgTx{ 1348 TxIn: []*wire.TxIn{ 1349 { 1350 PreviousOutPoint: secondLvlOp, 1351 }, 1352 }, 1353 1354 TxOut: []*wire.TxOut{ 1355 {Value: 10000}, 1356 }, 1357 } 1358 1359 // htlcSweep is used to spend the HTLC output directly using the 1360 // revocation key. 1361 htlcSweep := &wire.MsgTx{ 1362 TxIn: []*wire.TxIn{ 1363 { 1364 PreviousOutPoint: htlcOutpoint, 1365 }, 1366 }, 1367 TxOut: []*wire.TxOut{ 1368 {Value: 21000}, 1369 }, 1370 } 1371 1372 // In order for the breacharbiter to detect that it is being spent 1373 // using the revocation key, it will inspect the witness. Therefore 1374 // sign and add the witness to the HTLC sweep. 1375 retInfo := newRetributionInfo(chanPoint, retribution) 1376 1377 for i := range retInfo.breachedOutputs { 1378 inp := &retInfo.breachedOutputs[i] 1379 1380 // Find the HTLC output. so we can add the witness. 1381 switch inp.witnessType { 1382 case input.HtlcAcceptedRevoke: 1383 fallthrough 1384 case input.HtlcOfferedRevoke: 1385 inputScript, err := inp.CraftInputScript( 1386 signer, htlcSweep, 0, 1387 ) 1388 if err != nil { 1389 return nil, err 1390 } 1391 1392 htlcSweep.TxIn[0].SignatureScript, err = input.WitnessStackToSigScript(inputScript.Witness) 1393 if err != nil { 1394 return nil, err 1395 } 1396 } 1397 } 1398 1399 return &spendTxs{ 1400 commitSpendTx: commitSpendTx, 1401 htlc2ndLevlTx: htlc2ndLevlTx, 1402 htlc2ndLevlSpend: htlcSpendTx, 1403 htlcSweep: htlcSweep, 1404 }, nil 1405 } 1406 1407 var breachTests = []breachTest{ 1408 { 1409 name: "all spends", 1410 spend2ndLevel: true, 1411 whenNonZeroInputs: func(t *testing.T, 1412 inputs map[wire.OutPoint]struct{}, 1413 publTx chan *wire.MsgTx, _ chainhash.Hash) *wire.MsgTx { 1414 1415 var tx *wire.MsgTx 1416 select { 1417 case tx = <-publTx: 1418 case <-time.After(5 * time.Second): 1419 t.Fatalf("tx was not published") 1420 } 1421 1422 // The justice transaction should have the same number 1423 // of inputs as we are tracking in the test. 1424 if len(tx.TxIn) != len(inputs) { 1425 t.Fatalf("expected justice txn to have %d "+ 1426 "inputs, found %d", len(inputs), 1427 len(tx.TxIn)) 1428 } 1429 1430 // Ensure that each input exists on the justice 1431 // transaction. 1432 for in := range inputs { 1433 findInputIndex(t, in, tx) 1434 } 1435 1436 return tx 1437 }, 1438 whenZeroInputs: func(t *testing.T, 1439 inputs map[wire.OutPoint]struct{}, 1440 publTx chan *wire.MsgTx, _ chainhash.Hash) *wire.MsgTx { 1441 1442 // Sanity check to ensure the brar doesn't try to 1443 // broadcast another sweep, since all outputs have been 1444 // spent externally. 1445 select { 1446 case <-publTx: 1447 t.Fatalf("tx published unexpectedly") 1448 case <-time.After(50 * time.Millisecond): 1449 } 1450 1451 return nil 1452 }, 1453 }, 1454 { 1455 name: "commit spends, second level sweep", 1456 spend2ndLevel: false, 1457 sendFinalConf: true, 1458 whenNonZeroInputs: func(t *testing.T, 1459 inputs map[wire.OutPoint]struct{}, 1460 publTx chan *wire.MsgTx, _ chainhash.Hash) *wire.MsgTx { 1461 1462 var tx *wire.MsgTx 1463 select { 1464 case tx = <-publTx: 1465 case <-time.After(5 * time.Second): 1466 t.Fatalf("tx was not published") 1467 } 1468 1469 // The justice transaction should have the same number 1470 // of inputs as we are tracking in the test. 1471 if len(tx.TxIn) != len(inputs) { 1472 t.Fatalf("expected justice txn to have %d "+ 1473 "inputs, found %d", len(inputs), 1474 len(tx.TxIn)) 1475 } 1476 1477 // Ensure that each input exists on the justice 1478 // transaction. 1479 for in := range inputs { 1480 findInputIndex(t, in, tx) 1481 } 1482 1483 return tx 1484 }, 1485 whenZeroInputs: func(t *testing.T, 1486 inputs map[wire.OutPoint]struct{}, 1487 publTx chan *wire.MsgTx, 1488 htlc2ndLevlTxHash chainhash.Hash) *wire.MsgTx { 1489 1490 // Now a transaction attempting to spend from the second 1491 // level tx should be published instead. Let this 1492 // publish succeed by setting the publishing error to 1493 // nil. 1494 var tx *wire.MsgTx 1495 select { 1496 case tx = <-publTx: 1497 case <-time.After(5 * time.Second): 1498 t.Fatalf("tx was not published") 1499 } 1500 1501 // The commitment outputs should be gone, and there 1502 // should only be a single htlc spend. 1503 if len(tx.TxIn) != 1 { 1504 t.Fatalf("expect 1 htlc output, found %d "+ 1505 "outputs", len(tx.TxIn)) 1506 } 1507 1508 // The remaining TxIn previously attempting to spend 1509 // the HTLC outpoint should now be spending from the 1510 // second level tx. 1511 // 1512 // NOTE: Commitment outputs and htlc sweeps are spent 1513 // with a different transactions (and thus txids), 1514 // ensuring we aren't mistaking this for a different 1515 // output type. 1516 onlyInput := tx.TxIn[0].PreviousOutPoint.Hash 1517 if onlyInput != htlc2ndLevlTxHash { 1518 t.Fatalf("tx not attempting to spend second "+ 1519 "level tx, %v", tx.TxIn[0]) 1520 } 1521 1522 return tx 1523 }, 1524 }, 1525 { // nolint: dupl 1526 // Test that if the HTLC output is swept via the revoke path 1527 // (by us) in a separate tx, it will be handled correctly. 1528 name: "sweep htlc", 1529 sweepHtlc: true, 1530 whenNonZeroInputs: func(t *testing.T, 1531 inputs map[wire.OutPoint]struct{}, 1532 publTx chan *wire.MsgTx, _ chainhash.Hash) *wire.MsgTx { 1533 1534 var tx *wire.MsgTx 1535 select { 1536 case tx = <-publTx: 1537 case <-time.After(5 * time.Second): 1538 t.Fatalf("tx was not published") 1539 } 1540 1541 // The justice transaction should have the same number 1542 // of inputs as we are tracking in the test. 1543 if len(tx.TxIn) != len(inputs) { 1544 t.Fatalf("expected justice txn to have %d "+ 1545 "inputs, found %d", len(inputs), 1546 len(tx.TxIn)) 1547 } 1548 1549 // Ensure that each input exists on the justice 1550 // transaction. 1551 for in := range inputs { 1552 findInputIndex(t, in, tx) 1553 } 1554 1555 return tx 1556 }, 1557 whenZeroInputs: func(t *testing.T, 1558 inputs map[wire.OutPoint]struct{}, 1559 publTx chan *wire.MsgTx, _ chainhash.Hash) *wire.MsgTx { 1560 1561 // Sanity check to ensure the brar doesn't try to 1562 // broadcast another sweep, since all outputs have been 1563 // spent externally. 1564 select { 1565 case <-publTx: 1566 t.Fatalf("tx published unexpectedly") 1567 case <-time.After(50 * time.Millisecond): 1568 } 1569 1570 return nil 1571 }, 1572 }, 1573 } 1574 1575 // TestBreachSpends checks the behavior of the breach arbiter in response to 1576 // spend events on a channels outputs by asserting that it properly removes or 1577 // modifies the inputs from the justice txn. 1578 func TestBreachSpends(t *testing.T) { 1579 for _, test := range breachTests { 1580 tc := test 1581 t.Run(tc.name, func(t *testing.T) { 1582 testBreachSpends(t, tc) 1583 }) 1584 } 1585 } 1586 1587 func testBreachSpends(t *testing.T, test breachTest) { 1588 brar, alice, _, bobClose, contractBreaches, 1589 cleanUpChans, cleanUpArb := initBreachedState(t) 1590 defer cleanUpChans() 1591 defer cleanUpArb() 1592 1593 var ( 1594 height = bobClose.ChanSnapshot.CommitHeight 1595 forceCloseTx = bobClose.CloseTx 1596 chanPoint = alice.ChanPoint 1597 publTx = make(chan *wire.MsgTx) 1598 publErr error 1599 publMtx sync.Mutex 1600 ) 1601 1602 // Make PublishTransaction always return ErrDoubleSpend to begin with. 1603 publErr = lnwallet.ErrDoubleSpend 1604 brar.cfg.PublishTransaction = func(tx *wire.MsgTx, _ string) error { 1605 publMtx.Lock() 1606 err := publErr 1607 publMtx.Unlock() 1608 1609 select { 1610 case publTx <- tx: 1611 case <-brar.quit: 1612 return fmt.Errorf("brar quit") 1613 } 1614 1615 return err 1616 } 1617 1618 // Notify the breach arbiter about the breach. 1619 retribution, err := lnwallet.NewBreachRetribution( 1620 alice.State(), height, 1, 1621 ) 1622 if err != nil { 1623 t.Fatalf("unable to create breach retribution: %v", err) 1624 } 1625 1626 processACK := make(chan error) 1627 breach := &ContractBreachEvent{ 1628 ChanPoint: *chanPoint, 1629 ProcessACK: func(brarErr error) { 1630 processACK <- brarErr 1631 }, 1632 BreachRetribution: retribution, 1633 } 1634 select { 1635 case contractBreaches <- breach: 1636 case <-time.After(15 * time.Second): 1637 t.Fatalf("breach not delivered") 1638 } 1639 1640 // We'll also wait to consume the ACK back from the breach arbiter. 1641 select { 1642 case err := <-processACK: 1643 if err != nil { 1644 t.Fatalf("handoff failed: %v", err) 1645 } 1646 case <-time.After(time.Second * 15): 1647 t.Fatalf("breach arbiter didn't send ack back") 1648 } 1649 1650 state := alice.State() 1651 err = state.CloseChannel(&channeldb.ChannelCloseSummary{ 1652 ChanPoint: state.FundingOutpoint, 1653 ChainHash: state.ChainHash, 1654 RemotePub: state.IdentityPub, 1655 CloseType: channeldb.BreachClose, 1656 Capacity: state.Capacity, 1657 IsPending: true, 1658 ShortChanID: state.ShortChanID(), 1659 RemoteCurrentRevocation: state.RemoteCurrentRevocation, 1660 RemoteNextRevocation: state.RemoteNextRevocation, 1661 LocalChanConfig: state.LocalChanCfg, 1662 }) 1663 if err != nil { 1664 t.Fatalf("unable to close channel: %v", err) 1665 } 1666 1667 // After exiting, the breach arbiter should have persisted the 1668 // retribution information and the channel should be shown as pending 1669 // force closed. 1670 assertArbiterBreach(t, brar, chanPoint) 1671 1672 // Assert that the database sees the channel as pending close, otherwise 1673 // the breach arbiter won't be able to fully close it. 1674 assertPendingClosed(t, alice) 1675 1676 // Notify that the breaching transaction is confirmed, to trigger the 1677 // retribution logic. 1678 notifier := brar.cfg.Notifier.(*mock.SpendNotifier) 1679 1680 select { 1681 case notifier.ConfChan <- &chainntnfs.TxConfirmation{}: 1682 case <-time.After(15 * time.Second): 1683 t.Fatalf("conf not delivered") 1684 } 1685 1686 // The breach arbiter should attempt to sweep all outputs on the 1687 // breached commitment. We'll pretend that the HTLC output has been 1688 // spent by the channel counter party's second level tx already. 1689 var tx *wire.MsgTx 1690 select { 1691 case tx = <-publTx: 1692 case <-time.After(5 * time.Second): 1693 t.Fatalf("tx was not published") 1694 } 1695 1696 // All outputs should initially spend from the force closed txn. 1697 forceTxID := forceCloseTx.TxHash() 1698 for _, txIn := range tx.TxIn { 1699 if txIn.PreviousOutPoint.Hash != forceTxID { 1700 t.Fatalf("og justice tx not spending commitment") 1701 } 1702 } 1703 1704 localOutpoint := retribution.LocalOutpoint 1705 remoteOutpoint := retribution.RemoteOutpoint 1706 htlcOutpoint := retribution.HtlcRetributions[0].OutPoint 1707 1708 spendTxs, err := getSpendTransactions( 1709 brar.cfg.Signer, chanPoint, retribution, 1710 ) 1711 require.NoError(t, err) 1712 1713 // Construct a map from outpoint on the force close to the transaction 1714 // we want it to be spent by. As the test progresses, this map will be 1715 // updated to contain only the set of commitment or second level 1716 // outpoints that remain to be spent. 1717 spentBy := map[wire.OutPoint]*wire.MsgTx{ 1718 htlcOutpoint: spendTxs.htlc2ndLevlTx, 1719 localOutpoint: spendTxs.commitSpendTx, 1720 remoteOutpoint: spendTxs.commitSpendTx, 1721 } 1722 1723 // We also keep a map of those remaining outputs we expect the 1724 // breacharbiter to try and sweep. 1725 inputsToSweep := map[wire.OutPoint]struct{}{ 1726 htlcOutpoint: {}, 1727 localOutpoint: {}, 1728 remoteOutpoint: {}, 1729 } 1730 1731 htlc2ndLevlTx := spendTxs.htlc2ndLevlTx 1732 htlcSpendTx := spendTxs.htlc2ndLevlSpend 1733 1734 // If the test is checking sweep of the HTLC directly without the 1735 // second level, insert the sweep tx instead. 1736 if test.sweepHtlc { 1737 spentBy[htlcOutpoint] = spendTxs.htlcSweep 1738 } 1739 1740 // Until no more inputs to spend remain, deliver the spend events and 1741 // process the assertions prescribed by the test case. 1742 var justiceTx *wire.MsgTx 1743 for len(spentBy) > 0 { 1744 var ( 1745 op wire.OutPoint 1746 spendTx *wire.MsgTx 1747 ) 1748 1749 // Pick an outpoint at random from the set of inputs. 1750 for op, spendTx = range spentBy { 1751 delete(spentBy, op) 1752 break 1753 } 1754 1755 // Deliver the spend notification for the chosen transaction. 1756 notifier.Spend(&op, 2, spendTx) 1757 1758 // Since the remote just swept this input, we expect our next 1759 // justice transaction to not include them. 1760 delete(inputsToSweep, op) 1761 1762 // If this is the second-level spend, we must add the new 1763 // outpoint to our expected sweeps. 1764 spendTxID := spendTx.TxHash() 1765 if spendTxID == htlc2ndLevlTx.TxHash() { 1766 // Create the second level outpoint that will 1767 // be spent, the index is always zero for these 1768 // 1-in-1-out txns. 1769 spendOp := wire.OutPoint{Hash: spendTxID} 1770 inputsToSweep[spendOp] = struct{}{} 1771 1772 // When the second layer transfer is detected, add back 1773 // the outpoint of the second layer tx so that we can 1774 // spend it again. Only do so if the test requests this 1775 // behavior. 1776 if test.spend2ndLevel { 1777 spentBy[spendOp] = htlcSpendTx 1778 } 1779 } 1780 1781 if len(spentBy) > 0 { 1782 justiceTx = test.whenNonZeroInputs(t, inputsToSweep, publTx, htlc2ndLevlTx.TxHash()) 1783 } else { 1784 // Reset the publishing error so that any publication, 1785 // made by the breach arbiter, if any, will succeed. 1786 publMtx.Lock() 1787 publErr = nil 1788 publMtx.Unlock() 1789 justiceTx = test.whenZeroInputs(t, inputsToSweep, publTx, htlc2ndLevlTx.TxHash()) 1790 } 1791 } 1792 1793 // Deliver confirmation of sweep if the test expects it. Since we are 1794 // looking for the final justice tx to confirme, we deliver a spend of 1795 // all its inputs. 1796 if test.sendFinalConf { 1797 for _, txin := range justiceTx.TxIn { 1798 op := txin.PreviousOutPoint 1799 notifier.Spend(&op, 3, justiceTx) 1800 } 1801 } 1802 1803 // Assert that the channel is fully resolved. 1804 assertBrarCleanup(t, brar, alice.ChanPoint, alice.State().Db) 1805 } 1806 1807 // TestBreachDelayedJusticeConfirmation tests that the breach arbiter will 1808 // "split" the justice tx in case the first justice tx doesn't confirm within 1809 // a reasonable time. 1810 func TestBreachDelayedJusticeConfirmation(t *testing.T) { 1811 brar, alice, _, bobClose, contractBreaches, 1812 cleanUpChans, cleanUpArb := initBreachedState(t) 1813 defer cleanUpChans() 1814 defer cleanUpArb() 1815 1816 var ( 1817 height = bobClose.ChanSnapshot.CommitHeight 1818 blockHeight = int32(10) 1819 forceCloseTx = bobClose.CloseTx 1820 chanPoint = alice.ChanPoint 1821 publTx = make(chan *wire.MsgTx) 1822 ) 1823 1824 // Make PublishTransaction always return succeed. 1825 brar.cfg.PublishTransaction = func(tx *wire.MsgTx, _ string) error { 1826 select { 1827 case publTx <- tx: 1828 case <-brar.quit: 1829 return fmt.Errorf("brar quit") 1830 } 1831 return nil 1832 } 1833 1834 // Notify the breach arbiter about the breach. 1835 retribution, err := lnwallet.NewBreachRetribution( 1836 alice.State(), height, uint32(blockHeight), 1837 ) 1838 if err != nil { 1839 t.Fatalf("unable to create breach retribution: %v", err) 1840 } 1841 1842 processACK := make(chan error, 1) 1843 breach := &ContractBreachEvent{ 1844 ChanPoint: *chanPoint, 1845 ProcessACK: func(brarErr error) { 1846 processACK <- brarErr 1847 }, 1848 BreachRetribution: retribution, 1849 } 1850 1851 select { 1852 case contractBreaches <- breach: 1853 case <-time.After(defaultTimeout): 1854 t.Fatalf("breach not delivered") 1855 } 1856 1857 // We'll also wait to consume the ACK back from the breach arbiter. 1858 select { 1859 case err := <-processACK: 1860 if err != nil { 1861 t.Fatalf("handoff failed: %v", err) 1862 } 1863 case <-time.After(defaultTimeout): 1864 t.Fatalf("breach arbiter didn't send ack back") 1865 } 1866 1867 state := alice.State() 1868 err = state.CloseChannel(&channeldb.ChannelCloseSummary{ 1869 ChanPoint: state.FundingOutpoint, 1870 ChainHash: state.ChainHash, 1871 RemotePub: state.IdentityPub, 1872 CloseType: channeldb.BreachClose, 1873 Capacity: state.Capacity, 1874 IsPending: true, 1875 ShortChanID: state.ShortChanID(), 1876 RemoteCurrentRevocation: state.RemoteCurrentRevocation, 1877 RemoteNextRevocation: state.RemoteNextRevocation, 1878 LocalChanConfig: state.LocalChanCfg, 1879 }) 1880 if err != nil { 1881 t.Fatalf("unable to close channel: %v", err) 1882 } 1883 1884 // After exiting, the breach arbiter should have persisted the 1885 // retribution information and the channel should be shown as pending 1886 // force closed. 1887 assertArbiterBreach(t, brar, chanPoint) 1888 1889 // Assert that the database sees the channel as pending close, otherwise 1890 // the breach arbiter won't be able to fully close it. 1891 assertPendingClosed(t, alice) 1892 1893 // Notify that the breaching transaction is confirmed, to trigger the 1894 // retribution logic. 1895 notifier := brar.cfg.Notifier.(*mock.SpendNotifier) 1896 1897 select { 1898 case notifier.ConfChan <- &chainntnfs.TxConfirmation{}: 1899 case <-time.After(defaultTimeout): 1900 t.Fatalf("conf not delivered") 1901 } 1902 1903 // The breach arbiter should attempt to sweep all outputs on the 1904 // breached commitment. 1905 var justiceTx *wire.MsgTx 1906 select { 1907 case justiceTx = <-publTx: 1908 case <-time.After(defaultTimeout): 1909 t.Fatalf("tx was not published") 1910 } 1911 1912 require.Len(t, justiceTx.TxIn, 3) 1913 1914 // All outputs should initially spend from the force closed txn. 1915 forceTxID := forceCloseTx.TxHash() 1916 for _, txIn := range justiceTx.TxIn { 1917 if txIn.PreviousOutPoint.Hash != forceTxID { 1918 t.Fatalf("og justice tx not spending commitment") 1919 } 1920 } 1921 1922 // Now we'll pretend some blocks pass without the justice tx 1923 // confirming. 1924 const pollInterval = 500 * time.Millisecond 1925 for i := int32(0); i <= 3; i++ { 1926 notifier.EpochChan <- &chainntnfs.BlockEpoch{ 1927 Height: blockHeight + i, 1928 } 1929 1930 // On every epoch, check that no new tx is published. 1931 select { 1932 case <-publTx: 1933 t.Fatalf("tx was published") 1934 case <-time.After(pollInterval): 1935 } 1936 } 1937 1938 // Now mine another block without the justice tx confirming. This 1939 // should lead to the breacharbiter publishing the split justice tx 1940 // variants. 1941 notifier.EpochChan <- &chainntnfs.BlockEpoch{ 1942 Height: blockHeight + 4, 1943 } 1944 1945 var ( 1946 splits []*wire.MsgTx 1947 spending = make(map[wire.OutPoint]struct{}) 1948 maxIndex = uint32(len(forceCloseTx.TxOut)) - 1 1949 ) 1950 for i := 0; i < 2; i++ { 1951 1952 var tx *wire.MsgTx 1953 select { 1954 case tx = <-publTx: 1955 splits = append(splits, tx) 1956 1957 case <-time.After(defaultTimeout): 1958 t.Fatalf("tx not published") 1959 } 1960 1961 // Check that every input is from the breached tx and that 1962 // there are no duplicates. 1963 for _, in := range tx.TxIn { 1964 op := in.PreviousOutPoint 1965 _, ok := spending[op] 1966 if ok { 1967 t.Fatal("already spent") 1968 } 1969 1970 if op.Hash != forceTxID || op.Index > maxIndex { 1971 t.Fatalf("not spending breach") 1972 } 1973 1974 spending[op] = struct{}{} 1975 } 1976 } 1977 1978 // All the inputs from the original justice transaction should have 1979 // been spent by the 2 splits. 1980 require.Len(t, spending, len(justiceTx.TxIn)) 1981 require.Len(t, splits, 2) 1982 1983 // Notify that the first split confirm, making the breach arbiter 1984 // publish another TX with the remaining inputs. 1985 for _, in := range splits[0].TxIn { 1986 op := &in.PreviousOutPoint 1987 notifier.Spend(op, blockHeight+5, splits[0]) 1988 } 1989 1990 select { 1991 1992 // The published tx should spend the same inputs as our second split. 1993 case tx := <-publTx: 1994 require.Len(t, tx.TxIn, len(splits[1].TxIn)) 1995 for i := range tx.TxIn { 1996 require.Equal( 1997 t, tx.TxIn[i].PreviousOutPoint, 1998 splits[1].TxIn[i].PreviousOutPoint, 1999 ) 2000 } 2001 2002 case <-time.After(defaultTimeout): 2003 t.Fatalf("tx not published") 2004 } 2005 2006 // Finally notify that the second split confirms, making the breach 2007 // arbiter clean up since all inputs have been swept. 2008 for _, in := range splits[1].TxIn { 2009 op := &in.PreviousOutPoint 2010 notifier.Spend(op, blockHeight+6, splits[1]) 2011 } 2012 2013 // Assert that the channel is fully resolved. 2014 assertBrarCleanup(t, brar, alice.ChanPoint, alice.State().Db) 2015 } 2016 2017 // findInputIndex returns the index of the input that spends from the given 2018 // outpoint. This method fails if the outpoint is not found. 2019 func findInputIndex(t *testing.T, op wire.OutPoint, tx *wire.MsgTx) int { 2020 t.Helper() 2021 2022 inputIdx := -1 2023 for i, txIn := range tx.TxIn { 2024 if txIn.PreviousOutPoint == op { 2025 inputIdx = i 2026 } 2027 } 2028 if inputIdx == -1 { 2029 t.Fatalf("input %v in not found", op) 2030 } 2031 2032 return inputIdx 2033 } 2034 2035 // assertArbiterBreach checks that the breach arbiter has persisted the breach 2036 // information for a particular channel. 2037 func assertArbiterBreach(t *testing.T, brar *BreachArbiter, 2038 chanPoint *wire.OutPoint) { 2039 2040 t.Helper() 2041 2042 isBreached, err := brar.IsBreached(chanPoint) 2043 if err != nil { 2044 t.Fatalf("unable to determine if channel is "+ 2045 "breached: %v", err) 2046 } 2047 2048 if !isBreached { 2049 t.Fatalf("channel %v was never marked breached", 2050 chanPoint) 2051 } 2052 2053 } 2054 2055 // assertNoArbiterBreach checks that the breach arbiter has not persisted the 2056 // breach information for a particular channel. 2057 func assertNoArbiterBreach(t *testing.T, brar *BreachArbiter, 2058 chanPoint *wire.OutPoint) { 2059 2060 t.Helper() 2061 2062 isBreached, err := brar.IsBreached(chanPoint) 2063 if err != nil { 2064 t.Fatalf("unable to determine if channel is "+ 2065 "breached: %v", err) 2066 } 2067 2068 if isBreached { 2069 t.Fatalf("channel %v was marked breached", 2070 chanPoint) 2071 } 2072 } 2073 2074 // assertBrarCleanup blocks until the given channel point has been removed the 2075 // retribution store and the channel is fully closed in the database. 2076 func assertBrarCleanup(t *testing.T, brar *BreachArbiter, 2077 chanPoint *wire.OutPoint, db *channeldb.ChannelStateDB) { 2078 2079 t.Helper() 2080 2081 err := wait.NoError(func() error { 2082 isBreached, err := brar.IsBreached(chanPoint) 2083 if err != nil { 2084 return err 2085 } 2086 2087 if isBreached { 2088 return fmt.Errorf("channel %v still breached", 2089 chanPoint) 2090 } 2091 2092 closedChans, err := db.FetchClosedChannels(false) 2093 if err != nil { 2094 return err 2095 } 2096 2097 for _, channel := range closedChans { 2098 switch { 2099 // Wrong channel. 2100 case channel.ChanPoint != *chanPoint: 2101 continue 2102 2103 // Right channel, fully closed! 2104 case !channel.IsPending: 2105 return nil 2106 } 2107 2108 // Still pending. 2109 return fmt.Errorf("channel %v still pending "+ 2110 "close", chanPoint) 2111 } 2112 2113 return fmt.Errorf("channel %v not closed", chanPoint) 2114 2115 }, 5*time.Second) 2116 if err != nil { 2117 t.Fatalf(err.Error()) 2118 } 2119 } 2120 2121 // assertPendingClosed checks that the channel has been marked pending closed in 2122 // the channel database. 2123 func assertPendingClosed(t *testing.T, c *lnwallet.LightningChannel) { 2124 t.Helper() 2125 2126 closedChans, err := c.State().Db.FetchClosedChannels(true) 2127 if err != nil { 2128 t.Fatalf("unable to load pending closed channels: %v", err) 2129 } 2130 2131 for _, chanSummary := range closedChans { 2132 if chanSummary.ChanPoint == *c.ChanPoint { 2133 return 2134 } 2135 } 2136 2137 t.Fatalf("channel %v was not marked pending closed", c.ChanPoint) 2138 } 2139 2140 // assertNotPendingClosed checks that the channel has not been marked pending 2141 // closed in the channel database. 2142 func assertNotPendingClosed(t *testing.T, c *lnwallet.LightningChannel) { 2143 t.Helper() 2144 2145 closedChans, err := c.State().Db.FetchClosedChannels(true) 2146 if err != nil { 2147 t.Fatalf("unable to load pending closed channels: %v", err) 2148 } 2149 2150 for _, chanSummary := range closedChans { 2151 if chanSummary.ChanPoint == *c.ChanPoint { 2152 t.Fatalf("channel %v was marked pending closed", 2153 c.ChanPoint) 2154 } 2155 } 2156 } 2157 2158 // createTestArbiter instantiates a breach arbiter with a failing retribution 2159 // store, so that controlled failures can be tested. 2160 func createTestArbiter(t *testing.T, contractBreaches chan *ContractBreachEvent, 2161 db *channeldb.DB) (*BreachArbiter, func(), error) { 2162 2163 // Create a failing retribution store, that wraps a normal one. 2164 store := newFailingRetributionStore(func() RetributionStorer { 2165 return NewRetributionStore(db) 2166 }) 2167 2168 aliceKeyPriv := secp256k1.PrivKeyFromBytes(channels.AlicesPrivKey) 2169 signer := &mock.SingleSigner{Privkey: aliceKeyPriv} 2170 2171 // Assemble our test arbiter. 2172 notifier := mock.MakeMockSpendNotifier() 2173 ba := NewBreachArbiter(&BreachConfig{ 2174 CloseLink: func(_ *wire.OutPoint, _ ChannelCloseType) {}, 2175 DB: db.ChannelStateDB(), 2176 Estimator: chainfee.NewStaticEstimator(12500, 0), 2177 GenSweepScript: func() ([]byte, error) { return nil, nil }, 2178 ContractBreaches: contractBreaches, 2179 Signer: signer, 2180 Notifier: notifier, 2181 PublishTransaction: func(_ *wire.MsgTx, _ string) error { return nil }, 2182 Store: store, 2183 NetParams: chaincfg.RegNetParams(), 2184 }) 2185 2186 if err := ba.Start(); err != nil { 2187 return nil, nil, err 2188 } 2189 2190 // The caller is responsible for closing the database. 2191 cleanUp := func() { 2192 ba.Stop() 2193 } 2194 2195 return ba, cleanUp, nil 2196 } 2197 2198 // createInitChannels creates two initialized test channels funded with 10 DCR, 2199 // with 5 DCR allocated to each side. Within the channel, Alice is the 2200 // initiator. 2201 func createInitChannels(revocationWindow int) (*lnwallet.LightningChannel, *lnwallet.LightningChannel, func(), error) { 2202 2203 chainParams := chaincfg.RegNetParams() 2204 2205 aliceKeyPriv, aliceKeyPub := channels.PrivKeyFromBytes(channels.AlicesPrivKey) 2206 bobKeyPriv, bobKeyPub := channels.PrivKeyFromBytes(channels.BobsPrivKey) 2207 2208 channelCapacity, err := dcrutil.NewAmount(10) 2209 if err != nil { 2210 return nil, nil, nil, err 2211 } 2212 2213 estimator := chainfee.NewStaticEstimator(1e4, 0) 2214 feePerKB, err := estimator.EstimateFeePerKB(1) 2215 if err != nil { 2216 return nil, nil, nil, err 2217 } 2218 initiatorFee := feePerKB.FeeForSize(input.EstimateCommitmentTxSize(0)) 2219 2220 channelBal := channelCapacity / 2 2221 aliceDustLimit := dcrutil.Amount(6030) 2222 bobDustLimit := dcrutil.Amount(12060) 2223 csvTimeoutAlice := uint32(5) 2224 csvTimeoutBob := uint32(4) 2225 2226 prevOut := &wire.OutPoint{ 2227 Hash: channels.TestHdSeed, 2228 Index: 0, 2229 } 2230 fundingTxIn := wire.NewTxIn(prevOut, int64(channelCapacity), nil) 2231 2232 aliceCfg := channeldb.ChannelConfig{ 2233 ChannelConstraints: channeldb.ChannelConstraints{ 2234 DustLimit: aliceDustLimit, 2235 MaxPendingAmount: lnwire.MilliAtom(rand.Int63()), 2236 ChanReserve: 0, 2237 MinHTLC: 0, 2238 MaxAcceptedHtlcs: uint16(rand.Int31()), 2239 CsvDelay: uint16(csvTimeoutAlice), 2240 }, 2241 MultiSigKey: keychain.KeyDescriptor{ 2242 PubKey: aliceKeyPub, 2243 }, 2244 RevocationBasePoint: keychain.KeyDescriptor{ 2245 PubKey: aliceKeyPub, 2246 }, 2247 PaymentBasePoint: keychain.KeyDescriptor{ 2248 PubKey: aliceKeyPub, 2249 }, 2250 DelayBasePoint: keychain.KeyDescriptor{ 2251 PubKey: aliceKeyPub, 2252 }, 2253 HtlcBasePoint: keychain.KeyDescriptor{ 2254 PubKey: aliceKeyPub, 2255 }, 2256 } 2257 bobCfg := channeldb.ChannelConfig{ 2258 ChannelConstraints: channeldb.ChannelConstraints{ 2259 DustLimit: bobDustLimit, 2260 MaxPendingAmount: lnwire.MilliAtom(rand.Int63()), 2261 ChanReserve: 0, 2262 MinHTLC: 0, 2263 MaxAcceptedHtlcs: uint16(rand.Int31()), 2264 CsvDelay: uint16(csvTimeoutBob), 2265 }, 2266 MultiSigKey: keychain.KeyDescriptor{ 2267 PubKey: bobKeyPub, 2268 }, 2269 RevocationBasePoint: keychain.KeyDescriptor{ 2270 PubKey: bobKeyPub, 2271 }, 2272 PaymentBasePoint: keychain.KeyDescriptor{ 2273 PubKey: bobKeyPub, 2274 }, 2275 DelayBasePoint: keychain.KeyDescriptor{ 2276 PubKey: bobKeyPub, 2277 }, 2278 HtlcBasePoint: keychain.KeyDescriptor{ 2279 PubKey: bobKeyPub, 2280 }, 2281 } 2282 2283 bobRoot, err := shachain.NewHash(bobKeyPriv.Serialize()) 2284 if err != nil { 2285 return nil, nil, nil, err 2286 } 2287 bobPreimageProducer := shachain.NewRevocationProducer(*bobRoot) 2288 bobFirstRevoke, err := bobPreimageProducer.AtIndex(0) 2289 if err != nil { 2290 return nil, nil, nil, err 2291 } 2292 bobCommitPoint := input.ComputeCommitmentPoint(bobFirstRevoke[:]) 2293 2294 aliceRoot, err := shachain.NewHash(aliceKeyPriv.Serialize()) 2295 if err != nil { 2296 return nil, nil, nil, err 2297 } 2298 alicePreimageProducer := shachain.NewRevocationProducer(*aliceRoot) 2299 aliceFirstRevoke, err := alicePreimageProducer.AtIndex(0) 2300 if err != nil { 2301 return nil, nil, nil, err 2302 } 2303 aliceCommitPoint := input.ComputeCommitmentPoint(aliceFirstRevoke[:]) 2304 2305 aliceCommitTx, bobCommitTx, err := lnwallet.CreateCommitmentTxns( 2306 channelBal-initiatorFee, channelBal, &aliceCfg, &bobCfg, aliceCommitPoint, 2307 bobCommitPoint, *fundingTxIn, channeldb.SingleFunderTweaklessBit, 2308 false, 0, chainParams, 2309 ) 2310 if err != nil { 2311 return nil, nil, nil, err 2312 } 2313 2314 alicePath, err := ioutil.TempDir("", "alicedb") 2315 if err != nil { 2316 return nil, nil, nil, err 2317 } 2318 dbAlice, err := channeldb.Open(alicePath) 2319 if err != nil { 2320 return nil, nil, nil, err 2321 } 2322 2323 bobPath, err := ioutil.TempDir("", "bobdb") 2324 if err != nil { 2325 return nil, nil, nil, err 2326 } 2327 dbBob, err := channeldb.Open(bobPath) 2328 if err != nil { 2329 return nil, nil, nil, err 2330 } 2331 2332 commitFee := initiatorFee 2333 2334 // TODO(roasbeef): need to factor in commit fee? 2335 aliceCommit := channeldb.ChannelCommitment{ 2336 CommitHeight: 0, 2337 LocalBalance: lnwire.NewMAtomsFromAtoms(channelBal - commitFee), 2338 RemoteBalance: lnwire.NewMAtomsFromAtoms(channelBal), 2339 FeePerKB: dcrutil.Amount(feePerKB), 2340 CommitFee: 3640, 2341 CommitTx: aliceCommitTx, 2342 CommitSig: bytes.Repeat([]byte{1}, 71), 2343 } 2344 bobCommit := channeldb.ChannelCommitment{ 2345 CommitHeight: 0, 2346 LocalBalance: lnwire.NewMAtomsFromAtoms(channelBal), 2347 RemoteBalance: lnwire.NewMAtomsFromAtoms(channelBal - commitFee), 2348 FeePerKB: dcrutil.Amount(feePerKB), 2349 CommitFee: 3640, 2350 CommitTx: bobCommitTx, 2351 CommitSig: bytes.Repeat([]byte{1}, 71), 2352 } 2353 2354 var chanIDBytes [8]byte 2355 if _, err := io.ReadFull(crand.Reader, chanIDBytes[:]); err != nil { 2356 return nil, nil, nil, err 2357 } 2358 2359 shortChanID := lnwire.NewShortChanIDFromInt( 2360 binary.BigEndian.Uint64(chanIDBytes[:]), 2361 ) 2362 2363 aliceChannelState := &channeldb.OpenChannel{ 2364 LocalChanCfg: aliceCfg, 2365 RemoteChanCfg: bobCfg, 2366 IdentityPub: aliceKeyPub, 2367 FundingOutpoint: *prevOut, 2368 ShortChannelID: shortChanID, 2369 ChanType: channeldb.SingleFunderTweaklessBit, 2370 IsInitiator: true, 2371 Capacity: channelCapacity, 2372 RemoteCurrentRevocation: bobCommitPoint, 2373 RevocationProducer: alicePreimageProducer, 2374 RevocationStore: shachain.NewRevocationStore(), 2375 LocalCommitment: aliceCommit, 2376 RemoteCommitment: aliceCommit, 2377 Db: dbAlice.ChannelStateDB(), 2378 Packager: channeldb.NewChannelPackager(shortChanID), 2379 FundingTxn: channels.TestFundingTx, 2380 } 2381 bobChannelState := &channeldb.OpenChannel{ 2382 LocalChanCfg: bobCfg, 2383 RemoteChanCfg: aliceCfg, 2384 IdentityPub: bobKeyPub, 2385 FundingOutpoint: *prevOut, 2386 ShortChannelID: shortChanID, 2387 ChanType: channeldb.SingleFunderTweaklessBit, 2388 IsInitiator: false, 2389 Capacity: channelCapacity, 2390 RemoteCurrentRevocation: aliceCommitPoint, 2391 RevocationProducer: bobPreimageProducer, 2392 RevocationStore: shachain.NewRevocationStore(), 2393 LocalCommitment: bobCommit, 2394 RemoteCommitment: bobCommit, 2395 Db: dbBob.ChannelStateDB(), 2396 Packager: channeldb.NewChannelPackager(shortChanID), 2397 } 2398 2399 aliceSigner := &mock.SingleSigner{Privkey: aliceKeyPriv} 2400 bobSigner := &mock.SingleSigner{Privkey: bobKeyPriv} 2401 2402 alicePool := lnwallet.NewSigPool(1, aliceSigner) 2403 channelAlice, err := lnwallet.NewLightningChannel( 2404 aliceSigner, aliceChannelState, alicePool, chainParams, 2405 ) 2406 if err != nil { 2407 return nil, nil, nil, err 2408 } 2409 alicePool.Start() 2410 2411 bobPool := lnwallet.NewSigPool(1, bobSigner) 2412 channelBob, err := lnwallet.NewLightningChannel( 2413 bobSigner, bobChannelState, bobPool, chainParams, 2414 ) 2415 if err != nil { 2416 return nil, nil, nil, err 2417 } 2418 bobPool.Start() 2419 2420 addr := &net.TCPAddr{ 2421 IP: net.ParseIP("127.0.0.1"), 2422 Port: 18556, 2423 } 2424 if err := channelAlice.State().SyncPending(addr, 101); err != nil { 2425 return nil, nil, nil, err 2426 } 2427 2428 addr = &net.TCPAddr{ 2429 IP: net.ParseIP("127.0.0.1"), 2430 Port: 18555, 2431 } 2432 if err := channelBob.State().SyncPending(addr, 101); err != nil { 2433 return nil, nil, nil, err 2434 } 2435 2436 cleanUpFunc := func() { 2437 dbBob.Close() 2438 dbAlice.Close() 2439 os.RemoveAll(bobPath) 2440 os.RemoveAll(alicePath) 2441 } 2442 2443 // Now that the channel are open, simulate the start of a session by 2444 // having Alice and Bob extend their revocation windows to each other. 2445 err = initRevocationWindows(channelAlice, channelBob, revocationWindow) 2446 if err != nil { 2447 return nil, nil, nil, err 2448 } 2449 2450 return channelAlice, channelBob, cleanUpFunc, nil 2451 } 2452 2453 // initRevocationWindows simulates a new channel being opened within the p2p 2454 // network by populating the initial revocation windows of the passed 2455 // commitment state machines. 2456 // 2457 // TODO(conner) remove code duplication 2458 func initRevocationWindows(chanA, chanB *lnwallet.LightningChannel, windowSize int) error { 2459 aliceNextRevoke, err := chanA.NextRevocationKey() 2460 if err != nil { 2461 return err 2462 } 2463 if err := chanB.InitNextRevocation(aliceNextRevoke); err != nil { 2464 return err 2465 } 2466 2467 bobNextRevoke, err := chanB.NextRevocationKey() 2468 if err != nil { 2469 return err 2470 } 2471 if err := chanA.InitNextRevocation(bobNextRevoke); err != nil { 2472 return err 2473 } 2474 2475 return nil 2476 } 2477 2478 // createHTLC is a utility function for generating an HTLC with a given 2479 // preimage and a given amount. 2480 // TODO(conner) remove code duplication 2481 func createHTLC(data int, amount lnwire.MilliAtom) (*lnwire.UpdateAddHTLC, [32]byte) { 2482 preimage := bytes.Repeat([]byte{byte(data)}, 32) 2483 paymentHash := sha256.Sum256(preimage) 2484 2485 var returnPreimage [32]byte 2486 copy(returnPreimage[:], preimage) 2487 2488 return &lnwire.UpdateAddHTLC{ 2489 ID: uint64(data), 2490 PaymentHash: paymentHash, 2491 Amount: amount, 2492 Expiry: uint32(5), 2493 }, returnPreimage 2494 } 2495 2496 // forceStateTransition executes the necessary interaction between the two 2497 // commitment state machines to transition to a new state locking in any 2498 // pending updates. 2499 // TODO(conner) remove code duplication 2500 func forceStateTransition(chanA, chanB *lnwallet.LightningChannel) error { 2501 aliceSig, aliceHtlcSigs, _, err := chanA.SignNextCommitment() 2502 if err != nil { 2503 return fmt.Errorf("error on chanA.SignNextCommitment: %v", err) 2504 } 2505 if err = chanB.ReceiveNewCommitment(aliceSig, aliceHtlcSigs); err != nil { 2506 return fmt.Errorf("error on chanB.ReceiveNewCommitment: %v", err) 2507 } 2508 2509 bobRevocation, _, err := chanB.RevokeCurrentCommitment() 2510 if err != nil { 2511 return fmt.Errorf("error on chanB.RevokeCurrentCommitment: %v", err) 2512 } 2513 bobSig, bobHtlcSigs, _, err := chanB.SignNextCommitment() 2514 if err != nil { 2515 return fmt.Errorf("error on chanB.SignNextCommitment: %v", err) 2516 } 2517 2518 _, _, _, _, err = chanA.ReceiveRevocation(bobRevocation) 2519 if err != nil { 2520 return err 2521 } 2522 if err := chanA.ReceiveNewCommitment(bobSig, bobHtlcSigs); err != nil { 2523 return fmt.Errorf("error on chanA.ReceiveNewCommitment: %v", err) 2524 } 2525 2526 aliceRevocation, _, err := chanA.RevokeCurrentCommitment() 2527 if err != nil { 2528 return fmt.Errorf("error on chanA.RevokeCurrentCommitment: %v", err) 2529 } 2530 _, _, _, _, err = chanB.ReceiveRevocation(aliceRevocation) 2531 if err != nil { 2532 return err 2533 } 2534 2535 return nil 2536 }