fix(noncestore): return nonce incase of task failure

* Return must complete successfully else a nonce gap could form.
* TODO: add tests for Return
* closes#18
This commit is contained in:
Mohamed Sohail 2022-10-26 09:21:47 +00:00
parent 1bc8d65016
commit 24c81aaee2
Signed by: kamikazechaser
GPG Key ID: 7DD45520C01CD85D
3 changed files with 14 additions and 10 deletions

View File

@ -6,7 +6,7 @@ import "context"
type Noncestore interface { type Noncestore interface {
Peek(context.Context, string) (uint64, error) Peek(context.Context, string) (uint64, error)
Acquire(context.Context, string) (uint64, error) Acquire(context.Context, string) (uint64, error)
Return(context.Context, string) (uint64, error) Return(context.Context, string) error
SyncNetworkNonce(context.Context, string) (uint64, error) SyncNetworkNonce(context.Context, string) (uint64, error)
SetNewAccountNonce(context.Context, string) error SetNewAccountNonce(context.Context, string) error
} }

View File

@ -8,7 +8,6 @@ import (
"github.com/grassrootseconomics/cic-go-sdk/chain" "github.com/grassrootseconomics/cic-go-sdk/chain"
"github.com/lmittmann/w3" "github.com/lmittmann/w3"
"github.com/lmittmann/w3/module/eth" "github.com/lmittmann/w3/module/eth"
"github.com/zerodha/logf"
) )
// Opts represents the Redis nonce store specific params // Opts represents the Redis nonce store specific params
@ -18,14 +17,12 @@ type Opts struct {
MinIdleConns int MinIdleConns int
PoolSize int PoolSize int
ChainProvider *chain.Provider ChainProvider *chain.Provider
Lo logf.Logger
} }
// RedisNoncestore implements `noncestore.Noncestore` // RedisNoncestore implements `noncestore.Noncestore`
type RedisNoncestore struct { type RedisNoncestore struct {
chainProvider *chain.Provider chainProvider *chain.Provider
redis *redis.Client redis *redis.Client
lo logf.Logger
} }
func NewRedisNoncestore(o Opts) (noncestore.Noncestore, error) { func NewRedisNoncestore(o Opts) (noncestore.Noncestore, error) {
@ -43,7 +40,6 @@ func NewRedisNoncestore(o Opts) (noncestore.Noncestore, error) {
return &RedisNoncestore{ return &RedisNoncestore{
redis: redisClient, redis: redisClient,
chainProvider: o.ChainProvider, chainProvider: o.ChainProvider,
lo: o.Lo,
}, nil }, nil
} }
@ -81,20 +77,20 @@ func (ns *RedisNoncestore) Acquire(ctx context.Context, publicKey string) (uint6
return nonce, nil return nonce, nil
} }
func (ns *RedisNoncestore) Return(ctx context.Context, publicKey string) (uint64, error) { func (ns *RedisNoncestore) Return(ctx context.Context, publicKey string) error {
nonce, err := ns.redis.Get(ctx, publicKey).Uint64() nonce, err := ns.redis.Get(ctx, publicKey).Uint64()
if err != nil { if err != nil {
return 0, err return err
} }
if nonce > 0 { if nonce > 0 {
err = ns.redis.Decr(ctx, publicKey).Err() err = ns.redis.Decr(ctx, publicKey).Err()
if err != nil { if err != nil {
return 0, err return err
} }
} }
return nonce, nil return nil
} }
func (ns *RedisNoncestore) SyncNetworkNonce(ctx context.Context, publicKey string) (uint64, error) { func (ns *RedisNoncestore) SyncNetworkNonce(ctx context.Context, publicKey string) (uint64, error) {
@ -121,7 +117,6 @@ func (ns *RedisNoncestore) SyncNetworkNonce(ctx context.Context, publicKey strin
func (ns *RedisNoncestore) SetNewAccountNonce(ctx context.Context, publicKey string) error { func (ns *RedisNoncestore) SetNewAccountNonce(ctx context.Context, publicKey string) error {
err := ns.redis.Set(ctx, publicKey, 0, 0).Err() err := ns.redis.Set(ctx, publicKey, 0, 0).Err()
if err != nil { if err != nil {
ns.lo.Error("noncestore", "err", err)
return err return err
} }

View File

@ -62,6 +62,9 @@ func (tp *TaskerProcessor) giftGasProcessor(ctx context.Context, t *asynq.Task)
Nonce: nonce, Nonce: nonce,
}, big.NewInt(initialGiftGasValue)) }, big.NewInt(initialGiftGasValue))
if err != nil { if err != nil {
if err := tp.Noncestore.Return(ctx, p.PublicKey); err != nil {
return err
}
return err return err
} }
@ -69,11 +72,17 @@ func (tp *TaskerProcessor) giftGasProcessor(ctx context.Context, t *asynq.Task)
Tx: builtTx, Tx: builtTx,
}, client.TxDispatchTask) }, client.TxDispatchTask)
if err != nil { if err != nil {
if err := tp.Noncestore.Return(ctx, p.PublicKey); err != nil {
return err
}
return err return err
} }
_, err = tp.TaskerClient.CreateRegistrationTask(p, client.ActivateAccountTask) _, err = tp.TaskerClient.CreateRegistrationTask(p, client.ActivateAccountTask)
if err != nil { if err != nil {
if err := tp.Noncestore.Return(ctx, p.PublicKey); err != nil {
return err
}
return err return err
} }