Skip to content

Commit

Permalink
V3Call testing
Browse files Browse the repository at this point in the history
  • Loading branch information
Gekctek committed Nov 5, 2024
1 parent 6b197a2 commit 153177f
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 23 deletions.
16 changes: 3 additions & 13 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,10 @@
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": ".NET Core Launch (console)",
"type": "coreclr",
"name": "Sample.RestAPI",
"type": "dotnet",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/src/Sample/bin/Debug/net8.0/Sample.dll",
"args": [],
"cwd": "${workspaceFolder}/src/Sample",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
"projectPath": "${workspaceFolder}/samples/Sample.RestAPI/Sample.RestAPI.csproj"
},
{
"name": ".NET Core Attach",
Expand Down
6 changes: 5 additions & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
"${workspaceFolder}",
"/property:GenerateFullPaths=true"
],
"problemMatcher": "$msCompile"
"problemMatcher": "$msCompile",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
4 changes: 2 additions & 2 deletions samples/Sample.PocketIC/PocketIc.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public async Task HttpGateway_CounterWasm__Basic__Valid()


CancellationTokenSource cts = new(TimeSpan.FromSeconds(5));
CandidArg incResponseArg = await agent.CallAndWaitAsync(canisterId, "inc", CandidArg.Empty(), cancellationToken: cts.Token);
CandidArg incResponseArg = await agent.CallAsync(canisterId, "inc", CandidArg.Empty(), cancellationToken: cts.Token);
Assert.Equal(CandidArg.Empty(), incResponseArg);

// This alternative also doesnt work
Expand All @@ -137,7 +137,7 @@ public async Task HttpGateway_CounterWasm__Basic__Valid()
Assert.Equal((UnboundedUInt)1, getResponseValue);

CandidArg setRequestArg = CandidArg.FromObjects((UnboundedUInt)10);
CandidArg setResponseArg = await agent.CallAndWaitAsync(canisterId, "set", setRequestArg);
CandidArg setResponseArg = await agent.CallAsync(canisterId, "set", setRequestArg);
Assert.Equal(CandidArg.Empty(), setResponseArg);

getResponse = await agent.QueryAsync(canisterId, "get", CandidArg.Empty());
Expand Down
8 changes: 8 additions & 0 deletions samples/Sample.RestAPI/Controllers/GovernanceController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,13 @@ public async Task<IActionResult> GetProposalInfo(ulong id)
OptionalValue<ProposalInfo> info = await this.Client.GetProposalInfo(id);
return this.Ok(info);
}

[Route("rewards")]
[HttpGet]
public async Task<IActionResult> GetRewards()
{
Result4 rewards = await this.Client.GetMonthlyNodeProviderRewards();
return this.Ok(rewards);
}
}
}
28 changes: 24 additions & 4 deletions src/Agent/API.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions src/Agent/Agents/HttpAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,14 @@ public async Task<CandidArg> CallAsync(

byte[] cborBytes = await httpResponse.GetContentAsync();
var reader = new CborReader(cborBytes);
Certificate certificate = Certificate.FromCbor(reader);
V3CallResponse v3CallResponse = V3CallResponse.ReadCbor(reader);

SubjectPublicKeyInfo rootPublicKey = await this.GetRootKeyAsync(cancellationToken);
if (!certificate.IsValid(this.bls, rootPublicKey))
if (!v3CallResponse.Certificate.IsValid(this.bls, rootPublicKey))
{
throw new InvalidCertificateException("Certificate signature does not match the IC public key");
}
HashTree? requestStatusData = certificate.Tree.GetValueOrDefault(StatePath.FromSegments("request_status", requestId.RawValue));
HashTree? requestStatusData = v3CallResponse.Certificate.Tree.GetValueOrDefault(StatePath.FromSegments("request_status", requestId.RawValue));
RequestStatus? requestStatus = ParseRequestStatus(requestStatusData);
switch (requestStatus?.Type)
{
Expand Down
75 changes: 75 additions & 0 deletions src/Agent/Responses/V3CallResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using System.Diagnostics;
using System.Formats.Cbor;
using EdjCase.ICP.Agent.Models;
using EdjCase.ICP.Candid.Models;

namespace EdjCase.ICP.Agent.Responses
{
/// <summary>
/// Model for a reponse to a read state request
/// </summary>
public class V3CallResponse
{
/// <summary>
/// The status of the call ('replied', 'rejected', 'done)
/// </summary>
public string Status { get; }
/// <summary>
/// The certificate data of the current canister state
/// </summary>
public Certificate Certificate { get; }

/// <param name="status">The status of the call ('replied', 'rejected', 'done)</param>
/// <param name="certificate">The certificate data of the current canister state</param>
/// <exception cref="ArgumentNullException"></exception>
public V3CallResponse(string status, Certificate certificate)
{
this.Status = status ?? throw new ArgumentNullException(nameof(status));
this.Certificate = certificate ?? throw new ArgumentNullException(nameof(certificate));
}


internal static V3CallResponse ReadCbor(CborReader reader)
{
if (reader.ReadTag() != CborTag.SelfDescribeCbor)
{
throw new CborContentException("Expected self describe tag");
}
Certificate? certificate = null;
string? status = null;
reader.ReadStartMap();
while (reader.PeekState() != CborReaderState.EndMap)
{
string field = reader.ReadTextString();
switch (field)
{
case "certificate":
var certReader = new CborReader(reader.ReadByteString());
certificate = Certificate.FromCbor(certReader);
break;
case "status":
status = reader.ReadTextString();
break;
default:
Debug.WriteLine($"Unknown field '{field}' in v3 call response");
reader.SkipValue();
break;
}
}
reader.ReadEndMap();

if (status == null)
{
throw new CborContentException("Missing field: status");
}

if (certificate == null)
{
throw new CborContentException("Missing field: certificate");
}

return new V3CallResponse(status, certificate);
}
}
}

0 comments on commit 153177f

Please sign in to comment.