Skip to content

Commit

Permalink
add high level account logic
Browse files Browse the repository at this point in the history
  • Loading branch information
yihuang committed Nov 28, 2023
1 parent aad93e2 commit d62abcd
Showing 1 changed file with 29 additions and 6 deletions.
35 changes: 29 additions & 6 deletions docs/architecture/adr-069-unordered-account.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,29 @@ It would be good to expire the gap nonces after certain timeout is reached, to m

The prototype implementation use a roaring bitmap to record these gap values.

```golang
const (
MSBCheckMask = 1 << 63
MSBClearMask = ^(1 << 63)
)

// CheckNonce switches to un-ordered lane if the MSB of the nonce is set.
func (acct *Account) CheckNonce(nonce uint64, blockTime uint64) error {
if nonce & MSBCheckMask != 0 {
nonce &= MSBClearMask

if acct.unorderedNonce == nil {
acct.unorderedNonce = NewUnOrderedNonce()
}
return acct.unorderedNonce.CheckNonce(nonce, blockTime)
}

// current nonce logic
}
```



```golang
const (
// GapsCapacity is the capacity of the set of gap values.
Expand All @@ -64,16 +87,16 @@ const (
)

// getGaps returns the gap set, or create a new one if it's expired
func(u *UnOrderedNonce) getGaps(timestamp uint64) *IntSet {
if timestamp > u.Timestamp + GapsExpirationDuration {
func(u *UnOrderedNonce) getGaps(blockTime uint64) *IntSet {
if blockTime > u.Timestamp + GapsExpirationDuration {
return NewIntSet(GapsCapacity)
}

return &u.Gaps
}

// CheckNonce checks if the nonce in tx is valid, if yes, also update the internal state.
func(u *UnOrderedNonce) CheckNonce(nonce uint64, timestamp uint64) error {
func(u *UnOrderedNonce) CheckNonce(nonce uint64, blockTime uint64) error {
switch {
case nonce == u.Sequence:
// special case, the current sequence number must have been occupied
Expand All @@ -86,18 +109,18 @@ func(u *UnOrderedNonce) CheckNonce(nonce uint64, timestamp uint64) error {
return errors.New("max gap is exceeded")
}

gapSet := acct.getGaps(timestamp)
gapSet := acct.getGaps(blockTime)
// record the gaps into the bitmap
gapSet.AddRange(u.Sequence + 1, u.Sequence + gaps + 1)

// update the latest nonce
u.Gaps = *gapSet
u.Sequence = nonce
u.Timestamp = timestamp
u.Timestamp = blockTime

default:
// `nonce < u.Sequence`, the tx try to use a historical nonce
gapSet := acct.getGaps(timestamp)
gapSet := acct.getGaps(blockTime)
if !gapSet.Contains(nonce) {
return errors.New("nonce is occupied or expired")
}
Expand Down

0 comments on commit d62abcd

Please sign in to comment.