Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
110 commits
Select commit Hold shift + click to select a range
2d5a0a8
CONFIDENTIAL TRANSACTIONS
aivve May 12, 2026
42e6c35
Fix some CT errors
aivve May 12, 2026
22a9078
Honor topHeight when explicitly set in tests
aivve May 12, 2026
5448bd3
Per-member ring references
aivve May 12, 2026
f891ba3
Active decoy mixing
aivve May 12, 2026
8405d6d
mixed-bucket sampling
aivve May 12, 2026
968f94a
Worst-case perf benchmark + serializer fuzzing tests
aivve May 12, 2026
9d34342
Drop limits
aivve May 13, 2026
7959e38
Batched GK proofs verify ~1.32× speedup
aivve May 13, 2026
93209b2
Pippenger MSM speedup 1.5x
aivve May 13, 2026
7cd1a19
Precomputing the Denomination Ring
aivve May 13, 2026
8ea8eac
Bake the table as literal hex bytes in source
aivve May 13, 2026
16cab10
Increase max inputs and outputs for CT
aivve May 13, 2026
a88d63e
Consensus-track CT pool liability + reserve block v7
aivve May 14, 2026
af09407
Keep v1 plain txs valid post-fork + simplewallet --legacy-tx flag opt…
aivve May 14, 2026
0532798
Add --legacy-tx opt-out to GreenWallet and walletd
aivve May 14, 2026
598bb55
Cap unlock_time at v6 and unfreeze mistakenly locked outputs
aivve May 14, 2026
f96d22f
Merge branch 'master' into dev/ct
aivve May 14, 2026
f922d6b
Replace MLSAG with Triptych
aivve May 17, 2026
cef146f
Merge branch 'master' into dev/ct
aivve May 17, 2026
9ac87e5
Change header copy in BuiltinExplorer
aivve May 17, 2026
a20067d
Route 0.01-aligned non-CN-canonical inputs through v2 KeyInput
aivve May 17, 2026
22127f4
Drop "unmixable" surface from wallet UIs
aivve May 17, 2026
ec25109
Drop ring-size-1, harden batch verify
aivve May 18, 2026
ef5e74f
Drop ring-size-1 mapping from built-in explorer
aivve May 18, 2026
10efd16
Stop spamming about dust on each sync event
aivve May 18, 2026
bb50ad0
Bump CT_MAX_INPUTS from 128 to 512
aivve May 18, 2026
6dc2030
Built-in explorer: 2-row home header with account / CT stats
aivve May 18, 2026
d433521
Just swap total and confidential supply
aivve May 18, 2026
c569ba4
Unify per-input authorization as a variant array
aivve May 19, 2026
cb13a8b
Handle LMDB map full during rollback
aivve May 19, 2026
59e2900
Skip ConfidentialOutputs in legacy-tx input selection
aivve May 19, 2026
fa40746
Harden Triptych batched verifier and crypto RNG
aivve May 19, 2026
33d0206
Harden CT consensus path and fix batch determinism
aivve May 20, 2026
ff772a1
Harden CT validation even more and close defense-in-depth gaps
aivve May 20, 2026
eab29d4
Add the v1 empty-inputs/outputs check
aivve May 20, 2026
1bb6fe7
Fix tests; wrap per-block writes in nested LMDB txns; fix random-out …
aivve May 21, 2026
e4cff72
CT: reject nonzero ConfidentialOutput.amount in block path
aivve May 21, 2026
d664578
Merge branch 'master' into dev/ct
aivve May 21, 2026
eda5b7e
Snapshot alt-block txs so CT reorg is self-contained
aivve May 22, 2026
9928b71
Extract checkTransactionConsensusShape; dedupe Core/Blockchain valida…
aivve May 22, 2026
7c21707
Add reorg-with-pool-eviction regression test; remove dead code
aivve May 22, 2026
897128c
Fix alt-chain transaction snapshots
aivve May 23, 2026
19554e0
Honor dynamic upgradeHeightV6 in CT activation and unlock-time gates …
aivve May 24, 2026
5ac0d0d
Wire yespower PoW into test_generator for V5+ blocks
aivve May 24, 2026
7a3128e
Remove strict-aliasing UB in gk_verify_batch denomination loop
aivve May 24, 2026
6b1864c
Restrict CT structural-validation fast path to hardcoded checkpoints
aivve May 24, 2026
881a1e2
Require signed records for DNS checkpoints
aivve May 24, 2026
b93f580
Fix tests
aivve May 24, 2026
aa5721e
Close few CT-checkpoint trust gaps
aivve May 24, 2026
3238cb5
Treat signed DNS checkpoints as hardcoded for CT validation routing
aivve May 24, 2026
7b64885
Documented on checkpoints
aivve May 24, 2026
9763c28
Relax CT unlockTime=0 rule and document Karbo CT threat model
aivve May 24, 2026
aa54868
Fix CT unlockTime wire binding and zero excess scalar in kernel signing
aivve May 24, 2026
0e1f3b7
Cleanup stale CT unlock_time comment + regression test
aivve May 24, 2026
eba27a3
Patched --seed-node hostname support
aivve May 24, 2026
5063a48
Fix Difficulty 5
aivve May 25, 2026
149ffe9
Refactor difficulty reset logic for testnet handling
aivve May 25, 2026
dab3429
Refactor nextDifficultyV5 function for readability
aivve May 25, 2026
889e179
Fix logger output for nextDifficultyV5
aivve May 25, 2026
5b6115e
Refactor difficulty calculation logic in Currency.cpp
aivve May 25, 2026
bdafe2c
Update testnet upgrade heights for V6 and V7
aivve May 25, 2026
828017b
Update upgrade height for V5 to 380
aivve May 25, 2026
76ead27
Back-fill the ring when CT mixing falls short and fix CLI UX with uni…
aivve May 27, 2026
d854434
Fix large mined amounts sending
aivve May 27, 2026
5a79a62
Fix compile error
aivve May 28, 2026
f2002a8
Spendable-vs-total split (mainly for legacy-tx mode)
aivve May 28, 2026
0626cc5
Policy to purge unshielded dust
aivve May 28, 2026
63f86bf
Auto dust sweep with sending
aivve May 28, 2026
07885e6
Don't override explicit input selection
aivve May 28, 2026
3a2cc4a
Automatic dust sweeping only with -m 0
aivve May 28, 2026
7dc6d25
Sending with adaptive dust mixing
aivve May 28, 2026
63db7f3
Adaptive ring size for dust
aivve May 28, 2026
4899928
Fix fee display
aivve May 28, 2026
e383823
Merge branch 'dev/ct' of https://github.com/Karbovanets/karbowanec in…
aivve May 28, 2026
eb319a0
Adapt transparent input rings to available decoys in CT
aivve May 28, 2026
d605cd0
Merge branch 'dev/ct' of https://github.com/Karbovanets/karbowanec in…
aivve May 28, 2026
f13d238
Update design doc
aivve May 29, 2026
5e55ea7
Admit transaction version 3 (CT->CN unshield)
aivve May 29, 2026
e7c0b46
Allow mixed plain+confidential outputs in v3 (CT->CN unshield)
aivve May 30, 2026
e11aa0c
Verify v3 mixed-output serialization round-trip
aivve May 30, 2026
f7a68d0
Add plain-output term to v3 balance kernel
aivve May 30, 2026
cfa5189
Verify v3 CT pool delta accounting across shield directions
aivve May 30, 2026
e848b7b
Build v3 mixed outputs in confidential transaction builder
aivve May 30, 2026
8db6f0f
Add unshield intent to WalletGreen transaction core
aivve May 30, 2026
60db40c
Add GreenWallet unshield command with reveal-amount confirm
aivve May 30, 2026
a67291c
Add walletd unshield JSON-RPC method
aivve May 30, 2026
6fd025e
Add simplewallet/WalletRpcServer unshield via WalletLegacy v3 path
aivve May 30, 2026
486aa6d
Scan v3 unshield fee from prefix like CT (TransfersContainer)
aivve May 31, 2026
25f5e27
Add multi-plain-output unshield balance vectors
aivve May 31, 2026
fbb616b
Render v3 unshield in builtin explorer (CT kernel/proofs, input labels)
aivve May 31, 2026
a8460ca
Add atomic-swap derivation test vector
aivve May 31, 2026
df44059
Drop internal session-plan references from test comments
aivve May 31, 2026
4e0f7bd
Floor testnet next-difficulty at 1 in V3/V4 to avoid difficulty overhead
aivve May 31, 2026
a62beae
Clamp nextDifficultyV4 LWMA window to available blocks at low height
aivve May 31, 2026
e7b5a40
Add v3 chain-integration harness: mine testnet to v6 via real core
aivve May 31, 2026
c1124ce
Fix v3 unshield validation, output scanning, and fee accounting
aivve May 31, 2026
47ea66c
Propagate WalletGreen relay errors correctly
aivve May 31, 2026
48f2dcf
Exercise real v2 CT shield + v3 unshield txs through mempool in integ…
aivve May 31, 2026
76ff1ba
Add confidential-input spend, real unshield, and double-spend vectors…
aivve May 31, 2026
e8bc033
Realigns random-outs responses by amount before adapting rings / prep…
aivve Jun 1, 2026
3248092
Fix prepare raw tx
aivve Jun 1, 2026
e725ed3
Update CT-baseline wallet tests: ring-size cap + fee underflow guard
aivve Jun 2, 2026
f6da568
Merge stats from master, add confidentialSupply
aivve Jun 2, 2026
e40380d
Update getstatsbyheights, rename already_generated_coins to emitted_s…
aivve Jun 2, 2026
1d7026a
Merge branch 'dev/unshield' of https://github.com/Karbovanets/karbowa…
aivve Jun 2, 2026
49279a0
Add v3 tx support to RPC and Explorer
aivve Jun 2, 2026
8a92150
Add forged verify
aivve Jun 3, 2026
f9a1ca6
Bind CT key image to spend key; confidential-only rings
aivve Jun 3, 2026
45c1c3c
Сleanup stale comments/docs
aivve Jun 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,5 +120,16 @@ make SimpleWallet

