smapp icon indicating copy to clipboard operation
smapp copied to clipboard

Integrate new transactions structure: single-sig accounts

Open brusherru opened this issue 3 years ago • 7 comments

This issue contains bunches of questions in corresponding sections. Please indicate what time you are talking about: ASAP / Genesis / Post.

Rationale

This is an epic issue, that should be divided into smaller ones. But let's clarify all the details first.

The transaction structure and API have been changed due to support vaults. Within this issue we want to integrate these changes into Smapp and support:

  • creation of single-sig accounts
  • smeshing and getting rewards on such accounts
  • sending SpendTransactions to other single-sig accounts

Links to related changes in API & Go-Spacemesh:

  • https://github.com/spacemeshos/api/pull/164
  • https://github.com/spacemeshos/api/pull/165
  • https://github.com/spacemeshos/go-spacemesh/pull/3295
  • https://github.com/spacemeshos/go-spacemesh/pull/3229

Details

Concepts

image
  • Principle address — is the address of the single-sig account
  • Principle address should be used as coinbase for smeshing then.
  • To calculate a principle address we need to encode (?) the template address and arguments
  • In this case, argument is PublicKey,
  • The key pair may be generated/imported by Smapp and stored in the wallet file,
  • To send any transactions to the network User have to sign these transactions with the corresponding private key

Keys

So we will have two kinds of addresses stored in the wallet file:

  1. Keys — key-pairs used in spawning accounts and signing transactions They still should be generated from mnemonics, and probable should use HD wallet standard. At the moment we use ed25519 wasm-implementation, which implements deriving by index only (or mb I miss something).
  2. Vaults — list of principal addresses, that the User is interested in. Basically, this is the list of Principal addresses, which makes it easier to listen for updates only for particular addresses. In case the User lost his wallet file and recovers from mnemonics he has to import vaults using the same arguments or vault address. So basically not so user-friendly, but improving this user story is out of scope for this issue.

To make it a bit easier, we can pre-create one single-sig account by default (without spawning), as we're doing it now with the first derived key pair.

On the creation of subsequent single-sig accounts, the User will be asked to choose one of the existing keys or to generate a new one. If he wants to "recreate" the vault of another key, he has to reimport the keypair first. image He can reimport it just by creating new accounts (aka find needed derived index / HD path), importing a private key (not implemented). Without owning a keypair User can reimport the vault only by its address.

QUESTIONS:

  1. Do we need an HD wallet?

Codec

