Evm_node_lib_dev.Nonce_bitset
Nonce_bitset
registers known nonces from transactions that went through the tx_queue from a specific sender address. With this structure it's easy to do bookkeeping of address' nonce without going through all the transactions of the queue.
The invariants are that for any nonce_bitset nb
:
nb
, nb.next_nonce
is the next valid nonce for the state.n
to nb
, n
must be superior or equal to nb.next_nonce
. This is enforced by the validation in Validate.is_tx_valid
.nb.next_nonce
can only increase over time. This is enforced by shift
and offset
.type t = {
next_nonce : Z.t;
next_nonce
is the base value for any position found in bitset
. It’s set to be the next expected nonce for a given address, which is the nonce found in the backend.
bitset : Tezos_base.Bitset.t;
}
t
allows to register for a given address all nonces that are currently used by transaction in the tx_queue.
val offset : nonce1:Z.t -> nonce2:Z.t -> int Tezos_base.TzPervasives.tzresult
offset ~nonce1 ~nonce2
computes the difference between nonce1
and nonce2
.
Fails if nonce2 > nonce1
or if the difference between the two is more than Int.max_int
.
val add : t -> nonce:Z.t -> t Tezos_base.TzPervasives.tzresult
add bitset_nonce ~nonce
adds the nonce nonce
to bitset_nonce
.
val add_many :
t ->
nonce:Z.t ->
length:int ->
t Tezos_base.TzPervasives.tzresult
add_many bitset_nonce ~nonce ~length
adds the nonces nonce
, nonce+1
, ..., nonce+length-1
to bitset_nonce
.
val remove : t -> nonce:Z.t -> t Tezos_base.TzPervasives.tzresult
remove bitset_nonce ~nonce
removes the nonce nonce
from bitset_nonce
.
If nonce
is strictly inferior to bitset_nonce.next_nonce
then it's a no-op because nonce can't exist in the bitset.
val remove_many :
t ->
nonce:Z.t ->
length:int ->
t Tezos_base.TzPervasives.tzresult
remove_many bitset_nonce ~nonce ~length
removes the nonces nonce
, nonce+1
, ..., nonce+length-1
from bitset_nonce
.
If nonce
is strictly inferior to bitset_nonce.next_nonce
then it's a no-op because some nonces can't exist in the bitset.
val shift : t -> nonce:Z.t -> t Tezos_base.TzPervasives.tzresult
shift bitset_nonce ~nonce
shifts the bitset of bitset_nonce
so the next_nonce is now nonce
. Shifting the bitset means that nonces that are inferior to nonce
are dropped.
Fails if nonce
is strictly inferior to bitset_nonce.next_nonce
.
val is_empty : t -> bool
is_empty bitset_nonce
checks if the bitset is empty, i.e. no position is at 1.
val next_gap : t -> Z.t
next_gap bitset_nonce
returns the next available nonce.
val shift_then_next_gap :
t ->
shift_nonce:Z.t ->
Z.t Tezos_base.TzPervasives.tzresult
shift_then_next_gap bitset_nonce ~shift_nonce
calls shift
~nonce:shift_nonce
then !next_gap bitset_nonce
.