@ -15,36 +15,41 @@
static bool trim ( const struct htlc * htlc ,
static bool trim ( const struct htlc * htlc ,
u32 feerate_per_kw ,
u32 feerate_per_kw ,
struct amount_sat dust_limit ,
struct amount_sat dust_limit ,
bool option_anchor_outputs ,
enum side side )
enum side side )
{
{
return htlc_is_trimmed ( htlc_owner ( htlc ) , htlc - > amount ,
return htlc_is_trimmed ( htlc_owner ( htlc ) , htlc - > amount ,
feerate_per_kw , dust_limit , side ,
feerate_per_kw , dust_limit , side ,
false /* FIXME-anchor */ ) ;
option_anchor_outputs ) ;
}
}
size_t commit_tx_num_untrimmed ( const struct htlc * * htlcs ,
size_t commit_tx_num_untrimmed ( const struct htlc * * htlcs ,
u32 feerate_per_kw ,
u32 feerate_per_kw ,
struct amount_sat dust_limit ,
struct amount_sat dust_limit ,
bool option_anchor_outputs ,
enum side side )
enum side side )
{
{
size_t i , n ;
size_t i , n ;
for ( i = n = 0 ; i < tal_count ( htlcs ) ; i + + )
for ( i = n = 0 ; i < tal_count ( htlcs ) ; i + + )
n + = ! trim ( htlcs [ i ] , feerate_per_kw , dust_limit , side ) ;
n + = ! trim ( htlcs [ i ] , feerate_per_kw , dust_limit ,
option_anchor_outputs , side ) ;
return n ;
return n ;
}
}
static void add_offered_htlc_out ( struct bitcoin_tx * tx , size_t n ,
static void add_offered_htlc_out ( struct bitcoin_tx * tx , size_t n ,
const struct htlc * htlc ,
const struct htlc * htlc ,
const struct keyset * keyset )
const struct keyset * keyset ,
bool option_anchor_outputs )
{
{
struct ripemd160 ripemd ;
struct ripemd160 ripemd ;
u8 * wscript , * p2wsh ;
u8 * wscript , * p2wsh ;
struct amount_sat amount = amount_msat_to_sat_round_down ( htlc - > amount ) ;
struct amount_sat amount = amount_msat_to_sat_round_down ( htlc - > amount ) ;
ripemd160 ( & ripemd , htlc - > rhash . u . u8 , sizeof ( htlc - > rhash . u . u8 ) ) ;
ripemd160 ( & ripemd , htlc - > rhash . u . u8 , sizeof ( htlc - > rhash . u . u8 ) ) ;
wscript = htlc_offered_wscript ( tx , & ripemd , keyset , false /* FIXME-anchor */ ) ;
wscript = htlc_offered_wscript ( tx , & ripemd , keyset ,
option_anchor_outputs ) ;
p2wsh = scriptpubkey_p2wsh ( tx , wscript ) ;
p2wsh = scriptpubkey_p2wsh ( tx , wscript ) ;
bitcoin_tx_add_output ( tx , p2wsh , wscript , amount ) ;
bitcoin_tx_add_output ( tx , p2wsh , wscript , amount ) ;
SUPERVERBOSE ( " # HTLC % " PRIu64 " offered %s wscript %s \n " , htlc - > id ,
SUPERVERBOSE ( " # HTLC % " PRIu64 " offered %s wscript %s \n " , htlc - > id ,
@ -55,14 +60,16 @@ static void add_offered_htlc_out(struct bitcoin_tx *tx, size_t n,
static void add_received_htlc_out ( struct bitcoin_tx * tx , size_t n ,
static void add_received_htlc_out ( struct bitcoin_tx * tx , size_t n ,
const struct htlc * htlc ,
const struct htlc * htlc ,
const struct keyset * keyset )
const struct keyset * keyset ,
bool option_anchor_outputs )
{
{
struct ripemd160 ripemd ;
struct ripemd160 ripemd ;
u8 * wscript , * p2wsh ;
u8 * wscript , * p2wsh ;
struct amount_sat amount ;
struct amount_sat amount ;
ripemd160 ( & ripemd , htlc - > rhash . u . u8 , sizeof ( htlc - > rhash . u . u8 ) ) ;
ripemd160 ( & ripemd , htlc - > rhash . u . u8 , sizeof ( htlc - > rhash . u . u8 ) ) ;
wscript = htlc_received_wscript ( tx , & ripemd , & htlc - > expiry , keyset , false /* FIXME-anchor */ ) ;
wscript = htlc_received_wscript ( tx , & ripemd , & htlc - > expiry , keyset ,
option_anchor_outputs ) ;
p2wsh = scriptpubkey_p2wsh ( tx , wscript ) ;
p2wsh = scriptpubkey_p2wsh ( tx , wscript ) ;
amount = amount_msat_to_sat_round_down ( htlc - > amount ) ;
amount = amount_msat_to_sat_round_down ( htlc - > amount ) ;
@ -93,6 +100,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
const struct htlc * * * htlcmap ,
const struct htlc * * * htlcmap ,
struct wally_tx_output * direct_outputs [ NUM_SIDES ] ,
struct wally_tx_output * direct_outputs [ NUM_SIDES ] ,
u64 obscured_commitment_number ,
u64 obscured_commitment_number ,
bool option_anchor_outputs ,
enum side side )
enum side side )
{
{
struct amount_sat base_fee ;
struct amount_sat base_fee ;
@ -100,6 +108,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
struct bitcoin_tx * tx ;
struct bitcoin_tx * tx ;
size_t i , n , untrimmed ;
size_t i , n , untrimmed ;
u32 * cltvs ;
u32 * cltvs ;
bool to_local , to_remote ;
struct htlc * dummy_to_local = ( struct htlc * ) 0x01 ,
struct htlc * dummy_to_local = ( struct htlc * ) 0x01 ,
* dummy_to_remote = ( struct htlc * ) 0x02 ;
* dummy_to_remote = ( struct htlc * ) 0x02 ;
const u8 * funding_wscript = bitcoin_redeem_2of2 ( tmpctx ,
const u8 * funding_wscript = bitcoin_redeem_2of2 ( tmpctx ,
@ -117,7 +126,9 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
*/
*/
untrimmed = commit_tx_num_untrimmed ( htlcs ,
untrimmed = commit_tx_num_untrimmed ( htlcs ,
feerate_per_kw ,
feerate_per_kw ,
dust_limit , side ) ;
dust_limit ,
option_anchor_outputs ,
side ) ;
/* BOLT #3:
/* BOLT #3:
*
*
@ -125,11 +136,22 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
* fee ] ( # fee - calculation ) .
* fee ] ( # fee - calculation ) .
*/
*/
base_fee = commit_tx_base_fee ( feerate_per_kw , untrimmed ,
base_fee = commit_tx_base_fee ( feerate_per_kw , untrimmed ,
false /* FIXME-anchor */ ) ;
option_anchor_outputs ) ;
SUPERVERBOSE ( " # base commitment transaction fee = %s \n " ,
SUPERVERBOSE ( " # base commitment transaction fee = %s \n " ,
type_to_string ( tmpctx , struct amount_sat , & base_fee ) ) ;
type_to_string ( tmpctx , struct amount_sat , & base_fee ) ) ;
/* BOLT-a12da24dd0102c170365124782b46d9710950ac1:
* If ` option_anchor_outputs ` applies to the commitment
* transaction , also subtract two times the fixed anchor size
* of 330 sats from the funder ( either ` to_local ` or
* ` to_remote ` ) .
*/
if ( option_anchor_outputs
& & ! amount_sat_add ( & base_fee , base_fee , AMOUNT_SAT ( 660 ) ) )
/* Can't overflow: feerate is u32. */
abort ( ) ;
/* BOLT #3:
/* BOLT #3:
*
*
* 3. Subtract this base fee from the funder ( either ` to_local ` or
* 3. Subtract this base fee from the funder ( either ` to_local ` or
@ -142,7 +164,8 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
struct amount_sat out = AMOUNT_SAT ( 0 ) ;
struct amount_sat out = AMOUNT_SAT ( 0 ) ;
bool ok = true ;
bool ok = true ;
for ( i = 0 ; i < tal_count ( htlcs ) ; i + + ) {
for ( i = 0 ; i < tal_count ( htlcs ) ; i + + ) {
if ( ! trim ( htlcs [ i ] , feerate_per_kw , dust_limit , side ) )
if ( ! trim ( htlcs [ i ] , feerate_per_kw , dust_limit ,
option_anchor_outputs , side ) )
ok & = amount_sat_add ( & out , out , amount_msat_to_sat_round_down ( htlcs [ i ] - > amount ) ) ;
ok & = amount_sat_add ( & out , out , amount_msat_to_sat_round_down ( htlcs [ i ] - > amount ) ) ;
}
}
if ( amount_msat_greater_sat ( self_pay , dust_limit ) )
if ( amount_msat_greater_sat ( self_pay , dust_limit ) )
@ -155,8 +178,8 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
}
}
# endif
# endif
/* Worst-case sizing: both to-local and to-remote outputs. */
/* Worst-case sizing: both to-local and to-remote outputs, and anchors . */
tx = bitcoin_tx ( ctx , chainparams , 1 , untrimmed + 2 , 0 ) ;
tx = bitcoin_tx ( ctx , chainparams , 1 , untrimmed + 2 + 2 , 0 ) ;
/* We keep track of which outputs have which HTLCs */
/* We keep track of which outputs have which HTLCs */
* htlcmap = tal_arr ( tx , const struct htlc * , tx - > wtx - > outputs_allocation_len ) ;
* htlcmap = tal_arr ( tx , const struct htlc * , tx - > wtx - > outputs_allocation_len ) ;
@ -177,9 +200,11 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
for ( i = 0 ; i < tal_count ( htlcs ) ; i + + ) {
for ( i = 0 ; i < tal_count ( htlcs ) ; i + + ) {
if ( htlc_owner ( htlcs [ i ] ) ! = side )
if ( htlc_owner ( htlcs [ i ] ) ! = side )
continue ;
continue ;
if ( trim ( htlcs [ i ] , feerate_per_kw , dust_limit , side ) )
if ( trim ( htlcs [ i ] , feerate_per_kw , dust_limit ,
option_anchor_outputs , side ) )
continue ;
continue ;
add_offered_htlc_out ( tx , n , htlcs [ i ] , keyset ) ;
add_offered_htlc_out ( tx , n , htlcs [ i ] , keyset ,
option_anchor_outputs ) ;
( * htlcmap ) [ n ] = htlcs [ i ] ;
( * htlcmap ) [ n ] = htlcs [ i ] ;
cltvs [ n ] = abs_locktime_to_blocks ( & htlcs [ i ] - > expiry ) ;
cltvs [ n ] = abs_locktime_to_blocks ( & htlcs [ i ] - > expiry ) ;
n + + ;
n + + ;
@ -193,9 +218,11 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
for ( i = 0 ; i < tal_count ( htlcs ) ; i + + ) {
for ( i = 0 ; i < tal_count ( htlcs ) ; i + + ) {
if ( htlc_owner ( htlcs [ i ] ) = = side )
if ( htlc_owner ( htlcs [ i ] ) = = side )
continue ;
continue ;
if ( trim ( htlcs [ i ] , feerate_per_kw , dust_limit , side ) )
if ( trim ( htlcs [ i ] , feerate_per_kw , dust_limit ,
option_anchor_outputs , side ) )
continue ;
continue ;
add_received_htlc_out ( tx , n , htlcs [ i ] , keyset ) ;
add_received_htlc_out ( tx , n , htlcs [ i ] , keyset ,
option_anchor_outputs ) ;
( * htlcmap ) [ n ] = htlcs [ i ] ;
( * htlcmap ) [ n ] = htlcs [ i ] ;
cltvs [ n ] = abs_locktime_to_blocks ( & htlcs [ i ] - > expiry ) ;
cltvs [ n ] = abs_locktime_to_blocks ( & htlcs [ i ] - > expiry ) ;
n + + ;
n + + ;
@ -221,7 +248,9 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
type_to_string ( tmpctx , struct amount_sat , & amount ) ,
type_to_string ( tmpctx , struct amount_sat , & amount ) ,
tal_hex ( tmpctx , wscript ) ) ;
tal_hex ( tmpctx , wscript ) ) ;
n + + ;
n + + ;
}
to_local = true ;
} else
to_local = false ;
/* BOLT #3:
/* BOLT #3:
*
*
@ -251,6 +280,29 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
type_to_string ( tmpctx , struct pubkey ,
type_to_string ( tmpctx , struct pubkey ,
& keyset - > other_payment_key ) ) ;
& keyset - > other_payment_key ) ) ;
n + + ;
n + + ;
to_remote = true ;
} else
to_remote = false ;
if ( option_anchor_outputs ) {
/* BOLT-a12da24dd0102c170365124782b46d9710950ac1 #3:
* if ` to_local ` exists or there are untrimmed HTLCs , add a ` to_local_anchor ` output
*/
if ( to_local | | untrimmed ! = 0 ) {
tx_add_anchor_output ( tx , local_funding_key ) ;
( * htlcmap ) [ n ] = NULL ;
n + + ;
}
/* BOLT-a12da24dd0102c170365124782b46d9710950ac1 #3:
* if ` to_remote ` exists or there are untrimmed HTLCs , add a ` to_remote_anchor ` output
*/
if ( to_remote | | untrimmed ! = 0 ) {
tx_add_anchor_output ( tx , remote_funding_key ) ;
( * htlcmap ) [ n ] = NULL ;
n + + ;
}
}
}
/* BOLT #2:
/* BOLT #2: