cnct+lnwl+hswc: use lntypes.Preimage for witness beacon
This commit is contained in:
parent
2d8bc99d9e
commit
29f07a58cb
@ -1548,10 +1548,7 @@ func createInitChannels(revocationWindow int) (*lnwallet.LightningChannel, *lnwa
|
|||||||
Packager: channeldb.NewChannelPackager(shortChanID),
|
Packager: channeldb.NewChannelPackager(shortChanID),
|
||||||
}
|
}
|
||||||
|
|
||||||
pCache := &mockPreimageCache{
|
pCache := newMockPreimageCache()
|
||||||
// hash -> preimage
|
|
||||||
preimageMap: make(map[[32]byte][]byte),
|
|
||||||
}
|
|
||||||
|
|
||||||
aliceSigner := &mockSigner{aliceKeyPriv}
|
aliceSigner := &mockSigner{aliceKeyPriv}
|
||||||
bobSigner := &mockSigner{bobKeyPriv}
|
bobSigner := &mockSigner{bobKeyPriv}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
)
|
)
|
||||||
@ -40,7 +41,7 @@ type WitnessSubscription struct {
|
|||||||
// sent over.
|
// sent over.
|
||||||
//
|
//
|
||||||
// TODO(roasbeef): couple with WitnessType?
|
// TODO(roasbeef): couple with WitnessType?
|
||||||
WitnessUpdates <-chan []byte
|
WitnessUpdates <-chan lntypes.Preimage
|
||||||
|
|
||||||
// CancelSubscription is a function closure that should be used by a
|
// CancelSubscription is a function closure that should be used by a
|
||||||
// client to cancel the subscription once they are no longer interested
|
// client to cancel the subscription once they are no longer interested
|
||||||
@ -62,12 +63,12 @@ type WitnessBeacon interface {
|
|||||||
|
|
||||||
// LookupPreImage attempts to lookup a preimage in the global cache.
|
// LookupPreImage attempts to lookup a preimage in the global cache.
|
||||||
// True is returned for the second argument if the preimage is found.
|
// True is returned for the second argument if the preimage is found.
|
||||||
LookupPreimage(payhash []byte) ([]byte, bool)
|
LookupPreimage(payhash lntypes.Hash) (lntypes.Preimage, bool)
|
||||||
|
|
||||||
// AddPreimages adds a batch of newly discovered preimages to the global
|
// AddPreimages adds a batch of newly discovered preimages to the global
|
||||||
// cache, and also signals any subscribers of the newly discovered
|
// cache, and also signals any subscribers of the newly discovered
|
||||||
// witness.
|
// witness.
|
||||||
AddPreimages(preimages ...[]byte) error
|
AddPreimages(preimages ...lntypes.Preimage) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChannelArbitratorConfig contains all the functionality that the
|
// ChannelArbitratorConfig contains all the functionality that the
|
||||||
@ -1129,7 +1130,7 @@ func (c *ChannelArbitrator) checkChainActions(height uint32,
|
|||||||
// know the pre-image and it's close to timing out. We need to
|
// know the pre-image and it's close to timing out. We need to
|
||||||
// ensure that we claim the funds that our rightfully ours
|
// ensure that we claim the funds that our rightfully ours
|
||||||
// on-chain.
|
// on-chain.
|
||||||
if _, ok := c.cfg.PreimageDB.LookupPreimage(htlc.RHash[:]); !ok {
|
if _, ok := c.cfg.PreimageDB.LookupPreimage(htlc.RHash); !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
haveChainActions = haveChainActions || c.shouldGoOnChain(
|
haveChainActions = haveChainActions || c.shouldGoOnChain(
|
||||||
@ -1206,13 +1207,12 @@ func (c *ChannelArbitrator) checkChainActions(height uint32,
|
|||||||
// either learn of it eventually from the outgoing HTLC, or the sender
|
// either learn of it eventually from the outgoing HTLC, or the sender
|
||||||
// will timeout the HTLC.
|
// will timeout the HTLC.
|
||||||
for _, htlc := range c.activeHTLCs.incomingHTLCs {
|
for _, htlc := range c.activeHTLCs.incomingHTLCs {
|
||||||
payHash := htlc.RHash
|
|
||||||
|
|
||||||
// If we have the pre-image, then we should go on-chain to
|
// If we have the pre-image, then we should go on-chain to
|
||||||
// redeem the HTLC immediately.
|
// redeem the HTLC immediately.
|
||||||
if _, ok := c.cfg.PreimageDB.LookupPreimage(payHash[:]); ok {
|
if _, ok := c.cfg.PreimageDB.LookupPreimage(htlc.RHash); ok {
|
||||||
log.Tracef("ChannelArbitrator(%v): preimage for "+
|
log.Tracef("ChannelArbitrator(%v): preimage for "+
|
||||||
"htlc=%x is known!", c.cfg.ChanPoint, payHash[:])
|
"htlc=%x is known!", c.cfg.ChanPoint,
|
||||||
|
htlc.RHash[:])
|
||||||
|
|
||||||
actionMap[HtlcClaimAction] = append(
|
actionMap[HtlcClaimAction] = append(
|
||||||
actionMap[HtlcClaimAction], htlc,
|
actionMap[HtlcClaimAction], htlc,
|
||||||
@ -1222,7 +1222,7 @@ func (c *ChannelArbitrator) checkChainActions(height uint32,
|
|||||||
|
|
||||||
log.Tracef("ChannelArbitrator(%v): watching chain to decide "+
|
log.Tracef("ChannelArbitrator(%v): watching chain to decide "+
|
||||||
"action for incoming htlc=%x", c.cfg.ChanPoint,
|
"action for incoming htlc=%x", c.cfg.ChanPoint,
|
||||||
payHash[:])
|
htlc.RHash[:])
|
||||||
|
|
||||||
// Otherwise, we don't yet have the pre-image, but should watch
|
// Otherwise, we don't yet have the pre-image, but should watch
|
||||||
// on-chain to see if either: the remote party times out the
|
// on-chain to see if either: the remote party times out the
|
||||||
|
@ -2,12 +2,12 @@ package contractcourt
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
// htlcIncomingContestResolver is a ContractResolver that's able to resolve an
|
// htlcIncomingContestResolver is a ContractResolver that's able to resolve an
|
||||||
@ -74,11 +74,11 @@ func (h *htlcIncomingContestResolver) Resolve() (ContractResolver, error) {
|
|||||||
// resolver with the preimage we learn of. This should be called once
|
// resolver with the preimage we learn of. This should be called once
|
||||||
// the preimage is revealed so the inner resolver can properly complete
|
// the preimage is revealed so the inner resolver can properly complete
|
||||||
// its duties.
|
// its duties.
|
||||||
applyPreimage := func(preimage []byte) {
|
applyPreimage := func(preimage lntypes.Preimage) {
|
||||||
copy(h.htlcResolution.Preimage[:], preimage)
|
h.htlcResolution.Preimage = preimage
|
||||||
|
|
||||||
log.Infof("%T(%v): extracted preimage=%x from beacon!", h,
|
log.Infof("%T(%v): extracted preimage=%v from beacon!", h,
|
||||||
h.htlcResolution.ClaimOutpoint, preimage[:])
|
h.htlcResolution.ClaimOutpoint, preimage)
|
||||||
|
|
||||||
// If this our commitment transaction, then we'll need to
|
// If this our commitment transaction, then we'll need to
|
||||||
// populate the witness for the second-level HTLC transaction.
|
// populate the witness for the second-level HTLC transaction.
|
||||||
@ -93,8 +93,6 @@ func (h *htlcIncomingContestResolver) Resolve() (ContractResolver, error) {
|
|||||||
// preimage.
|
// preimage.
|
||||||
h.htlcResolution.SignedSuccessTx.TxIn[0].Witness[3] = preimage[:]
|
h.htlcResolution.SignedSuccessTx.TxIn[0].Witness[3] = preimage[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
copy(h.htlcResolution.Preimage[:], preimage[:])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the HTLC hasn't expired yet, then we may still be able to claim
|
// If the HTLC hasn't expired yet, then we may still be able to claim
|
||||||
@ -116,12 +114,12 @@ func (h *htlcIncomingContestResolver) Resolve() (ContractResolver, error) {
|
|||||||
|
|
||||||
// With the epochs and preimage subscriptions initialized, we'll query
|
// With the epochs and preimage subscriptions initialized, we'll query
|
||||||
// to see if we already know the preimage.
|
// to see if we already know the preimage.
|
||||||
preimage, ok := h.PreimageDB.LookupPreimage(h.payHash[:])
|
preimage, ok := h.PreimageDB.LookupPreimage(h.payHash)
|
||||||
if ok {
|
if ok {
|
||||||
// If we do, then this means we can claim the HTLC! However,
|
// If we do, then this means we can claim the HTLC! However,
|
||||||
// we don't know how to ourselves, so we'll return our inner
|
// we don't know how to ourselves, so we'll return our inner
|
||||||
// resolver which has the knowledge to do so.
|
// resolver which has the knowledge to do so.
|
||||||
applyPreimage(preimage[:])
|
applyPreimage(preimage)
|
||||||
return &h.htlcSuccessResolver, nil
|
return &h.htlcSuccessResolver, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,8 +129,8 @@ func (h *htlcIncomingContestResolver) Resolve() (ContractResolver, error) {
|
|||||||
case preimage := <-preimageSubscription.WitnessUpdates:
|
case preimage := <-preimageSubscription.WitnessUpdates:
|
||||||
// If this isn't our preimage, then we'll continue
|
// If this isn't our preimage, then we'll continue
|
||||||
// onwards.
|
// onwards.
|
||||||
newHash := sha256.Sum256(preimage)
|
hash := preimage.Hash()
|
||||||
preimageMatches := bytes.Equal(newHash[:], h.payHash[:])
|
preimageMatches := bytes.Equal(hash[:], h.payHash[:])
|
||||||
if !preimageMatches {
|
if !preimageMatches {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,15 @@ package contractcourt
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
|
||||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||||
|
"github.com/lightningnetwork/lnd/input"
|
||||||
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
// htlcOutgoingContestResolver is a ContractResolver that's able to resolve an
|
// htlcOutgoingContestResolver is a ContractResolver that's able to resolve an
|
||||||
@ -58,38 +60,47 @@ func (h *htlcOutgoingContestResolver) Resolve() (ContractResolver, error) {
|
|||||||
// If this is the remote party's commitment, then we'll be
|
// If this is the remote party's commitment, then we'll be
|
||||||
// looking for them to spend using the second-level success
|
// looking for them to spend using the second-level success
|
||||||
// transaction.
|
// transaction.
|
||||||
var preimage [32]byte
|
var preimageBytes []byte
|
||||||
if h.htlcResolution.SignedTimeoutTx == nil {
|
if h.htlcResolution.SignedTimeoutTx == nil {
|
||||||
// The witness stack when the remote party sweeps the
|
// The witness stack when the remote party sweeps the
|
||||||
// output to them looks like:
|
// output to them looks like:
|
||||||
//
|
//
|
||||||
// * <sender sig> <recvr sig> <preimage> <witness script>
|
// * <sender sig> <recvr sig> <preimage> <witness script>
|
||||||
copy(preimage[:], spendingInput.Witness[3])
|
preimageBytes = spendingInput.Witness[3]
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, they'll be spending directly from our
|
// Otherwise, they'll be spending directly from our
|
||||||
// commitment output. In which case the witness stack
|
// commitment output. In which case the witness stack
|
||||||
// looks like:
|
// looks like:
|
||||||
//
|
//
|
||||||
// * <sig> <preimage> <witness script>
|
// * <sig> <preimage> <witness script>
|
||||||
copy(preimage[:], spendingInput.Witness[1])
|
preimageBytes = spendingInput.Witness[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("%T(%v): extracting preimage=%x from on-chain "+
|
preimage, err := lntypes.MakePreimage(preimageBytes)
|
||||||
"spend!", h, h.htlcResolution.ClaimOutpoint, preimage[:])
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("%T(%v): extracting preimage=%v from on-chain "+
|
||||||
|
"spend!", h, h.htlcResolution.ClaimOutpoint,
|
||||||
|
preimage)
|
||||||
|
|
||||||
// With the preimage obtained, we can now add it to the global
|
// With the preimage obtained, we can now add it to the global
|
||||||
// cache.
|
// cache.
|
||||||
if err := h.PreimageDB.AddPreimages(preimage[:]); err != nil {
|
if err := h.PreimageDB.AddPreimages(preimage); err != nil {
|
||||||
log.Errorf("%T(%v): unable to add witness to cache",
|
log.Errorf("%T(%v): unable to add witness to cache",
|
||||||
h, h.htlcResolution.ClaimOutpoint)
|
h, h.htlcResolution.ClaimOutpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pre [32]byte
|
||||||
|
copy(pre[:], preimage[:])
|
||||||
|
|
||||||
// Finally, we'll send the clean up message, mark ourselves as
|
// Finally, we'll send the clean up message, mark ourselves as
|
||||||
// resolved, then exit.
|
// resolved, then exit.
|
||||||
if err := h.DeliverResolutionMsg(ResolutionMsg{
|
if err := h.DeliverResolutionMsg(ResolutionMsg{
|
||||||
SourceChan: h.ShortChanID,
|
SourceChan: h.ShortChanID,
|
||||||
HtlcIndex: h.htlcIndex,
|
HtlcIndex: h.htlcIndex,
|
||||||
PreImage: &preimage,
|
PreImage: &pre,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -3,15 +3,16 @@ package contractcourt
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
|
||||||
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
|
"github.com/lightningnetwork/lnd/input"
|
||||||
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
"github.com/lightningnetwork/lnd/sweep"
|
"github.com/lightningnetwork/lnd/sweep"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ type htlcSuccessResolver struct {
|
|||||||
broadcastHeight uint32
|
broadcastHeight uint32
|
||||||
|
|
||||||
// payHash is the payment hash of the original HTLC extended to us.
|
// payHash is the payment hash of the original HTLC extended to us.
|
||||||
payHash [32]byte
|
payHash lntypes.Hash
|
||||||
|
|
||||||
// sweepTx will be non-nil if we've already crafted a transaction to
|
// sweepTx will be non-nil if we've already crafted a transaction to
|
||||||
// sweep a direct HTLC output. This is only a concern if we're sweeping
|
// sweep a direct HTLC output. This is only a concern if we're sweeping
|
||||||
|
@ -1417,7 +1417,7 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) {
|
|||||||
// any contested contracts watched by any on-chain arbitrators
|
// any contested contracts watched by any on-chain arbitrators
|
||||||
// can now sweep this HTLC on-chain.
|
// can now sweep this HTLC on-chain.
|
||||||
go func() {
|
go func() {
|
||||||
err := l.cfg.PreimageCache.AddPreimages(pre[:])
|
err := l.cfg.PreimageCache.AddPreimages(pre)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.errorf("unable to add preimage=%x to "+
|
l.errorf("unable to add preimage=%x to "+
|
||||||
"cache", pre[:])
|
"cache", pre[:])
|
||||||
|
@ -1532,10 +1532,7 @@ func newSingleLinkTestHarness(chanAmt, chanReserve btcutil.Amount) (
|
|||||||
invoiceRegistry = newMockRegistry(globalPolicy.TimeLockDelta)
|
invoiceRegistry = newMockRegistry(globalPolicy.TimeLockDelta)
|
||||||
)
|
)
|
||||||
|
|
||||||
pCache := &mockPreimageCache{
|
pCache := newMockPreimageCache()
|
||||||
// hash -> preimage
|
|
||||||
preimageMap: make(map[[32]byte][]byte),
|
|
||||||
}
|
|
||||||
|
|
||||||
aliceDb := aliceChannel.State().Db
|
aliceDb := aliceChannel.State().Db
|
||||||
aliceSwitch, err := initSwitchWithDB(testStartingHeight, aliceDb)
|
aliceSwitch, err := initSwitchWithDB(testStartingHeight, aliceDb)
|
||||||
@ -4042,10 +4039,7 @@ func restartLink(aliceChannel *lnwallet.LightningChannel, aliceSwitch *Switch,
|
|||||||
|
|
||||||
invoiceRegistry = newMockRegistry(globalPolicy.TimeLockDelta)
|
invoiceRegistry = newMockRegistry(globalPolicy.TimeLockDelta)
|
||||||
|
|
||||||
pCache = &mockPreimageCache{
|
pCache = newMockPreimageCache()
|
||||||
// hash -> preimage
|
|
||||||
preimageMap: make(map[[32]byte][]byte),
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
aliceDb := aliceChannel.State().Db
|
aliceDb := aliceChannel.State().Db
|
||||||
|
@ -32,26 +32,31 @@ import (
|
|||||||
|
|
||||||
type mockPreimageCache struct {
|
type mockPreimageCache struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
preimageMap map[[32]byte][]byte
|
preimageMap map[lntypes.Hash]lntypes.Preimage
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockPreimageCache) LookupPreimage(hash []byte) ([]byte, bool) {
|
func newMockPreimageCache() *mockPreimageCache {
|
||||||
|
return &mockPreimageCache{
|
||||||
|
preimageMap: make(map[lntypes.Hash]lntypes.Preimage),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockPreimageCache) LookupPreimage(
|
||||||
|
hash lntypes.Hash) (lntypes.Preimage, bool) {
|
||||||
|
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
|
||||||
var h [32]byte
|
p, ok := m.preimageMap[hash]
|
||||||
copy(h[:], hash)
|
|
||||||
|
|
||||||
p, ok := m.preimageMap[h]
|
|
||||||
return p, ok
|
return p, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockPreimageCache) AddPreimages(preimages ...[]byte) error {
|
func (m *mockPreimageCache) AddPreimages(preimages ...lntypes.Preimage) error {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
|
||||||
for _, preimage := range preimages {
|
for _, preimage := range preimages {
|
||||||
m.preimageMap[sha256.Sum256(preimage)] = preimage
|
m.preimageMap[preimage.Hash()] = preimage
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -367,10 +367,7 @@ func createTestChannel(alicePrivKey, bobPrivKey []byte,
|
|||||||
aliceSigner := &mockSigner{aliceKeyPriv}
|
aliceSigner := &mockSigner{aliceKeyPriv}
|
||||||
bobSigner := &mockSigner{bobKeyPriv}
|
bobSigner := &mockSigner{bobKeyPriv}
|
||||||
|
|
||||||
pCache := &mockPreimageCache{
|
pCache := newMockPreimageCache()
|
||||||
// hash -> preimage
|
|
||||||
preimageMap: make(map[[32]byte][]byte),
|
|
||||||
}
|
|
||||||
|
|
||||||
alicePool := lnwallet.NewSigPool(runtime.NumCPU(), aliceSigner)
|
alicePool := lnwallet.NewSigPool(runtime.NumCPU(), aliceSigner)
|
||||||
channelAlice, err := lnwallet.NewLightningChannel(
|
channelAlice, err := lnwallet.NewLightningChannel(
|
||||||
@ -982,10 +979,7 @@ type hopNetwork struct {
|
|||||||
func newHopNetwork() *hopNetwork {
|
func newHopNetwork() *hopNetwork {
|
||||||
defaultDelta := uint32(6)
|
defaultDelta := uint32(6)
|
||||||
|
|
||||||
pCache := &mockPreimageCache{
|
pCache := newMockPreimageCache()
|
||||||
// hash -> preimage
|
|
||||||
preimageMap: make(map[[32]byte][]byte),
|
|
||||||
}
|
|
||||||
|
|
||||||
globalPolicy := ForwardingPolicy{
|
globalPolicy := ForwardingPolicy{
|
||||||
MinHTLC: lnwire.NewMSatFromSatoshis(5),
|
MinHTLC: lnwire.NewMSatFromSatoshis(5),
|
||||||
|
@ -5577,12 +5577,12 @@ func extractHtlcResolutions(feePerKw SatPerKWeight, ourCommit bool,
|
|||||||
// We'll now query the preimage cache for the preimage
|
// We'll now query the preimage cache for the preimage
|
||||||
// for this HTLC. If it's present then we can fully
|
// for this HTLC. If it's present then we can fully
|
||||||
// populate this resolution.
|
// populate this resolution.
|
||||||
preimage, _ := pCache.LookupPreimage(htlc.RHash[:])
|
preimage, _ := pCache.LookupPreimage(htlc.RHash)
|
||||||
|
|
||||||
// Otherwise, we'll create an incoming HTLC resolution
|
// Otherwise, we'll create an incoming HTLC resolution
|
||||||
// as we can satisfy the contract.
|
// as we can satisfy the contract.
|
||||||
var pre [32]byte
|
var pre [32]byte
|
||||||
copy(pre[:], preimage)
|
copy(pre[:], preimage[:])
|
||||||
ihr, err := newIncomingHtlcResolution(
|
ihr, err := newIncomingHtlcResolution(
|
||||||
signer, localChanCfg, commitHash, &htlc, keyRing,
|
signer, localChanCfg, commitHash, &htlc, keyRing,
|
||||||
feePerKw, dustLimit, uint32(csvDelay), ourCommit,
|
feePerKw, dustLimit, uint32(csvDelay), ourCommit,
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -584,7 +585,7 @@ func TestForceClose(t *testing.T) {
|
|||||||
|
|
||||||
// Before we force close Alice's channel, we'll add the pre-image of
|
// Before we force close Alice's channel, we'll add the pre-image of
|
||||||
// Bob's HTLC to her preimage cache.
|
// Bob's HTLC to her preimage cache.
|
||||||
aliceChannel.pCache.AddPreimages(preimageBob[:])
|
aliceChannel.pCache.AddPreimages(lntypes.Preimage(preimageBob))
|
||||||
|
|
||||||
// With the cache populated, we'll now attempt the force close
|
// With the cache populated, we'll now attempt the force close
|
||||||
// initiated by Alice.
|
// initiated by Alice.
|
||||||
@ -4953,7 +4954,7 @@ func TestChannelUnilateralCloseHtlcResolution(t *testing.T) {
|
|||||||
// Now that Bob has force closed, we'll modify Alice's pre image cache
|
// Now that Bob has force closed, we'll modify Alice's pre image cache
|
||||||
// such that she now gains the ability to also settle the incoming HTLC
|
// such that she now gains the ability to also settle the incoming HTLC
|
||||||
// from Bob.
|
// from Bob.
|
||||||
aliceChannel.pCache.AddPreimages(preimageBob[:])
|
aliceChannel.pCache.AddPreimages(lntypes.Preimage(preimageBob))
|
||||||
|
|
||||||
// We'll then use Bob's transaction to trigger a spend notification for
|
// We'll then use Bob's transaction to trigger a spend notification for
|
||||||
// Alice.
|
// Alice.
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AddressType is an enum-like type which denotes the possible address types
|
// AddressType is an enum-like type which denotes the possible address types
|
||||||
@ -272,15 +273,12 @@ type PreimageCache interface {
|
|||||||
// LookupPreimage attempts to look up a preimage according to its hash.
|
// LookupPreimage attempts to look up a preimage according to its hash.
|
||||||
// If found, the preimage is returned along with true for the second
|
// If found, the preimage is returned along with true for the second
|
||||||
// argument. Otherwise, it'll return false.
|
// argument. Otherwise, it'll return false.
|
||||||
LookupPreimage(hash []byte) ([]byte, bool)
|
LookupPreimage(hash lntypes.Hash) (lntypes.Preimage, bool)
|
||||||
|
|
||||||
// AddPreimages adds a batch of newly discovered preimages to the global
|
// AddPreimages adds a batch of newly discovered preimages to the global
|
||||||
// cache, and also signals any subscribers of the newly discovered
|
// cache, and also signals any subscribers of the newly discovered
|
||||||
// witness.
|
// witness.
|
||||||
//
|
AddPreimages(preimages ...lntypes.Preimage) error
|
||||||
// NOTE: The backing slice of MUST NOT be modified, otherwise the
|
|
||||||
// subscribers may be notified of the incorrect preimages.
|
|
||||||
AddPreimages(preimages ...[]byte) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WalletDriver represents a "driver" for a particular concrete
|
// WalletDriver represents a "driver" for a particular concrete
|
||||||
|
@ -3,7 +3,6 @@ package lnwallet
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"io"
|
"io"
|
||||||
@ -18,6 +17,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
"github.com/lightningnetwork/lnd/keychain"
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
"github.com/lightningnetwork/lnd/shachain"
|
"github.com/lightningnetwork/lnd/shachain"
|
||||||
)
|
)
|
||||||
@ -301,10 +301,7 @@ func CreateTestChannels() (*LightningChannel, *LightningChannel, func(), error)
|
|||||||
aliceSigner := &input.MockSigner{Privkeys: aliceKeys}
|
aliceSigner := &input.MockSigner{Privkeys: aliceKeys}
|
||||||
bobSigner := &input.MockSigner{Privkeys: bobKeys}
|
bobSigner := &input.MockSigner{Privkeys: bobKeys}
|
||||||
|
|
||||||
pCache := &mockPreimageCache{
|
pCache := newMockPreimageCache()
|
||||||
// hash -> preimage
|
|
||||||
preimageMap: make(map[[32]byte][]byte),
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(roasbeef): make mock version of pre-image store
|
// TODO(roasbeef): make mock version of pre-image store
|
||||||
|
|
||||||
@ -389,26 +386,36 @@ func initRevocationWindows(chanA, chanB *LightningChannel) error {
|
|||||||
|
|
||||||
type mockPreimageCache struct {
|
type mockPreimageCache struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
preimageMap map[[32]byte][]byte
|
preimageMap map[lntypes.Hash]lntypes.Preimage
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockPreimageCache) LookupPreimage(hash []byte) ([]byte, bool) {
|
func newMockPreimageCache() *mockPreimageCache {
|
||||||
|
return &mockPreimageCache{
|
||||||
|
preimageMap: make(map[lntypes.Hash]lntypes.Preimage),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockPreimageCache) LookupPreimage(
|
||||||
|
hash lntypes.Hash) (lntypes.Preimage, bool) {
|
||||||
|
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
|
||||||
var h [32]byte
|
p, ok := m.preimageMap[hash]
|
||||||
copy(h[:], hash)
|
|
||||||
|
|
||||||
p, ok := m.preimageMap[h]
|
|
||||||
return p, ok
|
return p, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockPreimageCache) AddPreimages(preimages ...[]byte) error {
|
func (m *mockPreimageCache) AddPreimages(preimages ...lntypes.Preimage) error {
|
||||||
|
preimageCopies := make([]lntypes.Preimage, 0, len(preimages))
|
||||||
|
for _, preimage := range preimages {
|
||||||
|
preimageCopies = append(preimageCopies, preimage)
|
||||||
|
}
|
||||||
|
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
|
||||||
for _, preimage := range preimages {
|
for _, preimage := range preimageCopies {
|
||||||
m.preimageMap[sha256.Sum256(preimage)] = preimage
|
m.preimageMap[preimage.Hash()] = preimage
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -780,10 +780,7 @@ func TestCommitmentAndHTLCTransactions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pCache := &mockPreimageCache{
|
pCache := newMockPreimageCache()
|
||||||
// hash -> preimage
|
|
||||||
preimageMap: make(map[[32]byte][]byte),
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, test := range testCases {
|
for i, test := range testCases {
|
||||||
expectedCommitmentTx, err := txFromHex(test.expectedCommitmentTxHex)
|
expectedCommitmentTx, err := txFromHex(test.expectedCommitmentTxHex)
|
||||||
|
21
mock.go
21
mock.go
@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@ -16,6 +15,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
"github.com/lightningnetwork/lnd/keychain"
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -303,26 +303,29 @@ func (m *mockSecretKeyRing) ScalarMult(keyDesc keychain.KeyDescriptor,
|
|||||||
|
|
||||||
type mockPreimageCache struct {
|
type mockPreimageCache struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
preimageMap map[[32]byte][]byte
|
preimageMap map[lntypes.Hash]lntypes.Preimage
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockPreimageCache) LookupPreimage(hash []byte) ([]byte, bool) {
|
func newMockPreimageCache() *mockPreimageCache {
|
||||||
|
return &mockPreimageCache{
|
||||||
|
preimageMap: make(map[lntypes.Hash]lntypes.Preimage),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockPreimageCache) LookupPreimage(hash lntypes.Hash) (lntypes.Preimage, bool) {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
|
||||||
var h [32]byte
|
p, ok := m.preimageMap[hash]
|
||||||
copy(h[:], hash)
|
|
||||||
|
|
||||||
p, ok := m.preimageMap[h]
|
|
||||||
return p, ok
|
return p, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockPreimageCache) AddPreimages(preimages ...[]byte) error {
|
func (m *mockPreimageCache) AddPreimages(preimages ...lntypes.Preimage) error {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
|
||||||
for _, preimage := range preimages {
|
for _, preimage := range preimages {
|
||||||
m.preimageMap[sha256.Sum256(preimage)] = preimage
|
m.preimageMap[preimage.Hash()] = preimage
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
// preimageSubscriber reprints an active subscription to be notified once the
|
// preimageSubscriber reprints an active subscription to be notified once the
|
||||||
// daemon discovers new preimages, either on chain or off-chain.
|
// daemon discovers new preimages, either on chain or off-chain.
|
||||||
type preimageSubscriber struct {
|
type preimageSubscriber struct {
|
||||||
updateChan chan []byte
|
updateChan chan lntypes.Preimage
|
||||||
|
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ func (p *preimageBeacon) SubscribeUpdates() *contractcourt.WitnessSubscription {
|
|||||||
|
|
||||||
clientID := p.clientCounter
|
clientID := p.clientCounter
|
||||||
client := &preimageSubscriber{
|
client := &preimageSubscriber{
|
||||||
updateChan: make(chan []byte, 10),
|
updateChan: make(chan lntypes.Preimage, 10),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,36 +66,42 @@ func (p *preimageBeacon) SubscribeUpdates() *contractcourt.WitnessSubscription {
|
|||||||
|
|
||||||
// LookupPreImage attempts to lookup a preimage in the global cache. True is
|
// LookupPreImage attempts to lookup a preimage in the global cache. True is
|
||||||
// returned for the second argument if the preimage is found.
|
// returned for the second argument if the preimage is found.
|
||||||
func (p *preimageBeacon) LookupPreimage(payHash []byte) ([]byte, bool) {
|
func (p *preimageBeacon) LookupPreimage(
|
||||||
|
payHash lntypes.Hash) (lntypes.Preimage, bool) {
|
||||||
|
|
||||||
p.RLock()
|
p.RLock()
|
||||||
defer p.RUnlock()
|
defer p.RUnlock()
|
||||||
|
|
||||||
// First, we'll check the invoice registry to see if we already know of
|
// First, we'll check the invoice registry to see if we already know of
|
||||||
// the preimage as it's on that we created ourselves.
|
// the preimage as it's on that we created ourselves.
|
||||||
var invoiceKey lntypes.Hash
|
invoice, _, err := p.invoices.LookupInvoice(payHash)
|
||||||
copy(invoiceKey[:], payHash)
|
|
||||||
invoice, _, err := p.invoices.LookupInvoice(invoiceKey)
|
|
||||||
switch {
|
switch {
|
||||||
case err == channeldb.ErrInvoiceNotFound:
|
case err == channeldb.ErrInvoiceNotFound:
|
||||||
// If we get this error, then it simply means that this invoice
|
// If we get this error, then it simply means that this invoice
|
||||||
// wasn't found, so we don't treat it as a critical error.
|
// wasn't found, so we don't treat it as a critical error.
|
||||||
case err != nil:
|
case err != nil:
|
||||||
return nil, false
|
return lntypes.Preimage{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we've found the invoice, then we can return the preimage
|
// If we've found the invoice, then we can return the preimage
|
||||||
// directly.
|
// directly.
|
||||||
if err != channeldb.ErrInvoiceNotFound {
|
if err != channeldb.ErrInvoiceNotFound {
|
||||||
return invoice.Terms.PaymentPreimage[:], true
|
return invoice.Terms.PaymentPreimage, true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, we'll perform a final check using the witness cache.
|
// Otherwise, we'll perform a final check using the witness cache.
|
||||||
preimage, err := p.wCache.LookupWitness(
|
preimageBytes, err := p.wCache.LookupWitness(
|
||||||
channeldb.Sha256HashWitness, payHash,
|
channeldb.Sha256HashWitness, payHash[:],
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ltndLog.Errorf("unable to lookup witness: %v", err)
|
ltndLog.Errorf("Unable to lookup witness: %v", err)
|
||||||
return nil, false
|
return lntypes.Preimage{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
preimage, err := lntypes.MakePreimage(preimageBytes)
|
||||||
|
if err != nil {
|
||||||
|
ltndLog.Errorf("Unable to build witness: %v", err)
|
||||||
|
return lntypes.Preimage{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return preimage, true
|
return preimage, true
|
||||||
@ -103,7 +109,7 @@ func (p *preimageBeacon) LookupPreimage(payHash []byte) ([]byte, bool) {
|
|||||||
|
|
||||||
// AddPreimages adds a batch of newly discovered preimages to the global cache,
|
// AddPreimages adds a batch of newly discovered preimages to the global cache,
|
||||||
// and also signals any subscribers of the newly discovered witness.
|
// and also signals any subscribers of the newly discovered witness.
|
||||||
func (p *preimageBeacon) AddPreimages(preimages ...[]byte) error {
|
func (p *preimageBeacon) AddPreimages(preimages ...lntypes.Preimage) error {
|
||||||
// Exit early if no preimages are presented.
|
// Exit early if no preimages are presented.
|
||||||
if len(preimages) == 0 {
|
if len(preimages) == 0 {
|
||||||
return nil
|
return nil
|
||||||
@ -111,14 +117,14 @@ func (p *preimageBeacon) AddPreimages(preimages ...[]byte) error {
|
|||||||
|
|
||||||
// Copy the preimages to ensure the backing area can't be modified by
|
// Copy the preimages to ensure the backing area can't be modified by
|
||||||
// the caller when delivering notifications.
|
// the caller when delivering notifications.
|
||||||
preimageCopies := make([][]byte, 0, len(preimages))
|
preimageCopies := make([]lntypes.Preimage, 0, len(preimages))
|
||||||
for _, preimage := range preimages {
|
for _, preimage := range preimages {
|
||||||
srvrLog.Infof("Adding preimage=%x to witness cache", preimage)
|
srvrLog.Infof("Adding preimage=%v to witness cache", preimage)
|
||||||
preimageCopies = append(preimageCopies, preimage)
|
preimageCopies = append(preimageCopies, preimage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, we'll add the witness to the decaying witness cache.
|
// First, we'll add the witness to the decaying witness cache.
|
||||||
err := p.wCache.AddWitnesses(channeldb.Sha256HashWitness, preimages...)
|
err := p.wCache.AddSha256Witnesses(preimages...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user