spacemeshos / SMIPS

Spacemesh Improvement Proposals
https://spacemesh.io
Creative Commons Zero v1.0 Universal
7 stars 1 forks source link

Account Unification #49

Open lrettig opened 3 years ago

lrettig commented 3 years ago

Overview

We propose an account and transaction model that unifies all accounts into a single smart contract-based account type. Under this proposal, unlike Ethereum today, Spacemesh would have no "EOA" (externally owned account) or "simple", keypair-based account (which cannot contain code). This abstracts or encapsulates the logic that allows nodes to verify transactions (e.g., by ensuring that they have valid signatures and nonces) into smart contract logic as part of a special verify method. It means that this verification logic, like all smart contract execution logic, runs in the VM and may in theory be arbitrarily complex (although in practice it will be subject to certain restrictions to prevent denial of service and griefing attacks, and will be optimized).

We introduce a subclass of account known as a "Principal" account, so-called because it's able to act as a principal, or source of funds, in a transaction. (The user who generates, signs, and broadcasts the transaction acts as its agent.) The only difference between a Principal and non-Principal account is that a Principal account implements the verify method that is executed to verify transactions sent on its behalf, and is thus allowed to act as a source of funds, while a non-Principal account implements no such method and is forbidden from acting as a source of funds. (Equivalently, all accounts can be thought of as Principal accounts, but those that don't explicitly implement verify() instead have an implicit implementation that always returns false and may therefore never be used as a source of funds.)

EOAs are replaced by a "personal wallet" smart contract template with simple, cheap, sanctioned verification logic that is effectively identical to the existing verification logic.

For background reading, please see:

Goals and motivation

Tradeoffs/downsides/challenges

High-level design

Prior art

Proposed implementation

Transaction format

The specifics of transaction format are outside the scope of this proposal (see #23, #37). However, Account Unification requires that transactions contain at least the following fields:

State management and transaction ordering

An important invariant in both Spacemesh 0.1 and Ethereum is that no transaction that originates from sender A can invalidate a transaction from sender B (where A != B). This is due to the fact that a transaction can only be invalidated if the sender account balance is too low to pay the gas, or if the sender nonce doesn't match, and an account's balance can only decrease, and its nonce can only change, as a result of a transaction from the same account. Without this invariant, mempool management and transaction selection become much harder because transactions are more order-dependent: processing any transaction from any sender could invalidate any other transaction from any sender.

If we allow verify() to implement arbitrary logic, maintaining this invariant becomes much harder. We propose to start with restrictions on verify() in an initial phase and relax them somewhat in a later phase, pending further research.

Phase I: Stateless verify

In the first phase, verify() must be totally stateless. It may only read immutable state such as storage items set when the principal contract was initially deployed. It must not read state from any other contract (since the existence or non-existence of such state is possibly mutable).

Certain opcodes that read external state, such as BLOCKHASH, COINBASE, TIMESTAMP, NUMBER, DIFFICULTY, GASLIMIT, BALANCE, and those that perform external call/create/state access (CALL , CALLCODE, STATICCALL, CREATE, CREATE2, EXTCODESIZE, EXTCODEHASH, EXTCODECOPY, DELEGATECALL) are also disallowed.

Phase II: Limited access to state

Pending further research, in future it should be possible to relax the restrictions on verify() somewhat, along the following lines:

Level one vs. level two state

In order to verify a transaction with a given principal, a node must already read the principal account data from the trie, including its code and balance. If we think of this account data as occupying a single "page" of memory, for some fixed page size, then the additional work associated with reading a small amount of "level one" storage is negligible. Intuitively we can think of this "level one" storage as consisting of a small number of 256-bit storage values: enough to store a few signatures (for a multisig), a nonce, and possibly a per-signature daily spending key.

Under this scheme, verify() may read and write this level one state for its own account but may not read or write any other state.

Protected state

Under this scheme, the account storage of a Principal account is divided into two sections: Protected and Unprotected. Unprotected state may be read and modified by any method other than verify(). Protected state may only be modified by the verify() method, and the verify() method may only read Protected state. (Any method may read, but not write, Protected state.)

Note that we may decide to combine level one state and protected state.

Slow reads and writes

We introduce new opcodes for "slow" read and write of account storage. A slow write only takes effect at the next state checkpoint: typically, the following layer. A slow read returns the value as of the last checkpoint: typically, as of the previous layer. Under this scheme, verify() may perform slow reads and writes only, since they can never invalidate other transactions before the next checkpoint.

Questions

A: yes, see the description of self-funded spawn, above

A: we want both. CREATE will set the account address based solely on spawning transaction principal account and nonce. CREATE2 will instead use principal account, salt, and init code (see EIP-1014). This is orthogonal to Account Unification.

Dependencies and interactions

Implementation plan

Stakeholders and reviewers

Testing and performance

tbd

countvonzero commented 3 years ago

We introduce a subclass of account known as...

this doused my fire quite a bit. what you said later simplicity and elegance rings the most true to me. i wonder if we can lose the distinction by enforcing the account creator to decide whether verify() returns true/false. i.e. make verify() mandatory and forces the creator to explicitly decide if this account is to be a fee-paying account.

Unprotected state may be read and updated by any method. Protected state ...

i am confused by the wordings here. do you mean Unprotected state may be read and updated by any method but verify()?

opcodes that read external state, such as …, are also considered Unprotected state

maybe i am looking at this from the wrong perspective, i found the word unprotected counter intuitive here. it seems if verify() should not call these opcodes, they are protected... what do you think of using safe/unsafe. i.e. verify() can read/write safe state.

If the account balance is insufficient to cover the gas spent when PAYGAS is called, the transaction is invalidated.

assuming the order of execution is below:

----------------------------> PAYGAS ---------------------------->
   verification phase                          execution phase

under this proposal, it's unclear to me whether we charge any gas for verification phase. the wording here seems to imply yes. if that's true, it makes the name PAYGAS a little awkward, because one already pays gas before PAYGAS is reached. in this case, i think we should use a different name for the opcode, say VERIFIED, and it serves as a checkpoint. that way, we can just send SVM the calldata after VERIFIED if we decide to run verify() outside SVM. i recall in the case of ED++, the public key extraction (required outside SVM) has essentially done the job for verify() and therefore can be skipped for optimization.

the Ethereum proposal was that no gas paid until it reaches PAYGAS opcode. and if the execution during the verification phase exceeds the cap, the transaction is considered invalid.

if we are not charging gas for the verification phase, then i misunderstand your words. tho i actually like the idea of paying gas for the verification phase after the signature verifies. however small, it deters the DoS attack. since we are potentially instantiating a SVM for verify(), the cost of being spammed doesn't seem negligible to me.

possible exceptions of coinbase and reward transactions

i had assumed that rewards (mining or otherwise) will be done via internal transfer instead of official transactions

lrettig commented 3 years ago

i wonder if we can lose the distinction by enforcing the account creator to decide whether verify() returns true/false. i.e. make verify() mandatory and forces the creator to explicitly decide if this account is to be a fee-paying account.

I don't understand what you mean. The way we verify a transaction is by passing its verifydata to the verify() method of a Principal account. If the method returns true (and the gas and state rules aren't violated), the transaction is verified/validated. If it returns false, the transaction is invalidated. I think allowing smart contracts to implement this method or not, and allowing those that do implement it to act as Principals, is about as simple and elegant as we can get here, but of course I'm open to alternative ideas!

Unprotected state may be read and updated by any method. Protected state ...

i am confused by the wordings here. do you mean Unprotected state may be read and updated by any method but verify()?

Yes, you're right, I fixed this.

opcodes that read external state, such as …, are also considered Unprotected state

maybe i am looking at this from the wrong perspective, i found the word unprotected counter intuitive here. it seems if verify() should not call these opcodes, they are protected... what do you think of using safe/unsafe. i.e. verify() can read/write safe state.

