diff --git a/docs/specs/p2p-message.md b/docs/specs/p2p-message.md index f25a83da..33f1e43e 100644 --- a/docs/specs/p2p-message.md +++ b/docs/specs/p2p-message.md @@ -54,13 +54,11 @@ table OpenChannel { funding_fee_rate: Uint64, commitment_fee_rate: Uint64, max_tlc_value_in_flight: Uint128, - max_tlc_number_in_flight: Uint64, + max_tlc_number_in_flight: Uint64, min_tlc_value: Uint128, to_self_delay: Uint64, funding_pubkey: Byte33, - revocation_basepoint: Byte33, - payment_basepoint: Byte33, - delayed_payment_basepoint: Byte33, + tlc_basepoint: Byte33, first_per_commitment_point: Byte33, second_per_commitment_point: Byte33, next_local_nonce: Byte66, @@ -69,7 +67,7 @@ table OpenChannel { ``` - chain_hash: Chain genesis block hash -- channel_id: The ID of the channel, which is a temporary ID derived from the revocation_basepoint before the channel is officially established. After the channel is established, it will be replaced with the actual channel ID, derived from a blake2b hash of the sorted revocation_basepoints of both parties. +- channel_id: The ID of the channel, which is a temporary ID derived from the tlc_basepoint before the channel is officially established. After the channel is established, it will be replaced with the actual channel ID, derived from a blake2b hash of the sorted tlc_basepoints of both parties. - funding_type_script: Specifies the asset type of the channel. If empty, it indicates using CKB native token as the asset. - funding_amount: The amount of assets the channel initiator wants to contribute. - funding_fee_rate: Funding transaction fee rate, in shannons per kilo-bytes. @@ -79,16 +77,12 @@ table OpenChannel { - min_tlc_value: The minimum value of TLCs that the channel initiator can accept. - to_self_delay: The delay time for the channel initiator to unlock the outputs from the commitment transaction, in EpochNumberWithFraction. - funding_pubkey: The pubkey of the channel initiator, used for generating 2-2 multisig contracts. -- revocation_basepoint: See further description below. -- payment_basepoint: -- delayed_payment_basepoint: +- tlc_basepoint: The master key used to derive child keys required for tlcs, we will use the same method as lightning network to derive these keys, see [Secret Derivations] for more details. - first_per_commitment_point: - second_per_commitment_point: - next_local_nonce: Used for generating partial signatures for unlocking 2-2 Schnorr multisig. - channel_flags: Channel flags, currently only using one bit to indicate whether to broadcast this channel information on the P2P network. -The xxx_basepoints here are master keys used to derive child keys required for different types of transactions. For example, they can be used with per_commitment_point to derive commitment transactions keys. We will use the same method as lightning network to derive these keys, see [Secret Derivations] for more details. - ### AcceptChannel `AcceptChannel` is sent by the receiver of the channel to the initiator of the channel to accept the establishment of a payment channel. @@ -98,11 +92,11 @@ table AcceptChannel { channel_id: Byte32, funding_amount: Uint128, max_tlc_value_in_flight: Uint128, - max_tlc_number_in_flight: Uint64, + max_tlc_number_in_flight: Uint64, min_tlc_value: Uint128, to_self_delay: Uint64, funding_pubkey: Byte33, - revocation_basepoint: Byte33, + tlc_basepoint: Byte33, payment_basepoint: Byte33, delayed_payment_basepoint: Byte33, first_per_commitment_point: Byte33, @@ -118,10 +112,7 @@ table AcceptChannel { - min_tlc_value: The minimum value of TLCs that the channel receiver can accept. - to_self_delay: The delay time for the channel receiver to unlock the outputs from the commitment transaction, in EpochNumberWithFraction. - funding_pubkey: The pubkey of the channel receiver, used for generating 2-2 multisig contracts. -- revocation_basepoint: See the description in `OpenChannel` message. -- payment_basepoint: -- delayed_payment_basepoint: -- tlc_basepoint: +- tlc_basepoint: See the description in `OpenChannel` message. - first_per_commitment_point: - second_per_commitment_point: - next_local_nonce: Used for generating partial signatures for unlocking 2-2 Schnorr multisig. diff --git a/src/fiber/channel.rs b/src/fiber/channel.rs index da434551..8660cf33 100644 --- a/src/fiber/channel.rs +++ b/src/fiber/channel.rs @@ -12,9 +12,9 @@ use crate::{ invoice::InvoiceStore, }; use ckb_hash::{blake2b_256, new_blake2b}; -use ckb_sdk::Since; +use ckb_sdk::{Since, SinceType}; use ckb_types::{ - core::{FeeRate, TransactionBuilder, TransactionView}, + core::{EpochNumberWithFraction, FeeRate, TransactionBuilder, TransactionView}, packed::{Bytes, CellInput, CellOutput, OutPoint, Script, Transaction}, prelude::{AsTransactionBuilder, IntoTransactionView, Pack, Unpack}, }; @@ -180,11 +180,16 @@ pub struct ChannelCommandWithId { pub const DEFAULT_FEE_RATE: u64 = 1_000; pub const DEFAULT_COMMITMENT_FEE_RATE: u64 = 1_000; +// The default commitment delay is 6 epochs = 24 hours. +pub const DEFAULT_COMMITMENT_DELAY_EPOCHS: u64 = 6; +// The min commitment delay is 1 epoch = 4 hours. +pub const MIN_COMMITMENT_DELAY_EPOCHS: u64 = 1; +// The max commitment delay is 84 epochs = 14 days. +pub const MAX_COMMITMENT_DELAY_EPOCHS: u64 = 84; pub const DEFAULT_MAX_TLC_VALUE_IN_FLIGHT: u128 = u128::MAX; pub const DEFAULT_MAX_TLC_NUMBER_IN_FLIGHT: u64 = 30; pub const SYS_MAX_TLC_NUMBER_IN_FLIGHT: u64 = 253; pub const DEFAULT_MIN_TLC_VALUE: u128 = 0; -pub const DEFAULT_TO_LOCAL_DELAY_BLOCKS: u64 = 10; #[derive(Debug)] pub struct TxUpdateCommand { @@ -199,6 +204,7 @@ pub struct OpenChannelParameter { pub shutdown_script: Script, pub channel_id_sender: oneshot::Sender, pub commitment_fee_rate: Option, + pub commitment_delay_epoch: Option, pub funding_fee_rate: Option, pub max_tlc_value_in_flight: Option, pub max_tlc_number_in_flight: Option, @@ -1508,12 +1514,12 @@ where channel_id, chain_hash, commitment_fee_rate, + commitment_delay_epoch, funding_fee_rate, funding_udt_type_script, funding_amount, shutdown_script, reserved_ckb_amount, - to_local_delay, first_per_commitment_point, second_per_commitment_point, next_local_nonce, @@ -1546,6 +1552,7 @@ where local_funding_amount, local_reserved_ckb_amount, *commitment_fee_rate, + *commitment_delay_epoch, *funding_fee_rate, funding_udt_type_script.clone(), &seed, @@ -1555,7 +1562,6 @@ where shutdown_script.clone(), *funding_amount, *reserved_ckb_amount, - *to_local_delay, counterpart_pubkeys, next_local_nonce.clone(), channel_announcement_nonce.clone(), @@ -1569,6 +1575,7 @@ where "local_reserved_ckb_amount", "remote_reserved_ckb_amount", "commitment_fee_rate", + "commitment_delay_epoch", "funding_fee_rate", "max_tlc_number_in_flight", ])?; @@ -1587,12 +1594,8 @@ where reserved_ckb_amount: local_reserved_ckb_amount, max_tlc_value_in_flight: DEFAULT_MAX_TLC_VALUE_IN_FLIGHT, max_tlc_number_in_flight: DEFAULT_MAX_TLC_NUMBER_IN_FLIGHT, - to_local_delay: *to_local_delay, funding_pubkey: state.signer.funding_key.pubkey(), - revocation_basepoint: state.signer.revocation_base_key.pubkey(), - payment_basepoint: state.signer.payment_key.pubkey(), min_tlc_value: DEFAULT_MIN_TLC_VALUE, - delayed_payment_basepoint: state.signer.delayed_payment_base_key.pubkey(), tlc_basepoint: state.signer.tlc_base_key.pubkey(), first_per_commitment_point: state .signer @@ -1631,6 +1634,7 @@ where shutdown_script, channel_id_sender, commitment_fee_rate, + commitment_delay_epoch, funding_fee_rate, max_tlc_number_in_flight, max_tlc_value_in_flight, @@ -1654,16 +1658,23 @@ where funding_amount, reserved_ckb_amount, commitment_fee_rate, + commitment_delay_epoch + .unwrap_or(EpochNumberWithFraction::new( + DEFAULT_COMMITMENT_DELAY_EPOCHS, + 0, + 1, + )) + .full_value(), funding_fee_rate, funding_udt_type_script.clone(), shutdown_script.clone(), max_tlc_value_in_flight.unwrap_or(DEFAULT_MAX_TLC_VALUE_IN_FLIGHT), max_tlc_number_in_flight.unwrap_or(DEFAULT_MAX_TLC_NUMBER_IN_FLIGHT), - LockTime::new(DEFAULT_TO_LOCAL_DELAY_BLOCKS), ); channel.check_ckb_params(vec![ "commitment_fee_rate", + "commitment_delay_epoch", "funding_fee_rate", "local_reserved_ckb_amount", "max_tlc_number_in_flight", @@ -1689,10 +1700,10 @@ where reserved_ckb_amount: channel.local_reserved_ckb_amount, funding_fee_rate, commitment_fee_rate, + commitment_delay_epoch: channel.commitment_delay_epoch, max_tlc_value_in_flight: channel.max_tlc_value_in_flight, max_tlc_number_in_flight: channel.max_tlc_number_in_flight, min_tlc_value: DEFAULT_MIN_TLC_VALUE, - to_local_delay: LockTime::new(DEFAULT_TO_LOCAL_DELAY_BLOCKS), channel_flags, first_per_commitment_point: channel .signer @@ -1700,23 +1711,8 @@ where second_per_commitment_point: channel .signer .get_commitment_point(commitment_number + 1), - funding_pubkey: channel - .get_local_channel_parameters() - .pubkeys - .funding_pubkey, - revocation_basepoint: channel - .get_local_channel_parameters() - .pubkeys - .revocation_base_key, - payment_basepoint: channel - .get_local_channel_parameters() - .pubkeys - .payment_base_key, - delayed_payment_basepoint: channel - .get_local_channel_parameters() - .pubkeys - .delayed_payment_base_key, - tlc_basepoint: channel.get_local_channel_parameters().pubkeys.tlc_base_key, + funding_pubkey: channel.get_local_channel_public_keys().funding_pubkey, + tlc_basepoint: channel.get_local_channel_public_keys().tlc_base_key, next_local_nonce: channel.get_local_musig2_pubnonce(), channel_announcement_nonce, }); @@ -1997,6 +1993,10 @@ pub struct ChannelActorState { // The side who want to submit the commitment transaction will pay fee pub commitment_fee_rate: u64, + // The delay time for the commitment transaction, this value is set by the initiator of the channel. + // It must be a relative EpochNumberWithFraction in u64 format. + pub commitment_delay_epoch: u64, + // The fee rate used for funding transaction, the initiator may set it as `funding_fee_rate` option, // if it's not set, DEFAULT_FEE_RATE will be used as default value, two sides will use the same fee rate pub funding_fee_rate: u64, @@ -2004,8 +2004,8 @@ pub struct ChannelActorState { // Signer is used to sign the commitment transactions. pub signer: InMemorySigner, - // Cached channel parameter for easier of access. - pub local_channel_parameters: ChannelParametersOneParty, + // Cached channel public keys for easier of access. + pub local_channel_public_keys: ChannelBasePublicKeys, // Commitment numbers that are used to derive keys. // This value is guaranteed to be 0 when channel is just created. @@ -2045,7 +2045,7 @@ pub struct ChannelActorState { // All the commitment point that are sent from the counterparty. // We need to save all these points to derive the keys for the commitment transactions. pub remote_commitment_points: Vec, - pub remote_channel_parameters: Option, + pub remote_channel_public_keys: Option, // The shutdown info for both local and remote, they are setup by the shutdown command or message. pub local_shutdown_info: Option, @@ -2280,25 +2280,18 @@ impl ChannelState { } } -pub fn new_channel_id_from_seed(seed: &[u8]) -> Hash256 { +fn new_channel_id_from_seed(seed: &[u8]) -> Hash256 { blake2b_256(seed).into() } -fn derive_channel_id_from_revocation_keys( - revocation_basepoint1: &Pubkey, - revocation_basepoint2: &Pubkey, -) -> Hash256 { - let local_revocation = revocation_basepoint1.0.serialize(); - let remote_revocation = revocation_basepoint2.0.serialize(); - let mut preimage = [local_revocation, remote_revocation]; +fn derive_channel_id_from_tlc_keys(tlc_basepoint1: &Pubkey, tlc_basepoint2: &Pubkey) -> Hash256 { + let mut preimage = [tlc_basepoint1.0.serialize(), tlc_basepoint2.0.serialize()]; preimage.sort(); new_channel_id_from_seed(&preimage.concat()) } -fn derive_temp_channel_id_from_revocation_key(revocation_basepoint: &Pubkey) -> Hash256 { - let revocation = revocation_basepoint.0.serialize(); - let zero_point = [0; 33]; - let preimage = [zero_point, revocation].concat(); +fn derive_temp_channel_id_from_tlc_key(tlc_basepoint: &Pubkey) -> Hash256 { + let preimage = [tlc_basepoint.0.serialize(), [0; 33]].concat(); new_channel_id_from_seed(&preimage) } @@ -2345,14 +2338,8 @@ impl From<&ChannelActorState> for Musig2VerifyContext { impl From<(&ChannelActorState, bool)> for Musig2SignContext { fn from(value: (&ChannelActorState, bool)) -> Self { let (channel, local) = value; - let local_pubkey = channel - .get_local_channel_parameters() - .pubkeys - .funding_pubkey; - let remote_pubkey = channel - .get_remote_channel_parameters() - .pubkeys - .funding_pubkey; + let local_pubkey = channel.get_local_channel_public_keys().funding_pubkey; + let remote_pubkey = channel.get_remote_channel_public_keys().funding_pubkey; let pubkeys = if local { [local_pubkey, remote_pubkey] } else { @@ -2381,14 +2368,8 @@ impl From<(&ChannelActorState, bool)> for Musig2SignContext { impl From<(&ChannelActorState, bool)> for Musig2VerifyContext { fn from(value: (&ChannelActorState, bool)) -> Self { let (channel, local) = value; - let local_pubkey = channel - .get_local_channel_parameters() - .pubkeys - .funding_pubkey; - let remote_pubkey = channel - .get_remote_channel_parameters() - .pubkeys - .funding_pubkey; + let local_pubkey = channel.get_local_channel_public_keys().funding_pubkey; + let remote_pubkey = channel.get_remote_channel_public_keys().funding_pubkey; let pubkeys = if local { [local_pubkey, remote_pubkey] } else { @@ -2661,6 +2642,7 @@ impl ChannelActorState { local_value: u128, local_reserved_ckb_amount: u64, commitment_fee_rate: u64, + commitment_delay_epoch: u64, funding_fee_rate: u64, funding_udt_type_script: Option