Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feat/implement-validator-system-…
Browse files Browse the repository at this point in the history
…v2' into test/fix-val-mgr-test

# Conflicts:
#	packages/contracts/contracts/L1/AssetManager.sol
  • Loading branch information
0xHansLee committed Jul 26, 2024
2 parents cd72996 + b70a4e3 commit 9be8fc4
Show file tree
Hide file tree
Showing 14 changed files with 1,085 additions and 889 deletions.
111 changes: 79 additions & 32 deletions kroma-validator/challenger.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,15 @@ type Challenger struct {
colosseumABI *abi.ABI
valPoolContract *bindings.ValidatorPoolCaller
valMgrContract *bindings.ValidatorManagerCaller
assetMgrContract *bindings.AssetManagerCaller

submissionInterval *big.Int
finalizationPeriodSeconds *big.Int
l2BlockTime *big.Int
checkpoint *big.Int
requiredBondAmount *big.Int
requiredBondAmountV1 *big.Int
requiredBondAmountV2 *big.Int
valPoolTerminationIndex *big.Int

l2OutputSubmittedSub ethereum.Subscription
challengeCreatedSub ethereum.Subscription
Expand Down Expand Up @@ -96,6 +99,11 @@ func NewChallenger(cfg Config, l log.Logger, m metrics.Metricer) (*Challenger, e
return nil, err
}

assetMgrContract, err := bindings.NewAssetManagerCaller(cfg.AssetManagerAddr, cfg.L1Client)
if err != nil {
return nil, err
}

return &Challenger{
log: l.New("service", "challenge"),
cfg: cfg,
Expand All @@ -110,6 +118,7 @@ func NewChallenger(cfg Config, l log.Logger, m metrics.Metricer) (*Challenger, e
colosseumABI: colosseumABI,
valPoolContract: valPoolContract,
valMgrContract: valMgrContract,
assetMgrContract: assetMgrContract,
}, nil
}

Expand Down Expand Up @@ -150,18 +159,49 @@ func (c *Challenger) InitConfig(ctx context.Context) error {
err = contractWatcher.WatchUpgraded(c.cfg.ValidatorPoolAddr, func() error {
cCtx, cCancel := context.WithTimeout(ctx, c.cfg.NetworkTimeout)
defer cCancel()
requiredBondAmount, err := c.valPoolContract.REQUIREDBONDAMOUNT(optsutils.NewSimpleCallOpts(cCtx))
requiredBondAmountV1, err := c.valPoolContract.REQUIREDBONDAMOUNT(optsutils.NewSimpleCallOpts(cCtx))
if err != nil {
return fmt.Errorf("failed to get submission interval: %w", err)
}
c.requiredBondAmount = requiredBondAmount
c.requiredBondAmountV1 = requiredBondAmountV1

cCtx, cCancel = context.WithTimeout(ctx, c.cfg.NetworkTimeout)
defer cCancel()
valPoolTerminationIndex, err := c.valPoolContract.TERMINATEOUTPUTINDEX(optsutils.NewSimpleCallOpts(cCtx))
if err != nil {
// If method is not in ValidatorPool, set the termination index to big value to ensure it sticks to validator system V1.
if errors.Is(err, errors.New("method 'TERMINATION_OUTPUT_INDEX' not found")) {
valPoolTerminationIndex = big.NewInt(math.MaxUint32)
} else {
return fmt.Errorf("failed to get valPool termination index: %w", err)
}
}
c.valPoolTerminationIndex = valPoolTerminationIndex

return nil
})
if err != nil {
return fmt.Errorf("failed to initiate valPool config: %w", err)
}

err = contractWatcher.WatchUpgraded(c.cfg.AssetManagerAddr, func() error {
cCtx, cCancel := context.WithTimeout(ctx, c.cfg.NetworkTimeout)
defer cCancel()
requiredBondAmountV2, err := c.assetMgrContract.BONDAMOUNT(optsutils.NewSimpleCallOpts(cCtx))
if err != nil {
if errors.Is(err, errors.New("method 'BOND_AMOUNT' not found")) {
requiredBondAmountV2 = big.NewInt(0)
}
return fmt.Errorf("failed to get required bond amount: %w", err)
}
c.requiredBondAmountV2 = requiredBondAmountV2

return nil
})
if err != nil {
return fmt.Errorf("failed to initiate assetMgr config: %w, err")
}

return nil
}

Expand Down Expand Up @@ -545,7 +585,7 @@ func (c *Challenger) handleChallenge(outputIndex *big.Int, asserter common.Addre
continue
}
case chal.StatusChallengerTimeout:
// call challenger timeout to increase bond from pending bond
// call challenger timeout to take challenger's bond away
tx, err := c.ChallengerTimeout(c.ctx, outputIndex, challenger)
if err != nil {
c.log.Error("failed to create challenger timeout tx", "err", err, "outputIndex", outputIndex, "challenger", challenger)
Expand All @@ -560,22 +600,17 @@ func (c *Challenger) handleChallenge(outputIndex *big.Int, asserter common.Addre

// if challenger
if isChallenger && c.cfg.ChallengerEnabled {
if isOutputDeleted {
// if output has been already deleted, cancel challenge to refund pending bond in ValidatorPool
if !c.IsValPoolTerminated(outputIndex) && status != chal.StatusChallengerTimeout {
tx, err := c.CancelChallenge(c.ctx, outputIndex)
if err != nil {
c.log.Error("failed to create cancel challenge tx", "err", err, "outputIndex", outputIndex)
continue
}
if err := c.submitChallengeTx(tx); err != nil {
c.log.Error("failed to submit cancel challenge tx", "err", err, "outputIndex", outputIndex)
continue
}
// if output has been already deleted, cancel challenge to refund challenger's bond
if isOutputDeleted && status != chal.StatusChallengerTimeout {
tx, err := c.CancelChallenge(c.ctx, outputIndex)
if err != nil {
c.log.Error("failed to create cancel challenge tx", "err", err, "outputIndex", outputIndex)
continue
}
if err := c.submitChallengeTx(tx); err != nil {
c.log.Error("failed to submit cancel challenge tx", "err", err, "outputIndex", outputIndex)
continue
}
// if output has been already deleted, terminate handling
c.log.Info("output is already deleted when handling challenge", "outputIndex", outputIndex)
return
}

// if output is already finalized, terminate handling
Expand Down Expand Up @@ -623,6 +658,8 @@ func (c *Challenger) CanCreateChallenge(ctx context.Context, outputIndex *big.In
cCtx, cCancel := context.WithTimeout(ctx, c.cfg.NetworkTimeout)
defer cCancel()
from := c.cfg.TxManager.From()

var balance, requiredBondAmount *big.Int
if c.IsValPoolTerminated(outputIndex) {
if isInJail, err := c.isInJail(ctx); err != nil {
return false, err
Expand All @@ -641,30 +678,40 @@ func (c *Challenger) CanCreateChallenge(ctx context.Context, outputIndex *big.In
c.log.Warn("validator is not in the status that can create a challenge", "status", validatorStatus)
return false, nil
}

balance, err = c.assetMgrContract.TotalValidatorKroNotBonded(optsutils.NewSimpleCallOpts(cCtx), from)
if err != nil {
return false, fmt.Errorf("failed to fetch balance: %w", err)
}
requiredBondAmount = c.requiredBondAmountV2
} else {
balance, err := c.valPoolContract.BalanceOf(optsutils.NewSimpleCallOpts(cCtx), from)
var err error
balance, err = c.valPoolContract.BalanceOf(optsutils.NewSimpleCallOpts(cCtx), from)
if err != nil {
return false, fmt.Errorf("failed to fetch deposit amount: %w", err)
}
c.metr.RecordDepositAmount(balance)

if balance.Cmp(c.requiredBondAmount) == -1 {
c.log.Warn(
"deposit is less than bond attempt amount",
"requiredBondAmount", c.requiredBondAmount,
"deposit", balance,
)
return false, nil
}
requiredBondAmount = c.requiredBondAmountV1
}

c.metr.RecordUnbondedDepositAmount(balance)

c.log.Info("deposit amount and bond amount", "deposit", balance, "bond", c.requiredBondAmount)
// Check if the unbonded deposit amount is less than the required bond amount
if balance.Cmp(requiredBondAmount) == -1 {
c.log.Warn(
"unbonded deposit is less than bond attempt amount",
"requiredBondAmount", requiredBondAmount,
"unbonded_deposit", balance,
)
return false, nil
}

c.log.Info("unbonded deposit amount and bond amount", "unbonded_deposit", balance, "bond", requiredBondAmount)

return true, nil
}

func (c *Challenger) IsValPoolTerminated(outputIndex *big.Int) bool {
return c.cfg.ValPoolTerminationIndex.Cmp(outputIndex) < 0
return c.valPoolTerminationIndex.Cmp(outputIndex) < 0
}

func (c *Challenger) isInJail(ctx context.Context) (bool, error) {
Expand Down
86 changes: 31 additions & 55 deletions kroma-validator/cmd/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,46 +21,12 @@ kroma-validator [command] --help

## Commands

### Commands for Validator System V1

The following commands are available in Validator System V1. Note that these commands will be **deprecated** and
removed in the future after the new validator system is introduced. You can still use `withdraw` and `unbond` even
after the transition to the Validator System V2.

- `deposit` - Deposit ETH to `ValidatorPool`.
- `--amount [value]` - _(Required)_ The amount of ETH to deposit (in Wei).

```bash
kroma-validator deposit --amount 100000000
```

- `withdraw` - Withdraw ETH from `ValidatorPool`.
- `--amount [value]` - _(Required)_ The amount of ETH to withdraw (in Wei).

```bash
kroma-validator withdraw --amount 100000000
```

- `withdrawTo` - Withdraw ETH from `ValidatorPool` to specific address.
- `--address` - _(Required)_ The address to receive withdrawn ETH.
- `--amount [value]` - _(Required)_ The amount of ETH to withdraw (in Wei).

```bash
kroma-validator withdrawTo --address 0x0000000000000000000000000000000000000001 --amount 100000000
```

- `unbond` - Manually unbond the bonded ETH from `ValidatorPool` (including reward distribution).

```bash
kroma-validator unbond
```

### Commands for Validator System V2 (_EXPERIMENTAL_)
### Commands for Validator System V2

The following commands are available in Validator System V2:

- `register` - Register as new validator to `ValidatorManager`.
- `--amount [value]` - _(Required)_ The amount of tokens to delegate initially (in Wei).
- `--amount [value]` - _(Required)_ The amount of tokens to deposit initially (in Wei).
- `--commission-rate [value]` - _(Required)_ The initial commission rate of the validator (in %).
- `--withdraw-account [value]` - _(Required)_ The address to withdraw deposited asset token.

Expand All @@ -80,50 +46,60 @@ The following commands are available in Validator System V2:
kroma-validator unjail
```

- `changeCommissionRate init` - Initiate the commission rate change of the validator in `ValidatorManager`.
- `changeCommission init` - Initiate the commission rate change of the validator in `ValidatorManager`.
- `--commission-rate [value]` - _(Required)_ The new commission rate of the validator (in %).

```bash
kroma-validator changeCommissionRate init --commission-rate 5
kroma-validator changeCommission init --commission-rate 5
```

- `changeCommissionRate finalize` - Finalize the commission rate change of the validator in `ValidatorManager`.
- `changeCommission finalize` - Finalize the commission rate change of the validator in `ValidatorManager`.

```bash
kroma-validator changeCommissionRate finalize
kroma-validator changeCommission finalize
```

- `delegate` - Self-delegate asset tokens to the `AssetManager`.
- `--amount [value]` - _(Required)_ The amount of tokens to delegate (in Wei).
- `depositKro` - Deposit asset tokens to the `AssetManager`.
- `--amount [value]` - _(Required)_ The amount of tokens to deposit (in Wei).

```bash
kroma-validator delegate --amount 100000000
kroma-validator depositKro --amount 100000000
```

- `undelegate init` - Initiate the undelegation of asset tokens from the `AssetManager`.
- `--amount [value]` - _(Required)_ The amount of tokens to undelegate (in Wei).
Note that withdraw of the deposited asset and reward must be done with the withdraw account that was set during the
registration. Please make sure that you must keep the private key of the withdraw account safe, since it cannot be
modified after the registration.

### Commands for Validator System V1 (_DEPRECATED_)

The following commands are available in Validator System V1. Note that these commands are **deprecated** and
will be removed since the new validator system is introduced. You can still use `withdraw` and `unbond` to withdraw
and unbond your ETH from the old `ValidatorPool`.

- `deposit` - Deposit ETH to `ValidatorPool`.
- `--amount [value]` - _(Required)_ The amount of ETH to deposit (in Wei).

```bash
kroma-validator undelegate init --amount 100000000
kroma-validator deposit --amount 100000000
```

- `undelegate finalize` - Finalize the undelegations of asset tokens from the `AssetManager`.
Should be called after 1 week has passed from the `undelegate init` command.
- `withdraw` - Withdraw ETH from `ValidatorPool`.
- `--amount [value]` - _(Required)_ The amount of ETH to withdraw (in Wei).

```bash
kroma-validator undelegate finalize
kroma-validator withdraw --amount 100000000
```

- `claim init` - Initiate the claim of validator reward from the `AssetManager`.
- `--amount [value]` - _(Required)_ The amount of tokens to claim (in Wei).
- `withdrawTo` - Withdraw ETH from `ValidatorPool` to specific address.
- `--address` - _(Required)_ The address to receive withdrawn ETH.
- `--amount [value]` - _(Required)_ The amount of ETH to withdraw (in Wei).

```bash
kroma-validator claim init --amount 100000000
kroma-validator withdrawTo --address 0x0000000000000000000000000000000000000001 --amount 100000000
```

- `claim finalize` - Finalize the claim of validator reward from the `AssetManager`. Should be called after 1 week
has passed from the `claim init` command.
- `unbond` - Manually unbond the bonded ETH from `ValidatorPool` (including reward distribution).

```bash
kroma-validator claim finalize
kroma-validator unbond
```
Loading

0 comments on commit 9be8fc4

Please sign in to comment.