Besides this, the new transaction structure uses scale codec. That means that to read the transaction we need to decode a raw part of the transaction using schema related to a particular template address and method. Afterward, we can store decoded data in a persistent store on fs (like we're doing using AccountStateManager), show it, etc.

QUESTIONS

  1. Do we hard-code template addresses or do we have any open on-chain storage for it?
  2. Do we already have some service for encoding/decoding transactions (within such on-chain storage/service aside)? I remember something like that, but I can't find it.
  3. Or do we have to implement encoding/decoding in JS?
  4. Do we have any service with encoding schemas or something similar? Aka (I got tx with template address 0xbb and method 0x01, then I want to decode it, it will be cool to have something like this:
    const msgSchema = await Node.requestMessageSchema(0xbb, 0x01);
    const { recipient, amount } = decode(rawTx, msgSchema);
    
  5. Meanwhile, we have to stick somehow Smapp's GUI to core message schemas. So, do we have some smart mechanism for that, or do we have just to hard-code template addresses?

I'd appreciate any help and ideas! 🙏 cc: @maparr @dshulyak @noamnelke @lrettig @oriya

Tasks

brusherru avatar Jul 08 '22 15:07 brusherru

A couple more questions regarding sending tx flow. As a Smapper I've run Smapp and have a pre-created single-sig account (or created it manually). Then I smesh and get some coins there... and I want to send a Tx to my friend:

  1. Do I need to explicitly sign and publish spawn tx? Or it should be automatically sent under the hood?
  2. If automatically, then does the Node take care of it or clients should take care?

brusherru avatar Jul 11 '22 07:07 brusherru

Do we hard-code template addresses or do we have any open on-chain storage for it?

we don't have any storage. for genesis it makes sense to hard code them

Or do we have to implement encoding/decoding in JS?

yes, encoding and signing is done on the client

Do we have any service with encoding schemas or something similar?

we don't have such service and schemas. it probably will be introduced together with svm, but for now it is not important. i assumed that for genesis all schemas will be known to the client, so they can be hardcoded as well.

Do I need to explicitly sign and publish spawn tx? Or it should be automatically sent under the hood?

self-spawn needs to be applied to the chain before submitting any other transactions. it should be done explicitly by the client, i am not aware of any option to make it automatically somehow

dshulyak avatar Jul 11 '22 08:07 dshulyak

Or do we have to implement encoding/decoding in JS?

yes, encoding and signing is done on the client

Do we have any service with encoding schemas or something similar?

we don't have such service and schemas. it probably will be introduced together with svm, but for now it is not important. i assumed that for genesis all schemas will be known to the client, so they can be hardcoded as well.

We previously discussed publishing a single Wasm codec that could be shared by SVM as well as by smapp and other downstream clients. I suppose this is up in the air at the moment, pending SVM design, CC @WilfredTA.

Do I need to explicitly sign and publish spawn tx? Or it should be automatically sent under the hood?

self-spawn needs to be applied to the chain before submitting any other transactions. it should be done explicitly by the client, i am not aware of any option to make it automatically somehow

Two notes:

  1. The spawn tx does not need to be published until the user wants to actually spend/move the funds. In particular, it does not need to be part of the smeshing setup. The user can safely accumulate funds (from coinbase txs, or from other sources) into their account, secure in the knowledge that they can spawn and spend those funds later (as long as they have the associated private key).
  2. It's theoretically possible to create a special, atomic "spawn-and-spend" tx that accomplishes both in a single tx (for an account that hasn't been spawned yet). Not sure what's the status of this on the VM/node side (CC @dshulyak @noamnelke). This can be done as two separate txs, but having an atomic tx type may result in slightly better UX/lower fees -- e.g., what happens if the spawn and spend txs are sent separately, around the same time, and the spawn doesn't make it into the block but the spend does?

lrettig avatar Jul 11 '22 19:07 lrettig

We previously discussed publishing a single Wasm codec that could be shared by SVM as well as by smapp and other downstream clients ❤️ Do we have any estimation on it? @WilfredTA

So the basic user story:

  1. The user get some SMH on his not spawned yet single-sig account
  2. Then User explicitly sends a spawn transaction
  3. User waits until this tx will be on-chain: Meanwhile, Smapp has to detect, that the User already sent a spawn transaction and it has a pending status, so Smapp should not allow sending one more spawn transaction until this one fails.
  4. Then User can send a spend transaction

Correct?

brusherru avatar Jul 12 '22 08:07 brusherru

3. Smapp has to detect, that the User already sent a spawn transaction and it has a pending status, so Smapp should not allow sending one more spawn transaction until this one fails.

Ideally spawn transactions should be idempotent, so that sending another one would have no effect and do no harm. (Nodes should drop them as duplicates.)

One more point: the "spawn" part should ideally be invisible to the user, i.e., from the frontend/UX/smapp perspective, the user should not need to create a "spawn" transaction separately from the first spend. When the user first tries to spend funds from the account, smapp should just automatically generate and send the spawn tx first.

lrettig avatar Jul 12 '22 14:07 lrettig

I want to emphasize that smapp should wait for a spawn transaction to execute. Effectively wait for the result. Only after that point other transactions from the same principal will become parsable and won't be discarded by the api.

It's theoretically possible to create a special, atomic "spawn-and-spend" tx that accomplishes both in a single tx (for an account that hasn't been spawned yet). Not sure what's the status of this on the VM/node side

we don't have anything like that implemented

dshulyak avatar Jul 12 '22 14:07 dshulyak

It's theoretically possible to create a special, atomic "spawn-and-spend" tx that accomplishes both in a single tx (for an account that hasn't been spawned yet). Not sure what's the status of this on the VM/node side

we don't have anything like that implemented

It can always be added as a new tx type later, and it's not critical (as long as the above UX is managed by smapp)

lrettig avatar Jul 12 '22 19:07 lrettig