Skip to content

Commit

Permalink
Update operator registration transactor
Browse files Browse the repository at this point in the history
  • Loading branch information
mooselumph committed Jan 19, 2024
1 parent 096d256 commit 581f7b5
Show file tree
Hide file tree
Showing 10 changed files with 4,776 additions and 34 deletions.
13 changes: 12 additions & 1 deletion churner/tests/churner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package test

import (
"context"
"crypto/rand"
"flag"
"fmt"
"log"
"math/big"
"os"
"testing"

Expand Down Expand Up @@ -106,7 +108,16 @@ func TestChurner(t *testing.T) {
for i, q := range quorumIds {
quorumIds_[i] = uint8(q)
}
err = operatorTransactor.RegisterOperator(ctx, keyPair, "socket", quorumIds_)

operatorSalt := [32]byte{}
_, err = rand.Read(operatorSalt[:])
assert.NoError(t, err)

expiry := big.NewInt(1000)
privKey, err := crypto.GenerateKey()
assert.NoError(t, err)

err = operatorTransactor.RegisterOperator(ctx, keyPair, "socket", quorumIds_, privKey, operatorSalt, expiry)
assert.NoError(t, err)

server := newTestServer(t)
Expand Down
4,574 changes: 4,574 additions & 0 deletions contracts/bindings/DelegationManager/binding.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion contracts/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function create_binding {
forge clean
forge build

contracts="BitmapUtils OperatorStateRetriever RegistryCoordinator BLSApkRegistry IndexRegistry StakeRegistry BN254 EigenDAServiceManager IEigenDAServiceManager MockRollup"
contracts="DelegationManager BitmapUtils OperatorStateRetriever RegistryCoordinator BLSApkRegistry IndexRegistry StakeRegistry BN254 EigenDAServiceManager IEigenDAServiceManager MockRollup"
for contract in $contracts; do
create_binding ./ $contract ./bindings
done
Expand Down
21 changes: 21 additions & 0 deletions core/attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

bn254utils "github.com/Layr-Labs/eigenda/core/bn254"
"github.com/consensys/gnark-crypto/ecc/bn254"
"github.com/consensys/gnark-crypto/ecc/bn254/fp"
"github.com/consensys/gnark-crypto/ecc/bn254/fr"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
Expand All @@ -16,6 +17,21 @@ type G1Point struct {
*bn254.G1Affine
}

func newFpElement(x *big.Int) fp.Element {
var p fp.Element
p.SetBigInt(x)
return p
}

func NewG1Point(x, y *big.Int) *G1Point {
return &G1Point{
&bn254.G1Affine{
X: newFpElement(x),
Y: newFpElement(y),
},
}
}

// Add another G1 point to this one
func (p *G1Point) Add(p2 *G1Point) {
p.G1Affine.Add(p.G1Affine, p2.G1Affine)
Expand Down Expand Up @@ -129,6 +145,11 @@ func (k *KeyPair) SignMessage(message [32]byte) *Signature {
return &Signature{&G1Point{sig}}
}

func (k *KeyPair) SignHashedToCurveMessage(g1HashedMsg *G1Point) *Signature {
sig := new(bn254.G1Affine).ScalarMultiplication(g1HashedMsg.G1Affine, k.PrivKey.BigInt(new(big.Int)))
return &Signature{&G1Point{sig}}
}

func (k *KeyPair) GetPubKeyG2() *G2Point {
return &G2Point{bn254utils.MulByGeneratorG2(k.PrivKey)}
}
Expand Down
102 changes: 84 additions & 18 deletions core/eth/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package eth

import (
"context"
"crypto/ecdsa"
"encoding/json"
"math/big"

Expand All @@ -10,6 +11,7 @@ import (
"github.com/Layr-Labs/eigenda/core"

blsapkreg "github.com/Layr-Labs/eigenda/contracts/bindings/BLSApkRegistry"
delegationmgr "github.com/Layr-Labs/eigenda/contracts/bindings/DelegationManager"
eigendasrvmg "github.com/Layr-Labs/eigenda/contracts/bindings/EigenDAServiceManager"
indexreg "github.com/Layr-Labs/eigenda/contracts/bindings/IIndexRegistry"
opstateretriever "github.com/Layr-Labs/eigenda/contracts/bindings/OperatorStateRetriever"
Expand All @@ -36,6 +38,8 @@ var _ core.Transactor = (*Transactor)(nil)

type ContractBindings struct {
RegCoordinatorAddr gethcommon.Address
ServiceManagerAddr gethcommon.Address
DelegationManager *delegationmgr.ContractDelegationManager
OpStateRetriever *opstateretriever.ContractOperatorStateRetriever
BLSApkRegistry *blsapkreg.ContractBLSApkRegistry
IndexRegistry *indexreg.ContractIIndexRegistry
Expand Down Expand Up @@ -94,17 +98,29 @@ func (t *Transactor) GetRegisteredQuorumIdsForOperator(ctx context.Context, oper
return quorumIds, nil
}

func (t *Transactor) getRegistrationParam(ctx context.Context, keypair *core.KeyPair) (*regcoordinator.IBLSApkRegistryPubkeyRegistrationParams, error) {
func (t *Transactor) getRegistrationParams(
ctx context.Context,
keypair *core.KeyPair,
operatorEcdsaPrivateKey *ecdsa.PrivateKey,
operatorToAvsRegistrationSigSalt [32]byte,
operatorToAvsRegistrationSigExpiry *big.Int,
) (*regcoordinator.IBLSApkRegistryPubkeyRegistrationParams, *regcoordinator.ISignatureUtilsSignatureWithSaltAndExpiry, error) {

operatorAddress := t.EthClient.GetAccountAddress()

signedMessageHash := keypair.MakePubkeyRegistrationData(operatorAddress)
msgToSignG1_, err := t.Bindings.RegistryCoordinator.PubkeyRegistrationMessageHash(&bind.CallOpts{}, operatorAddress)
if err != nil {
return nil, nil, err
}

msgToSignG1 := core.NewG1Point(msgToSignG1_.X, msgToSignG1_.Y)
signature := keypair.SignHashedToCurveMessage(msgToSignG1)

signedMessageHashParam_ := pubKeyG1ToBN254G1Point(signedMessageHash)
signedMessageHashParam := regcoordinator.BN254G1Point{
X: signedMessageHashParam_.X,
Y: signedMessageHashParam_.Y,
X: signature.X.BigInt(big.NewInt(0)),
Y: signature.Y.BigInt(big.NewInt(0)),
}

g1Point_ := pubKeyG1ToBN254G1Point(keypair.GetPubKeyG1())
g1Point := regcoordinator.BN254G1Point{
X: g1Point_.X,
Expand All @@ -122,16 +138,44 @@ func (t *Transactor) getRegistrationParam(ctx context.Context, keypair *core.Key
PubkeyG2: g2Point,
}

return &params, nil
// params to register operator in delegation manager's operator-avs mapping
msgToSign, err := t.Bindings.DelegationManager.CalculateOperatorAVSRegistrationDigestHash(
&bind.CallOpts{}, operatorAddress, t.Bindings.ServiceManagerAddr, operatorToAvsRegistrationSigSalt, operatorToAvsRegistrationSigExpiry)
if err != nil {
return nil, nil, err
}
operatorSignature, err := crypto.Sign(msgToSign[:], operatorEcdsaPrivateKey)
if err != nil {
return nil, nil, err
}
// this is annoying, and not sure why its needed, but seems like some historical baggage
// see https://github.com/ethereum/go-ethereum/issues/28757#issuecomment-1874525854
// and https://twitter.com/pcaversaccio/status/1671488928262529031
operatorSignature[64] += 27
operatorSignatureWithSaltAndExpiry := regcoordinator.ISignatureUtilsSignatureWithSaltAndExpiry{
Signature: operatorSignature,
Salt: operatorToAvsRegistrationSigSalt,
Expiry: operatorToAvsRegistrationSigExpiry,
}

return &params, &operatorSignatureWithSaltAndExpiry, nil

}

// RegisterOperator registers a new operator with the given public key and socket with the provided quorum ids.
// If the operator is already registered with a given quorum id, the transaction will fail (noop) and an error
// will be returned.
func (t *Transactor) RegisterOperator(ctx context.Context, keypair *core.KeyPair, socket string, quorumIds []core.QuorumID) error {
func (t *Transactor) RegisterOperator(
ctx context.Context,
keypair *core.KeyPair,
socket string,
quorumIds []core.QuorumID,
operatorEcdsaPrivateKey *ecdsa.PrivateKey,
operatorToAvsRegistrationSigSalt [32]byte,
operatorToAvsRegistrationSigExpiry *big.Int,
) error {

params, err := t.getRegistrationParam(ctx, keypair)
params, operatorSignature, err := t.getRegistrationParams(ctx, keypair, operatorEcdsaPrivateKey, operatorToAvsRegistrationSigSalt, operatorToAvsRegistrationSigExpiry)
if err != nil {
t.Logger.Error("Failed to get registration params", "err", err)
return err
Expand All @@ -144,10 +188,7 @@ func (t *Transactor) RegisterOperator(ctx context.Context, keypair *core.KeyPair
return err
}

// TODO(mooselumph): Fill out operatorSignature
operatorSignature := regcoordinator.ISignatureUtilsSignatureWithSaltAndExpiry{}

tx, err := t.Bindings.RegistryCoordinator.RegisterOperator(opts, quorumNumbers, socket, *params, operatorSignature)
tx, err := t.Bindings.RegistryCoordinator.RegisterOperator(opts, quorumNumbers, socket, *params, *operatorSignature)

if err != nil {
t.Logger.Error("Failed to register operator", "err", err)
Expand All @@ -164,9 +205,18 @@ func (t *Transactor) RegisterOperator(ctx context.Context, keypair *core.KeyPair

// RegisterOperatorWithChurn registers a new operator with the given public key and socket with the provided quorum ids
// with the provided signature from the churner
func (t *Transactor) RegisterOperatorWithChurn(ctx context.Context, keypair *core.KeyPair, socket string, quorumIds []core.QuorumID, churnReply *churner.ChurnReply) error {
func (t *Transactor) RegisterOperatorWithChurn(
ctx context.Context,
keypair *core.KeyPair,
socket string,
quorumIds []core.QuorumID,
operatorEcdsaPrivateKey *ecdsa.PrivateKey,
operatorToAvsRegistrationSigSalt [32]byte,
operatorToAvsRegistrationSigExpiry *big.Int,
churnReply *churner.ChurnReply,
) error {

params, err := t.getRegistrationParam(ctx, keypair)
params, operatorSignature, err := t.getRegistrationParams(ctx, keypair, operatorEcdsaPrivateKey, operatorToAvsRegistrationSigSalt, operatorToAvsRegistrationSigExpiry)
if err != nil {
t.Logger.Error("Failed to get registration params", "err", err)
return err
Expand All @@ -184,7 +234,7 @@ func (t *Transactor) RegisterOperatorWithChurn(ctx context.Context, keypair *cor

var salt [32]byte
copy(salt[:], churnReply.SignatureWithSaltAndExpiry.Salt[:])
signatureWithSaltAndExpiry := regcoordinator.ISignatureUtilsSignatureWithSaltAndExpiry{
churnApproverSignature := regcoordinator.ISignatureUtilsSignatureWithSaltAndExpiry{
Signature: churnReply.SignatureWithSaltAndExpiry.Signature,
Salt: salt,
Expiry: new(big.Int).SetInt64(churnReply.SignatureWithSaltAndExpiry.Expiry),
Expand All @@ -197,7 +247,6 @@ func (t *Transactor) RegisterOperatorWithChurn(ctx context.Context, keypair *cor
}

// TODO(mooselumph): Fill out these
operatorSignature := regcoordinator.ISignatureUtilsSignatureWithSaltAndExpiry{}
kickParams := []regcoordinator.IRegistryCoordinatorOperatorKickParam{}

tx, err := t.Bindings.RegistryCoordinator.RegisterOperatorWithChurn(
Expand All @@ -206,8 +255,8 @@ func (t *Transactor) RegisterOperatorWithChurn(ctx context.Context, keypair *cor
socket,
*params,
kickParams,
signatureWithSaltAndExpiry,
operatorSignature,
churnApproverSignature,
*operatorSignature,
)

if err != nil {
Expand Down Expand Up @@ -562,12 +611,25 @@ func (t *Transactor) GetQuorumCount(ctx context.Context, blockNumber uint32) (ui
}

func (t *Transactor) updateContractBindings(blsOperatorStateRetrieverAddr, eigenDAServiceManagerAddr gethcommon.Address) error {

contractEigenDAServiceManager, err := eigendasrvmg.NewContractEigenDAServiceManager(eigenDAServiceManagerAddr, t.EthClient)
if err != nil {
t.Logger.Error("Failed to fetch IEigenDAServiceManager contract", "err", err)
return err
}

delegationManagerAddr, err := contractEigenDAServiceManager.Delegation(&bind.CallOpts{})
if err != nil {
t.Logger.Error("Failed to fetch DelegationManager address", "err", err)
return err
}

contractDelegationManager, err := delegationmgr.NewContractDelegationManager(delegationManagerAddr, t.EthClient)
if err != nil {
t.Logger.Error("Failed to fetch DelegationManager contract", "err", err)
return err
}

registryCoordinatorAddr, err := contractEigenDAServiceManager.RegistryCoordinator(&bind.CallOpts{})
if err != nil {
t.Logger.Error("Failed to fetch RegistryCoordinator address", "err", err)
Expand All @@ -592,6 +654,8 @@ func (t *Transactor) updateContractBindings(blsOperatorStateRetrieverAddr, eigen
return err
}

t.Logger.Debug("Addresses", "blsOperatorStateRetrieverAddr", blsOperatorStateRetrieverAddr.Hex(), "eigenDAServiceManagerAddr", eigenDAServiceManagerAddr.Hex(), "registryCoordinatorAddr", registryCoordinatorAddr.Hex(), "blsPubkeyRegistryAddr", blsPubkeyRegistryAddr.Hex())

contractBLSPubkeyReg, err := blsapkreg.NewContractBLSApkRegistry(blsPubkeyRegistryAddr, t.EthClient)
if err != nil {
t.Logger.Error("Failed to fetch IBLSApkRegistry contract", "err", err)
Expand Down Expand Up @@ -623,13 +687,15 @@ func (t *Transactor) updateContractBindings(blsOperatorStateRetrieverAddr, eigen
}

t.Bindings = &ContractBindings{
ServiceManagerAddr: eigenDAServiceManagerAddr,
RegCoordinatorAddr: registryCoordinatorAddr,
OpStateRetriever: contractBLSOpStateRetr,
BLSApkRegistry: contractBLSPubkeyReg,
IndexRegistry: contractIIndexReg,
RegistryCoordinator: contractIRegistryCoordinator,
StakeRegistry: contractStakeRegistry,
EigenDAServiceManager: contractEigenDAServiceManager,
DelegationManager: contractDelegationManager,
}
return nil
}
Expand Down
13 changes: 12 additions & 1 deletion core/indexer/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package indexer_test

import (
"context"
"crypto/rand"
"flag"
"fmt"
"math/big"
"os"
"path/filepath"
"time"
Expand All @@ -24,6 +26,7 @@ import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rpc"
)

Expand Down Expand Up @@ -51,7 +54,15 @@ func mustRegisterOperators(env *deploy.Config, logger common.Logger) {

socket := fmt.Sprintf("%v:%v", op.NODE_HOSTNAME, op.NODE_DISPERSAL_PORT)

err = tx.RegisterOperator(context.Background(), keyPair, socket, quorums)
salt := [32]byte{}
_, err = rand.Read(salt[:])
Expect(err).To(BeNil())

expiry := big.NewInt(1000)
privKey, err := crypto.GenerateKey()
Expect(err).To(BeNil())

err = tx.RegisterOperator(context.Background(), keyPair, socket, quorums, privKey, salt, expiry)
Expect(err).To(BeNil())
}
}
Expand Down
21 changes: 19 additions & 2 deletions core/mock/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package mock

import (
"context"
"crypto/ecdsa"
"math/big"

"github.com/Layr-Labs/eigenda/api/grpc/churner"
Expand Down Expand Up @@ -33,12 +34,28 @@ func (t *MockTransactor) GetRegisteredQuorumIdsForOperator(ctx context.Context,
return result.([]core.QuorumID), args.Error(1)
}

func (t *MockTransactor) RegisterOperator(ctx context.Context, keypair *core.KeyPair, socket string, quorumIds []core.QuorumID) error {
func (t *MockTransactor) RegisterOperator(
ctx context.Context,
keypair *core.KeyPair,
socket string,
quorumIds []core.QuorumID,
operatorEcdsaPrivateKey *ecdsa.PrivateKey,
operatorToAvsRegistrationSigSalt [32]byte,
operatorToAvsRegistrationSigExpiry *big.Int,
) error {
args := t.Called()
return args.Error(0)
}

func (t *MockTransactor) RegisterOperatorWithChurn(ctx context.Context, keypair *core.KeyPair, socket string, quorumIds []core.QuorumID, churnReply *churner.ChurnReply) error {
func (t *MockTransactor) RegisterOperatorWithChurn(
ctx context.Context,
keypair *core.KeyPair,
socket string,
quorumIds []core.QuorumID,
operatorEcdsaPrivateKey *ecdsa.PrivateKey,
operatorToAvsRegistrationSigSalt [32]byte,
operatorToAvsRegistrationSigExpiry *big.Int,
churnReply *churner.ChurnReply) error {
args := t.Called()
return args.Error(0)
}
Expand Down
Loading

0 comments on commit 581f7b5

Please sign in to comment.