Skip to content

Commit

Permalink
feat: fill in transactor payment contract call
Browse files Browse the repository at this point in the history
  • Loading branch information
hopeyen committed Nov 22, 2024
1 parent b0f3288 commit acec203
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 45 deletions.
12 changes: 6 additions & 6 deletions core/chainio.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,16 @@ type Reader interface {
GetAllVersionedBlobParams(ctx context.Context) (map[uint8]*BlobVersionParameters, error)

// GetActiveReservations returns active reservations (end timestamp > current timestamp)
GetActiveReservations(ctx context.Context, blockNumber uint32, accountIDs []string) (map[string]ActiveReservation, error)
GetActiveReservations(ctx context.Context, accountIDs []string) (map[string]ActiveReservation, error)

// GetActiveReservationByAccount returns active reservation by account ID
GetActiveReservationByAccount(ctx context.Context, blockNumber uint32, accountID string) (ActiveReservation, error)
// GetActiveReservations returns active reservations (end timestamp > current timestamp)
GetActiveReservationByAccount(ctx context.Context, accountID string) (ActiveReservation, error)

// GetOnDemandPayments returns all on-demand payments
GetOnDemandPayments(ctx context.Context, blockNumber uint32, accountIDs []string) (map[string]OnDemandPayment, error)
GetOnDemandPayments(ctx context.Context, accountIDs []string) (map[string]OnDemandPayment, error)

// GetOnDemandPaymentByAccount returns on-demand payment of an account
GetOnDemandPaymentByAccount(ctx context.Context, blockNumber uint32, accountID string) (OnDemandPayment, error)
// GetOnDemandPayments returns all on-demand payments
GetOnDemandPaymentByAccount(ctx context.Context, accountID string) (OnDemandPayment, error)
}

