CAP: 0034
Title: Preserve Transaction-Set/Close-Time Affinity During Nomination
Authors: Terence Rokop, Nicolas Barry
Status: Implemented
Created: 2020-07-06
Discussion: https://github.com/stellar/stellar-protocol/issues/622
Protocol version: 14
Make the nomination protocol select the close time from the single candidate
whose transaction set it selects (rather than the current protocol's selection
of the maximum close time of all candidates), and preserve the signature of the
chosen <close time, transaction set>
pair.
The most severe problem addressed by the CAP is a race condition which means
that smart contracts can not, with the current protocol, safely be written as
chains of dependent transactions with incrementing sequence numbers, because
there is no way for a client to guarantee that a transaction will succeed if it
consumes a sequence number. There is always a possibility that it will return
txTOO_LATE
. But returning txTOO_LATE
while consuming a sequence number
(and being charged a fee) violates our
API documentation,
which states that "If the transaction is invalid, it will be immediately
rejected by stellar-core based on the validity rules of a transaction, the
account’s sequence number will not be incremented, and no fee will be consumed
from the source account", where the referenced
"validity rules of a transaction"
include "The transaction must be submitted within the set time bounds of the
transaction, otherwise it will be considered invalid".
There may therefore be smart contracts which are structured this way, and are
allowed to be structured this way according to our published API, yet are
vulnerable to inconsistencies because of this race.
A less catastrophic problem, but an inefficiency, is that externalizing
transaction sets that contain significant numbers of transactions that are
doomed to return txTOO_LATE
during ledger close might mean that we're
choosing sets that we would have not have chosen over other available
candidates if we had taken into account that those transactions were doomed.
More cosmetically, it might also come across as unfair, or at least
counterintuitive, considering that getting into a transaction set is what a
client pays a fee for, that the occasional transaction might be charged a fee
despite being rejected for not having made it into a transaction set in time.
Although this race is different from the perspective of stellar-core from the
usual case of txTOO_LATE
in which the transaction is discovered to have
expired before being accepted into the transaction set, the race looks the same
from the client's perspective as any other txTOO_LATE
-- except that when the
race is the cause, the client is, inexplicably from its perspective, charged a
fee.
Closing the race that leads to a transaction returning txTOO_LATE
while being
charged a fee and consuming a sequence number may therefore be viewed as having
desirable effects on both good-faith transactions and bad-faith (spam)
transactions:
-
Good-faith transactions should not be charged a fee without being included in a ledger, and should certainly not be subject to potential inconsistencies when part of smart contracts that depend upon sequence numbers to manage dependencies.
-
Bad-faith transactions should not be allowed into fill up ledgers, starving out good-faith transactions. This CAP ensures that consensus gets the opportunity to select transaction sets from among transactions that would be guaranteed not to return
txTOO_LATE
if they were externalized, so ledgers would only be filled by transactions that could actually be applied.
This CAP is aligned with the following Stellar Network Goals:
-
The Stellar Network should be secure and reliable.
-
The Stellar Network should run at scale and at low cost to all users.
It also aligns with the following Stellar Network Value:
- The protocol should bias toward simplicity.
Currently, the nomination protocol produces, from a set of candidate
StellarValue
s, a nominated StellarValue
comprising the composited
transaction set (as selected by a deterministic heuristic which chooses
one particular input set and favors larger sets), the maximum closeTime
of any
candidate, and a set of "maximal" ledger upgrades
from all candidates.
We propose to change the protocol to take the closeTime
from the same
candidate StellarValue
as the chosen transaction set (the heuristic which
decides which transaction set to choose does not change; nor does the method of
generating upgrades
). The protocol would then validate all transaction sets
against their associated closeTime
s, and could use SIGNED
StellarValue
s
throughout the ballot protocol as well as the nomination protocol.
The effect is that all trimming and validating of transaction sets during the nomination and ballot protocols use the exact same conditions as the validation of transactions does during ledger close. (Today, they differ: the nomination and ballot protocols use the last ledger close time, whereas ledger close uses the new ledger close time. This CAP allows this precise alignment because it allows the nomination and ballot protocols to predict exactly what the next ledger close time will be if the transaction set that they are validating is ultimately externalized.)
In particular, this affects how soon the core notices when transactions expire.
There are no changes to any XDR in this CAP. The treatment of the closeTime
in the StellarValue
XDR in some code paths changes, as does the use of
SIGNED
StellarValue
s in some places where BASIC
ones are currently used,
but the XDR itself does not change.
This CAP proposes to change the compositing function, which chooses a
StellarValue
to start the ballot protocol on, to remove the current combining
of closetimes and simply select the one from the same StellarValue
as the
selected transaction set. (This CAP proposes to preserve the existing selection
heuristic for "composited transaction set" unchanged.)
This CAP also proposes to trim and validate transaction sets in StellarValue
s
(in all places where such trimming or validating is currently done) against the
closeTime
in the same StellarValue
. The closeTime
affects whether a
transaction with an upper time bound (maxTime
) returns txTOO_LATE
, and
whether a transaction with a lower time bound (minTime
) returns txTOO_EARLY
.
Those are therefore the two transaction-validity tests which are affected by
the change in which closeTime
is used to validate transactions.
This CAP also proposes to make the nomination protocol produce a signed value (currently we nominate an unsigned, or "basic", value, because, as a combination of candidate values, it may not be equal to any one candidate value for which we have a signature). It does not propose any specific use of that signature yet, but preserving the signature as part of the same protocol change that allows it to be preserved will allow us to use it in the future if we discover a way to do so.
As with any protocol change, the new code must remember and maintain older protocols' behavior, and continue to use old behavior until after the network externalizes the ledger upgrade to the new protocol, through consensus.
The changes in this CAP build upon changes already made (without a CAP, since they were not protocol changes, but changes to the heuristics that a node uses to decide which transactions to flood and which to include in its first nominated transaction set in a new ledger) in PR 2608. Those changes already reduce the potential network burden of flooding transactions that appear likely to expire before getting into transaction sets, and they introduce some interfaces into the code which the code for this CAP can naturally re-use.
Therefore, we present the semantics in three stages: the behavior as released, the latest unreleased behavior (which contains heuristic but no protocol changes, and therefore involved no CAP), and the behavior as proposed in this CAP. Bold text indicates a semantic change from the previous stage. The proposal in this CAP embodies the bold semantics in the last column only; the bold semantics in the middle column are for context.
Index (for later reference) | Decision point | Released behavior | Latest unreleased behavior (PR 2608) | CAP behavior |
---|---|---|---|---|
1 | Which transactions to flood? | Valid with respect to last ledger close | Valid with respect to last ledger close; unexpired with respect to estimate of next ledger close | Valid with respect to last ledger close; unexpired with respect to estimate of next ledger close |
2 | Which time bounds to require for transactions to be included (not trimmed) in the StellarValue a node votes to nominate? |
Valid with respect to last ledger close | Valid with respect to last ledger close; unexpired with respect to estimate of next ledger close | Valid with respect to closeTime to nominate in same StellarValue |
3 | Which close time to validate transaction sets against in nomination and ballot protocols? | Last ledger close time | Last ledger close time | closeTime in same StellarValue as transaction set |
4 | Which close time to produce in composite value? | maximum of all candidates' closeTime s |
maximum of all candidates' closeTime s |
closeTime in same StellarValue as chosen ("composited") transaction set |
5 | Expect BASIC or SIGNED StellarValue in a composite value to be used in the ballot protocol? |
BASIC |
BASIC |
SIGNED |
It has seemed from the beginning that the problem could be addressed only through a CAP: it is a question of what relationships to maintain among the payment of fees, the consumption of sequence numbers, and the validity of transactions, that also leads to a question of what value to nominate given a set of candidates, and all of those questions must be answered by the Core through consensus.
-
The proposal prevents the race that motivated the CAP; it ensures in all cases that a transaction that returns
txTOO_LATE
does not consume a sequence number and does not pay a fee. This is ensured because before a transaction set gets to the point of having its transaction fees paid (which happens when a ledger is closing), we composite the candidate<txSet,closeTime>
pairs into one, and with the CAP behavior we do so by simply selecting one candidate. And every candidate has by the time of compositing been validated, including against the new condition that it contains no transactions that are expired with respect to itscloseTime
. -
The proposal prevents an ill-behaved validator from intentionally triggering the race that motivated the CAP through what we shall call "maximum
closeTime
injection": the ill-behaved validator could previously try to force transactions in transaction sets proposed by other nodes to fail during ledger close by proposing as large acloseTime
as allowed (the maximum time slip is currently one minute). -
This proposal refines PR 2608's trimming of transactions prior to initial nomination by changing the next-ledger-
closeTime
estimate (which PR2608 itself had changed from last-ledger-closeTime
) tocloseTime
-within-StellarValue
. Given this CAP's semantics, we know at this point that thatcloseTime
is the exact one that will be chosen as the ledger close time if the transaction set is ultimately externalized, so we can trim precisely the most efficient set of transactions: we trim all of those which would have later returnedtxTOO_LATE
if the transaction set were ultimately externalized, and we are guaranteed that none of those which survives trimming will returntxTOO_LATE
if the transaction set is ultimately externalized. -
This CAP in general makes changes to transaction set composition and validity in the earliest protocol phases possible, making use of knowledge as soon as we have it. The previous point is an example -- we trim a transaction set prior to first nomination precisely when we decide on which
closeTime
to nominate in the sameStellarValue
with it, which also tells us precisely which transactions we may as well trim because they'll be expired at ledger close time if thatStellarValue
is ultimately externalized. The change in the validation of transaction sets in the nomination and ballot protocols is a similar example; we can do more accurate validation than we could before this CAP, when all we could validate against was the last ledger close time. -
This CAP makes the
closeTime
-related transaction validity checks (the tests fortxTOO_EARLY
andtxTOO_LATE
) throughout consensus exactly equivalent to those used during ledger close. Previously, the tests used during consensus (which this CAP changes to align with those used during ledger close) were weaker than the tests used during ledger close with respect tomaxTime
/txTOO_LATE
(the consensus checks could admit transactions which, if they were ultimately externalized, ledger close would later reject withtxTOO_LATE
), and stronger than the tests used during ledger close with respect tominTime
/txTOO_EARLY
(the consensus checks could reject transactions withtxTOO_EARLY
which, had they been allowed and ultimately externalized, would not have been rejected withtxTOO_EARLY
during ledger close). -
This CAP, in both the change it proposes to protocol semantics and the changes it would induce in the code structure, facilitates the option to perform a follow-on change to the work done in PR 2608 which would further refine our heuristic for choosing which transactions to flood by allowing some transactions to be flooded which would be
txTOO_EARLY
if the next ledger were to close immediately, but which we estimate will no longer betxTOO_EARLY
by the time the next ledger actually does close. (That would not introduce any race analogous to the one that this CAP fixes with respect totxTOO_LATE
, because the nomination and ballot protocols would still discover that a transaction would be invalid withtxTOO_EARLY
before it reached the point of being in a closing ledger and therefore failing validation while nevertheless consuming a sequence number and being charged a fee.) -
This CAP has had a modest "test" in that it is the third proposal that we have considered, and appears not to suffer from any of the weaknesses which led us to reject the first two; see "Rejected alternatives" below for details.
With the current protocol, the following sequence of events can occur:
-
A smart-contract client submits a series of transactions
T1
,T2
withT2
's sequence number one greater thanT1
's.T2
is intended have its operations applied if and only ifT1
's are applied first; the smart contract is depending uponT2
having the wrong sequence number ifT1
's operations are not applied (in which case the smart contract expects thatT1
will not have consumed a sequence number). The smart contract sets an expiration time onT1
(as our documentation "highly advises" that clients do). -
The ledger happens first to have capacity to accept
T1
into a transaction set betweenT1
's expiration time and the time at which it will turn out (of course the network can not foresee that this will eventually be the case) that the next ledger will close. -
T1
happens at that point to be in the transaction queue of the validator who (though again this is not predictable yet) will turn out to nominate theStellarValue
that will ultimately be externalized. That node builds a transaction set that containsT1
. -
The transaction set containing
T1
is externalized, but (at least) one of the candidatecloseTime
s is greater thanT1
's expiration time. -
Transactions are applied using the maximum of all candidate
closeTime
s as the new last ledger close time.T1
therefore returnstxTOO_LATE
, and its operations are not applied. However, as it reached ledger close before being failed, it consumes a sequence number (and is charged a fee). -
T2
gets into an externalized transaction set (possibly, but not necessarily, the same one thatT1
got into) before it too expires. It has the correct sequence number, becauseT1
consumed a sequence number.T2
's operations are therefore applied -- even though its preconditions were intended to include guarantees thatT1
's operations had ensured, so the actual postconditions ofT2
could violate any of the smart contract's intended invariants which had depended uponT1
's operations having succeeded beforeT2
's operations could be applied.
So T
consumes a sequence number (and is charged a fee) but is never applied.
There is a design pattern in some smart contracts which breaks, allowing
inconsistent transactions to be committed, if it encounters this race: a smart
contract might submit a chain of transactions, with incrementing sequence
numbers, each intended to be applied only if the previous ones succeeded. If
there were transactions that were intended to be constrained by the incrementing
sequence numbers only to be applied if T
succeeded, they could do so because
T
had consumed its sequence number, even though it was never applied. The
dependent transactions would then perform operations which the smart contract
had intended to be performed only if T
had succeeded. This would
potentially be arbitrarily bad for the smart contract.
With the behavior proposed in this CAP, step #3 -- a node building a transaction
set containing T1
-- would only occur if T1
were not expired with respect to
the closeTime
in the same proposed StellarValue
as that transaction set.
Otherwise, T1
would not make it into a transaction set, and would therefore
never consume a sequence number (or be charged a fee), and T2
would fail
validation with a bad sequence number, as the smart contract intended in that
case. If T1
did make it into a transaction set, then, under the new behavior
in this CAP, step #5 would change -- if the transaction set containing T1
won
nomination, then the closeTime
of the new ledger would be the closeTime
from
the same StellarValue
as T1
, with respect to which T1
is in this case not
expired. Hence, T1
would be applied during ledger close; it would not return
txTOO_LATE
. T2
would therefore have the opportunity to be applied (assuming
it was valid in the other respects in addition to its sequence number), and in
this case that would be as expected, as T1
had previously succeeded.
Note that the duration that this race window in the current protocol remains
open can be lengthened (up to one minute) by the increase of any one candidate
closeTime
, since the current protocol combines candidate closeTime
s by
choosing the maximum. That means in particular that a single bad validator
can open this race window significantly, with the consequences including both
the failure of more transactions with txTOO_LATE
and the potential for
inconsistent smart contract behavior. This reflects that the current
protocol's choice of the maximum candidate closeTime
is, in a sense, too
sensitive: it can externalize a value that could have been manipulated by a
single bad actor. We refer to such manipulation as "maximum closeTime
injection". The proposal in this CAP is less sensitive: a node can affect the
composite closeTime
only if it manages to provide a transaction set that the
network as a whole selects as a composited one for the ballot protocol. We
force a node to do a "good deed" (putting together a transaction set which the
compositing function selects over any other node's candidate) for the network's
clients in order to influence the eventual externalized closeTime
. In the
presence of this CAP, one node's increasing the closeTime
significantly no
longer triggers the smart-contract race because that is closed completely by
this CAP, and it no longer reduces the number of applicable transactions in a
ledger because the high closeTime
provided by the bad actor does not affect
the validity of transactions in transaction sets proposed by other nodes.
Here we argue that this CAP would represent a clear improvement in behavior by arguing individually for each of the semantic changes in the table above, in the order presented (we shall use the "index" column for reference), so that the desirability of the first change depends only on the state of the current protocol and code, and the desirability of each further change may depend upon that of earlier changes as well, in effect assuming that they have been made because they are desirable (thus constructing an inductive argument for the desirability of the whole CAP).
-
The first listed change was one of the optimizations made in PR 2608, without requiring a protocol change (or, therefore, CAP), so we do not need to argue for it in this CAP, but we explain it for context: by estimating when the next ledger will close and avoiding flooding any transactions which will have expired by that time, we can save the network and memory resources that we might have spent on behalf of transactions which were unlikely ever to be applied anyway. This CAP could be seen in part as propagating a similar style of change to some later stages in the protocol; those changes do require a protocol upgrade.
-
The second listed decision point was changed in PR 2608, and we propose to refine it further in this CAP. The PR 2608 change was similar to the one made in the first decision point 1, at a different place: when we trim transactions before choosing which
StellarValue
to nominate first when triggering a new ledger. The change had the same idea as the aforementioned one, to minimize the use of resources on behalf of likely-useless transactions. In this CAP, we propose changing this decision point further to do the trimming based on the exactcloseTime
that we are nominating. Since the CAP behavior would allow us to know that that would be the exact externalizedcloseTime
if the transaction set that we nominate were to be externalized, we know that thatcloseTime
is optimal to use for trimming against. Knowing the optimal value, we no longer need an estimate. (The first decision point does not change because at that point we do not yet know the rest of theStellarValue
that we will end up nominating -- in particular we do not yet know thecloseTime
-- so an estimate is the best that we can do.) And because that value is optimal -- all the transactions that it leads to being trimmed would have been guaranteed to have returnedtxTOO_EARLY
/txTOO_LATE
if the transaction set had been externalized, and all the transactions that it leads to not being trimmed are guaranteed not to returntxTOO_EARLY
/txTOO_LATE
if the transaction set is ultimately externalized -- it is clearly desirable to use it. -
In the presence of change #2, which trims any premature/expired transactions before nominating a
StellarValue
, it is only an ill-behaved node that would nominate aStellarValue
containing a transaction which is premature/expired with respect to its owncloseTime
, so it becomes sensible for such a value to fail validation. There is no loss in this, since we would not want to accept aStellarValue
from an ill-behaved node in any case; this change (given change #2) simply represents a strict improvement in our ability to detect a particular incorrect behavior. -
In the presence of change #3, any candidate transaction set passed in to the compositing function consists only of transactions which are valid with respect to the
closeTime
in the sameStellarValue
as the transaction set. Therefore, once the compositing function has chosen one of the candidate transaction sets, the choice of a compositedcloseTime
equal to thecloseTime
in the sameStellarValue
as the chosen transaction set becomes optimal in the following sense: it is precisely the latestcloseTime
with respect to which all of the transactions in the chosen transaction set are valid (unexpired). By comparison, the old protocol's choice of the maximalcloseTime
of all candidates' is simply a loss:-
It might render some of the transactions in the composited set expired, which is the
txTOO_LATE
race that motivated this CAP. -
It might render some transactions still in the memory pools of some nodes expired, when they might have had a chance of getting into a future ledger if the
closeTime
had not been needlessly increased. -
It makes the ledger close time more sensitive to the choice of a large
closeTime
by a single bad actor, which we have called the "maximumcloseTime
injection" problem, and discussed above in the "Detailed illustration of failure mode".
-
-
Given the ability to preserve the signature (since it is on a nominated
<txSet,closeTime>
pair, of which we now choose a specific one rather than combining multiple ones in producing thecloseTime
) in the output of the compositing function, there is little cost to doing so (we have the signature in memory and have already checked it), so we may as well lose as little information as possible. And given that we have preserved the signature onStellarValue
s throughout the nomination protocol and into the ballot protocol, we must expectSIGNED
StellarValue
s in the ballot protocol, and we must check the signatures again in the ballot protocol, to make sure that the additional information that we are preserving is correct information. The additional signature-checking, however, will be on a signature that we just checked during the preceding nomination round, so we will likely simply hit in cache nearly all the time, and not have to do significantly more signature checks.
Therefore, we argue that each successive change represents a clear improvement, given the previous one (and the first represents a clear improvement over the existing implementation).
The proposal in this CAP is the third that we have considered as a means of fixing the problems described in the "Motivation" section. We record them here to motivate the proposal that we later settled on for this CAP.
The first idea was to change the point at which the current ledger header's
closeTime
was updated from before transactions are applied to afterwards.
(Ledger upgrades
are already performed after transaction applies.) This
would prevent an increase in the closeTime
brought about by candidates other
than the one whose transaction set was selected from causing transactions to
fail (it would not occur until after they had been applied). However, this
raised the concern that sometimes transactions would be applied despite having
expiration times earlier than the close time of the ledger in which they were
committed -- and there would not even be any bound on how large the gap
between those times might be. This CAP maintains the invariant that if a
transaction is applied, the close time of the ledger in which it is applied
falls within the time bounds of the transaction.
The second idea was to remove transactions from the composited transaction set
selected by the combine-candidates code in the nomination protocol, based on the
(maximal) closeTime
just selected by that code. However, that would seem to
have opened up a new denial-of-service attack on the ledger:
an attacker could create large numbers of transactions with very high fees,
making it likely that they would be accepted into transaction sets, but with
extremely short expiration times, that would almost certainly come before the
next ledger close. They could therefore fill up the transaction sets with
such transactions, yet avoid the transaction fees (the transactions would be
trimmed by the new code before fees were charged), leaving the transaction
sets produced by the nomination protocol with little or no room for legitimate
transactions.
Regarding the claim in the "Design Rationale" that "this CAP in general makes changes to transaction set composition and validity in the earliest protocol phases possible", note that from the first rejected alternative, to the second rejected alternative, to the proposal in this CAP, the phase of the protocol at which we have considered placing the new trimming and validating code has moved earlier at each step. The "detailed argument in favor" of this CAP also proceeded change-by-change in order from earlier to later phases of the consensus protocol.
Considering the closeTime
-related changes in this CAP also raised a further
discussion: because the SIGNED
StellarValue
, besides the transaction set and
close time, also contains a set of ledger upgrades
, we could choose
additionally to change upgrades
to come from the single selected
StellarValue
rather than being combined in a way similar to the closeTime
s,
as they are in the current protocol.
Upgrades do happen independently of the transactions: we could view the ledger closes as an optimization of alternating transaction set applies and ledger upgrades. So we did have a free choice between proposing to change upgrades in the same way as we were proposing to change closetime, or not doing so and letting them work differently (single-candidate-selection for closetimes and txsets, candidate-combination for upgrades).
There isn't any correlation that we've found among the different upgrades that
we combine, in the sense that today, if changing any given parameter A
from
1
to 2
and changing any given parameter B
from 1
to 2
would each be
sensible individually, then it would also be sensible to make both changes at
once. But if the type of possible upgrades could expand to one in which certain
combinations of parameter changes would be insensible, then it might no longer
make sense just to combine each parameter individually -- the simple union of
individual changes could produce a result which was inconsistent. In that case,
the right way to combine them consistently would become ambiguous; there could
be multiple options of which none would include all candidate parameter changes.
Choosing the best single nominated set of upgrades might be the simplest way
of choosing a consistent composite of all candidate upgrades.
Overall, changing the selection of upgrades
to match that of closeTime
could be said to make the resulting protocol simpler -- but it would make the
change for the CAP more complicated, and we haven't found any clear benefit to
making that further change. (We did start with and do some testing of an
implementation that also changed upgrades
selection, but in the latest
implementation we have undone that part and are changing only closeTime
.)
Semantic changes resulting from this CAP we hope to be limited to the correction of undesirable aspects of the current protocol, such as the potential inconsistency of smart contract behavior described in the "Motivation", and not on any aspects of the protocol that well-behaved clients could be relying on (a well-behaved client should not rely on a potentially harmful race happening!).
So far, we have not found new potential issues with safety or denial-of-service introduced by the proposal in this CAP, as we did with earlier ideas that we then rejected, as described above in the "Design Rationale".
-
A test is added to confirm that when a node selects a
StellarValue
to nominate, it trims from the selected transaction set precisely those transactions which would be invalid according to thecloseTime
in thatStellarValue
, and no others (in previous protocol versions, it should continue to trim those which are invalid according to the last ledger close time). -
A test is added to confirm that nominated
StellarValue
s are checked for internal consistency between their close times and transaction sets -- that is, that they contain no transactions which are invalid according to their own close times (a nominatedStellarValue
that does not meet that condition should be rejected by other nodes). (In old protocols, transactions in a nominatedStellarValue
are checked for validity against the last ledger close time.) -
A test is added to confirm that the new code which builds upon PR 2608 to allow a client to choose the
closeTime
to compare with a transaction'sminTime
correctly alters which transactions are consideredtxTOO_EARLY
and which are not. (PR 2608 introduced the option for clients to choose acloseTime
other than the last ledger close time to compare with a transaction'smaxTime
when determining which transactions are consideredtxTOO_LATE
.) -
The existing test for the compositing/combining function, which confirms that a set of candidate
StellarValue
s produces the expected compositedcloseTime
, changes in three ways:-
It tests that old protocols continue to behave the same way, but that in new protocol versions, the composited
closeTime
is simply that of theStellarValue
containing the best transaction set, not the maximumcloseTime
of all candidates. -
It is enhanced to test for expected
upgrades
as well (but these should behave the same between old and new protocols; it just checks that the new protocol doesn't accidentally change this). -
It tests that old nomination protocols produce
BASIC
StellarValue
s, but new nomination protocols produceSIGNED
ones.
-
-
The existing tests which check that the
StellarValue
produced by the nomination protocol has the correct type changes to expectBASIC
StellarValue
s in old protocol versions, butSIGNED
StellarValue
s in new protocols.
An implementation of this protocol has been written, which as far as the author knows is complete and correct in its semantics; it will certainly need refactoring, but it might constitute a demonstration of the practicality of implementing this proposal, and of a bound on the scope of the changes required, as well as a way of experimenting with its consequences:
The changes therein are limited to stellar-core, and comprise the following:
-
The protocol version is bumped (currently anticipated to be to 14).
-
The herder's choice of which transactions to include in the transaction set that it is going to nominate to depend, in new protocols only, on the close time that it is going to nominate, rather than (as in the current unreleased code) an estimate of when the next ledger is likely to close or (as in the released code) the last ledger close time.
-
The herder's validation of
StellarValue
s nominated by other nodes changes to expect, in new protocols only, that values used by the ballot protocol areSIGNED
. -
The herder's validation of
StellarValue
s nominated by other nodes changes whichcloseTime
to validate the transactions in theStellarValue
against from the last ledger close time to thecloseTime
in theStellarValue
. -
The herder's compositing of candidate
StellarValue
s into a single value to nominate, in new protocols only (it preserves its old behavior in old protocols), changes in the following ways:-
It chooses a composited
closeTime
directly from theStellarValue
containing the selected transaction set. In particular, it does not need any trimming of the selected transaction set. (That set should already be consistent withcloseTime
, since it came from one nominatedStellarValue
, which the herder has already validated by the time it composites them.) -
It returns
SIGNED
StellarValue
s.
-
-
Tests are modified and extended as described above under "Test Cases".