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

CORE-17494: Add check to CPB creation to ensure that 2 CPKs don't share a name #596

Merged
merged 12 commits into from
Dec 6, 2023

Conversation

malachyb
Copy link
Contributor

@malachyb malachyb commented Oct 25, 2023

As part of #595, we are adding the ability for users to set an identifiable name for their own CPKs. However, we do not want 2 CPKs in the same CPB to have the same name, so we need to add a check in the CPB plugin to ensure that names are not reused within it.

@malachyb malachyb marked this pull request as ready for review October 25, 2023 15:18
@@ -55,6 +58,8 @@ public CpbTask() {
m.getAttributes().put(CPB_NAME_ATTRIBUTE, getArchiveBaseName());
m.getAttributes().put(CPB_VERSION_ATTRIBUTE, getArchiveVersion());
});

cpkNames = new HashMap<>();

Choose a reason for hiding this comment

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

I'm not a gradle expert, but having a static you reset on each instantiation of this type strikes me as a bit odd. Could you explain it more?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not entirely sure why but for some reason when I don't reset it then it triggers the error. I think it might be persisting through multiple calls of the same plugin within the same project

Choose a reason for hiding this comment

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

I think what we are doing here (resetting it) suggests it should be made an instance property.

However it's interesting. I would expect this process to be one-off? I.e. pack CPKs intended for a single CPB and then exits? What more CPKs are there being processed/ output-ed by the prints added?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That fixed the issue, thanks

System.out.println(cpkCordappName);
if (cpkNames.containsKey(cpkCordappName)) {
if (cpkNames.get(cpkCordappName) == 1) {
cpkNames.put(cpkCordappName, 2);

Choose a reason for hiding this comment

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

So you're allowing two cpks of the same name? I assume this is one for workflow and one for contract? Is it possible to make this check a bit more foolproof?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The plugin seems to iterate through each CPK twice or for some other reason calls this function twice on each CPK, so one instance of the name appearing will be counted twice

Choose a reason for hiding this comment

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

You should be able to call this function as many times as you like. Shouldn't cpkNames be local to this method?

Maybe it would help get to the bottom of this behaviour if you logged all the cpkNames? I don't think we can merge this without knowing what's going on.

@@ -61,18 +65,29 @@ public CpbTask() {
@NotNull
public AbstractCopyTask from(@NotNull Object... args) {
return super.from(args, copySpec ->
copySpec.exclude(this::isCPK)

Choose a reason for hiding this comment

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

(this is how it used to be so nothing to do with the PR)

Not a Gradle expert but I think it looks to me a bit weird to exclude when isCPK.

} else {
cpkNames.put(cpkCordappName, manifest);
}
}
return cpkType != null && EXCLUDED_CPK_TYPES.contains(cpkType.toLowerCase());

Choose a reason for hiding this comment

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

(again before this PR)

the body of this function seems a bit misaligned with its name? The initial check (at line 73) does check if it's a CPK but then here we check if its Corda-CPK-Type (which I am not sure we currently use) is of of excluded cpk types?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It might make more sense if I split it into 3 functions that all get called by isValidCPK. Or maybe just 2 if Corda-CPK-Type isn't used anywhere?

Choose a reason for hiding this comment

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

Yes, I'd not spotted this before but

copySpec.exclude(this::isCPK)

seems to be excluding based on a predicate.

That would make "hijacking" this method fairly inappropriate for this same check. I'd revert this method to isCPK and make this logic it's own thing separate from that process.

Comment on lines 79 to 90
Manifest manifest = cpkStream.getManifest();
String cpkType = manifest.getMainAttributes().getValue(CORDA_CPK_TYPE);
String cpkCordappName = manifest.getMainAttributes().getValue(CPK_CORDAPP_NAME);
if (cpkCordappName != null) {
if (cpkNames.containsKey(cpkCordappName)) {
if (!cpkNames.get(cpkCordappName).equals(manifest)) {
throw new InvalidUserDataException("Two CPKs may not share a cordappCpkName. Error in " + cpkCordappName);
}
} else {
cpkNames.put(cpkCordappName, manifest);
}
}
Copy link

@kyriathar kyriathar Nov 17, 2023

Choose a reason for hiding this comment

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

Perhaps we could try and extract this logic into some function named checkCordappNameUniqueness? This function is about checking whether it's isCPK/ isValidCPK. But this is about 2 CPKs sharing the same cordapp name (in the same CPB).

@@ -31,6 +34,7 @@ public class CpbTask extends Jar {
public static final String CPB_VERSION_ATTRIBUTE = "Corda-CPB-Version";
public static final String CPB_FORMAT_VERSION = "Corda-CPB-Format";
public static final String CPB_CURRENT_FORMAT_VERSION = "2.0";
private final HashMap<String, Manifest> cpkNames = new HashMap<>();

Choose a reason for hiding this comment

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

Suggested change
private final HashMap<String, Manifest> cpkNames = new HashMap<>();
private final Map<String, Manifest> cpkNames = new HashMap<>();

@@ -31,6 +34,7 @@ public class CpbTask extends Jar {
public static final String CPB_VERSION_ATTRIBUTE = "Corda-CPB-Version";
public static final String CPB_FORMAT_VERSION = "Corda-CPB-Format";
public static final String CPB_CURRENT_FORMAT_VERSION = "2.0";
private final HashMap<String, Manifest> cpkNames = new HashMap<>();
Copy link

@kyriathar kyriathar Nov 17, 2023

Choose a reason for hiding this comment

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

I think worth adding a short note on why we decided to map to Manifests

Copy link

@kyriathar kyriathar left a comment

Choose a reason for hiding this comment

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

LGTM

@malachyb malachyb merged commit 39f3341 into malachy/CORE-13259 Dec 6, 2023
5 checks passed
@malachyb malachyb deleted the malachy/CORE-17494 branch December 6, 2023 15:52
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.

3 participants