order: update height hint for accounts in batch

This commit is contained in:
Wilmer Paulino 2020-07-01 17:01:23 -07:00
parent fb219d5879
commit 509cb4e64e
No known key found for this signature in database
GPG key ID: 6DF57B9F9514972F
5 changed files with 38 additions and 8 deletions

View file

@ -221,7 +221,7 @@ type BatchSigner interface {
type BatchStorer interface {
// StorePendingBatch makes sure all changes executed by a pending batch
// are correctly and atomically stored to the database.
StorePendingBatch(*Batch) error
StorePendingBatch(_ *Batch, bestHeight uint32) error
// MarkBatchComplete marks a pending batch as complete, allowing a
// trader to participate in a new batch.

View file

@ -9,6 +9,13 @@ import (
"github.com/lightninglabs/llm/clmrpc"
)
const (
// heightHintPadding is the padding we add to our best known height to
// avoid any discrepancies in block propagation between us and the
// auctioneer.
heightHintPadding = -3
)
// batchStorer is a type that implements BatchStorer and can persist a batch to
// the local trader database.
type batchStorer struct {
@ -23,7 +30,7 @@ type batchStorer struct {
// modifications will be applied atomically as a result of MarkBatchComplete.
//
// NOTE: This method is part of the BatchStorer interface.
func (s *batchStorer) StorePendingBatch(batch *Batch) error {
func (s *batchStorer) StorePendingBatch(batch *Batch, bestHeight uint32) error {
// Prepare the order modifications first.
orders := make([]Nonce, len(batch.MatchedOrders))
orderModifiers := make([][]Modifier, len(orders))
@ -64,6 +71,13 @@ func (s *batchStorer) StorePendingBatch(batch *Batch) error {
// Next create our account modifiers.
accounts := make([]*account.Account, len(batch.AccountDiffs))
accountModifiers := make([][]account.Modifier, len(accounts))
// Each account will have the same height hint applied.
heightHint := int64(bestHeight) + heightHintPadding
if heightHint < 0 {
heightHint = 0
}
for idx, diff := range batch.AccountDiffs {
// Get the current state of the account first so we can create
// a proper diff.
@ -107,10 +121,14 @@ func (s *batchStorer) StorePendingBatch(batch *Batch) error {
diff.EndingState)
}
// Finally update the account value and expiry.
accountModifiers[idx] = append(
// Finally update the account value and height hint.
modifiers = append(
modifiers, account.ValueModifier(diff.EndingBalance),
)
modifiers = append(
modifiers, account.HeightHintModifier(uint32(heightHint)),
)
accountModifiers[idx] = modifiers
}
// Everything is ready to be persisted now.

View file

@ -15,6 +15,7 @@ import (
func TestBatchStorer(t *testing.T) {
t.Parallel()
const bestHeight = 1337
var (
storeMock = newMockStore()
storer = &batchStorer{
@ -119,7 +120,7 @@ func TestBatchStorer(t *testing.T) {
}
// Pass the assembled batch to the storer now.
err := storer.StorePendingBatch(batch)
err := storer.StorePendingBatch(batch, bestHeight)
if err != nil {
t.Fatalf("error storing batch: %v", err)
}
@ -165,6 +166,11 @@ func TestBatchStorer(t *testing.T) {
t.Fatalf("invalid account expiry, got %d wanted %d",
smallAcct.Value, 144)
}
heightHint := uint32(bestHeight + heightHintPadding)
if smallAcct.HeightHint != heightHint {
t.Fatalf("invalid account height hint, got %d wanted %d",
smallAcct.Value, heightHint)
}
if bigAcct.State != account.StatePendingUpdate {
t.Fatalf("invalid account state, got %d wanted %d",
@ -178,6 +184,10 @@ func TestBatchStorer(t *testing.T) {
t.Fatalf("invalid account expiry, got %d wanted %d",
bigAcct.Value, 144)
}
if bigAcct.HeightHint != heightHint {
t.Fatalf("invalid account height hint, got %d wanted %d",
bigAcct.Value, heightHint)
}
}
func newKit(nonce Nonce, units SupplyUnit) Kit {

View file

@ -239,13 +239,14 @@ func (m *Manager) PendingBatch() *Batch {
// belong to the trader. Before sending off the signature to the auctioneer,
// we'll also persist the batch to disk as pending to ensure we can recover
// after a crash.
func (m *Manager) BatchSign() (BatchSignature, error) {
func (m *Manager) BatchSign(bestHeight uint32) (BatchSignature, error) {
sig, err := m.batchSigner.Sign(m.pendingBatch)
if err != nil {
return nil, err
}
if err := m.batchStorer.StorePendingBatch(m.pendingBatch); err != nil {
err = m.batchStorer.StorePendingBatch(m.pendingBatch, bestHeight)
if err != nil {
return nil, fmt.Errorf("unable to store batch: %v", err)
}

View file

@ -643,7 +643,8 @@ func (s *rpcServer) handleServerMessage(rpcMsg *clmrpc.ServerAuctionMessage) err
}
// Sign for the accounts in the batch.
sigs, err := s.orderManager.BatchSign()
bestHeight := atomic.LoadUint32(&s.bestHeight)
sigs, err := s.orderManager.BatchSign(bestHeight)
if err != nil {
log.Errorf("Error signing batch: %v", err)
return s.sendRejectBatch(batch, err)