-
Notifications
You must be signed in to change notification settings - Fork 201
Add IgnoreSenderReserveRequirements
param
#3751
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,6 +69,9 @@ type TicketParamsConfig struct { | |
// TxCostMultiplier is the desired multiplier of the transaction | ||
// cost for redemption | ||
TxCostMultiplier int | ||
|
||
// IgnoreSenderReserve instructs the recipient to skip sender reserve checks and accept tickets as long as the computed face value meets EV requirements | ||
IgnoreSenderReserve bool | ||
} | ||
|
||
// GasPriceMonitor defines methods for monitoring gas prices | ||
|
@@ -271,16 +274,28 @@ func (r *recipient) faceValue(sender ethcommon.Address) (*big.Int, error) { | |
faceValue = new(big.Int).Mul(r.cfg.EV, evMultiplier) | ||
} | ||
|
||
// Fetch current max float for sender | ||
maxFloat, err := r.sm.MaxFloat(sender) | ||
if err != nil { | ||
return nil, err | ||
} | ||
var maxFloat *big.Int | ||
if !r.cfg.IgnoreSenderReserve { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: how about revering the condition and check here |
||
// Fetch current max float for sender | ||
var err error | ||
maxFloat, err = r.sm.MaxFloat(sender) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if faceValue.Cmp(maxFloat) > 0 { | ||
// If faceValue > maxFloat | ||
// Set faceValue = maxFloat | ||
faceValue = maxFloat | ||
if faceValue.Cmp(maxFloat) > 0 { | ||
// If faceValue > maxFloat | ||
// Set faceValue = maxFloat | ||
faceValue = maxFloat | ||
} | ||
} else { | ||
available, err := r.sm.SenderFunds(sender) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if available.Cmp(faceValue) < 0 { | ||
return nil, errInsufficientSenderReserve | ||
} | ||
} | ||
|
||
if r.maxfacevalue.Cmp(big.NewInt(0)) > 0 { | ||
|
@@ -290,7 +305,9 @@ func (r *recipient) faceValue(sender ethcommon.Address) (*big.Int, error) { | |
} | ||
if monitor.Enabled { | ||
monitor.TicketFaceValue(sender.Hex(), faceValue) | ||
monitor.MaxFloat(sender.Hex(), maxFloat) | ||
if !r.cfg.IgnoreSenderReserve && maxFloat != nil { | ||
monitor.MaxFloat(sender.Hex(), maxFloat) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, so we monitor this metric only fi the |
||
} | ||
} | ||
if faceValue.Cmp(r.cfg.EV) < 0 { | ||
return nil, errInsufficientSenderReserve | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,6 +41,9 @@ type SenderMonitor interface { | |
// MaxFloat returns a remote sender's max float | ||
MaxFloat(addr ethcommon.Address) (*big.Int, error) | ||
|
||
// SenderFunds returns the broadcaster's spendable balance (deposit + total reserve - pending tickets) | ||
SenderFunds(addr ethcommon.Address) (*big.Int, error) | ||
|
||
// ValidateSender checks whether a sender's unlock period ends the round after the next round | ||
ValidateSender(addr ethcommon.Address) error | ||
} | ||
|
@@ -162,6 +165,35 @@ func (sm *LocalSenderMonitor) MaxFloat(addr ethcommon.Address) (*big.Int, error) | |
return sm.maxFloat(addr) | ||
} | ||
|
||
// SenderFunds returns the sender's deposit plus total reserve minus pending tickets | ||
func (sm *LocalSenderMonitor) SenderFunds(addr ethcommon.Address) (*big.Int, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any chance it's possible to add unit tests for this? |
||
sm.mu.Lock() | ||
defer sm.mu.Unlock() | ||
|
||
sm.ensureCache(addr) | ||
|
||
info, err := sm.smgr.GetSenderInfo(addr) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
totalReserve := new(big.Int).Set(info.Reserve.FundsRemaining) | ||
if info.Reserve.ClaimedInCurrentRound != nil { | ||
totalReserve.Add(totalReserve, info.Reserve.ClaimedInCurrentRound) | ||
} | ||
|
||
available := new(big.Int).Set(totalReserve) | ||
if info.Deposit != nil { | ||
available.Add(available, info.Deposit) | ||
} | ||
available.Sub(available, sm.senders[addr].pendingAmount) | ||
Comment on lines
+180
to
+189
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add a comment here or in the function comment explaining the calculations here? I don't exactly get it, so the sender funds are calculated as:
I think the most tricky part is why we add this |
||
if available.Sign() < 0 { | ||
available = big.NewInt(0) | ||
} | ||
|
||
return available, nil | ||
} | ||
|
||
// QueueTicket adds a ticket to the queue for a remote sender | ||
func (sm *LocalSenderMonitor) QueueTicket(ticket *SignedTicket) error { | ||
sm.mu.Lock() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -272,6 +272,29 @@ func (r *RedeemerClient) MaxFloat(sender ethcommon.Address) (*big.Int, error) { | |
return mf, nil | ||
} | ||
|
||
// SenderFunds retrieves the sender's spendable balance directly from the local sender manager cache | ||
func (r *RedeemerClient) SenderFunds(sender ethcommon.Address) (*big.Int, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any chance it's possible to add unit tests for this? |
||
info, err := r.sm.GetSenderInfo(sender) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
totalReserve := new(big.Int).Set(info.Reserve.FundsRemaining) | ||
if info.Reserve.ClaimedInCurrentRound != nil { | ||
totalReserve.Add(totalReserve, info.Reserve.ClaimedInCurrentRound) | ||
} | ||
|
||
available := new(big.Int).Set(totalReserve) | ||
if info.Deposit != nil { | ||
available.Add(available, info.Deposit) | ||
} | ||
Comment on lines
+277
to
+290
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any change it's possible to extract it to some utils and reuse? The code looks very similar to some other parts and the |
||
|
||
if available.Sign() < 0 { | ||
available = big.NewInt(0) | ||
} | ||
return available, nil | ||
} | ||
|
||
// ValidateSender checks whether a sender has not recently unlocked its deposit and reserve | ||
func (r *RedeemerClient) ValidateSender(sender ethcommon.Address) error { | ||
info, err := r.sm.GetSenderInfo(sender) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.