Skip to content

Commit 6e14aed

Browse files
committed
Revert "fix: make disperser client backwards compatible (#1686)"
This reverts commit 26c612f.
1 parent ec3aff1 commit 6e14aed

File tree

4 files changed

+10
-203
lines changed

4 files changed

+10
-203
lines changed

api/clients/v2/disperser_client.go

Lines changed: 1 addition & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ import (
1717
"github.com/Layr-Labs/eigenda/encoding/rs"
1818
"github.com/Layr-Labs/eigensdk-go/logging"
1919
"github.com/docker/go-units"
20-
gethcommon "github.com/ethereum/go-ethereum/common"
2120
"google.golang.org/grpc"
22-
"google.golang.org/grpc/codes"
23-
"google.golang.org/grpc/status"
2421
)
2522

2623
type DisperserClientConfig struct {
@@ -393,135 +390,7 @@ func (c *disperserClient) GetPaymentState(ctx context.Context) (*disperser_rpc.G
393390
Signature: signature,
394391
Timestamp: timestamp,
395392
}
396-
allQuorumsReply, err := c.client.GetPaymentStateForAllQuorums(ctx, request)
397-
if err != nil {
398-
// Check if error is "method not found" or "unimplemented"
399-
if isMethodNotFoundError(err) {
400-
// Fall back to old method
401-
return c.getPaymentStateFromLegacyAPI(ctx, accountID, signature, timestamp)
402-
}
403-
return nil, err
404-
}
405-
406-
return allQuorumsReply, nil
407-
}
408-
409-
// this is true if we are targeting a disperser that hasn't upgraded to the new API yet.
410-
func isMethodNotFoundError(err error) bool {
411-
if st, ok := status.FromError(err); ok {
412-
return st.Code() == codes.Unimplemented
413-
}
414-
return false
415-
}
416-
417-
// getPaymentStateFromLegacyAPI retrieves the payment state from the legacy GetPaymentState grpc method.
418-
// It is needed until we have upgraded all dispersers (testnet and mainnet) to the new API.
419-
// Check those endpoints for GetPaymentStateForAllQuorums using:
420-
// `grpcurl disperser-testnet-holesky.eigenda.xyz:443 list disperser.v2.Disperser`
421-
// `grpcurl disperser.eigenda.xyz:443 list disperser.v2.Disperser`
422-
func (c *disperserClient) getPaymentStateFromLegacyAPI(
423-
ctx context.Context, accountID gethcommon.Address, signature []byte, timestamp uint64,
424-
) (*disperser_rpc.GetPaymentStateForAllQuorumsReply, error) {
425-
oldRequest := &disperser_rpc.GetPaymentStateRequest{
426-
AccountId: accountID.Hex(),
427-
Signature: signature,
428-
Timestamp: timestamp,
429-
}
430-
431-
oldResult, err := c.client.GetPaymentState(ctx, oldRequest)
432-
if err != nil {
433-
return nil, err
434-
}
435-
436-
return convertLegacyPaymentStateToNew(oldResult)
437-
}
438-
439-
// convertLegacyPaymentStateToNew converts the old GetPaymentStateReply to the new GetPaymentStateForAllQuorumsReply format
440-
func convertLegacyPaymentStateToNew(legacyReply *disperser_rpc.GetPaymentStateReply) (*disperser_rpc.GetPaymentStateForAllQuorumsReply, error) {
441-
442-
if legacyReply.PaymentGlobalParams == nil {
443-
return nil, fmt.Errorf("legacy payment state received from disperser does not contain global params")
444-
}
445-
// Convert PaymentGlobalParams to PaymentVaultParams
446-
var paymentVaultParams *disperser_rpc.PaymentVaultParams
447-
{
448-
paymentVaultParams = &disperser_rpc.PaymentVaultParams{
449-
QuorumPaymentConfigs: make(map[uint32]*disperser_rpc.PaymentQuorumConfig),
450-
QuorumProtocolConfigs: make(map[uint32]*disperser_rpc.PaymentQuorumProtocolConfig),
451-
OnDemandQuorumNumbers: legacyReply.PaymentGlobalParams.OnDemandQuorumNumbers,
452-
}
453-
454-
// Apply the global params to all quorums, both on-demand and reservation.
455-
onDemandQuorums := legacyReply.PaymentGlobalParams.OnDemandQuorumNumbers
456-
if len(onDemandQuorums) == 0 {
457-
return nil, fmt.Errorf("no on-demand quorums specified in legacy PaymentGlobalParams received from disperser")
458-
}
459-
reservationQuorums := legacyReply.Reservation.QuorumNumbers
460-
// There may be overlapping quorums but it doesn't matter since we will apply the same global params to all of them.
461-
allQuorums := append(reservationQuorums, onDemandQuorums...)
462-
463-
for _, quorumID := range allQuorums {
464-
paymentVaultParams.QuorumPaymentConfigs[quorumID] = &disperser_rpc.PaymentQuorumConfig{
465-
ReservationSymbolsPerSecond: 0, // Not available in legacy format
466-
OnDemandSymbolsPerSecond: legacyReply.PaymentGlobalParams.GlobalSymbolsPerSecond,
467-
OnDemandPricePerSymbol: legacyReply.PaymentGlobalParams.PricePerSymbol,
468-
}
469-
470-
paymentVaultParams.QuorumProtocolConfigs[quorumID] = &disperser_rpc.PaymentQuorumProtocolConfig{
471-
MinNumSymbols: legacyReply.PaymentGlobalParams.MinNumSymbols,
472-
// ReservationAdvanceWindow is not used offchain at the moment so it's okay to set to any value.
473-
ReservationAdvanceWindow: 0,
474-
ReservationRateLimitWindow: legacyReply.PaymentGlobalParams.ReservationWindow,
475-
OnDemandRateLimitWindow: 0, // Not available in legacy format
476-
}
477-
}
478-
479-
for _, quorumID := range onDemandQuorums {
480-
paymentVaultParams.QuorumProtocolConfigs[quorumID].OnDemandEnabled = true
481-
}
482-
}
483-
484-
// If no reservation is available, return early with only payment vault params and cumulative payment info.
485-
if legacyReply.Reservation == nil {
486-
return &disperser_rpc.GetPaymentStateForAllQuorumsReply{
487-
PaymentVaultParams: paymentVaultParams,
488-
CumulativePayment: legacyReply.CumulativePayment,
489-
OnchainCumulativePayment: legacyReply.OnchainCumulativePayment,
490-
}, nil
491-
}
492-
493-
// Otherwise there is a reservation available, so we need to convert it to the per-quorum format.
494-
495-
// We first make sure that the disperser returned valid data.
496-
if len(legacyReply.PeriodRecords) == 0 {
497-
return nil, fmt.Errorf("legacy payment state received from disperser does not contain period records")
498-
}
499-
if len(legacyReply.Reservation.QuorumNumbers) == 0 {
500-
return nil, fmt.Errorf("legacy payment state received from disperser does not contain reservation quorums")
501-
}
502-
503-
reservations := make(map[uint32]*disperser_rpc.QuorumReservation)
504-
periodRecords := make(map[uint32]*disperser_rpc.PeriodRecords)
505-
506-
// Apply the reservation to all reservationQuorums mentioned in the reservation
507-
for _, quorumID := range legacyReply.Reservation.QuorumNumbers {
508-
reservations[quorumID] = &disperser_rpc.QuorumReservation{
509-
SymbolsPerSecond: legacyReply.Reservation.SymbolsPerSecond,
510-
StartTimestamp: legacyReply.Reservation.StartTimestamp,
511-
EndTimestamp: legacyReply.Reservation.EndTimestamp,
512-
}
513-
periodRecords[quorumID] = &disperser_rpc.PeriodRecords{
514-
Records: legacyReply.PeriodRecords,
515-
}
516-
}
517-
518-
return &disperser_rpc.GetPaymentStateForAllQuorumsReply{
519-
PaymentVaultParams: paymentVaultParams,
520-
PeriodRecords: periodRecords,
521-
Reservations: reservations,
522-
CumulativePayment: legacyReply.CumulativePayment,
523-
OnchainCumulativePayment: legacyReply.OnchainCumulativePayment,
524-
}, nil
393+
return c.client.GetPaymentStateForAllQuorums(ctx, request)
525394
}
526395

