Simplify getting latest state with GetState() or FindStates()
Summary or problem description Assume I want to retrieve the latest state. The current flow to do so is
- call
GetStateheight()to get the root index - call
GetStateRoot(index)to get thestateroot - call
GetState()orFindState()with the obtainedstateroot
That's 2 RPC calls before I can call GetState or FindState. RPC calls can be slow and it regularly happens that I get an exception from the code below while using the contract download feature of neo-express simply because the CurrentLocalRootHash of the node has already changed before I could finally submit what I obtained as the latest root hash.
https://github.com/neo-project/neo-modules/blob/7db1c7956ac68758793a6ea30b5329cceb6ab1bc/src/StateService/StatePlugin.cs#L294-L298
Do you have any solution you want to propose?
One way to solve this is selecting a node with FullState enabled, but that severely limits the available RPC nodes to choose from while we're not even interested in the full state.
Instead I want to propose accepting null as first argument to GetState and FindState and automatically replace it with the latest root hash. e.g.
UInt256.TryParse(_params[0].AsString(), root_hash);
if (root_hash is null) {
root_hash = StateStore.Singleton.CurrentLocalRootHash;
} else if (!Settings.Default.FullState && StateStore.Singleton.CurrentLocalRootHash != root_hash)
throw new RpcException(-100, "Old state not supported");
Note: It's up for discussion if GetProof() should also support this.
Where in the software does this update applies to?
- Other: StateService plugin
GetState(null,...) looks very much like GetStorage(...) to me. But we don't have anything similar to FindStates for the current state (maybe we should add something? It'd be more performant than going via MPT).
But it's easy to implement anyway, so if it's useful in some scenarios we can have it. The only thing I'd change is doing this just for empty strings passed in _params[0], because IIUC TryParse will return a null root_hash even if we feed it with garbage string and cases like this better be errored out.
A FindStorage() to complement GetStorage sounds good to me.