Ensuring the swap error codes match the swap ones from the SDK
What changed, and why it matters
This commit adds compile-time checks to make sure the Bitcoin app's own swap error codes line up with the official Ledger SDK's swap error codes. It does not change any runtime behavior or fix an active bug; it is a defensive quality-assurance change that prevents future mismatches.
No urgent action required. Treat as a normal code-quality/build-safety improvement. Reviewers should confirm the asserted mappings are semantically correct and that CI builds with HAVE_SWAP enabled still pass.
Security signals we found
Compile-time assertion guarding consistency between app-specific and SDK-wide swap error codes
Conditional inclusion under HAVE_SWAP, so no effect on non-swap builds
No functional code change; purely defensive/static-analysis aid
Evidence from the diff
The patch introduces _Static_assert macros in src/error_codes.h (only when HAVE_SWAP is defined) that verify each EC_SWAP_ERROR_* value’s high byte equals the corresponding SWAP_EC_ERROR_* value from swap_error_code_helpers.h. If a developer later changes either side inconsistently, the build will fail. The commit is purely additive and does not alter existing error-code values or runtime logic.
Changed components
src/error_codes.hInspect captured patch +37 / −0
diff --git a/src/error_codes.h b/src/error_codes.h
index 9782a49..86ee5de 100644
--- a/src/error_codes.h
+++ b/src/error_codes.h
@@ -1,5 +1,10 @@
#pragma once
+/* SDK headers */
+#ifdef HAVE_SWAP
+#include "swap_error_code_helpers.h"
+#endif /* HAVE_SWAP */
+
/**
* REGISTER_WALLET
*/
@@ -111,3 +116,35 @@
#define EC_SWAP_ERROR_GENERIC_UNKNOWN_MODE 0xFF01
// handle_swap_sign_transaction.c::copy_transaction_parameters failed.
#define EC_SWAP_ERROR_GENERIC_COPY_TRANSACTION_PARAMETERS_FAILED 0xFF02
+
+// Checking the match for the SWAP error codes with the SDK ones
+#ifdef HAVE_SWAP
+
+#define ASSERT_SWAP_ERR_CODE(btc_err_code, sdk_err_code) \
+ _Static_assert(((btc_err_code >> 8) & 0xFF) == sdk_err_code, \
+ "SWAP error code value does not match the SDK one")
+
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_INTERNAL, SWAP_EC_ERROR_INTERNAL);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_WRONG_AMOUNT, SWAP_EC_ERROR_WRONG_AMOUNT);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_WRONG_DESTINATION, SWAP_EC_ERROR_WRONG_DESTINATION);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_WRONG_FEES, SWAP_EC_ERROR_WRONG_FEES);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_WRONG_METHOD, SWAP_EC_ERROR_WRONG_METHOD);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_WRONG_METHOD_NONDEFAULT_POLICY, SWAP_EC_ERROR_WRONG_METHOD);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_WRONG_METHOD_EXTERNAL_INPUTS, SWAP_EC_ERROR_WRONG_METHOD);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_WRONG_METHOD_MISSING_NONWITNESSUTXO, SWAP_EC_ERROR_WRONG_METHOD);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_WRONG_METHOD_WRONG_N_OF_OUTPUTS, SWAP_EC_ERROR_WRONG_METHOD);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_WRONG_METHOD_WRONG_UNSUPPORTED_OUTPUT,
+ SWAP_EC_ERROR_WRONG_METHOD);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_CROSSCHAIN_WRONG_MODE, SWAP_EC_ERROR_CROSSCHAIN_WRONG_MODE);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_CROSSCHAIN_WRONG_METHOD, SWAP_EC_ERROR_CROSSCHAIN_WRONG_METHOD);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_CROSSCHAIN_WRONG_METHOD_INVALID_FIRST_OUTPUT,
+ SWAP_EC_ERROR_CROSSCHAIN_WRONG_METHOD);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_CROSSCHAIN_WRONG_METHOD_NONZERO_AMOUNT,
+ SWAP_EC_ERROR_CROSSCHAIN_WRONG_METHOD);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_CROSSCHAIN_WRONG_HASH, SWAP_EC_ERROR_CROSSCHAIN_WRONG_HASH);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_GENERIC, SWAP_EC_ERROR_GENERIC);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_GENERIC_UNKNOWN_MODE, SWAP_EC_ERROR_GENERIC);
+ASSERT_SWAP_ERR_CODE(EC_SWAP_ERROR_GENERIC_COPY_TRANSACTION_PARAMETERS_FAILED,
+ SWAP_EC_ERROR_GENERIC);
+
+#endif /* HAVE_SWAP */
Why this scored 22/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.