0xPolygonMiden / miden-base

Core components of the Polygon Miden rollup
MIT License
73 stars 45 forks source link

Few clarifications/pointers for Miden Rollup and it's smart contract in general #525

Open nlok5923 opened 8 months ago

nlok5923 commented 8 months ago

Hey Guys!

I had a few suggestions and need clarifications on few features by Miden Rollup

View functionalities in miden smart contract

Child - Factory Mechanism

Miden compilation

Benchmarking

Gas Mechanism

gubloon commented 8 months ago

Thanks @nlok5923 we will reference these points through our feature developments.

For the first point, I would like to add the miden-client issue 204 as a reference if you have not read it already.

those are mostly with respect to accounts as per my understanding

Yes, we have to start on the features that are mainly centred with an account and work gradually towards other aspects of a smart contract. Like how we are looking at write functionalities, we can also have view functions.

bobbinth commented 8 months ago

View functionalities in miden smart contract

At the MASM level, all exported procedures are the same (i.e., there is no difference between view and non-view procedures). A single account can have up to 255 exported procedures, and it is pretty simple to add procedures to an account.

For example, the built-in Basic Wallet smart contract has the following code:

use.miden::contracts::wallets::basic->basic_wallet
use.miden::contracts::auth::basic->basic_auth

export.basic_wallet::receive_asset
export.basic_wallet::send_asset
export.basic_auth::auth_tx_rpo_falcon512

To add a custom procedure to it we could just append it to the account code file:

use.miden::contracts::wallets::basic->basic_wallet
use.miden::contracts::auth::basic->basic_auth

export.basic_wallet::receive_asset
export.basic_wallet::send_asset
export.basic_auth::auth_tx_rpo_falcon512

export.my_proc
    # code for new procedure goes here
end

Child - Factory Mechanism

I don't think we currently have something like this in Miden - i.e., accounts cannot directly invoke methods of other accounts (all interaction goes through the notes). What are the main benefits of having child-factory mechanism vs. just deploying accounts directly?

Miden compiler is still in development right now, Would love to understand can we design it in such a way that it should be able to compile any external rust library and compile a MASM contract for it. As that would be an amazing feature since all the pre-written rust crates could be directly used with miden smart contracts.

This is our goal as well (with some restrictions as to what can be compiled). There is heavy work ongoing for this in the compiler repo, and the initial version of this should be reading in the next several weeks.

Benchmarking

The plan is to have a rather low TPS for the initial testnet (e.g., ~2 TPS) and then scale this up to 100+ TPS by mainnet, and then get it to 1000+ TPS within a year after the mainnet launch. The long term goal is to be able to process 10K+ TPS.

One thing to mention: a single Miden transaction can consume and produces hundreds of notes. So, in some cases, what would take hundreds of transactions on other networks may take just one transaction on Miden.

Gas Mechanism

We don't have a fee model developed yet (we'll start working on this in a couple of months). As a very rough preview, the fee model will likely be mulit-dimensional. So, transaction fees would depend on:

nlok5923 commented 8 months ago

Thanks for all the above answers

What are the main benefits of having child-factory mechanism vs. just deploying accounts directly?

I think there are certain benefits of having such factory - child approach over directly deploying accounts.

Dominik1999 commented 8 months ago

Child - Factory

@bobbinth, we could add an account procedure to create new accounts, right? Especially, if we copy the public key and the authentication schema.

@nlok5923 do you need to clone contracts/accounts onchain? You could also have an account factory off-chain, e.g., in your frontend, that creates public accounts. Or what is the advantage of cloning accounts on-chain via a factory?

nlok5923 commented 8 months ago

@bobbinth, we could add an account procedure to create new accounts, right? Especially, if we copy the public key and the authentication schema.

Yes having this procedure would suffice ig.

@nlok5923 do you need to clone contracts/accounts onchain? You could also have an account factory off-chain, e.g., in your frontend, that creates public accounts. Or what is the advantage of cloning accounts on-chain via a factory?

I think having an offchain factory could work well in context of miden, Since miden allows to have offchain account state. For the canonical EVM blockchains i think having an onchain make more sense.

Dominik1999 commented 8 months ago

I mean, for Poker, you could create one Account per game, even in your front end.

We do have an "Account Factory" for standard accounts at https://github.com/0xPolygonMiden/miden-base/tree/main/miden-lib/src/accounts

But we can also do some more sophisticated techniques. Creating accounts on-chain might make it more decentralized. What do you think?

bobbinth commented 8 months ago

