github.com/decred/dcrlnd@v0.7.6/lnwallet/revocation_producer_itest.go (about) 1 //go:build rpctest 2 // +build rpctest 3 4 package lnwallet 5 6 import ( 7 "github.com/decred/dcrd/chaincfg/chainhash" 8 "github.com/decred/dcrlnd/keychain" 9 "github.com/decred/dcrlnd/shachain" 10 ) 11 12 // nextRevocationProducer creates a new revocation producer, deriving the 13 // revocation root by applying ECDH to a new key from our revocation root family 14 // and the multisig key we use for the channel. 15 func (l *LightningWallet) nextRevocationProducer(res *ChannelReservation, 16 keyRing keychain.KeyRing) (shachain.Producer, error) { 17 18 // Derive the next key in the revocation root family. 19 nextRevocationKeyDesc, err := keyRing.DeriveNextKey( 20 keychain.KeyFamilyRevocationRoot, 21 ) 22 if err != nil { 23 return nil, err 24 } 25 26 // Within our itests, we want to make sure we can still restore channel 27 // backups created with the old revocation root derivation method. To 28 // create a channel in the legacy format during the test, we signal this 29 // by setting an explicit pending channel ID. The ID is the hex 30 // representation of the string "legacy-revocation". 31 itestLegacyFormatChanID := [32]byte{ 32 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x2d, 0x72, 0x65, 0x76, 33 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 34 } 35 if res.pendingChanID == itestLegacyFormatChanID { 36 revocationRoot, err := l.DerivePrivKey(nextRevocationKeyDesc) 37 if err != nil { 38 return nil, err 39 } 40 41 // Once we have the root, we can then generate our shachain 42 // producer and from that generate the per-commitment point. 43 revRoot, err := chainhash.NewHash(revocationRoot.Serialize()) 44 if err != nil { 45 return nil, err 46 } 47 48 return shachain.NewRevocationProducer(shachain.ShaHash(*revRoot)), nil 49 } 50 51 // If the DeriveNextKey call returns the first key with Index 0, we need 52 // to re-derive the key as the keychain/btcwallet.go DerivePrivKey call 53 // special-cases Index 0. 54 if nextRevocationKeyDesc.Index == 0 { 55 nextRevocationKeyDesc, err = keyRing.DeriveNextKey( 56 keychain.KeyFamilyRevocationRoot, 57 ) 58 if err != nil { 59 return nil, err 60 } 61 } 62 63 res.nextRevocationKeyLoc = nextRevocationKeyDesc.KeyLocator 64 65 // Perform an ECDH operation between the private key described in 66 // nextRevocationKeyDesc and our public multisig key. The result will be 67 // used to seed the revocation producer. 68 revRoot, err := l.ECDH( 69 nextRevocationKeyDesc, res.ourContribution.MultiSigKey.PubKey, 70 ) 71 if err != nil { 72 return nil, err 73 } 74 75 // Once we have the root, we can then generate our shachain producer 76 // and from that generate the per-commitment point. 77 return shachain.NewRevocationProducer(revRoot), nil 78 }