diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 5fa4d668..178c22f8 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -44,10 +44,6 @@ jobs: run: | make test - - name: Run Optimism Test - run: | - make optimism-test - gosec: runs-on: ubuntu-latest env: @@ -60,7 +56,7 @@ jobs: with: args: ./... - holesky-test: + e2e-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -70,14 +66,13 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: 1.21 + go-version: 1.21 - name: Install project dependencies run: | go mod download - - - name: Run holesky tests + - name: Run E2E Tests env: SIGNER_PRIVATE_KEY: ${{ secrets.SIGNER_PRIVATE_KEY }} run: | - SIGNER_PRIVATE_KEY=$SIGNER_PRIVATE_KEY make holesky-test \ No newline at end of file + SIGNER_PRIVATE_KEY=$SIGNER_PRIVATE_KEY make e2e-test \ No newline at end of file diff --git a/.gitignore b/.gitignore index 24d3e50c..bfa8bea1 100644 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,4 @@ go.work .env ## kzg cache -e2e/resources/kzg/SRSTables/ - -## Vscode -/.vscode \ No newline at end of file +test/resources/SRSTables/ \ No newline at end of file diff --git a/Makefile b/Makefile index 6f3aeada..014417ba 100644 --- a/Makefile +++ b/Makefile @@ -27,13 +27,10 @@ clean: rm bin/eigenda-proxy test: - go test -v ./... -parallel 4 + go test -v ./... -optimism-test: - OPTIMISM=true go test -timeout 1m -v ./e2e -deploy-config ../.devnet/devnetL1.json - -holesky-test: - TESTNET=true go test -timeout 50m -v ./e2e -parallel 4 +e2e-test: submodules + go test -timeout 50m -v ./test/e2e_test.go -testnet-integration .PHONY: lint lint: @@ -48,7 +45,7 @@ lint: @golangci-lint run gosec: - @echo "Running security scan with gosec..." + @echo "$(GREEN) Running security scan with gosec...$(COLOR_END)" gosec ./... submodules: @@ -59,10 +56,7 @@ srs: cd operator-setup && ./srs_setup.sh; \ fi -op-devnet-allocs: - @echo "Generating devnet allocs..." - @./scripts/op-devnet-allocs.sh - .PHONY: \ + op-batcher \ clean \ test diff --git a/README.md b/README.md index 4a4b73aa..5d5579a5 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ An ephemeral memory store backend can be used for faster feedback testing when p ## Running Locally 1. Compile binary: `make eigenda-proxy` -2. Run binary; e.g: `./bin/eigenda-proxy --addr 127.0.0.1 --port 5050 --eigenda-rpc 127.0.0.1:443 --eigenda-status-query-timeout 45m --eigenda-g1-path e2e/resources/kzg/g1.point --eigenda-g2-tau-path e2e/resources/kzg/g2.point.powerOf2 --eigenda-use-tls true` +2. Run binary; e.g: `./bin/eigenda-proxy --addr 127.0.0.1 --port 5050 --eigenda-rpc 127.0.0.1:443 --eigenda-status-query-timeout 45m --eigenda-g1-path test/resources/g1.point --eigenda-g2-tau-path test/resources/g2.point.powerOf2 --eigenda-use-tls true` **Env File** An env file can be provided to the binary for runtime process ingestion; e.g: @@ -67,17 +67,14 @@ The `raw commitment` for EigenDA is encoding certificate and kzg fields. ## Testing -### Unit -Unit tests can be ran via invoking `make test`. +Some unit tests have been introduced to assert the correctness of: -### Holesky -A holesky integration test can be ran using `make holesky-test` to assert proper dispersal/retrieval against a public network. Please **note** that EigenDA Holesky network which is subject to rate-limiting and slow confirmation times *(i.e, >10 minutes per blob confirmation)*. Please advise EigenDA's [inabox](https://github.com/Layr-Labs/eigenda/tree/master/inabox#readme) if you'd like to spin-up a local DA network for faster iteration testing. +* DA Certificate encoding/decoding logic +* commitment verification logic +Unit tests can be ran via `make test`. -### Optimism -An E2E test exists which spins up a local OP sequencer instance using the [op-e2e](https://github.com/ethereum-optimism/optimism/tree/develop/op-e2e) framework for asserting correct interaction behaviors with batch submission and state derivation. These tests can be ran via `make optimism-test`. - -**NOTE:** +Otherwise E2E tests (`test/e2e_test.go`) exists which asserts that a commitment can be generated when inserting some arbitrary data to the server and can be read using the commitment for a key lookup via the client. These can be ran via `make e2e-test`. Please **note** that this test uses the EigenDA Holesky network which is subject to rate-limiting and slow confirmation times *(i.e, >10 minutes per blob confirmation)*. Please advise EigenDA's [inabox](https://github.com/Layr-Labs/eigenda/tree/master/inabox#readme) if you'd like to spin-up a local DA network for faster iteration testing. ## Downloading Mainnet SRS diff --git a/client/client.go b/client/client.go index ed354550..f27f3423 100644 --- a/client/client.go +++ b/client/client.go @@ -7,9 +7,7 @@ import ( "io" "net/http" - "github.com/Layr-Labs/eigenda-proxy/common" - "github.com/Layr-Labs/eigenda-proxy/eigenda" - "github.com/ethereum/go-ethereum/rlp" + "github.com/Layr-Labs/eigenda-proxy/server" ) const ( @@ -25,8 +23,8 @@ type Config struct { // ProxyClient is an interface for communicating with the EigenDA proxy server type ProxyClient interface { Health() error - GetData(ctx context.Context, cert *common.Certificate, domain common.DomainType) ([]byte, error) - SetData(ctx context.Context, b []byte) (*common.Certificate, error) + GetData(ctx context.Context, cert []byte, domain server.DomainType, commitmentType server.CommitmentType) ([]byte, error) + SetData(ctx context.Context, b []byte, commitmentType server.CommitmentType) ([]byte, error) } // client is the implementation of ProxyClient @@ -64,16 +62,8 @@ func (c *client) Health() error { } // GetData fetches blob data associated with a DA certificate -func (c *client) GetData(ctx context.Context, cert *common.Certificate, domain common.DomainType) ([]byte, error) { - b, err := rlp.EncodeToBytes(cert) - if err != nil { - return nil, err - } - - // encode prefix bytes - b = eigenda.GenericPrefix(eigenda.Commitment(b).Encode()) - - url := fmt.Sprintf("%s/get/0x%x?domain=%s", c.cfg.URL, b, domain.String()) +func (c *client) GetData(ctx context.Context, comm []byte, domain server.DomainType, commitmentType server.CommitmentType) ([]byte, error) { + url := fmt.Sprintf("%s/get/0x%x?domain=%s&commitment_mode=%s", c.cfg.URL, comm, domain.String(), commitmentType) req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { @@ -96,8 +86,8 @@ func (c *client) GetData(ctx context.Context, cert *common.Certificate, domain c } // SetData writes raw byte data to DA and returns the respective certificate -func (c *client) SetData(ctx context.Context, b []byte) (*common.Certificate, error) { - url := fmt.Sprintf("%s/put/", c.cfg.URL) +func (c *client) SetData(ctx context.Context, b []byte, commitmentType server.CommitmentType) ([]byte, error) { + url := fmt.Sprintf("%s/put/?commitment_mode=%s", c.cfg.URL, commitmentType) req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(b)) if err != nil { return nil, fmt.Errorf("failed to create HTTP request: %w", err) @@ -117,14 +107,9 @@ func (c *client) SetData(ctx context.Context, b []byte) (*common.Certificate, er return nil, err } - if len(b) < decodingOffset { - return nil, fmt.Errorf("read certificate is of invalid length: %d", len(b)) - } - - var cert *common.Certificate - if err = rlp.DecodeBytes(b[decodingOffset:], &cert); err != nil { - return nil, err + if len(b) == 0 { + return nil, fmt.Errorf("read certificate is empty") } - return cert, err + return b, err } diff --git a/cmd/server/entrypoint.go b/cmd/server/entrypoint.go index ec45143d..b0f2f537 100644 --- a/cmd/server/entrypoint.go +++ b/cmd/server/entrypoint.go @@ -5,9 +5,9 @@ import ( "fmt" "github.com/Layr-Labs/eigenda-proxy/metrics" + "github.com/Layr-Labs/eigenda-proxy/server" "github.com/urfave/cli/v2" - "github.com/Layr-Labs/eigenda-proxy/server" oplog "github.com/ethereum-optimism/optimism/op-service/log" "github.com/ethereum-optimism/optimism/op-service/opio" ) diff --git a/commitments/da_service_op_commitment.go b/commitments/da_service_op_commitment.go new file mode 100644 index 00000000..d0b89a9e --- /dev/null +++ b/commitments/da_service_op_commitment.go @@ -0,0 +1,67 @@ +package commitments + +import ( + "fmt" + "log" +) + +type DAServiceOPCommitmentType byte + +const ( + EigenDAByte DAServiceOPCommitmentType = 0 +) + +// DAServiceOPCommitment represents a value of one of two possible types (Keccak256Commitment or DAServiceCommitment). +type DAServiceOPCommitment struct { + eigendaCommitment *EigenDACommitment +} + +var _ Commitment = (*DAServiceOPCommitment)(nil) + +func OptimismEigenDACommitment(value EigenDACommitment) DAServiceOPCommitment { + return DAServiceOPCommitment{eigendaCommitment: &value} +} + +func (e DAServiceOPCommitment) IsEigenDA() bool { + return e.eigendaCommitment != nil +} + +func (e DAServiceOPCommitment) MustEigenDAValue() EigenDACommitment { + if e.eigendaCommitment != nil { + return *e.eigendaCommitment + } + log.Panic("CommitmentEither does not contain a Keccak256Commitment value") + return EigenDACommitment{} // This will never be reached, but is required for compilation. +} + +func (e DAServiceOPCommitment) Marshal() ([]byte, error) { + if e.IsEigenDA() { + eigenDABytes, err := e.MustEigenDAValue().Marshal() + if err != nil { + return nil, err + } + return append([]byte{byte(EigenDAByte)}, eigenDABytes...), nil + } else { + return nil, fmt.Errorf("DAServiceOPCommitment is neither a keccak256 commitment or a DA service commitment") + } +} + +func (e *DAServiceOPCommitment) Unmarshal(bz []byte) error { + if len(bz) < 1 { + return fmt.Errorf("OP commitment does not contain generic commitment type prefix byte") + } + head := DAServiceOPCommitmentType(bz[0]) + tail := bz[1:] + switch head { + case EigenDAByte: + eigendaCommitment := EigenDACommitment{} + err := eigendaCommitment.Unmarshal(tail) + if err != nil { + return err + } + e.eigendaCommitment = &eigendaCommitment + default: + return fmt.Errorf("unrecognized generic commitment type byte: %x", bz[0]) + } + return nil +} diff --git a/commitments/eigenda_commitment.go b/commitments/eigenda_commitment.go new file mode 100644 index 00000000..6d92d65f --- /dev/null +++ b/commitments/eigenda_commitment.go @@ -0,0 +1,58 @@ +package commitments + +import ( + "fmt" + "log" +) + +// Define the parent and child types +type CertEncodingVersion byte + +const ( + CertEncodingV0 CertEncodingVersion = 0 +) + +type EigenDACommitment struct { + certV0 []byte +} + +var _ Commitment = (*EigenDACommitment)(nil) + +func EigenDACertV0(value []byte) EigenDACommitment { + return EigenDACommitment{certV0: value} +} + +func (e EigenDACommitment) IsCertV0() bool { + return e.certV0 != nil +} + +func (e EigenDACommitment) MustCertV0Value() []byte { + if e.certV0 != nil { + return e.certV0 + } + log.Panic("CommitmentEither does not contain a Keccak256Commitment value") + return nil // This will never be reached, but is required for compilation. +} + +func (e EigenDACommitment) Marshal() ([]byte, error) { + if e.IsCertV0() { + return append([]byte{byte(CertEncodingV0)}, e.certV0...), nil + } else { + return nil, fmt.Errorf("EigenDADAServiceOPCommitment is of unknown type") + } +} + +func (e *EigenDACommitment) Unmarshal(bz []byte) error { + if len(bz) < 1 { + return fmt.Errorf("OP commitment does not contain eigenda commitment encoding version prefix byte") + } + head := CertEncodingVersion(bz[0]) + tail := bz[1:] + switch head { + case CertEncodingV0: + e.certV0 = tail + default: + return fmt.Errorf("unrecognized EigenDA commitment encoding type byte: %x", bz[0]) + } + return nil +} diff --git a/commitments/interface.go b/commitments/interface.go new file mode 100644 index 00000000..da47a3b8 --- /dev/null +++ b/commitments/interface.go @@ -0,0 +1,6 @@ +package commitments + +type Commitment interface { + Marshal() ([]byte, error) + Unmarshal([]byte) error +} diff --git a/commitments/op_commitment.go b/commitments/op_commitment.go new file mode 100644 index 00000000..d53f4e0f --- /dev/null +++ b/commitments/op_commitment.go @@ -0,0 +1,90 @@ +package commitments + +import ( + "fmt" + "log" +) + +type OPCommitmentType byte + +const ( + // Keccak256Byte represents a commitment using Keccak256 hashing. + Keccak256Byte OPCommitmentType = 0 + // DAServiceByte represents a commitment using a DA service. + DAServiceByte OPCommitmentType = 1 +) + +type OPCommitment struct { + keccak256Commitment []byte + genericCommitment *DAServiceOPCommitment +} + +var _ Commitment = (*OPCommitment)(nil) + +func Keccak256Commitment(value []byte) OPCommitment { + return OPCommitment{keccak256Commitment: value} +} + +func DAServiceCommitment(value DAServiceOPCommitment) OPCommitment { + return OPCommitment{genericCommitment: &value} +} + +func (e OPCommitment) IsKeccak256Commitment() bool { + return e.keccak256Commitment != nil +} + +func (e OPCommitment) IsGenericCommitment() bool { + return e.genericCommitment != nil +} + +func (e OPCommitment) MustKeccak256Value() []byte { + if e.keccak256Commitment != nil { + return e.keccak256Commitment + } + log.Panic("OPCommitment does not contain a Keccak256Commitment value") + return nil // This will never be reached, but is required for compilation. +} + +func (e OPCommitment) MustDAServiceValue() DAServiceOPCommitment { + if e.genericCommitment != nil { + return *e.genericCommitment + } + log.Panic("OPCommitment does not contain a DAServiceCommitment value") + return DAServiceOPCommitment{} // This will never be reached, but is required for compilation. +} + +func (e OPCommitment) Marshal() ([]byte, error) { + if e.IsGenericCommitment() { + bytes, err := e.MustDAServiceValue().Marshal() + if err != nil { + return nil, err + } + return append([]byte{byte(DAServiceByte)}, bytes...), nil + } else if e.IsKeccak256Commitment() { + return append([]byte{byte(Keccak256Byte)}, e.MustKeccak256Value()...), nil + } else { + return nil, fmt.Errorf("OPCommitment is neither a Keccak256 commitment nor a DA service commitment") + } +} + +func (e *OPCommitment) Unmarshal(bz []byte) error { + if len(bz) < 1 { + return fmt.Errorf("OPCommitment does not contain a commitment type prefix byte") + } + head := OPCommitmentType(bz[0]) + tail := bz[1:] + switch head { + case Keccak256Byte: + e.keccak256Commitment = tail + case DAServiceByte: + daServiceCommitment := DAServiceOPCommitment{} + err := daServiceCommitment.Unmarshal(tail) + if err != nil { + return err + } + e.genericCommitment = &daServiceCommitment + default: + return fmt.Errorf("unrecognized commitment type byte: %x", bz[0]) + } + return nil +} diff --git a/e2e/server_test.go b/e2e/server_test.go index 2bf43445..967d29d6 100644 --- a/e2e/server_test.go +++ b/e2e/server_test.go @@ -5,8 +5,8 @@ import ( "time" "github.com/Layr-Labs/eigenda-proxy/client" + "github.com/Layr-Labs/eigenda-proxy/server" - "github.com/Layr-Labs/eigenda-proxy/common" "github.com/Layr-Labs/eigenda-proxy/e2e" "github.com/Layr-Labs/eigenda/api/clients/codecs" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" @@ -87,17 +87,17 @@ func TestProxyClient(t *testing.T) { var testPreimage = []byte("inter-subjective and not objective!") t.Log("Setting input data on proxy server...") - blobInfo, err := daClient.SetData(ts.Ctx, testPreimage) + blobInfo, err := daClient.SetData(ts.Ctx, testPreimage, server.DefaultCommitmentMode) require.NoError(t, err) // 2 - fetch data from EigenDA for generated commitment key t.Log("Getting input data from proxy server...") - preimage, err := daClient.GetData(ts.Ctx, blobInfo, common.BinaryDomain) + preimage, err := daClient.GetData(ts.Ctx, blobInfo, server.BinaryDomain, server.DefaultCommitmentMode) require.NoError(t, err) require.Equal(t, testPreimage, preimage) // 3 - fetch iFFT representation of preimage - iFFTPreimage, err := daClient.GetData(ts.Ctx, blobInfo, common.PolyDomain) + iFFTPreimage, err := daClient.GetData(ts.Ctx, blobInfo, server.PolyDomain, server.DefaultCommitmentMode) require.NoError(t, err) require.NotEqual(t, preimage, iFFTPreimage) diff --git a/e2e/setup.go b/e2e/setup.go index 7e234e67..96d3cc26 100644 --- a/e2e/setup.go +++ b/e2e/setup.go @@ -7,10 +7,8 @@ import ( "testing" "time" - "github.com/Layr-Labs/eigenda-proxy/eigenda" "github.com/Layr-Labs/eigenda-proxy/metrics" "github.com/Layr-Labs/eigenda-proxy/server" - "github.com/Layr-Labs/eigenda-proxy/store" "github.com/Layr-Labs/eigenda/api/clients" "github.com/ethereum/go-ethereum/log" @@ -49,7 +47,7 @@ func CreateTestSuite(t *testing.T, useMemory bool) (TestSuite, func()) { Color: true, }).New("role", svcName) - eigendaCfg := eigenda.Config{ + eigendaCfg := server.Config{ ClientConfig: clients.EigenDAClientConfig{ RPC: holeskyDA, StatusQueryTimeout: time.Minute * 45, @@ -59,21 +57,16 @@ func CreateTestSuite(t *testing.T, useMemory bool) (TestSuite, func()) { }, CacheDir: "../operator-setup/resources/SRSTables", G1Path: "../operator-setup/resources/g1_abbr.point", - G2Path: "../test/resources/kzg/g2.point", // do we need this? MaxBlobLength: "90kib", G2PowerOfTauPath: "../operator-setup/resources/kzg/g2_abbr.point.powerOf2", PutBlobEncodingVersion: 0x00, - } - - memstoreCfg := store.MemStoreConfig{ - Enabled: useMemory, - BlobExpiration: 14 * 24 * time.Hour, + MemstoreEnabled: useMemory, + MemstoreBlobExpiration: 14 * 24 * time.Hour, } store, err := server.LoadStore( server.CLIConfig{ EigenDAConfig: eigendaCfg, - MemStoreCfg: memstoreCfg, MetricsCfg: opmetrics.CLIConfig{}, }, ctx, diff --git a/eigenda/commitment.go b/eigenda/commitment.go deleted file mode 100644 index 2775719e..00000000 --- a/eigenda/commitment.go +++ /dev/null @@ -1,73 +0,0 @@ -package eigenda - -import ( - "errors" - - op_plasma "github.com/ethereum-optimism/optimism/op-plasma" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -// ErrCommitmentLength is returned when the commitment length is invalid. -var ErrCommitmentLength = errors.New("invalid commitment length") - -// ErrInvalidCommitment is returned when the commitment cannot be parsed into a known commitment type. -var ErrInvalidCommitment = errors.New("invalid commitment") - -// ErrCommitmentMismatch is returned when the commitment does not match the given input. -var ErrCommitmentMismatch = errors.New("commitment mismatch") - -// ExtDAType is the DA provider type. -type ExtDAType byte - -const ( - EigenDA ExtDAType = 0x00 -) - -// EigenDAVersion is the version being used for EigenDA. -type EigenDAVersion byte - -const ( - EigenV0 EigenDAVersion = 0x00 -) - -type Commitment []byte - -func (c Commitment) Encode() []byte { - return append([]byte{byte(EigenDA), byte(EigenV0)}, c...) -} - -func GenericPrefix(b []byte) []byte { - return append([]byte{byte(op_plasma.GenericCommitmentType)}, b...) -} - -func StringToCommit(key string) (Commitment, error) { - comm, err := hexutil.Decode(key) - if err != nil { - return nil, err - } - return DecodeCommitment(comm) -} - -// DecodeCommitment verifies and decodes an EigenDACommit from raw encoded bytes. -func DecodeCommitment(commitment []byte) (Commitment, error) { - if len(commitment) <= 3 { - return nil, ErrCommitmentLength - } - if commitment[0] != byte(op_plasma.GenericCommitmentType) { - return nil, ErrInvalidCommitment - } - - if commitment[1] != byte(EigenDA) { - return nil, ErrInvalidCommitment - } - - // additional versions will need to be hardcoded here - if commitment[2] != byte(EigenV0) { - return nil, ErrInvalidCommitment - } - - c := commitment[3:] - - // TODO - Add a length check - return c, nil -} diff --git a/operator-setup b/operator-setup index 2a5a91f8..10b5eeac 160000 --- a/operator-setup +++ b/operator-setup @@ -1 +1 @@ -Subproject commit 2a5a91f81f7ff92d28f8febbffbb889d3ca3a855 +Subproject commit 10b5eeac3ec8fd0de16bf59fa82b80812dc0a740 diff --git a/scripts/op-devnet-allocs.sh b/scripts/op-devnet-allocs.sh deleted file mode 100755 index 3f6af539..00000000 --- a/scripts/op-devnet-allocs.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -VERSION=$(cat go.mod | grep ethereum-optimism/optimism | awk '{print $2}' | sed 's/\/v//g') -VERSION=$(echo ${VERSION} | sed 's/v//g') - -REPO_NAME=optimism-$(echo ${VERSION} | sed 's/v//g') - -echo "Downloading ${REPO_NAME} ..." -git clone --branch v${VERSION} https://github.com/ethereum-optimism/optimism.git ${REPO_NAME} -cd ${REPO_NAME} - -echo "Initializing monorepo..." -make install-geth && -git submodule update --init --recursive && -make devnet-allocs && -cp -R .devnet ../. && -mv packages/contracts-bedrock/deploy-config/devnetL1.json ../.devnet/devnetL1.json - -STATUS=$? - -## Force cleanup of monorepo -echo "${STATUS} Cleaning up ${REPO_NAME} repo ..." -cd ../ && -rm -rf ${REPO_NAME} - -if [ $? -eq 0 ] ; then - echo "Successfully cleaned up ${REPO_NAME} repo" - exit ${STATUS} -else - echo "Failed to clean up ${REPO_NAME} repo" - exit ${STATUS} \ No newline at end of file diff --git a/server/commitment_type.go b/server/commitment_type.go new file mode 100644 index 00000000..212e2db9 --- /dev/null +++ b/server/commitment_type.go @@ -0,0 +1,97 @@ +package server + +import ( + "encoding/hex" + "fmt" + "net/http" + + "github.com/Layr-Labs/eigenda-proxy/commitments" +) + +type CommitmentType string + +const ( + OptimismCommitmentMode CommitmentType = "optimism" + DefaultCommitmentMode CommitmentType = "default" +) + +func StringToCommitmentMode(s string) (CommitmentType, error) { + switch s { + case string(OptimismCommitmentMode): + return OptimismCommitmentMode, nil + case string(DefaultCommitmentMode): + return DefaultCommitmentMode, nil + default: + return "", fmt.Errorf("unknown commitment mode: %s", s) + } +} + +func StringToCommitment(key string, c CommitmentType) ([]byte, error) { + if len(key) <= 2 { + return nil, fmt.Errorf("commitment is empty") + } + + if key[:2] != "0x" { + return nil, fmt.Errorf("commitment parameter does not have 0x prefix") + } + + b, err := hex.DecodeString(key[2:]) + if err != nil { + return nil, err + } + + switch c { + case OptimismCommitmentMode: + var comm commitments.OPCommitment + err = comm.Unmarshal(b) + if err != nil { + return nil, err + } + if !comm.IsGenericCommitment() { + return nil, fmt.Errorf("commitment is not a OP DA service commitment") + } + daComm := comm.MustDAServiceValue() + if !daComm.IsEigenDA() { + return nil, fmt.Errorf("commitment is not an EigenDA OP DA service commitment") + } + eigendaComm := daComm.MustEigenDAValue() + if !eigendaComm.IsCertV0() { + return nil, fmt.Errorf("commitment is not a supported EigenDA cert encoding") + } + return eigendaComm.MustCertV0Value(), nil + case DefaultCommitmentMode: + var eigendaComm commitments.EigenDACommitment + err = eigendaComm.Unmarshal(b) + if err != nil { + return nil, err + } + if !eigendaComm.IsCertV0() { + return nil, fmt.Errorf("commitment is not a supported EigenDA cert encoding") + } + return eigendaComm.MustCertV0Value(), nil + default: + return nil, fmt.Errorf("unknown commitment type") + } +} + +func EncodeCommitment(s []byte, c CommitmentType) ([]byte, error) { + switch c { + case OptimismCommitmentMode: + comm := commitments.OptimismEigenDACommitment(commitments.EigenDACertV0(s)) + return comm.Marshal() + case DefaultCommitmentMode: + comm := commitments.EigenDACertV0(s) + return comm.Marshal() + default: + return nil, fmt.Errorf("unknown commitment type") + } +} + +func ReadCommitmentMode(r *http.Request) (CommitmentType, error) { + query := r.URL.Query() + key := query.Get(CommitmentModeKey) + if key == "" { // default + return OptimismCommitmentMode, nil + } + return StringToCommitmentMode(key) +} diff --git a/eigenda/config.go b/server/config.go similarity index 84% rename from eigenda/config.go rename to server/config.go index 4a3e8de5..43756fab 100644 --- a/eigenda/config.go +++ b/server/config.go @@ -1,4 +1,4 @@ -package eigenda +package server import ( "fmt" @@ -6,7 +6,7 @@ import ( "runtime" "time" - "github.com/Layr-Labs/eigenda-proxy/common" + "github.com/Layr-Labs/eigenda-proxy/utils" "github.com/Layr-Labs/eigenda/api/clients" "github.com/Layr-Labs/eigenda/api/clients/codecs" "github.com/Layr-Labs/eigenda/encoding/kzg" @@ -25,10 +25,12 @@ const ( PutBlobEncodingVersionFlagName = "eigenda-put-blob-encoding-version" DisablePointVerificationModeFlagName = "eigenda-disable-point-verification-mode" // Kzg flags - G1PathFlagName = "eigenda-g1-path" - G2TauFlagName = "eigenda-g2-tau-path" - CachePathFlagName = "eigenda-cache-path" - MaxBlobLengthFlagName = "eigenda-max-blob-length" + G1PathFlagName = "eigenda-g1-path" + G2TauFlagName = "eigenda-g2-tau-path" + CachePathFlagName = "eigenda-cache-path" + MaxBlobLengthFlagName = "eigenda-max-blob-length" + MemstoreFlagName = "memstore.enabled" + MemstoreExpirationFlagName = "memstore.expiration" ) const BytesPerSymbol = 31 @@ -54,11 +56,15 @@ type Config struct { maxBlobLengthBytes uint64 G2PowerOfTauPath string + + // Memstore Config params + MemstoreEnabled bool + MemstoreBlobExpiration time.Duration } func (c *Config) GetMaxBlobLength() (uint64, error) { if c.maxBlobLengthBytes == 0 { - numBytes, err := common.ParseBytesAmount(c.MaxBlobLength) + numBytes, err := utils.ParseBytesAmount(c.MaxBlobLength) if err != nil { return 0, err } @@ -105,10 +111,12 @@ func ReadConfig(ctx *cli.Context) Config { PutBlobEncodingVersion: codecs.BlobEncodingVersion(ctx.Uint(PutBlobEncodingVersionFlagName)), DisablePointVerificationMode: ctx.Bool(DisablePointVerificationModeFlagName), }, - G1Path: ctx.String(G1PathFlagName), - G2PowerOfTauPath: ctx.String(G2TauFlagName), - CacheDir: ctx.String(CachePathFlagName), - MaxBlobLength: ctx.String(MaxBlobLengthFlagName), + G1Path: ctx.String(G1PathFlagName), + G2PowerOfTauPath: ctx.String(G2TauFlagName), + CacheDir: ctx.String(CachePathFlagName), + MaxBlobLength: ctx.String(MaxBlobLengthFlagName), + MemstoreEnabled: ctx.Bool(MemstoreFlagName), + MemstoreBlobExpiration: ctx.Duration(MemstoreExpirationFlagName), } return cfg } @@ -199,5 +207,16 @@ func CLIFlags(envPrefix string) []cli.Flag { Usage: "Directory path to SRS tables", EnvVars: prefixEnvVars("TARGET_CACHE_PATH"), }, + &cli.BoolFlag{ + Name: MemstoreFlagName, + Usage: "Whether to use mem-store for DA logic.", + EnvVars: []string{"MEMSTORE_ENABLED"}, + }, + &cli.DurationFlag{ + Name: MemstoreExpirationFlagName, + Usage: "Duration that a mem-store blob/commitment pair are allowed to live.", + Value: 25 * time.Minute, + EnvVars: []string{"MEMSTORE_EXPIRATION"}, + }, } } diff --git a/server/domain_type.go b/server/domain_type.go new file mode 100644 index 00000000..d161e0c8 --- /dev/null +++ b/server/domain_type.go @@ -0,0 +1,56 @@ +package server + +import ( + "fmt" + "net/http" +) + +var ( + ErrInvalidDomainType = fmt.Errorf("invalid domain type") +) + +// DomainType is a enumeration type for the different data domains for which a +// blob can exist between +type DomainType uint8 + +const ( + BinaryDomain DomainType = iota + PolyDomain + UnknownDomain +) + +func (d DomainType) String() string { + switch d { + case BinaryDomain: + return "binary" + case PolyDomain: + return "polynomial" + default: + return "unknown" + } +} + +func StrToDomainType(s string) DomainType { + switch s { + case "binary": + return BinaryDomain + case "polynomial": + return PolyDomain + default: + return UnknownDomain + } +} + +func ReadDomainFilter(r *http.Request) (DomainType, error) { + query := r.URL.Query() + key := query.Get(DomainFilterKey) + if key == "" { // default + return BinaryDomain, nil + } + dt := StrToDomainType(key) + if dt == UnknownDomain { + return UnknownDomain, ErrInvalidDomainType + } + + return dt, nil +} diff --git a/store/eigenda.go b/server/eigenda_store.go similarity index 91% rename from store/eigenda.go rename to server/eigenda_store.go index 8b4071e7..f8a4e350 100644 --- a/store/eigenda.go +++ b/server/eigenda_store.go @@ -1,15 +1,17 @@ -package store +package server import ( "context" "fmt" - "github.com/Layr-Labs/eigenda-proxy/common" "github.com/Layr-Labs/eigenda-proxy/verify" "github.com/Layr-Labs/eigenda/api/clients" + "github.com/Layr-Labs/eigenda/api/grpc/disperser" "github.com/ethereum/go-ethereum/rlp" ) +type Certificate = disperser.BlobInfo + // EigenDAStore does storage interactions and verifications for blobs with DA. type EigenDAStore struct { client *clients.EigenDAClient @@ -29,8 +31,8 @@ func NewEigenDAStore(ctx context.Context, client *clients.EigenDAClient, v *veri // Get fetches a blob from DA using certificate fields and verifies blob // against commitment to ensure data is valid and non-tampered. -func (e EigenDAStore) Get(ctx context.Context, key []byte, domain common.DomainType) ([]byte, error) { - var cert common.Certificate +func (e EigenDAStore) Get(ctx context.Context, key []byte, domain DomainType) ([]byte, error) { + var cert Certificate err := rlp.DecodeBytes(key, &cert) if err != nil { return nil, fmt.Errorf("failed to decode DA cert to RLP format: %w", err) @@ -52,9 +54,9 @@ func (e EigenDAStore) Get(ctx context.Context, key []byte, domain common.DomainT } switch domain { - case common.BinaryDomain: + case BinaryDomain: return decodedBlob, nil - case common.PolyDomain: + case PolyDomain: return encodedBlob, nil default: return nil, fmt.Errorf("unexpected domain type: %d", domain) @@ -89,6 +91,6 @@ func (e EigenDAStore) Put(ctx context.Context, value []byte) (comm []byte, err e } // Entries is a no-op for EigenDA Store -func (e EigenDAStore) Stats() *common.Stats { +func (e EigenDAStore) Stats() *Stats { return nil } diff --git a/server/flags.go b/server/flags.go index 7d2579a2..9f6547b6 100644 --- a/server/flags.go +++ b/server/flags.go @@ -5,8 +5,6 @@ import ( "github.com/urfave/cli/v2" - "github.com/Layr-Labs/eigenda-proxy/eigenda" - "github.com/Layr-Labs/eigenda-proxy/store" opservice "github.com/ethereum-optimism/optimism/op-service" oplog "github.com/ethereum-optimism/optimism/op-service/log" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" @@ -47,9 +45,8 @@ var optionalFlags = []cli.Flag{} func init() { optionalFlags = append(optionalFlags, oplog.CLIFlags(EnvVarPrefix)...) - optionalFlags = append(optionalFlags, eigenda.CLIFlags(EnvVarPrefix)...) + optionalFlags = append(optionalFlags, CLIFlags(EnvVarPrefix)...) optionalFlags = append(optionalFlags, opmetrics.CLIFlags(EnvVarPrefix)...) - optionalFlags = append(optionalFlags, store.CLIFlags(EnvVarPrefix)...) Flags = append(requiredFlags, optionalFlags...) } @@ -57,16 +54,14 @@ func init() { var Flags []cli.Flag type CLIConfig struct { - MemStoreCfg store.MemStoreConfig - EigenDAConfig eigenda.Config + EigenDAConfig Config MetricsCfg opmetrics.CLIConfig } func ReadCLIConfig(ctx *cli.Context) CLIConfig { return CLIConfig{ - EigenDAConfig: eigenda.ReadConfig(ctx), + EigenDAConfig: ReadConfig(ctx), MetricsCfg: opmetrics.ReadCLIConfig(ctx), - MemStoreCfg: store.ReadConfig(ctx), } } diff --git a/server/load_store.go b/server/load_store.go index 1ac7bc8c..9689bfdd 100644 --- a/server/load_store.go +++ b/server/load_store.go @@ -3,13 +3,12 @@ package server import ( "context" - "github.com/Layr-Labs/eigenda-proxy/store" "github.com/Layr-Labs/eigenda-proxy/verify" "github.com/Layr-Labs/eigenda/api/clients" "github.com/ethereum/go-ethereum/log" ) -func LoadStore(cfg CLIConfig, ctx context.Context, log log.Logger) (store.Store, error) { +func LoadStore(cfg CLIConfig, ctx context.Context, log log.Logger) (Store, error) { log.Info("Using eigenda backend") daCfg := cfg.EigenDAConfig @@ -23,16 +22,16 @@ func LoadStore(cfg CLIConfig, ctx context.Context, log log.Logger) (store.Store, return nil, err } - if cfg.MemStoreCfg.Enabled { + if cfg.EigenDAConfig.MemstoreEnabled { log.Info("Using memstore backend") - return store.NewMemStore(ctx, &cfg.MemStoreCfg, verifier, log, maxBlobLength) + return NewMemStore(ctx, verifier, log, maxBlobLength, cfg.EigenDAConfig.MemstoreBlobExpiration) } client, err := clients.NewEigenDAClient(log, daCfg.ClientConfig) if err != nil { return nil, err } - return store.NewEigenDAStore( + return NewEigenDAStore( ctx, client, verifier, diff --git a/store/memory.go b/server/memory_store.go similarity index 70% rename from store/memory.go rename to server/memory_store.go index 9d80edae..d089ada7 100644 --- a/store/memory.go +++ b/server/memory_store.go @@ -1,4 +1,4 @@ -package store +package server import ( "context" @@ -10,61 +10,50 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" - "github.com/Layr-Labs/eigenda-proxy/common" - eigendacommon "github.com/Layr-Labs/eigenda-proxy/common" "github.com/Layr-Labs/eigenda-proxy/verify" "github.com/Layr-Labs/eigenda/api/clients/codecs" - grpccommon "github.com/Layr-Labs/eigenda/api/grpc/common" + "github.com/Layr-Labs/eigenda/api/grpc/common" "github.com/Layr-Labs/eigenda/api/grpc/disperser" "github.com/ethereum/go-ethereum/crypto" - "github.com/urfave/cli/v2" ) const ( - MemStoreFlagName = "memstore.enabled" - ExpirationFlagName = "memstore.expiration" - DefaultPruneInterval = 500 * time.Millisecond ) -type MemStoreConfig struct { - Enabled bool - BlobExpiration time.Duration -} - // MemStore is a simple in-memory store for blobs which uses an expiration // time to evict blobs to best emulate the ephemeral nature of blobs dispersed to // EigenDA operators. type MemStore struct { sync.RWMutex - cfg *MemStoreConfig l log.Logger keyStarts map[string]time.Time store map[string][]byte verifier *verify.Verifier codec codecs.BlobCodec - reads int maxBlobSizeBytes uint64 + blobExpiration time.Duration + reads int } var _ Store = (*MemStore)(nil) // NewMemStore ... constructor -func NewMemStore(ctx context.Context, cfg *MemStoreConfig, verifier *verify.Verifier, l log.Logger, maxBlobSizeBytes uint64) (*MemStore, error) { +func NewMemStore(ctx context.Context, verifier *verify.Verifier, l log.Logger, maxBlobSizeBytes uint64, blobExpiration time.Duration) (*MemStore, error) { store := &MemStore{ - cfg: cfg, l: l, keyStarts: make(map[string]time.Time), store: make(map[string][]byte), verifier: verifier, codec: codecs.NewIFFTCodec(codecs.NewDefaultBlobCodec()), maxBlobSizeBytes: maxBlobSizeBytes, + blobExpiration: blobExpiration, } - if cfg.BlobExpiration != 0 { - l.Info("memstore expiration enabled", "time", cfg.BlobExpiration) + if store.blobExpiration != 0 { + l.Info("memstore expiration enabled", "time", store.blobExpiration) go store.EventLoop(ctx) } @@ -91,7 +80,7 @@ func (e *MemStore) pruneExpired() { defer e.Unlock() for commit, dur := range e.keyStarts { - if time.Since(dur) >= e.cfg.BlobExpiration { + if time.Since(dur) >= e.blobExpiration { delete(e.keyStarts, commit) delete(e.store, commit) @@ -102,12 +91,11 @@ func (e *MemStore) pruneExpired() { } // Get fetches a value from the store. -func (e *MemStore) Get(ctx context.Context, commit []byte, domain eigendacommon.DomainType) ([]byte, error) { - e.reads += 1 - e.Lock() - defer e.Unlock() +func (e *MemStore) Get(ctx context.Context, commit []byte, domain DomainType) ([]byte, error) { + e.RLock() + defer e.RUnlock() - var cert common.Certificate + var cert Certificate err := rlp.DecodeBytes(commit, &cert) if err != nil { return nil, fmt.Errorf("failed to decode DA cert to RLP format: %w", err) @@ -126,9 +114,9 @@ func (e *MemStore) Get(ctx context.Context, commit []byte, domain eigendacommon. } switch domain { - case eigendacommon.BinaryDomain: + case BinaryDomain: return e.codec.DecodeBlob(encodedBlob) - case eigendacommon.PolyDomain: + case PolyDomain: return encodedBlob, nil default: return nil, fmt.Errorf("unexpected domain type: %d", domain) @@ -163,9 +151,9 @@ func (e *MemStore) Put(ctx context.Context, value []byte) ([]byte, error) { mockBatchHeaderHash := crypto.Keccak256Hash(entropy) // only filling out commitment fields for now - cert := &common.Certificate{ + cert := &Certificate{ BlobHeader: &disperser.BlobHeader{ - Commitment: &grpccommon.G1Commitment{ + Commitment: &common.G1Commitment{ X: commitment.X.Marshal(), Y: commitment.Y.Marshal(), }, @@ -209,37 +197,11 @@ func (e *MemStore) Put(ctx context.Context, value []byte) ([]byte, error) { return certBytes, nil } -func (e *MemStore) Stats() *common.Stats { +func (e *MemStore) Stats() *Stats { e.RLock() defer e.RUnlock() - return &common.Stats{ + return &Stats{ Entries: len(e.store), Reads: e.reads, } } - -func ReadConfig(ctx *cli.Context) MemStoreConfig { - cfg := MemStoreConfig{ - /* Required Flags */ - Enabled: ctx.Bool(MemStoreFlagName), - BlobExpiration: ctx.Duration(ExpirationFlagName), - } - return cfg -} - -func CLIFlags(envPrefix string) []cli.Flag { - - return []cli.Flag{ - &cli.BoolFlag{ - Name: MemStoreFlagName, - Usage: "Whether to use mem-store for DA logic.", - EnvVars: []string{"MEMSTORE_ENABLED"}, - }, - &cli.DurationFlag{ - Name: ExpirationFlagName, - Usage: "Duration that a blob/commitment pair are allowed to live.", - Value: 25 * time.Minute, - EnvVars: []string{"MEMSTORE_EXPIRATION"}, - }, - } -} diff --git a/store/memory_test.go b/server/memory_store_test.go similarity index 68% rename from store/memory_test.go rename to server/memory_store_test.go index f3ce1783..e4727752 100644 --- a/store/memory_test.go +++ b/server/memory_store_test.go @@ -1,4 +1,4 @@ -package store +package server import ( "context" @@ -6,7 +6,6 @@ import ( "testing" "time" - "github.com/Layr-Labs/eigenda-proxy/common" "github.com/Layr-Labs/eigenda-proxy/verify" "github.com/Layr-Labs/eigenda/encoding/kzg" "github.com/ethereum/go-ethereum/log" @@ -22,9 +21,9 @@ func TestGetSet(t *testing.T) { defer cancel() kzgConfig := &kzg.KzgConfig{ - G1Path: "../e2e/resources/kzg/g1.point", - G2PowerOf2Path: "../e2e/resources/kzg/g2.point.powerOf2", - CacheDir: "../e2e/resources/kzg/SRSTables", + G1Path: "../operator-setup/resources/g1_abbr.point", + G2PowerOf2Path: "../operator-setup/resources/g2_abbr.point.powerOf2", + CacheDir: "../operator-setup/resources/SRSTables", SRSOrder: 3000, SRSNumberToLoad: 3000, NumWorker: uint64(runtime.GOMAXPROCS(0)), @@ -34,13 +33,10 @@ func TestGetSet(t *testing.T) { ms, err := NewMemStore( ctx, - &MemStoreConfig{ - Enabled: true, - BlobExpiration: time.Hour * 1000, - }, verifier, log.New(), 1024*1024*2, + time.Hour*1000, ) assert.NoError(t, err) @@ -49,21 +45,19 @@ func TestGetSet(t *testing.T) { key, err := ms.Put(ctx, expected) assert.NoError(t, err) - actual, err := ms.Get(ctx, key, common.BinaryDomain) + actual, err := ms.Get(ctx, key, BinaryDomain) assert.NoError(t, err) assert.Equal(t, actual, expected) } func TestExpiration(t *testing.T) { - t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) defer cancel() kzgConfig := &kzg.KzgConfig{ - G1Path: "../e2e/resources/kzg/g1.point", - G2PowerOf2Path: "../e2e/resources/kzg/g2.point.powerOf2", - CacheDir: "../e2e/resources/kzg/SRSTables", + G1Path: "../operator-setup/resources/g1_abbr.point", + G2PowerOf2Path: "../operator-setup/resources/g2_abbr.point.powerOf2", + CacheDir: "../operator-setup/resources/SRSTables", SRSOrder: 3000, SRSNumberToLoad: 3000, NumWorker: uint64(runtime.GOMAXPROCS(0)), @@ -73,13 +67,10 @@ func TestExpiration(t *testing.T) { ms, err := NewMemStore( ctx, - &MemStoreConfig{ - Enabled: true, - BlobExpiration: time.Millisecond * 10, - }, verifier, log.New(), 1024*1024*2, + time.Millisecond*10, ) assert.NoError(t, err) @@ -91,7 +82,7 @@ func TestExpiration(t *testing.T) { // sleep 1 second and verify that older blob entries are removed time.Sleep(time.Second * 1) - _, err = ms.Get(ctx, key, common.BinaryDomain) + _, err = ms.Get(ctx, key, BinaryDomain) assert.Error(t, err) } diff --git a/server/server.go b/server/server.go index d8d60206..51e94b26 100644 --- a/server/server.go +++ b/server/server.go @@ -11,10 +11,7 @@ import ( "strconv" "time" - "github.com/Layr-Labs/eigenda-proxy/common" - "github.com/Layr-Labs/eigenda-proxy/eigenda" "github.com/Layr-Labs/eigenda-proxy/metrics" - "github.com/Layr-Labs/eigenda-proxy/store" "github.com/ethereum-optimism/optimism/op-service/rpc" "github.com/ethereum/go-ethereum/log" ) @@ -24,27 +21,41 @@ var ( ) const ( - invalidDomain = "invalid domain type" -) + invalidDomain = "invalid domain type" + invalidCommitmentType = "invalid commitment type" -const ( GetRoute = "/get/" PutRoute = "/put/" - DomainFilterKey = "domain" + DomainFilterKey = "domain" + CommitmentModeKey = "commitment_mode" ) +type Store interface { + // Get retrieves the given key if it's present in the key-value data store. + Get(ctx context.Context, key []byte, domain DomainType) ([]byte, error) + // Put inserts the given value into the key-value data store. + Put(ctx context.Context, value []byte) (key []byte, err error) + // Stats returns the current usage metrics of the key-value data store. + Stats() *Stats +} + +type Stats struct { + Entries int + Reads int +} + type Server struct { log log.Logger endpoint string - store store.Store + store Store m metrics.Metricer tls *rpc.ServerTLSConfig httpServer *http.Server listener net.Listener } -func NewServer(host string, port int, store store.Store, log log.Logger, m metrics.Metricer) *Server { +func NewServer(host string, port int, store Store, log log.Logger, m metrics.Metricer) *Server { endpoint := net.JoinHostPort(host, strconv.Itoa(port)) return &Server{ m: m, @@ -147,9 +158,14 @@ func (svr *Server) HandleGet(w http.ResponseWriter, r *http.Request) error { svr.WriteBadRequest(w, invalidDomain) return err } + commitmentType, err := ReadCommitmentMode(r) + if err != nil { + svr.WriteBadRequest(w, invalidCommitmentType) + return err + } key := path.Base(r.URL.Path) - comm, err := eigenda.StringToCommit(key) + comm, err := StringToCommitment(key, commitmentType) if err != nil { svr.log.Info("failed to decode commitment", "err", err, "key", key) w.WriteHeader(http.StatusBadRequest) @@ -172,6 +188,12 @@ func (svr *Server) HandleGet(w http.ResponseWriter, r *http.Request) error { } func (svr *Server) HandlePut(w http.ResponseWriter, r *http.Request) error { + commitmentType, err := ReadCommitmentMode(r) + if err != nil { + svr.WriteBadRequest(w, invalidCommitmentType) + return err + } + input, err := io.ReadAll(r.Body) if err != nil { w.WriteHeader(http.StatusBadRequest) @@ -184,8 +206,15 @@ func (svr *Server) HandlePut(w http.ResponseWriter, r *http.Request) error { return err } + comm, err = EncodeCommitment(comm, commitmentType) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return err + } + + fmt.Printf("write cert: %x\n", comm) // write out encoded commitment - svr.WriteResponse(w, eigenda.Commitment.Encode(comm)) + svr.WriteResponse(w, comm) return nil } @@ -210,27 +239,13 @@ func (svr *Server) WriteBadRequest(w http.ResponseWriter, msg string) { w.WriteHeader(http.StatusBadRequest) } -func ReadDomainFilter(r *http.Request) (common.DomainType, error) { - query := r.URL.Query() - key := query.Get(DomainFilterKey) - if key == "" { // default - return common.BinaryDomain, nil - } - dt := common.StrToDomainType(key) - if dt == common.UnknownDomain { - return common.UnknownDomain, common.ErrInvalidDomainType - } - - return dt, nil -} - -func (svr *Server) Store() store.Store { - return svr.store -} - func (svr *Server) Port() int { // read from listener _, portStr, _ := net.SplitHostPort(svr.listener.Addr().String()) port, _ := strconv.Atoi(portStr) return port } + +func (svr *Server) Store() Store { + return svr.store +} diff --git a/store/types.go b/store/types.go deleted file mode 100644 index 5a283d18..00000000 --- a/store/types.go +++ /dev/null @@ -1,16 +0,0 @@ -package store - -import ( - "context" - - "github.com/Layr-Labs/eigenda-proxy/common" -) - -type Store interface { - // Get retrieves the given key if it's present in the key-value data store. - Get(ctx context.Context, key []byte, domain common.DomainType) ([]byte, error) - // Put inserts the given value into the key-value data store. - Put(ctx context.Context, value []byte) (key []byte, err error) - // Stats returns the current usage metrics of the key-value data store. - Stats() *common.Stats -} diff --git a/common/common.go b/utils/parse_bytes.go similarity index 55% rename from common/common.go rename to utils/parse_bytes.go index df8cb067..2ecc3fb4 100644 --- a/common/common.go +++ b/utils/parse_bytes.go @@ -1,69 +1,11 @@ -package common +package utils import ( "fmt" "strconv" "strings" - - "github.com/Layr-Labs/eigenda/api/grpc/disperser" -) - -var ( - ErrInvalidDomainType = fmt.Errorf("invalid domain type") -) - -type Certificate = disperser.BlobInfo - -// DomainType is a enumeration type for the different data domains for which a -// blob can exist between -type DomainType uint8 - -const ( - BinaryDomain DomainType = iota - PolyDomain - UnknownDomain ) -func (dt DomainType) String() string { - switch dt { - case BinaryDomain: - return "binary" - - case PolyDomain: - return "polynomial" - - default: - return "unknown" - } -} - -func StrToDomainType(s string) DomainType { - switch s { - case "binary": - return BinaryDomain - case "polynomial": - return PolyDomain - default: - return UnknownDomain - } -} - -// Helper utility functions // - -func EqualSlices[P comparable](s1, s2 []P) bool { - if len(s1) != len(s2) { - return false - } - - for i := 0; i < len(s1); i++ { - if s1[i] != s2[i] { - return false - } - } - - return true -} - func ParseBytesAmount(s string) (uint64, error) { s = strings.TrimSpace(s) @@ -110,8 +52,3 @@ func ParseBytesAmount(s string) (uint64, error) { return 0, fmt.Errorf("unsupported unit: %s", unit) } } - -type Stats struct { - Entries int - Reads int -} diff --git a/common/common_test.go b/utils/parse_bytes_test.go similarity index 91% rename from common/common_test.go rename to utils/parse_bytes_test.go index 11632c89..cf684667 100644 --- a/common/common_test.go +++ b/utils/parse_bytes_test.go @@ -1,15 +1,13 @@ -package common_test +package utils_test import ( "fmt" "testing" - "github.com/Layr-Labs/eigenda-proxy/common" + "github.com/Layr-Labs/eigenda-proxy/utils" ) func TestParseByteAmount(t *testing.T) { - t.Parallel() - testCases := []struct { input string expected uint64 @@ -44,7 +42,7 @@ func TestParseByteAmount(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("Input: %s", tc.input), func(t *testing.T) { - got, err := common.ParseBytesAmount(tc.input) + got, err := utils.ParseBytesAmount(tc.input) if (err != nil) != tc.wantErr { t.Errorf("wantErr: %v, got error: %v", tc.wantErr, err) } diff --git a/verify/verifier.go b/verify/verifier.go index 298db2b4..a6a3c793 100644 --- a/verify/verifier.go +++ b/verify/verifier.go @@ -3,11 +3,11 @@ package verify import ( "fmt" - "github.com/Layr-Labs/eigenda/api/grpc/common" "github.com/Layr-Labs/eigenda/encoding" "github.com/consensys/gnark-crypto/ecc/bn254" "github.com/consensys/gnark-crypto/ecc/bn254/fp" + "github.com/Layr-Labs/eigenda/api/grpc/common" "github.com/Layr-Labs/eigenda/encoding/kzg" "github.com/Layr-Labs/eigenda/encoding/kzg/prover" "github.com/Layr-Labs/eigenda/encoding/rs" @@ -60,7 +60,6 @@ func (v *Verifier) Verify(expectedCommit *common.G1Commitment, blob []byte) erro return err } - // convert to field elements expectedX := &fp.Element{} expectedX.Unmarshal(expectedCommit.X) expectedY := &fp.Element{} diff --git a/verify/verify_test.go b/verify/verify_test.go index 19ec5c8b..e7575d2e 100644 --- a/verify/verify_test.go +++ b/verify/verify_test.go @@ -12,14 +12,13 @@ import ( ) func TestVerification(t *testing.T) { - t.Parallel() var data = []byte("inter-subjective and not objective!") - x, err := hex.DecodeString("2fc55f968a2d29d22aebf55b382528d1d9401577c166483e162355b19d8bc446") + x, err := hex.DecodeString("1021d699eac68ce312196d480266e8b82fd5fe5c4311e53313837b64db6df178") assert.NoError(t, err) - y, err := hex.DecodeString("149e2241c21c391e069b9f317710c7f57f31ee88245a5e61f0d294b11acf9aff") + y, err := hex.DecodeString("02efa5a7813233ae13f32bae9b8f48252fa45c1b06a5d70bed471a9bea8d98ae") assert.NoError(t, err) c := &common.G1Commitment{ @@ -28,9 +27,9 @@ func TestVerification(t *testing.T) { } kzgConfig := &kzg.KzgConfig{ - G1Path: "../e2e/resources/kzg/g1.point", - G2PowerOf2Path: "../e2e/resources/kzg/g2.point.powerOf2", - CacheDir: "../e2e/resources/kzg/SRSTables", + G1Path: "../operator-setup/resources/g1_abbr.point", + G2PowerOf2Path: "../operator-setup/resources/g2_abbr.point.powerOf2", + CacheDir: "../operator-setup/resources/SRSTables", SRSOrder: 3000, SRSNumberToLoad: 3000, NumWorker: uint64(runtime.GOMAXPROCS(0)),