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

addition of c# wrapper with libs for windows and macos #66

Merged
merged 42 commits into from
Feb 14, 2024
Merged

Conversation

smartrics
Copy link
Member

No description provided.

@smartrics smartrics requested a review from conbon February 9, 2024 14:53
ffi/README.md Show resolved Hide resolved
ffi/README.md Outdated Show resolved Hide resolved
agentIdentity.Did, agentIdentity.KeyName, Tools.EnsureHashPrefix(agentIdentity.Id), agentIdentity.Seed,
twinIdentity.Did, twinIdentity.KeyName, Tools.EnsureHashPrefix(twinIdentity.Id), twinIdentity.Seed,
Tools.EnsureHashPrefix(cDelegationName)));
if(result != null) {
Copy link
Member

@vtermanis vtermanis Feb 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Shouldn't a level above be throwing exceptions and this class only is a pass-through wrapper?
  2. Tools.Ensure* (I know I mentioned it elsewhere already, but) wouldn't it be better to just pass through and let the golang lib validate?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I repeatedly endup writing the ensure in the application - i find it counter intuitive to have to prepend the string with a #

I am not strong about it but if you prefer not to do it in the Golang layer then we need to document it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you prefer not to do it in the Golang layer

Maybe I worded that badly - I am suggesting we do validate extra stuff in golang level (not even FFI) so that each of the FFI wrappers can be thinner and validation is consistent across languages.

/// <returns>a new agent identity.</returns>
public AgentIdentity CreateAgentIdentity(string seed, string cKeyName, string cId)
{
string did = Tools.InvokeGoFunction(() => IdLib.CreateAgentIdentity(ResolverAddress, cKeyName, Tools.EnsureHashPrefix(cId), seed));
Copy link
Member

@vtermanis vtermanis Feb 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Tools.Ensure* usage: Surely the golang layer should be performing validation like this and if not we should add it and keep the wrappers as thin as possible. (The extra logic conditions would all need tests to verify)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the golang validation kicks in if the # isn't present. I don't know why the library doesn't do it.
it's a bloody pain - so I decided to add it into the application layer.
but I choose not to touch the golang layer including ffi.
I am happy to remove it if it's a bother but then we need to document it somewhere for the users

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also - validation and input sanitisation should be done as early as possible

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validation and input sanitisation should be done as early as possible

Right, but C#/Java/FFI layers should be very thin so I'm not sure I agree that this means it should happen there. What's wrong with "throwing" things early on behind the actual golang API itself?
But I appreciate that's not done yet. This sounds like an improvement to make soon (but obv. not now).

}

// Remove the trailing slash from the string
public static string RemoveTrailingSlash(string input)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this? IIRC // or / shouldn't matter and the resolver should handle it fine anyway.
This again is extra logic in the wrapper which we shouldn't need (and if we do - why not make all of them behave the same by stuffing into the ffi or golang layer?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I usually validate input as early as possible - I understand the concern and it's a good idea to validate in the ffi. but it's not bad to do it in the client either

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and it's a good idea to validate in the ffi.

I actually mean validate in golang, not FFI (keep ffi & users of FFI thin)

return input.TrimEnd('/');
}

public static string EnsureHashPrefix(string input)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't just ensure but also disallow a hash anywhere else. (As per other comments - why not remove this and let golang layer handle)

@@ -328,7 +348,7 @@ func FreeUpCString(pointer *C.char) {
}

func createIdentity(
isUser bool, // true for userId, false for agentId
idDoc idDocType, // true for userId, false for agentId
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update comment

Copy link
Member Author

@smartrics smartrics left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@StephanieBracaloni @vtermanis thank you for the review - I hope I have addressed all the points. Two important things
1 - java is only there because I use it in my code. I will create separately a branch and remove it since it's not for external parties (I am maintaining a branch in my personal github for expediency)

2 - this is the first release to a single non paying user of this library. I suggest we skip automation and proper release packaging until we have a second user, for expediency and time, also I am hoping we get some proper feedback on the API. If you feel strong about creating GH actions to build it, I'd be happy to contribute... I'll leave it to you and JJ to decide

3 - we still need to find a place where we can store the binary files. I originally asked @conbon to commit the binaries in the lib directory for simplicity - again if this is not desired we can do the GH actions.

@StephanieBracaloni
Copy link
Contributor

@StephanieBracaloni @vtermanis thank you for the review - I hope I have addressed all the points. Two important things 1 - java is only there because I use it in my code. I will create separately a branch and remove it since it's not for external parties (I am maintaining a branch in my personal github for expediency)

2 - this is the first release to a single non paying user of this library. I suggest we skip automation and proper release packaging until we have a second user, for expediency and time, also I am hoping we get some proper feedback on the API. If you feel strong about creating GH actions to build it, I'd be happy to contribute... I'll leave it to you and JJ to decide

3 - we still need to find a place where we can store the binary files. I originally asked @conbon to commit the binaries in the lib directory for simplicity - again if this is not desired we can do the GH actions.

@smartrics Thank you for addressing the review feedback. I completely understand the need to keep it simple and move fast but I don't 100% agree with the lack of testing because we only have a non-paying user because it will be a pain for a linux developer to fix something and be sure it still works, ...

However this is just a bunch of recommendations since @JJCassidyIotics mentioned you will maintain the C# FFI wrapper and deal with the updates.
When you will decide to move to a more robust approach do not hesitate to let us know so we can prioritise it.

@smartrics
Copy link
Member Author

I am happy to support this for the time being and understood that this requires testing and automation. As soon as we have a second user of this library, I'll hand it over to engineering for proper production ready release.

@StephanieBracaloni
Copy link
Contributor

I am happy to support this for the time being and understood that this requires testing and automation. As soon as we have a second user of this library, I'll hand it over to engineering for proper production ready release.

Understood, this is a good compromise.
It can be made production-ready when we will have an additional user or when changes will be required.
I just want to highlight it will need to:

  • have tests
  • have a proper release process
    before being handed over to the engineering team. (of course, we will help with GH when it will be necessary).

@vtermanis
Copy link
Member

@smartrics - thank you for considering my feedback and it's great to have an initial C# option for users to trial. In summary (as you already know), my main two areas of concern are:

  1. Logic (validation/other) that is common in each wrapper (be it C#/Java/other) that could instead easily be added to the Golang layer (not even FFI). We should be able to offer the same experience / validation for all of the libs and only have to fix / improve it in one place. I disagree with the "validate early" argument - if the wrappers are thin then validating in Golang at first port of call is in my view just as valid (from a security perspective).

  2. Releases: The GH actions generate an Linux x86_64 FFI binary but that is it. It would be nice to include the officially supported FFI wrappers in that too, or at least the FFI binary builds that users might like. (It should be relatively easy to at least build the .so / .dll / dynlibs).

But I appreciate that for (1) we'd need to improve the Golang lib itself and (2) needs testing etc. I hope those we can consider in the near future.
And - if the Java one is indeed "beta" only - should we mark it as such? (So it's clear what we're not supporting currently.)

Copy link
Member

@vtermanis vtermanis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️

@smartrics smartrics merged commit c8ef295 into v3 Feb 14, 2024
4 checks passed
@smartrics smartrics deleted the csharp-ffi branch February 14, 2024 13:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants