@ -662,22 +662,24 @@ static void updates_complete(struct chain_topology *topo)
next_topology_timer ( topo ) ;
next_topology_timer ( topo ) ;
}
}
static void record_output_spend ( struct lightningd * ld ,
static void record_utxo_spent ( struct lightningd * ld ,
const struct bitcoin_txid * txid ,
const struct bitcoin_txid * txid ,
const struct bitcoin_txid * utxo_txid ,
const struct bitcoin_txid * utxo_txid ,
u32 vout , u32 blockheight ,
u32 vout , u32 blockheight ,
struct amount_sat * input_amt )
struct amount_sat * input_amt )
{
{
struct utxo * utxo ;
struct utxo * utxo ;
struct chain_coin_mvt * mvt ;
struct chain_coin_mvt * mvt ;
u8 * ctx = tal ( NULL , u8 ) ;
u8 * ctx = tal ( NULL , u8 ) ;
utxo = wallet_utxo_get ( ctx , ld - > wallet , utxo_txid , vout ) ;
utxo = wallet_utxo_get ( ctx , ld - > wallet , utxo_txid , vout ) ;
if ( ! utxo )
if ( ! utxo ) {
log_broken ( ld - > log , " No record of utxo %s:%d " ,
log_broken ( ld - > log , " No record of utxo %s:%d " ,
type_to_string ( tmpctx , struct bitcoin_txid ,
type_to_string ( tmpctx , struct bitcoin_txid ,
utxo_txid ) ,
utxo_txid ) ,
vout ) ;
vout ) ;
return ;
}
* input_amt = utxo - > amount ;
* input_amt = utxo - > amount ;
mvt = new_coin_spend_track ( ctx , txid , utxo_txid , vout , blockheight ) ;
mvt = new_coin_spend_track ( ctx , txid , utxo_txid , vout , blockheight ) ;
@ -685,23 +687,14 @@ static void record_output_spend(struct lightningd *ld,
tal_free ( ctx ) ;
tal_free ( ctx ) ;
}
}
static void record_tx_outs_and_fees ( struct lightningd * ld , const struct bitcoin_tx * tx ,
static void record_outputs_as_withdraws ( const tal_t * ctx ,
struct bitcoin_txid * txid , u32 blockheight ,
struct lightningd * ld ,
struct amount_sat inputs_total )
const struct bitcoin_tx * tx ,
struct bitcoin_txid * txid ,
u32 blockheight )
{
{
struct amount_sat fee ;
struct chain_coin_mvt * mvt ;
struct chain_coin_mvt * mvt ;
size_t i ;
for ( size_t i = 0 ; i < tx - > wtx - > num_outputs ; i + + ) {
u8 * ctx = tal ( NULL , u8 ) ;
if ( ! tx )
log_broken ( ld - > log , " We have no record of transaction %s " ,
type_to_string ( ctx , struct bitcoin_txid , txid ) ) ;
/* We record every output on this transaction as a withdraw */
/* FIXME: collaborative tx will need to keep track of which
* outputs are ours */
for ( i = 0 ; i < tx - > wtx - > num_outputs ; i + + ) {
struct amount_asset asset ;
struct amount_asset asset ;
struct amount_sat outval ;
struct amount_sat outval ;
if ( elements_tx_output_is_fee ( tx , i ) )
if ( elements_tx_output_is_fee ( tx , i ) )
@ -709,18 +702,55 @@ static void record_tx_outs_and_fees(struct lightningd *ld, const struct bitcoin_
asset = bitcoin_tx_output_get_amount ( tx , i ) ;
asset = bitcoin_tx_output_get_amount ( tx , i ) ;
assert ( amount_asset_is_main ( & asset ) ) ;
assert ( amount_asset_is_main ( & asset ) ) ;
outval = amount_asset_to_sat ( & asset ) ;
outval = amount_asset_to_sat ( & asset ) ;
mvt = new_coin_withdrawal_sat ( ctx , " wallet " , txid , txid ,
mvt = new_coin_withdrawal_sat ( ctx , " wallet " , txid ,
i , blockheight , outval ) ;
txid , i , blockheight ,
outval ) ;
notify_chain_mvt ( ld , mvt ) ;
notify_chain_mvt ( ld , mvt ) ;
}
}
}
fee = bitcoin_tx_compute_fee_w_inputs ( tx , inputs_total ) ;
static void record_tx_outs_and_fees ( struct lightningd * ld ,
const struct bitcoin_tx * tx ,
struct bitcoin_txid * txid ,
u32 blockheight ,
struct amount_sat inputs_total ,
bool our_tx )
{
struct amount_sat fee , out_val ;
struct chain_coin_mvt * mvt ;
bool ok ;
struct wally_psbt * psbt = NULL ;
u8 * ctx = tal ( NULL , u8 ) ;
/* We own every input on this tx, so track withdrawals precisely */
if ( our_tx ) {
record_outputs_as_withdraws ( ctx , ld , tx , txid , blockheight ) ;
fee = bitcoin_tx_compute_fee_w_inputs ( tx , inputs_total ) ;
goto log_fee ;
}
/* FIXME: look up stashed psbt! */
if ( ! psbt ) {
fee = bitcoin_tx_compute_fee_w_inputs ( tx , inputs_total ) ;
ok = amount_sat_sub ( & out_val , inputs_total , fee ) ;
assert ( ok ) ;
/* We don't have detailed withdrawal info for this tx,
* so we log the wallet withdrawal as a single entry */
mvt = new_coin_withdrawal_sat ( ctx , " wallet " , txid , NULL ,
0 , blockheight , out_val ) ;
notify_chain_mvt ( ld , mvt ) ;
goto log_fee ;
}
fee = AMOUNT_SAT ( 0 ) ;
/* Note that to figure out the *total* 'onchain'
/* Note that to figure out the *total* 'onchain'
* cost of a channel , you ' ll want to also include
* cost of a channel , you ' ll want to also include
* fees logged here , to the ' wallet ' account ( for funding tx ) .
* fees logged here , to the ' wallet ' account ( for funding tx ) .
* You can do this in post by accounting for any ' chain_fees ' logged for
* You can do this in post by accounting for any ' chain_fees ' logged for
* the funding txid when looking at a channel . */
* the funding txid when looking at a channel . */
log_fee :
notify_chain_mvt ( ld ,
notify_chain_mvt ( ld ,
new_coin_chain_fees_sat ( ctx , " wallet " , txid ,
new_coin_chain_fees_sat ( ctx , " wallet " , txid ,
blockheight , fee ) ) ;
blockheight , fee ) ) ;
@ -736,7 +766,7 @@ static void topo_update_spends(struct chain_topology *topo, struct block *b)
const struct short_channel_id * scid ;
const struct short_channel_id * scid ;
for ( size_t i = 0 ; i < tal_count ( b - > full_txs ) ; i + + ) {
for ( size_t i = 0 ; i < tal_count ( b - > full_txs ) ; i + + ) {
const struct bitcoin_tx * tx = b - > full_txs [ i ] ;
const struct bitcoin_tx * tx = b - > full_txs [ i ] ;
bool our_tx = false ;
bool our_tx = true , includes_our_spend = false ;
struct bitcoin_txid txid ;
struct bitcoin_txid txid ;
struct amount_sat inputs_total = AMOUNT_SAT ( 0 ) ;
struct amount_sat inputs_total = AMOUNT_SAT ( 0 ) ;
@ -758,34 +788,22 @@ static void topo_update_spends(struct chain_topology *topo, struct block *b)
tal_free ( scid ) ;
tal_free ( scid ) ;
}
}
our_tx | = our_spend ;
our_tx & = our_spend ;
includes_our_spend | = our_spend ;
if ( our_spend ) {
if ( our_spend ) {
struct amount_sat input_amt ;
struct amount_sat input_amt ;
bool ok ;
bool ok ;
record_output_spend ( topo - > ld , & txid , & outpoint_txid ,
record_utxo_spent ( topo - > ld , & txid , & outpoint_txid ,
input - > index , b - > height , & input_amt ) ;
input - > index , b - > height , & input_amt ) ;
ok = amount_sat_add ( & inputs_total , inputs_total , input_amt ) ;
ok = amount_sat_add ( & inputs_total , inputs_total , input_amt ) ;
assert ( ok ) ;
assert ( ok ) ;
} else if ( our_tx )
}
log_broken ( topo - > ld - > log , " Recording fee spend for tx %s but "
" our wallet did not contribute input %s:%d " ,
type_to_string ( tmpctx , struct bitcoin_txid ,
& txid ) ,
type_to_string ( tmpctx , struct bitcoin_txid ,
& outpoint_txid ) ,
input - > index ) ;
}
}
/* For now we assume that if one of the spent utxos
if ( includes_our_spend )
* in this tx is ' ours ' , that we own all of the
* utxos and therefore paid all of the fees
* FIXME : update once interactive tx construction
* is a reality */
if ( our_tx )
record_tx_outs_and_fees ( topo - > ld , tx , & txid ,
record_tx_outs_and_fees ( topo - > ld , tx , & txid ,
b - > height , inputs_total ) ;
b - > height , inputs_total , our_tx ) ;
}
}
}
}