diff --git a/api/clients/accountant.go b/api/clients/accountant.go
index bd8192b31..ef76eef1d 100644
--- a/api/clients/accountant.go
+++ b/api/clients/accountant.go
@@ -77,7 +77,7 @@ func (a *Accountant) BlobPaymentInfo(ctx context.Context, numSymbols uint64, quo
relativeBinRecord.Usage += numSymbols
// first attempt to use the active reservation
- binLimit := a.reservation.SymbolsPerSec * uint64(a.reservationWindow)
+ binLimit := a.reservation.SymbolsPerSecond * uint64(a.reservationWindow)
if relativeBinRecord.Usage <= binLimit {
if err := QuorumCheck(quorumNumbers, a.reservation.QuorumNumbers); err != nil {
return 0, big.NewInt(0), err
@@ -166,7 +166,7 @@ func (a *Accountant) SetPaymentState(paymentState *disperser_rpc.GetPaymentState
return fmt.Errorf("reservation cannot be nil")
} else if paymentState.GetReservation().GetQuorumNumbers() == nil {
return fmt.Errorf("reservation quorum numbers cannot be nil")
- } else if paymentState.GetReservation().GetQuorumSplit() == nil {
+ } else if paymentState.GetReservation().GetQuorumSplits() == nil {
return fmt.Errorf("reservation quorum split cannot be nil")
} else if paymentState.GetBinRecords() == nil {
return fmt.Errorf("bin records cannot be nil")
@@ -177,7 +177,7 @@ func (a *Accountant) SetPaymentState(paymentState *disperser_rpc.GetPaymentState
a.cumulativePayment = new(big.Int).SetBytes(paymentState.CumulativePayment)
a.pricePerSymbol = uint32(paymentState.PaymentGlobalParams.PricePerSymbol)
- a.reservation.SymbolsPerSec = uint64(paymentState.PaymentGlobalParams.GlobalSymbolsPerSecond)
+ a.reservation.SymbolsPerSecond = uint64(paymentState.PaymentGlobalParams.GlobalSymbolsPerSecond)
a.reservation.StartTimestamp = uint64(paymentState.Reservation.StartTimestamp)
a.reservation.EndTimestamp = uint64(paymentState.Reservation.EndTimestamp)
a.reservationWindow = uint32(paymentState.PaymentGlobalParams.ReservationWindow)
@@ -188,11 +188,11 @@ func (a *Accountant) SetPaymentState(paymentState *disperser_rpc.GetPaymentState
}
a.reservation.QuorumNumbers = quorumNumbers
- quorumSplit := make([]uint8, len(paymentState.Reservation.QuorumSplit))
- for i, quorum := range paymentState.Reservation.QuorumSplit {
- quorumSplit[i] = uint8(quorum)
+ quorumSplits := make([]uint8, len(paymentState.Reservation.QuorumSplits))
+ for i, quorum := range paymentState.Reservation.QuorumSplits {
+ quorumSplits[i] = uint8(quorum)
}
- a.reservation.QuorumSplit = quorumSplit
+ a.reservation.QuorumSplits = quorumSplits
binRecords := make([]BinRecord, len(paymentState.BinRecords))
for i, record := range paymentState.BinRecords {
diff --git a/api/clients/accountant_test.go b/api/clients/accountant_test.go
index 09b880664..5c19e1592 100644
--- a/api/clients/accountant_test.go
+++ b/api/clients/accountant_test.go
@@ -18,11 +18,11 @@ const numBins = uint32(3)
func TestNewAccountant(t *testing.T) {
reservation := &core.ActiveReservation{
- SymbolsPerSec: 100,
- StartTimestamp: 100,
- EndTimestamp: 200,
- QuorumSplit: []byte{50, 50},
- QuorumNumbers: []uint8{0, 1},
+ SymbolsPerSecond: 100,
+ StartTimestamp: 100,
+ EndTimestamp: 200,
+ QuorumSplits: []byte{50, 50},
+ QuorumNumbers: []uint8{0, 1},
}
onDemand := &core.OnDemandPayment{
CumulativePayment: big.NewInt(500),
@@ -48,11 +48,11 @@ func TestNewAccountant(t *testing.T) {
func TestAccountBlob_Reservation(t *testing.T) {
reservation := &core.ActiveReservation{
- SymbolsPerSec: 200,
- StartTimestamp: 100,
- EndTimestamp: 200,
- QuorumSplit: []byte{50, 50},
- QuorumNumbers: []uint8{0, 1},
+ SymbolsPerSecond: 200,
+ StartTimestamp: 100,
+ EndTimestamp: 200,
+ QuorumSplits: []byte{50, 50},
+ QuorumNumbers: []uint8{0, 1},
}
onDemand := &core.OnDemandPayment{
CumulativePayment: big.NewInt(500),
@@ -96,11 +96,11 @@ func TestAccountBlob_Reservation(t *testing.T) {
func TestAccountBlob_OnDemand(t *testing.T) {
reservation := &core.ActiveReservation{
- SymbolsPerSec: 200,
- StartTimestamp: 100,
- EndTimestamp: 200,
- QuorumSplit: []byte{50, 50},
- QuorumNumbers: []uint8{0, 1},
+ SymbolsPerSecond: 200,
+ StartTimestamp: 100,
+ EndTimestamp: 200,
+ QuorumSplits: []byte{50, 50},
+ QuorumNumbers: []uint8{0, 1},
}
onDemand := &core.OnDemandPayment{
CumulativePayment: big.NewInt(1500),
@@ -152,11 +152,11 @@ func TestAccountBlob_InsufficientOnDemand(t *testing.T) {
func TestAccountBlobCallSeries(t *testing.T) {
reservation := &core.ActiveReservation{
- SymbolsPerSec: 200,
- StartTimestamp: 100,
- EndTimestamp: 200,
- QuorumSplit: []byte{50, 50},
- QuorumNumbers: []uint8{0, 1},
+ SymbolsPerSecond: 200,
+ StartTimestamp: 100,
+ EndTimestamp: 200,
+ QuorumSplits: []byte{50, 50},
+ QuorumNumbers: []uint8{0, 1},
}
onDemand := &core.OnDemandPayment{
CumulativePayment: big.NewInt(1000),
@@ -200,11 +200,11 @@ func TestAccountBlobCallSeries(t *testing.T) {
func TestAccountBlob_BinRotation(t *testing.T) {
reservation := &core.ActiveReservation{
- SymbolsPerSec: 1000,
- StartTimestamp: 100,
- EndTimestamp: 200,
- QuorumSplit: []byte{50, 50},
- QuorumNumbers: []uint8{0, 1},
+ SymbolsPerSecond: 1000,
+ StartTimestamp: 100,
+ EndTimestamp: 200,
+ QuorumSplits: []byte{50, 50},
+ QuorumNumbers: []uint8{0, 1},
}
onDemand := &core.OnDemandPayment{
CumulativePayment: big.NewInt(1000),
@@ -242,11 +242,11 @@ func TestAccountBlob_BinRotation(t *testing.T) {
func TestConcurrentBinRotationAndAccountBlob(t *testing.T) {
reservation := &core.ActiveReservation{
- SymbolsPerSec: 1000,
- StartTimestamp: 100,
- EndTimestamp: 200,
- QuorumSplit: []byte{50, 50},
- QuorumNumbers: []uint8{0, 1},
+ SymbolsPerSecond: 1000,
+ StartTimestamp: 100,
+ EndTimestamp: 200,
+ QuorumSplits: []byte{50, 50},
+ QuorumNumbers: []uint8{0, 1},
}
onDemand := &core.OnDemandPayment{
CumulativePayment: big.NewInt(1000),
@@ -288,11 +288,11 @@ func TestConcurrentBinRotationAndAccountBlob(t *testing.T) {
func TestAccountBlob_ReservationWithOneOverflow(t *testing.T) {
reservation := &core.ActiveReservation{
- SymbolsPerSec: 200,
- StartTimestamp: 100,
- EndTimestamp: 200,
- QuorumSplit: []byte{50, 50},
- QuorumNumbers: []uint8{0, 1},
+ SymbolsPerSecond: 200,
+ StartTimestamp: 100,
+ EndTimestamp: 200,
+ QuorumSplits: []byte{50, 50},
+ QuorumNumbers: []uint8{0, 1},
}
onDemand := &core.OnDemandPayment{
CumulativePayment: big.NewInt(1000),
@@ -333,11 +333,11 @@ func TestAccountBlob_ReservationWithOneOverflow(t *testing.T) {
func TestAccountBlob_ReservationOverflowReset(t *testing.T) {
reservation := &core.ActiveReservation{
- SymbolsPerSec: 1000,
- StartTimestamp: 100,
- EndTimestamp: 200,
- QuorumSplit: []byte{50, 50},
- QuorumNumbers: []uint8{0, 1},
+ SymbolsPerSecond: 1000,
+ StartTimestamp: 100,
+ EndTimestamp: 200,
+ QuorumSplits: []byte{50, 50},
+ QuorumNumbers: []uint8{0, 1},
}
onDemand := &core.OnDemandPayment{
CumulativePayment: big.NewInt(1000),
diff --git a/api/docs/disperser_v2.html b/api/docs/disperser_v2.html
index 02c6ea22c..168ceeaf0 100644
--- a/api/docs/disperser_v2.html
+++ b/api/docs/disperser_v2.html
@@ -733,7 +733,7 @@
Reservation
- quorum_split |
+ quorum_splits |
uint32 |
repeated |
|
diff --git a/api/docs/disperser_v2.md b/api/docs/disperser_v2.md
index 5b987d96f..7c02307bc 100644
--- a/api/docs/disperser_v2.md
+++ b/api/docs/disperser_v2.md
@@ -248,7 +248,7 @@ GetPaymentStateRequest contains parameters to query the payment state of an acco
| start_timestamp | [uint32](#uint32) | | |
| end_timestamp | [uint32](#uint32) | | |
| quorum_numbers | [uint32](#uint32) | repeated | |
-| quorum_split | [uint32](#uint32) | repeated | |
+| quorum_splits | [uint32](#uint32) | repeated | |
diff --git a/api/docs/eigenda-protos.html b/api/docs/eigenda-protos.html
index 9f1c0c1c9..7ffceec02 100644
--- a/api/docs/eigenda-protos.html
+++ b/api/docs/eigenda-protos.html
@@ -2396,7 +2396,7 @@ Reservation
- quorum_split |
+ quorum_splits |
uint32 |
repeated |
|
diff --git a/api/docs/eigenda-protos.md b/api/docs/eigenda-protos.md
index 8b4992a42..fa357e9df 100644
--- a/api/docs/eigenda-protos.md
+++ b/api/docs/eigenda-protos.md
@@ -949,7 +949,7 @@ GetPaymentStateRequest contains parameters to query the payment state of an acco
| start_timestamp | [uint32](#uint32) | | |
| end_timestamp | [uint32](#uint32) | | |
| quorum_numbers | [uint32](#uint32) | repeated | |
-| quorum_split | [uint32](#uint32) | repeated | |
+| quorum_splits | [uint32](#uint32) | repeated | |
diff --git a/api/grpc/disperser/v2/disperser_v2.pb.go b/api/grpc/disperser/v2/disperser_v2.pb.go
index 6e1db037b..cca3e75de 100644
--- a/api/grpc/disperser/v2/disperser_v2.pb.go
+++ b/api/grpc/disperser/v2/disperser_v2.pb.go
@@ -862,7 +862,7 @@ type Reservation struct {
StartTimestamp uint32 `protobuf:"varint,2,opt,name=start_timestamp,json=startTimestamp,proto3" json:"start_timestamp,omitempty"`
EndTimestamp uint32 `protobuf:"varint,3,opt,name=end_timestamp,json=endTimestamp,proto3" json:"end_timestamp,omitempty"`
QuorumNumbers []uint32 `protobuf:"varint,4,rep,packed,name=quorum_numbers,json=quorumNumbers,proto3" json:"quorum_numbers,omitempty"`
- QuorumSplit []uint32 `protobuf:"varint,5,rep,packed,name=quorum_split,json=quorumSplit,proto3" json:"quorum_split,omitempty"`
+ QuorumSplits []uint32 `protobuf:"varint,5,rep,packed,name=quorum_splits,json=quorumSplits,proto3" json:"quorum_splits,omitempty"`
}
func (x *Reservation) Reset() {
@@ -925,9 +925,9 @@ func (x *Reservation) GetQuorumNumbers() []uint32 {
return nil
}
-func (x *Reservation) GetQuorumSplit() []uint32 {
+func (x *Reservation) GetQuorumSplits() []uint32 {
if x != nil {
- return x.QuorumSplit
+ return x.QuorumSplits
}
return nil
}
@@ -1108,7 +1108,7 @@ var file_disperser_v2_disperser_v2_proto_rawDesc = []byte{
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, 0xd3, 0x01, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74,
+ 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,
@@ -1119,47 +1119,47 @@ var file_disperser_v2_disperser_v2_proto_rawDesc = []byte{
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, 0x21, 0x0a, 0x0c, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d,
- 0x5f, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0b, 0x71, 0x75,
- 0x6f, 0x72, 0x75, 0x6d, 0x53, 0x70, 0x6c, 0x69, 0x74, 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,
+ 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,
}
var (
diff --git a/api/proto/disperser/v2/disperser_v2.proto b/api/proto/disperser/v2/disperser_v2.proto
index 4107023bc..a9425249d 100644
--- a/api/proto/disperser/v2/disperser_v2.proto
+++ b/api/proto/disperser/v2/disperser_v2.proto
@@ -164,7 +164,7 @@ message Reservation {
uint32 start_timestamp = 2;
uint32 end_timestamp = 3;
repeated uint32 quorum_numbers = 4;
- repeated uint32 quorum_split = 5;
+ repeated uint32 quorum_splits = 5;
}
// BinRecord is the usage record of an account in a bin. The API should return the active bin
diff --git a/core/chainio.go b/core/chainio.go
index b5b587c8d..f9bf66081 100644
--- a/core/chainio.go
+++ b/core/chainio.go
@@ -110,16 +110,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 []gethcommon.Address) (map[gethcommon.Address]*ActiveReservation, error)
// GetActiveReservationByAccount returns active reservation by account ID
- GetActiveReservationByAccount(ctx context.Context, blockNumber uint32, accountID string) (ActiveReservation, error)
+ GetActiveReservationByAccount(ctx context.Context, accountID gethcommon.Address) (*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 []gethcommon.Address) (map[gethcommon.Address]*OnDemandPayment, error)
// GetOnDemandPaymentByAccount returns on-demand payment of an account
- GetOnDemandPaymentByAccount(ctx context.Context, blockNumber uint32, accountID string) (OnDemandPayment, error)
+ GetOnDemandPaymentByAccount(ctx context.Context, accountID gethcommon.Address) (*OnDemandPayment, error)
// GetRelayURL returns the relay URL address for the given key.
GetRelayURL(ctx context.Context, key uint32) (string, error)
diff --git a/core/data.go b/core/data.go
index 1a3b5218a..256f6f70e 100644
--- a/core/data.go
+++ b/core/data.go
@@ -601,13 +601,13 @@ 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
+ SymbolsPerSecond uint64 // reserve number of symbols per second
//TODO: we are not using start and end timestamp, add check or remove
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
+ QuorumSplits []byte // ordered mapping of quorum number to payment split; on-chain validation should ensure split <= 100
}
type OnDemandPayment struct {
diff --git a/core/eth/reader.go b/core/eth/reader.go
index 8e231f867..b87724244 100644
--- a/core/eth/reader.go
+++ b/core/eth/reader.go
@@ -15,6 +15,7 @@ import (
relayreg "github.com/Layr-Labs/eigenda/contracts/bindings/IEigenDARelayRegistry"
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"
socketreg "github.com/Layr-Labs/eigenda/contracts/bindings/SocketRegistry"
stakereg "github.com/Layr-Labs/eigenda/contracts/bindings/StakeRegistry"
@@ -41,6 +42,7 @@ type ContractBindings struct {
AVSDirectory *avsdir.ContractAVSDirectory
SocketRegistry *socketreg.ContractSocketRegistry
RelayRegistry *relayreg.ContractIEigenDARelayRegistry
+ PaymentVault *paymentvault.ContractPaymentVault
}
type Reader struct {
@@ -208,6 +210,7 @@ func (t *Reader) updateContractBindings(blsOperatorStateRetrieverAddr, eigenDASe
EigenDAServiceManager: contractEigenDAServiceManager,
DelegationManager: contractDelegationManager,
RelayRegistry: contractRelayRegistry,
+ // PaymentVault: contractPaymentVault,
}
return nil
}
@@ -654,44 +657,152 @@ 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 []gethcommon.Address) (map[gethcommon.Address]*core.ActiveReservation, error) {
+ if t.bindings.PaymentVault == nil {
+ return nil, errors.New("payment vault not deployed")
+ }
+ reservationsMap := make(map[gethcommon.Address]*core.ActiveReservation)
+ reservations, err := t.bindings.PaymentVault.GetReservations(&bind.CallOpts{
+ Context: ctx,
+ }, accountIDs)
+ 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 {
+ res, err := ConvertToActiveReservation(reservation)
+ if err != nil {
+ t.logger.Warn("failed to get active reservation", "account", accountIDs[i], "err", err)
+ continue
+ }
+
+ reservationsMap[accountIDs[i]] = res
+ }
+
+ return reservationsMap, 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 gethcommon.Address) (*core.ActiveReservation, error) {
+ if t.bindings.PaymentVault == nil {
+ return nil, errors.New("payment vault not deployed")
+ }
+ reservation, err := t.bindings.PaymentVault.GetReservation(&bind.CallOpts{
+ Context: ctx,
+ }, accountID)
+ if err != nil {
+ return nil, err
+ }
+ return ConvertToActiveReservation(reservation)
}
-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 []gethcommon.Address) (map[gethcommon.Address]*core.OnDemandPayment, error) {
+ if t.bindings.PaymentVault == nil {
+ return nil, errors.New("payment vault not deployed")
+ }
+ paymentsMap := make(map[gethcommon.Address]*core.OnDemandPayment)
+ payments, err := t.bindings.PaymentVault.GetOnDemandAmounts(&bind.CallOpts{
+ Context: ctx,
+ }, accountIDs)
+ 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 {
+ if payment.Cmp(big.NewInt(0)) == 0 {
+ t.logger.Warn("failed to get on demand payment for account", "account", accountIDs[i])
+ continue
+ }
+ paymentsMap[accountIDs[i]] = &core.OnDemandPayment{
+ CumulativePayment: payment,
+ }
+ }
+
+ return paymentsMap, 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 gethcommon.Address) (*core.OnDemandPayment, error) {
+ if t.bindings.PaymentVault == nil {
+ return nil, errors.New("payment vault not deployed")
+ }
+ onDemandPayment, err := t.bindings.PaymentVault.GetOnDemandAmount(&bind.CallOpts{
+ Context: ctx,
+ }, accountID)
+ if err != nil {
+ return nil, err
+ }
+ if onDemandPayment.Cmp(big.NewInt(0)) == 0 {
+ return nil, errors.New("ondemand payment does not exist for given account")
+ }
+ return &core.OnDemandPayment{
+ CumulativePayment: onDemandPayment,
+ }, nil
}
func (t *Reader) GetGlobalSymbolsPerSecond(ctx context.Context) (uint64, error) {
- // contract is not implemented yet
- return 0, nil
+ if t.bindings.PaymentVault == nil {
+ return 0, errors.New("payment vault not deployed")
+ }
+ globalSymbolsPerSecond, err := t.bindings.PaymentVault.GlobalRateBinInterval(&bind.CallOpts{
+ Context: ctx,
+ })
+ if err != nil {
+ return 0, err
+ }
+ return globalSymbolsPerSecond.Uint64(), nil
+}
+
+func (t *Reader) GetGlobalRateBinInterval(ctx context.Context) (uint64, error) {
+ if t.bindings.PaymentVault == nil {
+ return 0, errors.New("payment vault not deployed")
+ }
+ globalRateBinInterval, err := t.bindings.PaymentVault.GlobalRateBinInterval(&bind.CallOpts{
+ Context: ctx,
+ })
+ if err != nil {
+ return 0, err
+ }
+ return globalRateBinInterval.Uint64(), nil
}
func (t *Reader) GetMinNumSymbols(ctx context.Context) (uint32, error) {
- // contract is not implemented yet
- return 0, nil
+ if t.bindings.PaymentVault == nil {
+ return 0, errors.New("payment vault not deployed")
+ }
+ minNumSymbols, err := t.bindings.PaymentVault.MinNumSymbols(&bind.CallOpts{
+ Context: ctx,
+ })
+ if err != nil {
+ return 0, err
+ }
+ return uint32(minNumSymbols.Uint64()), nil
}
func (t *Reader) GetPricePerSymbol(ctx context.Context) (uint32, error) {
- // contract is not implemented yet
- return 0, nil
+ if t.bindings.PaymentVault == nil {
+ return 0, errors.New("payment vault not deployed")
+ }
+ pricePerSymbol, err := t.bindings.PaymentVault.PricePerSymbol(&bind.CallOpts{
+ Context: ctx,
+ })
+ if err != nil {
+ return 0, err
+ }
+ return uint32(pricePerSymbol.Uint64()), nil
}
func (t *Reader) GetReservationWindow(ctx context.Context) (uint32, error) {
- // contract is not implemented yet
- return 0, nil
+ if t.bindings.PaymentVault == nil {
+ return 0, errors.New("payment vault not deployed")
+ }
+ reservationWindow, err := t.bindings.PaymentVault.ReservationBinInterval(&bind.CallOpts{
+ Context: ctx,
+ })
+ if err != nil {
+ return 0, err
+ }
+ return uint32(reservationWindow.Uint64()), nil
}
func (t *Reader) GetOperatorSocket(ctx context.Context, operatorId core.OperatorID) (string, error) {
diff --git a/core/eth/utils.go b/core/eth/utils.go
index 8556fa82d..d98b6def2 100644
--- a/core/eth/utils.go
+++ b/core/eth/utils.go
@@ -1,12 +1,14 @@
package eth
import (
+ "fmt"
"math/big"
"slices"
"github.com/Layr-Labs/eigenda/core"
eigendasrvmg "github.com/Layr-Labs/eigenda/contracts/bindings/EigenDAServiceManager"
+ paymentvault "github.com/Layr-Labs/eigenda/contracts/bindings/PaymentVault"
"github.com/ethereum/go-ethereum/crypto"
)
@@ -126,3 +128,27 @@ func bitmapToBytesArray(bitmap *big.Int) []byte {
}
return bytesArray
}
+
+func isZeroValuedReservation(reservation paymentvault.IPaymentVaultReservation) bool {
+ return reservation.SymbolsPerSecond == 0 &&
+ reservation.StartTimestamp == 0 &&
+ reservation.EndTimestamp == 0 &&
+ len(reservation.QuorumNumbers) == 0 &&
+ len(reservation.QuorumSplits) == 0
+}
+
+// ConvertToActiveReservation converts a upstream binding data structure to local definition.
+// Returns an error if the input reservation is zero-valued.
+func ConvertToActiveReservation(reservation paymentvault.IPaymentVaultReservation) (*core.ActiveReservation, error) {
+ if isZeroValuedReservation(reservation) {
+ return nil, fmt.Errorf("reservation is not a valid active reservation")
+ }
+
+ return &core.ActiveReservation{
+ SymbolsPerSecond: reservation.SymbolsPerSecond,
+ StartTimestamp: reservation.StartTimestamp,
+ EndTimestamp: reservation.EndTimestamp,
+ QuorumNumbers: reservation.QuorumNumbers,
+ QuorumSplits: reservation.QuorumSplits,
+ }, nil
+}
diff --git a/core/meterer/meterer.go b/core/meterer/meterer.go
index ba1f2cfc6..f8d46d0b7 100644
--- a/core/meterer/meterer.go
+++ b/core/meterer/meterer.go
@@ -8,6 +8,7 @@ import (
"github.com/Layr-Labs/eigenda/core"
"github.com/Layr-Labs/eigensdk-go/logging"
+ gethcommon "github.com/ethereum/go-ethereum/common"
)
// Config contains network parameters that should be published on-chain. We currently configure these params through disperser env vars.
@@ -71,21 +72,22 @@ func (m *Meterer) Start(ctx context.Context) {
// MeterRequest validates a blob header and adds it to the meterer's state
// TODO: return error if there's a rejection (with reasoning) or internal error (should be very rare)
func (m *Meterer) MeterRequest(ctx context.Context, header core.PaymentMetadata, numSymbols uint, quorumNumbers []uint8) error {
+ accountID := gethcommon.HexToAddress(header.AccountID)
// Validate against the payment method
if header.CumulativePayment.Sign() == 0 {
- reservation, err := m.ChainPaymentState.GetActiveReservationByAccount(ctx, header.AccountID)
+ reservation, err := m.ChainPaymentState.GetActiveReservationByAccount(ctx, accountID)
if err != nil {
return fmt.Errorf("failed to get active reservation by account: %w", err)
}
- if err := m.ServeReservationRequest(ctx, header, &reservation, numSymbols, quorumNumbers); err != nil {
+ if err := m.ServeReservationRequest(ctx, header, reservation, numSymbols, quorumNumbers); err != nil {
return fmt.Errorf("invalid reservation: %w", err)
}
} else {
- onDemandPayment, err := m.ChainPaymentState.GetOnDemandPaymentByAccount(ctx, header.AccountID)
+ onDemandPayment, err := m.ChainPaymentState.GetOnDemandPaymentByAccount(ctx, accountID)
if err != nil {
return fmt.Errorf("failed to get on-demand payment by account: %w", err)
}
- if err := m.ServeOnDemandRequest(ctx, header, &onDemandPayment, numSymbols, quorumNumbers); err != nil {
+ if err := m.ServeOnDemandRequest(ctx, header, onDemandPayment, numSymbols, quorumNumbers); err != nil {
return fmt.Errorf("invalid on-demand request: %w", err)
}
}
@@ -268,6 +270,7 @@ func (m *Meterer) ValidateGlobalBinIndex(header core.PaymentMetadata) (uint32, e
// IncrementBinUsage increments the bin usage atomically and checks for overflow
func (m *Meterer) IncrementGlobalBinUsage(ctx context.Context, symbolsCharged uint64) error {
+ //TODO: edit globalIndex based on bin interval in a subsequent PR
globalIndex := uint64(time.Now().Unix())
newUsage, err := m.OffchainStore.UpdateGlobalBin(ctx, globalIndex, symbolsCharged)
if err != nil {
@@ -281,5 +284,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())
}
diff --git a/core/meterer/meterer_test.go b/core/meterer/meterer_test.go
index d4298d601..dfc4b5f6b 100644
--- a/core/meterer/meterer_test.go
+++ b/core/meterer/meterer_test.go
@@ -17,6 +17,7 @@ import (
"github.com/Layr-Labs/eigenda/core/mock"
"github.com/Layr-Labs/eigenda/inabox/deploy"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
+ gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ory/dockertest/v3"
"github.com/stretchr/testify/assert"
@@ -30,12 +31,12 @@ var (
dockertestResource *dockertest.Resource
dynamoClient commondynamodb.Client
clientConfig commonaws.ClientConfig
- accountID1 string
- account1Reservations core.ActiveReservation
- account1OnDemandPayments core.OnDemandPayment
- accountID2 string
- account2Reservations core.ActiveReservation
- account2OnDemandPayments core.OnDemandPayment
+ accountID1 gethcommon.Address
+ account1Reservations *core.ActiveReservation
+ account1OnDemandPayments *core.OnDemandPayment
+ accountID2 gethcommon.Address
+ account2Reservations *core.ActiveReservation
+ account2OnDemandPayments *core.OnDemandPayment
mt *meterer.Meterer
deployLocalStack bool
@@ -123,12 +124,12 @@ 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}}
- account1OnDemandPayments = core.OnDemandPayment{CumulativePayment: big.NewInt(3864)}
- account2OnDemandPayments = core.OnDemandPayment{CumulativePayment: big.NewInt(2000)}
+ accountID1 = crypto.PubkeyToAddress(privateKey1.PublicKey)
+ accountID2 = crypto.PubkeyToAddress(privateKey2.PublicKey)
+ 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)}
store, err := meterer.NewOffchainStore(
clientConfig,
@@ -170,18 +171,19 @@ func TestMetererReservations(t *testing.T) {
ctx := context.Background()
paymentChainState.On("GetReservationWindow", testifymock.Anything).Return(uint32(1), nil)
paymentChainState.On("GetGlobalSymbolsPerSecond", testifymock.Anything).Return(uint64(1009), nil)
+ paymentChainState.On("GetGlobalRateBinInterval", testifymock.Anything).Return(uint64(1), nil)
paymentChainState.On("GetMinNumSymbols", testifymock.Anything).Return(uint32(3), nil)
binIndex := meterer.GetBinIndex(uint64(time.Now().Unix()), mt.ChainPaymentState.GetReservationWindow())
quoromNumbers := []uint8{0, 1}
- paymentChainState.On("GetActiveReservationByAccount", testifymock.Anything, testifymock.MatchedBy(func(account string) bool {
+ paymentChainState.On("GetActiveReservationByAccount", testifymock.Anything, testifymock.MatchedBy(func(account gethcommon.Address) bool {
return account == accountID1
})).Return(account1Reservations, nil)
- paymentChainState.On("GetActiveReservationByAccount", testifymock.Anything, testifymock.MatchedBy(func(account string) bool {
+ paymentChainState.On("GetActiveReservationByAccount", testifymock.Anything, testifymock.MatchedBy(func(account gethcommon.Address) bool {
return account == accountID2
})).Return(account2Reservations, nil)
- paymentChainState.On("GetActiveReservationByAccount", testifymock.Anything, testifymock.Anything).Return(core.ActiveReservation{}, fmt.Errorf("reservation not found"))
+ paymentChainState.On("GetActiveReservationByAccount", testifymock.Anything, testifymock.Anything).Return(&core.ActiveReservation{}, fmt.Errorf("reservation not found"))
// test invalid quorom ID
header := createPaymentHeader(1, 0, accountID1)
@@ -202,7 +204,7 @@ func TestMetererReservations(t *testing.T) {
if err != nil {
t.Fatalf("Failed to generate key: %v", err)
}
- header = createPaymentHeader(1, 0, crypto.PubkeyToAddress(unregisteredUser.PublicKey).Hex())
+ header = createPaymentHeader(1, 0, crypto.PubkeyToAddress(unregisteredUser.PublicKey))
assert.NoError(t, err)
err = mt.MeterRequest(ctx, *header, 1000, []uint8{0, 1, 2})
assert.ErrorContains(t, err, "failed to get active reservation by account: reservation not found")
@@ -220,11 +222,11 @@ func TestMetererReservations(t *testing.T) {
err = mt.MeterRequest(ctx, *header, symbolLength, quoromNumbers)
assert.NoError(t, err)
item, err := dynamoClient.GetItem(ctx, reservationTableName, commondynamodb.Key{
- "AccountID": &types.AttributeValueMemberS{Value: accountID2},
+ "AccountID": &types.AttributeValueMemberS{Value: accountID2.Hex()},
"BinIndex": &types.AttributeValueMemberN{Value: strconv.Itoa(int(binIndex))},
})
assert.NoError(t, err)
- assert.Equal(t, accountID2, item["AccountID"].(*types.AttributeValueMemberS).Value)
+ assert.Equal(t, accountID2.Hex(), item["AccountID"].(*types.AttributeValueMemberS).Value)
assert.Equal(t, strconv.Itoa(int(binIndex)), item["BinIndex"].(*types.AttributeValueMemberN).Value)
assert.Equal(t, strconv.Itoa((i+1)*int(requiredLength)), item["BinUsage"].(*types.AttributeValueMemberN).Value)
@@ -236,11 +238,11 @@ func TestMetererReservations(t *testing.T) {
assert.NoError(t, err)
overflowedBinIndex := binIndex + 2
item, err := dynamoClient.GetItem(ctx, reservationTableName, commondynamodb.Key{
- "AccountID": &types.AttributeValueMemberS{Value: accountID2},
+ "AccountID": &types.AttributeValueMemberS{Value: accountID2.Hex()},
"BinIndex": &types.AttributeValueMemberN{Value: strconv.Itoa(int(overflowedBinIndex))},
})
assert.NoError(t, err)
- assert.Equal(t, accountID2, item["AccountID"].(*types.AttributeValueMemberS).Value)
+ assert.Equal(t, accountID2.Hex(), item["AccountID"].(*types.AttributeValueMemberS).Value)
assert.Equal(t, strconv.Itoa(int(overflowedBinIndex)), item["BinIndex"].(*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)
@@ -259,13 +261,13 @@ func TestMetererOnDemand(t *testing.T) {
paymentChainState.On("GetMinNumSymbols", testifymock.Anything).Return(uint32(3), nil)
binIndex := uint32(0) // this field doesn't matter for on-demand payments wrt global rate limit
- paymentChainState.On("GetOnDemandPaymentByAccount", testifymock.Anything, testifymock.MatchedBy(func(account string) bool {
+ paymentChainState.On("GetOnDemandPaymentByAccount", testifymock.Anything, testifymock.MatchedBy(func(account gethcommon.Address) bool {
return account == accountID1
})).Return(account1OnDemandPayments, nil)
- paymentChainState.On("GetOnDemandPaymentByAccount", testifymock.Anything, testifymock.MatchedBy(func(account string) bool {
+ paymentChainState.On("GetOnDemandPaymentByAccount", testifymock.Anything, testifymock.MatchedBy(func(account gethcommon.Address) bool {
return account == accountID2
})).Return(account2OnDemandPayments, nil)
- paymentChainState.On("GetOnDemandPaymentByAccount", testifymock.Anything, testifymock.Anything).Return(core.OnDemandPayment{}, fmt.Errorf("payment not found"))
+ paymentChainState.On("GetOnDemandPaymentByAccount", testifymock.Anything, testifymock.Anything).Return(&core.OnDemandPayment{}, fmt.Errorf("payment not found"))
paymentChainState.On("GetOnDemandQuorumNumbers", testifymock.Anything).Return(quorumNumbers, nil)
// test unregistered account
@@ -273,7 +275,7 @@ func TestMetererOnDemand(t *testing.T) {
if err != nil {
t.Fatalf("Failed to generate key: %v", err)
}
- header := createPaymentHeader(binIndex, 2, crypto.PubkeyToAddress(unregisteredUser.PublicKey).Hex())
+ header := createPaymentHeader(binIndex, 2, crypto.PubkeyToAddress(unregisteredUser.PublicKey))
assert.NoError(t, err)
err = mt.MeterRequest(ctx, *header, 1000, quorumNumbers)
assert.ErrorContains(t, err, "failed to get on-demand payment by account: payment not found")
@@ -290,7 +292,7 @@ func TestMetererOnDemand(t *testing.T) {
// No rollback after meter request
result, err := dynamoClient.Query(ctx, ondemandTableName, "AccountID = :account", commondynamodb.ExpressionValues{
":account": &types.AttributeValueMemberS{
- Value: accountID1,
+ Value: accountID1.Hex(),
}})
assert.NoError(t, err)
assert.Equal(t, 1, len(result))
@@ -335,7 +337,7 @@ func TestMetererOnDemand(t *testing.T) {
numPrevRecords := 12
result, err = dynamoClient.Query(ctx, ondemandTableName, "AccountID = :account", commondynamodb.ExpressionValues{
":account": &types.AttributeValueMemberS{
- Value: accountID2,
+ Value: accountID2.Hex(),
}})
assert.NoError(t, err)
assert.Equal(t, numPrevRecords, len(result))
@@ -346,7 +348,7 @@ func TestMetererOnDemand(t *testing.T) {
// Correct rollback
result, err = dynamoClient.Query(ctx, ondemandTableName, "AccountID = :account", commondynamodb.ExpressionValues{
":account": &types.AttributeValueMemberS{
- Value: accountID2,
+ Value: accountID2.Hex(),
}})
assert.NoError(t, err)
assert.Equal(t, numPrevRecords, len(result))
@@ -463,9 +465,9 @@ func TestMeterer_symbolsCharged(t *testing.T) {
}
}
-func createPaymentHeader(binIndex uint32, cumulativePayment uint64, accountID string) *core.PaymentMetadata {
+func createPaymentHeader(binIndex uint32, cumulativePayment uint64, accountID gethcommon.Address) *core.PaymentMetadata {
return &core.PaymentMetadata{
- AccountID: accountID,
+ AccountID: accountID.Hex(),
BinIndex: binIndex,
CumulativePayment: big.NewInt(int64(cumulativePayment)),
}
diff --git a/core/meterer/onchain_state.go b/core/meterer/onchain_state.go
index 2725ef765..cdfaef457 100644
--- a/core/meterer/onchain_state.go
+++ b/core/meterer/onchain_state.go
@@ -4,9 +4,11 @@ import (
"context"
"fmt"
"sync"
+ "sync/atomic"
"github.com/Layr-Labs/eigenda/core"
"github.com/Layr-Labs/eigenda/core/eth"
+ gethcommon "github.com/ethereum/go-ethereum/common"
)
// PaymentAccounts (For reservations and on-demand payments)
@@ -14,10 +16,11 @@ import (
// OnchainPaymentState is an interface for getting information about the current chain state for payments.
type OnchainPayment interface {
RefreshOnchainPaymentState(ctx context.Context, tx *eth.Reader) error
- GetActiveReservationByAccount(ctx context.Context, accountID string) (core.ActiveReservation, error)
- GetOnDemandPaymentByAccount(ctx context.Context, accountID string) (core.OnDemandPayment, error)
+ GetActiveReservationByAccount(ctx context.Context, accountID gethcommon.Address) (*core.ActiveReservation, error)
+ GetOnDemandPaymentByAccount(ctx context.Context, accountID gethcommon.Address) (*core.OnDemandPayment, error)
GetOnDemandQuorumNumbers(ctx context.Context) ([]uint8, error)
GetGlobalSymbolsPerSecond() uint64
+ GetGlobalRateBinInterval() uint64
GetMinNumSymbols() uint32
GetPricePerSymbol() uint32
GetReservationWindow() uint32
@@ -28,69 +31,73 @@ var _ OnchainPayment = (*OnchainPaymentState)(nil)
type OnchainPaymentState struct {
tx *eth.Reader
- ActiveReservations map[string]core.ActiveReservation
- OnDemandPayments map[string]core.OnDemandPayment
+ ActiveReservations map[gethcommon.Address]*core.ActiveReservation
+ OnDemandPayments map[gethcommon.Address]*core.OnDemandPayment
ReservationsLock sync.RWMutex
OnDemandLocks sync.RWMutex
- PaymentVaultParams PaymentVaultParams
+ PaymentVaultParams atomic.Pointer[PaymentVaultParams]
}
type PaymentVaultParams struct {
GlobalSymbolsPerSecond uint64
+ GlobalRateBinInterval uint64
MinNumSymbols uint32
PricePerSymbol uint32
ReservationWindow uint32
OnDemandQuorumNumbers []uint8
}
-func NewOnchainPaymentState(ctx context.Context, tx *eth.Reader) (OnchainPaymentState, error) {
+func NewOnchainPaymentState(ctx context.Context, tx *eth.Reader) (*OnchainPaymentState, error) {
paymentVaultParams, err := GetPaymentVaultParams(ctx, tx)
if err != nil {
- return OnchainPaymentState{}, err
+ return nil, err
}
- return OnchainPaymentState{
+ state := OnchainPaymentState{
tx: tx,
- ActiveReservations: make(map[string]core.ActiveReservation),
- OnDemandPayments: make(map[string]core.OnDemandPayment),
- PaymentVaultParams: paymentVaultParams,
- }, nil
+ ActiveReservations: make(map[gethcommon.Address]*core.ActiveReservation),
+ OnDemandPayments: make(map[gethcommon.Address]*core.OnDemandPayment),
+ PaymentVaultParams: atomic.Pointer[PaymentVaultParams]{},
+ }
+ state.PaymentVaultParams.Store(paymentVaultParams)
+
+ return &state, nil
}
-func GetPaymentVaultParams(ctx context.Context, tx *eth.Reader) (PaymentVaultParams, error) {
+func GetPaymentVaultParams(ctx context.Context, tx *eth.Reader) (*PaymentVaultParams, error) {
blockNumber, err := tx.GetCurrentBlockNumber(ctx)
if err != nil {
- return PaymentVaultParams{}, err
+ return nil, err
}
quorumNumbers, err := tx.GetRequiredQuorumNumbers(ctx, blockNumber)
if err != nil {
- return PaymentVaultParams{}, err
+ return nil, err
}
globalSymbolsPerSecond, err := tx.GetGlobalSymbolsPerSecond(ctx)
if err != nil {
- return PaymentVaultParams{}, err
+ return nil, err
}
minNumSymbols, err := tx.GetMinNumSymbols(ctx)
if err != nil {
- return PaymentVaultParams{}, err
+ return nil, err
}
pricePerSymbol, err := tx.GetPricePerSymbol(ctx)
if err != nil {
- return PaymentVaultParams{}, err
+ return nil, err
}
reservationWindow, err := tx.GetReservationWindow(ctx)
if err != nil {
- return PaymentVaultParams{}, err
+ return nil, err
}
- return PaymentVaultParams{
+ return &PaymentVaultParams{
OnDemandQuorumNumbers: quorumNumbers,
GlobalSymbolsPerSecond: globalSymbolsPerSecond,
MinNumSymbols: minNumSymbols,
@@ -106,63 +113,88 @@ func (pcs *OnchainPaymentState) RefreshOnchainPaymentState(ctx context.Context,
return err
}
// These parameters should be rarely updated, but we refresh them anyway
- pcs.PaymentVaultParams = paymentVaultParams
+ pcs.PaymentVaultParams.Store(paymentVaultParams)
+
+ pcs.ReservationsLock.Lock()
+ accountIDs := make([]gethcommon.Address, 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([]gethcommon.Address, 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
}
// GetActiveReservationByAccount returns a pointer to the active reservation for the given account ID; no writes will be made to the reservation
-func (pcs *OnchainPaymentState) GetActiveReservationByAccount(ctx context.Context, accountID string) (core.ActiveReservation, error) {
- if reservation, ok := pcs.ActiveReservations[accountID]; ok {
+func (pcs *OnchainPaymentState) GetActiveReservationByAccount(ctx context.Context, accountID gethcommon.Address) (*core.ActiveReservation, error) {
+ pcs.ReservationsLock.RLock()
+ defer pcs.ReservationsLock.RUnlock()
+ 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
+ return nil, err
}
-
pcs.ReservationsLock.Lock()
- pcs.ActiveReservations[accountID] = res
+ (pcs.ActiveReservations)[accountID] = res
pcs.ReservationsLock.Unlock()
return res, nil
}
// 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)
+func (pcs *OnchainPaymentState) GetActiveReservationByAccountOnChain(ctx context.Context, accountID gethcommon.Address) (*core.ActiveReservation, error) {
+ res, err := pcs.tx.GetActiveReservationByAccount(ctx, accountID)
if err != nil {
- return core.ActiveReservation{}, fmt.Errorf("reservation account not found on-chain: %w", err)
+ return nil, fmt.Errorf("reservation account not found on-chain: %w", err)
}
return res, nil
}
// GetOnDemandPaymentByAccount returns a pointer to the on-demand payment for the given account ID; no writes will be made to the payment
-func (pcs *OnchainPaymentState) GetOnDemandPaymentByAccount(ctx context.Context, accountID string) (core.OnDemandPayment, error) {
- if payment, ok := pcs.OnDemandPayments[accountID]; ok {
+func (pcs *OnchainPaymentState) GetOnDemandPaymentByAccount(ctx context.Context, accountID gethcommon.Address) (*core.OnDemandPayment, error) {
+ pcs.OnDemandLocks.RLock()
+ defer pcs.OnDemandLocks.RUnlock()
+ 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
+ return nil, err
}
pcs.OnDemandLocks.Lock()
- pcs.OnDemandPayments[accountID] = res
+ (pcs.OnDemandPayments)[accountID] = res
pcs.OnDemandLocks.Unlock()
return res, nil
}
-func (pcs *OnchainPaymentState) GetOnDemandPaymentByAccountOnChain(ctx context.Context, accountID string) (core.OnDemandPayment, error) {
- blockNumber, err := pcs.tx.GetCurrentBlockNumber(ctx)
+func (pcs *OnchainPaymentState) GetOnDemandPaymentByAccountOnChain(ctx context.Context, accountID gethcommon.Address) (*core.OnDemandPayment, error) {
+ res, err := pcs.tx.GetOnDemandPaymentByAccount(ctx, accountID)
if err != nil {
- return core.OnDemandPayment{}, err
- }
- res, err := pcs.tx.GetOnDemandPaymentByAccount(ctx, blockNumber, accountID)
- if err != nil {
- return core.OnDemandPayment{}, fmt.Errorf("on-demand not found on-chain: %w", err)
+ return nil, fmt.Errorf("on-demand not found on-chain: %w", err)
}
return res, nil
}
@@ -176,17 +208,21 @@ func (pcs *OnchainPaymentState) GetOnDemandQuorumNumbers(ctx context.Context) ([
}
func (pcs *OnchainPaymentState) GetGlobalSymbolsPerSecond() uint64 {
- return pcs.PaymentVaultParams.GlobalSymbolsPerSecond
+ return pcs.PaymentVaultParams.Load().GlobalSymbolsPerSecond
+}
+
+func (pcs *OnchainPaymentState) GetGlobalRateBinInterval() uint64 {
+ return pcs.PaymentVaultParams.Load().GlobalRateBinInterval
}
func (pcs *OnchainPaymentState) GetMinNumSymbols() uint32 {
- return pcs.PaymentVaultParams.MinNumSymbols
+ return pcs.PaymentVaultParams.Load().MinNumSymbols
}
func (pcs *OnchainPaymentState) GetPricePerSymbol() uint32 {
- return pcs.PaymentVaultParams.PricePerSymbol
+ return pcs.PaymentVaultParams.Load().PricePerSymbol
}
func (pcs *OnchainPaymentState) GetReservationWindow() uint32 {
- return pcs.PaymentVaultParams.ReservationWindow
+ return pcs.PaymentVaultParams.Load().ReservationWindow
}
diff --git a/core/meterer/onchain_state_test.go b/core/meterer/onchain_state_test.go
index efd7149a6..d7fca8484 100644
--- a/core/meterer/onchain_state_test.go
+++ b/core/meterer/onchain_state_test.go
@@ -8,18 +8,19 @@ import (
"github.com/Layr-Labs/eigenda/core"
"github.com/Layr-Labs/eigenda/core/eth"
"github.com/Layr-Labs/eigenda/core/mock"
+ gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/assert"
testifymock "github.com/stretchr/testify/mock"
)
var (
- dummyActiveReservation = core.ActiveReservation{
- SymbolsPerSec: 100,
- StartTimestamp: 1000,
- EndTimestamp: 2000,
- QuorumSplit: []byte{50, 50},
+ dummyActiveReservation = &core.ActiveReservation{
+ SymbolsPerSecond: 100,
+ StartTimestamp: 1000,
+ EndTimestamp: 2000,
+ QuorumSplits: []byte{50, 50},
}
- dummyOnDemandPayment = core.OnDemandPayment{
+ dummyOnDemandPayment = &core.OnDemandPayment{
CumulativePayment: big.NewInt(1000),
}
)
@@ -47,7 +48,7 @@ func TestGetActiveReservationByAccount(t *testing.T) {
ctx := context.Background()
mockState.On("GetActiveReservationByAccount", testifymock.Anything, testifymock.Anything).Return(dummyActiveReservation, nil)
- reservation, err := mockState.GetActiveReservationByAccount(ctx, "account1")
+ reservation, err := mockState.GetActiveReservationByAccount(ctx, gethcommon.Address{})
assert.NoError(t, err)
assert.Equal(t, dummyActiveReservation, reservation)
}
@@ -55,10 +56,9 @@ func TestGetActiveReservationByAccount(t *testing.T) {
func TestGetOnDemandPaymentByAccount(t *testing.T) {
mockState := &mock.MockOnchainPaymentState{}
ctx := context.Background()
- accountID := "account1"
mockState.On("GetOnDemandPaymentByAccount", testifymock.Anything, testifymock.Anything, testifymock.Anything).Return(dummyOnDemandPayment, nil)
- payment, err := mockState.GetOnDemandPaymentByAccount(ctx, accountID)
+ payment, err := mockState.GetOnDemandPaymentByAccount(ctx, gethcommon.Address{})
assert.NoError(t, err)
assert.Equal(t, dummyOnDemandPayment, payment)
}
diff --git a/core/mock/payment_state.go b/core/mock/payment_state.go
index c5e788510..e4c89784d 100644
--- a/core/mock/payment_state.go
+++ b/core/mock/payment_state.go
@@ -6,6 +6,7 @@ import (
"github.com/Layr-Labs/eigenda/core"
"github.com/Layr-Labs/eigenda/core/eth"
"github.com/Layr-Labs/eigenda/core/meterer"
+ gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/mock"
)
@@ -29,20 +30,20 @@ func (m *MockOnchainPaymentState) RefreshOnchainPaymentState(ctx context.Context
return args.Error(0)
}
-func (m *MockOnchainPaymentState) GetActiveReservationByAccount(ctx context.Context, accountID string) (core.ActiveReservation, error) {
+func (m *MockOnchainPaymentState) GetActiveReservationByAccount(ctx context.Context, accountID gethcommon.Address) (*core.ActiveReservation, error) {
args := m.Called(ctx, accountID)
- var value core.ActiveReservation
+ var value *core.ActiveReservation
if args.Get(0) != nil {
- value = args.Get(0).(core.ActiveReservation)
+ value = args.Get(0).(*core.ActiveReservation)
}
return value, args.Error(1)
}
-func (m *MockOnchainPaymentState) GetOnDemandPaymentByAccount(ctx context.Context, accountID string) (core.OnDemandPayment, error) {
+func (m *MockOnchainPaymentState) GetOnDemandPaymentByAccount(ctx context.Context, accountID gethcommon.Address) (*core.OnDemandPayment, error) {
args := m.Called(ctx, accountID)
- var value core.OnDemandPayment
+ var value *core.OnDemandPayment
if args.Get(0) != nil {
- value = args.Get(0).(core.OnDemandPayment)
+ value = args.Get(0).(*core.OnDemandPayment)
}
return value, args.Error(1)
}
@@ -61,6 +62,11 @@ func (m *MockOnchainPaymentState) GetGlobalSymbolsPerSecond() uint64 {
return args.Get(0).(uint64)
}
+func (m *MockOnchainPaymentState) GetGlobalRateBinInterval() uint64 {
+ args := m.Called()
+ return args.Get(0).(uint64)
+}
+
func (m *MockOnchainPaymentState) GetMinNumSymbols() uint32 {
args := m.Called()
return args.Get(0).(uint32)
diff --git a/core/mock/writer.go b/core/mock/writer.go
index 7e56e64cc..0f1dcee9e 100644
--- a/core/mock/writer.go
+++ b/core/mock/writer.go
@@ -221,28 +221,28 @@ func (t *MockWriter) PubkeyHashToOperator(ctx context.Context, operatorId core.O
return result.(gethcommon.Address), args.Error(1)
}
-func (t *MockWriter) GetActiveReservations(ctx context.Context, blockNumber uint32, accountIDs []string) (map[string]core.ActiveReservation, error) {
+func (t *MockWriter) GetActiveReservations(ctx context.Context, accountIDs []gethcommon.Address) (map[gethcommon.Address]*core.ActiveReservation, error) {
args := t.Called()
result := args.Get(0)
- return result.(map[string]core.ActiveReservation), args.Error(1)
+ return result.(map[gethcommon.Address]*core.ActiveReservation), args.Error(1)
}
-func (t *MockWriter) GetActiveReservationByAccount(ctx context.Context, blockNumber uint32, accountID string) (core.ActiveReservation, error) {
+func (t *MockWriter) GetActiveReservationByAccount(ctx context.Context, accountID gethcommon.Address) (*core.ActiveReservation, error) {
args := t.Called()
result := args.Get(0)
- return result.(core.ActiveReservation), args.Error(1)
+ return result.(*core.ActiveReservation), args.Error(1)
}
-func (t *MockWriter) GetOnDemandPayments(ctx context.Context, blockNumber uint32, accountIDs []string) (map[string]core.OnDemandPayment, error) {
+func (t *MockWriter) GetOnDemandPayments(ctx context.Context, accountIDs []gethcommon.Address) (map[gethcommon.Address]*core.OnDemandPayment, error) {
args := t.Called()
result := args.Get(0)
- return result.(map[string]core.OnDemandPayment), args.Error(1)
+ return result.(map[gethcommon.Address]*core.OnDemandPayment), args.Error(1)
}
-func (t *MockWriter) GetOnDemandPaymentByAccount(ctx context.Context, blockNumber uint32, accountID string) (core.OnDemandPayment, error) {
+func (t *MockWriter) GetOnDemandPaymentByAccount(ctx context.Context, accountID gethcommon.Address) (*core.OnDemandPayment, error) {
args := t.Called()
result := args.Get(0)
- return result.(core.OnDemandPayment), args.Error(1)
+ return result.(*core.OnDemandPayment), args.Error(1)
}
func (t *MockWriter) GetOperatorSocket(ctx context.Context, operatorID core.OperatorID) (string, error) {
diff --git a/disperser/apiserver/server_test.go b/disperser/apiserver/server_test.go
index 43a5b0333..29f4f74a9 100644
--- a/disperser/apiserver/server_test.go
+++ b/disperser/apiserver/server_test.go
@@ -758,15 +758,15 @@ func newTestServer(transactor core.Writer, testName string) *apiserver.Dispersal
mockState.On("GetRequiredQuorumNumbers").Return([]uint8{0, 1}, nil)
mockState.On("GetOnDemandQuorumNumbers").Return([]uint8{0, 1}, nil)
mockState.On("GetReservationWindow").Return(uint32(1), nil)
- mockState.On("GetOnDemandPaymentByAccount", tmock.Anything, tmock.Anything).Return(core.OnDemandPayment{
+ mockState.On("GetOnDemandPaymentByAccount", tmock.Anything, tmock.Anything).Return(&core.OnDemandPayment{
CumulativePayment: big.NewInt(3000),
}, nil)
- mockState.On("GetActiveReservationByAccount", tmock.Anything, tmock.Anything).Return(core.ActiveReservation{
- SymbolsPerSec: 2048,
- StartTimestamp: 0,
- EndTimestamp: math.MaxUint32,
- QuorumNumbers: []uint8{0, 1},
- QuorumSplit: []byte{50, 50},
+ mockState.On("GetActiveReservationByAccount", tmock.Anything, tmock.Anything).Return(&core.ActiveReservation{
+ SymbolsPerSecond: 2048,
+ StartTimestamp: 0,
+ EndTimestamp: math.MaxUint32,
+ QuorumNumbers: []uint8{0, 1},
+ QuorumSplits: []byte{50, 50},
}, nil)
// append test name to each table name for an unique store
table_names := []string{"reservations_server_" + testName, "ondemand_server_" + testName, "global_server_" + testName}
diff --git a/disperser/apiserver/server_v2.go b/disperser/apiserver/server_v2.go
index e8dece0b3..cb96f8b40 100644
--- a/disperser/apiserver/server_v2.go
+++ b/disperser/apiserver/server_v2.go
@@ -22,6 +22,7 @@ import (
"github.com/Layr-Labs/eigenda/disperser/common/v2/blobstore"
"github.com/Layr-Labs/eigenda/encoding"
"github.com/Layr-Labs/eigensdk-go/logging"
+ gethcommon "github.com/ethereum/go-ethereum/common"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
)
@@ -222,6 +223,7 @@ func (s *DispersalServerV2) RefreshOnchainState(ctx context.Context) error {
}
func (s *DispersalServerV2) GetPaymentState(ctx context.Context, req *pb.GetPaymentStateRequest) (*pb.GetPaymentStateReply, error) {
+ accountID := gethcommon.HexToAddress(req.AccountId)
// validate the signature
if err := s.authenticator.AuthenticatePaymentStateRequest(req.GetSignature(), req.GetAccountId()); err != nil {
return nil, api.NewErrorInvalidArg(fmt.Sprintf("authentication failed: %s", err.Error()))
@@ -244,11 +246,11 @@ func (s *DispersalServerV2) GetPaymentState(ctx context.Context, req *pb.GetPaym
return nil, api.NewErrorNotFound("failed to get largest cumulative payment")
}
// on-Chain account state
- reservation, err := s.meterer.ChainPaymentState.GetActiveReservationByAccount(ctx, req.AccountId)
+ reservation, err := s.meterer.ChainPaymentState.GetActiveReservationByAccount(ctx, accountID)
if err != nil {
return nil, api.NewErrorNotFound("failed to get active reservation")
}
- onDemandPayment, err := s.meterer.ChainPaymentState.GetOnDemandPaymentByAccount(ctx, req.AccountId)
+ onDemandPayment, err := s.meterer.ChainPaymentState.GetOnDemandPaymentByAccount(ctx, accountID)
if err != nil {
return nil, api.NewErrorNotFound("failed to get on-demand payment")
}
@@ -264,20 +266,21 @@ 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)
+
+ quorumSplits := make([]uint32, len(reservation.QuorumSplits))
+ for i, v := range reservation.QuorumSplits {
+ quorumSplits[i] = uint32(v)
}
// build reply
reply := &pb.GetPaymentStateReply{
PaymentGlobalParams: &paymentGlobalParams,
BinRecords: binRecords[:],
Reservation: &pb.Reservation{
- SymbolsPerSecond: reservation.SymbolsPerSec,
+ SymbolsPerSecond: reservation.SymbolsPerSecond,
StartTimestamp: uint32(reservation.StartTimestamp),
EndTimestamp: uint32(reservation.EndTimestamp),
QuorumNumbers: quorumNumbers,
- QuorumSplit: quorumSplit,
+ QuorumSplits: quorumSplits,
},
CumulativePayment: largestCumulativePayment.Bytes(),
OnchainCumulativePayment: onDemandPayment.CumulativePayment.Bytes(),
diff --git a/disperser/apiserver/server_v2_test.go b/disperser/apiserver/server_v2_test.go
index 17f84f510..d5f826287 100644
--- a/disperser/apiserver/server_v2_test.go
+++ b/disperser/apiserver/server_v2_test.go
@@ -441,8 +441,8 @@ func newTestServerV2(t *testing.T) *testComponents {
mockState.On("GetMinNumSymbols", tmock.Anything).Return(uint32(3), nil)
now := uint64(time.Now().Unix())
- mockState.On("GetActiveReservationByAccount", tmock.Anything, tmock.Anything).Return(core.ActiveReservation{SymbolsPerSec: 100, StartTimestamp: now + 1200, EndTimestamp: now + 1800, QuorumSplit: []byte{50, 50}, QuorumNumbers: []uint8{0, 1}}, nil)
- mockState.On("GetOnDemandPaymentByAccount", tmock.Anything, tmock.Anything).Return(core.OnDemandPayment{CumulativePayment: big.NewInt(3864)}, nil)
+ mockState.On("GetActiveReservationByAccount", tmock.Anything, tmock.Anything).Return(&core.ActiveReservation{SymbolsPerSecond: 100, StartTimestamp: now + 1200, EndTimestamp: now + 1800, QuorumSplits: []byte{50, 50}, QuorumNumbers: []uint8{0, 1}}, nil)
+ mockState.On("GetOnDemandPaymentByAccount", tmock.Anything, tmock.Anything).Return(&core.OnDemandPayment{CumulativePayment: big.NewInt(3864)}, nil)
mockState.On("GetOnDemandQuorumNumbers", tmock.Anything).Return([]uint8{0, 1}, nil)
if err := mockState.RefreshOnchainPaymentState(context.Background(), nil); err != nil {
diff --git a/disperser/cmd/apiserver/main.go b/disperser/cmd/apiserver/main.go
index bebdc1812..9a5752b6a 100644
--- a/disperser/cmd/apiserver/main.go
+++ b/disperser/cmd/apiserver/main.go
@@ -124,7 +124,7 @@ func RunDisperserServer(ctx *cli.Context) error {
// add some default sensible configs
meterer = mt.NewMeterer(
mtConfig,
- &paymentChainState,
+ paymentChainState,
offchainStore,
logger,
// metrics.NewNoopMetrics(),
diff --git a/test/integration_test.go b/test/integration_test.go
index b3efdc25f..5016f3598 100644
--- a/test/integration_test.go
+++ b/test/integration_test.go
@@ -216,20 +216,20 @@ func mustMakeDisperser(t *testing.T, cst core.IndexedChainState, store disperser
if err != nil {
panic("failed to convert hex to ECDSA")
}
- publicKey := crypto.PubkeyToAddress(privateKey.PublicKey).Hex()
+ publicKey := crypto.PubkeyToAddress(privateKey.PublicKey)
mockState := &coremock.MockOnchainPaymentState{}
reservationLimit := uint64(1024)
paymentLimit := big.NewInt(512)
- mockState.On("GetActiveReservationByAccount", mock.Anything, mock.MatchedBy(func(account string) bool {
+ mockState.On("GetActiveReservationByAccount", mock.Anything, mock.MatchedBy(func(account gethcommon.Address) bool {
return account == publicKey
- })).Return(core.ActiveReservation{SymbolsPerSec: reservationLimit, StartTimestamp: 0, EndTimestamp: math.MaxUint32, QuorumSplit: []byte{50, 50}, QuorumNumbers: []uint8{0, 1}}, nil)
- mockState.On("GetActiveReservationByAccount", mock.Anything, mock.Anything).Return(core.ActiveReservation{}, errors.New("reservation not found"))
+ })).Return(&core.ActiveReservation{SymbolsPerSecond: reservationLimit, StartTimestamp: 0, EndTimestamp: math.MaxUint32, QuorumSplits: []byte{50, 50}, QuorumNumbers: []uint8{0, 1}}, nil)
+ mockState.On("GetActiveReservationByAccount", mock.Anything, mock.Anything).Return(&core.ActiveReservation{}, errors.New("reservation not found"))
- mockState.On("GetOnDemandPaymentByAccount", mock.Anything, mock.MatchedBy(func(account string) bool {
+ mockState.On("GetOnDemandPaymentByAccount", mock.Anything, mock.MatchedBy(func(account gethcommon.Address) bool {
return account == publicKey
- })).Return(core.OnDemandPayment{CumulativePayment: paymentLimit}, nil)
- mockState.On("GetOnDemandPaymentByAccount", mock.Anything, mock.Anything).Return(core.OnDemandPayment{}, errors.New("payment not found"))
+ })).Return(&core.OnDemandPayment{CumulativePayment: paymentLimit}, nil)
+ mockState.On("GetOnDemandPaymentByAccount", mock.Anything, mock.Anything).Return(&core.OnDemandPayment{}, errors.New("payment not found"))
mockState.On("GetOnDemandQuorumNumbers", mock.Anything).Return([]uint8{0, 1}, nil)
mockState.On("GetGlobalSymbolsPerSecond", mock.Anything).Return(uint64(1024), nil)
mockState.On("GetPricePerSymbol", mock.Anything).Return(uint32(1), nil)