Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add more chain reader coverage #6

Open
wants to merge 26 commits into
base: feat/add-reader-test-coverage
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
65792b2
Add test covering GetAllocatableMagnitude and GetMaxMagnitudes
maximopalopoli Jan 14, 2025
f189b5d
Add GetOperatorShares test
maximopalopoli Jan 14, 2025
5c8805f
Add GetOperatorsShares test
maximopalopoli Jan 14, 2025
fc87db0
Add simple GetOperatorSetsForOperator test case
maximopalopoli Jan 14, 2025
99d26d0
Merge branch 'feat/add-reader-test-coverage' into test/add-more-chain…
maximopalopoli Jan 15, 2025
f0a5173
Merge branch 'feat/add-reader-test-coverage' into test/add-more-chain…
maximopalopoli Jan 15, 2025
1cb3ba5
Use ReceiptStatusSuccessful constant from gethtypes
maximopalopoli Jan 15, 2025
cec441e
Merge branch 'feat/add-reader-test-coverage' into test/add-more-chain…
maximopalopoli Jan 15, 2025
5af43b4
feat: bls signer abstraction (#403)
shrimalmadhur Jan 15, 2025
78bcc4d
Improve test that covers getAllocatable and getMax
maximopalopoli Jan 15, 2025
56cd674
Improve GetOperatorShares test
maximopalopoli Jan 15, 2025
fb3bcb6
Improve GetOperatorsShares test
maximopalopoli Jan 15, 2025
448abaf
Modify terminology in TestGetAllocatableMagnitudeAndGetMaxMagnitudes
maximopalopoli Jan 15, 2025
3389c12
InstrumentedClient having rpcCallsCollector as mandatory (#378)
pablodeymo Jan 15, 2025
0671041
Remove outdated TODO (#396)
TomasArrachea Jan 15, 2025
1e176a1
test: `elcontracts.ChainWriter` claim functions (slashing) (#436)
ricomateo Jan 16, 2025
3bfa0a6
test: use read clients builder (#441)
maximopalopoli Jan 16, 2025
fda56ad
test: add reader test coverage (#429)
maximopalopoli Jan 16, 2025
3cc74f7
Merge branch 'dev' into test/add-more-chain-reader-coverage
maximopalopoli Jan 16, 2025
40e57ee
Remove constant
maximopalopoli Jan 16, 2025
563216e
Add comment in GetOperatorsShares
maximopalopoli Jan 16, 2025
35d8505
Rename GetOperatorsShares parameter to plural
maximopalopoli Jan 16, 2025
16753b1
fix: change literal string values for constants or predefined values …
maximopalopoli Jan 16, 2025
c2df79e
Merge branch 'dev' into test/add-more-chain-reader-coverage
maximopalopoli Jan 16, 2025
18e1163
Rename maxmagnitude var to maxMagnitudes
maximopalopoli Jan 16, 2025
d675c3f
Improve comment terminology
maximopalopoli Jan 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions chainio/clients/avsregistry/writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

chainioutils "github.com/Layr-Labs/eigensdk-go/chainio/utils"
"github.com/Layr-Labs/eigensdk-go/crypto/bls"
"github.com/Layr-Labs/eigensdk-go/testutils"
"github.com/Layr-Labs/eigensdk-go/testutils/testclients"
"github.com/Layr-Labs/eigensdk-go/types"
gethcommon "github.com/ethereum/go-ethereum/common"
Expand All @@ -20,9 +21,8 @@ func TestWriterMethods(t *testing.T) {
keypair, err := bls.NewKeyPairFromString("0x01")
require.NoError(t, err)

addr := gethcommon.HexToAddress("0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266")
ecdsaPrivKeyHex := "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
ecdsaPrivateKey, err := crypto.HexToECDSA(ecdsaPrivKeyHex)
addr := gethcommon.HexToAddress(testutils.ANVIL_FIRST_ADDRESS)
ecdsaPrivateKey, err := crypto.HexToECDSA(testutils.ANVIL_FIRST_PRIVATE_KEY)
require.NoError(t, err)

quorumNumbers := types.QuorumNums{0}
Expand Down
4 changes: 2 additions & 2 deletions chainio/clients/elcontracts/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,13 +461,13 @@ func (r *ChainReader) GetOperatorShares(

func (r *ChainReader) GetOperatorsShares(
ctx context.Context,
operatorAddress []gethcommon.Address,
operatorAddresses []gethcommon.Address,
strategyAddresses []gethcommon.Address,
) ([][]*big.Int, error) {
if r.delegationManager == nil {
return nil, errors.New("DelegationManager contract not provided")
}
return r.delegationManager.GetOperatorsShares(&bind.CallOpts{Context: ctx}, operatorAddress, strategyAddresses)
return r.delegationManager.GetOperatorsShares(&bind.CallOpts{Context: ctx}, operatorAddresses, strategyAddresses)
}

// GetNumOperatorSetsForOperator returns the number of operator sets that an operator is part of
Expand Down
194 changes: 173 additions & 21 deletions chainio/clients/elcontracts/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"testing"

"github.com/Layr-Labs/eigensdk-go/chainio/clients/elcontracts"
allocationmanager "github.com/Layr-Labs/eigensdk-go/contracts/bindings/AllocationManager"
erc20 "github.com/Layr-Labs/eigensdk-go/contracts/bindings/IERC20"
rewardscoordinator "github.com/Layr-Labs/eigensdk-go/contracts/bindings/IRewardsCoordinator"
"github.com/Layr-Labs/eigensdk-go/testutils"
Expand All @@ -20,38 +21,38 @@ import (
)

func TestChainReader(t *testing.T) {
clients, anvilHttpEndpoint := testclients.BuildTestClients(t)
read_clients, anvilHttpEndpoint := testclients.BuildTestReadClients(t)
ctx := context.Background()

contractAddrs := testutils.GetContractAddressesFromContractRegistry(anvilHttpEndpoint)
operator := types.Operator{
Address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
Address: testutils.ANVIL_FIRST_ADDRESS,
}

t.Run("is operator registered", func(t *testing.T) {
isOperator, err := clients.ElChainReader.IsOperatorRegistered(ctx, operator)
isOperator, err := read_clients.ElChainReader.IsOperatorRegistered(ctx, operator)
assert.NoError(t, err)
assert.Equal(t, isOperator, true)
})

t.Run("get operator details", func(t *testing.T) {
operatorDetails, err := clients.ElChainReader.GetOperatorDetails(ctx, operator)
operatorDetails, err := read_clients.ElChainReader.GetOperatorDetails(ctx, operator)
assert.NoError(t, err)
assert.NotNil(t, operatorDetails)
assert.Equal(t, operator.Address, operatorDetails.Address)
})

t.Run("get strategy and underlying token", func(t *testing.T) {
strategyAddr := contractAddrs.Erc20MockStrategy
strategy, underlyingTokenAddr, err := clients.ElChainReader.GetStrategyAndUnderlyingToken(
strategy, underlyingTokenAddr, err := read_clients.ElChainReader.GetStrategyAndUnderlyingToken(
ctx,
strategyAddr,
)
assert.NoError(t, err)
assert.NotNil(t, strategy)
assert.NotEqual(t, common.Address{}, underlyingTokenAddr)

erc20Token, err := erc20.NewContractIERC20(underlyingTokenAddr, clients.EthHttpClient)
erc20Token, err := erc20.NewContractIERC20(underlyingTokenAddr, read_clients.EthHttpClient)
assert.NoError(t, err)

tokenName, err := erc20Token.Name(&bind.CallOpts{})
Expand All @@ -61,7 +62,7 @@ func TestChainReader(t *testing.T) {

t.Run("get strategy and underlying ERC20 token", func(t *testing.T) {
strategyAddr := contractAddrs.Erc20MockStrategy
strategy, contractUnderlyingToken, underlyingTokenAddr, err := clients.ElChainReader.GetStrategyAndUnderlyingERC20Token(
strategy, contractUnderlyingToken, underlyingTokenAddr, err := read_clients.ElChainReader.GetStrategyAndUnderlyingERC20Token(
ctx,
strategyAddr,
)
Expand All @@ -76,7 +77,7 @@ func TestChainReader(t *testing.T) {
})

t.Run("get operator shares in strategy", func(t *testing.T) {
shares, err := clients.ElChainReader.GetOperatorSharesInStrategy(
shares, err := read_clients.ElChainReader.GetOperatorSharesInStrategy(
ctx,
common.HexToAddress(operator.Address),
contractAddrs.Erc20MockStrategy,
Expand All @@ -90,7 +91,7 @@ func TestChainReader(t *testing.T) {
delegationApprover := common.Address{0x0}
approverSalt := [32]byte{}
expiry := big.NewInt(0)
digest, err := clients.ElChainReader.CalculateDelegationApprovalDigestHash(
digest, err := read_clients.ElChainReader.CalculateDelegationApprovalDigestHash(
ctx,
staker,
common.HexToAddress(operator.Address),
Expand All @@ -106,7 +107,7 @@ func TestChainReader(t *testing.T) {
avs := common.Address{0x0}
salt := [32]byte{}
expiry := big.NewInt(0)
digest, err := clients.ElChainReader.CalculateOperatorAVSRegistrationDigestHash(
digest, err := read_clients.ElChainReader.CalculateOperatorAVSRegistrationDigestHash(
ctx,
common.HexToAddress(operator.Address),
avs,
Expand All @@ -118,19 +119,19 @@ func TestChainReader(t *testing.T) {
})

t.Run("get staker shares", func(t *testing.T) {
strategies, shares, err := clients.ElChainReader.GetStakerShares(
strategies, shares, err := read_clients.ElChainReader.GetStakerShares(
ctx,
common.HexToAddress(operator.Address),
)
assert.NotZero(t, len(strategies)) // Strategies has at least one element
assert.NotZero(t, len(shares)) // Shares has at least one element
assert.Equal(t, len(strategies), len(shares)) // Strategies has the same ammount of elements as shares
assert.NotZero(t, len(strategies), "Strategies has at least one element")
assert.NotZero(t, len(shares), "Shares has at least one element")
assert.Equal(t, len(strategies), len(shares), "Strategies has the same ammount of elements as shares")
assert.NoError(t, err)
})

t.Run("get delegated operator", func(t *testing.T) {
val := big.NewInt(0)
address, err := clients.ElChainReader.GetDelegatedOperator(
address, err := read_clients.ElChainReader.GetDelegatedOperator(
ctx,
common.HexToAddress(operator.Address),
val,
Expand All @@ -141,6 +142,75 @@ func TestChainReader(t *testing.T) {
assert.Equal(t, address.String(), operator.Address)
})

t.Run("GetOperatorShares", func(t *testing.T) {
strategyAddr := contractAddrs.Erc20MockStrategy
strategies := []common.Address{strategyAddr}
shares, err := read_clients.ElChainReader.GetOperatorShares(
ctx,
common.HexToAddress(operator.Address),
strategies,
)
assert.NoError(t, err)
assert.Len(t, shares, 1)

// with n strategies, response's list length is n
strategies = []common.Address{strategyAddr, strategyAddr, strategyAddr}
shares, err = read_clients.ElChainReader.GetOperatorShares(
ctx,
common.HexToAddress(operator.Address),
strategies,
)
assert.NoError(t, err)
assert.Len(t, shares, 3)

// We could test modify the shares and verify the diff is the expected
})

t.Run("GetOperatorsShares", func(t *testing.T) {
operatorAddr := common.HexToAddress(operator.Address)
operators := []common.Address{operatorAddr}
strategyAddr := contractAddrs.Erc20MockStrategy
strategies := []common.Address{strategyAddr}
shares, err := read_clients.ElChainReader.GetOperatorsShares(
ctx,
operators,
strategies,
)
assert.NoError(t, err)
assert.Len(t, shares, 1)

// with n strategies, response's list length is [1][n]
mult_strategies := []common.Address{strategyAddr, strategyAddr, strategyAddr}
shares, err = read_clients.ElChainReader.GetOperatorsShares(
ctx,
operators,
mult_strategies,
)
assert.NoError(t, err)
assert.Len(t, shares, 1)
assert.Len(t, shares[0], 3)

// with n strategies, response's list length is [n][1]
mult_operators := []common.Address{operatorAddr, operatorAddr, operatorAddr}
shares, err = read_clients.ElChainReader.GetOperatorsShares(
ctx,
mult_operators,
strategies,
)
assert.NoError(t, err)
assert.Len(t, shares, 3)
assert.Len(t, shares[0], 1)

// with n strategies and n operators, response's list length is [n][n]
shares, err = read_clients.ElChainReader.GetOperatorsShares(
ctx,
mult_operators,
mult_strategies,
)
assert.NoError(t, err)
assert.Len(t, shares, 3)
assert.Len(t, shares[2], 3)
})
}

func TestGetCurrentClaimableDistributionRoot(t *testing.T) {
Expand Down Expand Up @@ -275,7 +345,9 @@ func TestGetRootIndexFromRootHash(t *testing.T) {
root,
)
assert.Error(t, err)
assert.Equal(t, err.Error(), "execution reverted: custom error 0x504570e3")
assert.Equal(t, err.Error(), "execution reverted: custom error 0x504570e3",
"GetRootIndexFromHash should return an InvalidRoot() error",
)
assert.Zero(t, root_index)

currRewardsCalculationEndTimestamp, err := chainReader.CurrRewardsCalculationEndTimestamp(context.Background())
Expand Down Expand Up @@ -360,15 +432,14 @@ func TestGetCumulativeClaimedRewards(t *testing.T) {

// This tests that without claims result is zero
claimed, err := chainReader.GetCumulativeClaimed(ctx, anvil_address, underlyingTokenAddr)
assert.True(t, claimed.Cmp(big.NewInt(0)) == 0)
assert.Zero(t, claimed.Cmp(big.NewInt(0)))
assert.NoError(t, err)

cumulativeEarnings := int64(45)
claim, err := newTestClaim(chainReader, anvilHttpEndpoint, cumulativeEarnings, privateKeyHex)
require.NoError(t, err)

earner := common.HexToAddress(testutils.REWARDS_COORDINATOR_ADDRESS)
receipt, err = chainWriter.ProcessClaim(context.Background(), *claim, earner, true)
receipt, err = chainWriter.ProcessClaim(context.Background(), *claim, rewardsCoordinatorAddr, true)
require.NoError(t, err)
require.True(t, receipt.Status == gethtypes.ReceiptStatusSuccessful)

Expand Down Expand Up @@ -408,8 +479,7 @@ func TestCheckClaim(t *testing.T) {
claim, err := newTestClaim(chainReader, anvilHttpEndpoint, cumulativeEarnings, privateKeyHex)
require.NoError(t, err)

earner := common.HexToAddress(testutils.REWARDS_COORDINATOR_ADDRESS)
receipt, err = chainWriter.ProcessClaim(context.Background(), *claim, earner, true)
receipt, err = chainWriter.ProcessClaim(context.Background(), *claim, rewardsCoordinatorAddr, true)
require.NoError(t, err)
require.True(t, receipt.Status == gethtypes.ReceiptStatusSuccessful)

Expand All @@ -428,6 +498,88 @@ func TestCheckClaim(t *testing.T) {
assert.True(t, checked)
}

func TestGetAllocatableMagnitudeAndGetMaxMagnitudes(t *testing.T) {
// Without changes, Allocable magnitude is max magnitude

// Test setup
ctx := context.Background()

testConfig := testutils.GetDefaultTestConfig()
anvilC, err := testutils.StartAnvilContainer(testConfig.AnvilStateFileName)
require.NoError(t, err)

anvilHttpEndpoint, err := anvilC.Endpoint(context.Background(), "http")
require.NoError(t, err)
contractAddrs := testutils.GetContractAddressesFromContractRegistry(anvilHttpEndpoint)

operatorAddr := common.HexToAddress(testutils.ANVIL_FIRST_ADDRESS)
config := elcontracts.Config{
DelegationManagerAddress: contractAddrs.DelegationManager,
}

chainReader, err := testclients.NewTestChainReaderFromConfig(anvilHttpEndpoint, config)
require.NoError(t, err)

strategyAddr := contractAddrs.Erc20MockStrategy
testAddr := common.HexToAddress(testutils.ANVIL_FIRST_ADDRESS)
operatorSetId := uint32(1)

strategies := []common.Address{strategyAddr}
maxMagnitudes, err := chainReader.GetMaxMagnitudes(ctx, testAddr, strategies)
assert.NoError(t, err)

// Assert that at the beginning, Allocatable Magnitude is Max allocatable magnitude
allocable, err := chainReader.GetAllocatableMagnitude(ctx, testAddr, strategyAddr)
assert.NoError(t, err)

assert.Equal(t, maxMagnitudes[0], allocable)

// Reduce allocatable magnitude for testAddr
privateKeyHex := testutils.ANVIL_FIRST_PRIVATE_KEY

chainWriter, err := testclients.NewTestChainWriterFromConfig(anvilHttpEndpoint, privateKeyHex, config)
require.NoError(t, err)

waitForReceipt := true
delay := uint32(1)
receipt, err := chainWriter.SetAllocationDelay(context.Background(), operatorAddr, delay, waitForReceipt)
require.NoError(t, err)
require.Equal(t, gethtypes.ReceiptStatusSuccessful, receipt.Status)

allocationConfigurationDelay := 1200
testutils.AdvanceChainByNBlocksExecInContainer(context.Background(), allocationConfigurationDelay+1, anvilC)

// Check that Allocation delay has been applied
_, err = chainReader.GetAllocationDelay(context.Background(), operatorAddr)
require.NoError(t, err)

err = createOperatorSet(anvilHttpEndpoint, privateKeyHex, testAddr, operatorSetId, strategyAddr)
require.NoError(t, err)

operatorSet := allocationmanager.OperatorSet{
Avs: testAddr,
Id: operatorSetId,
}
allocatable_reduction := uint64(100)
allocateParams := []allocationmanager.IAllocationManagerTypesAllocateParams{
{
OperatorSet: operatorSet,
Strategies: []common.Address{strategyAddr},
NewMagnitudes: []uint64{allocatable_reduction},
},
}

receipt, err = chainWriter.ModifyAllocations(context.Background(), operatorAddr, allocateParams, waitForReceipt)
require.NoError(t, err)
require.Equal(t, gethtypes.ReceiptStatusSuccessful, receipt.Status)

// Assert that after stake reduction, Allocatable Magnitude + reduction ammount equals Max allocatable magnitude
allocable, err = chainReader.GetAllocatableMagnitude(ctx, testAddr, strategyAddr)
assert.NoError(t, err)

assert.Equal(t, maxMagnitudes[0], allocable+allocatable_reduction)
}

func TestAdminFunctions(t *testing.T) {
testConfig := testutils.GetDefaultTestConfig()
anvilC, err := testutils.StartAnvilContainer(testConfig.AnvilStateFileName)
Expand Down
8 changes: 4 additions & 4 deletions chainio/clients/elcontracts/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ func (w *ChainWriter) SetClaimerFor(
func (w *ChainWriter) ProcessClaim(
ctx context.Context,
claim rewardscoordinator.IRewardsCoordinatorTypesRewardsMerkleClaim,
earnerAddress gethcommon.Address,
recipientAddress gethcommon.Address,
waitForReceipt bool,
) (*gethtypes.Receipt, error) {
if w.rewardsCoordinator == nil {
Expand All @@ -354,7 +354,7 @@ func (w *ChainWriter) ProcessClaim(
return nil, utils.WrapError("failed to get no send tx opts", err)
}

tx, err := w.rewardsCoordinator.ProcessClaim(noSendTxOpts, claim, earnerAddress)
tx, err := w.rewardsCoordinator.ProcessClaim(noSendTxOpts, claim, recipientAddress)
if err != nil {
return nil, utils.WrapError("failed to create ProcessClaim tx", err)
}
Expand Down Expand Up @@ -424,7 +424,7 @@ func (w *ChainWriter) SetOperatorPISplit(
func (w *ChainWriter) ProcessClaims(
ctx context.Context,
claims []rewardscoordinator.IRewardsCoordinatorTypesRewardsMerkleClaim,
earnerAddress gethcommon.Address,
recipientAddress gethcommon.Address,
waitForReceipt bool,
) (*gethtypes.Receipt, error) {
if w.rewardsCoordinator == nil {
Expand All @@ -440,7 +440,7 @@ func (w *ChainWriter) ProcessClaims(
return nil, utils.WrapError("failed to get no send tx opts", err)
}

tx, err := w.rewardsCoordinator.ProcessClaims(noSendTxOpts, claims, earnerAddress)
tx, err := w.rewardsCoordinator.ProcessClaims(noSendTxOpts, claims, recipientAddress)
if err != nil {
return nil, utils.WrapError("failed to create ProcessClaims tx", err)
}
Expand Down
Loading
Loading