The way I think about it, "protected" means "may only be set inside verify()."

under this proposal, it's unclear to me whether we charge any gas for verification phase. the wording here seems to imply yes... the Ethereum proposal was that no gas paid until it reaches PAYGAS opcode. and if the execution during the verification phase exceeds the cap, the transaction is considered invalid.

This is a bit counterintuitive, but by definition you cannot charge gas before PAYGAS because you haven't yet established the validity of the transaction in question, and invalid transactions by definition cannot pay gas. This is no different than how things work in Ethereum 1 or Spacemesh v0.1: if a simple transaction has an invalid signature, you still need to perform some computation in order to establish the validity, and if the signature is invalid, no one pays any gas for this computation.

I don't see a reason to deviate from the EIP-2938 design here:

The opcode works as follows. If all three of the following conditions (in addition to the version number check above) are satisfied:

The account’s balance is >= gas_price * gas_limit globals.transaction_fee_paid == False We are in a top-level AA execution frame (ie. if the currently running EVM execution exits or reverts, the EVM execution of the entire transaction is finished) Then do the following:

Subtract gas_price * gas_limit from the contract’s balance Set globals.transaction_fee_paid to True Set globals.gas_price to gas_price, and globals.gas_limit to gas_limit Set the remaining gas in the current execution context to equal gas_limit minus the gas that was already consumed If any of the above three conditions are not satisfied, throw an exception.

At the end of execution of an AA transaction, it is mandatory that globals.transaction_fee_paid == True; if it is not, then the transaction is invalid. At the end of execution, the contract is refunded globals.gas_price remaining_gas for any remaining gas, and (globals.gas_limit - remaining_gas) globals.gas_price is transferred to the miner.

PAYGAS also serves as an EVM execution checkpoint: if the top-level execution frame reverts after PAYGAS has been called, then the execution only reverts up to the point right after PAYGAS was called, and exits there. In that case, the contract receives no refund, and globals.gas_limit * globals.gas_price is transferred to the miner.

possible exceptions of coinbase and reward transactions

i had assumed that rewards (mining or otherwise) will be done via internal transfer instead of official transactions

We haven't finalized this design yet. That's why I said "possible" exception :)

countvonzero commented 3 years ago

I don't understand what you mean. The way we verify a transaction is by passing its verifydata to the verify() method of a Principal account. If the method returns true (and the gas and state rules aren't violated), the transaction is verified/validated. If it returns false, the transaction is invalidated. I think allowing smart contracts to implement this method or not, and allowing those that do implement it to act as Principals, is about as simple and elegant as we can get here, but of course I'm open to alternative ideas!

like we discussed during the R&D meeting, my end goal is uniform treatment in code and in future design. whether an account has verify()/nonce can be "compressed away" like Tal said, but they will appear homogeneous to devs/users.

This is a bit counterintuitive, but by definition you cannot charge gas before PAYGAS because you haven't yet established the validity of the transaction in question, and invalid transactions by definition cannot pay gas.

what threw me off was this sentence

If the account balance is insufficient to cover the gas spent when PAYGAS is called, the transaction is invalidated.

since gas spent when PAYGAS is called is supposed to be zero. so i had mistaken you to mean that we want to charge gas before PAYGAS. but what you really meant was we are going to charge the max gas upfront as soon as we hit PAYGAS, and then do refund later if necessary. just like the EIP.

avive commented 3 years ago

Q: regarding principal - let's consider this use case: Alice wants to transfer funds to Bob via an app that pays gas. You mentioned that the principal both pays gas and is the source of funds in the proposed design - so how is this use case going to be handled, or are we saying that Alice can't be the source of funds in a transaction where she's not the principal and only an agent? Another example - in a 2/3 vault which pays gas for its users, alice wants to move coin from her account to the vault...

avive commented 3 years ago

