Skip to content

Commit

Permalink
feat(staking): change height on restart (#4856)
Browse files Browse the repository at this point in the history
  • Loading branch information
istae authored Oct 14, 2024
1 parent 1f0c3f6 commit eb0a89d
Show file tree
Hide file tree
Showing 4 changed files with 347 additions and 12 deletions.
42 changes: 34 additions & 8 deletions pkg/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -1004,18 +1004,44 @@ func NewBee(

stakingContract := staking.New(overlayEthAddress, stakingContractAddress, abiutil.MustParseABI(chainCfg.StakingABI), bzzTokenAddress, transactionService, common.BytesToHash(nonce), o.TrxDebugMode, uint8(o.ReserveCapacityDoubling))

if chainEnabled && changedOverlay {
stake, err := stakingContract.GetPotentialStake(ctx)
if chainEnabled {

if changedOverlay {
stake, err := stakingContract.GetPotentialStake(ctx)
if err != nil {
return nil, err
}
if stake.Cmp(big.NewInt(0)) > 0 {
logger.Debug("changing overlay address in staking contract")
tx, err := stakingContract.ChangeStakeOverlay(ctx, common.BytesToHash(nonce))
if err != nil {
return nil, fmt.Errorf("cannot change staking overlay address: %v", err.Error())
}
logger.Info("overlay address changed in staking contract", "transaction", tx)
}
}

// make sure that the staking contract has the up to date height
tx, updated, err := stakingContract.UpdateHeight(ctx)
if err != nil {
return nil, errors.New("getting stake balance")
return nil, err
}
if updated {
logger.Info("updated new reserve capacity doubling height in the staking contract", "transaction", tx, "new_height", o.ReserveCapacityDoubling)
}
if stake.Cmp(big.NewInt(0)) > 0 {
logger.Debug("changing overlay address in staking contract")
tx, err := stakingContract.ChangeStakeOverlay(ctx, common.BytesToHash(nonce))

if o.ReserveCapacityDoubling > 0 {
stake, err := stakingContract.GetPotentialStake(ctx)
if err != nil {
return nil, fmt.Errorf("cannot change staking overlay address: %v", err.Error())
return nil, err
}
if stake.Cmp(big.NewInt(0)) > 0 {
// Check if the staked amount is sufficient to cover the additional neighborhoods.
// The staked amount must be at least 2^h * MinimumStake.
if stake.Cmp(big.NewInt(0).Mul(big.NewInt(1<<o.ReserveCapacityDoubling), staking.MinimumStakeAmount)) < 0 {
logger.Warning("staked amount does not sufficiently cover the additional reserve capacity. Stake should be at least 2^h * 10 BZZ, where h is the number extra doublings.")
}
}
logger.Info("overlay address changed in staking contract", "transaction", tx)
}
}

Expand Down
54 changes: 50 additions & 4 deletions pkg/storageincentives/staking/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type Contract interface {
GetWithdrawableStake(ctx context.Context) (*big.Int, error)
WithdrawStake(ctx context.Context) (common.Hash, error)
MigrateStake(ctx context.Context) (common.Hash, error)
UpdateHeight(ctx context.Context) (common.Hash, bool, error)
RedistributionStatuser
}

Expand Down Expand Up @@ -116,7 +117,7 @@ func (c *contract) DepositStake(ctx context.Context, stakedAmount *big.Int) (com
return common.Hash{}, err
}

receipt, err := c.sendDepositStakeTransaction(ctx, stakedAmount, c.overlayNonce)
receipt, err := c.sendManageStakeTransaction(ctx, stakedAmount)
if err != nil {
return common.Hash{}, err
}
Expand All @@ -127,14 +128,34 @@ func (c *contract) DepositStake(ctx context.Context, stakedAmount *big.Int) (com
// ChangeStakeOverlay only changes the overlay address used in the redistribution game.
func (c *contract) ChangeStakeOverlay(ctx context.Context, nonce common.Hash) (common.Hash, error) {
c.overlayNonce = nonce
receipt, err := c.sendDepositStakeTransaction(ctx, new(big.Int), c.overlayNonce)
receipt, err := c.sendManageStakeTransaction(ctx, new(big.Int))
if err != nil {
return common.Hash{}, err
}

return receipt.TxHash, nil
}

// UpdateHeight submits the reserve doubling height to the contract only if the height is a new value.
func (c *contract) UpdateHeight(ctx context.Context) (common.Hash, bool, error) {

h, err := c.getHeight(ctx)
if err != nil {
return common.Hash{}, false, fmt.Errorf("staking contract: failed to read previous height: %w", err)
}

if h == c.height {
return common.Hash{}, false, nil
}

receipt, err := c.sendManageStakeTransaction(ctx, new(big.Int))
if err != nil {
return common.Hash{}, false, fmt.Errorf("staking contract: failed to write new height: %w", err)
}

return receipt.TxHash, true, nil
}

func (c *contract) GetPotentialStake(ctx context.Context) (*big.Int, error) {
stakedAmount, err := c.getPotentialStake(ctx)
if err != nil {
Expand Down Expand Up @@ -295,8 +316,8 @@ func (c *contract) sendTransaction(ctx context.Context, callData []byte, desc st
return receipt, nil
}

func (c *contract) sendDepositStakeTransaction(ctx context.Context, stakedAmount *big.Int, nonce common.Hash) (*types.Receipt, error) {
callData, err := c.stakingContractABI.Pack("manageStake", nonce, stakedAmount, c.height)
func (c *contract) sendManageStakeTransaction(ctx context.Context, stakedAmount *big.Int) (*types.Receipt, error) {
callData, err := c.stakingContractABI.Pack("manageStake", c.overlayNonce, stakedAmount, c.height)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -442,3 +463,28 @@ func (c *contract) paused(ctx context.Context) (bool, error) {

return results[0].(bool), nil
}

func (c *contract) getHeight(ctx context.Context) (uint8, error) {
callData, err := c.stakingContractABI.Pack("heightOfAddress", c.owner)
if err != nil {
return 0, err
}

result, err := c.transactionService.Call(ctx, &transaction.TxRequest{
To: &c.stakingContractAddress,
Data: callData,
})
if err != nil {
return 0, err
}
results, err := c.stakingContractABI.Unpack("heightOfAddress", result)
if err != nil {
return 0, err
}

if len(results) == 0 {
return 0, errors.New("unexpected empty results")
}

return results[0].(uint8), nil
}
Loading

0 comments on commit eb0a89d

Please sign in to comment.