22#include <assert.h>
33#include <math.h>
44#include <common/amount.h>
5+ #include <common/overflows.h>
56#include <tests/fuzz/libfuzz.h>
67
78void init (int * argc , char * * * argv ) {}
@@ -109,9 +110,16 @@ void run(const uint8_t *data, size_t size) {
109110 {
110111 if (b .millisatoshis == 0 )
111112 break ;
113+
114+ // The assertion remains valid ONLY if there's no overflow
115+ if (a .millisatoshis > UINT64_MAX - b .millisatoshis + 1 ) {
116+ break ;
117+ }
118+
112119 u64 ceil = amount_msat_ratio_ceil (a , b );
113120 u64 quotient = a .millisatoshis / b .millisatoshis ;
114121 u64 remainder = a .millisatoshis % b .millisatoshis ;
122+
115123 assert (ceil == quotient + (remainder != 0 ));
116124 break ;
117125 }
@@ -195,13 +203,22 @@ void run(const uint8_t *data, size_t size) {
195203 {
196204 u32 fee_base = (u32 )(a .millisatoshis & UINT32_MAX );
197205 u32 fee_prop = (u32 )(b .millisatoshis & UINT32_MAX );
198- if (amount_msat_add_fee (& a , fee_base , fee_prop )) {
199- struct amount_msat fee ;
200- if (amount_msat_fee (& fee , a , fee_base , fee_prop )) {
201- assert (amount_msat_greater_eq (a , fee ));
206+
207+ struct amount_msat original = a ;
208+ struct amount_msat fee ;
209+
210+ if (amount_msat_fee (& fee , original , fee_base , fee_prop )) {
211+ struct amount_msat total ;
212+ if (amount_msat_add (& total , original , fee )) {
213+ assert (amount_msat_greater_eq (total , fee ));
214+
215+ struct amount_msat expected_total ;
216+ assert (amount_msat_add (& expected_total , original , fee ));
217+ assert (amount_msat_eq (total , expected_total ));
218+
219+ a = total ;
202220 }
203221 }
204- break ;
205222 }
206223
207224 case OP_SUB_FEE :
@@ -210,8 +227,9 @@ void run(const uint8_t *data, size_t size) {
210227 u32 fee_prop = (u32 )(b .millisatoshis & UINT32_MAX );
211228 struct amount_msat input = a ;
212229 struct amount_msat output = amount_msat_sub_fee (input , fee_base , fee_prop );
230+
213231 struct amount_msat fee ;
214- if (amount_msat_fee (& fee , input , fee_base , fee_prop )) {
232+ if (amount_msat_fee (& fee , output , fee_base , fee_prop )) {
215233 struct amount_msat sum ;
216234 if (amount_msat_add (& sum , output , fee )) {
217235 assert (amount_msat_less_eq (sum , input ));
@@ -226,6 +244,10 @@ void run(const uint8_t *data, size_t size) {
226244 break ;
227245 u32 fee_per_kw = (u32 )(a .millisatoshis & UINT32_MAX );
228246 size_t weight = (size_t )(b .millisatoshis );
247+
248+ /* weights > 2^32 are not real tx and hence, discarded */
249+ if (mul_overflows_u64 (fee_per_kw , weight ))
250+ break ;
229251 struct amount_sat fee = amount_tx_fee (fee_per_kw , weight );
230252 u64 expected = (fee_per_kw * weight ) / MSAT_PER_SAT ;
231253 assert (fee .satoshis == expected );
0 commit comments