Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Cudos partial balance and delegations movement #387

Merged
merged 5 commits into from
Oct 9, 2024

Conversation

MissingNO57
Copy link
Contributor

Proposed Changes

[describe the changes here...]

Linked Issues

[if applicable, add links to issues resolved by this PR]

Types of changes

What type of change does this pull request make (put an x in the boxes that apply)?

  • Bug fix (non-breaking change that fixes an issue).
  • New feature added (non-breaking change that adds functionality).
  • Breaking change (fix or feature that would cause existing functionality to stop working as expected).
  • Documentation update.
  • Something else (e.g., tests, scripts, example, deployment, infrastructure).

Checklist

Put an x in the boxes that apply:

  • I have read the CONTRIBUTING guide
  • Checks and tests pass locally

If applicable

  • I have added tests that prove my fix is effective or that my feature works
  • I have checked that code coverage does not decrease
  • I have added/updated the documentation

Further comments

[if this is a relatively large or complex change, kick off a discussion by explaining why you chose the solution you did, what alternatives you considered, etc...]

return bondDenom, nil
}

func parseGenesisData(app *App, ctx sdk.Context, jsonData map[string]interface{}, genDoc *tmtypes.GenesisDoc, cudosCfg *CudosMergeConfig, manifest *UpgradeManifest) (*GenesisData, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the motivation behind this changing passing from by-pointer to by-value? Was it attempt to disable theoreticall possibility of accidental modification of ctx instance value?

The sdk.Context is quite big structure, from performance perspective it would make sense to keep passibg by-pointer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was just unification with other functions. I can unify it to convert everything to pointer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually some CosmoSDK function expects sdk.Context instead of *sdk.Context for example GetValidator(ctx sdk.Context

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically all CosmosSDK functions require sdk.Context, looks like this is intended way of passing.

Comment on lines +1082 to +1090
func convertAmount(app *App, ctx sdk.Context, genesisData *GenesisData, amount sdk.Int, cudosCfg *CudosMergeConfig) (sdk.Int, error) {
balance := sdk.NewCoins(sdk.NewCoin(genesisData.bondDenom, amount))
convertedBalance, err := convertBalance(app, ctx, balance, cudosCfg)
if err != nil {
return sdk.ZeroInt(), err
}
return convertedBalance.AmountOf(app.StakingKeeper.BondDenom(ctx)), nil

}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit pick: Performance wise, this is quite hoop (it is called in the 2nd nested for loop. But I do see that it iwas obviously the easiest solution to achive what is necessary.

srcCoins := sourceDelegations.MustGet(validatorAddr)
sourceDelegations, exists := genesisData.delegations.Get(fromDelegatorAddress)
if !exists {
return fmt.Errorf("genesis source delegations of %s not found", fromDelegatorAddress)
Copy link
Collaborator

@pbukva pbukva Oct 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It kind of feels like this should not be an error case, but simply a valid case for doing nothing = simple success return from the function.

Suggested change
return fmt.Errorf("genesis source delegations of %s not found", fromDelegatorAddress)
return nil

Though I see, the philosophical bent here - function is implemented the way that it is expected to be called with valid delegator & validator & amount delegation tripplet, and is expected to fail if any of these do not checkout against the situation on the ground ...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore the comment above, it is the philosophical bent - I checked as how the function is used

destDelegation.Set(validatorAddr, destCoins.Add(srcCoins...))
sourceAmount, exists := sourceDelegations.Get(validatorAddress)
if !exists {
return fmt.Errorf("genesis source delegation of %s to specific validator %s not found", fromDelegatorAddress, validatorAddress)
Copy link
Collaborator

@pbukva pbukva Oct 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Analogical to this comment.

Though my sensation of valid philosophical bent here is starting to grow.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore above, see here.


if delegatedAmount.GT(remainingAmountToMove) {
if delegatedAmount.GTE(remainingAmountToMove) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be GT(...) rather than GTE(...), as it was riginally?

Comment on lines +85 to +104
func (om *OrderedMap[K, V]) GetOrSetDefault(key K, defaultValue V) (V, bool) {
if value, exists := om.Get(key); exists {
return value, false
} else {
om.Set(key, defaultValue)
return om.MustGet(key), true
}
}

// Iterate returns a channel that yields key-value pairs in insertion order
func (om *OrderedMap[K, V]) Iterate() <-chan Pair[K, V] {
ch := make(chan Pair[K, V])
go func() {
for _, key := range om.keys {
ch <- Pair[K, V]{Key: key, Value: om.MustGet(key)}
}
close(ch)
}()
return ch
}
Copy link
Collaborator

@pbukva pbukva Oct 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep in mind that this solution does a lot of shuffling data through the tread safe queueue (most probably using mutex) - internally the channel is implemented effectivelly as a thread safe queue.

This involves literally copying value of every single element of a collection the iteration goes through in to the channel (in this case copying every single Pair[K, V] value) over to channel queue ...

Looking at this solely from the performance perspective, it is not worth it.
👉 Though I do understand, that given the resulting performance impact in our use case, it is practivally irrelevant + this approach makes code more lean and so more readable ...

Copy link
Collaborator

@pbukva pbukva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@MissingNO57 MissingNO57 merged commit 8872709 into feat/cudos_merge Oct 9, 2024
1 check passed
@MissingNO57 MissingNO57 deleted the feat/cudos_partial_balance_movement branch October 9, 2024 14:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants