onflow / flow-emulator

The Flow Emulator is a lightweight tool that emulates the behaviour of the real Flow network
https://onflow.org
Apache License 2.0
84 stars 49 forks source link

FEATURE: Auto create accounts and set network codeword #98

Closed bluesign closed 1 year ago

bluesign commented 2 years ago

Issue To Be Solved

I was playing around the idea of "auto create accounts" on demand. So instead of getting error on non-existing account with some flag we can force emulator to create the account on demand. ( I made a POC on https://github.com/bluesign/flow-emulator/tree/emulator_auto_accounts ) which creates account with the details of service account (pubkeys etc)

But I want to take this a bit further and curious about your ideas about this.

What about if we also let emulator to use any network codeword, especially testnet? ( with deploying contracts to that correct network addresses )

Also this would allow to write tests for testnet only and also can run them in emulator. I am not sure about feature parity between testnet and emulator, but seems like this can make life a bit easier for developers. Usually main problem with testnet is resetting account state, this can remove the need for that, also can push people to use emulator more.

Also this will be a backup for the times where testnet is down.

This can alternatively be implemented with using account keys data from X network, but keeping state internally, but it is a bit more confusing.

sideninja commented 2 years ago

Nice! This is an interesting idea, I had the time to just glance I will circle back to this. Maybe until then, should accounts just be generated once they error as non-existing or should you provide a whitelist? I'm thinking what is the benefit for creating accounts on demand instead of beforehand since they would probably be known to the developer no? Why I'm asking this is because there might be cases where you would also want to test non-existing accounts and I see the benefit of creating them on demand just on the first run then each subsequential run would create the same state anyhow. We had discussions on how to bring testnet closer to the emulator and give it the ability to run state from testnet on emulator and I feel this is a nice mock. Sorry that I didn't have the time sooner.

bluesign commented 2 years ago

This is very good point. Potentially there can be an option creating accounts only defined in flow.json in network section that we are trying to emulate.

flow emulator --emulate testnet can create accounts defined in testnet section of the flow.json and launch emulator with testnet codeword , (optionally deploy contracts etc)

My idea to create on demand was actually came out from trying to use blocto wallet also on emulator. ( so payer etc will be created on demand when needed ) So technically you can use blocto testnet account (even mainnet) with emulator.

Main problem currently I see is: people get in to testnet prematurely, then they are having a lot of issues with contract updates/deletes and state of the test accounts etc. Somehow pushing people in to emulator but with the real toolset ( like blocto wallet testnet used on emulator etc ) can help them.

sideninja commented 2 years ago

Yes I think the direction you are setting here is great and if we can leverage the testnet tools on the emulator or at least provide enough emulation of the testnet locally that you can use it for testing or debugging that would be amazing. I want to offer any help you will need with this.

I feel providing accounts in flow.json would work perfectly. Maybe there can be an environment section or something like that further defining attributes of the environment, maybe even allowing you to either provide a whitelist of accounts or just enable on-demand creation.

What would be super cool is ability to transfer the state to emulator from the testnet to inspect a bug, do some kind of debugging but I guess that then also needs to be more than just account creation but also storage migration. But maybe CLI can hide the complexity of that by inspecting the state for you and just making sure the same state is established (but this is I guess conditioned by Cadence adding API for state inspection - I believe that is coming soon or later).

janezpodhostnik commented 2 years ago

I like the idea of the emulator creating accounts defined in flow.json for the emulator chain.

For testnet or mainnet there could be a way to fetch the data needed on demand.

The way that would work is that when cadence wants to read a register which is forwarded to the fvm and then forwarded to the storage layer. the storage layer would read this register in three steps:

  1. Check local storage if register exists. If it does just read it
  2. Check a local testnet cache if the register exists, if it does read it
  3. Go to some service X and get the register (and all registers from the same account) and put them in the cache

When writing a register it would just be written to the local storage.

The service X would be a service that exposes an endpoint where you send it an address and a block height and it gives you all the registers for that address for that block height. The reason data is fetched per account instead of per register, is to have less requests otherwise composite objects that are split over multiple registers might cause a lot of traffic. The DPS could probably offer an endpoint like this.

One more thing that is probably needed is that if you are requesting a keys register, instead of looking it up you just substitute it with some know keys.

bluesign commented 2 years ago

@janezpodhostnik good suggestion for debugging, but I am more hesitant if we allow this, then development will stuck at testnet, emulator will be used only for debugging.

What I am trying to manage is, if we can bring up emulator with feature parity with testnet, people can delay deploying to testnet. What I see commonly is, people skip emulator, and jump into testnet. And then having a lot of issues with contract updates etc.

But this idea of yours gave me another idea:

if we have some DPS endpoint like this, probably we can simulate a transaction before running, and get a summary of state changes.

So if I am buying an NFT:

Transaction analyzer can tell me:

bluesign commented 2 years ago

I think with debugger this can be really nice feature.n So technically you can debug your testnet contract ( even maybe mainnet )

The DPS could probably offer an endpoint like this. @janezpodhostnik with whom we can discuss this ?

I started implementing needed parts for this.

bluesign commented 1 year ago

We added chainID support here, and I guess with new snapshot, there is no much need to create accounts in the start. I think we can close this, what do you think @sideninja ?