Q: I don't fully understand how the invariant discussed in verification can hold in this use case: both Alice and Bob send a transaction around the same time to the same app (e.g. a vault) to spend all of its coins, each transaction with a different payee. Only one of these transaction will executed and the other will throw an insufficient funds runtime exception. There's no way to validate these transactions without knowing the execution order of the STF and actually trying to execute these transactions in the agreed upon order. I think this is a simpler example than what Tal mentioned. I'm also not sure how the idea of parked balance is going to help in the use case I mentioned.

What tal proposes regarding only allowing 1 transaction to a smart contract that can reduce its balance, is quite problematic from usability perspective - popular smart contracts are going to be used frequently by many users, potentially hundreds or thousands of them around the same time. Also, smart contact methods may fail for different reasons based on execution order besides just contract coin balance going to 0. For example, contracts managing tokens, assets, etc... So it should not be about the benchmarks because we don't intend devs to implement Edwards point math in svm code. The benchmarks discussed should be the performance of the EC and crypto precompiled - our provided libs vs. native code.

avive commented 3 years ago

Q: what are concrete examples of verify() needing to write state? What use cases are not possible if verify() can not write state?

avive commented 3 years ago

Regarding iddo's 1st argument - in theory, signature checks via SVM should not be much more expensive because the actual computational work is going to be done in context library functions which should be implemented natively - so as long as a developer writes verify() that uses ed25519 scheme (or any other signature scheme we provide support to) there is no issue and the overhead is not in the core elliptical curve ops and should not be significant. As a bonus, with a tight gas limit on verify(), developers will not be able to implement signature verification which is not done efficiently by a core library at all. I think it is safe to assume that we are going to provide primitive hashing and signature scheme libs as svm libs which are optimized and native. We need to do so to make the svm development platform competitive. So tl;dr - you can't implement your own elliptical-curve math ops in verify() because you will go over the verify() gas limit but you can use our svm crypto libs for custom signature schemes. We can also add additional crypto libs to svm core via soft-forks with additional EC functions.

Regarding tal's argument about DoS using a smart contract that doesn't use a precompiles - the MAX_GAS on verify() addresses this attack scenario. It is not about pre-compiled contracts we approve, it is about providing a smart-contract EC and crypto libs which are natively compiled that developers use which are part of the runtime. For example, see the eth precompiles. Devs use these as building blocks for custom verification but can't implement EC low-level math in smart contracts. As a reference, here's a list of the precompiled eth methods - they are all computational extensive lib functions related to EC and crypto primitives. https://github.com/ethereum/go-ethereum/blob/bd6879ac518431174a490ba42f7e6e822dcb3ee1/core/vm/contracts.go#L51

avive commented 3 years ago

Regarding the idea to limit transactions per layer to a same contract - I don't like this idea. I think it is better the optimistically assume that some of them will work and just execute them in our pre-defined tx sorting order. There are going to be very popular smart contracts and limiting throughput to a small number of txs per layer is very problematic from the user experience perspective. I think there is no way good way around the issue that you can't tell whether a smart contract transaction is 'valid' without executing all the transactions to the contract in a layer and that we should work under this assumption. I think this is inherent to the state-full smart contracts computation model. The assumptions that this can be done needs to be revisited.

avive commented 3 years ago

A note regarding the discussion about state changes and transactions - there is no need for transactions which do not modify state - for this there's an API that reads apps and account state and we can assume there will always be at least one free open api endpoint over the Internet. Smapp will allow to read any app state w/o transactions as well via remote public or local node api. Explorer will also show app state for each spawned app. No rational user will submit a transaction that is not intended to change state as it costs money and reading the state is free.

lrettig commented 3 years ago

are we saying that Alice can't be the source of funds in a transaction where she's not the principal and only an agent?

