Skip to content

Commit be772d1

Browse files
committed
feat: integrate address directory to eth reader
- Add NewReaderWithAddressDirectory() for address directory-based initialization - ContractNames constants matching AddressDirectoryConstants.sol - optional AddressDirectoryFlag, BlsOperatorStateRetrieverFlag, and EigenDAServiceManagerFlag - validation to require either address directory OR both legacy flags - backward compatibility for existing deployments without address directory
1 parent 6531878 commit be772d1

File tree

49 files changed

+1814
-119
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1814
-119
lines changed

api/clients/v2/examples/client_construction.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ import (
2828
// These constants are specific to the EigenDA holesky testnet. To execute the provided examples on a different
2929
// network, you will need to set these constants to the correct values, based on the chosen network.
3030
const (
31-
ethRPCURL = "https://ethereum-holesky-rpc.publicnode.com"
32-
disperserHostname = "disperser-testnet-holesky.eigenda.xyz"
33-
certVerifierRouterAddress = "0x7F40A8e1B62aa1c8Afed23f6E8bAe0D340A4BC4e"
34-
registryCoordinatorAddress = "0x53012C69A189cfA2D9d29eb6F19B32e0A2EA3490"
31+
ethRPCURL = "https://ethereum-holesky-rpc.publicnode.com"
32+
disperserHostname = "disperser-testnet-holesky.eigenda.xyz"
33+
certVerifierRouterAddress = "0x7F40A8e1B62aa1c8Afed23f6E8bAe0D340A4BC4e"
34+
registryCoordinatorAddress = "0x53012C69A189cfA2D9d29eb6F19B32e0A2EA3490"
35+
addressDirectoryAddress = "0x0000000000000000000000000000000000000000" // TODO: Replace with actual EigenDADirectory address when deployed
36+
// Legacy addresses (use addressDirectoryAddress instead when available)
3537
blsOperatorStateRetrieverAddress = "0x003497Dd77E5B73C40e8aCbB562C8bb0410320E7"
3638
eigenDAServiceManagerAddress = "0xD4A7E1Bd8015057293f0D0A557088c286942e84b"
3739
)
@@ -329,14 +331,24 @@ func createKzgConfig() kzg.KzgConfig {
329331
}
330332

331333
func createEthReader(logger logging.Logger, ethClient common.EthClient) (*eth.Reader, error) {
334+
// Prefer address directory when available
335+
if addressDirectoryAddress != "0x0000000000000000000000000000000000000000" {
336+
ethReader, err := eth.NewReaderWithAddressDirectory(logger, ethClient, addressDirectoryAddress)
337+
if err != nil {
338+
return nil, fmt.Errorf("new reader with address directory: %w", err)
339+
}
340+
return ethReader, nil
341+
}
342+
343+
// Fallback to legacy approach
332344
ethReader, err := eth.NewReader(
333345
logger,
334346
ethClient,
335347
blsOperatorStateRetrieverAddress,
336348
eigenDAServiceManagerAddress,
337349
)
338350
if err != nil {
339-
return nil, fmt.Errorf("new reader: %w", err)
351+
return nil, fmt.Errorf("new reader legacy: %w", err)
340352
}
341353

342354
return ethReader, nil

contracts/bindings/EigenDADirectory/binding.go

Lines changed: 1149 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/compile.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ contracts="PaymentVault \
4949
EigenDAThresholdRegistry \
5050
EigenDARelayRegistry \
5151
IEigenDARelayRegistry \
52-
EigenDADisperserRegistry"
52+
EigenDADisperserRegistry \
53+
EigenDADirectory"
5354

5455
for contract in $contracts; do
5556
create_binding_abi_only ./ $contract ./bindings

contracts/script/SetUpEigenDA.s.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ contract SetupEigenDA is EigenDADeployer, EigenLayerUtils {
189189
}
190190

191191
string memory output = "eigenDA deployment output";
192+
vm.serializeAddress(output, "eigenDADirectory", address(eigenDADirectory));
192193
vm.serializeAddress(output, "eigenDAServiceManager", address(eigenDAServiceManager));
193194
vm.serializeAddress(output, "operatorStateRetriever", address(operatorStateRetriever));
194195
vm.serializeAddress(output, "blsApkRegistry", address(apkRegistry));

core/eth/address_directory_client.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package eth
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/Layr-Labs/eigenda/common"
8+
gethcommon "github.com/ethereum/go-ethereum/common"
9+
)
10+
11+
// AddressDirectoryClient provides access to the EigenDADirectory contract
12+
type AddressDirectoryClient struct {
13+
directoryAddr gethcommon.Address
14+
ethClient common.EthClient
15+
}
16+
17+
// NewAddressDirectoryClient creates a new AddressDirectoryClient
18+
func NewAddressDirectoryClient(directoryAddr gethcommon.Address, ethClient common.EthClient) *AddressDirectoryClient {
19+
return &AddressDirectoryClient{
20+
directoryAddr: directoryAddr,
21+
ethClient: ethClient,
22+
}
23+
}
24+
25+
// GetAddress retrieves an address by name from the directory
26+
func (a *AddressDirectoryClient) GetAddress(ctx context.Context, name string) (gethcommon.Address, error) {
27+
// TODO: Replace this with actual contract call once bindings are available
28+
// For now, return zero address to avoid compilation errors
29+
return gethcommon.Address{}, fmt.Errorf("address directory client not fully implemented - need contract bindings")
30+
}
31+
32+
// ContractNames defines the standard contract names used in the address directory
33+
var ContractNames = struct {
34+
ServiceManager string
35+
OperatorStateRetriever string
36+
RegistryCoordinator string
37+
BLSApkRegistry string
38+
IndexRegistry string
39+
StakeRegistry string
40+
SocketRegistry string
41+
PaymentVault string
42+
EjectionManager string
43+
RelayRegistry string
44+
ThresholdRegistry string
45+
DisperserRegistry string
46+
}{
47+
ServiceManager: "SERVICE_MANAGER",
48+
OperatorStateRetriever: "OPERATOR_STATE_RETRIEVER",
49+
RegistryCoordinator: "REGISTRY_COORDINATOR",
50+
BLSApkRegistry: "BLS_APK_REGISTRY",
51+
IndexRegistry: "INDEX_REGISTRY",
52+
StakeRegistry: "STAKE_REGISTRY",
53+
SocketRegistry: "SOCKET_REGISTRY",
54+
PaymentVault: "PAYMENT_VAULT",
55+
EjectionManager: "EJECTION_MANAGER",
56+
RelayRegistry: "RELAY_REGISTRY",
57+
ThresholdRegistry: "THRESHOLD_REGISTRY",
58+
DisperserRegistry: "DISPERSER_REGISTRY",
59+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package examples
2+
3+
import (
4+
"context"
5+
6+
"github.com/Layr-Labs/eigenda/common"
7+
"github.com/Layr-Labs/eigenda/core/eth"
8+
"github.com/Layr-Labs/eigensdk-go/logging"
9+
)
10+
11+
// ExampleAddressDirectoryUsage demonstrates how to use the new address directory integration
12+
func ExampleAddressDirectoryUsage() {
13+
logger, _ := logging.NewZapLogger(logging.Development)
14+
var ethClient common.EthClient // Initialize your eth client
15+
16+
// OLD WAY: Using individual contract addresses (now legacy)
17+
// blsOperatorStateRetrieverAddr := "0x123..."
18+
// eigenDAServiceManagerAddr := "0x456..."
19+
// reader, err := eth.NewReader(logger, ethClient, blsOperatorStateRetrieverAddr, eigenDAServiceManagerAddr)
20+
// writer, err := eth.NewWriterLegacy(logger, ethClient, blsOperatorStateRetrieverAddr, eigenDAServiceManagerAddr)
21+
22+
// NEW WAY: Using address directory (preferred)
23+
addressDirectoryAddr := "0x789..." // The address of the deployed EigenDADirectory contract
24+
25+
// Create reader with address directory
26+
reader, err := eth.NewReaderWithAddressDirectory(logger, ethClient, addressDirectoryAddr)
27+
if err != nil {
28+
panic(err)
29+
}
30+
31+
// Create writer with address directory
32+
writer, err := eth.NewWriterWithAddressDirectory(logger, ethClient, addressDirectoryAddr)
33+
if err != nil {
34+
panic(err)
35+
}
36+
37+
// Use reader and writer as normal
38+
ctx := context.Background()
39+
blockNumber, err := reader.GetCurrentBlockNumber(ctx)
40+
if err != nil {
41+
panic(err)
42+
}
43+
44+
// The reader and writer now automatically resolve contract addresses from the directory
45+
_ = blockNumber
46+
_ = writer
47+
}
48+
49+
// AvailableContractNames shows the standard contract names available in the address directory
50+
func AvailableContractNames() {
51+
// These contract names can be used with the address directory:
52+
_ = eth.ContractNames.ServiceManager // "SERVICE_MANAGER"
53+
_ = eth.ContractNames.OperatorStateRetriever // "OPERATOR_STATE_RETRIEVER"
54+
_ = eth.ContractNames.RegistryCoordinator // "REGISTRY_COORDINATOR"
55+
_ = eth.ContractNames.BLSApkRegistry // "BLS_APK_REGISTRY"
56+
_ = eth.ContractNames.IndexRegistry // "INDEX_REGISTRY"
57+
_ = eth.ContractNames.StakeRegistry // "STAKE_REGISTRY"
58+
_ = eth.ContractNames.SocketRegistry // "SOCKET_REGISTRY"
59+
_ = eth.ContractNames.PaymentVault // "PAYMENT_VAULT"
60+
_ = eth.ContractNames.EjectionManager // "EJECTION_MANAGER"
61+
_ = eth.ContractNames.RelayRegistry // "RELAY_REGISTRY"
62+
_ = eth.ContractNames.ThresholdRegistry // "THRESHOLD_REGISTRY"
63+
_ = eth.ContractNames.DisperserRegistry // "DISPERSER_REGISTRY"
64+
}

core/eth/reader.go

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@ import (
88
"math/big"
99
"strings"
1010

11+
"github.com/ethereum/go-ethereum/accounts/abi/bind"
12+
"github.com/ethereum/go-ethereum/crypto"
13+
1114
"github.com/Layr-Labs/eigenda/common"
1215
avsdir "github.com/Layr-Labs/eigenda/contracts/bindings/AVSDirectory"
1316
blsapkreg "github.com/Layr-Labs/eigenda/contracts/bindings/BLSApkRegistry"
1417
delegationmgr "github.com/Layr-Labs/eigenda/contracts/bindings/DelegationManager"
18+
eigendadirectory "github.com/Layr-Labs/eigenda/contracts/bindings/EigenDADirectory"
1519
disperserreg "github.com/Layr-Labs/eigenda/contracts/bindings/EigenDADisperserRegistry"
1620
relayreg "github.com/Layr-Labs/eigenda/contracts/bindings/EigenDARelayRegistry"
1721
eigendasrvmg "github.com/Layr-Labs/eigenda/contracts/bindings/EigenDAServiceManager"
@@ -25,10 +29,8 @@ import (
2529
stakereg "github.com/Layr-Labs/eigenda/contracts/bindings/StakeRegistry"
2630
"github.com/Layr-Labs/eigenda/core"
2731
"github.com/Layr-Labs/eigensdk-go/logging"
28-
"github.com/ethereum/go-ethereum/accounts/abi/bind"
2932
gethcommon "github.com/ethereum/go-ethereum/common"
3033
"github.com/ethereum/go-ethereum/core/types"
31-
"github.com/ethereum/go-ethereum/crypto"
3234
"github.com/pingcap/errors"
3335

3436
blssigner "github.com/Layr-Labs/eigensdk-go/signer/bls"
@@ -52,6 +54,7 @@ type ContractBindings struct {
5254
RelayRegistry *relayreg.ContractEigenDARelayRegistry
5355
ThresholdRegistry *thresholdreg.ContractEigenDAThresholdRegistry
5456
DisperserRegistry *disperserreg.ContractEigenDADisperserRegistry
57+
AddressDirectory *eigendadirectory.ContractEigenDADirectory
5558
}
5659

5760
type Reader struct {
@@ -80,6 +83,42 @@ func NewReader(
8083
return e, err
8184
}
8285

86+
// NewReaderWithAddressDirectory creates a new Reader using an address directory contract address
87+
func NewReaderWithAddressDirectory(
88+
logger logging.Logger,
89+
client common.EthClient,
90+
addressDirectoryHexAddr string) (*Reader, error) {
91+
92+
e := &Reader{
93+
ethClient: client,
94+
logger: logger.With("component", "Reader"),
95+
}
96+
97+
addressDirectoryAddr := gethcommon.HexToAddress(addressDirectoryHexAddr)
98+
addressDirectory, err := eigendadirectory.NewContractEigenDADirectory(addressDirectoryAddr, client)
99+
if err != nil {
100+
return nil, fmt.Errorf("failed to fetch EigenDADirectory contract: %w", err)
101+
}
102+
103+
// Convert contract names to keccak256 hashes as expected by the contract
104+
operatorStateRetrieverKey := crypto.Keccak256Hash([]byte(ContractNames.OperatorStateRetriever))
105+
blsOperatorStateRetrieverAddr, err := addressDirectory.GetAddress(&bind.CallOpts{}, operatorStateRetrieverKey)
106+
if err != nil {
107+
return nil, fmt.Errorf("failed to get operator state retriever address: %w", err)
108+
}
109+
110+
serviceManagerKey := crypto.Keccak256Hash([]byte(ContractNames.ServiceManager))
111+
eigenDAServiceManagerAddr, err := addressDirectory.GetAddress(&bind.CallOpts{}, serviceManagerKey)
112+
if err != nil {
113+
return nil, fmt.Errorf("failed to get service manager address: %w", err)
114+
}
115+
err = e.updateContractBindings(blsOperatorStateRetrieverAddr, eigenDAServiceManagerAddr)
116+
if err != nil {
117+
return nil, fmt.Errorf("failed to update contract bindings: %w", err)
118+
}
119+
return e, nil
120+
}
121+
83122
func (t *Reader) updateContractBindings(blsOperatorStateRetrieverAddr, eigenDAServiceManagerAddr gethcommon.Address) error {
84123

85124
contractEigenDAServiceManager, err := eigendasrvmg.NewContractEigenDAServiceManager(eigenDAServiceManagerAddr, t.ethClient)

core/eth/writer.go

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,16 @@ type Writer struct {
3434

3535
var _ core.Writer = (*Writer)(nil)
3636

37+
// NewWriter creates a new Writer using individual contract addresses (deprecated, use NewWriter instead)
3738
func NewWriter(
3839
logger logging.Logger,
3940
client common.EthClient,
4041
blsOperatorStateRetrieverHexAddr string,
4142
eigenDAServiceManagerHexAddr string) (*Writer, error) {
4243

43-
r := &Reader{
44-
ethClient: client,
45-
logger: logger.With("component", "Reader"),
44+
r, err := NewReader(logger, client, blsOperatorStateRetrieverHexAddr, eigenDAServiceManagerHexAddr)
45+
if err != nil {
46+
return nil, fmt.Errorf("failed to create reader with legacy addresses: %w", err)
4647
}
4748

4849
e := &Writer{
@@ -51,11 +52,27 @@ func NewWriter(
5152
Reader: r,
5253
}
5354

54-
blsOperatorStateRetrieverAddr := gethcommon.HexToAddress(blsOperatorStateRetrieverHexAddr)
55-
eigenDAServiceManagerAddr := gethcommon.HexToAddress(eigenDAServiceManagerHexAddr)
56-
err := e.updateContractBindings(blsOperatorStateRetrieverAddr, eigenDAServiceManagerAddr)
55+
return e, nil
56+
}
57+
58+
// NewWriterWithAddressDirectory creates a new Writer using an address directory contract address
59+
func NewWriterWithAddressDirectory(
60+
logger logging.Logger,
61+
client common.EthClient,
62+
addressDirectoryHexAddr string) (*Writer, error) {
63+
64+
r, err := NewReaderWithAddressDirectory(logger, client, addressDirectoryHexAddr)
65+
if err != nil {
66+
return nil, fmt.Errorf("failed to create reader with address directory: %w", err)
67+
}
68+
69+
e := &Writer{
70+
ethClient: client,
71+
logger: logger.With("component", "Writer"),
72+
Reader: r,
73+
}
5774

58-
return e, err
75+
return e, nil
5976
}
6077

6178
// RegisterOperator registers a new operator with the given public key and socket with the provided quorum ids.

disperser/cmd/apiserver/flags/flags.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,22 @@ var (
4646
EnvVar: common.PrefixEnvVar(envVarPrefix, "GRPC_STREAM_TIMEOUT"),
4747
Value: time.Second * 10,
4848
}
49+
AddressDirectoryFlag = cli.StringFlag{
50+
Name: common.PrefixFlag(FlagPrefix, "address-directory"),
51+
Usage: "Address of the EigenDA Directory contract (preferred over individual contract addresses)",
52+
Required: false,
53+
EnvVar: common.PrefixEnvVar(envVarPrefix, "ADDRESS_DIRECTORY"),
54+
}
4955
BlsOperatorStateRetrieverFlag = cli.StringFlag{
5056
Name: common.PrefixFlag(FlagPrefix, "bls-operator-state-retriever"),
5157
Usage: "Address of the BLS Operator State Retriever",
52-
Required: true,
53-
EnvVar: common.PrefixEnvVar(envVarPrefix, "BLS_OPERATOR_STATE_RETRIVER"),
58+
Required: false,
59+
EnvVar: common.PrefixEnvVar(envVarPrefix, "BLS_OPERATOR_STATE_RETRIEVER"),
5460
}
5561
EigenDAServiceManagerFlag = cli.StringFlag{
5662
Name: common.PrefixFlag(FlagPrefix, "eigenda-service-manager"),
5763
Usage: "Address of the EigenDA Service Manager",
58-
Required: true,
64+
Required: false,
5965
EnvVar: common.PrefixEnvVar(envVarPrefix, "EIGENDA_SERVICE_MANAGER"),
6066
}
6167
/* Optional Flags*/
@@ -270,8 +276,6 @@ var requiredFlags = []cli.Flag{
270276
DynamoDBTableNameFlag,
271277
GrpcPortFlag,
272278
BucketTableName,
273-
BlsOperatorStateRetrieverFlag,
274-
EigenDAServiceManagerFlag,
275279
}
276280

277281
var optionalFlags = []cli.Flag{
@@ -295,6 +299,9 @@ var optionalFlags = []cli.Flag{
295299
NtpServerFlag,
296300
NtpSyncIntervalFlag,
297301
ReservedOnly,
302+
AddressDirectoryFlag,
303+
BlsOperatorStateRetrieverFlag,
304+
EigenDAServiceManagerFlag,
298305
}
299306

300307
// Flags contains the list of configuration options available to the binary.

disperser/cmd/apiserver/lib/apiserver.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,12 @@ func RunDisperserServer(ctx *cli.Context) error {
5252
return err
5353
}
5454

55-
transactor, err := eth.NewReader(logger, client, config.BLSOperatorStateRetrieverAddr, config.EigenDAServiceManagerAddr)
55+
var transactor *eth.Reader
56+
if config.AddressDirectoryAddr != "" {
57+
transactor, err = eth.NewReaderWithAddressDirectory(logger, client, config.AddressDirectoryAddr)
58+
} else {
59+
transactor, err = eth.NewReader(logger, client, config.BLSOperatorStateRetrieverAddr, config.EigenDAServiceManagerAddr)
60+
}
5661
if err != nil {
5762
return err
5863
}

0 commit comments

Comments
 (0)