Skip to content

Commit

Permalink
Merge pull request #4049 from ElrondNetwork/fix-waiting-list-tests
Browse files Browse the repository at this point in the history
Fix adding keys to waiting list in tests setup
  • Loading branch information
mariusmihaic committed May 4, 2022
2 parents 97275d1 + a3bbea0 commit 29a59c4
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 99 deletions.
4 changes: 2 additions & 2 deletions epochStart/metachain/systemSCs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ func prepareStakingContractWithData(
ownerAddress []byte,
) {
stakingcommon.AddStakingData(accountsDB, ownerAddress, rewardAddress, [][]byte{stakedKey}, marshalizer)
stakingcommon.SaveOneKeyToWaitingList(accountsDB, waitingKey, marshalizer, rewardAddress, ownerAddress)
stakingcommon.AddKeysToWaitingList(accountsDB, [][]byte{waitingKey}, marshalizer, rewardAddress, ownerAddress)
stakingcommon.AddValidatorData(accountsDB, rewardAddress, [][]byte{stakedKey, waitingKey}, big.NewInt(10000000000), marshalizer)

_, err := accountsDB.Commit()
Expand Down Expand Up @@ -1650,7 +1650,7 @@ func TestSystemSCProcessor_ProcessSystemSmartContractJailAndUnStake(t *testing.T
[][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3")},
args.Marshalizer,
)
stakingcommon.SaveOneKeyToWaitingList(args.UserAccountsDB, []byte("waitingPubKey"), args.Marshalizer, []byte("ownerKey"), []byte("ownerKey"))
stakingcommon.AddKeysToWaitingList(args.UserAccountsDB, [][]byte{[]byte("waitingPubKey")}, args.Marshalizer, []byte("ownerKey"), []byte("ownerKey"))
stakingcommon.AddValidatorData(args.UserAccountsDB, []byte("ownerKey"), [][]byte{[]byte("stakedPubKey0"), []byte("stakedPubKey1"), []byte("stakedPubKey2"), []byte("stakedPubKey3"), []byte("waitingPubKey")}, big.NewInt(0), args.Marshalizer)
_, _ = args.UserAccountsDB.Commit()

Expand Down
33 changes: 4 additions & 29 deletions integrationTests/vm/staking/stakingQueue.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,14 @@ func createStakingQueue(
ownerWaitingNodes = append(ownerWaitingNodes, generateAddress(i))
}

// We need to save one key and then add keys to waiting list because there is a bug in those functions
// TODO: FIX bug in testscommon.AddKeysToWaitingList to also init staking queue if there are no keys in list
stakingcommon.SaveOneKeyToWaitingList(
stakingcommon.AddKeysToWaitingList(
accountsAdapter,
ownerWaitingNodes[0],
ownerWaitingNodes,
marshaller,
owner,
owner,
)
if numOfNodesInStakingQueue > 1 {
stakingcommon.AddKeysToWaitingList(
accountsAdapter,
ownerWaitingNodes[1:],
marshaller,
owner,
owner,
)
}

stakingcommon.AddValidatorData(
accountsAdapter,
owner,
Expand Down Expand Up @@ -83,7 +73,7 @@ func (tmp *TestMetaProcessor) getWaitingListKeys() [][]byte {
for len(nextKey) != 0 && index <= waitingList.Length {
allPubKeys = append(allPubKeys, nextKey)

element, errGet := tmp.getWaitingListElement(stakingSCAcc, nextKey)
element, errGet := stakingcommon.GetWaitingListElement(stakingSCAcc, tmp.Marshaller, nextKey)
if errGet != nil {
return nil
}
Expand All @@ -97,18 +87,3 @@ func (tmp *TestMetaProcessor) getWaitingListKeys() [][]byte {
}
return allPubKeys
}

func (tmp *TestMetaProcessor) getWaitingListElement(stakingSCAcc state.UserAccountHandler, key []byte) (*systemSmartContracts.ElementInList, error) {
marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue(key)
if len(marshaledData) == 0 {
return nil, vm.ErrElementNotFound
}

element := &systemSmartContracts.ElementInList{}
err := tmp.Marshaller.Unmarshal(element, marshaledData)
if err != nil {
return nil, err
}

return element, nil
}
149 changes: 81 additions & 68 deletions testscommon/stakingcommon/stakingCommon.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,115 +87,128 @@ func AddStakingData(
func AddKeysToWaitingList(
accountsDB state.AccountsAdapter,
waitingKeys [][]byte,
marshalizer marshal.Marshalizer,
marshaller marshal.Marshalizer,
rewardAddress []byte,
ownerAddress []byte,
) {
stakingSCAcc := LoadUserAccount(accountsDB, vm.StakingSCAddress)

for _, waitingKey := range waitingKeys {
stakedData := &systemSmartContracts.StakedDataV2_0{
Waiting: true,
RewardAddress: rewardAddress,
OwnerAddress: ownerAddress,
StakeValue: big.NewInt(100),
}
marshaledData, _ := marshalizer.Marshal(stakedData)
_ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKey, marshaledData)
if len(waitingKeys) == 0 {
return
}

marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList"))
waitingListHead := &systemSmartContracts.WaitingList{}
_ = marshalizer.Unmarshal(waitingListHead, marshaledData)

waitingListAlreadyHasElements := waitingListHead.Length > 0
waitingListLastKeyBeforeAddingNewKeys := waitingListHead.LastKey

waitingListHead.Length += uint32(len(waitingKeys))
lastKeyInList := []byte("w_" + string(waitingKeys[len(waitingKeys)-1]))
waitingListHead.LastKey = lastKeyInList

marshaledData, _ = marshalizer.Marshal(waitingListHead)
_ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData)
stakingSCAcc := LoadUserAccount(accountsDB, vm.StakingSCAddress)
waitingList := getWaitingList(stakingSCAcc, marshaller)

waitingListAlreadyHasElements := waitingList.Length > 0
waitingListLastKeyBeforeAddingNewKeys := waitingList.LastKey
previousKey := waitingList.LastKey
if !waitingListAlreadyHasElements {
waitingList.FirstKey = getPrefixedWaitingKey(waitingKeys[0])
previousKey = waitingList.FirstKey
}

numWaitingKeys := len(waitingKeys)
previousKey := waitingListHead.LastKey
for i, waitingKey := range waitingKeys {
waitingList.LastKey = getPrefixedWaitingKey(waitingKeys[numWaitingKeys-1])
waitingList.Length += uint32(numWaitingKeys)
saveWaitingList(stakingSCAcc, marshaller, waitingList)

waitingKeyInList := []byte("w_" + string(waitingKey))
for i, waitingKey := range waitingKeys {
waitingListElement := &systemSmartContracts.ElementInList{
BLSPublicKey: waitingKey,
PreviousKey: previousKey,
NextKey: make([]byte, 0),
}

if i < numWaitingKeys-1 {
nextKey := []byte("w_" + string(waitingKeys[i+1]))
nextKey := getPrefixedWaitingKey(waitingKeys[i+1])
waitingListElement.NextKey = nextKey
}

marshaledData, _ = marshalizer.Marshal(waitingListElement)
_ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData)
prefixedWaitingKey := getPrefixedWaitingKey(waitingKey)
saveStakedWaitingKey(stakingSCAcc, marshaller, rewardAddress, ownerAddress, waitingKey)
saveElemInList(stakingSCAcc, marshaller, waitingListElement, prefixedWaitingKey)

previousKey = waitingKeyInList
previousKey = prefixedWaitingKey
}

if waitingListAlreadyHasElements {
marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListLastKeyBeforeAddingNewKeys)
} else {
marshaledData, _ = stakingSCAcc.DataTrieTracker().RetrieveValue(waitingListHead.FirstKey)
lastElem, _ := GetWaitingListElement(stakingSCAcc, marshaller, waitingListLastKeyBeforeAddingNewKeys)
lastElem.NextKey = getPrefixedWaitingKey(waitingKeys[0])
saveElemInList(stakingSCAcc, marshaller, lastElem, waitingListLastKeyBeforeAddingNewKeys)
}

waitingListElement := &systemSmartContracts.ElementInList{}
_ = marshalizer.Unmarshal(waitingListElement, marshaledData)
waitingListElement.NextKey = []byte("w_" + string(waitingKeys[0]))
marshaledData, _ = marshalizer.Marshal(waitingListElement)
_ = accountsDB.SaveAccount(stakingSCAcc)
}

if waitingListAlreadyHasElements {
_ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListLastKeyBeforeAddingNewKeys, marshaledData)
} else {
_ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingListHead.FirstKey, marshaledData)
}
func getWaitingList(
stakingSCAcc state.UserAccountHandler,
marshaller marshal.Marshalizer,
) *systemSmartContracts.WaitingList {
marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue([]byte("waitingList"))
waitingList := &systemSmartContracts.WaitingList{}
_ = marshaller.Unmarshal(waitingList, marshaledData)

_ = accountsDB.SaveAccount(stakingSCAcc)
return waitingList
}

// SaveOneKeyToWaitingList will add one bls key with its associated owner in the staking queue list
func SaveOneKeyToWaitingList(
accountsDB state.AccountsAdapter,
waitingKey []byte,
marshalizer marshal.Marshalizer,
func saveWaitingList(
stakingSCAcc state.UserAccountHandler,
marshaller marshal.Marshalizer,
waitingList *systemSmartContracts.WaitingList,
) {
marshaledData, _ := marshaller.Marshal(waitingList)
_ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData)
}

func getPrefixedWaitingKey(key []byte) []byte {
return []byte("w_" + string(key))
}

func saveStakedWaitingKey(
stakingSCAcc state.UserAccountHandler,
marshaller marshal.Marshalizer,
rewardAddress []byte,
ownerAddress []byte,
key []byte,
) {
stakingSCAcc := LoadUserAccount(accountsDB, vm.StakingSCAddress)
stakedData := &systemSmartContracts.StakedDataV2_0{
Waiting: true,
RewardAddress: rewardAddress,
OwnerAddress: ownerAddress,
StakeValue: big.NewInt(100),
}
marshaledData, _ := marshalizer.Marshal(stakedData)
_ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKey, marshaledData)

waitingKeyInList := []byte("w_" + string(waitingKey))
waitingListHead := &systemSmartContracts.WaitingList{
FirstKey: waitingKeyInList,
LastKey: waitingKeyInList,
Length: 1,

marshaledData, _ := marshaller.Marshal(stakedData)
_ = stakingSCAcc.DataTrieTracker().SaveKeyValue(key, marshaledData)
}

func saveElemInList(
stakingSCAcc state.UserAccountHandler,
marshaller marshal.Marshalizer,
elem *systemSmartContracts.ElementInList,
key []byte,
) {
marshaledData, _ := marshaller.Marshal(elem)
_ = stakingSCAcc.DataTrieTracker().SaveKeyValue(key, marshaledData)
}

// GetWaitingListElement returns the element in waiting list saved at the provided key
func GetWaitingListElement(
stakingSCAcc state.UserAccountHandler,
marshaller marshal.Marshalizer,
key []byte,
) (*systemSmartContracts.ElementInList, error) {
marshaledData, _ := stakingSCAcc.DataTrieTracker().RetrieveValue(key)
if len(marshaledData) == 0 {
return nil, vm.ErrElementNotFound
}
marshaledData, _ = marshalizer.Marshal(waitingListHead)
_ = stakingSCAcc.DataTrieTracker().SaveKeyValue([]byte("waitingList"), marshaledData)

waitingListElement := &systemSmartContracts.ElementInList{
BLSPublicKey: waitingKey,
PreviousKey: waitingKeyInList,
NextKey: make([]byte, 0),
element := &systemSmartContracts.ElementInList{}
err := marshaller.Unmarshal(element, marshaledData)
if err != nil {
return nil, err
}
marshaledData, _ = marshalizer.Marshal(waitingListElement)
_ = stakingSCAcc.DataTrieTracker().SaveKeyValue(waitingKeyInList, marshaledData)

_ = accountsDB.SaveAccount(stakingSCAcc)
return element, nil
}

// LoadUserAccount returns address's state.UserAccountHandler from the provided db
Expand Down

0 comments on commit 29a59c4

Please sign in to comment.