Skip to content

Commit

Permalink
m2-mainnet Contracts Update (Layr-Labs#158)
Browse files Browse the repository at this point in the history
Co-authored-by: Robert Raynor <[email protected]>
Co-authored-by: Jian Xiao <[email protected]>
Co-authored-by: steven <[email protected]>
Co-authored-by: steven <[email protected]>
Co-authored-by: siddimore <[email protected]>
Co-authored-by: Ian Shim <[email protected]>
Co-authored-by: bolatfurkan <[email protected]>
Co-authored-by: Peter Straus <[email protected]>
Co-authored-by: WELLINGTON MIRANDA BARBOSA <[email protected]>
Co-authored-by: Wellington Barbosa <[email protected]>
Co-authored-by: Jian Xiao <[email protected]>
Co-authored-by: buldazer <[email protected]>
Co-authored-by: Madhur Shrimal <[email protected]>
Co-authored-by: Daniel Mancia <[email protected]>
  • Loading branch information
15 people authored and Ubuntu committed Feb 2, 2024
1 parent 9795106 commit 92eb8af
Show file tree
Hide file tree
Showing 104 changed files with 18,538 additions and 6,291 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ jobs:
run: make build && go test -v ./core/thegraph

- name: Inabox E2E
run: make build && cd inabox && make run-e2e-nochurner
run: make build && cd inabox && make run-e2e

- name: Save logs
if: always()
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ inabox/resources/kzg/SRSTables/*

**/bin/*
coverage.*

contracts/broadcast
81 changes: 46 additions & 35 deletions api/grpc/churner/churner.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions api/proto/churner/churner.proto
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ message ChurnRequest {
// - If any of the quorum fails to register, this entire request will fail.
// The IDs must be in range [0, 255].
repeated uint32 quorum_ids = 5;
// The Ethereum address (in hex like "0x123abcdef...") of the operator.
string operator_address = 6;
}

message ChurnReply {
Expand Down
26 changes: 10 additions & 16 deletions churner/churner.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ import (
var (
bipMultiplier = big.NewInt(10000)
secondsTillExpiry = 90 * time.Second
zeroAddressString = "0x0000000000000000000000000000000000000000"
)

type ChurnRequest struct {
OperatorAddress gethcommon.Address
OperatorToRegisterPubkeyG1 *core.G1Point
OperatorToRegisterPubkeyG2 *core.G2Point
OperatorRequestSignature *core.Signature
Expand All @@ -47,7 +47,7 @@ type churner struct {
mu sync.Mutex
Indexer thegraph.IndexedChainState
Transactor core.Transactor
QuorumCount uint16
QuorumCount uint8

privateKey *ecdsa.PrivateKey
logger common.Logger
Expand Down Expand Up @@ -78,14 +78,7 @@ func NewChurner(
}

func (c *churner) VerifyRequestSignature(ctx context.Context, churnRequest *ChurnRequest) (gethcommon.Address, error) {
operatorToRegisterAddress, err := c.Transactor.OperatorIDToAddress(ctx, churnRequest.OperatorToRegisterPubkeyG1.GetOperatorID())
if err != nil {
return gethcommon.Address{}, err
}
if operatorToRegisterAddress == gethcommon.HexToAddress(zeroAddressString) {
return gethcommon.Address{}, errors.New("operatorToRegisterPubkey is not registered with bls pubkey compendium")
}

operatorToRegisterAddress := churnRequest.OperatorAddress
isEqual, err := churnRequest.OperatorToRegisterPubkeyG1.VerifyEquivalence(churnRequest.OperatorToRegisterPubkeyG2)
if err != nil {
return gethcommon.Address{}, err
Expand Down Expand Up @@ -121,7 +114,7 @@ func (c *churner) ProcessChurnRequest(ctx context.Context, operatorToRegisterAdd
}
}

return c.createChurnResponse(ctx, operatorToRegisterId, operatorToRegisterAddress, churnRequest.QuorumIDs)
return c.createChurnResponse(ctx, operatorToRegisterAddress, operatorToRegisterId, churnRequest.QuorumIDs)
}

func (c *churner) UpdateQuorumCount(ctx context.Context) error {
Expand All @@ -142,8 +135,8 @@ func (c *churner) UpdateQuorumCount(ctx context.Context) error {

func (c *churner) createChurnResponse(
ctx context.Context,
operatorToRegisterId core.OperatorID,
operatorToRegisterAddress gethcommon.Address,
operatorToRegisterId core.OperatorID,
quorumIDs []core.QuorumID,
) (*ChurnResponse, error) {
currentBlockNumber, err := c.Transactor.GetCurrentBlockNumber(ctx)
Expand All @@ -163,7 +156,7 @@ func (c *churner) createChurnResponse(
return nil, err
}

signatureWithSaltAndExpiry, err := c.sign(ctx, operatorToRegisterId, operatorsToChurn)
signatureWithSaltAndExpiry, err := c.sign(ctx, operatorToRegisterAddress, operatorToRegisterId, operatorsToChurn)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -210,7 +203,7 @@ func (c *churner) getOperatorsToChurn(ctx context.Context, quorumIDs []uint8, op
churnBIPsOfOperatorStake := big.NewInt(int64(operatorSetParams.ChurnBIPsOfOperatorStake))
churnBIPsOfTotalStake := big.NewInt(int64(operatorSetParams.ChurnBIPsOfTotalStake))

c.logger.Info("lowestStake", "lowestStake", lowestStake.String(), "operatorToRegisterStake", operatorToRegisterStake.String(), "totalStake", totalStake.String())
c.logger.Info("lowestStake", "lowestStake", lowestStake.String(), "operatorToRegisterStake", operatorToRegisterStake.String(), "totalStake", totalStake.String(), "operatorToRegisterAddress", operatorToRegisterAddress.Hex())

// verify the lowest stake against the registering operator's stake
// make sure that: lowestStake * churnBIPsOfOperatorStake < operatorToRegisterStake * bipMultiplier
Expand Down Expand Up @@ -256,7 +249,7 @@ func (c *churner) getOperatorsToChurn(ctx context.Context, quorumIDs []uint8, op
return operatorsToChurn, nil
}

func (c *churner) sign(ctx context.Context, operatorToRegisterId core.OperatorID, operatorsToChurn []core.OperatorToChurn) (*SignatureWithSaltAndExpiry, error) {
func (c *churner) sign(ctx context.Context, operatorToRegisterAddress gethcommon.Address, operatorToRegisterId core.OperatorID, operatorsToChurn []core.OperatorToChurn) (*SignatureWithSaltAndExpiry, error) {
now := time.Now()
privateKeyBytes := crypto.FromECDSA(c.privateKey)
saltKeccak256 := crypto.Keccak256([]byte("churn"), []byte(now.String()), operatorToRegisterId[:], privateKeyBytes)
Expand All @@ -268,7 +261,7 @@ func (c *churner) sign(ctx context.Context, operatorToRegisterId core.OperatorID
expiry := big.NewInt(now.Add(secondsTillExpiry).Unix())

// sign and return signature
hashToSign, err := c.Transactor.CalculateOperatorChurnApprovalDigestHash(ctx, operatorToRegisterId, operatorsToChurn, salt, expiry)
hashToSign, err := c.Transactor.CalculateOperatorChurnApprovalDigestHash(ctx, operatorToRegisterAddress, operatorToRegisterId, operatorsToChurn, salt, expiry)
if err != nil {
return nil, err
}
Expand All @@ -290,6 +283,7 @@ func CalculateRequestHash(churnRequest *ChurnRequest) [32]byte {
var requestHash [32]byte
requestHashBytes := crypto.Keccak256(
[]byte("ChurnRequest"),
[]byte(churnRequest.OperatorAddress.Hex()),
churnRequest.OperatorToRegisterPubkeyG1.Serialize(),
churnRequest.OperatorToRegisterPubkeyG2.Serialize(),
churnRequest.Salt[:],
Expand Down
4 changes: 4 additions & 0 deletions churner/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
pb "github.com/Layr-Labs/eigenda/api/grpc/churner"
"github.com/Layr-Labs/eigenda/common"
"github.com/Layr-Labs/eigenda/core"
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/prometheus/client_golang/prometheus"
)

Expand Down Expand Up @@ -161,6 +162,8 @@ func (s *Server) validateChurnRequest(ctx context.Context, req *pb.ChurnRequest)
func createChurnRequest(req *pb.ChurnRequest) *ChurnRequest {
signature := &core.Signature{G1Point: new(core.G1Point).Deserialize(req.GetOperatorRequestSignature())}

address := gethcommon.HexToAddress(req.GetOperatorAddress())

salt := [32]byte{}
copy(salt[:], req.GetSalt())

Expand All @@ -170,6 +173,7 @@ func createChurnRequest(req *pb.ChurnRequest) *ChurnRequest {
}

return &ChurnRequest{
OperatorAddress: address,
OperatorToRegisterPubkeyG1: new(core.G1Point).Deserialize(req.GetOperatorToRegisterPubkeyG1()),
OperatorToRegisterPubkeyG2: new(core.G2Point).Deserialize(req.GetOperatorToRegisterPubkeyG2()),
OperatorRequestSignature: signature,
Expand Down
4 changes: 3 additions & 1 deletion churner/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func TestChurn(t *testing.T) {

salt := crypto.Keccak256([]byte(operatorToChurnInPrivateKeyHex), []byte("ChurnRequest"))
request := &pb.ChurnRequest{
OperatorAddress: operatorAddr.Hex(),
OperatorToRegisterPubkeyG1: keyPair.PubKey.Serialize(),
OperatorToRegisterPubkeyG2: keyPair.GetPubKeyG2().Serialize(),
Salt: salt,
Expand All @@ -49,6 +50,7 @@ func TestChurn(t *testing.T) {
var requestHash [32]byte
requestHashBytes := crypto.Keccak256(
[]byte("ChurnRequest"),
[]byte(request.OperatorAddress),
request.OperatorToRegisterPubkeyG1,
request.OperatorToRegisterPubkeyG2,
request.Salt,
Expand Down Expand Up @@ -118,7 +120,7 @@ func setupMockTransactor() {
transactorMock.On("OperatorIDToAddress").Return(operatorAddr, nil)
transactorMock.On("GetCurrentQuorumBitmapByOperatorId").Return(big.NewInt(2), nil)
transactorMock.On("GetCurrentBlockNumber").Return(uint32(2), nil)
transactorMock.On("GetQuorumCount").Return(uint16(1), nil)
transactorMock.On("GetQuorumCount").Return(uint8(1), nil)
transactorMock.On("GetOperatorStakesForQuorums").Return(dacore.OperatorStakes{
0: {
0: {
Expand Down
19 changes: 5 additions & 14 deletions churner/tests/churner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ var (
logger = &commock.Logger{}
mockIndexer = &indexermock.MockIndexedChainState{}
rpcURL = "http://localhost:8545"
quorumIds = []uint32{0}
quorumIds = []uint32{0, 1}
operatorAddr = gethcommon.HexToAddress("0x0000000000000000000000000000000000000001")
churnerPrivateKeyHex = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
operatorToChurnInPrivateKeyHex = "0000000000000000000000000000000000000000000000000000000000000020"
Expand Down Expand Up @@ -89,26 +89,14 @@ func teardown() {
func TestChurner(t *testing.T) {
ctx := context.Background()

// get the operator to churn in's transactor and bls public key registered
op := testConfig.Operators[0]
operatorTransactor, err := createTransactorFromScratch(
op.NODE_PRIVATE_KEY,
testConfig.EigenDA.OperatorStateRetreiver,
testConfig.EigenDA.ServiceManager,
logger,
)
assert.NoError(t, err)

keyPair, err := dacore.GenRandomBlsKeys()
assert.NoError(t, err)

err = operatorTransactor.RegisterBLSPublicKey(ctx, keyPair)
assert.NoError(t, err)

server := newTestServer(t)

salt := crypto.Keccak256([]byte(operatorToChurnInPrivateKeyHex), []byte("ChurnRequest"))
request := &pb.ChurnRequest{
OperatorAddress: operatorAddr.Hex(),
OperatorToRegisterPubkeyG1: keyPair.PubKey.Serialize(),
OperatorToRegisterPubkeyG2: keyPair.GetPubKeyG2().Serialize(),
Salt: salt,
Expand All @@ -118,6 +106,7 @@ func TestChurner(t *testing.T) {
var requestHash [32]byte
requestHashBytes := crypto.Keccak256(
[]byte("ChurnRequest"),
[]byte(request.OperatorAddress),
request.OperatorToRegisterPubkeyG1,
request.OperatorToRegisterPubkeyG2,
request.Salt,
Expand All @@ -132,6 +121,7 @@ func TestChurner(t *testing.T) {
}, nil)

reply, err := server.Churn(ctx, request)

assert.NoError(t, err)
assert.NotNil(t, reply)
assert.NotNil(t, reply.SignatureWithSaltAndExpiry.GetSalt())
Expand All @@ -144,6 +134,7 @@ func TestChurner(t *testing.T) {
assert.Equal(t, operatorAddr.Bytes(), param.GetOperator())
assert.Equal(t, keyPair.PubKey.Serialize(), param.GetPubkey())
}

}

func createTransactorFromScratch(privateKey, operatorStateRetriever, serviceManager string, logger common.Logger) (*eth.Transactor, error) {
Expand Down
2 changes: 1 addition & 1 deletion common/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ import (
//go:embed abis/EigenDAServiceManager.json
var ServiceManagerAbi []byte

var BatchConfirmedEventSigHash = crypto.Keccak256Hash([]byte("BatchConfirmed(bytes32,uint32,uint96)"))
var BatchConfirmedEventSigHash = crypto.Keccak256Hash([]byte("BatchConfirmed(bytes32,uint32)"))
Loading

0 comments on commit 92eb8af

Please sign in to comment.