-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RpcClient missing state root related methods (#644)
* RpcClient missing state root related methods Fixes #635 * fix formatting * Add RpcSend/Send methods (fixes #646) * update names to match rpc endpoint * update to latest state api * fix formatting * use span/memory instead of array where possible * add EnumerateFindStatesAsync and fix MakeFindStatesParams * Adapt to latest state api changes * fix formatting * CR Feedback * rename * rename * fix formatting <grrr> * PR Feedback Co-authored-by: Owen Zhang <[email protected]> Co-authored-by: Harry Pierson <[email protected]>
- Loading branch information
1 parent
50f0473
commit 606bd27
Showing
4 changed files
with
191 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
using System; | ||
using System.Linq; | ||
using Neo.IO.Json; | ||
|
||
namespace Neo.Network.RPC.Models | ||
{ | ||
public class RpcFoundStates | ||
{ | ||
public bool Truncated; | ||
public (byte[] key, byte[] value)[] Results; | ||
public byte[] FirstProof; | ||
public byte[] LastProof; | ||
|
||
public static RpcFoundStates FromJson(JObject json) | ||
{ | ||
return new RpcFoundStates | ||
{ | ||
Truncated = json["truncated"].AsBoolean(), | ||
Results = ((JArray)json["results"]) | ||
.Select(j => ( | ||
Convert.FromBase64String(j["key"].AsString()), | ||
Convert.FromBase64String(j["value"].AsString()) | ||
)) | ||
.ToArray(), | ||
FirstProof = ProofFromJson(json["firstProof"]), | ||
LastProof = ProofFromJson(json["lastProof"]), | ||
}; | ||
} | ||
|
||
static byte[] ProofFromJson(JObject json) | ||
=> json == null ? null : Convert.FromBase64String(json.AsString()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using System.Linq; | ||
using Neo.IO.Json; | ||
using Neo.Network.P2P.Payloads; | ||
|
||
namespace Neo.Network.RPC.Models | ||
{ | ||
public class RpcStateRoot | ||
{ | ||
public byte Version; | ||
public uint Index; | ||
public UInt256 RootHash; | ||
public Witness Witness; | ||
|
||
public static RpcStateRoot FromJson(JObject json) | ||
{ | ||
return new RpcStateRoot | ||
{ | ||
Version = (byte)json["version"].AsNumber(), | ||
Index = (uint)json["index"].AsNumber(), | ||
RootHash = UInt256.Parse(json["roothash"].AsString()), | ||
Witness = ((JArray)json["witnesses"]).Select(p => Utility.WitnessFromJson(p)).FirstOrDefault() | ||
}; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Runtime.CompilerServices; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Neo.IO.Json; | ||
using Neo.Network.RPC.Models; | ||
|
||
namespace Neo.Network.RPC | ||
{ | ||
public class StateAPI | ||
{ | ||
private readonly RpcClient rpcClient; | ||
|
||
public StateAPI(RpcClient rpc) | ||
{ | ||
this.rpcClient = rpc; | ||
} | ||
|
||
public async Task<RpcStateRoot> GetStateRootAsync(uint index) | ||
{ | ||
var result = await rpcClient.RpcSendAsync(RpcClient.GetRpcName(), index).ConfigureAwait(false); | ||
return RpcStateRoot.FromJson(result); | ||
} | ||
|
||
public async Task<byte[]> GetProofAsync(UInt256 rootHash, UInt160 scriptHash, byte[] key) | ||
{ | ||
var result = await rpcClient.RpcSendAsync(RpcClient.GetRpcName(), | ||
rootHash.ToString(), scriptHash.ToString(), Convert.ToBase64String(key)).ConfigureAwait(false); | ||
return Convert.FromBase64String(result.AsString()); | ||
} | ||
|
||
public async Task<byte[]> VerifyProofAsync(UInt256 rootHash, byte[] proofBytes) | ||
{ | ||
var result = await rpcClient.RpcSendAsync(RpcClient.GetRpcName(), | ||
rootHash.ToString(), Convert.ToBase64String(proofBytes)).ConfigureAwait(false); | ||
|
||
return Convert.FromBase64String(result.AsString()); | ||
} | ||
|
||
public async Task<(uint? localRootIndex, uint? validatedRootIndex)> GetStateHeightAsync() | ||
{ | ||
var result = await rpcClient.RpcSendAsync(RpcClient.GetRpcName()).ConfigureAwait(false); | ||
var localRootIndex = ToNullableUint(result["localrootindex"]); | ||
var validatedRootIndex = ToNullableUint(result["validatedrootindex"]); | ||
return (localRootIndex, validatedRootIndex); | ||
} | ||
|
||
static uint? ToNullableUint(JObject json) => (json == null) ? (uint?)null : (uint?)json.AsNumber(); | ||
|
||
public static JObject[] MakeFindStatesParams(UInt256 rootHash, UInt160 scriptHash, ReadOnlySpan<byte> prefix, ReadOnlySpan<byte> from = default, int? count = null) | ||
{ | ||
var paramCount = from.Length == 0 ? 3 : count == null ? 4 : 5; | ||
var @params = new JObject[paramCount]; | ||
@params[0] = rootHash.ToString(); | ||
@params[1] = scriptHash.ToString(); | ||
@params[2] = Convert.ToBase64String(prefix); | ||
if (from.Length > 0) | ||
{ | ||
@params[3] = Convert.ToBase64String(from); | ||
if (count.HasValue) | ||
{ | ||
@params[4] = count.Value; | ||
} | ||
} | ||
return @params; | ||
} | ||
|
||
public async Task<RpcFoundStates> FindStatesAsync(UInt256 rootHash, UInt160 scriptHash, ReadOnlyMemory<byte> prefix, ReadOnlyMemory<byte> from = default, int? count = null) | ||
{ | ||
var @params = MakeFindStatesParams(rootHash, scriptHash, prefix.Span, from.Span, count); | ||
var result = await rpcClient.RpcSendAsync(RpcClient.GetRpcName(), @params).ConfigureAwait(false); | ||
|
||
return RpcFoundStates.FromJson(result); | ||
} | ||
|
||
public async Task<byte[]> GetStateAsync(UInt256 rootHash, UInt160 scriptHash, byte[] key) | ||
{ | ||
var result = await rpcClient.RpcSendAsync(RpcClient.GetRpcName(), | ||
rootHash.ToString(), scriptHash.ToString(), Convert.ToBase64String(key)).ConfigureAwait(false); | ||
return Convert.FromBase64String(result.AsString()); | ||
} | ||
} | ||
} |