Skip to content

Commit 1d6f908

Browse files
committed
Auto-expire account keys based on the reference block height they were used for
1 parent 4d01b01 commit 1d6f908

File tree

3 files changed

+24
-24
lines changed

3 files changed

+24
-24
lines changed

services/ingestion/event_subscriber.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ func (r *RPCEventSubscriber) subscribe(ctx context.Context, height uint64) <-cha
175175
for _, evt := range blockEvents.Events {
176176
r.keyLock.UnlockKey(evt.TransactionID)
177177
}
178+
r.keyLock.Notify(blockEvents.Height)
178179

179180
eventsChan <- evmEvents
180181

services/requester/key_store.go

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,23 @@ package requester
33
import (
44
"fmt"
55
"sync"
6-
"time"
76

87
flowsdk "github.com/onflow/flow-go-sdk"
98
"github.com/onflow/flow-go-sdk/crypto"
10-
flowGo "github.com/onflow/flow-go/model/flow"
119
)
1210

1311
var ErrNoKeysAvailable = fmt.Errorf("no keys available")
1412

15-
const accountKeyExpiry = 10 * time.Second
13+
const accountKeyBlockExpiration = 1_000
1614

1715
type AccountKey struct {
1816
flowsdk.AccountKey
1917

20-
mu sync.Mutex
21-
ks *KeyStore
22-
Address flowsdk.Address
23-
Signer crypto.Signer
24-
lastUsed time.Time
18+
mu sync.Mutex
19+
ks *KeyStore
20+
Address flowsdk.Address
21+
Signer crypto.Signer
22+
lastUsedBlock uint64
2523
}
2624

2725
// Done unlocks a key after use and puts it back into the pool.
@@ -58,13 +56,14 @@ func (k *AccountKey) SetProposerPayerAndSign(
5856
SignEnvelope(k.Address, k.Index, k.Signer)
5957
}
6058

61-
func (k *AccountKey) expired() bool {
62-
return time.Since(k.lastUsed) > flowGo.DefaultTransactionExpiry
63-
}
64-
6559
type KeyLock interface {
66-
LockKey(txID flowsdk.Identifier, key *AccountKey)
60+
LockKey(
61+
txID flowsdk.Identifier,
62+
referenceBlockHeight uint64,
63+
key *AccountKey,
64+
)
6765
UnlockKey(txID flowsdk.Identifier)
66+
Notify(blockHeight uint64)
6867
}
6968

7069
type KeyStore struct {
@@ -88,8 +87,6 @@ func NewKeyStore(keys []*AccountKey) *KeyStore {
8887
ks.size = len(keys)
8988
ks.availableKeys = availableKeys
9089

91-
go ks.keyExpiryChecker()
92-
9390
return ks
9491
}
9592

@@ -106,11 +103,15 @@ func (k *KeyStore) Take() (*AccountKey, error) {
106103
}
107104
}
108105

109-
func (k *KeyStore) LockKey(txID flowsdk.Identifier, key *AccountKey) {
106+
func (k *KeyStore) LockKey(
107+
txID flowsdk.Identifier,
108+
referenceBlockHeight uint64,
109+
key *AccountKey,
110+
) {
110111
key.mu.Lock()
111112
defer key.mu.Unlock()
112113

113-
key.lastUsed = time.Now()
114+
key.lastUsedBlock = referenceBlockHeight
114115
k.usedKeys[txID] = key
115116
}
116117

@@ -122,12 +123,10 @@ func (k *KeyStore) UnlockKey(txID flowsdk.Identifier) {
122123
}
123124
}
124125

125-
func (k *KeyStore) keyExpiryChecker() {
126-
for range time.Tick(accountKeyExpiry) {
127-
for txID, key := range k.usedKeys {
128-
if key.expired() {
129-
k.UnlockKey(txID)
130-
}
126+
func (k *KeyStore) Notify(blockHeight uint64) {
127+
for txID, key := range k.usedKeys {
128+
if blockHeight-key.lastUsedBlock >= accountKeyBlockExpiration {
129+
k.UnlockKey(txID)
131130
}
132131
}
133132
}

services/requester/requester.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ func (e *EVM) buildTransaction(
571571
if err := accKey.SetProposerPayerAndSign(flowTx, account); err != nil {
572572
return nil, err
573573
}
574-
e.keystore.LockKey(flowTx.ID(), accKey)
574+
e.keystore.LockKey(flowTx.ID(), latestBlock.Height, accKey)
575575

576576
e.collector.AvailableSigningKeys(e.keystore.AvailableKeys())
577577
e.collector.OperatorBalance(account)

0 commit comments

Comments
 (0)