The idea here is that "Alice" is a person, not an account. In the terminology of this proposal, she's an "agent," and agents don't have funds, only principals do (agents have private keys that let them sign transactions). Alice stores her funds in a "wallet" which is really a principal account under the hood. If she wants to send funds from this wallet to Bob, she creates, signs, and broadcasts a transaction with the wallet address set as the principal (and Bob's address in the calldata).

Alice wants to transfer funds to Bob via an app that pays gas

Let me rephrase your question: Alice wants to send funds contained in her private (1-of-1) wallet but she wants a different app to pay the fees for the transaction. This is an interesting question. I think this sort of use case is a tiny corner case, that in practice it is not at all common, and that we're probably better off not trying to support this in the beginning. I have to give some thought to whether allowing two sources of funds in a single transaction is secure.

Here's one pattern that would work within the proposed framework: Alice grants the app in question permission to spend funds contained in her private wallet. (The permission could be time- or amount-limited, or there could be a whitelisted set of destination addresses, etc.). Then she can submit a transaction to the app, and let the app pay, and the app could call the wallet as a delegate and send the funds to Bob on her behalf.

in a 2/3 vault which pays gas for its users, alice wants to move coin from her account to the vault...

Assuming by "her account" you mean the sort of private wallet I described above, then the same pattern should work: Alice would first have to delegate authority to the vault to move funds from her private wallet, then the vault could do this on her behalf and pay the fees. This pattern is very similar to how ERC-20 works today.

lrettig commented 3 years ago

I'm also not sure how the idea of parked balance is going to help in the use case I mentioned.

In the simplest, and most extreme, case, when one of these transactions is processed, the miner/validator immediately sets the parked balance of the app account to zero (at least until the following layer when all pending transactions have been processed). Then all other transactions with the same principal would be dropped, or at least would be held in "stasis" and not put into blocks in the same layer. The goal here is to avoid multiple conflicting transactions actually being included in the same layer. This is precisely the same with simple transactions as it is with account unification: if a miner sees a tx that empties an account's balance completely, it should drop or hold all other transactions from that account.

What tal proposes regarding only allowing 1 transaction to a smart contract that can reduce its balance, is quite problematic from usability perspective - popular smart contracts are going to be used frequently by many users, potentially hundreds or thousands of them around the same time.

Agree

we don't intend devs to implement Edwards point math in svm code. The benchmarks discussed should be the performance of the EC and crypto precompiled - our provided libs vs. native code.

Agree, this is what precompiles are for. But Wasm is really performant and, if the performance is pretty close, it might make sense to actually perform these checks inside the VM.

lrettig commented 3 years ago

Q: what are concrete examples of verify() needing to write state? What use cases are not possible if verify() can not write state?

We discussed an example on the call: a vault (multisig) with a per-user daily spending limit, or a vault where we want to be able to change the signatories/keys. If verify() couldn't read state, any valid user could drain all the funds in the vault by sending lots of transactions. In general, any use case that needs to be able to invalidate a transaction (before it pays any gas at all) in a state-dependent fashion wouldn't be possible. I'm sure we could think of other examples.

Here's another: a decentralized exchange which charges zero gas if you submit a tx but the price has already moved too far.

lrettig commented 3 years ago

there is no need for transactions which do not modify state

The question isn't about transactions with don't modify state, it's about reading and writing state inside verify() specifically.

avive commented 3 years ago

Summary: TX format for AA - trying to have a high-level model here first based on the Smipp.

I think it will be useful to think about define how the following basic uses cases going to work with transactions and AA:

  1. Simple coin transfer between two ED and ED++ simple accounts (that were created by smeshing rewards)
  2. Create and fund a 2/3 multi-sig account tx by 3 users.
  3. Withdraw funds form a 2/3 multi-sig account tx by 2 users.
  4. Deploy a 2/3 vault with daily spending tx.
  5. Use a custom signature scheme instead of ED to sign transactions.
avive commented 3 years ago

Q: where are we on the open questions in the smipp the recent post brainstorming session about it, and how do we move forward on providing good answers to them?

tal-m commented 3 years ago

Q: where are we on the open questions in the smipp the recent post brainstorming session about it, and how do we move forward on providing good answers to them?

I think the first order of business is to benchmark signature verification inside and outside the SVM, to make sure SVM doesn't add unacceptable overhead.

Regarding other questions, we have some discussions going on in the forum.

avive commented 3 years ago

I think the first order of business is to benchmark signature verification inside and outside the SVM, to make sure SVM doesn't add unacceptable overhead.

Please read my comment above regarding performance - I think you may have missed it. Signature(s) verification is either going to be provided as a native pre-compiles, or using native svm host-functions - or at least the time-consuming parts of it, e.g. the EC and crypto low-level operations. It is clear that you don't want to do these kind of operations in SVM code. Either way, there will not be an unacceptable overhead and so it is should not be a priority for next step on this project. We will provide the low-level EC and crypto functions needed for the various modern signature schemes to enable multi-sig, aggregation and threshold. It should not be feasible to add a scheme that we don't provide such primitive for in svm because we don't want dev to roll-out their own crypto and likely svm is not going to be robust enough or low-level enough to implement such code in an efficient way.

I'm more concerned about open issues such as multi-tenancy, the need for another concepts such as 'conservative balance' which have broad implications on the platform design. More generally, are we at a point that we are convinced that AA is doable and we can move forward and specify the transaction format? There's a large body of work needed to be done around transaction singing and processing considering AA, so we need to finalize the transaction model and syntax asap for 0.3 soon. How do we keep moving forward on this project?

@lrettig @noamnelke @moshababo

tal-m commented 3 years ago

The overhead isn't from running the EC itself, it's from everything around it. Even if we can keep a single SVM instance up (and thus avoid the cost of starting and tearing down an SVM instance), there will be context switches in and out of SVM code, possibly memory allocations and frees, etc. All of these could add a lot compared to a signature verification outside the SVM.

My guess is that the overhead will be reasonably low, but I'm not 100% sure. Iddo is 100% sure it will be unacceptably high. This is an unknown, and quite easy to test, so I think it should have very high priority. I think this is the main question mark about whether AA is "doable". If the answer turns out to be that the overhead is too high, we will have to abandon AA (at least for now). If the overhead is low, we can definitely have some version of AA --- in the worst case (e.g., we don't want to support writing state) it will not allow much greater flexibility than we currently have (but will still be slightly more general).