Contract upgradability: In a scenario where we are required to update the contracts getting deployed we can directly upgrade the singleton contract and proxies would follow the upgrade.

I see the convenience - but I think there is also a potential risk here: compromising a single parent contract would compromise all child contracts as well. So, in a way it creates a "honey pot".

Efficient deployment: I think deployment via factory offer more efficiency in deploying and managing child contracts.

I think this is an interesting point. It would be cool if instead of specifying all of the account code inside of an account, we would allow executing code defined in other accounts (still executed in the context of the current account though). Basically, this would enable something like "on-chain libraries" of code and lead to more compact public contracts.

@Dominik1999 - should we create an issue to think this trough?

nlok5923 commented 8 months ago

Another small doubt

I see there are three notes standard for now P2ID, P2IDR and SWAP.

I wanted to understand how can we tweak the P2ID standard such that instead of sending assets from one account to another we should be able change storage of recipient account (as evm analogy is making a authorised function calls which updates the state of the recipient account).

For my usecase what i need to do is i am trying to create and send a note from game account to player account (basic wallet for now) which contains information of which sets of cards are alloted to that particular player. Such that on consuming the note we will store the alloted cards information in the user defined storage of 256 words of player account.

Additionally, would love to get some feedback here. Whether is it the correct mental model to store player related state information in their account or i should store the mapping of alloted cards to the player account id in the game account itself ?

cc @Dominik1999 @gubloon @bobbinth

bobbinth commented 8 months ago

I wanted to understand how can we tweak the P2ID standard such that instead of sending assets from one account to another we should be able change storage of recipient account (as evm analogy is making a authorised function calls which updates the state of the recipient account).

For this to work, you'd need to do a couple of things:

  1. Add a procedure to the account interface which would be responsible for updating account storage when called (e.g., something like save_cards).
  2. Write a new note script (maybe using P2ID as a starting point) which would call the above procedure with relevant inputs.

One annoying thing is that right now every note must include at least one asset, which seems like something that is not very relevant to your use case. @Dominik1999 brought up previously changing the protocol to allow notes with no assets - so, we can create a feature request issue for this.

Additionally, would love to get some feedback here. Whether is it the correct mental model to store player related state information in their account or i should store the mapping of alloted cards to the player account id in the game account itself?

I think either should work - but I haven't thought through pros and cons of each. It seems like storing allotted cards in a single game account could be conceptually simpler - though it would be tricky to implement before #521 lands.

nlok5923 commented 8 months ago
  1. Add a procedure to the account interface which would be responsible for updating account storage when called (e.g., something like save_cards).

Isn't this is an issue, Like isn't their should be a standard account code for each user miden account ? And adding a new procedure would certainly work if we (dapp) are creating player accounts. But what if user wants to use their existing miden account ?

I think either should work - but I haven't thought through pros and cons of each. It seems like storing allotted cards in a single game account could be conceptually simpler - though it would be tricky to implement before #521 lands.

Won't maintaining a mapping in game account would enforce sequential consumption of notes ? Since all the notes would try to access the same storage slots and even consuming notes in batch might not help here ? Please do correct me if something is wrong here.

bobbinth commented 8 months ago

Isn't this is an issue, Like isn't their should be a standard account code for each user miden account ? And adding a new procedure would certainly work if we (dapp) are creating player accounts. But what if user wants to use their existing miden account ?

There is a very minimalistic standard account - BasicWallet, but users are free to add more functionality to their accounts (i.e., adding other procedures in addition to the ones provided by the basic wallet). Right now, this must be done at account creation time, but we will enable support for updatable accounts in the future. This way, the users will be able to add procedures to their accounts when they deem necessary.

I would say though that adding a public procedure to an account which enables modification of arbitrary storage slots is probably quite risky (e.g., this procedure could swap out the public key associated with the account) - so, I don't think it is a good idea to do this generically.

If the goal is for the user not to create new accounts (or modify existing accounts) - then I think the only solution is to have a game account which contains all the logic and users interact with it by sending notes to it (these could be custom notes issued from accounts via send_assets procedure).

Won't maintaining a mapping in game account would enforce sequential consumption of notes ? Since all the notes would try to access the same storage slots and even consuming notes in batch might not help here ? Please do correct me if something is wrong here.

I would need to understand the specifics of the design to answer this in detail - but in general, this doesn't have to be the case. Yes, the notes are executed sequentially, but depending on how the account interface and note scripts are defined, the sequence may be decided at various points in time after the notes are created.