From b1c19e8f4e21f174a351590a8e76c409b6b0b155 Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Mon, 9 Dec 2024 13:55:29 +0100 Subject: [PATCH] staticaddr: add initiation height of address --- loopd/daemon.go | 1 + .../migrations/000009_static_address.up.sql | 6 +++- loopdb/sqlc/models.go | 17 +++++----- loopdb/sqlc/queries/static_addresses.sql | 6 ++-- loopdb/sqlc/static_addresses.sql.go | 28 +++++++++------ staticaddr/address/interface.go | 3 ++ staticaddr/address/manager.go | 34 +++++++++++++++++-- staticaddr/address/manager_test.go | 3 +- staticaddr/address/sql_store.go | 16 +++++---- staticaddr/deposit/manager.go | 9 ++--- 10 files changed, 87 insertions(+), 36 deletions(-) diff --git a/loopd/daemon.go b/loopd/daemon.go index 5f7d25808..cf570d101 100644 --- a/loopd/daemon.go +++ b/loopd/daemon.go @@ -592,6 +592,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error { Store: staticAddressStore, WalletKit: d.lnd.WalletKit, ChainParams: d.lnd.ChainParams, + ChainNotifier: d.lnd.ChainNotifier, } staticAddressManager = address.NewManager(addrCfg) diff --git a/loopdb/sqlc/migrations/000009_static_address.up.sql b/loopdb/sqlc/migrations/000009_static_address.up.sql index f4b293e2a..089645cbc 100644 --- a/loopdb/sqlc/migrations/000009_static_address.up.sql +++ b/loopdb/sqlc/migrations/000009_static_address.up.sql @@ -34,5 +34,9 @@ CREATE TABLE IF NOT EXISTS static_addresses ( -- Note that this version is not upgraded if the client upgrades or -- downgrades their protocol version for static address outputs already in -- use. - protocol_version INTEGER NOT NULL + protocol_version INTEGER NOT NULL, + + -- initiation_height is the block height at which the static address was + -- created. + initiation_height INT NOT NULL ); \ No newline at end of file diff --git a/loopdb/sqlc/models.go b/loopdb/sqlc/models.go index 59939ad7a..c79ae9b5e 100644 --- a/loopdb/sqlc/models.go +++ b/loopdb/sqlc/models.go @@ -114,14 +114,15 @@ type ReservationUpdate struct { } type StaticAddress struct { - ID int32 - ClientPubkey []byte - ServerPubkey []byte - Expiry int32 - ClientKeyFamily int32 - ClientKeyIndex int32 - Pkscript []byte - ProtocolVersion int32 + ID int32 + ClientPubkey []byte + ServerPubkey []byte + Expiry int32 + ClientKeyFamily int32 + ClientKeyIndex int32 + Pkscript []byte + ProtocolVersion int32 + InitiationHeight int32 } type StaticAddressSwap struct { diff --git a/loopdb/sqlc/queries/static_addresses.sql b/loopdb/sqlc/queries/static_addresses.sql index a0a1fd05e..c613cfd93 100644 --- a/loopdb/sqlc/queries/static_addresses.sql +++ b/loopdb/sqlc/queries/static_addresses.sql @@ -13,7 +13,8 @@ INSERT INTO static_addresses ( client_key_family, client_key_index, pkscript, - protocol_version + protocol_version, + initiation_height ) VALUES ( $1, $2, @@ -21,5 +22,6 @@ INSERT INTO static_addresses ( $4, $5, $6, - $7 + $7, + $8 ); \ No newline at end of file diff --git a/loopdb/sqlc/static_addresses.sql.go b/loopdb/sqlc/static_addresses.sql.go index 23902a22f..054c07364 100644 --- a/loopdb/sqlc/static_addresses.sql.go +++ b/loopdb/sqlc/static_addresses.sql.go @@ -10,7 +10,7 @@ import ( ) const allStaticAddresses = `-- name: AllStaticAddresses :many -SELECT id, client_pubkey, server_pubkey, expiry, client_key_family, client_key_index, pkscript, protocol_version FROM static_addresses +SELECT id, client_pubkey, server_pubkey, expiry, client_key_family, client_key_index, pkscript, protocol_version, initiation_height FROM static_addresses ` func (q *Queries) AllStaticAddresses(ctx context.Context) ([]StaticAddress, error) { @@ -31,6 +31,7 @@ func (q *Queries) AllStaticAddresses(ctx context.Context) ([]StaticAddress, erro &i.ClientKeyIndex, &i.Pkscript, &i.ProtocolVersion, + &i.InitiationHeight, ); err != nil { return nil, err } @@ -53,7 +54,8 @@ INSERT INTO static_addresses ( client_key_family, client_key_index, pkscript, - protocol_version + protocol_version, + initiation_height ) VALUES ( $1, $2, @@ -61,18 +63,20 @@ INSERT INTO static_addresses ( $4, $5, $6, - $7 + $7, + $8 ) ` type CreateStaticAddressParams struct { - ClientPubkey []byte - ServerPubkey []byte - Expiry int32 - ClientKeyFamily int32 - ClientKeyIndex int32 - Pkscript []byte - ProtocolVersion int32 + ClientPubkey []byte + ServerPubkey []byte + Expiry int32 + ClientKeyFamily int32 + ClientKeyIndex int32 + Pkscript []byte + ProtocolVersion int32 + InitiationHeight int32 } func (q *Queries) CreateStaticAddress(ctx context.Context, arg CreateStaticAddressParams) error { @@ -84,12 +88,13 @@ func (q *Queries) CreateStaticAddress(ctx context.Context, arg CreateStaticAddre arg.ClientKeyIndex, arg.Pkscript, arg.ProtocolVersion, + arg.InitiationHeight, ) return err } const getStaticAddress = `-- name: GetStaticAddress :one -SELECT id, client_pubkey, server_pubkey, expiry, client_key_family, client_key_index, pkscript, protocol_version FROM static_addresses +SELECT id, client_pubkey, server_pubkey, expiry, client_key_family, client_key_index, pkscript, protocol_version, initiation_height FROM static_addresses WHERE pkscript=$1 ` @@ -105,6 +110,7 @@ func (q *Queries) GetStaticAddress(ctx context.Context, pkscript []byte) (Static &i.ClientKeyIndex, &i.Pkscript, &i.ProtocolVersion, + &i.InitiationHeight, ) return i, err } diff --git a/staticaddr/address/interface.go b/staticaddr/address/interface.go index fee6be2f8..5e39abdf7 100644 --- a/staticaddr/address/interface.go +++ b/staticaddr/address/interface.go @@ -54,4 +54,7 @@ type Parameters struct { // ProtocolVersion is the protocol version of the static address. ProtocolVersion version.AddressProtocolVersion + + // InitiationHeight is the height at which the address was initiated. + InitiationHeight int32 } diff --git a/staticaddr/address/manager.go b/staticaddr/address/manager.go index 8932d4dd4..4cb5391c6 100644 --- a/staticaddr/address/manager.go +++ b/staticaddr/address/manager.go @@ -40,6 +40,10 @@ type ManagerConfig struct { // ChainParams is the chain configuration(mainnet, testnet...) this // manager uses. ChainParams *chaincfg.Params + + // ChainNotifier is the chain notifier that is used to listen for new + // blocks. + ChainNotifier lndclient.ChainNotifierClient } // Manager manages the address state machines. @@ -47,6 +51,8 @@ type Manager struct { cfg *ManagerConfig sync.Mutex + + currentHeight int32 } // NewManager creates a new address manager. @@ -58,8 +64,26 @@ func NewManager(cfg *ManagerConfig) *Manager { // Run runs the address manager. func (m *Manager) Run(ctx context.Context) error { - <-ctx.Done() - return nil + newBlockChan, newBlockErrChan, err := + m.cfg.ChainNotifier.RegisterBlockEpochNtfn(ctx) + + if err != nil { + return err + } + + for { + select { + case currentHeight := <-newBlockChan: + m.currentHeight = currentHeight + + case err = <-newBlockErrChan: + return err + + case <-ctx.Done(): + // Signal subroutines that the manager is exiting. + return ctx.Err() + } + } } // NewAddress starts a new address creation flow. @@ -86,6 +110,11 @@ func (m *Manager) NewAddress(ctx context.Context) (*btcutil.AddressTaproot, } m.Unlock() + // Ensure that we have that we have a sane current block height. + if m.currentHeight == 0 { + return nil, fmt.Errorf("current block height is unknown") + } + // We are fetching a new L402 token from the server. There is one static // address per L402 token allowed. err = m.cfg.FetchL402(ctx) @@ -147,6 +176,7 @@ func (m *Manager) NewAddress(ctx context.Context) (*btcutil.AddressTaproot, ProtocolVersion: version.AddressProtocolVersion( protocolVersion, ), + InitiationHeight: m.currentHeight, } err = m.cfg.Store.CreateStaticAddress(ctx, addrParams) if err != nil { diff --git a/staticaddr/address/manager_test.go b/staticaddr/address/manager_test.go index 68161050c..35a6d0069 100644 --- a/staticaddr/address/manager_test.go +++ b/staticaddr/address/manager_test.go @@ -97,7 +97,7 @@ func TestManager(t *testing.T) { // Start the manager. go func() { err := testContext.manager.Run(ctxb) - require.NoError(t, err) + require.ErrorIs(t, err, context.Canceled) }() // Create the expected static address. @@ -179,6 +179,7 @@ func NewAddressManagerTestContext(t *testing.T) *ManagerTestContext { WalletKit: mockLnd.WalletKit, ChainParams: mockLnd.ChainParams, AddressClient: mockStaticAddressClient, + ChainNotifier: mockLnd.ChainNotifier, FetchL402: func(context.Context) error { return nil }, } diff --git a/staticaddr/address/sql_store.go b/staticaddr/address/sql_store.go index 2823564f9..9f47db027 100644 --- a/staticaddr/address/sql_store.go +++ b/staticaddr/address/sql_store.go @@ -28,13 +28,14 @@ func (s *SqlStore) CreateStaticAddress(ctx context.Context, addrParams *Parameters) error { createArgs := sqlc.CreateStaticAddressParams{ - ClientPubkey: addrParams.ClientPubkey.SerializeCompressed(), - ServerPubkey: addrParams.ServerPubkey.SerializeCompressed(), - Expiry: int32(addrParams.Expiry), - ClientKeyFamily: int32(addrParams.KeyLocator.Family), - ClientKeyIndex: int32(addrParams.KeyLocator.Index), - Pkscript: addrParams.PkScript, - ProtocolVersion: int32(addrParams.ProtocolVersion), + ClientPubkey: addrParams.ClientPubkey.SerializeCompressed(), + ServerPubkey: addrParams.ServerPubkey.SerializeCompressed(), + Expiry: int32(addrParams.Expiry), + ClientKeyFamily: int32(addrParams.KeyLocator.Family), + ClientKeyIndex: int32(addrParams.KeyLocator.Index), + Pkscript: addrParams.PkScript, + ProtocolVersion: int32(addrParams.ProtocolVersion), + InitiationHeight: addrParams.InitiationHeight, } return s.baseDB.Queries.CreateStaticAddress(ctx, createArgs) @@ -106,5 +107,6 @@ func (s *SqlStore) toAddressParameters(row sqlc.StaticAddress) ( ProtocolVersion: version.AddressProtocolVersion( row.ProtocolVersion, ), + InitiationHeight: row.InitiationHeight, }, nil } diff --git a/staticaddr/deposit/manager.go b/staticaddr/deposit/manager.go index a2c02e6fd..efaef97aa 100644 --- a/staticaddr/deposit/manager.go +++ b/staticaddr/deposit/manager.go @@ -336,10 +336,11 @@ func (m *Manager) getBlockHeight(ctx context.Context, "deposit, %w", err) } - notifChan, errChan, err := m.cfg.ChainNotifier.RegisterConfirmationsNtfn( //nolint:lll - ctx, &utxo.OutPoint.Hash, addressParams.PkScript, MinConfs, - int32(m.initiationHeight), - ) + notifChan, errChan, err := + m.cfg.ChainNotifier.RegisterConfirmationsNtfn( + ctx, &utxo.OutPoint.Hash, addressParams.PkScript, + MinConfs, addressParams.InitiationHeight, + ) if err != nil { return 0, err }