Skip to content

Commit

Permalink
delegation manager tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sasurobert committed Oct 3, 2024
1 parent 9c31b53 commit afd0639
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 7 deletions.
21 changes: 15 additions & 6 deletions vm/systemSmartContracts/delegationManager.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

const delegationManagementKey = "delegationManagement"
const delegationContractsList = "delegationContracts"
const maxAmountLength = 32

var nextAddressAdd = big.NewInt(1 << 24)

Expand Down Expand Up @@ -158,7 +159,7 @@ func (d *delegationManager) Execute(args *vmcommon.ContractCallInput) vmcommon.R
return d.claimMulti(args)
case "reDelegateMulti":
return d.reDelegateMulti(args)
case "changeProvider":
case "changeStakingProvider":
return d.changeStakingProvider(args)
}

Expand Down Expand Up @@ -567,7 +568,7 @@ func (d *delegationManager) changeStakingProvider(args *vmcommon.ContractCallInp
err := d.eei.UseGas(d.gasCost.MetaChainSystemSCsCost.DelegationOps)
if err != nil {
d.eei.AddReturnMessage(err.Error())
return vmcommon.UserError
return vmcommon.OutOfGas
}

amount := args.Arguments[0]
Expand All @@ -578,8 +579,16 @@ func (d *delegationManager) changeStakingProvider(args *vmcommon.ContractCallInp
d.eei.AddReturnMessage("input argument missmatch, not an address")
return vmcommon.UserError
}
if bytes.Equal(delegationAddrA, delegationAddrB) {
d.eei.AddReturnMessage("invalid addresses, they are equal")
return vmcommon.UserError
}
if len(amount) > maxAmountLength {
d.eei.AddReturnMessage("invalid amount, too long")
return vmcommon.UserError
}

// step 1
// step 1 - remove delegation from source SP
removeDelegation := []byte("removeDelegationFromSource@" + hex.EncodeToString(args.CallerAddr) + "@" + hex.EncodeToString(amount))
vmOutput, err := d.eei.ExecuteOnDestContext(delegationAddrA, args.RecipientAddr, big.NewInt(0), removeDelegation)
if err != nil {
Expand All @@ -590,7 +599,7 @@ func (d *delegationManager) changeStakingProvider(args *vmcommon.ContractCallInp
return vmOutput.ReturnCode
}

// step 2
// step 2 - add delegation to destination SP
moveDelegation := []byte("moveDelegationToDestination@" + hex.EncodeToString(args.CallerAddr) + "@" + hex.EncodeToString(amount))
vmOutput, err = d.eei.ExecuteOnDestContext(delegationAddrB, args.RecipientAddr, big.NewInt(0), moveDelegation)
if err != nil {
Expand All @@ -601,8 +610,8 @@ func (d *delegationManager) changeStakingProvider(args *vmcommon.ContractCallInp
return vmOutput.ReturnCode
}

// step 3
moveStake := []byte("moveDelegationToDestination@" + hex.EncodeToString(amount) +
// step 3 - move funds internally in the validator SC between the 2 SPs
moveStake := []byte("moveStakeFromValidatorToValidator@" + hex.EncodeToString(amount) +
"@" + hex.EncodeToString(delegationAddrA) + "@" + hex.EncodeToString(delegationAddrB))
vmOutput, err = d.eei.ExecuteOnDestContext(d.validatorSCAddr, args.RecipientAddr, big.NewInt(0), moveStake)
if err != nil {
Expand Down
121 changes: 120 additions & 1 deletion vm/systemSmartContracts/delegationManager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ func createMockArgumentsForDelegationManager() ArgsNewDelegationManager {
ConfigChangeAddress: configChangeAddress,
GasCost: vm.GasCost{MetaChainSystemSCsCost: vm.MetaChainSystemSCsCost{ESDTIssue: 10}},
Marshalizer: &mock.MarshalizerMock{},
EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.DelegationManagerFlag, common.ValidatorToDelegationFlag, common.MultiClaimOnDelegationFlag),
EnableEpochsHandler: enableEpochsHandlerMock.NewEnableEpochsHandlerStub(
common.DelegationManagerFlag,
common.ValidatorToDelegationFlag,
common.MultiClaimOnDelegationFlag,
common.DelegationImprovementsV3Flag),
}
}

Expand Down Expand Up @@ -1298,3 +1302,118 @@ func TestDelegationManager_CorrectOwnerOnAccount(t *testing.T) {
assert.True(t, updateCalled)
})
}

func TestDelegationManagerSystemSC_ChangeStakingProvider(t *testing.T) {
t.Parallel()

d, eei := createTestEEIAndDelegationFormMergeValidator()
_ = prepareVmInputContextAndDelegationManager(d, eei)

removeDelegationShouldFail := true
moveDelegationToDestinationShouldFail := true
moveStakeFromValidatorToValidatorShouldFail := true

_ = eei.SetSystemSCContainer(
&mock.SystemSCContainerStub{
GetCalled: func(key []byte) (vm.SystemSmartContract, error) {
return &mock.SystemSCStub{
ExecuteCalled: func(args *vmcommon.ContractCallInput) vmcommon.ReturnCode {
switch args.Function {
case "removeDelegationFromSource":
if removeDelegationShouldFail {
d.eei.AddReturnMessage("remove delegation from source failed")
return vmcommon.UserError
}
return vmcommon.Ok
case "moveDelegationToDestination":
if moveDelegationToDestinationShouldFail {
d.eei.AddReturnMessage("move delegation to destination failed")
return vmcommon.UserError
}
return vmcommon.Ok
case "moveStakeFromValidatorToValidator":
if moveStakeFromValidatorToValidatorShouldFail {
d.eei.AddReturnMessage("move stake from validator to validator failed")
return vmcommon.UserError
}
return vmcommon.Ok
}
return vmcommon.FunctionNotFound
},
}, nil
}})

vmInput := getDefaultVmInputForDelegationManager("changeStakingProvider", [][]byte{})
vmInput.CallerAddr = bytes.Repeat([]byte{1}, 32)
vmInput.RecipientAddr = vm.DelegationManagerSCAddress
vmInput.Arguments = [][]byte{bytes.Repeat([]byte{2}, 32), bytes.Repeat([]byte{3}, 32)}

enableEpochsHandler, _ := d.enableEpochsHandler.(*enableEpochsHandlerMock.EnableEpochsHandlerStub)
enableEpochsHandler.RemoveActiveFlags(common.DelegationImprovementsV3Flag)

returnCode := d.Execute(vmInput)
require.Equal(t, vmcommon.UserError, returnCode)
require.Equal(t, eei.returnMessage, "invalid function to call")

enableEpochsHandler.AddActiveFlags(common.DelegationImprovementsV3Flag)
eei.returnMessage = ""

returnCode = d.Execute(vmInput)
require.Equal(t, vmcommon.UserError, returnCode)
require.Equal(t, eei.returnMessage, vm.ErrInvalidNumOfArguments.Error())

eei.returnMessage = ""
vmInput.Arguments = append(vmInput.Arguments, []byte{})
eei.gasRemaining = 0
d.gasCost.MetaChainSystemSCsCost.DelegationOps = 1

returnCode = d.Execute(vmInput)
require.Equal(t, vmcommon.OutOfGas, returnCode)
require.Equal(t, eei.returnMessage, vm.ErrNotEnoughGas.Error())

eei.gasRemaining = 10
eei.returnMessage = ""

returnCode = d.Execute(vmInput)
require.Equal(t, vmcommon.UserError, returnCode)
require.Equal(t, eei.returnMessage, "input argument missmatch, not an address")

eei.returnMessage = ""
vmInput.Arguments[1] = vm.FirstDelegationSCAddress
vmInput.Arguments[2] = vm.FirstDelegationSCAddress

returnCode = d.Execute(vmInput)
require.Equal(t, vmcommon.UserError, returnCode)
require.Equal(t, eei.returnMessage, "invalid addresses, they are equal")

eei.returnMessage = ""
vmInput.Arguments[0] = bytes.Repeat([]byte{3}, 33)
vmInput.Arguments[1] = vm.FirstDelegationSCAddress
vmInput.Arguments[2] = createNewAddress(vm.FirstDelegationSCAddress)

returnCode = d.Execute(vmInput)
require.Equal(t, vmcommon.UserError, returnCode)
require.Equal(t, eei.returnMessage, "invalid amount, too long")

eei.returnMessage = ""
vmInput.Arguments[0] = big.NewInt(100).Bytes()
returnCode = d.Execute(vmInput)
require.Equal(t, vmcommon.UserError, returnCode)
require.Equal(t, eei.returnMessage, "remove delegation from source failed")

eei.returnMessage = ""
removeDelegationShouldFail = false
returnCode = d.Execute(vmInput)
require.Equal(t, vmcommon.UserError, returnCode)
require.Equal(t, eei.returnMessage, "move delegation to destination failed")

eei.returnMessage = ""
moveDelegationToDestinationShouldFail = false
returnCode = d.Execute(vmInput)
require.Equal(t, vmcommon.UserError, returnCode)
require.Equal(t, eei.returnMessage, "move stake from validator to validator failed")

moveStakeFromValidatorToValidatorShouldFail = false
returnCode = d.Execute(vmInput)
require.Equal(t, vmcommon.Ok, returnCode)
}

0 comments on commit afd0639

Please sign in to comment.