relinquish the lock while signing in PushWithNonce

This commit is contained in:
vyzo 2020-08-12 20:26:58 +03:00
parent 7be18df6ea
commit f2ac17845b

View File

@ -55,6 +55,8 @@ var (
ErrBroadcastAnyway = errors.New("broadcasting message despite validation fail") ErrBroadcastAnyway = errors.New("broadcasting message despite validation fail")
ErrRBFTooLowPremium = errors.New("replace by fee has too low GasPremium") ErrRBFTooLowPremium = errors.New("replace by fee has too low GasPremium")
ErrTryAgain = errors.New("state inconsistency while signing message; please try again")
) )
const ( const (
@ -516,30 +518,57 @@ func (mp *MessagePool) PushWithNonce(ctx context.Context, addr address.Address,
}() }()
mp.curTsLk.Lock() mp.curTsLk.Lock()
defer mp.curTsLk.Unlock()
mp.lk.Lock() mp.lk.Lock()
defer mp.lk.Unlock()
curTs := mp.curTs
fromKey := addr fromKey := addr
if fromKey.Protocol() == address.ID { if fromKey.Protocol() == address.ID {
var err error var err error
fromKey, err = mp.api.StateAccountKey(ctx, fromKey, mp.curTs) fromKey, err = mp.api.StateAccountKey(ctx, fromKey, mp.curTs)
if err != nil { if err != nil {
mp.lk.Unlock()
mp.curTsLk.Unlock()
return nil, xerrors.Errorf("resolving sender key: %w", err) return nil, xerrors.Errorf("resolving sender key: %w", err)
} }
} }
nonce, err := mp.getNonceLocked(fromKey, mp.curTs) nonce, err := mp.getNonceLocked(fromKey, mp.curTs)
if err != nil { if err != nil {
mp.lk.Unlock()
mp.curTsLk.Unlock()
return nil, xerrors.Errorf("get nonce locked failed: %w", err) return nil, xerrors.Errorf("get nonce locked failed: %w", err)
} }
// release the locks for signing
mp.lk.Unlock()
mp.curTsLk.Unlock()
msg, err := cb(fromKey, nonce) msg, err := cb(fromKey, nonce)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// reacquire the locks and check state for consistency
mp.curTsLk.Lock()
defer mp.curTsLk.Unlock()
if mp.curTs != curTs {
return nil, ErrTryAgain
}
mp.lk.Lock()
defer mp.lk.Unlock()
nonce2, err := mp.getNonceLocked(fromKey, mp.curTs)
if err != nil {
return nil, xerrors.Errorf("get nonce locked failed: %w", err)
}
if nonce2 != nonce {
return nil, ErrTryAgain
}
if err := mp.verifyMsgBeforePush(msg, mp.curTs.Height()); err != nil { if err := mp.verifyMsgBeforePush(msg, mp.curTs.Height()); err != nil {
return nil, err return nil, err
} }