Skip to content

Commit

Permalink
Add commitment mode parameter and commitment type system
Browse files Browse the repository at this point in the history
  • Loading branch information
teddyknox committed Jun 14, 2024
1 parent 322002e commit 3277de9
Show file tree
Hide file tree
Showing 25 changed files with 526 additions and 346 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,11 @@ 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
env:
SIGNER_PRIVATE_KEY: ${{ secrets.SIGNER_PRIVATE_KEY }}
Expand Down
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ go.work
.env

## kzg cache
e2e/resources/kzg/SRSTables/
../test/resources/SRSTables/

## Vscode
/.vscode
35 changes: 10 additions & 25 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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)
Expand All @@ -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
}
2 changes: 1 addition & 1 deletion cmd/server/entrypoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down
67 changes: 67 additions & 0 deletions commitments/da_service_op_commitment.go
Original file line number Diff line number Diff line change
@@ -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
}
58 changes: 58 additions & 0 deletions commitments/eigenda_commitment.go
Original file line number Diff line number Diff line change
@@ -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
}
6 changes: 6 additions & 0 deletions commitments/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package commitments

type Commitment interface {
Marshal() ([]byte, error)
Unmarshal([]byte) error
}
90 changes: 90 additions & 0 deletions commitments/op_commitment.go
Original file line number Diff line number Diff line change
@@ -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
}
8 changes: 4 additions & 4 deletions e2e/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)

Expand Down
Loading

0 comments on commit 3277de9

Please sign in to comment.