diff --git a/CHANGELOG.md b/CHANGELOG.md index a837a7e1b..3155dbbb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,8 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline ### Features -* bump snapshot version to 4.12.1 [#2058](https://github.com/web3j/web3j/pull/2058) +* bump snapshot version to 4.12.1 [#2058](https://github.com/hyperledger/web3j/pull/2058) +* Update maintainer requirements status [#2064](https://github.com/hyperledger/web3j/pull/2064) ### BREAKING CHANGES diff --git a/MAINTAINERS.md b/MAINTAINERS.md index c64310bc1..7b2df5f33 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -1,16 +1,17 @@ Maintainers =========== + **Active Maintainers** -| Name | GitHub | Chat | -|----------------|--------|-----| -| Conor Svensson | [conor10][conor10] | conor10 | -| Andrii | [andrii-kl][andrii-kl] | andrii-kl | -| George Ţebrean | [gtebrean][gtebrean] | gdev#2230 | -| Nischal Sharma | [NickSneo][NickSneo] | nicks1106 | - + +| Name | Github | LFID | +|----------------|------------------------|-----------| +| Andrii Kliui | [andrii-kl][andrii-kl] | andrii.k | +| Conor Svensson | [conor10][conor10] | conor | +| George Ţebrean | [gtebrean][gtebrean] | gtebrean | +| Nischal Sharma | [NickSneo][NickSneo] | nicks1106 | [conor10]: https://github.com/conor10 [gtebrean]: https://github.com/gtebrean @@ -21,8 +22,95 @@ Maintainers **Emeritus Maintainers** -| Name | GitHub | Chat | -|------|------------------|------| -|Christian Felde | [cfelde][cfelde] | cfelde | +| Name | Github | LFID | +|-----------------|---------------------|---------| +| Christian Felde | [cfelde][cfelde] | cfelde | [cfelde]: https://github.com/cfelde + +## Becoming a Maintainer + +Web3J welcomes community contribution. +Each community member may progress to become a maintainer. + +How to become a maintainer: + +- Contribute significantly to the code in web3j repositories. + +### Maintainers contribution requirement + +The requirement to be able to be proposed as a maintainer is: + +- 5 significant changes on code have been authored in this repos by the proposed maintainer and accepted (merged PRs). + +### Maintainers approval process + +The following steps must occur for a contributor to be "upgraded" as a maintainer: + +- The proposed maintainer has the sponsorship of at least one other maintainer. + - This sponsoring maintainer will create a proposal PR modifying the list of + maintainers. (see [proposal PR template](#proposal-pr-template).) + - The proposed maintainer accepts the nomination and expresses a willingness + to be a long-term (more than 6 month) committer by adding a comment in the proposal PR. + - The PR will be communicated in all appropriate communication channels + including at least [web3j-contributors channel on Hyperledger Discord](https://discord.gg/hyperledger), + the [mailing list](https://lists.hyperledger.org/g/web3j) + and any maintainer/community call. +- Approval by at least 2 current maintainers within two weeks of the proposal or + an absolute majority (half the total + 1) of current maintainers. + - Maintainers will vote by approving the proposal PR. +- No veto raised by another maintainer within the voting timeframe. + - All vetoes must be accompanied by a public explanation as a comment in the + proposal PR. + - A veto can be retracted, in that case the voting timeframe is reset and all approvals are removed. + - It is bad form to veto, retract, and veto again. + +The proposed maintainer becomes a maintainer either: + +- when two weeks have passed without veto since the third approval of the proposal PR, +- or an absolute majority of maintainers approved the proposal PR. + +In either case, no maintainer raised and stood by a veto. + +## Removing Maintainers + +Being a maintainer is not a status symbol or a title to be maintained indefinitely. + +It will occasionally be necessary and appropriate to move a maintainer to emeritus status. + +This can occur in the following situations: + +- Resignation of a maintainer. +- Violation of the Code of Conduct warranting removal. +- Inactivity. + - A general measure of inactivity will be no commits or code review comments + for two reporting quarters, although this will not be strictly enforced if + the maintainer expresses a reasonable intent to continue contributing. + - Reasonable exceptions to inactivity will be granted for known long term + leave such as parental leave and medical leave. +- Other unspecified circumstances. + +As for adding a maintainer, the record and governance process for moving a +maintainer to emeritus status is recorded using review approval in the PR making that change. + +Returning to active status from emeritus status uses the same steps as adding a +new maintainer. + +Note that the emeritus maintainer always already has the required significant contributions. +There is no contribution prescription delay. + +## Proposal PR template + +```markdown +I propose to add [maintainer github handle] as a Web3J project maintainer. + +[maintainer github handle] contributed with many high quality commits: + +- [list significant achievements] + +Here are [their past contributions on Web3J project](https://github.com/hyperledger/web3j/commits?author=[user github handle]). + +Voting ends two weeks from today. + +For more information on this process see the Becoming a Maintainer section in the MAINTAINERS.md file. +``` \ No newline at end of file diff --git a/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java b/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java index 51092dafe..b29dd6c18 100644 --- a/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java +++ b/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java @@ -457,24 +457,29 @@ private List buildStructTypes(final List functionDefini final List orderedKeys = extractStructs(functionDefinitions); int structCounter = 0; final List structs = new ArrayList<>(); + final Map structNamesCountPreview = new HashMap<>(); + + for (final AbiDefinition.NamedType namedType : orderedKeys) { + final String internalType = namedType.getInternalType(); + if (internalType != null && !internalType.isEmpty()) { + final String structName = getStructName(internalType); + structNamesCountPreview.putIfAbsent(structName, 0); + structNamesCountPreview.compute(structName, (s, count) -> count + 1); + } + } + for (final AbiDefinition.NamedType namedType : orderedKeys) { final String internalType = namedType.getInternalType(); final String structName; if (internalType == null || internalType.isEmpty()) { structName = "Struct" + structCounter; } else { - final String fullStructName = - internalType.substring(internalType.lastIndexOf(" ") + 1); - String tempStructName = - fullStructName.substring(fullStructName.lastIndexOf(".") + 1); - int arrayPos = tempStructName.indexOf("["); - if (arrayPos > -1) { - tempStructName = tempStructName.substring(0, arrayPos); + String tempStructName = getStructName(internalType); + if (structNamesCountPreview.getOrDefault(tempStructName, 0) > 1) { + structName = getStructName(internalType.replace(".", "_")); + } else { + structName = tempStructName; } - structName = - SourceVersion.isName(tempStructName) - ? tempStructName - : "_" + tempStructName; } final TypeSpec.Builder builder = @@ -578,6 +583,19 @@ private List buildStructTypes(final List functionDefini return structs; } + @NotNull + private static String getStructName(String internalType) { + final String fullStructName = internalType.substring(internalType.lastIndexOf(" ") + 1); + String tempStructName = fullStructName.substring(fullStructName.lastIndexOf(".") + 1); + int arrayPos = tempStructName.indexOf("["); + if (arrayPos > -1) { + tempStructName = tempStructName.substring(0, arrayPos); + } + final String structName = + SourceVersion.isName(tempStructName) ? tempStructName : "_" + tempStructName; + return structName; + } + private String adjustToNativeTypeIfNecessary(NamedType component) { if (useNativeJavaTypes && structClassNameMap.get(component.structIdentifier()) == null) { if (ARRAY_SUFFIX.matcher(component.getType()).find() diff --git a/codegen/src/test/java/org/web3j/codegen/SolidityFunctionWrapperGeneratorTest.java b/codegen/src/test/java/org/web3j/codegen/SolidityFunctionWrapperGeneratorTest.java index db761445b..8c3e924d5 100644 --- a/codegen/src/test/java/org/web3j/codegen/SolidityFunctionWrapperGeneratorTest.java +++ b/codegen/src/test/java/org/web3j/codegen/SolidityFunctionWrapperGeneratorTest.java @@ -207,6 +207,17 @@ public void testDeployMethodGenerated() throws Exception { compareJavaFile("MetaCoin", true); } + @Test + public void testSameInnerStructName() throws Exception { + testCodeGeneration("sameinnerstructname", "SameInnerStructName", JAVA_TYPES_ARG, false); + testCodeGeneration("sameinnerstructname", "SameInnerStructName", SOLIDITY_TYPES_ARG, false); + } + + @Test + public void testSameInnerStructNameCompareJavaFile() throws Exception { + compareJavaFile("SameInnerStructName", true); + } + @Test public void testArrayOfStructClassGeneration() throws Exception { testCodeGeneration( diff --git a/codegen/src/test/resources/solidity/sameinnerstructname/SameInnerStructName.sol b/codegen/src/test/resources/solidity/sameinnerstructname/SameInnerStructName.sol new file mode 100644 index 000000000..4d4cb70cf --- /dev/null +++ b/codegen/src/test/resources/solidity/sameinnerstructname/SameInnerStructName.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.20; + +library Foo { + struct Info { + bool dummy; + } +} + +library Bar { + struct Info { + bool dummy; + } +} +contract SameInnerStructName { + + constructor() { + + } + function test(Foo.Info calldata foo, Bar.Info calldata bar) external { + revert(); + } +} diff --git a/codegen/src/test/resources/solidity/sameinnerstructname/build/Bar.abi b/codegen/src/test/resources/solidity/sameinnerstructname/build/Bar.abi new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/codegen/src/test/resources/solidity/sameinnerstructname/build/Bar.abi @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/codegen/src/test/resources/solidity/sameinnerstructname/build/Bar.bin b/codegen/src/test/resources/solidity/sameinnerstructname/build/Bar.bin new file mode 100644 index 000000000..df2e7a5bd --- /dev/null +++ b/codegen/src/test/resources/solidity/sameinnerstructname/build/Bar.bin @@ -0,0 +1 @@ +6055604b600b8282823980515f1a607314603f577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea264697066735822122084a12bad14446abd271fd63e8490580f720401bd246b20d3c4c44a014f9b353064736f6c63430008140033 \ No newline at end of file diff --git a/codegen/src/test/resources/solidity/sameinnerstructname/build/Foo.abi b/codegen/src/test/resources/solidity/sameinnerstructname/build/Foo.abi new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/codegen/src/test/resources/solidity/sameinnerstructname/build/Foo.abi @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/codegen/src/test/resources/solidity/sameinnerstructname/build/Foo.bin b/codegen/src/test/resources/solidity/sameinnerstructname/build/Foo.bin new file mode 100644 index 000000000..0fc8292d6 --- /dev/null +++ b/codegen/src/test/resources/solidity/sameinnerstructname/build/Foo.bin @@ -0,0 +1 @@ +6055604b600b8282823980515f1a607314603f577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea264697066735822122050486bc1933b68f15a8374411ab7b0405b4f544c21aa8c14252f303a3b358ce464736f6c63430008140033 \ No newline at end of file diff --git a/codegen/src/test/resources/solidity/sameinnerstructname/build/SameInnerStructName.abi b/codegen/src/test/resources/solidity/sameinnerstructname/build/SameInnerStructName.abi new file mode 100644 index 000000000..5fa2ec3bb --- /dev/null +++ b/codegen/src/test/resources/solidity/sameinnerstructname/build/SameInnerStructName.abi @@ -0,0 +1 @@ +[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"components":[{"internalType":"bool","name":"dummy","type":"bool"}],"internalType":"struct Foo.Info","name":"foo","type":"tuple"},{"components":[{"internalType":"bool","name":"dummy","type":"bool"}],"internalType":"struct Bar.Info","name":"bar","type":"tuple"}],"name":"test","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/codegen/src/test/resources/solidity/sameinnerstructname/build/SameInnerStructName.bin b/codegen/src/test/resources/solidity/sameinnerstructname/build/SameInnerStructName.bin new file mode 100644 index 000000000..9c2ae6a5c --- /dev/null +++ b/codegen/src/test/resources/solidity/sameinnerstructname/build/SameInnerStructName.bin @@ -0,0 +1 @@ +608060405234801561000f575f80fd5b5060f18061001c5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c8063b1a29dbb14602a575b5f80fd5b60406004803603810190603c91906084565b6042565b005b5f80fd5b5f80fd5b5f80fd5b5f60208284031215606057605f604a565b5b81905092915050565b5f60208284031215607b57607a604a565b5b81905092915050565b5f806040838503121560975760966046565b5b5f60a285828601604e565b925050602060b1858286016069565b915050925092905056fea2646970667358221220024a769b6d57f11f6f5df0145ce9d31d8dd2ec08b9a923116f016e14a0912bb464736f6c63430008140033 \ No newline at end of file diff --git a/codegen/src/test/resources/solidity/sameinnerstructname/build/java/SameInnerStructName.java b/codegen/src/test/resources/solidity/sameinnerstructname/build/java/SameInnerStructName.java new file mode 100644 index 000000000..3dca11bf3 --- /dev/null +++ b/codegen/src/test/resources/solidity/sameinnerstructname/build/java/SameInnerStructName.java @@ -0,0 +1,153 @@ +package org.web3j.unittests.java; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Bool; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.StaticStruct; +import org.web3j.abi.datatypes.Type; +import org.web3j.crypto.Credentials; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.RemoteCall; +import org.web3j.protocol.core.RemoteFunctionCall; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.tx.Contract; +import org.web3j.tx.TransactionManager; +import org.web3j.tx.gas.ContractGasProvider; + +/** + *