type Writer interface {
Expand Down
10 changes: 2 additions & 8 deletions core/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

commonpb "github.com/Layr-Labs/eigenda/api/grpc/common"
"github.com/Layr-Labs/eigenda/common"
paymentvault "github.com/Layr-Labs/eigenda/contracts/bindings/PaymentVault"
"github.com/Layr-Labs/eigenda/encoding"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
"github.com/consensys/gnark-crypto/ecc/bn254"
Expand Down Expand Up @@ -600,14 +601,7 @@ func ConvertToPaymentMetadata(ph *commonpb.PaymentHeader) *PaymentMetadata {

// OperatorInfo contains information about an operator which is stored on the blockchain state,
// corresponding to a particular quorum
type ActiveReservation struct {
SymbolsPerSec uint64 // reserve number of symbols per second
StartTimestamp uint64 // Unix timestamp that's valid for basically eternity
EndTimestamp uint64

QuorumNumbers []uint8 // allowed quorums
QuorumSplit []byte // ordered mapping of quorum number to payment split; on-chain validation should ensure split <= 100
}
type ActiveReservation = paymentvault.IPaymentVaultReservation

type OnDemandPayment struct {
CumulativePayment *big.Int // Total amount deposited by the user
Expand Down
73 changes: 61 additions & 12 deletions core/eth/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
ejectionmg "github.com/Layr-Labs/eigenda/contracts/bindings/EjectionManager"
indexreg "github.com/Layr-Labs/eigenda/contracts/bindings/IIndexRegistry"
opstateretriever "github.com/Layr-Labs/eigenda/contracts/bindings/OperatorStateRetriever"
paymentvault "github.com/Layr-Labs/eigenda/contracts/bindings/PaymentVault"
regcoordinator "github.com/Layr-Labs/eigenda/contracts/bindings/RegistryCoordinator"
stakereg "github.com/Layr-Labs/eigenda/contracts/bindings/StakeRegistry"
"github.com/Layr-Labs/eigenda/core"
Expand All @@ -37,6 +38,7 @@ type ContractBindings struct {
EigenDAServiceManager *eigendasrvmg.ContractEigenDAServiceManager
EjectionManager *ejectionmg.ContractEjectionManager
AVSDirectory *avsdir.ContractAVSDirectory
PaymentVault *paymentvault.ContractPaymentVault
}

type Reader struct {
Expand Down Expand Up @@ -616,24 +618,71 @@ func (t *Reader) GetAllVersionedBlobParams(ctx context.Context) (map[uint8]*core
return res, nil
}

func (t *Reader) GetActiveReservations(ctx context.Context, blockNumber uint32, accountIDs []string) (map[string]core.ActiveReservation, error) {
// contract is not implemented yet
return map[string]core.ActiveReservation{}, nil
func (t *Reader) GetActiveReservations(ctx context.Context, accountIDs []string) (map[string]core.ActiveReservation, error) {
// map accountIDs to addresses
accountAddresses := make([]gethcommon.Address, len(accountIDs))
for i, accountID := range accountIDs {
accountAddresses[i] = gethcommon.HexToAddress(accountID)
}

reservations_map := make(map[string]core.ActiveReservation)
reservations, err := t.bindings.PaymentVault.GetReservations(&bind.CallOpts{
Context: ctx,
}, accountAddresses)
if err != nil {
return nil, err
}

// since reservations are returned in the same order as the accountIDs, we can directly map them
for i, reservation := range reservations {
reservations_map[accountIDs[i]] = reservation
}
return reservations_map, nil
}

func (t *Reader) GetActiveReservationByAccount(ctx context.Context, blockNumber uint32, accountID string) (core.ActiveReservation, error) {
// contract is not implemented yet
return core.ActiveReservation{}, nil
func (t *Reader) GetActiveReservationByAccount(ctx context.Context, accountID string) (core.ActiveReservation, error) {
reservation, err := t.bindings.PaymentVault.GetReservation(&bind.CallOpts{
Context: ctx,
}, gethcommon.HexToAddress(accountID))
if err != nil {
return core.ActiveReservation{}, err
}
return reservation, nil
}

func (t *Reader) GetOnDemandPayments(ctx context.Context, blockNumber uint32, accountIDs []string) (map[string]core.OnDemandPayment, error) {
// contract is not implemented yet
return map[string]core.OnDemandPayment{}, nil
func (t *Reader) GetOnDemandPayments(ctx context.Context, accountIDs []string) (map[string]core.OnDemandPayment, error) {
// map accountIDs to addresses
accountAddresses := make([]gethcommon.Address, len(accountIDs))
for i, accountID := range accountIDs {
accountAddresses[i] = gethcommon.HexToAddress(accountID)
}
payments_map := make(map[string]core.OnDemandPayment)
payments, err := t.bindings.PaymentVault.GetOnDemandAmounts(&bind.CallOpts{
Context: ctx,
}, accountAddresses)
if err != nil {
return nil, err
}

// since payments are returned in the same order as the accountIDs, we can directly map them
for i, payment := range payments {
payments_map[accountIDs[i]] = core.OnDemandPayment{
CumulativePayment: payment,
}
}
return payments_map, nil
}

func (t *Reader) GetOnDemandPaymentByAccount(ctx context.Context, blockNumber uint32, accountID string) (core.OnDemandPayment, error) {
// contract is not implemented yet
return core.OnDemandPayment{}, nil
func (t *Reader) GetOnDemandPaymentByAccount(ctx context.Context, accountID string) (core.OnDemandPayment, error) {
onDemandPayment, err := t.bindings.PaymentVault.GetOnDemandAmount(&bind.CallOpts{
Context: ctx,
}, gethcommon.HexToAddress(accountID))
if err != nil {
return core.OnDemandPayment{}, err
}
return core.OnDemandPayment{
CumulativePayment: onDemandPayment,
}, nil
}

func (t *Reader) GetGlobalSymbolsPerSecond(ctx context.Context) (uint64, error) {
Expand Down
2 changes: 1 addition & 1 deletion core/meterer/meterer.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,5 +281,5 @@ func (m *Meterer) IncrementGlobalBinUsage(ctx context.Context, symbolsCharged ui

// GetReservationBinLimit returns the bin limit for a given reservation
func (m *Meterer) GetReservationBinLimit(reservation *core.ActiveReservation) uint64 {
return reservation.SymbolsPerSec * uint64(m.ChainPaymentState.GetReservationWindow())
return reservation.SymbolsPerSecond * uint64(m.ChainPaymentState.GetReservationWindow())
}
4 changes: 2 additions & 2 deletions core/meterer/meterer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ func setup(_ *testing.M) {
now := uint64(time.Now().Unix())
accountID1 = crypto.PubkeyToAddress(privateKey1.PublicKey).Hex()
accountID2 = crypto.PubkeyToAddress(privateKey2.PublicKey).Hex()
account1Reservations = core.ActiveReservation{SymbolsPerSec: 100, StartTimestamp: now + 1200, EndTimestamp: now + 1800, QuorumSplit: []byte{50, 50}, QuorumNumbers: []uint8{0, 1}}
account2Reservations = core.ActiveReservation{SymbolsPerSec: 200, StartTimestamp: now - 120, EndTimestamp: now + 180, QuorumSplit: []byte{30, 70}, QuorumNumbers: []uint8{0, 1}}
account1Reservations = core.ActiveReservation{SymbolsPerSecond: 100, StartTimestamp: now + 1200, EndTimestamp: now + 1800, QuorumSplits: []byte{50, 50}, QuorumNumbers: []uint8{0, 1}}
account2Reservations = core.ActiveReservation{SymbolsPerSecond: 200, StartTimestamp: now - 120, EndTimestamp: now + 180, QuorumSplits: []byte{30, 70}, QuorumNumbers: []uint8{0, 1}}
account1OnDemandPayments = core.OnDemandPayment{CumulativePayment: big.NewInt(3864)}
account2OnDemandPayments = core.OnDemandPayment{CumulativePayment: big.NewInt(2000)}

Expand Down
45 changes: 33 additions & 12 deletions core/meterer/onchain_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,33 @@ func (pcs *OnchainPaymentState) RefreshOnchainPaymentState(ctx context.Context,
}
// These parameters should be rarely updated, but we refresh them anyway
pcs.PaymentVaultParams = paymentVaultParams

pcs.ReservationsLock.Lock()
accountIDs := make([]string, 0, len(pcs.ActiveReservations))
for accountID := range pcs.ActiveReservations {
accountIDs = append(accountIDs, accountID)
}

activeReservations, err := tx.GetActiveReservations(ctx, accountIDs)
if err != nil {
return err
}
pcs.ActiveReservations = activeReservations
pcs.ReservationsLock.Unlock()

pcs.OnDemandLocks.Lock()
accountIDs = make([]string, 0, len(pcs.OnDemandPayments))
for accountID := range pcs.OnDemandPayments {
accountIDs = append(accountIDs, accountID)
}

onDemandPayments, err := tx.GetOnDemandPayments(ctx, accountIDs)
if err != nil {
return err
}
pcs.OnDemandPayments = onDemandPayments
pcs.OnDemandLocks.Unlock()

return nil
}

Expand All @@ -115,7 +142,8 @@ func (pcs *OnchainPaymentState) GetActiveReservationByAccount(ctx context.Contex
if reservation, ok := pcs.ActiveReservations[accountID]; ok {
return reservation, nil
}
res, err := pcs.GetActiveReservationByAccountOnChain(ctx, accountID)
// pulls the chain state
res, err := pcs.tx.GetActiveReservationByAccount(ctx, accountID)
if err != nil {
return core.ActiveReservation{}, err
}
Expand All @@ -128,11 +156,7 @@ func (pcs *OnchainPaymentState) GetActiveReservationByAccount(ctx context.Contex

// GetActiveReservationByAccountOnChain returns on-chain reservation for the given account ID
func (pcs *OnchainPaymentState) GetActiveReservationByAccountOnChain(ctx context.Context, accountID string) (core.ActiveReservation, error) {
blockNumber, err := pcs.tx.GetCurrentBlockNumber(ctx)
if err != nil {
return core.ActiveReservation{}, err
}
res, err := pcs.tx.GetActiveReservationByAccount(ctx, blockNumber, accountID)
res, err := pcs.tx.GetActiveReservationByAccount(ctx, accountID)
if err != nil {
return core.ActiveReservation{}, fmt.Errorf("reservation account not found on-chain: %w", err)
}
Expand All @@ -144,7 +168,8 @@ func (pcs *OnchainPaymentState) GetOnDemandPaymentByAccount(ctx context.Context,
if payment, ok := pcs.OnDemandPayments[accountID]; ok {
return payment, nil
}
res, err := pcs.GetOnDemandPaymentByAccountOnChain(ctx, accountID)
// pulls the chain state
res, err := pcs.tx.GetOnDemandPaymentByAccount(ctx, accountID)
if err != nil {
return core.OnDemandPayment{}, err
}
Expand All @@ -156,11 +181,7 @@ func (pcs *OnchainPaymentState) GetOnDemandPaymentByAccount(ctx context.Context,
}

func (pcs *OnchainPaymentState) GetOnDemandPaymentByAccountOnChain(ctx context.Context, accountID string) (core.OnDemandPayment, error) {
blockNumber, err := pcs.tx.GetCurrentBlockNumber(ctx)
if err != nil {
return core.OnDemandPayment{}, err
}
res, err := pcs.tx.GetOnDemandPaymentByAccount(ctx, blockNumber, accountID)
res, err := pcs.tx.GetOnDemandPaymentByAccount(ctx, accountID)
if err != nil {
return core.OnDemandPayment{}, fmt.Errorf("on-demand not found on-chain: %w", err)
}
Expand Down
8 changes: 4 additions & 4 deletions core/meterer/onchain_state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import (

var (
dummyActiveReservation = core.ActiveReservation{
SymbolsPerSec: 100,
StartTimestamp: 1000,
EndTimestamp: 2000,
QuorumSplit: []byte{50, 50},
SymbolsPerSecond: 100,
StartTimestamp: 1000,
EndTimestamp: 2000,
QuorumSplits: []byte{50, 50},
}
dummyOnDemandPayment = core.OnDemandPayment{
CumulativePayment: big.NewInt(1000),
Expand Down

0 comments on commit acec203

Please sign in to comment.