Skip to content

Commit 601758e

Browse files
bboston7Copilot
andauthored
[CAP-83] Add StellarValue type representing a skipped ledger (stellar#1904)
* [CAP-83] Add StellarValue type representing a skipped ledger * Simple copilot typo / phrasing suggestions Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Clarify "backwards incompatibilities" section * Add mddiffcheck metadata * Clarify that this is a new extension type * originalValue -> proposedValue --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 44f5f5d commit 601758e

2 files changed

Lines changed: 212 additions & 0 deletions

File tree

core/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
| [CAP-0060](cap-0060.md) | Update to Wasmi register machine| Graydon Hoare | Accepted |
115115
| [CAP-0071](cap-0071.md) | Authentication delegation for custom accounts | Dmytro Kozhevin | Draft |
116116
| [CAP-0072](cap-0072.md) | Contract signers for Stellar accounts | Dmytro Kozhevin | Draft |
117+
| [CAP-0083](cap-0083.md) | Add `StellarValue` type representing a skipped ledger | Brett Boston | Draft |
117118

118119
### Rejected Proposals
119120
| Number | Title | Author | Status |

core/cap-0083.md

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
## Preamble
2+
3+
```
4+
CAP: 0083
5+
Title: Add StellarValue type representing a skipped ledger
6+
Working Group:
7+
Owner: Brett Boston <@bboston7>
8+
Authors: Brett Boston <@bboston7>
9+
Consulted: Nicolas Barry <@MonsieurNicolas>, Giuliano Losa <@nano-o>, Marta Lokhova <@marta-lokhova>
10+
Status: Draft
11+
Created: 2026-03-31
12+
Discussion: https://github.com/orgs/stellar/discussions/1865
13+
Protocol version: TBD
14+
```
15+
16+
## Simple Summary
17+
18+
This CAP introduces a new `StellarValue` type to allow validators to explicitly
19+
skip the ledger that is being voted on.
20+
21+
## Working Group
22+
23+
As specified in the preamble.
24+
25+
## Motivation
26+
27+
Providing a mechanism for validators to explicitly vote to skip ledgers allows
28+
them to conduct some SCP voting prior to receiving a transaction set. This will
29+
improve SCP performance, as transaction set dissemination is costly and
30+
validators can safely make initial progress on consensus while waiting for
31+
transaction sets.
32+
33+
If, during the PREPARE phase of balloting, a validator has not received the
34+
transaction set being voted on within a reasonable amount of time, or the
35+
transaction set is invalid, they may vote to skip the current ledger. This
36+
prevents consensus from getting stuck waiting for a transaction set that may
37+
never arrive, as a valid transaction set is required before moving on to the
38+
CONFIRM phase of balloting.
39+
40+
### Goals Alignment
41+
42+
This CAP is aligned with the following Stellar Network Goal:
43+
44+
* The Stellar Network should run at scale and at low cost to all participants of the network.
45+
46+
## Abstract
47+
48+
This CAP introduces a new `StellarValue` extension type `STELLAR_VALUE_SKIP`.
49+
With this change, validators may switch their ballot to a `STELLAR_VALUE_SKIP`
50+
during the PREPARE phase of balloting prior to setting `c`[^1].
51+
`STELLAR_VALUE_SKIP` includes information about the value that a validator was
52+
considering before switching to voting to skip the ledger.
53+
54+
## Specification
55+
56+
### XDR changes
57+
58+
To enable ledger skipping, this CAP proposes the following change to
59+
`Stellar-ledger.x`:
60+
61+
```diff mddiffcheck.base=0a621ec7811db000a60efae5b35f78dee3aa2533
62+
diff --git a/Stellar-ledger.x b/Stellar-ledger.x
63+
index a17036b..667f8e7 100644
64+
--- a/Stellar-ledger.x
65+
+++ b/Stellar-ledger.x
66+
@@ -13,7 +13,8 @@ typedef opaque UpgradeType<128>;
67+
enum StellarValueType
68+
{
69+
STELLAR_VALUE_BASIC = 0,
70+
- STELLAR_VALUE_SIGNED = 1
71+
+ STELLAR_VALUE_SIGNED = 1,
72+
+ STELLAR_VALUE_SKIP = 2
73+
};
74+
75+
struct LedgerCloseValueSignature
76+
@@ -43,6 +44,14 @@ struct StellarValue
77+
void;
78+
case STELLAR_VALUE_SIGNED:
79+
LedgerCloseValueSignature lcValueSignature;
80+
+ case STELLAR_VALUE_SKIP:
81+
+ struct
82+
+ {
83+
+ Hash txSetHash;
84+
+ Hash previousLedgerHash;
85+
+ uint32 previousLedgerVersion;
86+
+ LedgerCloseValueSignature lcValueSignature;
87+
+ } proposedValue;
88+
}
89+
ext;
90+
};
91+
```
92+
93+
94+
With this change, the full `StellarValue` struct becomes:
95+
```xdr
96+
/* StellarValue is the value used by SCP to reach consensus on a given ledger
97+
*/
98+
struct StellarValue
99+
{
100+
Hash txSetHash; // transaction set to apply to previous ledger
101+
TimePoint closeTime; // network close time
102+
103+
// upgrades to apply to the previous ledger (usually empty)
104+
// this is a vector of encoded 'LedgerUpgrade' so that nodes can drop
105+
// unknown steps during consensus if needed.
106+
// see notes below on 'LedgerUpgrade' for more detail
107+
// max size is dictated by number of upgrade types (+ room for future)
108+
UpgradeType upgrades<6>;
109+
110+
// reserved for future use
111+
union switch (StellarValueType v)
112+
{
113+
case STELLAR_VALUE_BASIC:
114+
void;
115+
case STELLAR_VALUE_SIGNED:
116+
LedgerCloseValueSignature lcValueSignature;
117+
case STELLAR_VALUE_SKIP:
118+
struct
119+
{
120+
Hash txSetHash;
121+
Hash previousLedgerHash;
122+
uint32 previousLedgerVersion;
123+
LedgerCloseValueSignature lcValueSignature;
124+
} proposedValue;
125+
}
126+
ext;
127+
};
128+
```
129+
130+
131+
#### XDR Example
132+
TBD
133+
134+
### Semantics
135+
136+
#### Skip Value Representation
137+
138+
When the network votes to skip the ledger, validators will externalize a `StellarValue` with fields set as follows:
139+
140+
* `txSetHash` : Set to `0x0`
141+
* `closeTime` : Set as usual
142+
* `upgrades` : Set as usual
143+
* `ext` : Set to `STELLAR_VALUE_SKIP`
144+
* `proposedValue` : Details about the original `StellarValue` that a quorum of validators decided to skip.
145+
* `proposedValue.txSetHash` : The hash of the transaction set that was insufficiently disseminated or invalid.
146+
* `proposedValue.previousLedgerHash` : The hash of the ledger prior to this one. Used to construct an empty transaction set corresponding to this skip value.
147+
* `proposedValue.previousLedgerVersion` : The ledger version of the previous ledger. Used to construct an empty transaction set corresponding to this skip value.
148+
* `proposedValue.lcValueSignature` : The signature from the original `StellarValue`. Can be used to determine which validator proposed the original `StellarValue`.
149+
150+
#### Skip Value Application
151+
152+
At apply time, ledgers containing a skip value should be treated as ledgers with
153+
empty transaction sets. In every other way, they should be treated as normal
154+
`STELLAR_VALUE_SIGNED` ledgers.
155+
156+
## Design Rationale
157+
158+
We considered a few alternative methods to achieve parallel downloading of transaction sets before landing on this protocol change:
159+
160+
* Rather than skipping a ledger on failure to download a transaction set, we looked into rolling back SCP to an earlier phase. However, this would be a large change to SCP, which was not designed to ever step backwards. We decided it was cleaner, and easier to verify the change if validators instead voted to skip the current ledger.
161+
* We analyzed how far along consensus a validator could safely proceed without a transaction set if there was no skip or rollback mechanism, and decided that the lack of such a mechanism was too limiting. Without some method for validators to agree that a transaction set is unavailable, it is only safe to proceed with early nomination voting.
162+
163+
## Protocol Upgrade Transition
164+
165+
`STELLAR_VALUE_SKIP` values will become valid on the network at the protocol boundary. However, validators will not generate them unless they have enabled parallel transaction set downloading. Parallel transaction set downloading will initially be disabled by default, and we would like to gradually enable it across the validator network.
166+
167+
168+
### Downstream Impact
169+
170+
Downstream consumers of `StellarValue`s may require modification. Specifically, those that reason about `txSetHash` will need to handle the new `0x0` value, and those that reason about `ext` will need to handle the new `STELLAR_VALUE_SKIP` extension.
171+
172+
To help determine if you depend on something that contains a `StellarValue`, transitive dependencies on `StellarValue` are as follows:
173+
```
174+
StellarValue
175+
176+
├──► LedgerHeader.scpValue
177+
│ │
178+
│ └──► LedgerHeaderHistoryEntry.header
179+
│ │
180+
│ ├──► LedgerCloseMetaV0.ledgerHeader
181+
│ ├──► LedgerCloseMetaV1.ledgerHeader
182+
│ └──► LedgerCloseMetaV2.ledgerHeader
183+
│ │
184+
│ └──► LedgerCloseMeta (union)
185+
│ │
186+
│ └──► LedgerCloseMetaBatch.ledgerCloseMetas
187+
188+
└──► StoredDebugTransactionSet.scpValue
189+
```
190+
191+
Downstream consumers of `StellarValue`s should treat skipped ledgers as empty ledgers.
192+
193+
### Backwards Incompatibilities
194+
As detailed in the previous section, downstream consumers of `StellarValue`s may require modification.
195+
196+
### Resource Utilization
197+
We expect this change to increase throughput on validators by expediting consensus. Simulation has shown this to be manageable. However, we will rollout the parallel downloading portion of this change slowly to ensure that real-world performance data matches simulation.
198+
199+
## Security Concerns
200+
This CAP introduces a new method by which malicious validators could negatively impact the network. A malicious validator could introduce bad transaction set hashes, which then force the network to skip a ledger after some delay. However, this attack is mitigated by the following factors:
201+
202+
* The attacker would have to win leader election to propose the bad value. This limits the frequency with which this attack can be pulled off.
203+
* By design, we include the original value that was skipped in the `STELLAR_VALUE_SKIP` struct, including the signature for the value. This enables node operators to easily determine which validators are misbehaving and remove them from their quorum sets.
204+
205+
## Test Cases
206+
TBD
207+
208+
## Implementation
209+
TBD
210+
211+
[^1]: See the [SCP IETF draft](https://www.ietf.org/archive/id/draft-mazieres-dinrg-scp-05.txt) for a complete semantics of `c`

0 commit comments

Comments
 (0)