Auto generated code. + *

Do not modify! + *

Please use the web3j command line tools, + * or the org.web3j.codegen.SolidityFunctionWrapperGenerator in the + * codegen module to update. + * + *

Generated with web3j version none. + */ +@SuppressWarnings("rawtypes") +public class SameInnerStructName extends Contract { + public static final String BINARY = "608060405234801561000f575f80fd5b5060f18061001c5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c8063b1a29dbb14602a575b5f80fd5b60406004803603810190603c91906084565b6042565b005b5f80fd5b5f80fd5b5f80fd5b5f60208284031215606057605f604a565b5b81905092915050565b5f60208284031215607b57607a604a565b5b81905092915050565b5f806040838503121560975760966046565b5b5f60a285828601604e565b925050602060b1858286016069565b915050925092905056fea2646970667358221220024a769b6d57f11f6f5df0145ce9d31d8dd2ec08b9a923116f016e14a0912bb464736f6c63430008140033"; + + private static String librariesLinkedBinary; + + public static final String FUNC_TEST = "test"; + + @Deprecated + protected SameInnerStructName(String contractAddress, Web3j web3j, Credentials credentials, + BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + protected SameInnerStructName(String contractAddress, Web3j web3j, Credentials credentials, + ContractGasProvider contractGasProvider) { + super(BINARY, contractAddress, web3j, credentials, contractGasProvider); + } + + @Deprecated + protected SameInnerStructName(String contractAddress, Web3j web3j, + TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + protected SameInnerStructName(String contractAddress, Web3j web3j, + TransactionManager transactionManager, ContractGasProvider contractGasProvider) { + super(BINARY, contractAddress, web3j, transactionManager, contractGasProvider); + } + + public RemoteFunctionCall test(Foo_Info foo, Bar_Info bar) { + final Function function = new Function( + FUNC_TEST, + Arrays.asList(foo, + bar), + Collections.>emptyList()); + return executeRemoteCallTransaction(function); + } + + @Deprecated + public static SameInnerStructName load(String contractAddress, Web3j web3j, + Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + return new SameInnerStructName(contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + @Deprecated + public static SameInnerStructName load(String contractAddress, Web3j web3j, + TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + return new SameInnerStructName(contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public static SameInnerStructName load(String contractAddress, Web3j web3j, + Credentials credentials, ContractGasProvider contractGasProvider) { + return new SameInnerStructName(contractAddress, web3j, credentials, contractGasProvider); + } + + public static SameInnerStructName load(String contractAddress, Web3j web3j, + TransactionManager transactionManager, ContractGasProvider contractGasProvider) { + return new SameInnerStructName(contractAddress, web3j, transactionManager, contractGasProvider); + } + + public static RemoteCall deploy(Web3j web3j, Credentials credentials, + ContractGasProvider contractGasProvider) { + return deployRemoteCall(SameInnerStructName.class, web3j, credentials, contractGasProvider, getDeploymentBinary(), ""); + } + + public static RemoteCall deploy(Web3j web3j, + TransactionManager transactionManager, ContractGasProvider contractGasProvider) { + return deployRemoteCall(SameInnerStructName.class, web3j, transactionManager, contractGasProvider, getDeploymentBinary(), ""); + } + + @Deprecated + public static RemoteCall deploy(Web3j web3j, Credentials credentials, + BigInteger gasPrice, BigInteger gasLimit) { + return deployRemoteCall(SameInnerStructName.class, web3j, credentials, gasPrice, gasLimit, getDeploymentBinary(), ""); + } + + @Deprecated + public static RemoteCall deploy(Web3j web3j, + TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + return deployRemoteCall(SameInnerStructName.class, web3j, transactionManager, gasPrice, gasLimit, getDeploymentBinary(), ""); + } + + public static void linkLibraries(List references) { + librariesLinkedBinary = linkBinaryWithReferences(BINARY, references); + } + + private static String getDeploymentBinary() { + if (librariesLinkedBinary != null) { + return librariesLinkedBinary; + } else { + return BINARY; + } + } + + public static class Foo_Info extends StaticStruct { + public Boolean dummy; + + public Foo_Info(Boolean dummy) { + super(new org.web3j.abi.datatypes.Bool(dummy)); + this.dummy = dummy; + } + + public Foo_Info(Bool dummy) { + super(dummy); + this.dummy = dummy.getValue(); + } + } + + public static class Bar_Info extends StaticStruct { + public Boolean dummy; + + public Bar_Info(Boolean dummy) { + super(new org.web3j.abi.datatypes.Bool(dummy)); + this.dummy = dummy; + } + + public Bar_Info(Bool dummy) { + super(dummy); + this.dummy = dummy.getValue(); + } + } +} +