security: [T1-08] add regtest-only runtime guards to MockOracleManager (DGB-SEC-005)#377
Conversation
…r (DGB-SEC-005) MockOracleManager::GetCurrentPrice() was called without a REGTEST check in validation.cpp, meaning mock oracle prices could leak into consensus code on mainnet/testnet if the singleton was instantiated. Fix adds guards at two layers: - validation.cpp: gate mock oracle access behind REGTEST chain check - MockOracleManager: GetCurrentPrice() and SetMockPrice() now reject calls on non-REGTEST networks as defense-in-depth
There was a problem hiding this comment.
Pull request overview
This pull request addresses a security vulnerability (DGB-SEC-005) where the MockOracleManager::GetCurrentPrice() function could potentially be called on non-REGTEST networks, allowing mock prices to leak into consensus validation on mainnet/testnet. The fix implements defense-in-depth by adding both call-site guards and internal runtime checks.
Changes:
- Added REGTEST guard at the call site in
validation.cppforGetOraclePriceForTransaction() - Added internal runtime guards in
MockOracleManager::GetCurrentPrice()andSetMockPrice()to reject calls on non-REGTEST networks - Updated code comments to clarify security implications
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/validation.cpp | Added ChainType::REGTEST check before accessing MockOracleManager in GetOraclePriceForTransaction() |
| src/oracle/mock_oracle.cpp | Added internal runtime guards to reject GetCurrentPrice() and SetMockPrice() calls on non-REGTEST networks |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
OpenSSL 1.1.1w Configure misparses multi-word flags like "-arch arm64" when passed as positional args — the shell splits them and Configure treats the second word as a target name, causing "target already defined" on ARM64 macOS. Pass CFLAGS/CPPFLAGS as VAR=value assignments per OpenSSL's official INSTALL docs. libcurl 8.5.0 fopen.c uses fileno/fdopen (POSIX) which are hidden by the depends system's strict -std=c11. Add -D_GNU_SOURCE for Linux.
Use $$ deferred evaluation for CFLAGS/CPPFLAGS assignments so OS-specific flags (cflags_linux, cppflags_linux) appended by funcs.mk after set_vars are included. Route -fPIC and -D_GNU_SOURCE through proper cflags/cppflags variables instead of bare config_opts to avoid OpenSSL's "Mixing make variables" rejection.
The depends system never defines $(package)_arflags, so ARFLAGS=$($(package)_arflags) in config_env exported an empty ARFLAGS="" to the environment. When CFLAGS/CPPFLAGS are passed as VAR=value assignments (not positional flags), OpenSSL 1.1.1w's Configure sets $anyuseradd=false and falls back to reading env vars. The empty ARFLAGS overrides the target default "r" from Configurations/00-base-templates.conf, producing a Makefile with ARFLAGS= (empty). This causes "ar: two different operation options specified" on Linux and "ar: illegal option -- /" on macOS during build_libs, as ar interprets the archive path as flags. Fix: remove ARFLAGS from config_env entirely, letting Configure use its target default ARFLAGS="r". Verified locally: - Linux x86_64: ar r apps/libapps.a ... (ARFLAGS=r in Makefile) - macOS ARM64: ar r apps/libapps.a ... (ARFLAGS=r in Makefile) - Full build_libs completes successfully on darwin64-arm64-cc
Replace BOOST_CHECK with BOOST_CHECK_MESSAGE in 5 mint validation tests that fail on CI but pass locally. Diagnostic output captures the exact reject reason, script sizes, collateral amounts, and script type identification to help debug the CI-specific failure.
Replace ClearFreeze() with ClearHistory() in the validation test fixture. ClearFreeze() only clears freeze flags, but UpdateState() (called during ValidateDigiDollarTransaction) recalculates volatility from stale price history left by earlier test suites (e.g., digidollar_health_tests) and re-sets the freeze. This caused all "valid mint" tests to fail with "minting-frozen-volatility" on CI where the test suite ordering (linker-dependent) places health_tests before validation_tests. ClearHistory() resets price history, volatility state, and all freeze flags, ensuring each test starts from a clean state.
The merge with feature/digidollar-v1 silently dropped critical code: 1. DD amount double-counting prevention in ValidateMintTransaction() The OP_RETURN and DD token output both encode ddAmount. Without the consistency check, totalDD was counted twice (e.g. 10000 + 10000 = 20000), requiring 2x the collateral and failing all valid mint tests. 2. Missing #include <digidollar/health.h> 3. Improved log format for insufficient-collateral diagnostic Also adopts the base branch's test file which includes: - DD OP_RETURN outputs required for T1-04b NUMS verification - Proper NUMS key usage via GetCollateralNUMSKey() - ClearHistory() fix for cross-suite volatility state pollution
|
Reviewed and merged manually into What was applied:
Defense-in-depth: even though What was NOT applied:
Verification:
Closing as manually merged. Good defense-in-depth @gto90. |
Summary
MockOracleManager::GetCurrentPrice()was called invalidation.cppwithout a REGTEST chain-type check — mock prices could leak into consensus on mainnet/testnetvalidation.cppGetCurrentPrice()andSetMockPrice()now reject calls on non-REGTEST networks internallyTest plan
setmockoraclepriceRPC)GetCurrentPrice()returns 0 on non-REGTESTtest_digibyte --run_test=digidollar_dca_tests