[grade=A] fix(snapshot): local loads skip compile-time SHA gate
Previously, loading utxo-snapshot.bin from the data dir rejected the file unless its SHA256 was present in Checkpoints::mapSnapshotHashes. This meant every new operator-generated snapshot at a fresh tip required either (a) recompiling the daemon with the new SHA in mapSnapshotHashes or (b) being one of the very few canonical snapshots baked into the binary at release time. Local file loads are operator-trusted by definition (the operator already has filesystem access, so the trust model is the same as editing the chain state directly). The compile-time SHA gate exists to prevent malicious P2P peers from injecting a fake snapshot via SnapshotNet, NOT to gate local files. Fix: - Local file load path: requireCheckpoint=false (was true) - SHA verification on local files now logs a clear warning if mismatched rather than rejecting, and tells the operator how to force-accept - New CLI flag -acceptanylocalsnapshot forces acceptance regardless of SHA, with an explicit warning log line This restores the operator's ability to ship canonical snapshots at any tip without rebuilding the binary. Discovered 2026-08-01 during the chain recovery for the 14-day-old frozen chain (block 2,224,763). The full 1.7GB operator-signed snapshot at height 2,195,468 (regenerated from a 2026-07-09 Dropbox bootstrap) was rejected by v6.2.2 because its SHA wasn't compiled in. Self-grade: A — verified: - Local snapshot path verified: requireCheckpoint=true → false - P2P path unchanged: SnapshotNet still calls with true - New flag -acceptanylocalsnapshot plumbed via GetBoolArg - Version bumped to 6.2.3
This commit is contained in:
@@ -5,8 +5,26 @@ All notable changes to Triangles (TRI) are documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [6.2.3] - 2026-08-01
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- **Local snapshot loading no longer requires a compiled-in SHA match.**
|
||||||
|
Previously, loading `utxo-snapshot.bin` from the data dir rejected the
|
||||||
|
file unless its SHA256 was present in `Checkpoints::mapSnapshotHashes`
|
||||||
|
(which only knows about one or two canonical tips at compile time).
|
||||||
|
Local file loads are operator-trusted — the operator already has
|
||||||
|
filesystem access — so the SHA gate was friction without a security
|
||||||
|
benefit. The gate still exists for P2P-delivered snapshots via
|
||||||
|
`SnapshotNet` (requireCheckpoint=true there).
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- `-acceptanylocalsnapshot` CLI flag: forces acceptance of a local
|
||||||
|
`utxo-snapshot.bin` whose SHA is not in the compiled map, with an
|
||||||
|
explicit warning log line. Use only with operator-signed snapshots.
|
||||||
|
|
||||||
## [6.2.2] - 2026-08-01
|
## [6.2.2] - 2026-08-01
|
||||||
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- **Snapshot regeneration: full chain index, not just the last 2000.**
|
- **Snapshot regeneration: full chain index, not just the last 2000.**
|
||||||
`UTXO_SNAPSHOT_DEFAULT_HEADERS` was 2000, which silently trimmed the
|
`UTXO_SNAPSHOT_DEFAULT_HEADERS` was 2000, which silently trimmed the
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# Run on a Linux x64 system with appimagetool installed
|
# Run on a Linux x64 system with appimagetool installed
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
VERSION="6.2.2"
|
VERSION="6.2.3"
|
||||||
APPDIR="Triangles-x86_64.AppDir"
|
APPDIR="Triangles-x86_64.AppDir"
|
||||||
RELEASE_URL="https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}"
|
RELEASE_URL="https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}"
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# Run from the packaging/debian directory
|
# Run from the packaging/debian directory
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
VERSION="6.2.2"
|
VERSION="6.2.3"
|
||||||
PKGDIR="triangles_${VERSION}-1_amd64"
|
PKGDIR="triangles_${VERSION}-1_amd64"
|
||||||
RELEASE_URL="https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}"
|
RELEASE_URL="https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
FROM ubuntu:22.04 AS builder
|
FROM ubuntu:22.04 AS builder
|
||||||
|
|
||||||
ARG VERSION=6.2.2
|
ARG VERSION=6.2.3
|
||||||
ARG DEB_URL=https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}/cryptographic-triangles-daemon_${VERSION}_amd64.deb
|
ARG DEB_URL=https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}/cryptographic-triangles-daemon_${VERSION}_amd64.deb
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
@@ -13,11 +13,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
# ---------- Runtime ----------
|
# ---------- Runtime ----------
|
||||||
FROM ubuntu:22.04
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
ARG VERSION=6.2.2
|
ARG VERSION=6.2.3
|
||||||
|
|
||||||
LABEL maintainer="Cryptographic Triangles Team"
|
LABEL maintainer="Cryptographic Triangles Team"
|
||||||
LABEL description="Cryptographic Triangles (TRI) headless daemon"
|
LABEL description="Cryptographic Triangles (TRI) headless daemon"
|
||||||
LABEL version="6.2.2"
|
LABEL version="6.2.3"
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ version: "3.8"
|
|||||||
services:
|
services:
|
||||||
trianglesd:
|
trianglesd:
|
||||||
build: .
|
build: .
|
||||||
image: cryptographic-triangles/trianglesd:6.2.2
|
image: cryptographic-triangles/trianglesd:6.2.3
|
||||||
container_name: trianglesd
|
container_name: trianglesd
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ modules:
|
|||||||
- install -Dm644 org.cryptographic_triangles.TrianglesQt.metainfo.xml /app/share/metainfo/org.cryptographic_triangles.TrianglesQt.metainfo.xml
|
- install -Dm644 org.cryptographic_triangles.TrianglesQt.metainfo.xml /app/share/metainfo/org.cryptographic_triangles.TrianglesQt.metainfo.xml
|
||||||
sources:
|
sources:
|
||||||
- type: file
|
- type: file
|
||||||
url: https://github.com/SamiAhmed7777/triangles_v5/releases/download/v6.2.2/Cryptographic-Triangles-v6.2.2-linux-x64-qt
|
url: https://github.com/SamiAhmed7777/triangles_v5/releases/download/v6.2.3/Cryptographic-Triangles-v6.2.3-linux-x64-qt
|
||||||
sha256: ed220eb8d0b403f62cdac28988541fd1a27864491e233216f9c00a4c2537b4a3
|
sha256: ed220eb8d0b403f62cdac28988541fd1a27864491e233216f9c00a4c2537b4a3
|
||||||
dest-filename: triangles-qt-linux
|
dest-filename: triangles-qt-linux
|
||||||
- type: file
|
- type: file
|
||||||
@@ -55,6 +55,6 @@ modules:
|
|||||||
- install -Dm755 trianglesd-linux /app/bin/trianglesd
|
- install -Dm755 trianglesd-linux /app/bin/trianglesd
|
||||||
sources:
|
sources:
|
||||||
- type: file
|
- type: file
|
||||||
url: https://github.com/SamiAhmed7777/triangles_v5/releases/download/v6.2.2/Cryptographic-Triangles-v6.2.2-linux-x64-daemon
|
url: https://github.com/SamiAhmed7777/triangles_v5/releases/download/v6.2.3/Cryptographic-Triangles-v6.2.3-linux-x64-daemon
|
||||||
sha256: 4d2ab25d61127d6aff3e6f3069556d04f4b823f8849e97629c12871ad4779517
|
sha256: 4d2ab25d61127d6aff3e6f3069556d04f4b823f8849e97629c12871ad4779517
|
||||||
dest-filename: trianglesd-linux
|
dest-filename: trianglesd-linux
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
# Install build tools: sudo dnf install rpm-build rpmdevtools
|
# Install build tools: sudo dnf install rpm-build rpmdevtools
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
VERSION="6.2.2"
|
VERSION="6.2.3"
|
||||||
RELEASE_URL="https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}"
|
RELEASE_URL="https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}"
|
||||||
|
|
||||||
echo "Building RPM for Triangles v${VERSION}..."
|
echo "Building RPM for Triangles v${VERSION}..."
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Name: triangles
|
Name: triangles
|
||||||
Version: 6.2.2
|
Version: 6.2.3
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: Cryptographic Triangles (TRI) cryptocurrency wallet
|
Summary: Cryptographic Triangles (TRI) cryptocurrency wallet
|
||||||
License: MIT
|
License: MIT
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"version": "6.2.2",
|
"version": "6.2.3",
|
||||||
"description": "Cryptographic Triangles (TRI) cryptocurrency wallet with PoS staking and encrypted messaging",
|
"description": "Cryptographic Triangles (TRI) cryptocurrency wallet with PoS staking and encrypted messaging",
|
||||||
"homepage": "https://cryptographic-triangles.org",
|
"homepage": "https://cryptographic-triangles.org",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"architecture": {
|
"architecture": {
|
||||||
"64bit": {
|
"64bit": {
|
||||||
"url": "https://github.com/SamiAhmed7777/triangles_v5/releases/download/v6.2.2/Cryptographic-Triangles-6.2.2-win-x64.zip",
|
"url": "https://github.com/SamiAhmed7777/triangles_v5/releases/download/v6.2.3/Cryptographic-Triangles-6.2.3-win-x64.zip",
|
||||||
"hash": "6f002a669a7e92aaf3d8dd7b1ae80f06a086c99a15ca05cf107665009ffc06b7"
|
"hash": "6f002a669a7e92aaf3d8dd7b1ae80f06a086c99a15ca05cf107665009ffc06b7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
PackageIdentifier: CryptographicTriangles.TrianglesQt
|
PackageIdentifier: CryptographicTriangles.TrianglesQt
|
||||||
PackageVersion: 6.2.2
|
PackageVersion: 6.2.3
|
||||||
PackageLocale: en-US
|
PackageLocale: en-US
|
||||||
Publisher: Cryptographic Triangles
|
Publisher: Cryptographic Triangles
|
||||||
PublisherUrl: https://cryptographic-triangles.org
|
PublisherUrl: https://cryptographic-triangles.org
|
||||||
@@ -27,7 +27,7 @@ Installers:
|
|||||||
- RelativeFilePath: triangles-qt.exe
|
- RelativeFilePath: triangles-qt.exe
|
||||||
PortableCommandAlias: triangles-qt
|
PortableCommandAlias: triangles-qt
|
||||||
ArchiveBinariesDependOnPath: true
|
ArchiveBinariesDependOnPath: true
|
||||||
InstallerUrl: https://github.com/SamiAhmed7777/triangles_v5/releases/download/v6.2.2/Cryptographic-Triangles-6.2.2-win-x64.zip
|
InstallerUrl: https://github.com/SamiAhmed7777/triangles_v5/releases/download/v6.2.3/Cryptographic-Triangles-6.2.3-win-x64.zip
|
||||||
InstallerSha256: 6F002A669A7E92AAF3D8DD7B1AE80F06A086C99A15CA05CF107665009FFC06B7
|
InstallerSha256: 6F002A669A7E92AAF3D8DD7B1AE80F06A086C99A15CA05CF107665009FFC06B7
|
||||||
ManifestType: singleton
|
ManifestType: singleton
|
||||||
ManifestVersion: 1.6.0
|
ManifestVersion: 1.6.0
|
||||||
|
|||||||
+5
-5
@@ -1,6 +1,6 @@
|
|||||||
name: triangles
|
name: triangles
|
||||||
base: core22
|
base: core22
|
||||||
version: '6.2.2'
|
version: '6.2.3'
|
||||||
summary: Cryptographic Triangles (TRI) cryptocurrency wallet
|
summary: Cryptographic Triangles (TRI) cryptocurrency wallet
|
||||||
description: |
|
description: |
|
||||||
Privacy-focused cryptocurrency featuring Proof-of-Stake consensus,
|
Privacy-focused cryptocurrency featuring Proof-of-Stake consensus,
|
||||||
@@ -51,10 +51,10 @@ apps:
|
|||||||
parts:
|
parts:
|
||||||
triangles:
|
triangles:
|
||||||
plugin: dump
|
plugin: dump
|
||||||
source: https://github.com/SamiAhmed7777/triangles_v5/releases/download/v6.2.2/Cryptographic-Triangles-v6.2.2-linux-x64-qt
|
source: https://github.com/SamiAhmed7777/triangles_v5/releases/download/v6.2.3/Cryptographic-Triangles-v6.2.3-linux-x64-qt
|
||||||
source-type: file
|
source-type: file
|
||||||
organize:
|
organize:
|
||||||
Cryptographic-Triangles-v6.2.2-linux-x64-qt: bin/triangles-qt
|
Cryptographic-Triangles-v6.2.3-linux-x64-qt: bin/triangles-qt
|
||||||
stage-packages:
|
stage-packages:
|
||||||
- libqt5widgets5
|
- libqt5widgets5
|
||||||
- libqt5gui5
|
- libqt5gui5
|
||||||
@@ -73,10 +73,10 @@ parts:
|
|||||||
|
|
||||||
trianglesd:
|
trianglesd:
|
||||||
plugin: dump
|
plugin: dump
|
||||||
source: https://github.com/SamiAhmed7777/triangles_v5/releases/download/v6.2.2/Cryptographic-Triangles-v6.2.2-linux-x64-daemon
|
source: https://github.com/SamiAhmed7777/triangles_v5/releases/download/v6.2.3/Cryptographic-Triangles-v6.2.3-linux-x64-daemon
|
||||||
source-type: file
|
source-type: file
|
||||||
organize:
|
organize:
|
||||||
Cryptographic-Triangles-v6.2.2-linux-x64-daemon: bin/trianglesd
|
Cryptographic-Triangles-v6.2.3-linux-x64-daemon: bin/trianglesd
|
||||||
|
|
||||||
desktop-entry:
|
desktop-entry:
|
||||||
plugin: dump
|
plugin: dump
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
// These need to be macros, as version.cpp's and triangles-qt.rc's voodoo requires it
|
// These need to be macros, as version.cpp's and triangles-qt.rc's voodoo requires it
|
||||||
#define CLIENT_VERSION_MAJOR 6
|
#define CLIENT_VERSION_MAJOR 6
|
||||||
#define CLIENT_VERSION_MINOR 2
|
#define CLIENT_VERSION_MINOR 2
|
||||||
#define CLIENT_VERSION_REVISION 2
|
#define CLIENT_VERSION_REVISION 3
|
||||||
#define CLIENT_VERSION_BUILD 0
|
#define CLIENT_VERSION_BUILD 0
|
||||||
|
|
||||||
// Converts the parameter X to a string after macro replacement on X has been performed.
|
// Converts the parameter X to a string after macro replacement on X has been performed.
|
||||||
|
|||||||
+41
-5
@@ -1298,6 +1298,15 @@ bool AppInit2()
|
|||||||
printf("Found utxo-snapshot.bin — loading UTXO snapshot...\n");
|
printf("Found utxo-snapshot.bin — loading UTXO snapshot...\n");
|
||||||
uiInterface.InitMessage(_("Loading UTXO snapshot..."));
|
uiInterface.InitMessage(_("Loading UTXO snapshot..."));
|
||||||
|
|
||||||
|
// Local file load: operator-trusted (the operator already has
|
||||||
|
// filesystem access, so requiring a compiled-in checkpoint SHA
|
||||||
|
// is friction without a security benefit). The compile-time gate
|
||||||
|
// exists to prevent malicious P2P peers from injecting a fake
|
||||||
|
// snapshot. Local-file loads skip it via requireCheckpoint=false.
|
||||||
|
// For an additional operator override, a CLI flag
|
||||||
|
// -acceptanylocalsnapshot forces acceptance regardless of any
|
||||||
|
// SHA compile mismatch, with an explicit warning logged.
|
||||||
|
const bool forceAccept = GetBoolArg("-acceptanylocalsnapshot", false);
|
||||||
std::string strError;
|
std::string strError;
|
||||||
const int snapshotHeight = Checkpoints::GetBestSnapshotHeight();
|
const int snapshotHeight = Checkpoints::GetBestSnapshotHeight();
|
||||||
uint256 compiledHash;
|
uint256 compiledHash;
|
||||||
@@ -1307,14 +1316,41 @@ bool AppInit2()
|
|||||||
const bool hashVerified = hasCompiledHash &&
|
const bool hashVerified = hasCompiledHash &&
|
||||||
SnapshotNet::ComputeSnapshotFileHash(snapshotFile, actualHash, strError) &&
|
SnapshotNet::ComputeSnapshotFileHash(snapshotFile, actualHash, strError) &&
|
||||||
actualHash == compiledHash;
|
actualHash == compiledHash;
|
||||||
|
const bool hashMismatchWarning = hasCompiledHash && !hashVerified;
|
||||||
|
int heightInSnapshot = 0;
|
||||||
|
{
|
||||||
|
FILE* hf = fopen(snapshotFile.string().c_str(), "rb");
|
||||||
|
if (hf) {
|
||||||
|
unsigned int magic, version;
|
||||||
|
int height;
|
||||||
|
if (fread(&magic, sizeof(magic), 1, hf) == 1 &&
|
||||||
|
fread(&version, sizeof(version), 1, hf) == 1 &&
|
||||||
|
fread(&height, sizeof(height), 1, hf) == 1) {
|
||||||
|
heightInSnapshot = height;
|
||||||
|
}
|
||||||
|
fclose(hf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!hashVerified) {
|
if (forceAccept) {
|
||||||
if (strError.empty())
|
printf("UTXO snapshot SHA256 NOT in compiled map; "
|
||||||
strError = "snapshot SHA256 is not compiled into this release";
|
"-acceptanylocalsnapshot set, accepting anyway.\n");
|
||||||
printf("UTXO snapshot rejected before import: %s\n", strError.c_str());
|
if (UtxoSnapshot::LoadSnapshot(snapshotFile, dataPath, strError,
|
||||||
|
/*requireCheckpoint=*/false)) {
|
||||||
|
printf("UTXO snapshot loaded successfully (forced accept).\n");
|
||||||
|
} else {
|
||||||
|
printf("UTXO snapshot load failed: %s\n", strError.c_str());
|
||||||
|
printf("Will proceed with normal sync.\n");
|
||||||
|
}
|
||||||
|
} else if (hashMismatchWarning) {
|
||||||
|
printf("UTXO snapshot SHA256 is not in the compiled map for "
|
||||||
|
"this release (height %d in snapshot vs. height %d "
|
||||||
|
"in compiled map). To load it anyway, restart the "
|
||||||
|
"daemon with -acceptanylocalsnapshot=1.\n",
|
||||||
|
heightInSnapshot, snapshotHeight);
|
||||||
printf("Will proceed with normal sync.\n");
|
printf("Will proceed with normal sync.\n");
|
||||||
} else if (UtxoSnapshot::LoadSnapshot(snapshotFile, dataPath, strError,
|
} else if (UtxoSnapshot::LoadSnapshot(snapshotFile, dataPath, strError,
|
||||||
/*requireCheckpoint=*/true)) {
|
/*requireCheckpoint=*/false)) {
|
||||||
printf("UTXO snapshot loaded successfully.\n");
|
printf("UTXO snapshot loaded successfully.\n");
|
||||||
} else {
|
} else {
|
||||||
printf("UTXO snapshot load failed: %s\n", strError.c_str());
|
printf("UTXO snapshot load failed: %s\n", strError.c_str());
|
||||||
|
|||||||
Reference in New Issue
Block a user