527396
// GetBlobCommitment is a utility method that calculates commitment for a blob payload.

api/grpc/disperser/v2/disperser_v2.pb.go

Lines changed: 4 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/proto/disperser/v2/disperser_v2.proto

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,6 @@ message BlobCommitmentReply {
134134
}
135135

136136
// GetPaymentStateRequest contains parameters to query the payment state of an account.
137-
// GetPaymentStateForAllQuorumsRequest is a separate message type even though it currently contains the same fields,
138-
// because we follow buf's best practices and linting rules which recommend every RPC having its own request and reply types,
139-
// to allow for evolution of the API without breaking changes: https://buf.build/docs/lint/rules/#rpc_no_server_streaming
140137
message GetPaymentStateRequest {
141138
// The ID of the account being queried. This account ID is an eth wallet address of the user.
142139
string account_id = 1;
@@ -163,21 +160,12 @@ message GetPaymentStateReply {
163160
// global payment vault parameters
164161
PaymentGlobalParams payment_global_params = 1;
165162
// off-chain account reservation usage records
166-
// Should be empty if reservation.quorum_numbers is empty (i.e. no reservation exists for the account).
167163
repeated PeriodRecord period_records = 2;
168164
// on-chain account reservation setting
169165
Reservation reservation = 3;
170-
// off-chain on-demand payment usage.
171-
// The bytes are parsed to a big.Int value.
172-
// This value should always be <= onchain_cumulative_payment.
173-
// See [common.v2.PaymentHeader.cumulative_payment] for more details.
174-
//
175-
// This value should only be nonzero for the EigenLabs disperser, as it is the only disperser that supports on-demand payments currently.
176-
// Future work will support decentralized on-demand dispersals.
166+
// off-chain on-demand payment usage
177167
bytes cumulative_payment = 4;
178168
// on-chain on-demand payment deposited
179-
// The bytes are parsed to a big.Int value.
180-
// See [common.v2.PaymentHeader.cumulative_payment] for more details.
181169
bytes onchain_cumulative_payment = 5;
182170
}
183171

@@ -190,23 +178,14 @@ message GetPaymentStateForAllQuorumsReply {
190178
// payment vault parameters with per-quorum configurations
191179
PaymentVaultParams payment_vault_params = 1;
192180
// period_records maps quorum IDs to the off-chain account reservation usage records for the current and next two periods
193-
// Should contain the same number of entries as the `reservations` field.
194181
map<uint32, PeriodRecords> period_records = 2;
195182
// reservations maps quorum IDs to the on-chain account reservation record
196-
// Should contain the same number of entries as the `period_records` field.
197183
map<uint32, QuorumReservation> reservations = 3;
198-
// off-chain on-demand payment usage.
199-
// The bytes are parsed to a big.Int value.
200-
// This value should always be <= onchain_cumulative_payment.
201-
// See [common.v2.PaymentHeader.cumulative_payment] for more details.
202-
//
203-
// This value should only be nonzero for the EigenLabs disperser, as it is the only disperser that supports on-demand payments currently.
204-
// Future work will support decentralized on-demand dispersals.
184+
// off-chain on-demand payment usage. This field is currently only tracked by EigenLabs disperser because on-demand requests are only
185+
// supported by EigenLabs. Future work will support decentralized on-demand dispersals and this field later be tracked and shared by
186+
// dispersers unlimited to EigenLabs.
205187
bytes cumulative_payment = 4;
206188
// on-chain on-demand payment deposited.
207-
// The bytes are parsed to a big.Int value.
208-
// This value should always be >= cumulative_payment.
209-
// See [common.v2.PaymentHeader.cumulative_payment] for more details.
210189
bytes onchain_cumulative_payment = 5;
211190
}
212191

@@ -362,8 +341,6 @@ message PaymentQuorumProtocolConfig {
362341
uint64 min_num_symbols = 1;
363342

364343
// reservation_advance_window is the window in seconds before a reservation starts that it can be activated
365-
// It is added here for offchain to have access to all onchain data structs, but it isn't currently used,
366-
// and might get removed in the future.
367344
uint64 reservation_advance_window = 2;
368345

369346
// reservation_rate_limit_window is the time window in seconds for reservation rate limiting

disperser/apiserver/server_v2.go

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -298,22 +298,6 @@ func (s *DispersalServerV2) GetPaymentState(ctx context.Context, req *pb.GetPaym
298298
return nil, err
299299
}
300300

301-
return convertAllQuorumsReplyToLegacy(allQuorumsReply), nil
302-
}
303-
304-
// convertAllQuorumsReplyToLegacy converts the new per-quorum payment state format to the legacy aggregated format.
305-
// This enables backwards compatibility by flattening multi-quorum data into a single legacy response,
306-
// allowing old clients to continue working properly.
307-
//
308-
// Conversion logic:
309-
// - PaymentVaultParams: Uses quorum 0 configuration as the global parameters (arbitrary choice)
310-
// - Reservations: Finds the most restrictive reservation across all quorums (minimum symbols/sec, latest start, earliest end)
311-
// - PeriodRecords: Selects the highest usage for each period index across all quorums
312-
// - OnDemand cumulative payment amounts: Passed through unchanged as they represent account-level totals
313-
//
314-
// This conversion may result in information loss for clients that need per-quorum details,
315-
// but preserves the most restrictive constraints to ensure client behavior remains within reservation or ondemand.
316-
func convertAllQuorumsReplyToLegacy(allQuorumsReply *pb.GetPaymentStateForAllQuorumsReply) *pb.GetPaymentStateReply {
317301
// For PaymentVaultParams, use quorum 0 for protocol level parameters and on-demand quorum numbers
318302
var paymentGlobalParams *pb.PaymentGlobalParams
319303
if allQuorumsReply.PaymentVaultParams != nil &&
@@ -400,7 +384,7 @@ func convertAllQuorumsReplyToLegacy(allQuorumsReply *pb.GetPaymentStateForAllQuo
400384
Reservation: reservation,
401385
CumulativePayment: allQuorumsReply.CumulativePayment,
402386
OnchainCumulativePayment: allQuorumsReply.OnchainCumulativePayment,
403-
}
387+
}, nil
404388
}
405389

406390
// GetPaymentStateForAllQuorums returns payment state for all quorums including vault parameters,

0 commit comments

Comments
 (0)