diff --git a/api/clients/v2/accountant.go b/api/clients/v2/accountant.go index 02dd58d9f6..31f8863fd1 100644 --- a/api/clients/v2/accountant.go +++ b/api/clients/v2/accountant.go @@ -26,15 +26,15 @@ type Accountant struct { // local accounting // contains 3 bins; circular wrapping of indices - binRecords []BinRecord - usageLock sync.Mutex - cumulativePayment *big.Int + reservationPeriodRecords []ReservationPeriodRecord + usageLock sync.Mutex + cumulativePayment *big.Int - // number of bins in the circular accounting, restricted by minNumBins which is 3 + // number of bins in the circular accounting, restricted by MinNumPeriods which is 3 numBins uint32 } -type BinRecord struct { +type ReservationPeriodRecord struct { Index uint32 Usage uint64 } @@ -43,20 +43,20 @@ 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} + reservationPeriodRecords := make([]ReservationPeriodRecord, numBins) + for i := range reservationPeriodRecords { + reservationPeriodRecords[i] = ReservationPeriodRecord{Index: uint32(i), Usage: 0} } a := Accountant{ - accountID: accountID, - reservation: reservation, - onDemand: onDemand, - reservationWindow: reservationWindow, - pricePerSymbol: pricePerSymbol, - minNumSymbols: minNumSymbols, - binRecords: binRecords, - cumulativePayment: big.NewInt(0), - numBins: max(numBins, uint32(meterer.MinNumBins)), + accountID: accountID, + reservation: reservation, + onDemand: onDemand, + reservationWindow: reservationWindow, + pricePerSymbol: pricePerSymbol, + minNumSymbols: minNumSymbols, + reservationPeriodRecords: reservationPeriodRecords, + cumulativePayment: big.NewInt(0), + numBins: max(numBins, uint32(meterer.MinNumPeriods)), } // TODO: add a routine to refresh the on-chain state occasionally? return &a @@ -67,39 +67,39 @@ func NewAccountant(accountID string, reservation *core.ReservedPayment, onDemand // then on-demand if the reservation is not available. The returned values are // reservation period for reservation payments and cumulative payment for on-demand payments, // and both fields are used to create the payment header and signature -func (a *Accountant) BlobPaymentInfo(ctx context.Context, numSymbols uint32, quorumNumbers []uint8) (uint32, *big.Int, error) { +func (a *Accountant) BlobPaymentInfo(ctx context.Context, numSymbols uint64, quorumNumbers []uint8) (uint32, *big.Int, error) { now := time.Now().Unix() currentReservationPeriod := meterer.GetReservationPeriod(uint64(now), a.reservationWindow) - symbolUsage := uint64(a.SymbolsCharged(numSymbols)) + symbolUsage := uint64(a.SymbolsCharged(uint32(numSymbols))) a.usageLock.Lock() defer a.usageLock.Unlock() - relativeBinRecord := a.GetRelativeBinRecord(currentReservationPeriod) - relativeBinRecord.Usage += symbolUsage + relativeReservationPeriodRecord := a.GetRelativeReservationPeriodRecord(currentReservationPeriod) + relativeReservationPeriodRecord.Usage += symbolUsage // first attempt to use the active reservation binLimit := a.reservation.SymbolsPerSecond * uint64(a.reservationWindow) - if relativeBinRecord.Usage <= binLimit { + if relativeReservationPeriodRecord.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) + overflowReservationPeriodRecord := a.GetRelativeReservationPeriodRecord(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 overflowReservationPeriodRecord.Usage == 0 && relativeReservationPeriodRecord.Usage-symbolUsage < binLimit && symbolUsage <= binLimit { + overflowReservationPeriodRecord.Usage += relativeReservationPeriodRecord.Usage - binLimit if err := QuorumCheck(quorumNumbers, a.reservation.QuorumNumbers); err != nil { return 0, big.NewInt(0), err } return currentReservationPeriod, big.NewInt(0), nil } - // reservation not available, rollback reservation records, attempt on-demand - //todo: rollback on-demand if disperser respond with some type of rejection? - relativeBinRecord.Usage -= symbolUsage - incrementRequired := big.NewInt(int64(a.PaymentCharged(numSymbols))) + // reservation not available, attempt on-demand + //todo: rollback later if disperser respond with some type of rejection? + relativeReservationPeriodRecord.Usage -= symbolUsage + incrementRequired := big.NewInt(int64(a.PaymentCharged(uint32(numSymbols)))) a.cumulativePayment.Add(a.cumulativePayment, incrementRequired) if a.cumulativePayment.Cmp(a.onDemand.CumulativePayment) <= 0 { if err := QuorumCheck(quorumNumbers, requiredQuorums); err != nil { @@ -111,7 +111,7 @@ func (a *Accountant) BlobPaymentInfo(ctx context.Context, numSymbols uint32, quo } // AccountBlob accountant provides and records payment information -func (a *Accountant) AccountBlob(ctx context.Context, numSymbols uint32, quorums []uint8, salt uint32) (*core.PaymentMetadata, error) { +func (a *Accountant) AccountBlob(ctx context.Context, numSymbols uint64, quorums []uint8, salt uint32) (*core.PaymentMetadata, error) { reservationPeriod, cumulativePayment, err := a.BlobPaymentInfo(ctx, numSymbols, quorums) if err != nil { return nil, err @@ -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) GetRelativeReservationPeriodRecord(index uint32) *ReservationPeriodRecord { relativeIndex := index % a.numBins - if a.binRecords[relativeIndex].Index != uint32(index) { - a.binRecords[relativeIndex] = BinRecord{ + if a.reservationPeriodRecords[relativeIndex].Index != uint32(index) { + a.reservationPeriodRecords[relativeIndex] = ReservationPeriodRecord{ Index: uint32(index), Usage: 0, } } - return &a.binRecords[relativeIndex] + return &a.reservationPeriodRecords[relativeIndex] } // SetPaymentState sets the accountant's state from the disperser's response @@ -214,18 +214,18 @@ func (a *Accountant) SetPaymentState(paymentState *disperser_rpc.GetPaymentState } } - binRecords := make([]BinRecord, len(paymentState.GetBinRecords())) - for i, record := range paymentState.GetBinRecords() { + reservationPeriodRecords := make([]ReservationPeriodRecord, len(paymentState.GetReservationPeriodRecords())) + for i, record := range paymentState.GetReservationPeriodRecords() { if record == nil { - binRecords[i] = BinRecord{Index: 0, Usage: 0} + reservationPeriodRecords[i] = ReservationPeriodRecord{Index: 0, Usage: 0} } else { - binRecords[i] = BinRecord{ + reservationPeriodRecords[i] = ReservationPeriodRecord{ Index: record.Index, Usage: record.Usage, } } } - a.binRecords = binRecords + a.reservationPeriodRecords = reservationPeriodRecords return nil } diff --git a/api/clients/v2/accountant_test.go b/api/clients/v2/accountant_test.go index ac8672ff5f..94e5714c5b 100644 --- a/api/clients/v2/accountant_test.go +++ b/api/clients/v2/accountant_test.go @@ -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, []ReservationPeriodRecord{{Index: 0, Usage: 0}, {Index: 1, Usage: 0}, {Index: 2, Usage: 0}}, accountant.reservationPeriodRecords) assert.Equal(t, big.NewInt(0), accountant.cumulativePayment) } @@ -68,7 +68,7 @@ func TestAccountBlob_Reservation(t *testing.T) { accountant := NewAccountant(accountId, reservation, onDemand, reservationWindow, pricePerSymbol, minNumSymbols, numBins) ctx := context.Background() - symbolLength := uint32(500) + symbolLength := uint64(500) quorums := []uint8{0, 1} header, err := accountant.AccountBlob(ctx, symbolLength, quorums, salt) @@ -76,16 +76,16 @@ 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.reservationPeriodRecords)), true) - symbolLength = uint32(700) + symbolLength = uint64(700) header, err = accountant.AccountBlob(ctx, symbolLength, quorums, salt) 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.reservationPeriodRecords)), true) // Second call should use on-demand payment header, err = accountant.AccountBlob(ctx, 300, quorums, salt) @@ -116,16 +116,16 @@ func TestAccountBlob_OnDemand(t *testing.T) { accountant := NewAccountant(accountId, reservation, onDemand, reservationWindow, pricePerSymbol, minNumSymbols, numBins) ctx := context.Background() - numSymbols := uint32(1500) + numSymbols := uint64(1500) quorums := []uint8{0, 1} header, err := accountant.AccountBlob(ctx, numSymbols, quorums, salt) assert.NoError(t, err) - expectedPayment := big.NewInt(int64(numSymbols * pricePerSymbol)) + expectedPayment := big.NewInt(int64(numSymbols * uint64(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.reservationPeriodRecords)), true) assert.Equal(t, expectedPayment, accountant.cumulativePayment) } @@ -144,7 +144,7 @@ func TestAccountBlob_InsufficientOnDemand(t *testing.T) { accountant := NewAccountant(accountId, reservation, onDemand, reservationWindow, pricePerSymbol, minNumSymbols, numBins) ctx := context.Background() - numSymbols := uint32(2000) + numSymbols := uint64(2000) quorums := []uint8{0, 1} _, err = accountant.AccountBlob(ctx, numSymbols, quorums, salt) @@ -225,7 +225,7 @@ 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.reservationPeriodRecords)), true) // next reservation duration time.Sleep(1000 * time.Millisecond) @@ -233,12 +233,12 @@ func TestAccountBlob_BinRotation(t *testing.T) { // 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.reservationPeriodRecords)), 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.reservationPeriodRecords)), true) } func TestConcurrentBinRotationAndAccountBlob(t *testing.T) { @@ -279,7 +279,7 @@ func TestConcurrentBinRotationAndAccountBlob(t *testing.T) { wg.Wait() // Check final state - usages := mapRecordUsage(accountant.binRecords) + usages := mapRecordUsage(accountant.reservationPeriodRecords) assert.Equal(t, uint64(1000), usages[0]+usages[1]+usages[2]) } @@ -313,14 +313,14 @@ 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.reservationPeriodRecords)), 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.reservationPeriodRecords)), true) // Third call: Should use on-demand payment header, err = accountant.AccountBlob(ctx, 200, quorums, salt+2) @@ -328,7 +328,7 @@ func TestAccountBlob_ReservationWithOneOverflow(t *testing.T) { 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.reservationPeriodRecords)), true) } func TestAccountBlob_ReservationOverflowReset(t *testing.T) { @@ -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.reservationPeriodRecords)), 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.reservationPeriodRecords)), true) assert.Equal(t, big.NewInt(500), header.CumulativePayment) // Wait for next reservation duration @@ -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.reservationPeriodRecords)), true) } func TestQuorumCheck(t *testing.T) { @@ -431,7 +431,7 @@ func TestQuorumCheck(t *testing.T) { } } -func mapRecordUsage(records []BinRecord) []uint64 { +func mapRecordUsage(records []ReservationPeriodRecord) []uint64 { return []uint64{records[0].Usage, records[1].Usage, records[2].Usage} } diff --git a/api/clients/v2/disperser_client.go b/api/clients/v2/disperser_client.go index 3ef20404be..eb78c7da93 100644 --- a/api/clients/v2/disperser_client.go +++ b/api/clients/v2/disperser_client.go @@ -139,7 +139,7 @@ func (c *disperserClient) DisperseBlob( } symbolLength := encoding.GetBlobLengthPowerOf2(uint(len(data))) - payment, err := c.accountant.AccountBlob(ctx, uint32(symbolLength), quorums, salt) + payment, err := c.accountant.AccountBlob(ctx, uint64(symbolLength), quorums, salt) if err != nil { return nil, [32]byte{}, fmt.Errorf("error accounting blob: %w", err) } diff --git a/api/docs/disperser_v2.html b/api/docs/disperser_v2.html index 50b3685d72..d975346a5d 100644 --- a/api/docs/disperser_v2.html +++ b/api/docs/disperser_v2.html @@ -182,10 +182,6 @@
BinRecord 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.
- - -Field | Type | Label | Description |
index | -uint32 | -- |
|
-
usage | -uint64 | -- |
|
-
off-chain account reservation usage records
ReservationPeriodRecord 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.
+ + +Field | Type | Label | Description |
index | +uint32 | ++ |
|
+
usage | +uint64 | ++ |
|
+
SignedBatch is a batch of blobs with a signature.
diff --git a/api/docs/disperser_v2.md b/api/docs/disperser_v2.md index 0ca84f3b0d..5424a041bb 100644 --- a/api/docs/disperser_v2.md +++ b/api/docs/disperser_v2.md @@ -5,7 +5,6 @@ - [disperser/v2/disperser_v2.proto](#disperser_v2_disperser_v2-proto) - [Attestation](#disperser-v2-Attestation) - - [BinRecord](#disperser-v2-BinRecord) - [BlobCommitmentReply](#disperser-v2-BlobCommitmentReply) - [BlobCommitmentRequest](#disperser-v2-BlobCommitmentRequest) - [BlobStatusReply](#disperser-v2-BlobStatusReply) @@ -17,6 +16,7 @@ - [GetPaymentStateRequest](#disperser-v2-GetPaymentStateRequest) - [PaymentGlobalParams](#disperser-v2-PaymentGlobalParams) - [Reservation](#disperser-v2-Reservation) + - [ReservationPeriodRecord](#disperser-v2-ReservationPeriodRecord) - [SignedBatch](#disperser-v2-SignedBatch) - [BlobStatus](#disperser-v2-BlobStatus) @@ -54,23 +54,6 @@ - - -### BinRecord -BinRecord 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. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| index | [uint32](#uint32) | | | -| usage | [uint64](#uint64) | | | - - - - - - ### BlobCommitmentReply @@ -192,7 +175,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 | +| reservation_period_records | [ReservationPeriodRecord](#disperser-v2-ReservationPeriodRecord) | 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 | @@ -256,6 +239,23 @@ GetPaymentStateRequest contains parameters to query the payment state of an acco + + +### ReservationPeriodRecord +ReservationPeriodRecord 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. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| index | [uint32](#uint32) | | | +| usage | [uint64](#uint64) | | | + + + + + + ### SignedBatch diff --git a/api/docs/eigenda-protos.html b/api/docs/eigenda-protos.html index 44474db3c8..53e5fcd704 100644 --- a/api/docs/eigenda-protos.html +++ b/api/docs/eigenda-protos.html @@ -350,10 +350,6 @@BinRecord 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.
- - -Field | Type | Label | Description |
index | -uint32 | -- |
|
-
usage | -uint64 | -- |
|
-
off-chain account reservation usage records
ReservationPeriodRecord 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.
+ + +Field | Type | Label | Description |
index | +uint32 | ++ |
|
+
usage | +uint64 | ++ |
|
+
SignedBatch is a batch of blobs with a signature.
diff --git a/api/docs/eigenda-protos.md b/api/docs/eigenda-protos.md index 60d2a21c90..b49dbf0d08 100644 --- a/api/docs/eigenda-protos.md +++ b/api/docs/eigenda-protos.md @@ -47,7 +47,6 @@ - [disperser/v2/disperser_v2.proto](#disperser_v2_disperser_v2-proto) - [Attestation](#disperser-v2-Attestation) - - [BinRecord](#disperser-v2-BinRecord) - [BlobCommitmentReply](#disperser-v2-BlobCommitmentReply) - [BlobCommitmentRequest](#disperser-v2-BlobCommitmentRequest) - [BlobStatusReply](#disperser-v2-BlobStatusReply) @@ -59,6 +58,7 @@ - [GetPaymentStateRequest](#disperser-v2-GetPaymentStateRequest) - [PaymentGlobalParams](#disperser-v2-PaymentGlobalParams) - [Reservation](#disperser-v2-Reservation) + - [ReservationPeriodRecord](#disperser-v2-ReservationPeriodRecord) - [SignedBatch](#disperser-v2-SignedBatch) - [BlobStatus](#disperser-v2-BlobStatus) @@ -756,23 +756,6 @@ If DisperseBlob returns the following error codes: INVALID_ARGUMENT (400): reque - - -### BinRecord -BinRecord 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. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| index | [uint32](#uint32) | | | -| usage | [uint64](#uint64) | | | - - - - - - ### BlobCommitmentReply @@ -894,7 +877,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 | +| reservation_period_records | [ReservationPeriodRecord](#disperser-v2-ReservationPeriodRecord) | 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 | @@ -958,6 +941,23 @@ GetPaymentStateRequest contains parameters to query the payment state of an acco + + +### ReservationPeriodRecord +ReservationPeriodRecord 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. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| index | [uint32](#uint32) | | | +| usage | [uint64](#uint64) | | | + + + + + + ### SignedBatch diff --git a/api/grpc/disperser/v2/disperser_v2.pb.go b/api/grpc/disperser/v2/disperser_v2.pb.go index 4fb9718f65..8356625dac 100644 --- a/api/grpc/disperser/v2/disperser_v2.pb.go +++ b/api/grpc/disperser/v2/disperser_v2.pb.go @@ -488,7 +488,7 @@ type GetPaymentStateReply struct { // global payment vault parameters PaymentGlobalParams *PaymentGlobalParams `protobuf:"bytes,1,opt,name=payment_global_params,json=paymentGlobalParams,proto3" json:"payment_global_params,omitempty"` // off-chain account reservation usage records - BinRecords []*BinRecord `protobuf:"bytes,2,rep,name=bin_records,json=binRecords,proto3" json:"bin_records,omitempty"` + ReservationPeriodRecords []*ReservationPeriodRecord `protobuf:"bytes,2,rep,name=reservation_period_records,json=reservationPeriodRecords,proto3" json:"reservation_period_records,omitempty"` // on-chain account reservation setting Reservation *Reservation `protobuf:"bytes,3,opt,name=reservation,proto3" json:"reservation,omitempty"` // off-chain on-demand payment usage @@ -536,9 +536,9 @@ func (x *GetPaymentStateReply) GetPaymentGlobalParams() *PaymentGlobalParams { return nil } -func (x *GetPaymentStateReply) GetBinRecords() []*BinRecord { +func (x *GetPaymentStateReply) GetReservationPeriodRecords() []*ReservationPeriodRecord { if x != nil { - return x.BinRecords + return x.ReservationPeriodRecords } return nil } @@ -941,9 +941,9 @@ func (x *Reservation) GetQuorumSplits() []uint32 { return nil } -// BinRecord is the usage record of an account in a bin. The API should return the active bin +// ReservationPeriodRecord 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. -type BinRecord struct { +type ReservationPeriodRecord struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -952,8 +952,8 @@ type BinRecord struct { Usage uint64 `protobuf:"varint,2,opt,name=usage,proto3" json:"usage,omitempty"` } -func (x *BinRecord) Reset() { - *x = BinRecord{} +func (x *ReservationPeriodRecord) Reset() { + *x = ReservationPeriodRecord{} if protoimpl.UnsafeEnabled { mi := &file_disperser_v2_disperser_v2_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -961,13 +961,13 @@ func (x *BinRecord) Reset() { } } -func (x *BinRecord) String() string { +func (x *ReservationPeriodRecord) String() string { return protoimpl.X.MessageStringOf(x) } -func (*BinRecord) ProtoMessage() {} +func (*ReservationPeriodRecord) ProtoMessage() {} -func (x *BinRecord) ProtoReflect() protoreflect.Message { +func (x *ReservationPeriodRecord) ProtoReflect() protoreflect.Message { mi := &file_disperser_v2_disperser_v2_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -979,19 +979,19 @@ func (x *BinRecord) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use BinRecord.ProtoReflect.Descriptor instead. -func (*BinRecord) Descriptor() ([]byte, []int) { +// Deprecated: Use ReservationPeriodRecord.ProtoReflect.Descriptor instead. +func (*ReservationPeriodRecord) Descriptor() ([]byte, []int) { return file_disperser_v2_disperser_v2_proto_rawDescGZIP(), []int{13} } -func (x *BinRecord) GetIndex() uint32 { +func (x *ReservationPeriodRecord) GetIndex() uint32 { if x != nil { return x.Index } return 0 } -func (x *BinRecord) GetUsage() uint64 { +func (x *ReservationPeriodRecord) GetUsage() uint64 { if x != nil { return x.Usage } @@ -1049,129 +1049,133 @@ var file_disperser_v2_disperser_v2_proto_rawDesc = []byte{ 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xd1, 0x02, 0x0a, 0x14, + 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xfc, 0x02, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x55, 0x0a, 0x15, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x13, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x47, - 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x38, 0x0a, 0x0b, 0x62, - 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, - 0x42, 0x69, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x0a, 0x62, 0x69, 0x6e, 0x52, 0x65, - 0x63, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x64, 0x69, 0x73, - 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, - 0x5f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, - 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, - 0x74, 0x12, 0x3c, 0x0a, 0x1a, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x75, 0x6d, - 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x18, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x75, - 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x22, - 0x7a, 0x0a, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x2e, - 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x3b, - 0x0a, 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, - 0x76, 0x32, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, - 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa5, 0x01, 0x0a, 0x14, - 0x42, 0x6c, 0x6f, 0x62, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x45, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x63, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x62, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, - 0x6c, 0x6f, 0x62, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x09, 0x62, 0x6c, 0x6f, 0x62, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, - 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, - 0x6f, 0x6f, 0x66, 0x22, 0xec, 0x01, 0x0a, 0x0b, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x6e, 0x6f, 0x6e, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, - 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, - 0x10, 0x6e, 0x6f, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, - 0x73, 0x12, 0x15, 0x0a, 0x06, 0x61, 0x70, 0x6b, 0x5f, 0x67, 0x32, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x05, 0x61, 0x70, 0x6b, 0x47, 0x32, 0x12, 0x1f, 0x0a, 0x0b, 0x71, 0x75, 0x6f, 0x72, - 0x75, 0x6d, 0x5f, 0x61, 0x70, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x71, - 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x41, 0x70, 0x6b, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x69, 0x67, - 0x6d, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x69, 0x67, 0x6d, 0x61, 0x12, - 0x25, 0x0a, 0x0e, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0d, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x4e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x3a, 0x0a, 0x19, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, - 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, - 0x67, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x17, 0x71, 0x75, 0x6f, 0x72, 0x75, - 0x6d, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, - 0x65, 0x73, 0x22, 0x8a, 0x02, 0x0a, 0x13, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x47, 0x6c, - 0x6f, 0x62, 0x61, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x39, 0x0a, 0x19, 0x67, 0x6c, - 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x5f, 0x70, 0x65, 0x72, - 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x67, - 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x50, 0x65, 0x72, 0x53, - 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x5f, 0x6e, 0x75, 0x6d, - 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, - 0x6d, 0x69, 0x6e, 0x4e, 0x75, 0x6d, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x12, 0x28, 0x0a, - 0x10, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, - 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x70, 0x72, 0x69, 0x63, 0x65, 0x50, 0x65, - 0x72, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, 0x73, 0x65, 0x72, - 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x11, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x12, 0x37, 0x0a, 0x18, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x6d, - 0x61, 0x6e, 0x64, 0x5f, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x15, 0x6f, 0x6e, 0x44, 0x65, 0x6d, 0x61, - 0x6e, 0x64, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, - 0xd5, 0x01, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x2c, 0x0a, 0x12, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, - 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x73, 0x79, 0x6d, - 0x62, 0x6f, 0x6c, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x27, 0x0a, - 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x65, - 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x71, - 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0d, 0x52, 0x0d, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x4e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x73, 0x70, 0x6c, - 0x69, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0c, 0x71, 0x75, 0x6f, 0x72, 0x75, - 0x6d, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x73, 0x22, 0x37, 0x0a, 0x09, 0x42, 0x69, 0x6e, 0x52, 0x65, - 0x63, 0x6f, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x73, - 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, - 0x2a, 0x6a, 0x0a, 0x0a, 0x42, 0x6c, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, - 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x51, - 0x55, 0x45, 0x55, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x4e, 0x43, 0x4f, 0x44, - 0x45, 0x44, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, - 0x1b, 0x0a, 0x17, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, - 0x53, 0x49, 0x47, 0x4e, 0x41, 0x54, 0x55, 0x52, 0x45, 0x53, 0x10, 0x05, 0x32, 0xf2, 0x02, 0x0a, - 0x09, 0x44, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x12, 0x54, 0x0a, 0x0c, 0x44, 0x69, - 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x21, 0x2e, 0x64, 0x69, 0x73, - 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x69, 0x73, 0x70, 0x65, 0x72, - 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, - 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x69, 0x73, - 0x70, 0x65, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, - 0x12, 0x51, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x1f, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x32, - 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, - 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, - 0x79, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, - 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, - 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x6c, 0x6f, - 0x62, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x24, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, - 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x64, 0x69, - 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, - 0x00, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x4c, 0x61, 0x79, 0x72, 0x2d, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x65, 0x69, 0x67, 0x65, 0x6e, 0x64, - 0x61, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x64, 0x69, 0x73, 0x70, 0x65, - 0x72, 0x73, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x63, 0x0a, 0x1a, 0x72, + 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, + 0x64, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x52, + 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, + 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x18, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, + 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, + 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, + 0x12, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x63, 0x75, 0x6d, 0x75, 0x6c, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x1a, + 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, + 0x76, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x18, 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x7a, 0x0a, 0x0b, 0x53, 0x69, + 0x67, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x2e, 0x0a, 0x06, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x0b, 0x61, 0x74, 0x74, + 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x74, + 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa5, 0x01, 0x0a, 0x14, 0x42, 0x6c, 0x6f, 0x62, 0x56, + 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x45, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x0f, 0x62, 0x6c, 0x6f, 0x62, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x62, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, + 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0xec, + 0x01, 0x0a, 0x0b, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, + 0x0a, 0x12, 0x6e, 0x6f, 0x6e, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, + 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x10, 0x6e, 0x6f, 0x6e, 0x53, + 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x15, 0x0a, 0x06, + 0x61, 0x70, 0x6b, 0x5f, 0x67, 0x32, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x61, 0x70, + 0x6b, 0x47, 0x32, 0x12, 0x1f, 0x0a, 0x0b, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x61, 0x70, + 0x6b, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, + 0x41, 0x70, 0x6b, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x69, 0x67, 0x6d, 0x61, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x69, 0x67, 0x6d, 0x61, 0x12, 0x25, 0x0a, 0x0e, 0x71, 0x75, + 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x0d, 0x52, 0x0d, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x12, 0x3a, 0x0a, 0x19, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x73, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x73, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x17, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x53, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x73, 0x22, 0x8a, 0x02, + 0x0a, 0x13, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x39, 0x0a, 0x19, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, + 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, + 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x5f, 0x6e, 0x75, 0x6d, 0x5f, 0x73, 0x79, 0x6d, 0x62, + 0x6f, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x4e, 0x75, + 0x6d, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x70, 0x72, 0x69, 0x63, + 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0e, 0x70, 0x72, 0x69, 0x63, 0x65, 0x50, 0x65, 0x72, 0x53, 0x79, 0x6d, 0x62, + 0x6f, 0x6c, 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, + 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x12, 0x37, 0x0a, 0x18, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x71, + 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0d, 0x52, 0x15, 0x6f, 0x6e, 0x44, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x51, 0x75, 0x6f, + 0x72, 0x75, 0x6d, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0xd5, 0x01, 0x0a, 0x0b, 0x52, + 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x79, + 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x50, + 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, + 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0d, + 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x23, 0x0a, + 0x0d, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0c, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x53, 0x70, 0x6c, 0x69, + 0x74, 0x73, 0x22, 0x45, 0x0a, 0x17, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x14, 0x0a, + 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x2a, 0x6a, 0x0a, 0x0a, 0x42, 0x6c, 0x6f, + 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, + 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x51, 0x55, 0x45, 0x55, 0x45, 0x44, 0x10, 0x01, + 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0d, 0x0a, + 0x09, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, + 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, 0x1b, 0x0a, 0x17, 0x49, 0x4e, 0x53, 0x55, + 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41, 0x54, 0x55, + 0x52, 0x45, 0x53, 0x10, 0x05, 0x32, 0xf2, 0x02, 0x0a, 0x09, 0x44, 0x69, 0x73, 0x70, 0x65, 0x72, + 0x73, 0x65, 0x72, 0x12, 0x54, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x42, + 0x6c, 0x6f, 0x62, 0x12, 0x21, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, + 0x76, 0x32, 0x2e, 0x44, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, + 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x42, 0x6c, + 0x6f, 0x62, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0d, 0x47, 0x65, 0x74, + 0x42, 0x6c, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x2e, 0x64, 0x69, 0x73, + 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x64, 0x69, + 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x11, + 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, + 0x74, 0x12, 0x23, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x32, + 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, + 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x0f, 0x47, + 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x24, + 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, + 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, + 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4c, 0x61, 0x79, 0x72, 0x2d, 0x4c, 0x61, + 0x62, 0x73, 0x2f, 0x65, 0x69, 0x67, 0x65, 0x6e, 0x64, 0x61, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, + 0x72, 0x70, 0x63, 0x2f, 0x64, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x65, 0x72, 0x2f, 0x76, 0x32, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1189,25 +1193,25 @@ func file_disperser_v2_disperser_v2_proto_rawDescGZIP() []byte { var file_disperser_v2_disperser_v2_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_disperser_v2_disperser_v2_proto_msgTypes = make([]protoimpl.MessageInfo, 14) var file_disperser_v2_disperser_v2_proto_goTypes = []interface{}{ - (BlobStatus)(0), // 0: disperser.v2.BlobStatus - (*DisperseBlobRequest)(nil), // 1: disperser.v2.DisperseBlobRequest - (*DisperseBlobReply)(nil), // 2: disperser.v2.DisperseBlobReply - (*BlobStatusRequest)(nil), // 3: disperser.v2.BlobStatusRequest - (*BlobStatusReply)(nil), // 4: disperser.v2.BlobStatusReply - (*BlobCommitmentRequest)(nil), // 5: disperser.v2.BlobCommitmentRequest - (*BlobCommitmentReply)(nil), // 6: disperser.v2.BlobCommitmentReply - (*GetPaymentStateRequest)(nil), // 7: disperser.v2.GetPaymentStateRequest - (*GetPaymentStateReply)(nil), // 8: disperser.v2.GetPaymentStateReply - (*SignedBatch)(nil), // 9: disperser.v2.SignedBatch - (*BlobVerificationInfo)(nil), // 10: disperser.v2.BlobVerificationInfo - (*Attestation)(nil), // 11: disperser.v2.Attestation - (*PaymentGlobalParams)(nil), // 12: disperser.v2.PaymentGlobalParams - (*Reservation)(nil), // 13: disperser.v2.Reservation - (*BinRecord)(nil), // 14: disperser.v2.BinRecord - (*v2.BlobHeader)(nil), // 15: common.v2.BlobHeader - (*common.BlobCommitment)(nil), // 16: common.BlobCommitment - (*v2.BatchHeader)(nil), // 17: common.v2.BatchHeader - (*v2.BlobCertificate)(nil), // 18: common.v2.BlobCertificate + (BlobStatus)(0), // 0: disperser.v2.BlobStatus + (*DisperseBlobRequest)(nil), // 1: disperser.v2.DisperseBlobRequest + (*DisperseBlobReply)(nil), // 2: disperser.v2.DisperseBlobReply + (*BlobStatusRequest)(nil), // 3: disperser.v2.BlobStatusRequest + (*BlobStatusReply)(nil), // 4: disperser.v2.BlobStatusReply + (*BlobCommitmentRequest)(nil), // 5: disperser.v2.BlobCommitmentRequest + (*BlobCommitmentReply)(nil), // 6: disperser.v2.BlobCommitmentReply + (*GetPaymentStateRequest)(nil), // 7: disperser.v2.GetPaymentStateRequest + (*GetPaymentStateReply)(nil), // 8: disperser.v2.GetPaymentStateReply + (*SignedBatch)(nil), // 9: disperser.v2.SignedBatch + (*BlobVerificationInfo)(nil), // 10: disperser.v2.BlobVerificationInfo + (*Attestation)(nil), // 11: disperser.v2.Attestation + (*PaymentGlobalParams)(nil), // 12: disperser.v2.PaymentGlobalParams + (*Reservation)(nil), // 13: disperser.v2.Reservation + (*ReservationPeriodRecord)(nil), // 14: disperser.v2.ReservationPeriodRecord + (*v2.BlobHeader)(nil), // 15: common.v2.BlobHeader + (*common.BlobCommitment)(nil), // 16: common.BlobCommitment + (*v2.BatchHeader)(nil), // 17: common.v2.BatchHeader + (*v2.BlobCertificate)(nil), // 18: common.v2.BlobCertificate } var file_disperser_v2_disperser_v2_proto_depIdxs = []int32{ 15, // 0: disperser.v2.DisperseBlobRequest.blob_header:type_name -> common.v2.BlobHeader @@ -1217,7 +1221,7 @@ var file_disperser_v2_disperser_v2_proto_depIdxs = []int32{ 10, // 4: disperser.v2.BlobStatusReply.blob_verification_info:type_name -> disperser.v2.BlobVerificationInfo 16, // 5: disperser.v2.BlobCommitmentReply.blob_commitment:type_name -> common.BlobCommitment 12, // 6: disperser.v2.GetPaymentStateReply.payment_global_params:type_name -> disperser.v2.PaymentGlobalParams - 14, // 7: disperser.v2.GetPaymentStateReply.bin_records:type_name -> disperser.v2.BinRecord + 14, // 7: disperser.v2.GetPaymentStateReply.reservation_period_records:type_name -> disperser.v2.ReservationPeriodRecord 13, // 8: disperser.v2.GetPaymentStateReply.reservation:type_name -> disperser.v2.Reservation 17, // 9: disperser.v2.SignedBatch.header:type_name -> common.v2.BatchHeader 11, // 10: disperser.v2.SignedBatch.attestation:type_name -> disperser.v2.Attestation @@ -1400,7 +1404,7 @@ func file_disperser_v2_disperser_v2_proto_init() { } } file_disperser_v2_disperser_v2_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BinRecord); i { + switch v := v.(*ReservationPeriodRecord); i { case 0: return &v.state case 1: diff --git a/api/proto/disperser/v2/disperser_v2.proto b/api/proto/disperser/v2/disperser_v2.proto index 0cae0f0d1b..7765e5040b 100644 --- a/api/proto/disperser/v2/disperser_v2.proto +++ b/api/proto/disperser/v2/disperser_v2.proto @@ -79,7 +79,7 @@ message GetPaymentStateReply { // global payment vault parameters PaymentGlobalParams payment_global_params = 1; // off-chain account reservation usage records - repeated BinRecord bin_records = 2; + repeated ReservationPeriodRecord reservation_period_records = 2; // on-chain account reservation setting Reservation reservation = 3; // off-chain on-demand payment usage @@ -169,9 +169,9 @@ message Reservation { repeated uint32 quorum_splits = 5; } -// BinRecord is the usage record of an account in a bin. The API should return the active bin +// ReservationPeriodRecord 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. -message BinRecord { +message ReservationPeriodRecord { uint32 index = 1; uint64 usage = 2; } diff --git a/core/meterer/meterer.go b/core/meterer/meterer.go index f9b9dfd3b7..7794d458ed 100644 --- a/core/meterer/meterer.go +++ b/core/meterer/meterer.go @@ -18,8 +18,8 @@ type Config struct { // ChainReadTimeout is the timeout for reading payment state from chain ChainReadTimeout time.Duration - // UpdateInterval is the interval for refreshing the on-chain state - UpdateInterval time.Duration + // OnchainUpdateInterval is the interval for refreshing the on-chain state + OnchainUpdateInterval time.Duration } // Meterer handles payment accounting across different accounts. Disperser API server receives requests from clients and each request contains a blob header @@ -51,10 +51,10 @@ func NewMeterer( } } -// Start starts to periodically refreshing the on-chain state +// Start starts to periodically refreshing the on-chain state and pruning the off-chain state func (m *Meterer) Start(ctx context.Context) { go func() { - ticker := time.NewTicker(m.UpdateInterval) + ticker := time.NewTicker(m.OnchainUpdateInterval) defer ticker.Stop() for { @@ -108,9 +108,9 @@ func (m *Meterer) ServeReservationRequest(ctx context.Context, header core.Payme return fmt.Errorf("invalid reservation period for reservation") } - // Update bin usage atomically and check against reservation's data rate as the bin limit - if err := m.IncrementBinUsage(ctx, header, reservation, numSymbols); err != nil { - return fmt.Errorf("bin overflows: %w", err) + // Update reservation period usage atomically and check against reservation's data rate as the period limit + if err := m.IncrementReservatiionPeriodUsage(ctx, header, reservation, numSymbols); err != nil { + return fmt.Errorf("period overflows: %w", err) } return nil @@ -140,46 +140,46 @@ func (m *Meterer) ValidateReservationPeriod(header core.PaymentMetadata, reserva now := uint64(time.Now().Unix()) reservationWindow := m.ChainPaymentState.GetReservationWindow() currentReservationPeriod := GetReservationPeriod(now, reservationWindow) - // Valid reservation periodes are either the current bin or the previous bin + // Valid reservation periods are either the current period or the previous period if (header.ReservationPeriod != currentReservationPeriod && header.ReservationPeriod != (currentReservationPeriod-1)) || (GetReservationPeriod(reservation.StartTimestamp, reservationWindow) > header.ReservationPeriod || header.ReservationPeriod > GetReservationPeriod(reservation.EndTimestamp, reservationWindow)) { return false } return true } -// IncrementBinUsage increments the bin usage atomically and checks for overflow -func (m *Meterer) IncrementBinUsage(ctx context.Context, header core.PaymentMetadata, reservation *core.ReservedPayment, numSymbols uint) error { +// IncrementReservatiionPeriodUsage increments the reservation period usage atomically and checks for overflow +func (m *Meterer) IncrementReservatiionPeriodUsage(ctx context.Context, header core.PaymentMetadata, reservation *core.ReservedPayment, numSymbols uint) error { symbolsCharged := m.SymbolsCharged(numSymbols) - newUsage, err := m.OffchainStore.UpdateReservationBin(ctx, header.AccountID, uint64(header.ReservationPeriod), uint64(symbolsCharged)) + newUsage, err := m.OffchainStore.UpdateReservationPeriod(ctx, header.AccountID, uint64(header.ReservationPeriod), uint64(symbolsCharged)) if err != nil { - return fmt.Errorf("failed to increment bin usage: %w", err) + return fmt.Errorf("failed to increment reservation period usage: %w", err) } - // metered usage stays within the bin limit - usageLimit := m.GetReservationBinLimit(reservation) + // metered usage stays within the period limit + usageLimit := m.GetReservationPeriodLimit(reservation) if newUsage <= usageLimit { return nil } else if newUsage-uint64(symbolsCharged) >= usageLimit { // metered usage before updating the size already exceeded the limit - return fmt.Errorf("bin has already been filled") + return fmt.Errorf("period has already been filled") } if newUsage <= 2*usageLimit && header.ReservationPeriod+2 <= GetReservationPeriod(reservation.EndTimestamp, m.ChainPaymentState.GetReservationWindow()) { - _, err := m.OffchainStore.UpdateReservationBin(ctx, header.AccountID, uint64(header.ReservationPeriod+2), newUsage-usageLimit) + _, err := m.OffchainStore.UpdateReservationPeriod(ctx, header.AccountID, uint64(header.ReservationPeriod+2), newUsage-usageLimit) if err != nil { return err } return nil } - return fmt.Errorf("overflow usage exceeds bin limit") + return fmt.Errorf("overflow usage exceeds period limit") } -// GetReservationPeriod returns the current reservation period by chunking time by the bin interval; +// GetReservationPeriod returns the current reservation period by chunking time by the period interval; // bin interval used by the disperser should be public information -func GetReservationPeriod(timestamp uint64, binInterval uint32) uint32 { - if binInterval == 0 { +func GetReservationPeriod(timestamp uint64, periodInterval uint32) uint32 { + if periodInterval == 0 { return 0 } - return uint32(timestamp) / binInterval + return uint32(timestamp) / periodInterval } // ServeOnDemandRequest handles the rate limiting logic for incoming requests @@ -207,8 +207,8 @@ func (m *Meterer) ServeOnDemandRequest(ctx context.Context, header core.PaymentM return fmt.Errorf("invalid on-demand payment: %w", err) } - // Update bin usage atomically and check against bin capacity - if err := m.IncrementGlobalBinUsage(ctx, uint64(symbolsCharged)); err != nil { + // Update reservation period usage atomically and check against period capacity + if err := m.IncrementGlobalPeriodUsage(ctx, uint64(symbolsCharged)); err != nil { //TODO: conditionally remove the payment based on the error type (maybe if the error is store-op related) dbErr := m.OffchainStore.RemoveOnDemandPayment(ctx, header.AccountID, header.CumulativePayment) if dbErr != nil { @@ -265,21 +265,21 @@ func (m *Meterer) SymbolsCharged(numSymbols uint) uint32 { return uint32(core.RoundUpDivide(uint(numSymbols), uint(m.ChainPaymentState.GetMinNumSymbols()))) * m.ChainPaymentState.GetMinNumSymbols() } -// IncrementBinUsage increments the bin usage atomically and checks for overflow -func (m *Meterer) IncrementGlobalBinUsage(ctx context.Context, symbolsCharged uint64) error { +// IncrementGlobalPeriodUsage increments the period usage atomically and checks for overflow +func (m *Meterer) IncrementGlobalPeriodUsage(ctx context.Context, symbolsCharged uint64) error { globalPeriod := GetReservationPeriod(uint64(time.Now().Unix()), m.ChainPaymentState.GetGlobalRatePeriodInterval()) - newUsage, err := m.OffchainStore.UpdateGlobalBin(ctx, globalPeriod, symbolsCharged) + newUsage, err := m.OffchainStore.UpdateGlobalPeriod(ctx, globalPeriod, symbolsCharged) if err != nil { - return fmt.Errorf("failed to increment global bin usage: %w", err) + return fmt.Errorf("failed to increment global reservation period usage: %w", err) } if newUsage > m.ChainPaymentState.GetGlobalSymbolsPerSecond()*uint64(m.ChainPaymentState.GetGlobalRatePeriodInterval()) { - return fmt.Errorf("global bin usage overflows") + return fmt.Errorf("global reservation period usage overflows") } return nil } -// GetReservationBinLimit returns the bin limit for a given reservation -func (m *Meterer) GetReservationBinLimit(reservation *core.ReservedPayment) uint64 { +// GetReservationPeriodLimit returns the period limit for a given reservation +func (m *Meterer) GetReservationPeriodLimit(reservation *core.ReservedPayment) uint64 { return reservation.SymbolsPerSecond * uint64(m.ChainPaymentState.GetReservationWindow()) } diff --git a/core/meterer/meterer_test.go b/core/meterer/meterer_test.go index 0f9c16569c..8f15087008 100644 --- a/core/meterer/meterer_test.go +++ b/core/meterer/meterer_test.go @@ -110,8 +110,8 @@ func setup(_ *testing.M) { logger = logging.NewNoopLogger() config := meterer.Config{ - ChainReadTimeout: 3 * time.Second, - UpdateInterval: 1 * time.Second, + ChainReadTimeout: 1 * time.Second, + OnchainUpdateInterval: 1 * time.Second, } err = meterer.CreateReservationTable(clientConfig, reservationTableName) @@ -145,6 +145,8 @@ func setup(_ *testing.M) { reservationTableName, ondemandTableName, globalReservationTableName, + uint64(100), + uint64(100), logger, ) @@ -202,14 +204,14 @@ func TestMetererReservations(t *testing.T) { err := mt.MeterRequest(ctx, *header, 1000, []uint8{0, 1, 2}) assert.ErrorContains(t, err, "quorum number mismatch") - // overwhelming bin overflow for empty bins + // overwhelming period overflow for empty periods header = createPaymentHeader(reservationPeriod-1, big.NewInt(0), accountID2) err = mt.MeterRequest(ctx, *header, 10, quoromNumbers) assert.NoError(t, err) - // overwhelming bin overflow for empty bins + // overwhelming period overflow for empty periods header = createPaymentHeader(reservationPeriod-1, big.NewInt(0), accountID2) err = mt.MeterRequest(ctx, *header, 1000, quoromNumbers) - assert.ErrorContains(t, err, "overflow usage exceeds bin limit") + assert.ErrorContains(t, err, "overflow usage exceeds period limit") // test non-existent account unregisteredUser, err := crypto.GenerateKey() @@ -231,7 +233,7 @@ func TestMetererReservations(t *testing.T) { err = mt.MeterRequest(ctx, *header, 2000, quoromNumbers) assert.ErrorContains(t, err, "invalid reservation period for reservation") - // test bin usage metering + // test period usage metering symbolLength := uint(20) requiredLength := uint(21) // 21 should be charged for length of 20 since minNumSymbols is 3 for i := 0; i < 9; i++ { @@ -245,7 +247,7 @@ func TestMetererReservations(t *testing.T) { assert.NoError(t, err) assert.Equal(t, accountID2.Hex(), item["AccountID"].(*types.AttributeValueMemberS).Value) assert.Equal(t, strconv.Itoa(int(reservationPeriod)), item["ReservationPeriod"].(*types.AttributeValueMemberN).Value) - assert.Equal(t, strconv.Itoa((i+1)*int(requiredLength)), item["BinUsage"].(*types.AttributeValueMemberN).Value) + assert.Equal(t, strconv.Itoa((i+1)*int(requiredLength)), item["PeriodUsage"].(*types.AttributeValueMemberN).Value) } // first over flow is allowed @@ -262,13 +264,13 @@ func TestMetererReservations(t *testing.T) { assert.Equal(t, accountID2.Hex(), item["AccountID"].(*types.AttributeValueMemberS).Value) assert.Equal(t, strconv.Itoa(int(overflowedReservationPeriod)), item["ReservationPeriod"].(*types.AttributeValueMemberN).Value) // 25 rounded up to the nearest multiple of minNumSymbols - (200-21*9) = 16 - assert.Equal(t, strconv.Itoa(int(16)), item["BinUsage"].(*types.AttributeValueMemberN).Value) + assert.Equal(t, strconv.Itoa(int(16)), item["PeriodUsage"].(*types.AttributeValueMemberN).Value) // second over flow header = createPaymentHeader(reservationPeriod, big.NewInt(0), accountID2) assert.NoError(t, err) err = mt.MeterRequest(ctx, *header, 1, quoromNumbers) - assert.ErrorContains(t, err, "bin has already been filled") + assert.ErrorContains(t, err, "period has already been filled") } func TestMetererOnDemand(t *testing.T) { diff --git a/core/meterer/offchain_store.go b/core/meterer/offchain_store.go index 5899ca75e9..5022f80ce5 100644 --- a/core/meterer/offchain_store.go +++ b/core/meterer/offchain_store.go @@ -17,15 +17,16 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" ) -const MinNumBins int32 = 3 +const MinNumPeriods int32 = 3 type OffchainStore struct { - dynamoClient commondynamodb.Client - reservationTableName string - onDemandTableName string - globalBinTableName string - logger logging.Logger - // TODO: add maximum storage for both tables + dynamoClient commondynamodb.Client + reservationTableName string + onDemandTableName string + globalBinTableName string + logger logging.Logger + MaxOnDemandStorage uint64 + MaxReservationPeriods uint64 } func NewOffchainStore( @@ -33,6 +34,8 @@ func NewOffchainStore( reservationTableName string, onDemandTableName string, globalBinTableName string, + maxOnDemandStorage uint64, + maxReservationPeriods uint64, logger logging.Logger, ) (OffchainStore, error) { @@ -45,80 +48,95 @@ func NewOffchainStore( if err != nil { return OffchainStore{}, err } + err = dynamoClient.TableExists(context.Background(), onDemandTableName) if err != nil { return OffchainStore{}, err } + err = dynamoClient.TableExists(context.Background(), globalBinTableName) if err != nil { return OffchainStore{}, err } + //TODO: add a separate thread to periodically clean up the tables - // delete expired reservation bins (