Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to interops calls in SDK #157

Merged
7 commits merged into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,6 @@ jobs:
with:
submodules: recursive

- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ env.RUST_VERSION }}
override: true
components: rustfmt, clippy

- name: Format Rust Project
run: cargo fmt --manifest-path=./backend/rust-bindings/Cargo.toml --check

- name: Clippy Rust Project
run: cargo clippy --manifest-path=./backend/rust-bindings/Cargo.toml --tests --release -- --no-deps

- name: Build Rust Project
run: cargo build --manifest-path=./backend/rust-bindings/Cargo.toml --release

- name: Test Rust Project
run: cargo test --manifest-path=./backend/rust-bindings/Cargo.toml --release

- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
Expand Down
7 changes: 0 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,6 @@ See the description of `CCDSCAN_BACKEND_PORT` for an explanation of why Mac user

In `./timescaledb-restore` a description is given how to spin up and restore CCD scan database locally from Stage- or Testnet backups.

## Rust-bindings

The CCD scan does interops to compiled code from rust. The `.csproj` file is dependent on compiled binaries which is why one manually needs to run below
```
make build-rust-bindings

```
This is only needed to be done once. They will be recompiled on later changes as part of `dotnet build`.

## Unstable features
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using Application.Aggregates.Contract.Types;
using Application.Api.GraphQL;
using Application.Api.GraphQL.EfCore;
using Application.Interop;
using Concordium.Sdk.Types;
using Dapper;
using HotChocolate;
Expand Down Expand Up @@ -101,78 +100,35 @@ internal sealed record ModuleSourceInfo(string ModuleSource, string? Schema, Mod
{
internal static async Task<ModuleSourceInfo> Create(IContractNodeClient client, ulong blockHeight, string moduleReference)
{
var (versionedModuleSource, moduleSource, module) = await GetWasmModule(client, blockHeight, moduleReference);
var schema = GetModuleSchema(module, versionedModuleSource);
return new ModuleSourceInfo(moduleSource, schema?.Schema, schema?.SchemaVersion);
var (versionedModuleSource, moduleSource) = await GetVersionedModuleSchema(client, blockHeight, moduleReference);
return new ModuleSourceInfo(moduleSource, versionedModuleSource?.Schema != null ? Convert.ToHexString(versionedModuleSource.Schema) : null, versionedModuleSource?.Version);
}

private static async Task<(VersionedModuleSource VersionedModuleSource, string ModuleSource, WebAssembly.Module Module)> GetWasmModule(IContractNodeClient client, ulong blockHeight, string moduleReference)
private static async Task<(VersionedModuleSchema? versionedModuleSchema, string ModuleSource)> GetVersionedModuleSchema(IContractNodeClient client, ulong blockHeight, string moduleReference)
{
var absolute = new Absolute(blockHeight);
var moduleRef = new ModuleReference(moduleReference);

var moduleSourceAsync = await client.GetModuleSourceAsync(absolute, moduleRef);
var versionedModuleSource = moduleSourceAsync.Response;
var versionedModuleSchema = versionedModuleSource.GetModuleSchema();
var moduleSourceHex = Convert.ToHexString(versionedModuleSource.Source);

using var stream = new MemoryStream(versionedModuleSource.Source);
var moduleWasm = WebAssembly.Module.ReadFromBinary(stream);
return (versionedModuleSource, moduleSourceHex, moduleWasm);
}

/// <summary>
/// The module can contain a schema in one of two different custom sections.
/// The supported sections depend on the module version.
/// The schema version can be either defined by the section name or embedded into the actual schema:
/// - Both v0 and v1 modules support the section 'concordium-schema' where the schema includes the version.
/// - For v0 modules this is always a v0 schema.
/// - For v1 modules this can be a v1, v2, or v3 schema.
///- V0 modules additionally support section 'concordium-schema-v1' which always contain a v0 schema (not a typo).
/// - V1 modules additionally support section 'concordium-schema-v2' which always contain a v1 schema (not a typo).
/// The section 'concordium-schema' is the most common and is what the current tooling produces.
/// </summary>
private static (string Schema, ModuleSchemaVersion SchemaVersion)? GetModuleSchema(WebAssembly.Module module, VersionedModuleSource moduleSource)
{
switch (moduleSource)
{
case ModuleV0:
if (GetSchemaFromWasmCustomSection(module, "concordium-schema", out var moduleV0SchemaUndefined))
{
return (moduleV0SchemaUndefined!, Application.Aggregates.Contract.Types.ModuleSchemaVersion.Undefined); // always v0
}
if (GetSchemaFromWasmCustomSection(module, "concordium-schema-v1", out var moduleV0SchemaV0))
{
return (moduleV0SchemaV0!, Application.Aggregates.Contract.Types.ModuleSchemaVersion.V0); // v0 (not a typo)
}
return null;
case ModuleV1:
if (GetSchemaFromWasmCustomSection(module, "concordium-schema", out var moduleV1SchemaUndefined))
{
return (moduleV1SchemaUndefined!, Application.Aggregates.Contract.Types.ModuleSchemaVersion.Undefined); // v1, v2, or v3
}
if (GetSchemaFromWasmCustomSection(module, "concordium-schema-v2", out var moduleV1SchemaV1))
{
return (moduleV1SchemaV1!, Application.Aggregates.Contract.Types.ModuleSchemaVersion.V1); // v1 (not a typo)
}
return null;
default:
throw new ArgumentOutOfRangeException(nameof(moduleSource));
}
}

private static bool GetSchemaFromWasmCustomSection(WebAssembly.Module module, string entryKey, out string? schema)
{
schema = null;
var customSection = module.CustomSections
.SingleOrDefault(section => section.Name.Equals(entryKey, StringComparison.InvariantCulture));

if (customSection == null) return false;

schema = Convert.ToHexString(customSection.Content.ToArray());
return true;
return (versionedModuleSchema, moduleSourceHex);
}
}

internal VersionedModuleSchema? GetVersionedModuleSchema()
{
return HasSchema() ? new VersionedModuleSchema(Convert.FromHexString(Schema!), SchemaVersion!.Value): null;
}

/// <summary>
/// Checks both <see cref="Schema"/> and <see cref="SchemaVersion"/> is not null.
/// </summary>
private bool HasSchema() => Schema != null && SchemaVersion != null;


[ExtendObjectType(typeof(Query))]
public class ModuleReferenceEventQuery
{
Expand Down Expand Up @@ -215,14 +171,9 @@ public sealed class ModuleReferenceEventExtensions
/// </summary>
public string? GetDisplaySchema([Parent] ModuleReferenceEvent module)
{
if (module.Schema == null)
{
return null;
}

try
{
return InteropBinding.SchemaDisplay(module.Schema, module.SchemaVersion);
return module.GetVersionedModuleSchema()?.GetDeserializedSchema().ToString();
}
catch (Exception e)
{
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -188,16 +188,16 @@ ulong transactionIndex
using var _ = LogContext.PushProperty("ContractAddress", ContractAddress.AsString);

var moduleReferenceEvent = await moduleReadonlyRepository.GetModuleReferenceEventAtAsync(ContractAddress, blockHeight, transactionIndex, 0);
if (moduleReferenceEvent.Schema == null)
var versionedModuleSchema = moduleReferenceEvent.GetVersionedModuleSchema();
if (versionedModuleSchema == null)
{
return null;
}

var receiveName = new ReceiveName(ReceiveName);
var message = receiveName.DeserializeMessage(
MessageAsHex,
moduleReferenceEvent.Schema,
moduleReferenceEvent.SchemaVersion,
versionedModuleSchema,
logger,
moduleReferenceEvent.ModuleReference,
nameof(RejectedReceive)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using Application.Aggregates.Contract.Entities;
using Application.Api.GraphQL.Bakers;
using Application.Exceptions;
using Application.Interop;
using Concordium.Sdk.Types;
using HotChocolate.Types;
using Serilog.Context;
Expand All @@ -12,6 +11,7 @@
using AccountTransactionDetails = Concordium.Sdk.Types.AccountTransactionDetails;
using BakerPoolOpenStatus = Application.Api.GraphQL.Bakers.BakerPoolOpenStatus;
using BakerStakeUpdatedData = Concordium.Sdk.Types.BakerStakeUpdatedData;
using ContractEvent = Concordium.Sdk.Types.ContractEvent;
using EncryptedAmountRemovedEvent = Concordium.Sdk.Types.EncryptedAmountRemovedEvent;
using NewEncryptedAmountEvent = Concordium.Sdk.Types.NewEncryptedAmountEvent;
using ReceiveName = Application.Types.ReceiveName;
Expand Down Expand Up @@ -198,7 +198,8 @@ internal static IEnumerable<TransactionResultEvent> ToIter(ContractUpdateIssued
string instigator
)
{
if (moduleReferenceEvent.Schema == null)
var versionedModuleSchema = moduleReferenceEvent.GetVersionedModuleSchema();
if (versionedModuleSchema == null)
{
return null;
}
Expand All @@ -208,13 +209,8 @@ string instigator
try
{
var eventAsHex = eventsAsHex[i];
var eventContract = InteropBinding.GetEventContract(moduleReferenceEvent.Schema, contractName, eventAsHex, moduleReferenceEvent.SchemaVersion);
if (eventContract == null)
{
logger.Warning("{ContractName} on {Module} got null returned when parsing hexadecimal event {EventAsHex}", contractName, moduleReferenceEvent.ModuleReference, eventAsHex);
return null;
}
events[i] = eventContract;
var deserializeEvent = new ContractEvent(Convert.FromHexString(eventAsHex)).GetDeserializeEvent(versionedModuleSchema, new ContractIdentifier(contractName));
events[i] = deserializeEvent.ToString();
}
catch (InteropBindingException e)
{
Expand Down Expand Up @@ -580,10 +576,7 @@ internal static ContractInitialized From(Concordium.Sdk.Types.ContractInitialize
using var _ = LogContext.PushProperty("ContractAddress", ContractAddress.AsString);

var moduleReferenceEvent = await moduleReadonlyRepository.GetModuleReferenceEventAsync(ModuleRef);
if (moduleReferenceEvent.Schema == null)
{
return null;
}

var contractName = GetName();

return GetParsedEvents(moduleReferenceEvent, contractName, EventsAsHex, logger, nameof(ContractInitialized));
Expand Down Expand Up @@ -660,7 +653,8 @@ uint eventIndex
using var _ = LogContext.PushProperty("ContractAddress", ContractAddress.AsString);

var moduleReferenceEvent = await moduleReadonlyRepository.GetModuleReferenceEventAtAsync(ContractAddress, blockHeight, transactionIndex, eventIndex);
if (moduleReferenceEvent.Schema == null)
var versionedModuleSchema = moduleReferenceEvent.GetVersionedModuleSchema();
if (versionedModuleSchema == null)
{
return null;
}
Expand All @@ -670,8 +664,7 @@ uint eventIndex
var receiveName = new ReceiveName(ReceiveName);
var message = receiveName.DeserializeMessage(
MessageAsHex,
moduleReferenceEvent.Schema,
moduleReferenceEvent.SchemaVersion,
versionedModuleSchema,
logger,
moduleReferenceEvent.ModuleReference,
nameof(ContractUpdated)
Expand Down
33 changes: 2 additions & 31 deletions backend/Application/Application.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<Version>1.8.3</Version>
<Version>1.8.4</Version>
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
<RunRustBuild>true</RunRustBuild>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="ConcordiumNetSdk" Version="4.1.0" />
<PackageReference Include="ConcordiumNetSdk" Version="4.2.1" />
<PackageReference Include="Dapper" Version="2.0.123" />
<PackageReference Include="dbup-postgresql" Version="4.5.0" />
<PackageReference Include="HotChocolate.AspNetCore" Version="13.5.1" />
Expand Down Expand Up @@ -44,34 +44,5 @@
<ItemGroup>
<InternalsVisibleTo Include="Tests" />
</ItemGroup>
<ItemGroup>
<!-- Include librust.dll on Windows -->
<None Include="../rust-bindings/target/release/librust_bindings.dll" Condition="'$(IsWindows)'=='true'">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<!-- Include librust.dylib on macOS -->
<None Include="../rust-bindings/target/release/librust_bindings.dylib" Condition="'$(IsOSX)'=='true'">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<!-- Include librust.so on Linux -->
<None Include="../rust-bindings/target/release/librust_bindings.so" Condition="'$(IsLinux)'=='true'">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

<Target Name="BuildRustProject" BeforeTargets="Build" Condition="$(RunRustBuild)">
<Exec Command="cargo build --manifest-path=../rust-bindings/Cargo.toml --release" />
</Target>

<ItemGroup>
<Content Include="..\rust-bindings\Cargo.toml">
<Link>rust-bindings\Cargo.toml</Link>
</Content>
<Content Include="..\rust-bindings\src\lib.rs">
<Link>rust-bindings\src\lib.rs</Link>
</Content>
<Content Include="..\rust-bindings\test-data\cis2_wCCD_sub">
<Link>rust-bindings\test-data\cis2_wCCD_sub</Link>
</Content>
</ItemGroup>
</Project>
Loading
Loading