Skip to content

Commit bc1506f

Browse files
authored
Merge branch 'dev' into feature/improve-stringextensions-exception-messages
2 parents 394d9e3 + bc6f34e commit bc1506f

File tree

13 files changed

+386
-126
lines changed

13 files changed

+386
-126
lines changed

neo.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.Plugins.RestServer.Test
9797
EndProject
9898
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestServer", "src\Plugins\RestServer\RestServer.csproj", "{4865C487-C1A1-4E36-698D-1EC4CCF08FDB}"
9999
EndProject
100+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.Plugins.StateService.Tests", "tests\Neo.Plugins.StateService.Tests\Neo.Plugins.StateService.Tests.csproj", "{229C7877-C0FA-4399-A0DB-96E714A59481}"
101+
EndProject
100102
Global
101103
GlobalSection(SolutionConfigurationPlatforms) = preSolution
102104
Debug|Any CPU = Debug|Any CPU
@@ -271,6 +273,10 @@ Global
271273
{4865C487-C1A1-4E36-698D-1EC4CCF08FDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
272274
{4865C487-C1A1-4E36-698D-1EC4CCF08FDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
273275
{4865C487-C1A1-4E36-698D-1EC4CCF08FDB}.Release|Any CPU.Build.0 = Release|Any CPU
276+
{229C7877-C0FA-4399-A0DB-96E714A59481}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
277+
{229C7877-C0FA-4399-A0DB-96E714A59481}.Debug|Any CPU.Build.0 = Debug|Any CPU
278+
{229C7877-C0FA-4399-A0DB-96E714A59481}.Release|Any CPU.ActiveCfg = Release|Any CPU
279+
{229C7877-C0FA-4399-A0DB-96E714A59481}.Release|Any CPU.Build.0 = Release|Any CPU
274280
EndGlobalSection
275281
GlobalSection(SolutionProperties) = preSolution
276282
HideSolutionNode = FALSE
@@ -319,6 +325,7 @@ Global
319325
{8C7A7070-08E3-435A-A909-9541B5C66E8C} = {EDE05FA8-8E73-4924-BC63-DD117127EEE1}
320326
{A7FE2B30-11F8-E88D-D5BF-AF1B11EFEC8E} = {7F257712-D033-47FF-B439-9D4320D06599}
321327
{4865C487-C1A1-4E36-698D-1EC4CCF08FDB} = {C2DC830A-327A-42A7-807D-295216D30DBB}
328+
{229C7877-C0FA-4399-A0DB-96E714A59481} = {7F257712-D033-47FF-B439-9D4320D06599}
322329
EndGlobalSection
323330
GlobalSection(ExtensibilityGlobals) = postSolution
324331
SolutionGuid = {BCBA19D9-F868-4C6D-8061-A2B91E06E3EC}

src/Plugins/ApplicationLogs/LogReader.cs

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -95,37 +95,29 @@ protected override void OnSystemLoaded(NeoSystem system)
9595
#region JSON RPC Methods
9696

9797
[RpcMethod]
98-
public JToken GetApplicationLog(JArray _params)
98+
public JToken GetApplicationLog(UInt256 hash, string triggerType = "")
9999
{
100-
if (_params == null || _params.Count == 0)
101-
throw new RpcException(RpcError.InvalidParams);
102-
if (UInt256.TryParse(_params[0]!.AsString(), out var hash))
103-
{
104-
var raw = BlockToJObject(hash);
105-
if (raw == null)
106-
raw = TransactionToJObject(hash);
107-
if (raw == null)
108-
throw new RpcException(RpcError.InvalidParams.WithData("Unknown transaction/blockhash"));
100+
var raw = BlockToJObject(hash);
101+
if (raw == null) raw = TransactionToJObject(hash);
102+
if (raw == null) throw new RpcException(RpcError.InvalidParams.WithData("Unknown transaction/blockhash"));
109103

110-
if (_params.Count >= 2 && Enum.TryParse(_params[1]!.AsString(), true, out TriggerType triggerType))
104+
if (!string.IsNullOrEmpty(triggerType) && Enum.TryParse(triggerType, true, out TriggerType _))
105+
{
106+
var executions = raw["executions"] as JArray;
107+
if (executions != null)
111108
{
112-
var executions = raw["executions"] as JArray;
113-
if (executions != null)
109+
for (var i = 0; i < executions.Count;)
114110
{
115-
for (var i = 0; i < executions.Count;)
116-
{
117-
if (executions[i]!["trigger"]?.AsString().Equals(triggerType.ToString(), StringComparison.OrdinalIgnoreCase) == false)
118-
executions.RemoveAt(i);
119-
else
120-
i++;
121-
}
111+
if (executions[i]!["trigger"]?.AsString().Equals(triggerType, StringComparison.OrdinalIgnoreCase) == false)
112+
executions.RemoveAt(i);
113+
else
114+
i++;
122115
}
123116
}
124-
125-
return raw;
126117
}
127-
else
128-
throw new RpcException(RpcError.InvalidParams);
118+
119+
return raw;
120+
129121
}
130122

131123
#endregion
@@ -215,7 +207,8 @@ internal void OnGetContractCommand(UInt160 scripthash, uint page = 1, uint pageS
215207

216208
#region Blockchain Events
217209

218-
void ICommittingHandler.Blockchain_Committing_Handler(NeoSystem system, Block block, DataCache snapshot, IReadOnlyList<Blockchain.ApplicationExecuted> applicationExecutedList)
210+
void ICommittingHandler.Blockchain_Committing_Handler(NeoSystem system, Block block, DataCache snapshot,
211+
IReadOnlyList<Blockchain.ApplicationExecuted> applicationExecutedList)
219212
{
220213
if (system.Settings.Network != ApplicationLogsSettings.Default.Network)
221214
return;

src/Plugins/OracleService/OracleService.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ private void OnShow()
171171
ConsoleHelper.Info($"Oracle status: ", $"{status}");
172172
}
173173

174-
void ICommittingHandler.Blockchain_Committing_Handler(NeoSystem system, Block block, DataCache snapshot, IReadOnlyList<Blockchain.ApplicationExecuted> applicationExecutedList)
174+
void ICommittingHandler.Blockchain_Committing_Handler(NeoSystem system, Block block, DataCache snapshot,
175+
IReadOnlyList<Blockchain.ApplicationExecuted> applicationExecutedList)
175176
{
176177
if (system.Settings.Network != OracleSettings.Default.Network) return;
177178

@@ -226,25 +227,37 @@ private async void OnTimer(object state)
226227
}
227228
}
228229

230+
/// <summary>
231+
/// Submit oracle response
232+
/// </summary>
233+
/// <param name="oraclePubkey">Oracle public key, base64-encoded if access from json-rpc</param>
234+
/// <param name="requestId">Request id</param>
235+
/// <param name="txSign">Transaction signature, base64-encoded if access from json-rpc</param>
236+
/// <param name="msgSign">Message signature, base64-encoded if access from json-rpc</param>
237+
/// <returns>JObject</returns>
229238
[RpcMethod]
230-
public JObject SubmitOracleResponse(JArray _params)
239+
public JObject SubmitOracleResponse(byte[] oraclePubkey, ulong requestId, byte[] txSign, byte[] msgSign)
231240
{
232241
status.Equals(OracleStatus.Running).True_Or(RpcError.OracleDisabled);
233-
ECPoint oraclePub = ECPoint.DecodePoint(Convert.FromBase64String(_params[0].AsString()), ECCurve.Secp256r1);
234-
ulong requestId = Result.Ok_Or(() => (ulong)_params[1].AsNumber(), RpcError.InvalidParams.WithData($"Invalid requestId: {_params[1]}"));
235-
byte[] txSign = Result.Ok_Or(() => Convert.FromBase64String(_params[2].AsString()), RpcError.InvalidParams.WithData($"Invalid txSign: {_params[2]}"));
236-
byte[] msgSign = Result.Ok_Or(() => Convert.FromBase64String(_params[3].AsString()), RpcError.InvalidParams.WithData($"Invalid msgSign: {_params[3]}"));
237242

243+
var oraclePub = ECPoint.DecodePoint(oraclePubkey, ECCurve.Secp256r1);
238244
finishedCache.ContainsKey(requestId).False_Or(RpcError.OracleRequestFinished);
239245

240246
using (var snapshot = _system.GetSnapshotCache())
241247
{
242-
uint height = NativeContract.Ledger.CurrentIndex(snapshot) + 1;
248+
var height = NativeContract.Ledger.CurrentIndex(snapshot) + 1;
243249
var oracles = NativeContract.RoleManagement.GetDesignatedByRole(snapshot, Role.Oracle, height);
250+
251+
// Check if the oracle is designated
244252
oracles.Any(p => p.Equals(oraclePub)).True_Or(RpcErrorFactory.OracleNotDesignatedNode(oraclePub));
253+
254+
// Check if the request exists
245255
NativeContract.Oracle.GetRequest(snapshot, requestId).NotNull_Or(RpcError.OracleRequestNotFound);
256+
257+
// Check if the transaction signature is valid
246258
byte[] data = [.. oraclePub.ToArray(), .. BitConverter.GetBytes(requestId), .. txSign];
247-
Crypto.VerifySignature(data, msgSign, oraclePub).True_Or(RpcErrorFactory.InvalidSignature($"Invalid oracle response transaction signature from '{oraclePub}'."));
259+
Crypto.VerifySignature(data, msgSign, oraclePub)
260+
.True_Or(RpcErrorFactory.InvalidSignature($"Invalid oracle response transaction signature from '{oraclePub}'."));
248261
AddResponseTxSign(snapshot, requestId, oraclePub, txSign);
249262
}
250263
return new JObject();

src/Plugins/StateService/StatePlugin.cs

Lines changed: 35 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,9 @@ private void OnGetStateHeight()
170170
[ConsoleCommand("get proof", Category = "StateService", Description = "Get proof of key and contract hash")]
171171
private void OnGetProof(UInt256 rootHash, UInt160 scriptHash, string key)
172172
{
173-
if (_system is null || _system.Settings.Network != StateServiceSettings.Default.Network) throw new InvalidOperationException("Network doesn't match");
173+
if (_system is null || _system.Settings.Network != StateServiceSettings.Default.Network)
174+
throw new InvalidOperationException("Network doesn't match");
175+
174176
try
175177
{
176178
ConsoleHelper.Info("Proof: ", GetProof(rootHash, scriptHash, Convert.FromBase64String(key)));
@@ -186,8 +188,7 @@ private void OnVerifyProof(UInt256 rootHash, string proof)
186188
{
187189
try
188190
{
189-
ConsoleHelper.Info("Verify Result: ",
190-
VerifyProof(rootHash, Convert.FromBase64String(proof)));
191+
ConsoleHelper.Info("Verify Result: ", VerifyProof(rootHash, Convert.FromBase64String(proof)));
191192
}
192193
catch (RpcException e)
193194
{
@@ -196,9 +197,8 @@ private void OnVerifyProof(UInt256 rootHash, string proof)
196197
}
197198

198199
[RpcMethod]
199-
public JToken GetStateRoot(JArray _params)
200+
public JToken GetStateRoot(uint index)
200201
{
201-
var index = Result.Ok_Or(() => uint.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid state root index: {_params[0]}"));
202202
using var snapshot = StateStore.Singleton.GetSnapshot();
203203
var stateRoot = snapshot.GetStateRoot(index).NotNull_Or(RpcError.UnknownStateRoot);
204204
return stateRoot.ToJson();
@@ -233,7 +233,7 @@ private string GetProof(Trie trie, StorageKey skey)
233233

234234
private string GetProof(UInt256 rootHash, UInt160 scriptHash, byte[] key)
235235
{
236-
(!StateServiceSettings.Default.FullState && StateStore.Singleton.CurrentLocalRootHash != rootHash).False_Or(RpcError.UnsupportedState);
236+
CheckRootHash(rootHash);
237237

238238
using var store = StateStore.Singleton.GetStoreSnapshot();
239239
var trie = new Trie(store, rootHash);
@@ -242,12 +242,10 @@ private string GetProof(UInt256 rootHash, UInt160 scriptHash, byte[] key)
242242
}
243243

244244
[RpcMethod]
245-
public JToken GetProof(JArray _params)
245+
public JToken GetProof(UInt256 rootHash, UInt160 scriptHash, string key)
246246
{
247-
var rootHash = Result.Ok_Or(() => UInt256.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid root hash: {_params[0]}"));
248-
var scriptHash = Result.Ok_Or(() => UInt160.Parse(_params[1].AsString()), RpcError.InvalidParams.WithData($"Invalid script hash: {_params[1]}"));
249-
var key = Result.Ok_Or(() => Convert.FromBase64String(_params[2].AsString()), RpcError.InvalidParams.WithData($"Invalid key: {_params[2]}"));
250-
return GetProof(rootHash, scriptHash, key);
247+
var keyBytes = Result.Ok_Or(() => Convert.FromBase64String(key), RpcError.InvalidParams.WithData($"Invalid key: {key}"));
248+
return GetProof(rootHash, scriptHash, keyBytes);
251249
}
252250

253251
private string VerifyProof(UInt256 rootHash, byte[] proof)
@@ -269,15 +267,15 @@ private string VerifyProof(UInt256 rootHash, byte[] proof)
269267
}
270268

271269
[RpcMethod]
272-
public JToken VerifyProof(JArray _params)
270+
public JToken VerifyProof(UInt256 rootHash, string proof)
273271
{
274-
var rootHash = Result.Ok_Or(() => UInt256.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid root hash: {_params[0]}"));
275-
var proofBytes = Result.Ok_Or(() => Convert.FromBase64String(_params[1].AsString()), RpcError.InvalidParams.WithData($"Invalid proof: {_params[1]}"));
272+
var proofBytes = Result.Ok_Or(
273+
() => Convert.FromBase64String(proof), RpcError.InvalidParams.WithData($"Invalid proof: {proof}"));
276274
return VerifyProof(rootHash, proofBytes);
277275
}
278276

279277
[RpcMethod]
280-
public JToken GetStateHeight(JArray _params)
278+
public JToken GetStateHeight()
281279
{
282280
return new JObject()
283281
{
@@ -289,50 +287,39 @@ public JToken GetStateHeight(JArray _params)
289287
private ContractState GetHistoricalContractState(Trie trie, UInt160 scriptHash)
290288
{
291289
const byte prefix = 8;
292-
StorageKey skey = new KeyBuilder(NativeContract.ContractManagement.Id, prefix).Add(scriptHash);
293-
return trie.TryGetValue(skey.ToArray(), out var value) ? value.AsSerializable<StorageItem>().GetInteroperable<ContractState>() : null;
290+
var skey = new KeyBuilder(NativeContract.ContractManagement.Id, prefix).Add(scriptHash);
291+
return trie.TryGetValue(skey.ToArray(), out var value)
292+
? value.AsSerializable<StorageItem>().GetInteroperable<ContractState>()
293+
: null;
294294
}
295295

296296
private StorageKey ParseStorageKey(byte[] data)
297297
{
298-
return new()
299-
{
300-
Id = BinaryPrimitives.ReadInt32LittleEndian(data),
301-
Key = data.AsMemory(sizeof(int)),
302-
};
298+
return new() { Id = BinaryPrimitives.ReadInt32LittleEndian(data), Key = data.AsMemory(sizeof(int)) };
303299
}
304300

305-
[RpcMethod]
306-
public JToken FindStates(JArray _params)
301+
private void CheckRootHash(UInt256 rootHash)
307302
{
308-
var rootHash = Result.Ok_Or(() => UInt256.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid root hash: {_params[0]}"));
309-
(!StateServiceSettings.Default.FullState && StateStore.Singleton.CurrentLocalRootHash != rootHash).False_Or(RpcError.UnsupportedState);
303+
var fullState = StateServiceSettings.Default.FullState;
304+
var current = StateStore.Singleton.CurrentLocalRootHash;
305+
(!fullState && current != rootHash)
306+
.False_Or(RpcError.UnsupportedState.WithData($"fullState:{fullState},current:{current},rootHash:{rootHash}"));
307+
}
310308

311-
var scriptHash = Result.Ok_Or(() => UInt160.Parse(_params[1].AsString()), RpcError.InvalidParams.WithData($"Invalid script hash: {_params[1]}"));
312-
var prefix = Result.Ok_Or(() => Convert.FromBase64String(_params[2].AsString()), RpcError.InvalidParams.WithData($"Invalid prefix: {_params[2]}"));
313-
var key = Array.Empty<byte>();
314-
if (3 < _params.Count)
315-
key = Result.Ok_Or(() => Convert.FromBase64String(_params[3].AsString()), RpcError.InvalidParams.WithData($"Invalid key: {_params[3]}"));
309+
[RpcMethod]
310+
public JToken FindStates(UInt256 rootHash, UInt160 scriptHash, byte[] prefix, byte[] key = null, int count = 0)
311+
{
312+
CheckRootHash(rootHash);
316313

317-
int count = StateServiceSettings.Default.MaxFindResultItems;
318-
if (4 < _params.Count)
319-
count = Result.Ok_Or(() => int.Parse(_params[4].AsString()), RpcError.InvalidParams.WithData($"Invalid count: {_params[4]}"));
320-
if (StateServiceSettings.Default.MaxFindResultItems < count)
321-
count = StateServiceSettings.Default.MaxFindResultItems;
314+
key ??= [];
315+
count = count <= 0 ? StateServiceSettings.Default.MaxFindResultItems : count;
316+
count = Math.Min(count, StateServiceSettings.Default.MaxFindResultItems);
322317

323318
using var store = StateStore.Singleton.GetStoreSnapshot();
324319
var trie = new Trie(store, rootHash);
325320
var contract = GetHistoricalContractState(trie, scriptHash).NotNull_Or(RpcError.UnknownContract);
326-
var pkey = new StorageKey()
327-
{
328-
Id = contract.Id,
329-
Key = prefix,
330-
};
331-
var fkey = new StorageKey()
332-
{
333-
Id = pkey.Id,
334-
Key = key,
335-
};
321+
var pkey = new StorageKey() { Id = contract.Id, Key = prefix };
322+
var fkey = new StorageKey() { Id = pkey.Id, Key = key };
336323

337324
var json = new JObject();
338325
var jarr = new JArray();
@@ -364,16 +351,12 @@ public JToken FindStates(JArray _params)
364351
}
365352

366353
[RpcMethod]
367-
public JToken GetState(JArray _params)
354+
public JToken GetState(UInt256 rootHash, UInt160 scriptHash, byte[] key)
368355
{
369-
var rootHash = Result.Ok_Or(() => UInt256.Parse(_params[0].AsString()), RpcError.InvalidParams.WithData($"Invalid root hash: {_params[0]}"));
370-
(!StateServiceSettings.Default.FullState && StateStore.Singleton.CurrentLocalRootHash != rootHash).False_Or(RpcError.UnsupportedState);
356+
CheckRootHash(rootHash);
371357

372-
var scriptHash = Result.Ok_Or(() => UInt160.Parse(_params[1].AsString()), RpcError.InvalidParams.WithData($"Invalid script hash: {_params[1]}"));
373-
var key = Result.Ok_Or(() => Convert.FromBase64String(_params[2].AsString()), RpcError.InvalidParams.WithData($"Invalid key: {_params[2]}"));
374358
using var store = StateStore.Singleton.GetStoreSnapshot();
375359
var trie = new Trie(store, rootHash);
376-
377360
var contract = GetHistoricalContractState(trie, scriptHash).NotNull_Or(RpcError.UnknownContract);
378361
var skey = new StorageKey()
379362
{

src/Plugins/StateService/StateService.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,8 @@
1717
</None>
1818
</ItemGroup>
1919

20+
<ItemGroup>
21+
<InternalsVisibleTo Include="$(PackageId).Tests" />
22+
</ItemGroup>
23+
2024
</Project>

0 commit comments

Comments
 (0)