Skip to content

Commit

Permalink
refactor: rename protobuf binRecords
Browse files Browse the repository at this point in the history
  • Loading branch information
hopeyen committed Jan 8, 2025
1 parent d6daeb8 commit b367b9e
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 85 deletions.
44 changes: 22 additions & 22 deletions api/clients/v2/accountant.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ type Accountant struct {

// local accounting
// contains 3 bins; circular wrapping of indices
binRecords []BinRecord
periodRecords []PeriodRecord
usageLock sync.Mutex
cumulativePayment *big.Int

// number of bins in the circular accounting, restricted by minNumBins which is 3
numBins uint32
}

type BinRecord struct {
type PeriodRecord struct {
Index uint32
Usage uint64
}
Expand All @@ -43,9 +43,9 @@ func NewAccountant(accountID string, reservation *core.ReservedPayment, onDemand
//TODO: client storage; currently every instance starts fresh but on-chain or a small store makes more sense
// Also client is currently responsible for supplying network params, we need to add RPC in order to be automatic
// There's a subsequent PR that handles populating the accountant with on-chain state from the disperser
binRecords := make([]BinRecord, numBins)
for i := range binRecords {
binRecords[i] = BinRecord{Index: uint32(i), Usage: 0}
periodRecords := make([]PeriodRecord, numBins)
for i := range periodRecords {
periodRecords[i] = PeriodRecord{Index: uint32(i), Usage: 0}
}
a := Accountant{
accountID: accountID,
Expand All @@ -54,7 +54,7 @@ func NewAccountant(accountID string, reservation *core.ReservedPayment, onDemand
reservationWindow: reservationWindow,
pricePerSymbol: pricePerSymbol,
minNumSymbols: minNumSymbols,
binRecords: binRecords,
periodRecords: periodRecords,
cumulativePayment: big.NewInt(0),
numBins: max(numBins, uint32(meterer.MinNumBins)),
}
Expand All @@ -74,22 +74,22 @@ func (a *Accountant) BlobPaymentInfo(ctx context.Context, numSymbols uint32, quo

a.usageLock.Lock()
defer a.usageLock.Unlock()
relativeBinRecord := a.GetRelativeBinRecord(currentReservationPeriod)
relativeBinRecord.Usage += symbolUsage
relativePeriodRecord := a.GetRelativePeriodRecord(currentReservationPeriod)
relativePeriodRecord.Usage += symbolUsage

// first attempt to use the active reservation
binLimit := a.reservation.SymbolsPerSecond * uint64(a.reservationWindow)
if relativeBinRecord.Usage <= binLimit {
if relativePeriodRecord.Usage <= binLimit {
if err := QuorumCheck(quorumNumbers, a.reservation.QuorumNumbers); err != nil {
return 0, big.NewInt(0), err
}
return currentReservationPeriod, big.NewInt(0), nil
}

overflowBinRecord := a.GetRelativeBinRecord(currentReservationPeriod + 2)
overflowPeriodRecord := a.GetRelativePeriodRecord(currentReservationPeriod + 2)
// Allow one overflow when the overflow bin is empty, the current usage and new length are both less than the limit
if overflowBinRecord.Usage == 0 && relativeBinRecord.Usage-symbolUsage < binLimit && symbolUsage <= binLimit {
overflowBinRecord.Usage += relativeBinRecord.Usage - binLimit
if overflowPeriodRecord.Usage == 0 && relativePeriodRecord.Usage-symbolUsage < binLimit && symbolUsage <= binLimit {
overflowPeriodRecord.Usage += relativePeriodRecord.Usage - binLimit
if err := QuorumCheck(quorumNumbers, a.reservation.QuorumNumbers); err != nil {
return 0, big.NewInt(0), err
}
Expand All @@ -98,7 +98,7 @@ func (a *Accountant) BlobPaymentInfo(ctx context.Context, numSymbols uint32, quo

// reservation not available, rollback reservation records, attempt on-demand
//todo: rollback on-demand if disperser respond with some type of rejection?
relativeBinRecord.Usage -= symbolUsage
relativePeriodRecord.Usage -= symbolUsage
incrementRequired := big.NewInt(int64(a.PaymentCharged(numSymbols)))
a.cumulativePayment.Add(a.cumulativePayment, incrementRequired)
if a.cumulativePayment.Cmp(a.onDemand.CumulativePayment) <= 0 {
Expand Down Expand Up @@ -143,16 +143,16 @@ func (a *Accountant) SymbolsCharged(numSymbols uint32) uint32 {
return uint32(core.RoundUpDivide(uint(numSymbols), uint(a.minNumSymbols))) * a.minNumSymbols
}

func (a *Accountant) GetRelativeBinRecord(index uint32) *BinRecord {
func (a *Accountant) GetRelativePeriodRecord(index uint32) *PeriodRecord {
relativeIndex := index % a.numBins
if a.binRecords[relativeIndex].Index != uint32(index) {
a.binRecords[relativeIndex] = BinRecord{
if a.periodRecords[relativeIndex].Index != uint32(index) {
a.periodRecords[relativeIndex] = PeriodRecord{
Index: uint32(index),
Usage: 0,
}
}

return &a.binRecords[relativeIndex]
return &a.periodRecords[relativeIndex]
}

// SetPaymentState sets the accountant's state from the disperser's response
Expand Down Expand Up @@ -214,18 +214,18 @@ func (a *Accountant) SetPaymentState(paymentState *disperser_rpc.GetPaymentState
}
}

binRecords := make([]BinRecord, len(paymentState.GetBinRecords()))
for i, record := range paymentState.GetBinRecords() {
periodRecords := make([]PeriodRecord, len(paymentState.GetPeriodRecords()))
for i, record := range paymentState.GetPeriodRecords() {
if record == nil {
binRecords[i] = BinRecord{Index: 0, Usage: 0}
periodRecords[i] = PeriodRecord{Index: 0, Usage: 0}
} else {
binRecords[i] = BinRecord{
periodRecords[i] = PeriodRecord{
Index: record.Index,
Usage: record.Usage,
}
}
}
a.binRecords = binRecords
a.periodRecords = periodRecords
return nil
}

Expand Down
30 changes: 15 additions & 15 deletions api/clients/v2/accountant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestNewAccountant(t *testing.T) {
assert.Equal(t, reservationWindow, accountant.reservationWindow)
assert.Equal(t, pricePerSymbol, accountant.pricePerSymbol)
assert.Equal(t, minNumSymbols, accountant.minNumSymbols)
assert.Equal(t, []BinRecord{{Index: 0, Usage: 0}, {Index: 1, Usage: 0}, {Index: 2, Usage: 0}}, accountant.binRecords)
assert.Equal(t, []PeriodRecord{{Index: 0, Usage: 0}, {Index: 1, Usage: 0}, {Index: 2, Usage: 0}}, accountant.periodRecords)
assert.Equal(t, big.NewInt(0), accountant.cumulativePayment)
}

Expand Down Expand Up @@ -76,7 +76,7 @@ func TestAccountBlob_Reservation(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, meterer.GetReservationPeriod(uint64(time.Now().Unix()), reservationWindow), header.ReservationPeriod)
assert.Equal(t, big.NewInt(0), header.CumulativePayment)
assert.Equal(t, isRotation([]uint64{500, 0, 0}, mapRecordUsage(accountant.binRecords)), true)
assert.Equal(t, isRotation([]uint64{500, 0, 0}, mapRecordUsage(accountant.periodRecords)), true)

symbolLength = uint32(700)

Expand All @@ -85,7 +85,7 @@ func TestAccountBlob_Reservation(t *testing.T) {
assert.NoError(t, err)
assert.NotEqual(t, 0, header.ReservationPeriod)
assert.Equal(t, big.NewInt(0), header.CumulativePayment)
assert.Equal(t, isRotation([]uint64{1200, 0, 200}, mapRecordUsage(accountant.binRecords)), true)
assert.Equal(t, isRotation([]uint64{1200, 0, 200}, mapRecordUsage(accountant.periodRecords)), true)

// Second call should use on-demand payment
header, err = accountant.AccountBlob(ctx, 300, quorums, salt)
Expand Down Expand Up @@ -125,7 +125,7 @@ func TestAccountBlob_OnDemand(t *testing.T) {
expectedPayment := big.NewInt(int64(numSymbols * pricePerSymbol))
assert.Equal(t, uint32(0), header.ReservationPeriod)
assert.Equal(t, expectedPayment, header.CumulativePayment)
assert.Equal(t, isRotation([]uint64{0, 0, 0}, mapRecordUsage(accountant.binRecords)), true)
assert.Equal(t, isRotation([]uint64{0, 0, 0}, mapRecordUsage(accountant.periodRecords)), true)
assert.Equal(t, expectedPayment, accountant.cumulativePayment)
}

Expand Down Expand Up @@ -225,20 +225,20 @@ func TestAccountBlob_BinRotation(t *testing.T) {
// First call
_, err = accountant.AccountBlob(ctx, 800, quorums, salt)
assert.NoError(t, err)
assert.Equal(t, isRotation([]uint64{800, 0, 0}, mapRecordUsage(accountant.binRecords)), true)
assert.Equal(t, isRotation([]uint64{800, 0, 0}, mapRecordUsage(accountant.periodRecords)), true)

// next reservation duration
time.Sleep(1000 * time.Millisecond)

// Second call
_, err = accountant.AccountBlob(ctx, 300, quorums, salt)
assert.NoError(t, err)
assert.Equal(t, isRotation([]uint64{800, 300, 0}, mapRecordUsage(accountant.binRecords)), true)
assert.Equal(t, isRotation([]uint64{800, 300, 0}, mapRecordUsage(accountant.periodRecords)), true)

// Third call
_, err = accountant.AccountBlob(ctx, 500, quorums, salt)
assert.NoError(t, err)
assert.Equal(t, isRotation([]uint64{800, 800, 0}, mapRecordUsage(accountant.binRecords)), true)
assert.Equal(t, isRotation([]uint64{800, 800, 0}, mapRecordUsage(accountant.periodRecords)), true)
}

func TestConcurrentBinRotationAndAccountBlob(t *testing.T) {
Expand Down Expand Up @@ -279,7 +279,7 @@ func TestConcurrentBinRotationAndAccountBlob(t *testing.T) {
wg.Wait()

// Check final state
usages := mapRecordUsage(accountant.binRecords)
usages := mapRecordUsage(accountant.periodRecords)
assert.Equal(t, uint64(1000), usages[0]+usages[1]+usages[2])
}

Expand Down Expand Up @@ -313,22 +313,22 @@ func TestAccountBlob_ReservationWithOneOverflow(t *testing.T) {
assert.Equal(t, salt, header.Salt)
assert.Equal(t, meterer.GetReservationPeriod(uint64(now), reservationWindow), header.ReservationPeriod)
assert.Equal(t, big.NewInt(0), header.CumulativePayment)
assert.Equal(t, isRotation([]uint64{800, 0, 0}, mapRecordUsage(accountant.binRecords)), true)
assert.Equal(t, isRotation([]uint64{800, 0, 0}, mapRecordUsage(accountant.periodRecords)), true)

// Second call: Allow one overflow
header, err = accountant.AccountBlob(ctx, 500, quorums, salt+1)
assert.NoError(t, err)
assert.Equal(t, salt+1, header.Salt)
assert.Equal(t, big.NewInt(0), header.CumulativePayment)
assert.Equal(t, isRotation([]uint64{1300, 0, 300}, mapRecordUsage(accountant.binRecords)), true)
assert.Equal(t, isRotation([]uint64{1300, 0, 300}, mapRecordUsage(accountant.periodRecords)), true)

// Third call: Should use on-demand payment
header, err = accountant.AccountBlob(ctx, 200, quorums, salt+2)
assert.NoError(t, err)
assert.Equal(t, salt+2, header.Salt)
assert.Equal(t, uint32(0), header.ReservationPeriod)
assert.Equal(t, big.NewInt(200), header.CumulativePayment)
assert.Equal(t, isRotation([]uint64{1300, 0, 300}, mapRecordUsage(accountant.binRecords)), true)
assert.Equal(t, isRotation([]uint64{1300, 0, 300}, mapRecordUsage(accountant.periodRecords)), true)
}

func TestAccountBlob_ReservationOverflowReset(t *testing.T) {
Expand Down Expand Up @@ -357,12 +357,12 @@ func TestAccountBlob_ReservationOverflowReset(t *testing.T) {
// full reservation
_, err = accountant.AccountBlob(ctx, 1000, quorums, salt)
assert.NoError(t, err)
assert.Equal(t, isRotation([]uint64{1000, 0, 0}, mapRecordUsage(accountant.binRecords)), true)
assert.Equal(t, isRotation([]uint64{1000, 0, 0}, mapRecordUsage(accountant.periodRecords)), true)

// no overflow
header, err := accountant.AccountBlob(ctx, 500, quorums, salt)
assert.NoError(t, err)
assert.Equal(t, isRotation([]uint64{1000, 0, 0}, mapRecordUsage(accountant.binRecords)), true)
assert.Equal(t, isRotation([]uint64{1000, 0, 0}, mapRecordUsage(accountant.periodRecords)), true)
assert.Equal(t, big.NewInt(500), header.CumulativePayment)

// Wait for next reservation duration
Expand All @@ -371,7 +371,7 @@ func TestAccountBlob_ReservationOverflowReset(t *testing.T) {
// Third call: Should use new bin and allow overflow again
_, err = accountant.AccountBlob(ctx, 500, quorums, salt)
assert.NoError(t, err)
assert.Equal(t, isRotation([]uint64{1000, 500, 0}, mapRecordUsage(accountant.binRecords)), true)
assert.Equal(t, isRotation([]uint64{1000, 500, 0}, mapRecordUsage(accountant.periodRecords)), true)
}

func TestQuorumCheck(t *testing.T) {
Expand Down Expand Up @@ -431,7 +431,7 @@ func TestQuorumCheck(t *testing.T) {
}
}

func mapRecordUsage(records []BinRecord) []uint64 {
func mapRecordUsage(records []PeriodRecord) []uint64 {
return []uint64{records[0].Usage, records[1].Usage, records[2].Usage}
}

Expand Down
8 changes: 4 additions & 4 deletions api/docs/disperser_v2.html
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ <h2>Table of Contents</h2>
</li>

<li>
<a href="#disperser.v2.BinRecord"><span class="badge">M</span>BinRecord</a>
<a href="#disperser.v2.PeriodRecord"><span class="badge">M</span>PeriodRecord</a>
</li>

<li>
Expand Down Expand Up @@ -321,8 +321,8 @@ <h3 id="disperser.v2.Attestation">Attestation</h3>



<h3 id="disperser.v2.BinRecord">BinRecord</h3>
<p>BinRecord is the usage record of an account in a bin. The API should return the active bin </p><p>record and the subsequent two records that contains potential overflows.</p>
<h3 id="disperser.v2.PeriodRecord">PeriodRecord</h3>
<p>PeriodRecord is the usage record of an account in a bin. The API should return the active bin </p><p>record and the subsequent two records that contains potential overflows.</p>


<table class="field-table">
Expand Down Expand Up @@ -586,7 +586,7 @@ <h3 id="disperser.v2.GetPaymentStateReply">GetPaymentStateReply</h3>

<tr>
<td>bin_records</td>
<td><a href="#disperser.v2.BinRecord">BinRecord</a></td>
<td><a href="#disperser.v2.PeriodRecord">PeriodRecord</a></td>
<td>repeated</td>
<td><p>off-chain account reservation usage records </p></td>
</tr>
Expand Down
10 changes: 5 additions & 5 deletions api/docs/disperser_v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

- [disperser/v2/disperser_v2.proto](#disperser_v2_disperser_v2-proto)
- [Attestation](#disperser-v2-Attestation)
- [BinRecord](#disperser-v2-BinRecord)
- [PeriodRecord](#disperser-v2-PeriodRecord)
- [BlobCommitmentReply](#disperser-v2-BlobCommitmentReply)
- [BlobCommitmentRequest](#disperser-v2-BlobCommitmentRequest)
- [BlobStatusReply](#disperser-v2-BlobStatusReply)
Expand Down Expand Up @@ -54,10 +54,10 @@



<a name="disperser-v2-BinRecord"></a>
<a name="disperser-v2-PeriodRecord"></a>

### BinRecord
BinRecord is the usage record of an account in a bin. The API should return the active bin
### PeriodRecord
PeriodRecord is the usage record of an account in a bin. The API should return the active bin
record and the subsequent two records that contains potential overflows.


Expand Down Expand Up @@ -192,7 +192,7 @@ GetPaymentStateReply contains the payment state of an account.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| payment_global_params | [PaymentGlobalParams](#disperser-v2-PaymentGlobalParams) | | global payment vault parameters |
| bin_records | [BinRecord](#disperser-v2-BinRecord) | repeated | off-chain account reservation usage records |
| bin_records | [PeriodRecord](#disperser-v2-PeriodRecord) | repeated | off-chain account reservation usage records |
| reservation | [Reservation](#disperser-v2-Reservation) | | on-chain account reservation setting |
| cumulative_payment | [bytes](#bytes) | | off-chain on-demand payment usage |
| onchain_cumulative_payment | [bytes](#bytes) | | on-chain on-demand payment deposited |
Expand Down
8 changes: 4 additions & 4 deletions api/docs/eigenda-protos.html
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ <h2>Table of Contents</h2>
</li>

<li>
<a href="#disperser.v2.BinRecord"><span class="badge">M</span>BinRecord</a>
<a href="#disperser.v2.PeriodRecord"><span class="badge">M</span>PeriodRecord</a>
</li>

<li>
Expand Down Expand Up @@ -2015,8 +2015,8 @@ <h3 id="disperser.v2.Attestation">Attestation</h3>



<h3 id="disperser.v2.BinRecord">BinRecord</h3>
<p>BinRecord is the usage record of an account in a bin. The API should return the active bin </p><p>record and the subsequent two records that contains potential overflows.</p>
<h3 id="disperser.v2.PeriodRecord">PeriodRecord</h3>
<p>PeriodRecord is the usage record of an account in a bin. The API should return the active bin </p><p>record and the subsequent two records that contains potential overflows.</p>


<table class="field-table">
Expand Down Expand Up @@ -2280,7 +2280,7 @@ <h3 id="disperser.v2.GetPaymentStateReply">GetPaymentStateReply</h3>

<tr>
<td>bin_records</td>
<td><a href="#disperser.v2.BinRecord">BinRecord</a></td>
<td><a href="#disperser.v2.PeriodRecord">PeriodRecord</a></td>
<td>repeated</td>
<td><p>off-chain account reservation usage records </p></td>
</tr>
Expand Down
10 changes: 5 additions & 5 deletions api/docs/eigenda-protos.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@

- [disperser/v2/disperser_v2.proto](#disperser_v2_disperser_v2-proto)
- [Attestation](#disperser-v2-Attestation)
- [BinRecord](#disperser-v2-BinRecord)
- [PeriodRecord](#disperser-v2-PeriodRecord)
- [BlobCommitmentReply](#disperser-v2-BlobCommitmentReply)
- [BlobCommitmentRequest](#disperser-v2-BlobCommitmentRequest)
- [BlobStatusReply](#disperser-v2-BlobStatusReply)
Expand Down Expand Up @@ -762,10 +762,10 @@ If DisperseBlob returns the following error codes: INVALID_ARGUMENT (400): reque



<a name="disperser-v2-BinRecord"></a>
<a name="disperser-v2-PeriodRecord"></a>

### BinRecord
BinRecord is the usage record of an account in a bin. The API should return the active bin
### PeriodRecord
PeriodRecord is the usage record of an account in a bin. The API should return the active bin
record and the subsequent two records that contains potential overflows.


Expand Down Expand Up @@ -900,7 +900,7 @@ GetPaymentStateReply contains the payment state of an account.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| payment_global_params | [PaymentGlobalParams](#disperser-v2-PaymentGlobalParams) | | global payment vault parameters |
| bin_records | [BinRecord](#disperser-v2-BinRecord) | repeated | off-chain account reservation usage records |
| bin_records | [PeriodRecord](#disperser-v2-PeriodRecord) | repeated | off-chain account reservation usage records |
| reservation | [Reservation](#disperser-v2-Reservation) | | on-chain account reservation setting |
| cumulative_payment | [bytes](#bytes) | | off-chain on-demand payment usage |
| onchain_cumulative_payment | [bytes](#bytes) | | on-chain on-demand payment deposited |
Expand Down
Loading

0 comments on commit b367b9e

Please sign in to comment.