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

Add msg_server methods #1923

Merged
merged 24 commits into from
Nov 13, 2024
Merged

Add msg_server methods #1923

merged 24 commits into from
Nov 13, 2024

Conversation

mj850
Copy link
Contributor

@mj850 mj850 commented Nov 7, 2024

Describe your changes and provide context

Adds server side logic to msg_server, as well as sets up the module account so this module can send and receive tokens.

Testing performed to validate your change

Writing msg_sever_tests right now.

x/confidentialtransfers/keeper/msg_server.go Outdated Show resolved Hide resolved
// Store the account
m.Keeper.SetAccount(ctx, address, req.Denom, account)

ctx.EventManager().EmitEvents(sdk.Events{
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like EmitTypedEvents can be used instead, since EmitEvents is deprecated

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Going to add a todo to look into this a bit later

sdk.NewEvent(
types.EventTypeInitializeAccount,
sdk.NewAttribute(types.AttributeDenom, instruction.Denom),
sdk.NewAttribute(types.AttributeAddress, instruction.FromAddress),
Copy link
Contributor

Choose a reason for hiding this comment

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

There probably could be several events like this for single account, which may look all the same for indexer. Adding public key might help to distinguish between them

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm this particular event is specific to the denom and address so I think we should be good! Pubkey generation is deterministic actually so even if the user closes and reinitializes their account here, it should be the same pubkey

Copy link
Contributor

Choose a reason for hiding this comment

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

Never mind, I think denom makes it unique

}

// Check if the account exists
address, err := sdk.AccAddressFromBech32(req.FromAddress)
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like checking address and returning account is logic that is repeated (and could be extracted into seperate method and re-used)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refactored the keeper methods (get, set and delete accounts) to take in address as a string instead and try to perform this conversion, since the only place that needs this sdkAccAddress is the keeper for now.

// Convert the instruction to proto. This also validates the request.
instruction, err := req.FromProto()
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid Msg")
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: general recommendation is to not capitalize error messages https://go.dev/wiki/CodeReviewComments#error-strings

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense, uncapitalized all the error messages in msg, zk and msg_server


// Split the deposit amount into lo and hi bits.
// Extract the bottom 16 bits (rightmost 16 bits)
bottom16 := uint16(req.Amount & 0xFFFF)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we could follow the PoC approach and have a split logic in a separate method. May simplify testing of it as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a utils package in the module for stuff like this. There's probably 1 or 2 other commonly used things I can add there when I think of them

return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid Msg")
}

// Verify that the account has sufficient funds (Remaining balance after making the transfer is greater than or equal to zero.)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: let's try to keep the line size within 120 chars


// Return the tokens to the sender
coins := sdk.NewCoins(sdk.NewCoin(instruction.Denom, sdk.NewIntFromUint64(instruction.Amount)))
if err := m.Keeper.SendTokens(ctx, address, coins); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

Out of scope for this method, but curious, how do we prevent funds in module address to not be sent anywhere, say other module address.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmmm haven't thought about that. Is this an issue that we need to be aware of?

// Get the user's account
account, exists := m.Keeper.GetAccount(ctx, address, req.Denom)
if !exists {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Account does not exist")
Copy link
Contributor

Choose a reason for hiding this comment

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

There is also not found sdk error

ErrNotFound = Register(RootCodespace, 38, "not found")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense! Refactored all the account not found errors to ErrNotFound

return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Error summing balances")
}

zeroCiphertextLo, err := elgamal.SubtractCiphertext(account.PendingBalanceLo, account.PendingBalanceLo)
Copy link
Contributor

Choose a reason for hiding this comment

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

Curious, if we need to subtract balance from itself. Why not alternatively just encrypt 0? Can we store nil instead? Also curious if this can be a source of non-determinism

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We use subtraction here since Encryption is non deterministic (since it generates randomness), but subtraction is a deterministic operation.

From a confidentiality pov, It somewhat makes sense to store nil here since the pending balance counter will be set to 0 instead so everyone knows there are no pending balances in the account.
But from a implementation perspective I think its much easier to deal with accounts if we just assume the pending balances and available balances are always a ciphertext (don't have to check for nil, write special edge cases for when pending balance is nil etc, we can just perform arithmetic on the ciphertext)

@mj850 mj850 merged commit 27b032b into feature/ct_types Nov 13, 2024
22 of 27 checks passed
@mj850 mj850 deleted the mj/ctMod2 branch November 13, 2024 01:15
mj850 added a commit that referenced this pull request Dec 7, 2024
* new types

* add deposit to msgs

* add import issues

* revert evm/params to old state

* withdraw with tests

* small changes

* refactor and add tests

* comment

* refactor initialize type

* types

* non module account types

* msg server methods with module accounts

* tests scaffold

* add msg server tests

* codeql

* test issues

* test improvements

* comments

* todo

* app
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