diff --git a/contracts/script/SetUpEigenDA.s.sol b/contracts/script/SetUpEigenDA.s.sol index 47213d9df..a46f5d8cd 100644 --- a/contracts/script/SetUpEigenDA.s.sol +++ b/contracts/script/SetUpEigenDA.s.sol @@ -174,20 +174,31 @@ contract SetupEigenDA is EigenDADeployer, EigenLayerUtils { // Register Reservations for client as the eigenDACommunityMultisig - IPaymentVault.Reservation memory reservation = IPaymentVault.Reservation({ - symbolsPerSecond: 452198, + IPaymentVault.Reservation memory reservation1 = IPaymentVault.Reservation({ + symbolsPerSecond: 50, // 15k symbols over 5 minute bin interval startTimestamp: uint64(block.timestamp), endTimestamp: uint64(block.timestamp + 1000000000), quorumNumbers: hex"0001", quorumSplits: hex"3232" }); - address clientAddress = address(0x641691973c98dFe68b07Ee3613E270406285DFE8); - vm.startBroadcast(msg.sender); - paymentVault.setReservation(clientAddress, reservation); + vm.startBroadcast(); + paymentVault.setReservation(address(0x641691973c98dFe68b07Ee3613E270406285DFE8), reservation1); + + // small reservation + IPaymentVault.Reservation memory reservation2 = IPaymentVault.Reservation({ + symbolsPerSecond: 15, // 4500 symbols over 5 minute bin interval + startTimestamp: uint64(block.timestamp), + endTimestamp: uint64(block.timestamp + 1000000000), + quorumNumbers: hex"0001", + quorumSplits: hex"3232" + }); + paymentVault.setReservation(address(0x56242c5e4C968669FE04331AC89967a7F5A06B24), reservation2); + // Deposit OnDemand - paymentVault.depositOnDemand{value: 0.1 ether}(clientAddress); - vm.stopBroadcast(); + paymentVault.depositOnDemand{value: 0.1 ether}(address(0x641691973c98dFe68b07Ee3613E270406285DFE8)); + paymentVault.depositOnDemand{value: 2000 gwei}(address(0x55c781dd60F8418Fc8a65D14907aFF47C903a559)); + vm.stopBroadcast(); // Deposit stakers into EigenLayer and delegate to operators for (uint256 i = 0; i < stakerPrivateKeys.length; i++) { vm.startBroadcast(stakerPrivateKeys[i]); diff --git a/disperser/apiserver/disperse_blob_v2.go b/disperser/apiserver/disperse_blob_v2.go index d8fcd3dd8..4e3e8ca7d 100644 --- a/disperser/apiserver/disperse_blob_v2.go +++ b/disperser/apiserver/disperse_blob_v2.go @@ -118,7 +118,7 @@ func (s *DispersalServerV2) validateDispersalRequest(ctx context.Context, req *p return api.NewErrorInvalidArg("payment metadata is required") } - if len(blobHeader.PaymentMetadata.AccountID) == 0 || blobHeader.PaymentMetadata.ReservationPeriod == 0 || blobHeader.PaymentMetadata.CumulativePayment == nil { + if len(blobHeader.PaymentMetadata.AccountID) == 0 || (blobHeader.PaymentMetadata.ReservationPeriod == 0 && blobHeader.PaymentMetadata.CumulativePayment.Cmp(big.NewInt(0)) == 0) { return api.NewErrorInvalidArg("invalid payment metadata") } diff --git a/disperser/apiserver/server_v2_test.go b/disperser/apiserver/server_v2_test.go index 367d3c9bb..305b6bd43 100644 --- a/disperser/apiserver/server_v2_test.go +++ b/disperser/apiserver/server_v2_test.go @@ -223,7 +223,7 @@ func TestV2DisperseBlobRequestValidation(t *testing.T) { PaymentHeader: &pbcommon.PaymentHeader{ AccountId: accountID, ReservationPeriod: 0, - CumulativePayment: big.NewInt(100).Bytes(), + CumulativePayment: big.NewInt(0).Bytes(), }, } blobHeader, err := corev2.BlobHeaderFromProtobuf(invalidReqProto) diff --git a/inabox/tests/integration_v2_payments_test.go b/inabox/tests/integration_v2_payments_test.go new file mode 100644 index 000000000..3c9755c0d --- /dev/null +++ b/inabox/tests/integration_v2_payments_test.go @@ -0,0 +1,94 @@ +package integration_test + +import ( + "context" + "crypto/rand" + "time" + + "github.com/Layr-Labs/eigenda/api/clients/v2" + auth "github.com/Layr-Labs/eigenda/core/auth/v2" + dispv2 "github.com/Layr-Labs/eigenda/disperser/common/v2" + "github.com/Layr-Labs/eigenda/encoding/utils/codec" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("Inabox v2 Integration", func() { + It("reservation runs out", func() { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + privateKeyHex := "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdee" + signer := auth.NewLocalBlobRequestSigner(privateKeyHex) + + disp, err := clients.NewDisperserClient(&clients.DisperserClientConfig{ + Hostname: "localhost", + Port: "32005", + }, signer, nil, nil) + Expect(err).To(BeNil()) + Expect(disp).To(Not(BeNil())) + + data1 := make([]byte, 992) + _, err = rand.Read(data1) + Expect(err).To(BeNil()) + data2 := make([]byte, 123) + _, err = rand.Read(data2) + Expect(err).To(BeNil()) + + paddedData1 := codec.ConvertByPaddingEmptyByte(data1) + paddedData2 := codec.ConvertByPaddingEmptyByte(data2) + + blobStatus1, key1, err := disp.DisperseBlob(ctx, paddedData1, 0, []uint8{0, 1}, 0) + Expect(err).To(BeNil()) + Expect(key1).To(Not(BeNil())) + Expect(blobStatus1).To(Not(BeNil())) + Expect(*blobStatus1).To(Equal(dispv2.Queued)) + + blobStatus2, key2, err := disp.DisperseBlob(ctx, paddedData2, 0, []uint8{0}, 0) + Expect(err).To(BeNil()) + Expect(key2).To(Not(BeNil())) + Expect(blobStatus2).To(Not(BeNil())) + Expect(*blobStatus2).To(Equal(dispv2.Queued)) + + blobStatus3, key3, err := disp.DisperseBlob(ctx, paddedData2, 0, []uint8{0}, 0) + Expect(err.Error()).To(ContainSubstring("neither reservation nor on-demand payment is available")) + Expect(key3).To(Not(BeNil())) + Expect(blobStatus3).To(BeNil()) + }) + + It("ondemand runs out", func() { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + privateKeyHex := "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + signer := auth.NewLocalBlobRequestSigner(privateKeyHex) + + disp, err := clients.NewDisperserClient(&clients.DisperserClientConfig{ + Hostname: "localhost", + Port: "32005", + }, signer, nil, nil) + Expect(err).To(BeNil()) + Expect(disp).To(Not(BeNil())) + + data1 := make([]byte, 992) + _, err = rand.Read(data1) + Expect(err).To(BeNil()) + data2 := make([]byte, 123) + _, err = rand.Read(data2) + Expect(err).To(BeNil()) + + paddedData1 := codec.ConvertByPaddingEmptyByte(data1) + paddedData2 := codec.ConvertByPaddingEmptyByte(data2) + + blobStatus1, key1, err := disp.DisperseBlob(ctx, paddedData1, 0, []uint8{0, 1}, 0) + Expect(err).To(BeNil()) + Expect(key1).To(Not(BeNil())) + Expect(blobStatus1).To(Not(BeNil())) + Expect(*blobStatus1).To(Equal(dispv2.Queued)) + + blobStatus2, key2, err := disp.DisperseBlob(ctx, paddedData2, 0, []uint8{0}, 0) + Expect(err.Error()).To(ContainSubstring("neither reservation nor on-demand payment is available")) + Expect(blobStatus2).To(BeNil()) + Expect(key2).To(Not(BeNil())) + }) +})