commit 7d6d1cd02663828579bf9e446a6f7f9041f08277
parent 4b9821373b8f2ddf3d91fffbaf2d7ac08e0afef6
Author: Antoine A <>
Date: Mon, 22 Nov 2021 17:25:19 +0100
Handle insufficient amount refund
Diffstat:
| M | Cargo.lock | | | 408 | ------------------------------------------------------------------------------- |
| M | Cargo.toml | | | 66 | +++++++++++++++++++++++++++++++----------------------------------- |
| M | src/bin/test.rs | | | 33 | ++++++++++++++++++++++++++++++++- |
| M | src/lib.rs | | | 22 | ++++++++++++++-------- |
| M | src/rpc_patch.rs | | | 110 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
5 files changed, 186 insertions(+), 453 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -32,17 +32,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38de00daab4eac7d753e97697066238d67ce9d7e2d823ab4f72fe14af29f3f33"
[[package]]
-name = "atty"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
-dependencies = [
- "hermit-abi",
- "libc",
- "winapi",
-]
-
-[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -121,24 +110,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
-name = "bstr"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
-dependencies = [
- "lazy_static",
- "memchr",
- "regex-automata",
- "serde",
-]
-
-[[package]]
-name = "bumpalo"
-version = "3.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
-
-[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -151,15 +122,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]]
-name = "cast"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a"
-dependencies = [
- "rustc_version",
-]
-
-[[package]]
name = "cc"
version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -172,17 +134,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
-name = "clap"
-version = "2.33.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
-dependencies = [
- "bitflags",
- "textwrap",
- "unicode-width",
-]
-
-[[package]]
name = "clipboard-win"
version = "4.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -194,108 +145,6 @@ dependencies = [
]
[[package]]
-name = "criterion"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10"
-dependencies = [
- "atty",
- "cast",
- "clap",
- "criterion-plot",
- "csv",
- "itertools",
- "lazy_static",
- "num-traits",
- "oorandom",
- "plotters",
- "rayon",
- "regex",
- "serde",
- "serde_cbor",
- "serde_derive",
- "serde_json",
- "tinytemplate",
- "walkdir",
-]
-
-[[package]]
-name = "criterion-plot"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57"
-dependencies = [
- "cast",
- "itertools",
-]
-
-[[package]]
-name = "crossbeam-channel"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-deque"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
-dependencies = [
- "cfg-if",
- "crossbeam-epoch",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-epoch"
-version = "0.9.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
- "lazy_static",
- "memoffset",
- "scopeguard",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
-dependencies = [
- "cfg-if",
- "lazy_static",
-]
-
-[[package]]
-name = "csv"
-version = "1.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
-dependencies = [
- "bstr",
- "csv-core",
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "csv-core"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
-dependencies = [
- "memchr",
-]
-
-[[package]]
name = "darling"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -337,7 +186,6 @@ dependencies = [
"argh",
"bech32",
"bitcoincore-rpc",
- "criterion",
"fastrand",
"owo-colors",
"rand",
@@ -367,12 +215,6 @@ dependencies = [
]
[[package]]
-name = "either"
-version = "1.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
-
-[[package]]
name = "endian-type"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -460,12 +302,6 @@ dependencies = [
]
[[package]]
-name = "half"
-version = "1.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
-
-[[package]]
name = "heck"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -556,30 +392,12 @@ dependencies = [
]
[[package]]
-name = "itertools"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
-dependencies = [
- "either",
-]
-
-[[package]]
name = "itoa"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
-name = "js-sys"
-version = "0.3.55"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
-dependencies = [
- "wasm-bindgen",
-]
-
-[[package]]
name = "jsonrpc"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -690,15 +508,6 @@ dependencies = [
]
[[package]]
-name = "num-traits"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
name = "num_cpus"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -715,12 +524,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]]
-name = "oorandom"
-version = "11.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
-
-[[package]]
name = "owo-colors"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -764,34 +567,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
-name = "plotters"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a"
-dependencies = [
- "num-traits",
- "plotters-backend",
- "plotters-svg",
- "wasm-bindgen",
- "web-sys",
-]
-
-[[package]]
-name = "plotters-backend"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c"
-
-[[package]]
-name = "plotters-svg"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9"
-dependencies = [
- "plotters-backend",
-]
-
-[[package]]
name = "ppv-lite86"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -866,31 +641,6 @@ dependencies = [
]
[[package]]
-name = "rayon"
-version = "1.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
-dependencies = [
- "autocfg",
- "crossbeam-deque",
- "either",
- "rayon-core",
-]
-
-[[package]]
-name = "rayon-core"
-version = "1.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
-dependencies = [
- "crossbeam-channel",
- "crossbeam-deque",
- "crossbeam-utils",
- "lazy_static",
- "num_cpus",
-]
-
-[[package]]
name = "redox_syscall"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -910,36 +660,6 @@ dependencies = [
]
[[package]]
-name = "regex"
-version = "1.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
-dependencies = [
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-automata"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
-
-[[package]]
-name = "regex-syntax"
-version = "0.6.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
-
-[[package]]
-name = "rustc_version"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
-dependencies = [
- "semver",
-]
-
-[[package]]
name = "rustversion"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -976,15 +696,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
-name = "same-file"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
-dependencies = [
- "winapi-util",
-]
-
-[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1010,12 +721,6 @@ dependencies = [
]
[[package]]
-name = "semver"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
-
-[[package]]
name = "serde"
version = "1.0.130"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1025,16 +730,6 @@ dependencies = [
]
[[package]]
-name = "serde_cbor"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
-dependencies = [
- "half",
- "serde",
-]
-
-[[package]]
name = "serde_derive"
version = "1.0.130"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1128,15 +823,6 @@ dependencies = [
]
[[package]]
-name = "textwrap"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
-dependencies = [
- "unicode-width",
-]
-
-[[package]]
name = "thiserror"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1157,16 +843,6 @@ dependencies = [
]
[[package]]
-name = "tinytemplate"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
-dependencies = [
- "serde",
- "serde_json",
-]
-
-[[package]]
name = "tokio"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1254,17 +930,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372"
[[package]]
-name = "walkdir"
-version = "2.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
-dependencies = [
- "same-file",
- "winapi",
- "winapi-util",
-]
-
-[[package]]
name = "want"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1281,70 +946,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
-name = "wasm-bindgen"
-version = "0.2.78"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
-dependencies = [
- "cfg-if",
- "wasm-bindgen-macro",
-]
-
-[[package]]
-name = "wasm-bindgen-backend"
-version = "0.2.78"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
-dependencies = [
- "bumpalo",
- "lazy_static",
- "log",
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.78"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
-dependencies = [
- "quote",
- "wasm-bindgen-macro-support",
-]
-
-[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.78"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-backend",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.78"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
-
-[[package]]
-name = "web-sys"
-version = "0.3.55"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1361,15 +962,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
-name = "winapi-util"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
-dependencies = [
- "winapi",
-]
-
-[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
@@ -1,35 +1,31 @@
-[package]
-name = "depolymerization"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-# Typed bitcoin json-rpc library
-bitcoincore-rpc = "0.14.0"
-# Cli args
-argh = "0.1.6"
-# Readline
-rustyline = "9.0.0"
-# Bech32 encoding and decoding
-bech32 = "0.8.1"
-# Secure random
-rand = { version = "0.8.4", features = ["getrandom"] }
-# Fast unsecure random
-fastrand = "1.5.0"
-# Serialization library
-serde = { version = "1.0.130", features = ["derive"] }
-# Zero allocation terminal color
-owo-colors = "3.1.0"
-
-[dev-dependencies]
-# statistics-driven micro-benchmarks
-criterion = "0.3.5"
-
-[workspace]
-members = ["wire-gateway"]
-
-[[bench]]
-name = "metadata"
-harness = false
+[package]
+name = "depolymerization"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+# Typed bitcoin json-rpc library
+bitcoincore-rpc = "0.14.0"
+# Cli args
+argh = "0.1.6"
+# Readline
+rustyline = "9.0.0"
+# Bech32 encoding and decoding
+bech32 = "0.8.1"
+# Secure random
+rand = { version = "0.8.4", features = ["getrandom"] }
+# Fast unsecure random
+fastrand = "1.5.0"
+# Serialization library
+serde = { version = "1.0.130", features = ["derive"] }
+# Zero allocation terminal color
+owo-colors = "3.1.0"
+
+[workspace]
+members = ["wire-gateway"]
+
+[[bench]]
+name = "metadata"
+harness = false
diff --git a/src/bin/test.rs b/src/bin/test.rs
@@ -224,6 +224,38 @@ pub fn main() {
let after = client_rpc.get_balance(None, None).unwrap();
assert_eq!(before - after, refund_tx_fee + refund_fee + send_tx_fee);
});
+ runner.test("Refund minimal amount", || {
+ let send_id = client_rpc
+ .send_to_address(
+ &wire_addr,
+ Amount::from_sat(294),
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ )
+ .unwrap();
+ next_block();
+ assert!(refund(&wire_rpc, &send_id, refund_fee).is_err());
+ });
+ runner.test("Refund too small amount", || {
+ let send_id = client_rpc
+ .send_to_address(
+ &wire_addr,
+ Amount::from_sat(294) + refund_fee,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ )
+ .unwrap();
+ next_block();
+ assert!(refund(&wire_rpc, &send_id, refund_fee).is_err());
+ });
runner.test("Refund complex", || {
// Generate 6 new addresses
let addresses: Vec<Address> =
@@ -302,7 +334,6 @@ pub fn main() {
.unwrap();
assert_eq!(before - after, refund_tx_fee + refund_fee + send_tx_fee);
});
- // TODO refund minimal amount
runner.conclude();
}
diff --git a/src/lib.rs b/src/lib.rs
@@ -11,7 +11,9 @@ use bitcoincore_rpc::{
use rand::{rngs::OsRng, RngCore};
use rpc_patch::{ClientPatched, GetTransactionFull};
-mod rpc_patch;
+use crate::rpc_patch::{rpc_error, RpcErrorCode};
+
+pub mod rpc_patch;
/// Minimum dust amount to perform a transaction to a segwit address
fn segwit_min_amount() -> Amount {
@@ -158,16 +160,20 @@ fn send_many(
/// There is no reliable way to refund a transaction as you cannot know if the addresses used are shared
///
/// This is not a best-effort solution but a reasonable one
-pub fn refund(
- rpc: &Client,
- id: &Txid,
- refund_fee: Amount,
-) -> bitcoincore_rpc::Result<Txid> {
+pub fn refund(rpc: &Client, id: &Txid, refund_fee: Amount) -> bitcoincore_rpc::Result<Txid> {
// TODO handle insufficient_funds error
let full = rpc.get_transaction_full(id)?;
let detail = &full.tx.details[0];
assert_eq!(detail.category, Category::Receive);
-
+
+ let amount = detail.amount.to_unsigned().unwrap();
+ if amount <= refund_fee {
+ return Err(rpc_error(
+ RpcErrorCode::RpcWalletInsufficientFunds,
+ "The refund amount is inferior to the refund fee".to_string(),
+ ));
+ }
+
// List all addresses
let mut addresses = Vec::new();
for vin in full.decoded.vin {
@@ -179,7 +185,7 @@ pub fn refund(
}
// Split received amount (minus refund fee) equally to each addresses
- let split = (detail.amount.to_unsigned().unwrap() - refund_fee) / addresses.len() as u64;
+ let split = (amount - refund_fee) / addresses.len() as u64;
let recipients: Vec<(String, Amount)> =
addresses.iter().map(|addr| (addr.clone(), split)).collect();
// Send refund making recipient pay the transaction fees
diff --git a/src/rpc_patch.rs b/src/rpc_patch.rs
@@ -1,7 +1,12 @@
//! bitcoincore-rpc does not handle all the command we need and is not compatible with bitcoincore v22.0 that we use.
//! We add additional typed command with a custom trait
-use bitcoincore_rpc::{Client, RpcApi, bitcoin::{Address, Amount, BlockHash, Txid, Wtxid}, json::{GetRawTransactionResultVin, GetTransactionResult, ScriptPubkeyType}, jsonrpc::serde_json::Value};
+use bitcoincore_rpc::{
+ bitcoin::{Address, Amount, BlockHash, Txid, Wtxid},
+ json::{GetRawTransactionResultVin, GetTransactionResult, ScriptPubkeyType},
+ jsonrpc::serde_json::Value,
+ Client, RpcApi,
+};
pub trait ClientPatched {
fn get_transaction_full(&self, id: &Txid) -> bitcoincore_rpc::Result<GetTransactionFull>;
@@ -82,3 +87,106 @@ pub struct GetTransactionFull {
pub tx: GetTransactionResult,
pub decoded: TransactionDecoded,
}
+
+pub fn rpc_error(code: RpcErrorCode, msg: impl Into<String>) -> bitcoincore_rpc::Error {
+ bitcoincore_rpc::Error::JsonRpc(bitcoincore_rpc::jsonrpc::Error::Rpc(
+ bitcoincore_rpc::jsonrpc::error::RpcError {
+ code: code as i32,
+ message: msg.into(),
+ data: None,
+ },
+ ))
+}
+
+/// Bitcoin RPC error codes <https://github.com/bitcoin/bitcoin/blob/master/src/rpc/protocol.h>
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[repr(i32)]
+pub enum RpcErrorCode {
+ // Standard JSON-RPC 2.0 errors
+ // RPC_INVALID_REQUEST is internally mapped to HTTP_BAD_REQUEST (400).
+ // It should not be used for application-layer errors.
+ RpcInvalidRequest = -32600,
+ // RPC_METHOD_NOT_FOUND is internally mapped to HTTP_NOT_FOUND (404).
+ // It should not be used for application-layer errors.
+ RpcMethodNotFound = -32601,
+ RpcInvalidParams = -32602,
+ // RPC_INTERNAL_ERROR should only be used for genuine errors in bitcoind
+ // (for example datadir corruption).
+ RpcInternalError = -32603,
+ RpcParseError = -32700,
+
+ // General application defined errors
+ /// std::exception thrown in command handling
+ RpcMiscError = -1,
+
+ /// Unexpected type was passed as parameter
+ RpcTypeError = -3,
+ /// Invalid address or key
+ RpcInvalidAddressOrKey = -5,
+ /// Ran out of memory during operation
+ RpcOutOfMemory = -7,
+ /// Invalid, missing or duplicate parameter
+ RpcInvalidParameter = -8,
+ /// Database error
+ RpcDatabaseError = -20,
+ /// Error parsing or validating structure in raw format
+ RpcDeserializationError = -22,
+ /// General error during transaction or block submission
+ RpcVerifyError = -25,
+ /// Transaction or block was rejected by network rules
+ RpcVerifyRejected = -26,
+ /// Transaction already in chain
+ RpcVerifyAlreadyInChain = -27,
+ /// Client still warming up
+ RpcInWarmup = -28,
+ /// RPC method is deprecated
+ RpcMethodDeprecated = -32,
+ // P2P client errors
+ /// Bitcoin is not connected
+ RpcClientNotConnected = -9,
+ /// Still downloading initial blocks
+ RpcClientInInitialDownload = -10,
+ /// Node is already added
+ RpcClientNodeAlreadyAdded = -23,
+ /// Node has not been added before
+ RpcClientNodeNotAdded = -24,
+ /// Node to disconnect not found in connected nodes
+ RpcClientNodeNotConnected = -29,
+ /// Invalid IP/Subnet
+ RpcClientInvalidIpOrSubnet = -30,
+ /// No valid connection manager instance found
+ RpcClientP2pDisabled = -31,
+ /// Max number of outbound or block-relay connections already open
+ RpcClientNodeCapacityReached = -34,
+ // Chain errors
+ RpcClientMempoolDisabled = -33,
+ /// No mempool instance found
+ // Wallet errors
+ /// Unspecified problem with wallet (key not found etc.)
+ RpcWalletError = -4,
+ /// Not enough funds in wallet or account
+ RpcWalletInsufficientFunds = -6,
+ /// Invalid label name
+ RpcWalletInvalidLabelName = -11,
+ /// Keypool ran out, call keypoolrefill first
+ RpcWalletKeypoolRanOut = -12,
+ /// Enter the wallet passphrase with walletpassphrase first
+ RpcWalletUnlockNeeded = -13,
+ /// The wallet passphrase entered was incorrect
+ RpcWalletPassphraseIncorrect = -14,
+ /// Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.)
+ RpcWalletWrongEncState = -15,
+ /// Failed to encrypt the wallet
+ RpcWalletEncryptionFailed = -16,
+ /// Wallet is already unlocked
+ RpcWalletAlreadyUnlocked = -17,
+ /// Invalid wallet specified
+ RpcWalletNotFound = -18,
+ /// No wallet specified (error when there are multiple wallets loaded)
+ RpcWalletNotSpecified = -19,
+ /// This same wallet is already loaded
+ RpcWalletAlreadyLoaded = -35,
+ // Unused reserved codes, kept around for backwards compatibility. Do not reuse.
+ /// Server is in safe mode, and command is not allowed in safe mode
+ RpcForbiddenBySafeMode = -2,
+}