-
Notifications
You must be signed in to change notification settings - Fork 286
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
feat(copm): add Corda COPM implementation #3625
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jenniferlianne Looking pretty high quality in general, but as usual I have some requests. On top of the comments I left inline, please make sure to include a test case which verifies the plugin being functional while used through the API server (you'll most likely need a separate package because this one cannot depend on the API server due to circular dependency issues)
If you need examples just let me know.
...acti/plugin/cacti/plugin/copm/core/services/defaultservice/DefaultServiceOuterClassGrpcKt.kt
Outdated
Show resolved
Hide resolved
@@ -0,0 +1 @@ | |||
{"O=PartyA, L=London, C=GB@Corda_Network":{"host":"127.0.0.1","username":"clientUser1","password":"test","port":10006},"O=PartyB, L=London, C=GB@Corda_Network":{"host":"127.0.0.1","username":"clientUser1","password":"test","port":10009},"O=PartyA, L=London, C=GB@Corda_Network2":{"host":"127.0.0.1","username":"clientUser1","password":"test","port":30006},"O=PartyB, L=London, C=GB@Corda_Network2":{"host":"127.0.0.1","username":"clientUser1","password":"test","port":30009}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jenniferlianne Is this something that has to be shipped to production or just a testing aritfact? If it's only for testing then I'd recommend placing it somewhere under src/test/json/resources or similar like src/test/json/fixtures/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The file has been moved to /src/test/json
packages/cacti-plugin-copm-corda/src/main/typescript/plugin-copm-corda.ts
Outdated
Show resolved
Hide resolved
...plugin-copm-corda/src/main/kotlin/org/hyperledger/cacti/plugin/copm/corda/CordaAssetClaim.kt
Show resolved
Hide resolved
e107eb5
to
e04747c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jenniferlianne LGTM, thank you!
e04747c
to
69d8450
Compare
As mentioned on the call, the plugin is brought up via the ApiServer in both fabric and corda cases. Please see: |
packages/cacti-copm-core/Makefile
Outdated
@@ -0,0 +1,194 @@ | |||
WORKSPACE ?= $(shell realpath `pwd`/../../) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming this makefile is for starting the test networks and testing the copm end-to-end, as per structure of cacti, shouldn't this go to examples
instead of packages
?
@petermetz @VRamakrishna let me know if I make sense...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The file can be moved to cacti-copm-test.
cacti-copm-test uses the weaver samples to do end-to-end testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer it be moved to cacti-copm-test then. Let's completely separate the testing setup and logic from the generic components.
Ideally, I'd separate the test setups from the testing logic too, so that the testing logic could get a "spec" for the test setup and run generic tests on the network it's been given, but I think the Cacti package structure doesn't make this easy.
Moving this logic to the cacti-copm-test package seems to be the low-hanging-fruit option now, so let's do that. Perhaps later, we can refactor this to move the testnet launch logic to examples
(as @sandeepnRES suggests), thereby making cacti-copm-test also oblivious to the network structure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have moved all the Makefiles to cacti-copm-test. The Makefile_corda and Makefile_fabric files have 3 key targes: setup, lock-network, and pledge-network. These can be referenced either directly:
make -f Makefile_corda setup
or via wildcard targets in the main makefile:
make corda-setup
Future network types can follow this pattern.
packages/cacti-copm-core/src/main/proto/generated/openapi/models/asset_lock_claim_v1_pb.proto
Show resolved
Hide resolved
|
||
export class WeaverInteropConfiguration implements CopmIF.InteropConfiguration { | ||
private log: Logger; | ||
private weaverRelativePath = "../../../../../../weaver/"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are hardcoded paths in this file, since this is for testing purpose, may be make it more configurable, instead of hardcoded values?
Also this is also why I believe this package should be in examples and not in packages directory...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see this in several places above (and probably below) too. Given that this is a test package, I suppose hardcoding these paths is OK for now. But I wonder if you can allow such values to be passed through constructors instead, with the hardcoded paths then being moved to the commands that start and run the tests. That will make the code base more maintainable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay yeah agree with Rama.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is an example implementation of an abstract interface, and not meant to be re-used. In addition to the hard-coded location of the weaver fabric-cli json settings (stored in a file), the class also contains hard-coded reference to the weaver contracts.
In general, I would advise against forcing use of a local json file for data storage. While it's nice for getting an example system going, it scales poorly and precludes other options that would be easier for end-users to maintain.
@@ -0,0 +1,119 @@ | |||
package com.copmCorda |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this file is a sample? Asking because I don't see any hard coded values or anything specific to testnet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is in the sample
subfolder within the Corda plugin folder. That said, it does look like the logic is generic, though the remoteCopmContracts
variable seems specific to the asset exchange contracts.
} | ||
|
||
override fun getPledgeInfoCmd(claim: ValidatedClaimPledgedAssetV1Request): DLTransactionParams { | ||
return DLTransactionParams("com.cordaSimpleApplication.flow", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hardcoded value here, we should not refer sample application anywhere unless its a test-code. I'll suggest take it from parameters, or configurations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I just saw that this is inside sample
directory, so for every application someone needs to write code similar to these files? I'd prefer some config jsons/yaml instead of a kotlin code. But that's my preference, others can comment too if they are okay with it @VRamakrishna @petermetz
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. This is left up to the app for now (as opposed to json files) as in larger applications configuration info could be stored in, for instance, a database to make it easier to administer.
As I have mentioned elsewhere, I also think some of this application configuration could be pushed down to the contracts. As requested by @VRamakrishna , have a working draft where asset type registration is done in the interop contract: https://github.com/jenniferlianne/cacti/tree/copm_register_assets_in_chaincode
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay makes sense then.
Only thing is, if someone's application is to do remote call only once, they will have overhead to store everything in contract which will be useless after one call.
Its useful only if the remote transaction is used regularly.
} | ||
|
||
override fun getPledgeInfoCmd(claim: ValidatedClaimPledgedAssetV1Request): DLTransactionParams { | ||
return DLTransactionParams("com.cordaSimpleApplication.flow", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here... and below line 16 too
claim.sourceCert, | ||
claim.destinationAccount.organization, | ||
claim.destCert) | ||
return DLTransactionParams("simpleassettransfer","GetTokenAssetPledgeStatus", params ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here too hardcoded...
} | ||
|
||
override fun getPledgeInfoCmd(claim: ValidatedClaimPledgedAssetV1Request): DLTransactionParams { | ||
return DLTransactionParams("simpleassettransfer", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here.
} | ||
|
||
public getPackageName(): string { | ||
return `@hyperledger-cacti/cacti-plugin-copm-corda`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a way to get this programmatically?
Because the prefix might change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This follows the example of other cactus packages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to get this from a configuration file or an environmental variable. Personally, I'd suggest that other Cactus packages do something similar too, @petermetz, rather than hardcode such values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check if we can get it from package.json
, I think that would be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed on the project channel, this is outside of the scope of the copm project.
setup: build-local-deps server-docker-image | ||
|
||
|
||
pledge-network: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would suggest moving these makefile targets, like starting network and other components to tests, and those should ideally be not in packages
I believe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makefiles have been moved to cacti-copm-test and the cacti-plugin-copm-corda/src/test/kotlin directories.
@jenniferlianne Thank you for the PR, overall looks good to me. Just some small suggestions above I've shared. |
jest.config.js
Outdated
@@ -6,6 +6,7 @@ module.exports = { | |||
moduleNameMapper: { | |||
"^(\\.\\.?\\/.+)\\.jsx?$": "$1", | |||
}, | |||
modulePathIgnorePatterns: ["./weaver/core/identity-management"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This module does get exercised in Weaver transaction pipelines, though currently only the iin-agent
subfolder (other subfolders are placeholders for mechanisms that are specified in the Weaver RFCs but haven't been implemented yet).
Is this module causing any issues that necessitates its exclusion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is specific to the jest testing system, and there are no jest tests in weaver. The weaver convention of copying packages when building causes collisions in the haste map, so jest tests are unable to run. In my branch where I am building the dependencies as part of running the test, I have had to make additional exceptions.
packages/cacti-copm-core/Makefile
Outdated
make convert-compose-method2 && \ | ||
make start-server COMPOSE_ARG='--env-file docker/testnet-envs/.env.n2' | ||
|
||
# IIN -------------------------------------------------------------------------------------- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sandeepnRES I think we don't need the iin
agents for scenarios involving Corda, right? They won't do anything useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jenniferlianne Is this used for Fabric-Fabric testing too, or just ones that involve Corda networks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is used for testing all combinations. I have reorganized the Makefiles into cacti-copm-test.
} | ||
}, | ||
"operationId": "noopV1", | ||
"summary": "A no-op operation. May be used as a heath check", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"heath" --> "health"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected.
"source_certificate", | ||
"hash_info" | ||
], | ||
"required": ["lock_id", "destination", "asset", "hash_info"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why remove source
(or source_certificate
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the lock claim for the fabric NFT case to use the lock id instead of the asset agreement to claim the lock, to be consistent with the Corda implementation. After making this change you don't need information about source any more.
"post": { | ||
"x-hyperledger-cacti": { | ||
"http": { | ||
"path": "/api/v1/plugins/@hyperledger/cacti-plugin-copm/no-op", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change @hyperledger
--> @hyperledger-cacti
here and in other locations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -15,7 +16,8 @@ export type CopmContractNames = { | |||
}; | |||
|
|||
export type RemoteNetworkConfig = { | |||
channelName: string; | |||
channelName: string; // fabric-specific | |||
chaincode: string; // fabric-specific |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rename this to chaincodeName
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably networkName
instead of network
in the below line 21?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After further discussion on the project channel I have removed the chaincode and flowPackage variables from the remote network configuration struct as remote networks may use multiple chaincode packages in both fabric and corda. The network variable has been renamed networkName.
"author": { | ||
"name": "Hyperledger Cacti Contributors", | ||
"email": "[email protected]", | ||
"url": "https://www.hyperledger.org/use/cacti" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This URL now automatically redirects to https://www.lfdecentralizedtrust.org/projects/cacti, so perhaps you can change it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been updated.
} | ||
|
||
public networkNames(): string[] { | ||
return ["Corda_Network", "Corda_Network2"]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this should be hardcoded or lifted from a configuration file. @sandeepnRES ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the user identities and org names are also hardcoded below. I looked at the older code, where such values were hardcoded in the test
folders of the corda-interop-app
module, so if this package is the equivalent of that test suite, then I'm fine with the hardcoding.
69d8450
to
28bc627
Compare
cp $(WORKSPACE)/weaver/core/network/corda-interop-app/interop-workflows/build/libs/interop-workflows-*.jar localdeps | ||
cp $(WORKSPACE)/weaver/core/network/corda-interop-app/interop-contracts/build/libs/interop-contracts-*.jar localdeps | ||
cp $(WORKSPACE)/weaver/samples/corda/corda-simple-application/contracts-kotlin/build/libs/contracts-kotlin-*.jar localdeps | ||
cp $(WORKSPACE)/weaver/samples/corda/corda-simple-application/workflows-kotlin/build/libs/workflows-kotlin-*.jar localdeps |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can understand the rest, but why do you need weaver/samples/...
as dependencies?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current corda interop chaincode require passing down the asset-specific CommandData instances for issue and burn, as well as getting the pledgeId. This is something that could be avoided with asset type registration.
Here are the asset-specific commands being passed to the chaincode in the corda CLI:
Line 116 in 27a24dd
AssetContract.Commands.Delete(), |
"@hyperledger-cacti/cacti-copm-core": "2.0.0", | ||
"@hyperledger-cacti/cacti-copm-test": "2.0.0", | ||
"@hyperledger/cacti-weaver-protos-js": "2.0.0", | ||
"@hyperledger/cacti-weaver-sdk-fabric": "2.0.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2.0.0
version doesn't exist for the two packages above. Because of the organization change, the last version tagged under @hyperledger
was [2.0.0-rc.7](https://github.com/orgs/hyperledger/packages/container/cacti-weaver-driver-fabric/283162801?tag=2.0.0-rc.7)
. Weaver publish actions failed during the 2.0.0
release because paths were not updated. These actions should succeed when the next release (2.0.1
) is done, hopefully in the next few days. So you have two options: (1) wait for the next release and then update these version numbers here and elsewhere in your code, or (2) use the last release version 2.0.0-rc.7
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These refer to the local monorepo versions, which is why they are able to compile. The packages are built in the cactus way, with npm run configure
at the top level. This uses the tsconfig file at at the root level which builds the packages in a specific order and keeps a reference of local packages. One of the challenges of this project was getting everything to build successfully given the differences in build philosophy between cactus and weaver.
f9859fc
to
ac09efd
Compare
Primary change: Implements COPM primitives for Corda as a cacti plugin. The implementation follows the model of the Corda ledger connector plugin, where a typescript pass-through implementation is registered on the plugin server, and commands are implemented on a separate grpc server in the Kotlin Spring framework. Secondary changes: - The lock claim protobuf structure was updated to reduce the number of parameters. - A no-op endpoint was added, per project specification - The format of the inter-network command for requesting the status of a pledge varies by remote network type and asset. Adds a function to the typescript interop configuration interface to supply the appropriate command given the remote network and asset. - Adds test package to test combinations of network types - Updates CI script to use new testing framework - Updates linter ignore to include weaver build directories, allowing yarn lint to pass on a system where weaver libraries have been built. Also excludes docs directory to avoid linting minified js from documentation packages. Signed-off-by: Jennifer Bell <[email protected]>
ac09efd
to
f88723e
Compare
Primary change:
Implements COPM primitives for Corda as a cacti plugin. The implementation follows the model of
the Corda ledger connector plugin, where a typescript pass-through implementation is registered on the plugin server, and commands are implemented on a separate grpc server in the Kotlin Spring framework.
Secondary changes:
Pull Request Requirements
upstream/main
branch and squashed into single commit to help maintainers review it more efficient and to avoid spaghetti git commit graphs that obfuscate which commit did exactly what change, when and, why.-s
flag when usinggit commit
command. You may refer to this link for more information.Character Limit
A Must Read for Beginners
For rebasing and squashing, here's a must read guide for beginners.