Benchmarking code will be needed in any case for 0.3, since that is how we will construct the gas cost table for each operation. So it's not like we'll be doing extra work. It's also work that can be done in parallel to research we are doing on multi-tenancy, nonces, etc.

The conservative balance is not due to AA --- it's due to the mesh vs chain construction. It's a requirement even if we don't have smart contracts at all.

lrettig commented 3 years ago

I updated the proposal to factor in our recent discussions and decisions. Please take another look. One fairly important change: I removed nonce from the account model and moved this, too, inside verify() since different contracts/principal accounts should be free to implement whatever replay protection scheme they wish (or none at all).

tal-m commented 3 years ago

I've been thinking a lot about nonces lately --- at the moment I don't see a way to fully generalize nonces, much less to fold them into the verify method. Ensuring that the transaction verification code is efficient is pretty tricky. I do have some ideas (I'm writing a forum post about this now), but at the moment I think including nonce verification in verify is overly optimistic...

avive commented 3 years ago

The overhead isn't from running the EC itself, it's from everything around it. Even if we can keep a single SVM instance up (and thus avoid the cost of starting and tearing down an SVM instance), there will be context switches in and out of SVM code, possibly memory allocations and frees, etc. All of these could add a lot compared to a signature verification outside the SVM.

I don't think there needs to be any context switches at all. For standard signature schemes we are going to support for genesis, e.g. ed, e++ and multi-sig smart contracts - in the templates we are going to provide - the implementation of verify can and should be 100% native w/o spawning SVM at all - there is absolutely no reason to and this kind of an obvious optimization and ALL transactions until devs can deploy templates in the future will use these optimized verify.

For custom signature schemes that devs are going to implement once we open the platform for devs to submit templates with custom verify code, there will be overhead which is identical to overhead of running a smart contract method which should be factored in the gas cost of the execution. So, in other words, supporting custom dev-provided verified is not any different then supporting a smart contract method that requires svm instantiation and is governed by metered execution. So I still argue this is a non-issue right now compared with having a complete spec that we feel good about and handles all of the use cases and the open issues lane mentioned in this smip.

I also don't think that we should consider this performance issue as part of AA decisions - it should be factored in the gas unit computation for svm methods and for verify and for the hard-limit we are going to impose on verify in terms of gas units.

tal-m commented 3 years ago

@avive: If the overhead of SVM is too high to support anything except native-code precompiles, we don't gain anything from account unification (it's not actually unification in this case).

