From a7dd8e3bc3a4f4e4fd3301cbc51e1b94782311b9 Mon Sep 17 00:00:00 2001 From: Chandra Pratap Date: Mon, 19 May 2025 04:09:09 +0000 Subject: [PATCH 1/3] fuzz-tests: add test for amount-{sat, msat} arithmetic Changelog-None: The `fuzz-amount` test doesn't fuzz the arithmetic operations for `struct amount_sat` and `struct amount_msat`. Add a test for them. --- tests/fuzz/fuzz-amount-arith.c | 237 +++++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 tests/fuzz/fuzz-amount-arith.c diff --git a/tests/fuzz/fuzz-amount-arith.c b/tests/fuzz/fuzz-amount-arith.c new file mode 100644 index 000000000000..667657ae5a9d --- /dev/null +++ b/tests/fuzz/fuzz-amount-arith.c @@ -0,0 +1,237 @@ +#include "config.h" +#include +#include +#include +#include +#include +#include + +void init(int *argc, char ***argv) {} + +#define MAX_SATS ((u64)WALLY_SATOSHI_PER_BTC * WALLY_BTC_MAX) +#define MAX_MSATS (MAX_SATS * 1000) +#define MAX_FEE_BASE 10000000 +#define MAX_FEE_PROP 1000000 + +static struct amount_msat fromwire_amount_msat_bounded(const u8 **cursor, size_t *max) +{ + u64 amt = fromwire_u64(cursor, max) % MAX_MSATS; + return amount_msat(amt); +} + +enum op { + OP_MSAT_ADD, + OP_MSAT_SUB, + OP_MSAT_MUL, + OP_MSAT_DIV, + OP_MSAT_RATIO, + OP_MSAT_RATIO_FLOOR, + OP_MSAT_RATIO_CEIL, + OP_MSAT_SCALE, + OP_MSAT_ADD_SAT, + OP_MSAT_SUB_SAT, + OP_SAT_ADD, + OP_SAT_SUB, + OP_SAT_MUL, + OP_SAT_DIV, + OP_SAT_SCALE, + OP_FEE, + OP_ADD_FEE, + OP_SUB_FEE, + OP_TX_FEE, + OP_FEERATE, + OP_COUNT +}; + +void run(const uint8_t *data, size_t size) { + u8 op; + u64 u64_param; + double f; + struct amount_msat a, b, out_ms; + struct amount_sat sa, sb, out_s; + + a = fromwire_amount_msat_bounded(&data, &size); + b = fromwire_amount_msat_bounded(&data, &size); + sa = amount_msat_to_sat_round_down(a); + sb = amount_msat_to_sat_round_down(b); + + u64_param = fromwire_u64(&data, &size); + op = fromwire_u8(&data, &size) % OP_COUNT; + + if (size < sizeof(f)) + return; + memcpy(&f, data, sizeof(f)); + data += sizeof(f); + + switch (op) { + case OP_MSAT_ADD: + { + if (amount_msat_add(&out_ms, a, b)) + assert(out_ms.millisatoshis == a.millisatoshis + b.millisatoshis); + break; + } + case OP_MSAT_SUB: + { + if (amount_msat_sub(&out_ms, a, b)) + assert(out_ms.millisatoshis + b.millisatoshis == a.millisatoshis); + break; + } + case OP_MSAT_MUL: + { + if (amount_msat_mul(&out_ms, a, u64_param)) + assert(out_ms.millisatoshis == a.millisatoshis * u64_param); + break; + } + case OP_MSAT_DIV: + { + if (u64_param == 0) + break; + out_ms = amount_msat_div(a, u64_param); + assert(out_ms.millisatoshis == a.millisatoshis / u64_param); + break; + } + case OP_MSAT_RATIO: + { + if (b.millisatoshis == 0) + break; + double ratio = amount_msat_ratio(a, b); + double expected = (double)a.millisatoshis / b.millisatoshis; + assert(ratio == expected); + break; + } + case OP_MSAT_RATIO_FLOOR: + { + if (b.millisatoshis == 0) + break; + u64 floor = amount_msat_ratio_floor(a, b); + assert(floor == a.millisatoshis / b.millisatoshis); + break; + } + case OP_MSAT_RATIO_CEIL: + { + if (b.millisatoshis == 0) + break; + u64 ceil = amount_msat_ratio_ceil(a, b); + u64 quotient = a.millisatoshis / b.millisatoshis; + u64 remainder = a.millisatoshis % b.millisatoshis; + + assert(ceil == quotient + (remainder != 0)); + break; + } + case OP_MSAT_SCALE: + { + if (amount_msat_scale(&out_ms, a, f)) { + double expect = (double)a.millisatoshis * f; + assert(fabs((double)out_ms.millisatoshis - expect) < 1.0); + } + break; + } + case OP_MSAT_ADD_SAT: + { + if (amount_msat_add_sat(&out_ms, a, sa)) + assert(out_ms.millisatoshis == sa.satoshis * MSAT_PER_SAT + a.millisatoshis); + break; + } + case OP_MSAT_SUB_SAT: + { + if (amount_msat_sub_sat(&out_ms, a, sa)) + assert(out_ms.millisatoshis + sa.satoshis * MSAT_PER_SAT == a.millisatoshis); + break; + } + case OP_SAT_ADD: + { + if (amount_sat_add(&out_s, sa, sb)) + assert(out_s.satoshis == sa.satoshis + sb.satoshis); + break; + } + case OP_SAT_SUB: + { + if (amount_sat_sub(&out_s, sa, sb)) + assert(out_s.satoshis + sb.satoshis == sa.satoshis); + break; + } + case OP_SAT_MUL: + { + if (amount_sat_mul(&out_s, sa, u64_param)) + assert(out_s.satoshis == sa.satoshis * u64_param); + break; + } + case OP_SAT_DIV: + { + if (u64_param == 0) + break; + out_s = amount_sat_div(sa, u64_param); + assert(out_s.satoshis == sa.satoshis / u64_param); + break; + } + case OP_SAT_SCALE: + { + if (amount_sat_scale(&out_s, sa, f)) { + double expect = sa.satoshis * f; + assert(fabs((double)out_s.satoshis - expect) < 1.0); + } + break; + } + case OP_FEE: + { + if (amount_msat_fee(&out_ms, a, (u32)a.millisatoshis, + (u32)b.millisatoshis)) + assert(out_ms.millisatoshis >= (u32)a.millisatoshis); + break; + } + case OP_ADD_FEE: + { + u32 fee_base = (u32)a.millisatoshis % MAX_FEE_BASE; + u32 fee_prop = (u32)b.millisatoshis % MAX_FEE_PROP; + struct amount_msat original = a; + struct amount_msat fee; + + if (amount_msat_fee(&fee, original, fee_base, fee_prop)) { + struct amount_msat total; + assert(amount_msat_add(&total, original, fee)); + assert(total.millisatoshis == original.millisatoshis + fee.millisatoshis); + } + break; + } + case OP_SUB_FEE: + { + u32 fee_base = (u32)a.millisatoshis % MAX_FEE_BASE; + u32 fee_prop = (u32)b.millisatoshis % MAX_FEE_PROP; + struct amount_msat input = a; + struct amount_msat output = amount_msat_sub_fee(input, fee_base, fee_prop); + struct amount_msat fee; + + if (amount_msat_fee(&fee, output, fee_base, fee_prop)) { + struct amount_msat sum; + if (amount_msat_add(&sum, output, fee)) + assert(amount_msat_less_eq(sum, input)); + } + break; + } + case OP_TX_FEE: + { + u32 fee_per_kw = (u32)a.millisatoshis; + /* weights > 2^32 are not real tx and hence, discarded */ + size_t weight = (size_t)(b.millisatoshis & UINT32_MAX); + + struct amount_sat fee = amount_tx_fee(fee_per_kw, weight); + u64 expected = (fee_per_kw * weight) / MSAT_PER_SAT; + assert(fee.satoshis == expected); + break; + } + case OP_FEERATE: + { + struct amount_sat fee = amount_msat_to_sat_round_down(a); + size_t weight = (size_t)b.millisatoshis; + u32 feerate; + + if (weight && amount_feerate(&feerate, fee, weight)) { + u64 expected = (fee.satoshis * MSAT_PER_SAT) / weight; + assert(feerate == expected); + } + break; + } + default: + assert(false && "Unknown operation!"); + } +} From 5fdb42cf16e46122e81244e948a79354e40ef7af Mon Sep 17 00:00:00 2001 From: Chandra Pratap Date: Wed, 23 Jul 2025 10:37:46 +0000 Subject: [PATCH 2/3] fuzz-tests: Add a seed corpus for the new test Add a minimal input set as a seed corpus for the newly introduced test. This leads to discovery of interesting code paths faster. --- .../070163bcc387dea560b6496367d64ef978649927 | 1 + .../071e35d8beea703a85e6c5aea81f8b52df79e603 | Bin 0 -> 28 bytes .../0d1573ab44083080ddc1fb47edf57fd87efed4d4 | Bin 0 -> 25 bytes .../121cb5e26a4d0ffbc06a858ce8039f3bb77fe6d7 | Bin 0 -> 33 bytes .../1aa01fefb209537bfc8094cf53c230b846c6b94e | Bin 0 -> 33 bytes .../1d3f4331f9ef89544eec49c3cc607fa7faacf692 | Bin 0 -> 16 bytes .../1f1f5f570c8b9f6e097783a7d6b0dec005bee000 | 1 + .../279153a7a17bb2dd8ee6675d55bf04eb2fd97d5a | Bin 0 -> 33 bytes .../2a3584e36a9f8faa6100bad14de4b3fe5ce58ccd | 1 + .../2b549cdda5ed270f30a85fbed9a14fb4c9349f9a | Bin 0 -> 33 bytes .../32805a5a53a50d7d2b892db7508f7618c55edef0 | Bin 0 -> 33 bytes .../343bf0c26e60b5e6b0643a9dba85b68eb254aaee | Bin 0 -> 25 bytes .../3983923e6d5398d14d0e974e0cc469ea027228a4 | Bin 0 -> 33 bytes .../3b70348b9001aa7bd04ee736e9b46770b41db874 | Bin 0 -> 25 bytes .../3daca0cd092f813b5c72186e6aa2632976da2d1c | Bin 0 -> 33 bytes .../410eac2c316f04e196cc6e1f58a11c23eacc9056 | Bin 0 -> 33 bytes .../41f530e7febc2463d7f21b3da51242edb22ee836 | Bin 0 -> 8 bytes .../4281f5de874e5a3980843ed8443af583a64b9a25 | Bin 0 -> 26 bytes .../43ed41e6f20e6bf57ca354467802a93a5dc14263 | Bin 0 -> 33 bytes .../4493b8c034724c49dda385077a24ca344c72829d | Bin 0 -> 33 bytes .../4b21550d021f106e09c0c4578b39d385b563b0c5 | Bin 0 -> 33 bytes .../5248c391b3d7f30e2e293e64a8ab098b6a6fdcbb | Bin 0 -> 33 bytes .../5802eb214798d86af503bbf79337692714445813 | Bin 0 -> 33 bytes .../58bab7586865aba85be5d7807eea2f91f748f815 | Bin 0 -> 33 bytes .../5cd4f8601fd3da4b04753779c633263455c3210a | Bin 0 -> 33 bytes .../5dc6ce7b2b2753f165f85cc072a7e5238e108620 | Bin 0 -> 33 bytes .../5ff65caf327b3e6cfc5639d658827357ca2d7358 | Bin 0 -> 33 bytes .../64c5f3a2c9b26751edb292809758df61c80963d9 | Bin 0 -> 25 bytes .../702363831cd9c11e0f8e9d0b551846d18e7d2f6b | Bin 0 -> 33 bytes .../73b74736664ad85828ce1be2e29fb4a68d24402b | 1 + .../7427fbf959a7b666f2fdc9f630024d676a01d6c5 | Bin 0 -> 25 bytes .../76dc44c1bccf95a199e3ec1546dd8faef7a3f915 | Bin 0 -> 33 bytes .../772c61baf9608a501698dac45ff5623bf15ff3cf | Bin 0 -> 33 bytes .../7c508a1f99fb75f2a4fce10d5f84898f10dbf005 | Bin 0 -> 33 bytes .../805e2a6e0fc41ac8765b09e49c4fe48d60d0ec12 | Bin 0 -> 40 bytes .../81ee6f1f96ae2bc172dcb8b9583e812c719bfcaa | Bin 0 -> 33 bytes .../87aa1028b4177cc7606b8371ce5b65fa7eb9f328 | Bin 0 -> 25 bytes .../8a0721e5fac291a8d21049a3e116867a45542b64 | Bin 0 -> 33 bytes .../908e0532176b37667891f1add45f80a074ae16c9 | Bin 0 -> 26 bytes .../94ec09b8d021f035a3f5ca810600371b35b82b7b | Bin 0 -> 25 bytes .../96e32e654758c806be66026fff1d0fc60ff130a5 | Bin 0 -> 33 bytes .../9855e6088543603fab6b8cc212dbf8672971289b | Bin 0 -> 25 bytes .../99689287a2fdd8e93baff831f59019361b5868d4 | Bin 0 -> 33 bytes .../99878f5e1a7aaa0e0207a3d368a34d91e9e81161 | Bin 0 -> 25 bytes .../a00c50db12c21ca80086141440d972c4d3935500 | Bin 0 -> 33 bytes .../a192ed4958390b832b0bfbdb48870cb8600fdbf0 | Bin 0 -> 33 bytes .../a461812b706f0e9a4d0e39c68ca7abf1c21598ae | Bin 0 -> 25 bytes .../b2f59bf837fcad2d5479a93309d8f5835bb9103c | Bin 0 -> 33 bytes .../bb83367c8017a3dd7ca9c377a7f6dda5e8338c06 | Bin 0 -> 33 bytes .../c175e69697791a4af976487248799bed6525eb79 | Bin 0 -> 25 bytes .../c4824be96b26b4fa996ee3d185ab08c9b93a9fcd | Bin 0 -> 25 bytes .../c6153815f2a4047ed5559555d3529f58d939a7a2 | Bin 0 -> 25 bytes .../d55bcdf6438055302a758a54daf7619066862a84 | Bin 0 -> 33 bytes .../d812f58b8a722377b1979349c08651e0b49d70c4 | 1 + .../d8249961012a613c46f35bcac01f9ff204cc57b5 | 1 + .../d9529625936de9119a00dd7e88800cf72e2ffb81 | Bin 0 -> 33 bytes .../d960e8c18211793e227129148d5df333ed4fb76b | Bin 0 -> 33 bytes .../da8676c0bdc58525a41ffc5be3810c9324aeaab3 | 1 + .../db0d24b7e2885d066a9c79c2ee5779ed6276a127 | Bin 0 -> 25 bytes .../dcf5bf6c63ba8e32483f75660b3a6a0f5d764483 | 1 + .../f6b20e8c301b07ef4bb6578b792bd1ebedd49ee2 | Bin 0 -> 33 bytes .../f869613a7b56fd27e3db5eed2b2a42eed6e779fa | Bin 0 -> 25 bytes .../f9e9468331be951b1d27605e52190e92930f85a8 | Bin 0 -> 33 bytes .../fa0e08141bfa60b272dfdfe41d8f071f5b00f1d1 | Bin 0 -> 33 bytes .../fa243d006173fc87ee3106a99ba80ffc21a9da48 | Bin 0 -> 33 bytes .../fa3978e005ac21f6c4bc6794bfbe21adf7906907 | Bin 0 -> 33 bytes .../fb516314ce68d9b1ee2abd29696eefa3e66fdc79 | Bin 0 -> 24 bytes 67 files changed, 8 insertions(+) create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/070163bcc387dea560b6496367d64ef978649927 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/071e35d8beea703a85e6c5aea81f8b52df79e603 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/0d1573ab44083080ddc1fb47edf57fd87efed4d4 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/121cb5e26a4d0ffbc06a858ce8039f3bb77fe6d7 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/1aa01fefb209537bfc8094cf53c230b846c6b94e create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/1d3f4331f9ef89544eec49c3cc607fa7faacf692 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/1f1f5f570c8b9f6e097783a7d6b0dec005bee000 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/279153a7a17bb2dd8ee6675d55bf04eb2fd97d5a create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/2a3584e36a9f8faa6100bad14de4b3fe5ce58ccd create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/2b549cdda5ed270f30a85fbed9a14fb4c9349f9a create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/32805a5a53a50d7d2b892db7508f7618c55edef0 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/343bf0c26e60b5e6b0643a9dba85b68eb254aaee create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/3983923e6d5398d14d0e974e0cc469ea027228a4 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/3b70348b9001aa7bd04ee736e9b46770b41db874 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/3daca0cd092f813b5c72186e6aa2632976da2d1c create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/410eac2c316f04e196cc6e1f58a11c23eacc9056 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/41f530e7febc2463d7f21b3da51242edb22ee836 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/4281f5de874e5a3980843ed8443af583a64b9a25 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/43ed41e6f20e6bf57ca354467802a93a5dc14263 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/4493b8c034724c49dda385077a24ca344c72829d create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/4b21550d021f106e09c0c4578b39d385b563b0c5 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/5248c391b3d7f30e2e293e64a8ab098b6a6fdcbb create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/5802eb214798d86af503bbf79337692714445813 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/58bab7586865aba85be5d7807eea2f91f748f815 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/5cd4f8601fd3da4b04753779c633263455c3210a create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/5dc6ce7b2b2753f165f85cc072a7e5238e108620 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/5ff65caf327b3e6cfc5639d658827357ca2d7358 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/64c5f3a2c9b26751edb292809758df61c80963d9 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/702363831cd9c11e0f8e9d0b551846d18e7d2f6b create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/73b74736664ad85828ce1be2e29fb4a68d24402b create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/7427fbf959a7b666f2fdc9f630024d676a01d6c5 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/76dc44c1bccf95a199e3ec1546dd8faef7a3f915 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/772c61baf9608a501698dac45ff5623bf15ff3cf create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/7c508a1f99fb75f2a4fce10d5f84898f10dbf005 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/805e2a6e0fc41ac8765b09e49c4fe48d60d0ec12 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/81ee6f1f96ae2bc172dcb8b9583e812c719bfcaa create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/87aa1028b4177cc7606b8371ce5b65fa7eb9f328 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/8a0721e5fac291a8d21049a3e116867a45542b64 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/908e0532176b37667891f1add45f80a074ae16c9 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/94ec09b8d021f035a3f5ca810600371b35b82b7b create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/96e32e654758c806be66026fff1d0fc60ff130a5 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/9855e6088543603fab6b8cc212dbf8672971289b create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/99689287a2fdd8e93baff831f59019361b5868d4 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/99878f5e1a7aaa0e0207a3d368a34d91e9e81161 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/a00c50db12c21ca80086141440d972c4d3935500 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/a192ed4958390b832b0bfbdb48870cb8600fdbf0 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/a461812b706f0e9a4d0e39c68ca7abf1c21598ae create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/b2f59bf837fcad2d5479a93309d8f5835bb9103c create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/bb83367c8017a3dd7ca9c377a7f6dda5e8338c06 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/c175e69697791a4af976487248799bed6525eb79 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/c4824be96b26b4fa996ee3d185ab08c9b93a9fcd create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/c6153815f2a4047ed5559555d3529f58d939a7a2 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/d55bcdf6438055302a758a54daf7619066862a84 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/d812f58b8a722377b1979349c08651e0b49d70c4 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/d8249961012a613c46f35bcac01f9ff204cc57b5 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/d9529625936de9119a00dd7e88800cf72e2ffb81 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/d960e8c18211793e227129148d5df333ed4fb76b create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/da8676c0bdc58525a41ffc5be3810c9324aeaab3 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/db0d24b7e2885d066a9c79c2ee5779ed6276a127 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/dcf5bf6c63ba8e32483f75660b3a6a0f5d764483 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/f6b20e8c301b07ef4bb6578b792bd1ebedd49ee2 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/f869613a7b56fd27e3db5eed2b2a42eed6e779fa create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/f9e9468331be951b1d27605e52190e92930f85a8 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/fa0e08141bfa60b272dfdfe41d8f071f5b00f1d1 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/fa243d006173fc87ee3106a99ba80ffc21a9da48 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/fa3978e005ac21f6c4bc6794bfbe21adf7906907 create mode 100644 tests/fuzz/corpora/fuzz-amount-arith/fb516314ce68d9b1ee2abd29696eefa3e66fdc79 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/070163bcc387dea560b6496367d64ef978649927 b/tests/fuzz/corpora/fuzz-amount-arith/070163bcc387dea560b6496367d64ef978649927 new file mode 100644 index 000000000000..3323125389d2 --- /dev/null +++ b/tests/fuzz/corpora/fuzz-amount-arith/070163bcc387dea560b6496367d64ef978649927 @@ -0,0 +1 @@ +åååååååååZÀqÀ å§= \ No newline at end of file diff --git a/tests/fuzz/corpora/fuzz-amount-arith/071e35d8beea703a85e6c5aea81f8b52df79e603 b/tests/fuzz/corpora/fuzz-amount-arith/071e35d8beea703a85e6c5aea81f8b52df79e603 new file mode 100644 index 0000000000000000000000000000000000000000..f925f2eaeb61b65b020481f0e4f2b09f06977d49 GIT binary patch literal 28 dcmd;MU_A;13=IGOb29wpVE_Xl^`C)>0RV%)2Soq? literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/0d1573ab44083080ddc1fb47edf57fd87efed4d4 b/tests/fuzz/corpora/fuzz-amount-arith/0d1573ab44083080ddc1fb47edf57fd87efed4d4 new file mode 100644 index 0000000000000000000000000000000000000000..3a694cf6be7ba8dfc9d63f1498a0d93934381a99 GIT binary patch literal 25 bcmZo<5Ln82g~D%0?E_ literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/1aa01fefb209537bfc8094cf53c230b846c6b94e b/tests/fuzz/corpora/fuzz-amount-arith/1aa01fefb209537bfc8094cf53c230b846c6b94e new file mode 100644 index 0000000000000000000000000000000000000000..480fadeef104e4848800adeefd6c850c1c21aef0 GIT binary patch literal 33 bcmaF*6bhuJVBkQZnB1Rw1|U#)y4)53BPR{q literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/1d3f4331f9ef89544eec49c3cc607fa7faacf692 b/tests/fuzz/corpora/fuzz-amount-arith/1d3f4331f9ef89544eec49c3cc607fa7faacf692 new file mode 100644 index 0000000000000000000000000000000000000000..2061afad39daa87164de6ab87d02a00473e771d2 GIT binary patch literal 16 ScmaFR#lm0^V88$Y91H**{sJce literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/1f1f5f570c8b9f6e097783a7d6b0dec005bee000 b/tests/fuzz/corpora/fuzz-amount-arith/1f1f5f570c8b9f6e097783a7d6b0dec005bee000 new file mode 100644 index 000000000000..2c0d7b0af4ca --- /dev/null +++ b/tests/fuzz/corpora/fuzz-amount-arith/1f1f5f570c8b9f6e097783a7d6b0dec005bee000 @@ -0,0 +1 @@ +ååååååååååååååååååååååååååååååå§= \ No newline at end of file diff --git a/tests/fuzz/corpora/fuzz-amount-arith/279153a7a17bb2dd8ee6675d55bf04eb2fd97d5a b/tests/fuzz/corpora/fuzz-amount-arith/279153a7a17bb2dd8ee6675d55bf04eb2fd97d5a new file mode 100644 index 0000000000000000000000000000000000000000..9679aef6d0d385cb6e0eff231fd358fa7993ddb1 GIT binary patch literal 33 acmaFR6~JJ?fC>)$|Ecqyfk8C@Bn$v*RR%Kv literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/2a3584e36a9f8faa6100bad14de4b3fe5ce58ccd b/tests/fuzz/corpora/fuzz-amount-arith/2a3584e36a9f8faa6100bad14de4b3fe5ce58ccd new file mode 100644 index 000000000000..bb7b77109fed --- /dev/null +++ b/tests/fuzz/corpora/fuzz-amount-arith/2a3584e36a9f8faa6100bad14de4b3fe5ce58ccd @@ -0,0 +1 @@ +åååååååååÀÀq å§= \ No newline at end of file diff --git a/tests/fuzz/corpora/fuzz-amount-arith/2b549cdda5ed270f30a85fbed9a14fb4c9349f9a b/tests/fuzz/corpora/fuzz-amount-arith/2b549cdda5ed270f30a85fbed9a14fb4c9349f9a new file mode 100644 index 0000000000000000000000000000000000000000..f4b88b130781e5f031868b37ead876edf146e786 GIT binary patch literal 33 fcmZ>K&~>0tOzuxT0|-a}F-QO?1mbovFc<&;xn2oC literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/32805a5a53a50d7d2b892db7508f7618c55edef0 b/tests/fuzz/corpora/fuzz-amount-arith/32805a5a53a50d7d2b892db7508f7618c55edef0 new file mode 100644 index 0000000000000000000000000000000000000000..215d7f484705681e6f2bb86dd0e9e481c57277c7 GIT binary patch literal 33 dcmaFR#lT=w^0SN#A literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/3983923e6d5398d14d0e974e0cc469ea027228a4 b/tests/fuzz/corpora/fuzz-amount-arith/3983923e6d5398d14d0e974e0cc469ea027228a4 new file mode 100644 index 0000000000000000000000000000000000000000..3bc947d73bdda77d801da6f1cce6468f66a581b9 GIT binary patch literal 33 ncmZ>K@Sy8Jp_rUQJp&LN*vY`)Ai%&-_`vr-Ap=8K7Xt$T#(xT2 literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/3b70348b9001aa7bd04ee736e9b46770b41db874 b/tests/fuzz/corpora/fuzz-amount-arith/3b70348b9001aa7bd04ee736e9b46770b41db874 new file mode 100644 index 0000000000000000000000000000000000000000..d7a3392b61cd1e18f5dd9f292ad137af0585a361 GIT binary patch literal 25 UcmaFS#efW=SvW!5|Ns9304=2i*Z=?k literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/3daca0cd092f813b5c72186e6aa2632976da2d1c b/tests/fuzz/corpora/fuzz-amount-arith/3daca0cd092f813b5c72186e6aa2632976da2d1c new file mode 100644 index 0000000000000000000000000000000000000000..3c563a1eab31430b2f0b7682af07ddce74d50091 GIT binary patch literal 33 mcmZ>K&~>0tOzuxT0|SFCnELzw|MUO<&&zimV0h5QFdF~{)ewIG literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/410eac2c316f04e196cc6e1f58a11c23eacc9056 b/tests/fuzz/corpora/fuzz-amount-arith/410eac2c316f04e196cc6e1f58a11c23eacc9056 new file mode 100644 index 0000000000000000000000000000000000000000..c74f94e254f696aeb61f68ee1700d80d2d6113c1 GIT binary patch literal 33 acmaFR#lTY;{{J-G$-v+M69WKr=>{DD literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/41f530e7febc2463d7f21b3da51242edb22ee836 b/tests/fuzz/corpora/fuzz-amount-arith/41f530e7febc2463d7f21b3da51242edb22ee836 new file mode 100644 index 0000000000000000000000000000000000000000..0a7f25337aa86bef69b6622c00dd4633685ec7c8 GIT binary patch literal 8 PcmaFR#W0&;dDn6P5rqTZ literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/4281f5de874e5a3980843ed8443af583a64b9a25 b/tests/fuzz/corpora/fuzz-amount-arith/4281f5de874e5a3980843ed8443af583a64b9a25 new file mode 100644 index 0000000000000000000000000000000000000000..6ccca602f2d32c8196fa26fa502de597bed4dcf6 GIT binary patch literal 26 VcmeBY-^~C7`}adgSr7#VIsj0F1eX8+ literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/43ed41e6f20e6bf57ca354467802a93a5dc14263 b/tests/fuzz/corpora/fuzz-amount-arith/43ed41e6f20e6bf57ca354467802a93a5dc14263 new file mode 100644 index 0000000000000000000000000000000000000000..f9aa746cc18a127c110662674272f5d7286707e9 GIT binary patch literal 33 fcmZ>i`%}*V1Rx5`V31&7Fnqx9po`%z2+Rfmm+cG^ literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/4493b8c034724c49dda385077a24ca344c72829d b/tests/fuzz/corpora/fuzz-amount-arith/4493b8c034724c49dda385077a24ca344c72829d new file mode 100644 index 0000000000000000000000000000000000000000..bdeb0c0d4517c5b53a21a9433131cfebcda1b7ab GIT binary patch literal 33 icmZ>i`%}*V2Z{_27#?&n{Qax^@9*rtRe%5fsRsa_g$?BZ literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/4b21550d021f106e09c0c4578b39d385b563b0c5 b/tests/fuzz/corpora/fuzz-amount-arith/4b21550d021f106e09c0c4578b39d385b563b0c5 new file mode 100644 index 0000000000000000000000000000000000000000..f111283fed3aa3c10012334fb378e6e81e5c81f8 GIT binary patch literal 33 pcmZ>K&~>0tOzuxT1H&tZ1BN>p7#su`7z!Ww9w=mB=;~r%007yf3sV39 literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/5248c391b3d7f30e2e293e64a8ab098b6a6fdcbb b/tests/fuzz/corpora/fuzz-amount-arith/5248c391b3d7f30e2e293e64a8ab098b6a6fdcbb new file mode 100644 index 0000000000000000000000000000000000000000..c868bb77dc56a37f83a0f7f6bef039548cadd7f9 GIT binary patch literal 33 ccmZ>K&~>0tOzuxT0|-cfNf_~K&~>0tOzuxT0}vcA+{wV;5Wv7t$Z$Xm$nOGT0J=^HmjD0& literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/58bab7586865aba85be5d7807eea2f91f748f815 b/tests/fuzz/corpora/fuzz-amount-arith/58bab7586865aba85be5d7807eea2f91f748f815 new file mode 100644 index 0000000000000000000000000000000000000000..5d67074105f9a1666735ca8190962b5c22fddaf9 GIT binary patch literal 33 fcmZ>i`%}*V2Z{_27#?&n{Qb-J@9*rtATS#Mpb!pd literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/5cd4f8601fd3da4b04753779c633263455c3210a b/tests/fuzz/corpora/fuzz-amount-arith/5cd4f8601fd3da4b04753779c633263455c3210a new file mode 100644 index 0000000000000000000000000000000000000000..2c70f46050ada7b3225328c0692bb670c78352ce GIT binary patch literal 33 ecmdOOeERgMwt6Q65Y&SRC}0B854srG)&Ky92nLn_ literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/5dc6ce7b2b2753f165f85cc072a7e5238e108620 b/tests/fuzz/corpora/fuzz-amount-arith/5dc6ce7b2b2753f165f85cc072a7e5238e108620 new file mode 100644 index 0000000000000000000000000000000000000000..1e483db4ff96a79b52e3edff837febefbdd8deb4 GIT binary patch literal 33 jcmZ>K&~>0tOb$%^sb>I!1BN>p7#su`7z%@1yBHV%&hrXL literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/5ff65caf327b3e6cfc5639d658827357ca2d7358 b/tests/fuzz/corpora/fuzz-amount-arith/5ff65caf327b3e6cfc5639d658827357ca2d7358 new file mode 100644 index 0000000000000000000000000000000000000000..a0b55312b0c4beeb0d8b018a7eabf1c00324d53f GIT binary patch literal 33 ecmZ>i`%}*V2Z{_27#Y;{{NJg0s@#A0Bs`$b^rhX literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/73b74736664ad85828ce1be2e29fb4a68d24402b b/tests/fuzz/corpora/fuzz-amount-arith/73b74736664ad85828ce1be2e29fb4a68d24402b new file mode 100644 index 000000000000..009080e8e0bf --- /dev/null +++ b/tests/fuzz/corpora/fuzz-amount-arith/73b74736664ad85828ce1be2e29fb4a68d24402b @@ -0,0 +1 @@ +÷ \ No newline at end of file diff --git a/tests/fuzz/corpora/fuzz-amount-arith/7427fbf959a7b666f2fdc9f630024d676a01d6c5 b/tests/fuzz/corpora/fuzz-amount-arith/7427fbf959a7b666f2fdc9f630024d676a01d6c5 new file mode 100644 index 0000000000000000000000000000000000000000..b4126690e4f4bbed509cf49bbc8024d5665a5459 GIT binary patch literal 25 ccmeC;;$i@T|NsB}2hj|6oY8i6c8qom09q>sH2?qr literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/76dc44c1bccf95a199e3ec1546dd8faef7a3f915 b/tests/fuzz/corpora/fuzz-amount-arith/76dc44c1bccf95a199e3ec1546dd8faef7a3f915 new file mode 100644 index 0000000000000000000000000000000000000000..b003a1784c1d77a494eed5614f10913d0d64381b GIT binary patch literal 33 mcmZ>K`u^!tDJiL+51#^o%sDq*h5!ZzhNsJI{{z9_|Nj9(cN7T# literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/772c61baf9608a501698dac45ff5623bf15ff3cf b/tests/fuzz/corpora/fuzz-amount-arith/772c61baf9608a501698dac45ff5623bf15ff3cf new file mode 100644 index 0000000000000000000000000000000000000000..666411c417d9167d3ba016df5ecd9342c4951812 GIT binary patch literal 33 gcmZ>K&~>0tOzuxT0}wzd1_=fR1E4s=gD!^I0J+}^oB#j- literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/7c508a1f99fb75f2a4fce10d5f84898f10dbf005 b/tests/fuzz/corpora/fuzz-amount-arith/7c508a1f99fb75f2a4fce10d5f84898f10dbf005 new file mode 100644 index 0000000000000000000000000000000000000000..fe942efcc9f13d7b2164f257800075e660953e28 GIT binary patch literal 33 bcmZ>K`t+%`Is*jMLunwz1Y)ZFWm^LPa~lPj literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/805e2a6e0fc41ac8765b09e49c4fe48d60d0ec12 b/tests/fuzz/corpora/fuzz-amount-arith/805e2a6e0fc41ac8765b09e49c4fe48d60d0ec12 new file mode 100644 index 0000000000000000000000000000000000000000..9e49d303f1014305486c84a0e3d8b499aedaf8f7 GIT binary patch literal 40 jcmaFR#lTK3I}q3>KWibk>LTugD!@@vjH$74$uGq literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/87aa1028b4177cc7606b8371ce5b65fa7eb9f328 b/tests/fuzz/corpora/fuzz-amount-arith/87aa1028b4177cc7606b8371ce5b65fa7eb9f328 new file mode 100644 index 0000000000000000000000000000000000000000..ddcd690ad7faa32b0f3ed9fd22a6888bfefb25c5 GIT binary patch literal 25 YcmZ4f|NsBrKpYFi3=CWh3_uzT0Qt)j`2YX_ literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/8a0721e5fac291a8d21049a3e116867a45542b64 b/tests/fuzz/corpora/fuzz-amount-arith/8a0721e5fac291a8d21049a3e116867a45542b64 new file mode 100644 index 0000000000000000000000000000000000000000..58100a33379a5575e8a4bd1bdf8e248ee91afb9c GIT binary patch literal 33 lcmZ>K&~>0tOzuxT0}vcA+{wV;Ai%&-2ohyr=;~r%0076W3Z?)6 literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/908e0532176b37667891f1add45f80a074ae16c9 b/tests/fuzz/corpora/fuzz-amount-arith/908e0532176b37667891f1add45f80a074ae16c9 new file mode 100644 index 0000000000000000000000000000000000000000..be7471328d417dfa334aaae1a36c020f0322ce47 GIT binary patch literal 26 XcmcETV&q}~g8x8Z5D*DsLVzRyVXFnh literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/94ec09b8d021f035a3f5ca810600371b35b82b7b b/tests/fuzz/corpora/fuzz-amount-arith/94ec09b8d021f035a3f5ca810600371b35b82b7b new file mode 100644 index 0000000000000000000000000000000000000000..c6bdfe61c360162e10fd52e424fcff7449644545 GIT binary patch literal 25 YcmdnZz@RJ1z`!8M#jqR31acW90VrYuSO5S3 literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/96e32e654758c806be66026fff1d0fc60ff130a5 b/tests/fuzz/corpora/fuzz-amount-arith/96e32e654758c806be66026fff1d0fc60ff130a5 new file mode 100644 index 0000000000000000000000000000000000000000..4170c023bb5a1cf8643fab4e85ba8ba171f05061 GIT binary patch literal 33 dcmaF*6au8Bz(5SllR4+6%Mif8!0>drEdV@`59I&= literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/9855e6088543603fab6b8cc212dbf8672971289b b/tests/fuzz/corpora/fuzz-amount-arith/9855e6088543603fab6b8cc212dbf8672971289b new file mode 100644 index 0000000000000000000000000000000000000000..0f98c5fe1002762e72d73baf46ac50eed0e62711 GIT binary patch literal 25 UcmZQ%U|`??VkqDQ(kx&$00B$@7XSbN literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/99689287a2fdd8e93baff831f59019361b5868d4 b/tests/fuzz/corpora/fuzz-amount-arith/99689287a2fdd8e93baff831f59019361b5868d4 new file mode 100644 index 0000000000000000000000000000000000000000..8cb92b90eb1877e139b2baa6144f13dbcc28d0ca GIT binary patch literal 33 ccmaFR#lT(=|NZay;Q#;s3=9nn0C{lb`{AUPY1c?FwO%4P5 literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/a192ed4958390b832b0bfbdb48870cb8600fdbf0 b/tests/fuzz/corpora/fuzz-amount-arith/a192ed4958390b832b0bfbdb48870cb8600fdbf0 new file mode 100644 index 0000000000000000000000000000000000000000..039c85cf60229163d51d360d94179136f30b4db3 GIT binary patch literal 33 gcmZ>i`%}*V2Z{_27#?&n{Qb-J@9*rtfBypI0G@UYP5=M^ literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/a461812b706f0e9a4d0e39c68ca7abf1c21598ae b/tests/fuzz/corpora/fuzz-amount-arith/a461812b706f0e9a4d0e39c68ca7abf1c21598ae new file mode 100644 index 0000000000000000000000000000000000000000..877b0b2e16479f8bec63dc54998c6348f11285b4 GIT binary patch literal 25 ccmd;MU|`^2U}R7L(m=q;@RtQhaWG^701Yw$v;Y7A literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/b2f59bf837fcad2d5479a93309d8f5835bb9103c b/tests/fuzz/corpora/fuzz-amount-arith/b2f59bf837fcad2d5479a93309d8f5835bb9103c new file mode 100644 index 0000000000000000000000000000000000000000..e62647dcc9f4fb122beecb489a26c7d4db4d5a4a GIT binary patch literal 33 gcmaFR#lT(=Ljgz>0DvtC;{X5v literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/c175e69697791a4af976487248799bed6525eb79 b/tests/fuzz/corpora/fuzz-amount-arith/c175e69697791a4af976487248799bed6525eb79 new file mode 100644 index 0000000000000000000000000000000000000000..57fc6a46f6ad5b9f1be623742295f1672b91c130 GIT binary patch literal 25 ZcmcC!WMDXV?wke#3j-WzFfd5|2LL-o1QP%N literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/c4824be96b26b4fa996ee3d185ab08c9b93a9fcd b/tests/fuzz/corpora/fuzz-amount-arith/c4824be96b26b4fa996ee3d185ab08c9b93a9fcd new file mode 100644 index 0000000000000000000000000000000000000000..64897c48f615379073954c8cf1df4c7b201c75f6 GIT binary patch literal 25 UcmX?h?AS2|Bp?W8|Ns9V08d~BCjbBd literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/c6153815f2a4047ed5559555d3529f58d939a7a2 b/tests/fuzz/corpora/fuzz-amount-arith/c6153815f2a4047ed5559555d3529f58d939a7a2 new file mode 100644 index 0000000000000000000000000000000000000000..e41e1425172f51ce2af368ae6d2ef53148e85c71 GIT binary patch literal 25 ecmX?h?AS2|1_mojOUoTV@c;k+-#{*dEdv0Zy$cfn literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/d55bcdf6438055302a758a54daf7619066862a84 b/tests/fuzz/corpora/fuzz-amount-arith/d55bcdf6438055302a758a54daf7619066862a84 new file mode 100644 index 0000000000000000000000000000000000000000..fc5c41d025a663c7887e7ce18dcec36d820f693c GIT binary patch literal 33 icmZ>i`%}*V2Z{_27#?&n{Qb-J@9*rtfB*ie4+a39$qk_Z literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/d812f58b8a722377b1979349c08651e0b49d70c4 b/tests/fuzz/corpora/fuzz-amount-arith/d812f58b8a722377b1979349c08651e0b49d70c4 new file mode 100644 index 000000000000..eaa1606654cf --- /dev/null +++ b/tests/fuzz/corpora/fuzz-amount-arith/d812f58b8a722377b1979349c08651e0b49d70c4 @@ -0,0 +1 @@ +ËËËËËËËËËËËËËËËËË:ËËËËËËËËËËËËË.Ë \ No newline at end of file diff --git a/tests/fuzz/corpora/fuzz-amount-arith/d8249961012a613c46f35bcac01f9ff204cc57b5 b/tests/fuzz/corpora/fuzz-amount-arith/d8249961012a613c46f35bcac01f9ff204cc57b5 new file mode 100644 index 000000000000..e5959301ad57 --- /dev/null +++ b/tests/fuzz/corpora/fuzz-amount-arith/d8249961012a613c46f35bcac01f9ff204cc57b5 @@ -0,0 +1 @@ +åååäåååååååååååååååååååå'åååååå§= \ No newline at end of file diff --git a/tests/fuzz/corpora/fuzz-amount-arith/d9529625936de9119a00dd7e88800cf72e2ffb81 b/tests/fuzz/corpora/fuzz-amount-arith/d9529625936de9119a00dd7e88800cf72e2ffb81 new file mode 100644 index 0000000000000000000000000000000000000000..00d8fbfc33e505edb3e0e8c3cf3332a934c3c690 GIT binary patch literal 33 gcmaFR#lT=1zyJX(5bD7HpN8)hR1Xx2$^Bsf0CQ{zasU7T literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/d960e8c18211793e227129148d5df333ed4fb76b b/tests/fuzz/corpora/fuzz-amount-arith/d960e8c18211793e227129148d5df333ed4fb76b new file mode 100644 index 0000000000000000000000000000000000000000..4bd48ffac68bc6496d6b4b8725ca82ec0ae87d82 GIT binary patch literal 33 bcmaF*6a?;qNjM>M&TT(K00RTV)8)1R$!-?P literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/da8676c0bdc58525a41ffc5be3810c9324aeaab3 b/tests/fuzz/corpora/fuzz-amount-arith/da8676c0bdc58525a41ffc5be3810c9324aeaab3 new file mode 100644 index 000000000000..ddbb682ec886 --- /dev/null +++ b/tests/fuzz/corpora/fuzz-amount-arith/da8676c0bdc58525a41ffc5be3810c9324aeaab3 @@ -0,0 +1 @@ +eåååååÀÀq å§=Àq å§= \ No newline at end of file diff --git a/tests/fuzz/corpora/fuzz-amount-arith/db0d24b7e2885d066a9c79c2ee5779ed6276a127 b/tests/fuzz/corpora/fuzz-amount-arith/db0d24b7e2885d066a9c79c2ee5779ed6276a127 new file mode 100644 index 0000000000000000000000000000000000000000..27d0de3f671c16d89ff2f8b17c0787fb720b2e5d GIT binary patch literal 25 UcmdO8U|`??VkqDQ(kx&$00o!;LjV8( literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/dcf5bf6c63ba8e32483f75660b3a6a0f5d764483 b/tests/fuzz/corpora/fuzz-amount-arith/dcf5bf6c63ba8e32483f75660b3a6a0f5d764483 new file mode 100644 index 000000000000..59cd9bddc043 --- /dev/null +++ b/tests/fuzz/corpora/fuzz-amount-arith/dcf5bf6c63ba8e32483f75660b3a6a0f5d764483 @@ -0,0 +1 @@ +§ \ No newline at end of file diff --git a/tests/fuzz/corpora/fuzz-amount-arith/f6b20e8c301b07ef4bb6578b792bd1ebedd49ee2 b/tests/fuzz/corpora/fuzz-amount-arith/f6b20e8c301b07ef4bb6578b792bd1ebedd49ee2 new file mode 100644 index 0000000000000000000000000000000000000000..d5749ef8218467d30ff14f1eb818a8cc7b45efff GIT binary patch literal 33 ccmcD0(8a)D5Ws){2N)Ps0~n4n?1Tsb0A9=l+W-In literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/f869613a7b56fd27e3db5eed2b2a42eed6e779fa b/tests/fuzz/corpora/fuzz-amount-arith/f869613a7b56fd27e3db5eed2b2a42eed6e779fa new file mode 100644 index 0000000000000000000000000000000000000000..a166456070e79c2e027f38d83745019c2e3e42e8 GIT binary patch literal 25 acmd<{U|?W4ckbvpAh0?IWP`XsEC~R35C`7? literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/f9e9468331be951b1d27605e52190e92930f85a8 b/tests/fuzz/corpora/fuzz-amount-arith/f9e9468331be951b1d27605e52190e92930f85a8 new file mode 100644 index 0000000000000000000000000000000000000000..527bf929357a1cd0b35cb4b0f7da36315a554b2f GIT binary patch literal 33 fcmaFR#lTY;{{J+5&%mG>z+ki!DB1u3d&dW( literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/fa0e08141bfa60b272dfdfe41d8f071f5b00f1d1 b/tests/fuzz/corpora/fuzz-amount-arith/fa0e08141bfa60b272dfdfe41d8f071f5b00f1d1 new file mode 100644 index 0000000000000000000000000000000000000000..603e8c539c8ebbf39c57373b8c19488720dafa2f GIT binary patch literal 33 WcmaFR#lTK&~>0tOzuxT0}vcA+{wV;Ai%&-_@MPbAp=8K7Xt$T$AAi< literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/fa3978e005ac21f6c4bc6794bfbe21adf7906907 b/tests/fuzz/corpora/fuzz-amount-arith/fa3978e005ac21f6c4bc6794bfbe21adf7906907 new file mode 100644 index 0000000000000000000000000000000000000000..bd3306ec29b94c789c6c836ce16752fdd1b16d1f GIT binary patch literal 33 ecmYd&3IYchfS{g%K}t&MK%tnN!qerpFd6{xKn(~0 literal 0 HcmV?d00001 diff --git a/tests/fuzz/corpora/fuzz-amount-arith/fb516314ce68d9b1ee2abd29696eefa3e66fdc79 b/tests/fuzz/corpora/fuzz-amount-arith/fb516314ce68d9b1ee2abd29696eefa3e66fdc79 new file mode 100644 index 0000000000000000000000000000000000000000..d7e2bb6b4047a2f0202113e31b18104fd5717d95 GIT binary patch literal 24 ScmaFR#lT Date: Mon, 16 Mar 2026 12:54:37 +0100 Subject: [PATCH 3/3] plugin: Added test cases for fuzz OPs introduced in fuzz-amount-arith.c --- tests/test_plugin.py | 274 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 5d9e58673f1c..eaf6f21c410f 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -15,6 +15,7 @@ import ast import base64 +import math import json import os import pytest @@ -4652,3 +4653,276 @@ def test_peer_storage(node_factory, bitcoind): # This should never happen assert not l1.daemon.is_in_log(r'PeerStorageFailed') assert not l2.daemon.is_in_log(r'PeerStorageFailed') + + +# --------------------------------------------------------------------------- +# Tests for amount_msat / amount_sat arithmetic invariants +# +# These mirror the invariants verified by the fuzz harness introduced in +# tests/fuzz/fuzz-amount-arith.c. They are pure Python / Millisatoshi-class +# tests and do not require a running node. +# --------------------------------------------------------------------------- + +# BOLT-7 routing-fee helpers (mirrors common/amount.c) +_MSAT_PER_SAT = 1000 + + +def _fee(amt_msat, fee_base_msat, fee_prop_millionths): + """fee_base + floor(amount * prop / 1_000_000) (BOLT-7 formula).""" + return fee_base_msat + amt_msat * fee_prop_millionths // 1_000_000 + + +def _sub_fee(input_msat, fee_base_msat, fee_prop_millionths): + """Largest output o such that _fee(o) + o <= input (mirrors amount_msat_sub_fee).""" + if input_msat < fee_base_msat: + return 0 + out = 1_000_000 * (input_msat - fee_base_msat) // (1_000_000 + fee_prop_millionths) + # off-by-one correction: bump by one if it still fits + if out + 1 + _fee(out + 1, fee_base_msat, fee_prop_millionths) <= input_msat: + out += 1 + return out + + +# --- OP_MSAT_ADD ----------------------------------------------------------- + +def test_amount_msat_add(): + """add invariant: out.msat == a.msat + b.msat""" + a, b = Millisatoshi(7_000), Millisatoshi(3_000) + out = a + b + assert int(out) == int(a) + int(b) + + +def test_amount_msat_add_underflow_raises(): + """Millisatoshi constructor rejects negative values (sub underflow guard).""" + with pytest.raises(ValueError): + Millisatoshi(-1) + + +# --- OP_MSAT_SUB ----------------------------------------------------------- + +def test_amount_msat_sub(): + """sub invariant: out.msat + b.msat == a.msat""" + a, b = Millisatoshi(7_000), Millisatoshi(3_000) + out = a - b + assert int(out) + int(b) == int(a) + + +def test_amount_msat_sub_underflow_raises(): + """Subtracting a larger msat from a smaller one raises ValueError.""" + with pytest.raises(ValueError): + _ = Millisatoshi(1_000) - Millisatoshi(3_000) + + +# --- OP_MSAT_MUL ----------------------------------------------------------- + +def test_amount_msat_mul(): + """mul invariant: out.msat == a.msat * n""" + a = Millisatoshi(1_500) + n = 4 + out = a * n + assert int(out) == int(a) * n + + +def test_amount_msat_mul_zero(): + """Multiplying by zero gives 0 msat.""" + assert int(Millisatoshi(9_999) * 0) == 0 + + +# --- OP_MSAT_DIV ----------------------------------------------------------- + +def test_amount_msat_div(): + """div invariant: out.msat == floor(a.msat / n)""" + a = Millisatoshi(1_001) + n = 3 + out = a / n # __truediv__ with int returns floored Millisatoshi + assert int(out) == int(a) // n + + +# --- OP_MSAT_RATIO --------------------------------------------------------- + +def test_amount_msat_ratio(): + """ratio invariant: float(a / b) == a.msat / b.msat""" + a, b = Millisatoshi(7_000), Millisatoshi(3_000) + ratio = a / b # __truediv__ with Millisatoshi returns float + assert ratio == 7_000 / 3_000 + + +# --- OP_MSAT_RATIO_FLOOR --------------------------------------------------- + +def test_amount_msat_ratio_floor(): + """ratio_floor invariant: a // b == a.msat // b.msat""" + a, b = Millisatoshi(7_000), Millisatoshi(3_000) + floor = a // b # __floordiv__ with Millisatoshi returns int + assert floor == 7_000 // 3_000 + + +# --- OP_MSAT_RATIO_CEIL ---------------------------------------------------- + +def test_amount_msat_ratio_ceil(): + """ratio_ceil invariant: ceil == quotient + (1 if remainder else 0)""" + cases = [(7_000, 3_000), (9_000, 3_000), (1, 3_000)] + for a_val, b_val in cases: + quotient, remainder = divmod(a_val, b_val) + expected_ceil = quotient + (1 if remainder else 0) + assert expected_ceil == math.ceil(a_val / b_val) + + +# --- OP_MSAT_SCALE --------------------------------------------------------- + +def test_amount_msat_scale(): + """scale invariant: |out.msat - a.msat * f| < 1.0""" + a = Millisatoshi(1_000) + f = 1.5 + out = a * f # __mul__ with float returns floor(a * f) + assert abs(int(out) - int(a) * f) < 1.0 + + +def test_amount_msat_scale_small(): + """Scaling by a sub-unit float rounds down correctly.""" + a = Millisatoshi(1_001) + f = 0.1 + out = a * f + assert abs(int(out) - int(a) * f) < 1.0 + + +# --- OP_MSAT_ADD_SAT / OP_MSAT_SUB_SAT ------------------------------------ + +def test_amount_msat_add_sat(): + """msat + sat cross-type: out.msat == a.msat + sa.sat * MSAT_PER_SAT""" + a_msat = 5_500 + sa_sat = 5 + out_msat = a_msat + sa_sat * _MSAT_PER_SAT + assert out_msat == a_msat + sa_sat * _MSAT_PER_SAT + + +def test_amount_msat_sub_sat(): + """msat - sat cross-type: out.msat + sa.sat * MSAT_PER_SAT == a.msat""" + a_msat = 8_500 + sa_sat = 3 + out_msat = a_msat - sa_sat * _MSAT_PER_SAT + assert out_msat + sa_sat * _MSAT_PER_SAT == a_msat + + +# --- OP_SAT_ADD / OP_SAT_SUB / OP_SAT_MUL / OP_SAT_DIV / OP_SAT_SCALE ---- + +def test_amount_sat_add(): + """sat add: out.sat == sa + sb""" + sa, sb = 5, 3 + assert sa + sb == 8 + + +def test_amount_sat_sub(): + """sat sub: (sa - sb) + sb == sa""" + sa, sb = 10, 4 + out = sa - sb + assert out + sb == sa + + +def test_amount_sat_mul(): + """sat mul: out.sat == sa * n""" + sa, n = 7, 6 + assert sa * n == 42 + + +def test_amount_sat_div(): + """sat div: out.sat == floor(sa / n)""" + sa, n = 10, 3 + assert sa // n == 3 + + +def test_amount_sat_scale(): + """sat scale: |out.sat - sa * f| < 1.0""" + sa = 100 + f = 1.5 + out = int(sa * f) + assert abs(out - sa * f) < 1.0 + + +# --- OP_FEE / OP_ADD_FEE --------------------------------------------------- + +def test_amount_msat_fee_gte_base(): + """Computed fee is always >= fee_base_msat (OP_FEE invariant).""" + amt_msat = 100_000 + fee_base = 1_000 + fee_prop = 500 # 0.05 % + fee = _fee(amt_msat, fee_base, fee_prop) + assert fee >= fee_base + + +def test_amount_msat_add_fee(): + """total == original + fee (OP_ADD_FEE invariant).""" + amt_msat = 100_000 + fee_base = 1_000 + fee_prop = 500 + fee = _fee(amt_msat, fee_base, fee_prop) + total = amt_msat + fee + assert total == amt_msat + fee + + +def test_amount_msat_fee_zero_prop(): + """With zero proportional component, fee == fee_base exactly.""" + amt_msat = 1_000_000 + fee_base = 2_000 + assert _fee(amt_msat, fee_base, 0) == fee_base + + +# --- OP_SUB_FEE ------------------------------------------------------------ + +def test_amount_msat_sub_fee(): + """sub_fee invariant: fee(output) + output <= input (OP_SUB_FEE).""" + cases = [ + (102_000, 1_000, 1_000), # typical routing hop + (5_000, 1_000, 0), # prop == 0 + (500_000, 500, 2_000), # higher proportional fee + ] + for input_msat, fee_base, fee_prop in cases: + out = _sub_fee(input_msat, fee_base, fee_prop) + assert out + _fee(out, fee_base, fee_prop) <= input_msat, ( + f"sub_fee violated for input={input_msat} base={fee_base} prop={fee_prop}: " + f"out={out} fee={_fee(out, fee_base, fee_prop)}" + ) + + +def test_amount_msat_sub_fee_less_than_base(): + """When input < fee_base, sub_fee returns 0 (no usable amount).""" + assert _sub_fee(500, 1_000, 0) == 0 + + +# --- OP_TX_FEE ------------------------------------------------------------- + +def test_amount_tx_fee(): + """tx_fee == fee_per_kw * weight // 1000 (amount_tx_fee invariant).""" + cases = [ + (253, 1_000), # typical 1-vbyte-unit weight + (1_000, 4_000), # 4 kweight + (500, 0), # zero-weight edge case + ] + for fee_per_kw, weight in cases: + expected = fee_per_kw * weight // 1_000 + assert fee_per_kw * weight // 1_000 == expected + + +# --- OP_FEERATE ------------------------------------------------------------ + +def test_amount_feerate(): + """feerate == fee_sat * 1000 // weight (amount_feerate invariant).""" + cases = [ + (1_000, 4_000), # feerate == 250 + (253, 1_000), + (100_000, 100_000), + ] + for fee_sat, weight in cases: + feerate = fee_sat * 1_000 // weight + # Inverse: fee_sat >= feerate * weight // 1000 + assert fee_sat * 1_000 // weight == feerate + + +def test_amount_feerate_tx_fee_roundtrip(): + """feerate(tx_fee(fee_per_kw, w), w) recovers fee_per_kw (within rounding).""" + fee_per_kw = 500 + weight = 4_000 + tx_fee_sat = fee_per_kw * weight // 1_000 # amount_tx_fee + recovered_feerate = tx_fee_sat * 1_000 // weight # amount_feerate + # Due to integer division, recovered value may be slightly less + assert recovered_feerate <= fee_per_kw + assert fee_per_kw - recovered_feerate < fee_per_kw // weight + 1