Skip to content

Commit

Permalink
refactor: type conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
hopeyen committed Oct 31, 2024
1 parent bd4fb22 commit d5b7f37
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 65 deletions.
10 changes: 7 additions & 3 deletions api/clients/accountant.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/Layr-Labs/eigenda/core/meterer"
)

var minNumBins uint32 = 3

type IAccountant interface {
AccountBlob(ctx context.Context, data []byte, quorums []uint8) (uint32, uint64, error)
}
Expand All @@ -32,14 +34,15 @@ type accountant struct {
cumulativePayment *big.Int

paymentSigner core.PaymentSigner
numBins uint32
}

type BinRecord struct {
Index uint32
Usage uint64
}

func NewAccountant(reservation *core.ActiveReservation, onDemand *core.OnDemandPayment, reservationWindow uint32, pricePerSymbol uint32, minNumSymbols uint32, paymentSigner core.PaymentSigner) *accountant {
func NewAccountant(reservation *core.ActiveReservation, onDemand *core.OnDemandPayment, reservationWindow uint32, pricePerSymbol uint32, minNumSymbols uint32, paymentSigner core.PaymentSigner, numBins uint32) *accountant {
//TODO: client storage; currently every instance starts fresh but on-chain or a small store makes more sense
// Also client is currently responsible for supplying network params, we need to add RPC in order to be automatic
// There's a subsequent PR that handles populating the accountant with on-chain state from the disperser
Expand All @@ -52,6 +55,7 @@ func NewAccountant(reservation *core.ActiveReservation, onDemand *core.OnDemandP
binRecords: []BinRecord{{Index: 0, Usage: 0}, {Index: 1, Usage: 0}, {Index: 2, Usage: 0}},
cumulativePayment: big.NewInt(0),
paymentSigner: paymentSigner,
numBins: max(numBins, minNumBins),
}
// TODO: add a routine to refresh the on-chain state occasionally?
return &a
Expand Down Expand Up @@ -119,7 +123,7 @@ func (a *accountant) AccountBlob(ctx context.Context, numSymbols uint64, quorums
}
protoPaymentHeader := pm.ConvertToProtoPaymentHeader()

signature, err := a.paymentSigner.SignBlobPayment(protoPaymentHeader)
signature, err := a.paymentSigner.SignBlobPayment(pm)
if err != nil {
return nil, nil, err
}
Expand All @@ -144,7 +148,7 @@ func (a *accountant) SymbolsCharged(numSymbols uint) uint32 {
}

func (a *accountant) GetRelativeBinRecord(index uint32) *BinRecord {
relativeIndex := index % 3
relativeIndex := index % a.numBins
if a.binRecords[relativeIndex].Index != uint32(index) {
a.binRecords[relativeIndex] = BinRecord{
Index: uint32(index),
Expand Down
20 changes: 11 additions & 9 deletions api/clients/accountant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import (
"github.com/stretchr/testify/assert"
)

const numBins = uint32(3)

func TestNewAccountant(t *testing.T) {
reservation := core.ActiveReservation{
SymbolsPerSec: 100,
Expand All @@ -34,7 +36,7 @@ func TestNewAccountant(t *testing.T) {
privateKey1, err := crypto.GenerateKey()
assert.NoError(t, err)
paymentSigner := auth.NewPaymentSigner(hex.EncodeToString(privateKey1.D.Bytes()))
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner)
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner, numBins)

assert.NotNil(t, accountant)
assert.Equal(t, reservation, accountant.reservation)
Expand Down Expand Up @@ -64,7 +66,7 @@ func TestAccountBlob_Reservation(t *testing.T) {
privateKey1, err := crypto.GenerateKey()
assert.NoError(t, err)
paymentSigner := auth.NewPaymentSigner(hex.EncodeToString(privateKey1.D.Bytes()))
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner)
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner, numBins)

ctx := context.Background()
symbolLength := uint64(500)
Expand Down Expand Up @@ -115,7 +117,7 @@ func TestAccountBlob_OnDemand(t *testing.T) {
privateKey1, err := crypto.GenerateKey()
assert.NoError(t, err)
paymentSigner := auth.NewPaymentSigner(hex.EncodeToString(privateKey1.D.Bytes()))
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner)
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner, numBins)

ctx := context.Background()
numSymbols := uint64(1500)
Expand Down Expand Up @@ -144,7 +146,7 @@ func TestAccountBlob_InsufficientOnDemand(t *testing.T) {
privateKey1, err := crypto.GenerateKey()
assert.NoError(t, err)
paymentSigner := auth.NewPaymentSigner(hex.EncodeToString(privateKey1.D.Bytes()))
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner)
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner, numBins)

ctx := context.Background()
numSymbols := uint64(2000)
Expand Down Expand Up @@ -172,7 +174,7 @@ func TestAccountBlobCallSeries(t *testing.T) {
privateKey1, err := crypto.GenerateKey()
assert.NoError(t, err)
paymentSigner := auth.NewPaymentSigner(hex.EncodeToString(privateKey1.D.Bytes()))
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner)
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner, numBins)

ctx := context.Background()
quorums := []uint8{0, 1}
Expand Down Expand Up @@ -222,7 +224,7 @@ func TestAccountBlob_BinRotation(t *testing.T) {
privateKey1, err := crypto.GenerateKey()
assert.NoError(t, err)
paymentSigner := auth.NewPaymentSigner(hex.EncodeToString(privateKey1.D.Bytes()))
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner)
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner, numBins)

ctx := context.Background()
quorums := []uint8{0, 1}
Expand Down Expand Up @@ -265,7 +267,7 @@ func TestConcurrentBinRotationAndAccountBlob(t *testing.T) {
privateKey1, err := crypto.GenerateKey()
assert.NoError(t, err)
paymentSigner := auth.NewPaymentSigner(hex.EncodeToString(privateKey1.D.Bytes()))
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner)
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner, numBins)

