diff --git a/core/state_transition.go b/core/state_transition.go index 577612125..c65536fdb 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -394,7 +394,6 @@ func (st *StateTransition) applyDelegateTx(delegate *staking.Delegate) error { // Firstly use the tokens in undelegation to delegate (redelegate) undelegateAmount := big.NewInt(0).Set(delegate.Amount) // Use the latest undelegated token first as it has the longest remaining locking time. - // TODO: always order the list by epoch. i := len(delegation.Entries) - 1 for ; i >= 0; i-- { if delegation.Entries[i].Amount.Cmp(undelegateAmount) <= 0 { diff --git a/internal/chain/engine.go b/internal/chain/engine.go index b1092d654..ee6bc7289 100644 --- a/internal/chain/engine.go +++ b/internal/chain/engine.go @@ -187,7 +187,6 @@ func (e *engineImpl) Finalize( delegation := wrapper.Delegations[i] totalWithdraw := big.NewInt(0) count := 0 - // TODO: need ot make sure the entries are ordered by epoch for j := range delegation.Entries { if delegation.Entries[j].Epoch.Cmp(header.Epoch()) > 14 { // need to wait at least 14 epochs to withdraw; totalWithdraw.Add(totalWithdraw, delegation.Entries[j].Amount) diff --git a/staking/types/delegation.go b/staking/types/delegation.go index f9fa710f4..8844e02be 100644 --- a/staking/types/delegation.go +++ b/staking/types/delegation.go @@ -3,6 +3,7 @@ package types import ( "errors" "math/big" + "sort" "github.com/ethereum/go-ethereum/common" ) @@ -59,7 +60,14 @@ func (d *Delegation) Undelegate(epoch *big.Int, amt *big.Int) error { if !exist { item := UndelegationEntry{amt, epoch} d.Entries = append(d.Entries, &item) + + // Always sort the undelegate by epoch in increasing order + sort.SliceStable( + d.Entries, + func(i, j int) bool { return d.Entries[i].Epoch.Cmp(d.Entries[j].Epoch) < 0 }, + ) } + return nil }