fix(send): validate recipient address checksums (Base58Check + Bech32)
The send screen labelled any prefix+length match as a "Valid" address, so a mistyped address that still matched the pattern passed the gate. Add pure, offline checksum validation — Base58Check (transparent R-addresses) and Bech32 (Sapling zs-addresses) — and require it in the validity check. Both verifiers are version-byte/HRP agnostic (the HRP is taken from the string, the Base58 checksum is chain-independent), so a correct implementation never rejects a genuine address while catching transcription errors. Works for both build variants (no daemon round-trip), unit-tested against standard BIP173 / Base58Check vectors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#include "ui/windows/mining_benchmark.h"
|
||||
#include "ui/windows/mining_pool_panel.h"
|
||||
#include "ui/windows/mining_tab_helpers.h"
|
||||
#include "util/address_validation.h"
|
||||
#include "util/amount_format.h"
|
||||
#include "util/payment_uri.h"
|
||||
#include "util/platform.h"
|
||||
@@ -4242,6 +4243,29 @@ void testAtomicFileWrite()
|
||||
fs::remove_all(dir);
|
||||
}
|
||||
|
||||
// Address checksum validation. Uses standard Base58Check / BIP173 Bech32 vectors — the
|
||||
// algorithms are chain-agnostic, so passing these means real DRGX addresses validate too.
|
||||
void testAddressChecksumValidation()
|
||||
{
|
||||
using dragonx::util::isValidBase58Check;
|
||||
using dragonx::util::isValidBech32;
|
||||
|
||||
// Base58Check: a valid P2PKH address verifies; a one-char transcription error fails.
|
||||
EXPECT_TRUE(isValidBase58Check("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"));
|
||||
EXPECT_FALSE(isValidBase58Check("1A1zP1eP5QGefi2DMPTfTL5SLmv7Divfna")); // last char flipped
|
||||
EXPECT_FALSE(isValidBase58Check("not-base58-0OIl")); // invalid alphabet
|
||||
EXPECT_FALSE(isValidBase58Check(""));
|
||||
|
||||
// Bech32 (BIP173 valid vectors) verify; corrupted checksums fail.
|
||||
EXPECT_TRUE(isValidBech32("A12UEL5L"));
|
||||
EXPECT_TRUE(isValidBech32("abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw"));
|
||||
EXPECT_TRUE(isValidBech32("split1checkupstagehandshakeupstreamerranterredcaperred2y9e3w"));
|
||||
EXPECT_FALSE(isValidBech32("A12UEL5M")); // checksum corrupted
|
||||
EXPECT_FALSE(isValidBech32("abc1rzg")); // too short / bad checksum
|
||||
EXPECT_FALSE(isValidBech32("Abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw")); // mixed case
|
||||
EXPECT_FALSE(isValidBech32("nosalt")); // no separator
|
||||
}
|
||||
|
||||
// Live probe of a real lite server (env-gated). Validates CONNECT_ONLY latency + IP capture.
|
||||
void testLiteServerProbeLive()
|
||||
{
|
||||
@@ -4426,6 +4450,7 @@ int main()
|
||||
testLiteServerHostParsing();
|
||||
testLiteOfficialServerDetection();
|
||||
testAtomicFileWrite();
|
||||
testAddressChecksumValidation();
|
||||
testLiteServerProbeLive();
|
||||
testXmrigLiveInstall();
|
||||
testGeneratedResourceBehavior();
|
||||
|
||||
Reference in New Issue
Block a user