@ -31,6 +31,7 @@ from .i18n import _
from . lnaddr import lndecode
from . lnaddr import lndecode
from . bip32 import BIP32Node , BIP32_PRIME
from . bip32 import BIP32Node , BIP32_PRIME
from . transaction import BCDataStream , OPPushDataGeneric
from . transaction import BCDataStream , OPPushDataGeneric
from . logging import get_logger
if TYPE_CHECKING :
if TYPE_CHECKING :
@ -39,6 +40,9 @@ if TYPE_CHECKING:
from . lnonion import OnionRoutingFailure
from . lnonion import OnionRoutingFailure
_logger = get_logger ( __name__ )
# defined in BOLT-03:
# defined in BOLT-03:
HTLC_TIMEOUT_WEIGHT = 663
HTLC_TIMEOUT_WEIGHT = 663
HTLC_SUCCESS_WEIGHT = 703
HTLC_SUCCESS_WEIGHT = 703
@ -192,7 +196,7 @@ class LocalConfig(ChannelConfig):
per_commitment_secret_seed = attr . ib ( type = bytes , converter = hex_to_bytes )
per_commitment_secret_seed = attr . ib ( type = bytes , converter = hex_to_bytes )
@classmethod
@classmethod
def from_seed ( self , * * kwargs ) :
def from_seed ( cl s, * * kwargs ) :
channel_seed = kwargs [ ' channel_seed ' ]
channel_seed = kwargs [ ' channel_seed ' ]
static_remotekey = kwargs . pop ( ' static_remotekey ' )
static_remotekey = kwargs . pop ( ' static_remotekey ' )
node = BIP32Node . from_rootseed ( channel_seed , xtype = ' standard ' )
node = BIP32Node . from_rootseed ( channel_seed , xtype = ' standard ' )
@ -202,7 +206,11 @@ class LocalConfig(ChannelConfig):
kwargs [ ' htlc_basepoint ' ] = keypair_generator ( LnKeyFamily . HTLC_BASE )
kwargs [ ' htlc_basepoint ' ] = keypair_generator ( LnKeyFamily . HTLC_BASE )
kwargs [ ' delayed_basepoint ' ] = keypair_generator ( LnKeyFamily . DELAY_BASE )
kwargs [ ' delayed_basepoint ' ] = keypair_generator ( LnKeyFamily . DELAY_BASE )
kwargs [ ' revocation_basepoint ' ] = keypair_generator ( LnKeyFamily . REVOCATION_BASE )
kwargs [ ' revocation_basepoint ' ] = keypair_generator ( LnKeyFamily . REVOCATION_BASE )
kwargs [ ' payment_basepoint ' ] = OnlyPubkeyKeypair ( static_remotekey ) if static_remotekey else keypair_generator ( LnKeyFamily . PAYMENT_BASE )
if static_remotekey :
kwargs [ ' payment_basepoint ' ] = OnlyPubkeyKeypair ( static_remotekey )
else :
# we expect all our channels to use option_static_remotekey, so ending up here likely indicates an issue...
kwargs [ ' payment_basepoint ' ] = keypair_generator ( LnKeyFamily . PAYMENT_BASE )
return LocalConfig ( * * kwargs )
return LocalConfig ( * * kwargs )
def validate_params ( self , * , funding_sat : int ) - > None :
def validate_params ( self , * , funding_sat : int ) - > None :
@ -236,7 +244,9 @@ class ChannelConstraints(StoredObject):
funding_txn_minimum_depth = attr . ib ( type = int )
funding_txn_minimum_depth = attr . ib ( type = int )
CHANNEL_BACKUP_VERSION = 0
CHANNEL_BACKUP_VERSION_LATEST = 1
KNOWN_CHANNEL_BACKUP_VERSIONS = ( 0 , 1 , )
assert CHANNEL_BACKUP_VERSION_LATEST in KNOWN_CHANNEL_BACKUP_VERSIONS
@attr . s
@attr . s
class ChannelBackupStorage ( StoredObject ) :
class ChannelBackupStorage ( StoredObject ) :
@ -255,13 +265,13 @@ class ChannelBackupStorage(StoredObject):
@stored_in ( ' onchain_channel_backups ' )
@stored_in ( ' onchain_channel_backups ' )
@attr . s
@attr . s
class OnchainChannelBackupStorage ( ChannelBackupStorage ) :
class OnchainChannelBackupStorage ( ChannelBackupStorage ) :
node_id_prefix = attr . ib ( type = bytes , converter = hex_to_bytes )
node_id_prefix = attr . ib ( type = bytes , converter = hex_to_bytes ) # remote node pubkey
@stored_in ( ' imported_channel_backups ' )
@stored_in ( ' imported_channel_backups ' )
@attr . s
@attr . s
class ImportedChannelBackupStorage ( ChannelBackupStorage ) :
class ImportedChannelBackupStorage ( ChannelBackupStorage ) :
node_id = attr . ib ( type = bytes , converter = hex_to_bytes )
node_id = attr . ib ( type = bytes , converter = hex_to_bytes ) # remote node pubkey
privkey = attr . ib ( type = bytes , converter = hex_to_bytes )
privkey = attr . ib ( type = bytes , converter = hex_to_bytes ) # local node privkey
host = attr . ib ( type = str )
host = attr . ib ( type = str )
port = attr . ib ( type = int , converter = int )
port = attr . ib ( type = int , converter = int )
channel_seed = attr . ib ( type = bytes , converter = hex_to_bytes )
channel_seed = attr . ib ( type = bytes , converter = hex_to_bytes )
@ -269,10 +279,11 @@ class ImportedChannelBackupStorage(ChannelBackupStorage):
remote_delay = attr . ib ( type = int , converter = int )
remote_delay = attr . ib ( type = int , converter = int )
remote_payment_pubkey = attr . ib ( type = bytes , converter = hex_to_bytes )
remote_payment_pubkey = attr . ib ( type = bytes , converter = hex_to_bytes )
remote_revocation_pubkey = attr . ib ( type = bytes , converter = hex_to_bytes )
remote_revocation_pubkey = attr . ib ( type = bytes , converter = hex_to_bytes )
local_payment_pubkey = attr . ib ( type = bytes , converter = hex_to_bytes ) # type: Optional[bytes]
def to_bytes ( self ) - > bytes :
def to_bytes ( self ) - > bytes :
vds = BCDataStream ( )
vds = BCDataStream ( )
vds . write_uint16 ( CHANNEL_BACKUP_VERSION )
vds . write_uint16 ( CHANNEL_BACKUP_VERSION_LATEST )
vds . write_boolean ( self . is_initiator )
vds . write_boolean ( self . is_initiator )
vds . write_bytes ( self . privkey , 32 )
vds . write_bytes ( self . privkey , 32 )
vds . write_bytes ( self . channel_seed , 32 )
vds . write_bytes ( self . channel_seed , 32 )
@ -286,6 +297,7 @@ class ImportedChannelBackupStorage(ChannelBackupStorage):
vds . write_uint16 ( self . remote_delay )
vds . write_uint16 ( self . remote_delay )
vds . write_string ( self . host )
vds . write_string ( self . host )
vds . write_uint16 ( self . port )
vds . write_uint16 ( self . port )
vds . write_bytes ( self . local_payment_pubkey , 33 )
return bytes ( vds . input )
return bytes ( vds . input )
@staticmethod
@staticmethod
@ -293,22 +305,40 @@ class ImportedChannelBackupStorage(ChannelBackupStorage):
vds = BCDataStream ( )
vds = BCDataStream ( )
vds . write ( s )
vds . write ( s )
version = vds . read_uint16 ( )
version = vds . read_uint16 ( )
if version != CHANNEL_BACKUP_VERSION :
if version not in KNOWN_CHANNEL_BACKUP_VERSIONS :
raise Exception ( f " unknown version for channel backup: { version } " )
raise Exception ( f " unknown version for channel backup: { version } " )
is_initiator = vds . read_boolean ( )
privkey = vds . read_bytes ( 32 )
channel_seed = vds . read_bytes ( 32 )
node_id = vds . read_bytes ( 33 )
funding_txid = vds . read_bytes ( 32 ) . hex ( )
funding_index = vds . read_uint16 ( )
funding_address = vds . read_string ( )
remote_payment_pubkey = vds . read_bytes ( 33 )
remote_revocation_pubkey = vds . read_bytes ( 33 )
local_delay = vds . read_uint16 ( )
remote_delay = vds . read_uint16 ( )
host = vds . read_string ( )
port = vds . read_uint16 ( )
if version > = 1 :
local_payment_pubkey = vds . read_bytes ( 33 )
else :
local_payment_pubkey = None
return ImportedChannelBackupStorage (
return ImportedChannelBackupStorage (
is_initiator = vds . read_boolean ( ) ,
is_initiator = is_initiator ,
privkey = vds . read_bytes ( 32 ) ,
privkey = privkey ,
channel_seed = vds . read_bytes ( 32 ) ,
channel_seed = channel_seed ,
node_id = vds . read_bytes ( 33 ) ,
node_id = node_id ,
funding_txid = vds . read_bytes ( 32 ) . hex ( ) ,
funding_txid = funding_txid ,
funding_index = vds . read_uint16 ( ) ,
funding_index = funding_index ,
funding_address = vds . read_string ( ) ,
funding_address = funding_address ,
remote_payment_pubkey = vds . read_bytes ( 33 ) ,
remote_payment_pubkey = remote_payment_pubkey ,
remote_revocation_pubkey = vds . read_bytes ( 33 ) ,
remote_revocation_pubkey = remote_revocation_pubkey ,
local_delay = vds . read_uint16 ( ) ,
local_delay = local_delay ,
remote_delay = vds . read_uint16 ( ) ,
remote_delay = remote_delay ,
host = vds . read_string ( ) ,
host = host ,
port = vds . read_uint16 ( ) ,
port = port ,
local_payment_pubkey = local_payment_pubkey ,
)
)
@staticmethod
@staticmethod