Skip to content

Commit

Permalink
mitigate unexpected state
Browse files Browse the repository at this point in the history
  • Loading branch information
agouin committed Dec 11, 2023
1 parent 26c340c commit 105bb20
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
20 changes: 17 additions & 3 deletions signer/cosigner_nonce_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,21 +375,29 @@ func (cnc *CosignerNonceCache) PruneNonces() int {
cnc.cache.mu.Lock()
defer cnc.cache.mu.Unlock()
nonExpiredIndex := len(cnc.cache.cache) - 1
for i := len(cnc.cache.cache) - 1; i >= 0; i-- {
total := len(cnc.cache.cache)
for i := total - 1; i >= 0; i-- {
if time.Now().Before(cnc.cache.cache[i].Expiration) {
nonExpiredIndex = i
break
}
if i == 0 {
deleteCount := len(cnc.cache.cache)
cnc.cache.cache = nil
cnc.logger.Debug("Pruned all nonces due to expiration", "deleted", deleteCount, "total", total)
return deleteCount
}
}
deleteCount := len(cnc.cache.cache) - nonExpiredIndex - 1
if nonExpiredIndex != len(cnc.cache.cache)-1 {
deleteCount := total - nonExpiredIndex - 1
if nonExpiredIndex != total-1 {
cnc.cache.cache = cnc.cache.cache[:nonExpiredIndex+1]
}
if deleteCount > 0 {
cnc.logger.Debug("Pruned some nonces due to expiration", "deleted", deleteCount, "total", total)
} else {
cnc.logger.Debug("No nonces pruned due to expiration", "total", total)
}

return deleteCount
}

Expand Down Expand Up @@ -418,3 +426,9 @@ func (cnc *CosignerNonceCache) ClearNonces(cosigner Cosigner) {
}
}
}

func (cnc *CosignerNonceCache) ClearAllNonces() {
cnc.cache.mu.Lock()
defer cnc.cache.mu.Unlock()
cnc.cache.cache = nil
}
16 changes: 16 additions & 0 deletions signer/cosigner_nonce_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,23 @@ func TestClearNonces(t *testing.T) {

for _, n := range cnc.cache.cache {
require.Len(t, n.Nonces, 2)
oneFound := false
twoFound := false
for _, cnr := range n.Nonces {
if cnr.Cosigner == cosigners[1] {
oneFound = true
}
if cnr.Cosigner == cosigners[2] {
twoFound = true
}
}
require.True(t, oneFound)
require.True(t, twoFound)
}

cnc.ClearNonces(cosigners[1])

require.Equal(t, 0, cnc.cache.Size())
}

type mockPruner struct {
Expand Down
9 changes: 8 additions & 1 deletion signer/threshold_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"os"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -734,7 +735,13 @@ func (pv *ThresholdValidator) Sign(ctx context.Context, chainID string, block Bl
"err", err.Error(),
)

if cosigner.GetID() == pv.myCosigner.GetID() {
isMyCosigner := cosigner.GetID() == pv.myCosigner.GetID()

if strings.Contains(err.Error(), "unexpected state, metadata does not exist for U:") {
pv.nonceCache.ClearNonces(cosigner)
}

if isMyCosigner {
return err
}

Expand Down

0 comments on commit 105bb20

Please sign in to comment.