By default it will compile portable binary, to build optimized for your CPU, run Cmake with flag `-DARCH=native`.

### Checkpointed Sync and CT Validation

By default the daemon uses built-in checkpoints and signed DNS checkpoints to
speed up historical sync. In the trusted checkpoint zone, a block still has to
match its checkpoint hash, but the daemon may skip expensive historical checks,
including full CT proof validation and local PoW for checkpointed blocks.

Run with `--without-checkpoints` to sync without checkpoint shortcuts and
perform full local validation from genesis. See
`docs/CT_CHECKPOINT_TRUST.md` for the CT checkpoint trust model and checkpoint
publishing policy.


371 changes: 371 additions & 0 deletions docs/CT-DESIGN.md

Large diffs are not rendered by default.

141 changes: 141 additions & 0 deletions docs/CT-ROUTE1-KEYIMAGE-FIX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# CT Route 1 — Bound Linking Tag (key-image soundness fix)

## Why

The Triptych spend proof as shipped does **not** bind the key image to the
spend key. The verifier runs three independent ring checks; the linking (U)
track uses an independent response `f_U` with witness `1/x` that is never
cross-checked against the spend response `f_P` (witness `x`). Result: for an
owned confidential output `P_l = x·G`, a prover can emit **any** key image
`I = c·Hp(P_l)` for a chosen `c ≠ x` (set `f_U = (1/c)·ξⁿ − Σσ_U[m]ξᵐ`), and
both `triptych_verify` and `triptych_verify_batch` accept it. Distinct `c` ⇒
distinct image ⇒ the same confidential output can be spent repeatedly without
colliding in the `spent_keys` set.

