diff --git a/api/clients/accountant.go b/api/clients/accountant.go index d70b323238..9e0ade2e91 100644 --- a/api/clients/accountant.go +++ b/api/clients/accountant.go @@ -8,6 +8,7 @@ import ( "sync" "time" + disperser_rpc "github.com/Layr-Labs/eigenda/api/grpc/disperser/v2" "github.com/Layr-Labs/eigenda/core" "github.com/Layr-Labs/eigenda/core/meterer" ) @@ -158,6 +159,37 @@ func (a *accountant) GetRelativeBinRecord(index uint32) *BinRecord { return &a.binRecords[relativeIndex] } +func (a *accountant) SetPaymentState(paymentState *disperser_rpc.GetPaymentStateReply) { + a.minNumSymbols = uint32(paymentState.PaymentGlobalParams.MinNumSymbols) + + a.onDemand.CumulativePayment = new(big.Int).SetBytes(paymentState.OnchainCumulativePayment) + a.cumulativePayment = new(big.Int).SetBytes(paymentState.CumulativePayment) + a.pricePerSymbol = uint32(paymentState.PaymentGlobalParams.PricePerSymbol) + + a.reservation.SymbolsPerSec = uint64(paymentState.PaymentGlobalParams.GlobalSymbolsPerSecond) + a.reservation.StartTimestamp = uint64(paymentState.Reservation.StartTimestamp) + a.reservation.EndTimestamp = uint64(paymentState.Reservation.EndTimestamp) + a.reservationWindow = uint32(paymentState.PaymentGlobalParams.ReservationWindow) + quorumNumbers := make([]uint8, len(paymentState.Reservation.QuorumNumbers)) + for i, quorum := range paymentState.Reservation.QuorumNumbers { + quorumNumbers[i] = uint8(quorum) + } + a.reservation.QuorumNumbers = quorumNumbers + quorumSplit := make([]uint8, len(paymentState.Reservation.QuorumSplit)) + for i, quorum := range paymentState.Reservation.QuorumSplit { + quorumSplit[i] = uint8(quorum) + } + a.reservation.QuorumSplit = quorumSplit + binRecords := make([]BinRecord, len(paymentState.BinRecords)) + for i, record := range paymentState.BinRecords { + binRecords[i] = BinRecord{ + Index: record.Index, + Usage: record.Usage, + } + } + a.binRecords = binRecords +} + // QuorumCheck eagerly returns error if the check finds a quorum number not an element of the allowed quorum numbers func QuorumCheck(quorumNumbers []uint8, allowedNumbers []uint8) error { if len(quorumNumbers) == 0 { diff --git a/api/clients/disperser_client_v2.go b/api/clients/disperser_client_v2.go index 1378014707..6098007a94 100644 --- a/api/clients/disperser_client_v2.go +++ b/api/clients/disperser_client_v2.go @@ -35,7 +35,7 @@ type disperserClientV2 struct { conn *grpc.ClientConn client disperser_rpc.DisperserClient prover encoding.Prover - accountant Accountant + accountant *accountant } var _ DisperserClientV2 = &disperserClientV2{} @@ -60,7 +60,7 @@ var _ DisperserClientV2 = &disperserClientV2{} // // // Subsequent calls will use the existing connection // status2, blobKey2, err := client.DisperseBlob(ctx, data, blobHeader) -func NewDisperserClientV2(config *DisperserClientV2Config, signer corev2.BlobRequestSigner, prover encoding.Prover, accountant Accountant) (*disperserClientV2, error) { +func NewDisperserClientV2(config *DisperserClientV2Config, signer corev2.BlobRequestSigner, prover encoding.Prover) (*disperserClientV2, error) { if config == nil { return nil, api.NewErrorInvalidArg("config must be provided") } @@ -74,6 +74,8 @@ func NewDisperserClientV2(config *DisperserClientV2Config, signer corev2.BlobReq return nil, api.NewErrorInvalidArg("signer must be provided") } + accountant := &accountant{} + return &disperserClientV2{ config: config, signer: signer, @@ -83,6 +85,17 @@ func NewDisperserClientV2(config *DisperserClientV2Config, signer corev2.BlobReq }, nil } +// PopulateAccountant populates the accountant with the payment state from the disperser. +// This function is required to be called before using the accountant. Perhaps rename to Start()? +func (c *disperserClientV2) PopulateAccountant(ctx context.Context) error { + paymentState, err := c.GetPaymentState(ctx) + if err != nil { + return fmt.Errorf("error getting payment state for initializing accountant: %w", err) + } + c.accountant.SetPaymentState(paymentState) + return nil +} + // Close closes the grpc connection to the disperser server. // It is thread safe and can be called multiple times. func (c *disperserClientV2) Close() error { @@ -199,6 +212,30 @@ func (c *disperserClientV2) GetBlobStatus(ctx context.Context, blobKey corev2.Bl return c.client.GetBlobStatus(ctx, request) } +// GetPaymentState returns the payment state of the disperser client +func (c *disperserClientV2) GetPaymentState(ctx context.Context) (*disperser_rpc.GetPaymentStateReply, error) { + err := c.initOnceGrpcConnection() + if err != nil { + return nil, api.NewErrorInternal(err.Error()) + } + + accountID, err := c.signer.GetAccountID() + if err != nil { + return nil, fmt.Errorf("error getting signer's account ID: %w", err) + } + + signature, err := c.signer.SignPaymentStateRequest() + if err != nil { + return nil, fmt.Errorf("error signing payment state request: %w", err) + } + + request := &disperser_rpc.GetPaymentStateRequest{ + AccountId: accountID, + Signature: signature, + } + return c.client.GetPaymentState(ctx, request) +} + // GetBlobCommitment is a utility method that calculates commitment for a blob payload. // While the blob commitment can be calculated by anyone, it requires SRS points to // be loaded. For service that does not have access to SRS points, this method can be diff --git a/disperser/apiserver/server_v2.go b/disperser/apiserver/server_v2.go index 114f244093..a289c61471 100644 --- a/disperser/apiserver/server_v2.go +++ b/disperser/apiserver/server_v2.go @@ -255,6 +255,10 @@ func (s *DispersalServerV2) GetPaymentState(ctx context.Context, req *pb.GetPaym for i, v := range reservation.QuorumNumbers { quorumNumbers[i] = uint32(v) } + quorumSplit := make([]uint32, len(reservation.QuorumSplit)) + for i, v := range reservation.QuorumSplit { + quorumSplit[i] = uint32(v) + } // build reply reply := &pb.GetPaymentStateReply{ PaymentGlobalParams: &paymentGlobalParams, @@ -264,6 +268,7 @@ func (s *DispersalServerV2) GetPaymentState(ctx context.Context, req *pb.GetPaym StartTimestamp: uint32(reservation.StartTimestamp), EndTimestamp: uint32(reservation.EndTimestamp), QuorumNumbers: quorumNumbers, + QuorumSplit: quorumSplit, }, CumulativePayment: largestCumulativePayment.Bytes(), OnchainCumulativePayment: onDemandPayment.CumulativePayment.Bytes(),