ctx := context.Background()
quorums := []uint8{0, 1}
Expand Down Expand Up @@ -311,7 +313,7 @@ func TestAccountBlob_ReservationWithOneOverflow(t *testing.T) {
privateKey1, err := crypto.GenerateKey()
assert.NoError(t, err)
paymentSigner := auth.NewPaymentSigner(hex.EncodeToString(privateKey1.D.Bytes()))
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner)
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner, numBins)
ctx := context.Background()
quorums := []uint8{0, 1}
now := time.Now().Unix()
Expand Down Expand Up @@ -358,7 +360,7 @@ func TestAccountBlob_ReservationOverflowReset(t *testing.T) {
privateKey1, err := crypto.GenerateKey()
assert.NoError(t, err)
paymentSigner := auth.NewPaymentSigner(hex.EncodeToString(privateKey1.D.Bytes()))
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner)
accountant := NewAccountant(&reservation, &onDemand, reservationWindow, pricePerSymbol, minNumSymbols, paymentSigner, numBins)

ctx := context.Background()
quorums := []uint8{0, 1}
Expand Down
3 changes: 3 additions & 0 deletions api/clients/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ type EigenDAClientConfig struct {
// if set to "", will result in a non-paying client and cannot disperse paid blobs.
PaymentSignerPrivateKeyHex string

// Payment number of bins indicate how many bins are kept at all times; the minimum is set to 3.
PaymentNumBins uint32

// Whether to disable TLS for an insecure connection when connecting to a local EigenDA disperser instance.
DisableTLS bool

Expand Down
2 changes: 1 addition & 1 deletion api/clients/eigenda_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func NewEigenDAClient(log log.Logger, config EigenDAClientConfig) (*EigenDAClien
}

// a subsequent PR contains updates to fill in payment state
accountant := NewAccountant(&core.ActiveReservation{}, &core.OnDemandPayment{}, 0, 0, 0, paymentSigner)
accountant := NewAccountant(&core.ActiveReservation{}, &core.OnDemandPayment{}, 0, 0, 0, paymentSigner, config.PaymentNumBins)

disperserClient := NewDisperserClient(disperserConfig, signer, accountant)

Expand Down
4 changes: 2 additions & 2 deletions core/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"errors"
"fmt"

commonpb "github.com/Layr-Labs/eigenda/api/grpc/common"
geth "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
Expand Down Expand Up @@ -51,6 +50,7 @@ func VerifySignature(message []byte, accountAddr geth.Address, sig []byte) error
}

type PaymentSigner interface {
SignBlobPayment(header *commonpb.PaymentHeader) ([]byte, error)
// SignBlobPayment(header *commonpb.PaymentHeader) ([]byte, error)
SignBlobPayment(header *PaymentMetadata) ([]byte, error)
GetAccountID() string
}
17 changes: 8 additions & 9 deletions core/auth/payment_signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"log"

commonpb "github.com/Layr-Labs/eigenda/api/grpc/common"
"github.com/Layr-Labs/eigenda/core"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
Expand All @@ -31,9 +30,10 @@ func NewPaymentSigner(privateKeyHex string) *PaymentSigner {
}

// SignBlobPayment signs the payment header and returns the signature
func (s *PaymentSigner) SignBlobPayment(header *commonpb.PaymentHeader) ([]byte, error) {
header.AccountId = s.GetAccountID()
pm := core.ConvertPaymentHeader(header)
// func (s *PaymentSigner) SignBlobPayment(header *commonpb.PaymentHeader) ([]byte, error) {
func (s *PaymentSigner) SignBlobPayment(pm *core.PaymentMetadata) ([]byte, error) {
// header.AccountId = s.GetAccountID()
// pm := core.ConvertPaymentHeader(header)
hash, err := pm.Hash()
if err != nil {
return nil, fmt.Errorf("failed to hash payment header: %v", err)
Expand All @@ -53,7 +53,7 @@ func NewNoopPaymentSigner() *NoopPaymentSigner {
return &NoopPaymentSigner{}
}

func (s *NoopPaymentSigner) SignBlobPayment(header *commonpb.PaymentHeader) ([]byte, error) {
func (s *NoopPaymentSigner) SignBlobPayment(header *core.PaymentMetadata) ([]byte, error) {
return nil, fmt.Errorf("noop signer cannot sign blob payment header")
}

Expand All @@ -62,9 +62,8 @@ func (s *NoopPaymentSigner) GetAccountID() string {
}

// VerifyPaymentSignature verifies the signature against the payment metadata
func VerifyPaymentSignature(paymentHeader *commonpb.PaymentHeader, paymentSignature []byte) bool {
pm := core.ConvertPaymentHeader(paymentHeader)
hash, err := pm.Hash()
func VerifyPaymentSignature(paymentHeader *core.PaymentMetadata, paymentSignature []byte) bool {
hash, err := paymentHeader.Hash()
if err != nil {
return false
}
Expand All @@ -76,7 +75,7 @@ func VerifyPaymentSignature(paymentHeader *commonpb.PaymentHeader, paymentSignat
}

recoveredAddress := crypto.PubkeyToAddress(*recoveredPubKey)
accountId := common.HexToAddress(paymentHeader.AccountId)
accountId := common.HexToAddress(paymentHeader.AccountID)
if recoveredAddress != accountId {
log.Printf("Signature address %s does not match account id %s\n", recoveredAddress.Hex(), accountId.Hex())
return false
Expand Down
21 changes: 11 additions & 10 deletions core/auth/payment_signer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package auth_test

import (
"encoding/hex"
"math/big"
"testing"

commonpb "github.com/Layr-Labs/eigenda/api/grpc/common"
"github.com/Layr-Labs/eigenda/core"
"github.com/Layr-Labs/eigenda/core/auth"
"github.com/ethereum/go-ethereum/crypto"
"github.com/stretchr/testify/assert"
Expand All @@ -19,10 +20,10 @@ func TestPaymentSigner(t *testing.T) {
signer := auth.NewPaymentSigner(privateKeyHex)

t.Run("SignBlobPayment", func(t *testing.T) {
header := &commonpb.PaymentHeader{
header := &core.PaymentMetadata{
AccountID: "",
BinIndex: 1,
CumulativePayment: []byte{0x01, 0x02, 0x03},
AccountId: "",
CumulativePayment: big.NewInt(1),
}

signature, err := signer.SignBlobPayment(header)
Expand All @@ -35,10 +36,10 @@ func TestPaymentSigner(t *testing.T) {
})

t.Run("VerifyPaymentSignature_InvalidSignature", func(t *testing.T) {
header := &commonpb.PaymentHeader{
header := &core.PaymentMetadata{
BinIndex: 1,
CumulativePayment: []byte{0x01, 0x02, 0x03},
AccountId: "",
CumulativePayment: big.NewInt(1),
AccountID: "",
}

// Create an invalid signature
Expand All @@ -48,10 +49,10 @@ func TestPaymentSigner(t *testing.T) {
})

t.Run("VerifyPaymentSignature_ModifiedHeader", func(t *testing.T) {
header := &commonpb.PaymentHeader{
header := &core.PaymentMetadata{
BinIndex: 1,
CumulativePayment: []byte{0x01, 0x02, 0x03},
AccountId: "",
CumulativePayment: big.NewInt(1),
AccountID: "",
}

signature, err := signer.SignBlobPayment(header)
Expand Down
11 changes: 10 additions & 1 deletion core/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ func ConvertPaymentHeader(header *commonpb.PaymentHeader) *PaymentMetadata {
}
}

// Hash returns the Keccak256 hash of the PaymentMetadata
// ConvertToProtoPaymentHeader converts a PaymentMetadata to a protobuf payment header
func (pm *PaymentMetadata) ConvertToProtoPaymentHeader() *commonpb.PaymentHeader {
return &commonpb.PaymentHeader{
AccountId: pm.AccountID,
Expand All @@ -581,6 +581,15 @@ func (pm *PaymentMetadata) ConvertToProtoPaymentHeader() *commonpb.PaymentHeader
}
}

// ConvertToProtoPaymentHeader converts a PaymentMetadata to a protobuf payment header
func ConvertToPaymentMetadata(ph *commonpb.PaymentHeader) *PaymentMetadata {
return &PaymentMetadata{
AccountID: ph.AccountId,
BinIndex: ph.BinIndex,
CumulativePayment: new(big.Int).SetBytes(ph.CumulativePayment),
}
}

// OperatorInfo contains information about an operator which is stored on the blockchain state,
// corresponding to a particular quorum
type ActiveReservation struct {
Expand Down
Loading

0 comments on commit d5b7f37

Please sign in to comment.