Confirmed empirically: `tests/forge_ki_poc.cpp` builds a forged proof against
the production `Crypto.lib` and both verifiers accept it.

The pool-liability counter (`confidential_supply`) caps *net visible* coin
extraction at total-shielded, so this is not unlimited mint-to-cash — but it is
a full **confidential double-spend** (pay multiple parties the same shielded
coin; over-subscribe the pool). Not shippable.

## Decision: Route 1 (fixed-generator linking tag)

Replace the per-key CryptoNote image `I = x·Hp(P)` (for CT inputs only) with a
**fixed-generator** image `J = x·U`, and prove it by **reusing the spend
response `f_P`** instead of an independent inverse witness. This is the
published Triptych linking construction; the binding is automatic because one
witness `x` drives both the spend equation (base `G`) and the linking equation
(base `U`).

Trade-off (accepted, consistent with the threat model "hide amounts, not the
graph"): CT rings become **confidential-output-only**. A transparent output is
spendable only via a legacy `KeyInput` (image `x·Hp(P)`); a confidential output
only via a `ConfidentialInput` (image `x·U`). No output ever has two image
formats, so a single `spent_keys` DB stays collision-correct. Transparent
ring members were weak decoys anyway (an analyst discounts them) and become
provably worthless under Route 1, so they are dropped.

This is a **hard fork** (proof wire format + key-image derivation change). CT is
testnet-only today (`CT_FORK_HEIGHT = UPGRADE_HEIGHT_V6`; testnet v6 = 400),
so fix before any mainnet activation. Old-format CT txs will not validate under
the new rules — clean break at the fork.

## Construction (authoritative)

Generators (all NUMS, pairwise-unknown DL):
- `G` — Ed25519 base point.
- `H` — Pedersen value generator = `hash_to_point("CN-amount-generator")` (existing).
- `U` — **new** linking-tag generator = `hash_to_point("Karbo-CT-keyimage-generator-v1")`,
cofactor-cleared to the prime-order subgroup. dlog unknown wrt `G` and `H`.

Per CT input, public statement (ring size `N ∈ {4,8,16}`, `n = log2 N`):
- Ring `(P_k, C_k)`, k=0..N-1 — all **confidential outputs** (sentinel bucket).
- Pseudo-output commitment `C' = v·H + r'·G`.
- Key image / linking tag `J = x·U`.

Witnesses: index `l`, `x` (with `P_l = x·G`), `z = r_real − r_pseudo`
(with `C_l − C' = z·G`).

GK bit-decomposition (unchanged): `I_bits[j], A[j], B[j]` and responses
`z[j], za[j], zb[j]` prove each index bit ∈ {0,1}. Selector polynomial
`p_k(X)`; key identity `Σ_k p_k(X) = Xⁿ`.

Three tracks:

1. **P-ring** (spend): `Q_P[m] = ρ_P[m]·G + Σ_k p_{k,m}·P_k`;
`f_P = x·ξⁿ − Σ_m ρ_P[m]·ξᵐ`.
Verify `Σ_k p_k(ξ)·P_k = f_P·G + Σ_{m<n} ξᵐ·Q_P[m]`. ⇒ `P_l = x·G`.

2. **M-ring** (amount balance, unchanged): `Q_M[m] = ρ_M[m]·G + Σ_k p_{k,m}·M_k`,
`M_k = C_k − C'`; `f_M = z·ξⁿ − Σ_m ρ_M[m]·ξᵐ`.
Verify `Σ_k p_k(ξ)·M_k = f_M·G + Σ_{m<n} ξᵐ·Q_M[m]`. ⇒ `C_l − C' = z·G`
(pseudo commits to the real value — no amount inflation).

3. **Linking** (replaces the U-ring): `Q_J[m] = ρ_P[m]·U` ← **reuses ρ_P[m]**.
**No new response — reuses `f_P`.**
Verify `ξⁿ·J = f_P·U + Σ_{m<n} ξᵐ·Q_J[m]`. ⇒ `J = x·U`.

Soundness of the binding (special-soundness extraction over n+1 challenges):
`f_P = x·ξⁿ − Σρ_P[m]ξᵐ` is forced by the P-ring (so its `ξⁿ` coefficient is
`x`). Substituting into the linking equation gives, as a polynomial identity in
`ξ`: `ξⁿ·J = x·ξⁿ·U − Σρ_P[m]ξᵐ·U + Σξᵐ·Q_J[m]`. The `ξⁿ` coefficient forces
`J = x·U`; `Q_J` only spans `m<n`, so the prover cannot inject a `ξⁿ` term to
move `J`. A forged `J = c·U`, `c≠x`, contradicts the extracted identity ⇒
rejected. ZK preserved: `ρ_P[m]` random ⇒ `Q_P[m]`, `Q_J[m]` uniform
(Chaum–Pedersen-style shared blinding).

Fiat-Shamir transcript ξ (domain `"Triptych-KarboCT-v2"` — bump from v1):
`domain ‖ message ‖ ring_size ‖ {P_k} ‖ {C_k} ‖ C' ‖ J ‖ {I_bits} ‖ {A} ‖ {B}
‖ {Q_P} ‖ {Q_M} ‖ {Q_J}`. (Replace `Q_U` with `Q_J`; drop nothing else.)

## Wire / struct changes

`TriptychSignature`: rename `Q_U → Q_J` (same slot, `n` points); **remove `f_U`**.
New body per CT input: `n` header + 6·n points (I_bits,A,B,Q_P,Q_M,Q_J) +
(3n+2) scalars (z,za,zb,f_P,f_M). One scalar smaller than before.

## Implementation checklist (consensus-critical) — LANDED

- [x] `crypto`: added `U` generator (`keyimage_generator_U`) + `triptych_key_image(x) → J = x·U` (canonical helper).
- [x] `crypto/triptych.{h,cpp}`: struct `Q_U→Q_J`, dropped `f_U`; `triptych_sign`
(J=x·U, Q_J=ρ_P·U, reuse f_P, dropped σ_U/U_k=Hp(P_k)/sc_invert); `triptych_verify`
(linking eq); `triptych_collect_claims`/batch (linking equation terms
`{ξⁿ,J} − {f_P,U} − Σ{ξᵐ,Q_J[m]}`); transcript domain `Triptych-KarboCT-v2`.
- [x] `include/CryptoNote.h` + `CryptoNoteSerialization.cpp` `CTInputSignature`: dropped `f_U`, `Q_U→Q_J` (binary + JSON).
- [x] `Wallet/TransactionBuilder.cpp`: CT input key image = `x·U` via `triptych_key_image`; KeyInput stays `x·Hp(P)`.
- [x] `Blockchain.cpp checkConfidentialTransaction`: **confidential-only rings** —
every ring member must resolve to a `ConfidentialOutput` in the sentinel
bucket; transparent-`KeyOutput` ring-member branch removed.
- [x] `TransactionValidation.cpp`: ConfidentialInput ring members `amount == CT_CONFIDENTIAL_OUTPUT_AMOUNT`.
- [x] `Core.cpp` shape check: `Q_U→Q_J`.
- [x] `Rpc/BuiltinExplorer.cpp`: `Q_U→Q_J`, dropped `f_U`.
- [x] Tests: `test_triptych.cpp`, `test_mixed_v2_roundtrip.cpp`, `fuzz_ct_serializer.cpp`,
`CoreTests/CryptoNoteBoostSerialization.h` updated; `forge_ki_poc.cpp` rewritten + registered
as CTest target `ForgeKeyImagePoC`.

## Verification gates — ALL PASSING

1. `forge_ki_poc` (J=x·U): honest image ACCEPTS; 8 forged `J=c·U`, `c≠x` →
**rejected** by both `triptych_verify` and `triptych_verify_batch`. ✔
2. `triptych_tests` 57/57 (honest all sizes/indices, key-image consistency,
hidden-inflation rejected, tampering, batch). ✔
`gk_proof_tests` 82/82, `tx_balance_tests` 27/27, `ct_integration_tests` 53/53. ✔
3. `V3ChainIntegration` 1/1: v2 shield → v3 unshield → CT→CT (ring 4) →
confidential-input unshield → **cross-version double-spend rejected on the
shared key-image set**. ✔ `CTFuzz`: 200k mutations, no crash. ✔
4. Full solution builds clean (daemon, simplewallet, greenwallet, walletd, all tests).

## Still open (follow-ups, non-blocking)

- External cryptographer sign-off on the linking construction before mainnet.
- Wallet decoy-selection policy for confidential-only rings (ring-size ramp vs
pool depth right after CT activation).
- Testnet reset / fork-height bump (proof wire format changed — old CT txs won't validate).

## Notes for the PQ family (v4)

The GK one-of-many *membership* engine is reusable. The linking tag is **not**
— `x·U` has no clean lattice analogue. Treat the PQ linking tag as a separate,
independently-reviewed design; do not assume this binding trick transfers.
53 changes: 53 additions & 0 deletions docs/CT_CHECKPOINT_TRUST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# CT Checkpoint Trust Model

Karbo supports checkpointed sync to avoid repeating expensive historical
validation for blocks that the operator chooses to trust. This matters more
after CT because full validation includes Triptych proofs, GK proofs, CT
balance kernels, ring resolution, and related amount-accounting checks.

## Default Sync

By default the daemon loads built-in checkpoints and signed DNS checkpoints.
An operator can also load a checkpoint file with `--load-checkpoints`.

A checkpoint is trusted when it comes from one of these sources:

- the checkpoint table compiled into the binary
- a checkpoint file explicitly supplied by the operator
- a DNS checkpoint whose signature verifies against `DNS_CHECKPOINT_SIGNERS`

Unsigned or malformed DNS checkpoint records are rejected before they become
checkpoints.

Inside the trusted checkpoint zone, the daemon still verifies that the block
hash matches the checkpoint anchor. It also continues to run structural CT
sanity checks such as version and shape checks, subgroup checks, key-image
domain checks, canonical ordering checks, and double-spend checks.

The daemon may skip expensive historical validation that the checkpoint
authorizes, including local PoW for checkpointed blocks and full CT proof
verification. This is the intended checkpoint tradeoff: faster sync in exchange
for trusting the checkpoint source for already-checkpointed history.

## Full Local Validation

Operators who do not want to trust checkpoints should start the daemon with:

```text
--without-checkpoints
```

That mode does not seed the checkpoint table. Historical blocks are validated
locally instead of being routed through checkpoint shortcuts.

## Publishing Policy

Do not publish a built-in, file, or signed DNS checkpoint until the block has
already been fully validated by a node that was not relying on a checkpoint for
that block. For CT-era blocks, that full validation must include the Triptych,
GK, balance-kernel, ring-resolution, key-image, and supply-accounting checks.

Treat checkpoint signing keys as consensus-sensitive infrastructure. A bad
checkpoint can cause default-syncing nodes to accept the signer's assertion for
historical data until operators resync without checkpoints or upgrade to a
release that removes or supersedes the checkpoint.
36 changes: 33 additions & 3 deletions include/BlockchainExplorerData.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,20 @@ struct KeyInputDetails {
std::vector<TransactionOutputReferenceDetails> outputs;
};

typedef boost::variant<BaseInputDetails, KeyInputDetails> transactionInputDetails2;
// Confidential (CT) input detail: amount is hidden, but the ring layout,
// pseudo-commitment and key image are public and useful for explorers.
// ringMembers carries the per-member (amount, outputIndex) tuples needed
// to render mixed transparent/confidential rings; outputs[] holds the
// matching resolved (txHash, outputIndex) pairs in the same order.
struct ConfidentialInputDetails {
Crypto::KeyImage keyImage;
Crypto::EllipticCurvePoint pseudoCommitment;
uint64_t mixin;
std::vector<RingMemberRef> ringMembers;
std::vector<TransactionOutputReferenceDetails> outputs;
};

typedef boost::variant<BaseInputDetails, KeyInputDetails, ConfidentialInputDetails> transactionInputDetails2;

struct TransactionExtraDetails2 {
std::vector<size_t> padding;
Expand All @@ -114,7 +127,8 @@ struct TransactionDetails {
uint64_t fee = 0;
uint64_t totalInputsAmount = 0;
uint64_t totalOutputsAmount = 0;
uint64_t mixin = 0;
uint64_t mixin = 0; // max ring size across inputs (legacy field)
uint64_t minMixin = 0; // min ring size across inputs (CT rings must be a supported power of two: 4, 8, or 16)
uint64_t unlockTime = 0;
uint64_t timestamp = 0;
uint8_t version = 0;
Expand All @@ -124,9 +138,19 @@ struct TransactionDetails {
Crypto::Hash blockHash;
uint32_t blockHeight = 0;
TransactionExtraDetails2 extra;
std::vector<std::vector<Crypto::Signature>> signatures;
// Per-input authorization, parallel to inputs:
// BaseInput → boost::blank
// KeyInput → std::vector<Crypto::Signature>
// ConfidentialInput → CTInputSignature (Triptych spend proof)
std::vector<InputSignatures> signatures;
std::vector<transactionInputDetails2> inputs;
std::vector<transactionOutputDetails2> outputs;

// CT-family proof body. Empty / value-initialized for non-CT transactions.
// In v3 unshield, ctProofs[i] corresponds to the i-th confidential output,
// not necessarily outputs[i] because transparent payout outputs have no GK proof.
std::vector<CTOutputProof> ctProofs; // per-confidential-output GK denomination membership
TransactionKernel kernel; // balance-equation excess + Schnorr
};

struct BlockDetails {
Expand All @@ -147,6 +171,12 @@ struct BlockDetails {
uint64_t blockSize = 0;
uint64_t transactionsCumulativeSize = 0;
uint64_t alreadyGeneratedCoins = 0;
// Consensus-tracked: total visible value currently locked inside the ECC CT
// pool at this block height. See Blockchain::getConfidentialSupply.
uint64_t confidentialSupply = 0;
// Consensus-tracked: total visible value held by PQ-owned plain outputs.
// Stubbed at 0 today; will become non-zero once PQ-plain activates.
uint64_t pqPlainSupply = 0;
uint64_t alreadyGeneratedTransactions = 0;
uint64_t sizeMedian = 0;
uint64_t effectiveSizeMedian = 0;
Expand Down
Loading
Loading