The point is that a failed verify doesn't pay any gas, so the overhead matters a lot, unlike smart contract executions which can pay for their overhead as part of the gas cost. This is why performance is a critical part of the AA decision.

(Also, custom signature schemes are far in the future (if ever) -- that's not what we're talking about at the moment)

YaronWittenstein commented 3 years ago

@noamnelke and I have discussed a couple of topics concerning the development efforts for the Accounts Abstraction:

1. Transaction format

Firstly, we've covered the new Transaction format. I'll open a SMIP detailing what we've talked about

@noamnelke and others will help with finalizing it.

2. Signing

Then, we've moved to talk about signing a Transaction. As a reminder, with the new design, the verifydata will contain signatures and other inputs to be used by the verify code.

But we still need to finalize how signing the whole transaction will work. Furthermore, we need to agree on the formula for deriving a transaction id and on what data it will rely on.

3. Discarding transactions running in Fixed Gas mode

Given a transaction passing the verify stage. In case we know ahead (using the Fixed Gas mechanism) it has not enough gas left for executing later the function - do we want to discard it?

4. Funding

Will funding the target Account will occur prior to calling verify? It's probably not important right now since in the first version of verify we won't allow the running code to ask for its balance.

It's still good to agree on when exactly funding an Account will take place.

5. go-svm Query API

Right now, I'm in the process of adapting The SVM API. In particular, the FFI API is undergoing new changes and it will affect go-svm.

Besides SVM execution API - there will be API used for Querying SVM (and the new Global-State). The vast majority of it will be used to supply data to the Node API layer for smapp / Process Explorer The work here will be derived from the Node API requirements (@avive , @lrettig , and I are already on top of this).

aAdditionally, the Node will necessitate data from SVM for its core.

Probably, we'll need a Get Balance of an Account or Get State Root Hash given a Layer Id. We need to map what are the other the remaining Queries here.

6. Lack of Nonce

This seems to be the most urgent unknown that must be resolved ASAP. The lack of nonce will have to be compensated by SVM implementing more features.

7. Others

Similarly to computing the Transaction Id - we need to finalize how we derive an Account Address and a Template Address as well.

YaronWittenstein commented 3 years ago

The main topics discussed in the last R&D call were:

Explicit Nonce Field Replacement Mechanism

Tal has detailed an Explicit Nonce Field Replacement mechanism that will be used as part of moving to the new Account Unification Account Model. It involves adding more steps into the life-cycle execution of a transaction. (the nonce threshold, validity predicate and state update function).

Seems we have everything required in order to move forward to writing a SMIP before implementation.

Shared Transaction input between functions

Tal stressed the need that each running SVM function will have full-access to the input data of the transaction. For example, verify needs to have access to the function name and its calldata that will run later (in case the verify will be resolved as true). Likewise, a running function should have access to the verifydata supplied when executing formerly the verify function.

Limit on #coins transfer allowed while running a function

Tal said he believes we need to be able to restrict the amount of coins a running function will be allowed to transfer during its run. Having this information will be leveraged by the Transaction Selection Algorithm.

One way of implementing it will be by having verify return a max_withdraw value in addition to only a boolean.