11#include "config.h"
22#include <bitcoin/script.h>
33#include <ccan/array_size/array_size.h>
4+ #include <ccan/asort/asort.h>
45#include <ccan/cast/cast.h>
56#include <ccan/mem/mem.h>
67#include <ccan/tal/str/str.h>
78#include <channeld/channeld_wiregen.h>
89#include <common/clock_time.h>
910#include <common/memleak.h>
1011#include <common/onionreply.h>
12+ #include <common/randbytes.h>
1113#include <common/trace.h>
1214#include <db/bindings.h>
1315#include <db/common.h>
@@ -451,7 +453,23 @@ bool wallet_update_output_status(struct wallet *w,
451453 return changes > 0 ;
452454}
453455
454- static struct utxo * * gather_utxos (const tal_t * ctx , struct db_stmt * stmt STEALS )
456+ static int cmp_utxo (struct utxo * const * a ,
457+ struct utxo * const * b ,
458+ void * unused )
459+ {
460+ int ret = memcmp (& (* a )-> outpoint .txid , & (* b )-> outpoint .txid ,
461+ sizeof ((* a )-> outpoint .txid ));
462+ if (ret )
463+ return ret ;
464+ if ((* a )-> outpoint .n < (* b )-> outpoint .n )
465+ return -1 ;
466+ else if ((* a )-> outpoint .n > (* b )-> outpoint .n )
467+ return 1 ;
468+ return 0 ;
469+ }
470+
471+ static struct utxo * * gather_utxos (const tal_t * ctx ,
472+ struct db_stmt * stmt STEALS )
455473{
456474 struct utxo * * results ;
457475
@@ -463,6 +481,10 @@ static struct utxo **gather_utxos(const tal_t *ctx, struct db_stmt *stmt STEALS)
463481 }
464482 tal_free (stmt );
465483
484+ /* Make sure these are in order if we're trying to remove entropy */
485+ if (randbytes_overridden ())
486+ asort (results , tal_count (results ), cmp_utxo , NULL );
487+
466488 return results ;
467489}
468490
@@ -809,27 +831,53 @@ struct utxo *wallet_find_utxo(const tal_t *ctx, struct wallet *w,
809831 struct db_stmt * stmt ;
810832 struct utxo * utxo ;
811833
812- stmt = db_prepare_v2 (w -> db , SQL ("SELECT"
813- " prev_out_tx"
814- ", prev_out_index"
815- ", value"
816- ", type"
817- ", status"
818- ", keyindex"
819- ", channel_id"
820- ", peer_id"
821- ", commitment_point"
822- ", option_anchor_outputs"
823- ", confirmation_height"
824- ", spend_height"
825- ", scriptpubkey "
826- ", reserved_til"
827- ", csv_lock"
828- ", is_in_coinbase"
829- " FROM outputs"
830- " WHERE status = ?"
831- " OR (status = ? AND reserved_til <= ?)"
832- "ORDER BY RANDOM();" ));
834+ /* Make sure these are in order if we're trying to remove entropy! */
835+ if (w -> ld -> developer && getenv ("CLN_DEV_ENTROPY_SEED" )) {
836+ stmt = db_prepare_v2 (w -> db , SQL ("SELECT"
837+ " prev_out_tx"
838+ ", prev_out_index"
839+ ", value"
840+ ", type"
841+ ", status"
842+ ", keyindex"
843+ ", channel_id"
844+ ", peer_id"
845+ ", commitment_point"
846+ ", option_anchor_outputs"
847+ ", confirmation_height"
848+ ", spend_height"
849+ ", scriptpubkey "
850+ ", reserved_til"
851+ ", csv_lock"
852+ ", is_in_coinbase"
853+ " FROM outputs"
854+ " WHERE status = ?"
855+ " OR (status = ? AND reserved_til <= ?)"
856+ "ORDER BY prev_out_tx, prev_out_index;" ));
857+ } else {
858+ stmt = db_prepare_v2 (w -> db , SQL ("SELECT"
859+ " prev_out_tx"
860+ ", prev_out_index"
861+ ", value"
862+ ", type"
863+ ", status"
864+ ", keyindex"
865+ ", channel_id"
866+ ", peer_id"
867+ ", commitment_point"
868+ ", option_anchor_outputs"
869+ ", confirmation_height"
870+ ", spend_height"
871+ ", scriptpubkey "
872+ ", reserved_til"
873+ ", csv_lock"
874+ ", is_in_coinbase"
875+ " FROM outputs"
876+ " WHERE status = ?"
877+ " OR (status = ? AND reserved_til <= ?)"
878+ "ORDER BY RANDOM();" ));
879+ }
880+
833881 db_bind_int (stmt , output_status_in_db (OUTPUT_STATE_AVAILABLE ));
834882 db_bind_int (stmt , output_status_in_db (OUTPUT_STATE_RESERVED ));
835883 db_bind_u64 (stmt , current_blockheight );
0 commit comments