From 993c760d4f78c1564ebc1f05849d6b2cacaf87a7 Mon Sep 17 00:00:00 2001 From: naneey Date: Mon, 4 Mar 2024 13:08:59 +0545 Subject: [PATCH 01/64] chore: integration test setup --- build.gradle | 101 +++++- .../lib/interfaces/CPFTreasuryInterface.java | 3 +- .../lib/interfaces/CPSCoreInterface.java | 3 +- .../lib/interfaces/CPSTreasuryInterface.java | 4 +- .../score/lib/interfaces/SystemInterface.java | 4 +- test-lib/build.gradle | 40 +-- test-lib/conf/godWallet.json | 22 -- .../icon/cps/score/test/integration/CPS.java | 195 +++++------ .../cps/score/test/integration/CPSClient.java | 72 +++- .../{Env.java => Environment.java} | 92 +++-- .../score/test/integration/ScoreDeployer.java | 89 +++++ .../integration/ScoreIntegrationTest.java | 225 +++---------- .../score/test/integration/model/Score.java | 81 +++++ .../scores/CPFTreasuryInterface.java | 149 ++++++++ .../integration/scores/CPSCoreInterface.java | 318 ++++++++++++++++++ .../scores/CPSTreasuryInterface.java | 91 +++++ .../integration/scores/SystemInterface.java | 48 +++ .../integration/utils/DefaultICONClient.java | 197 +++++++++++ .../{ => src/main/resources}/conf/env.props | 2 + testinteg/build.gradle | 8 - .../main/foundation/icon/test/Constants.class | Bin 1131 -> 0 bytes .../main/foundation/icon/test/Env$Chain.class | Bin 1243 -> 0 bytes .../java/main/foundation/icon/test/Env.class | Bin 4139 -> 0 bytes .../java/main/foundation/icon/test/Log.class | Bin 4001 -> 0 bytes .../icon/test/ResultTimeoutException.class | Bin 1299 -> 0 bytes .../main/foundation/icon/test/TestBase.class | Bin 5496 -> 0 bytes .../test/TransactionFailureException.class | Bin 996 -> 0 bytes .../icon/test/TransactionHandler.class | Bin 11344 -> 0 bytes .../icon/test/score/ChainScore.class | Bin 1020 -> 0 bytes .../foundation/icon/test/score/Score.class | Bin 8978 -> 0 bytes .../foundation/icon/test/util/ZipFile.class | Bin 2534 -> 0 bytes testinteg/build/libs/testinteg.jar | Bin 20414 -> 0 bytes testinteg/build/tmp/jar/MANIFEST.MF | 2 - testinteg/conf/env.props | 5 - testinteg/conf/godWallet.json | 22 -- .../java/foundation/icon/test/Constants.java | 37 -- .../main/java/foundation/icon/test/Env.java | 103 ------ .../main/java/foundation/icon/test/Log.java | 126 ------- .../icon/test/ResultTimeoutException.java | 40 --- .../java/foundation/icon/test/TestBase.java | 97 ------ .../test/TransactionFailureException.java | 42 --- .../icon/test/TransactionHandler.java | 201 ----------- .../icon/test/score/ChainScore.java | 34 -- .../foundation/icon/test/score/Score.java | 164 --------- .../foundation/icon/test/util/ZipFile.java | 62 ---- 45 files changed, 1354 insertions(+), 1325 deletions(-) delete mode 100644 test-lib/conf/godWallet.json rename test-lib/src/main/java/community/icon/cps/score/test/integration/{Env.java => Environment.java} (52%) create mode 100644 test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreDeployer.java create mode 100644 test-lib/src/main/java/community/icon/cps/score/test/integration/model/Score.java create mode 100644 test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPFTreasuryInterface.java create mode 100644 test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java create mode 100644 test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSTreasuryInterface.java create mode 100644 test-lib/src/main/java/community/icon/cps/score/test/integration/scores/SystemInterface.java create mode 100644 test-lib/src/main/java/community/icon/cps/score/test/integration/utils/DefaultICONClient.java rename test-lib/{ => src/main/resources}/conf/env.props (82%) delete mode 100644 testinteg/build.gradle delete mode 100644 testinteg/build/classes/java/main/foundation/icon/test/Constants.class delete mode 100644 testinteg/build/classes/java/main/foundation/icon/test/Env$Chain.class delete mode 100644 testinteg/build/classes/java/main/foundation/icon/test/Env.class delete mode 100644 testinteg/build/classes/java/main/foundation/icon/test/Log.class delete mode 100644 testinteg/build/classes/java/main/foundation/icon/test/ResultTimeoutException.class delete mode 100644 testinteg/build/classes/java/main/foundation/icon/test/TestBase.class delete mode 100644 testinteg/build/classes/java/main/foundation/icon/test/TransactionFailureException.class delete mode 100644 testinteg/build/classes/java/main/foundation/icon/test/TransactionHandler.class delete mode 100644 testinteg/build/classes/java/main/foundation/icon/test/score/ChainScore.class delete mode 100644 testinteg/build/classes/java/main/foundation/icon/test/score/Score.class delete mode 100644 testinteg/build/classes/java/main/foundation/icon/test/util/ZipFile.class delete mode 100644 testinteg/build/libs/testinteg.jar delete mode 100644 testinteg/build/tmp/jar/MANIFEST.MF delete mode 100644 testinteg/conf/env.props delete mode 100644 testinteg/conf/godWallet.json delete mode 100644 testinteg/src/main/java/foundation/icon/test/Constants.java delete mode 100644 testinteg/src/main/java/foundation/icon/test/Env.java delete mode 100644 testinteg/src/main/java/foundation/icon/test/Log.java delete mode 100644 testinteg/src/main/java/foundation/icon/test/ResultTimeoutException.java delete mode 100644 testinteg/src/main/java/foundation/icon/test/TestBase.java delete mode 100644 testinteg/src/main/java/foundation/icon/test/TransactionFailureException.java delete mode 100644 testinteg/src/main/java/foundation/icon/test/TransactionHandler.java delete mode 100644 testinteg/src/main/java/foundation/icon/test/score/ChainScore.java delete mode 100644 testinteg/src/main/java/foundation/icon/test/score/Score.java delete mode 100644 testinteg/src/main/java/foundation/icon/test/util/ZipFile.java diff --git a/build.gradle b/build.gradle index 1e59de7f..ddd57cc3 100644 --- a/build.gradle +++ b/build.gradle @@ -17,10 +17,14 @@ task buildContracts(type: Exec) { subprojects { repositories { mavenCentral() + flatDir { + dirs "$rootProject.projectDir/jars" + } } - apply plugin: 'java' - apply plugin: 'jacoco' + +// apply plugin: 'java' +// apply plugin: 'jacoco' apply plugin: 'foundation.icon.javaee' sourceSets { @@ -38,6 +42,49 @@ subprojects { intTestRuntimeOnly.extendsFrom testRuntimeOnly } + ext { + env = has("network") ? getProperty("network") : 'dev' + javaeeVersion = findProperty("javaee.version") ?: '0.9.0' + scorexVersion = findProperty("scorex.version") ?: '0.5.2' + javaeeUnittestVersion = findProperty("javaee-unittest.version") ?: '0.9.2' + scoreClientVersion = findProperty("score-client.version") ?: '0.9.0' + iconsdkVersion = findProperty("iconsdk.version") ?: '2.0.0' + jacksonVersion = findProperty("jackson.version") ?: '2.13.2' + mockitoVersion = findProperty("mockito.version") ?: '4.3.1' + junitVersion = findProperty("junit.version") ?: '5.8.1' + javafakerVersion = findProperty("javafaker.version") ?: '1.0.2' + commonIOVersion = findProperty("common-io.version") ?: '2.11.0' + + } + + dependencies{ + compileOnly "foundation.icon:javaee-api:$javaeeVersion" + implementation ("foundation.icon:javaee-annotation-processor:$javaeeVersion") + + implementation "foundation.icon:javaee-scorex:$scorexVersion" + implementation "com.github.sink772:minimal-json:0.9.6" + compileOnly name: "score-client-$scoreClientVersion" + annotationProcessor "foundation.icon:javaee-score-client:$scoreClientVersion" + + testImplementation name: "score-client-$scoreClientVersion" + testAnnotationProcessor "foundation.icon:javaee-score-client:$scoreClientVersion" + + implementation ("com.fasterxml.jackson.core:jackson-core:$jacksonVersion") + implementation ("com.fasterxml.jackson.core:jackson-annotations:$jacksonVersion") + testImplementation("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion") + + testImplementation "foundation.icon:javaee-unittest:$javaeeUnittestVersion" + testImplementation "org.junit.jupiter:junit-jupiter:$junitVersion" + testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion" + testImplementation "org.mockito:mockito-core:$mockitoVersion" +// testImplementation "foundation.icon:icon-sdk:$iconsdkVersion" + testImplementation group: "org.json", name: "json", version: "20211205" + + // TODO: need to find the import for WALLET in foundation.icon.icx + + + } + java { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 @@ -48,28 +95,54 @@ subprojects { options.compilerArgs += ['-parameters'] } - tasks.named('test') { - // Use JUnit Platform for unit tests. - useJUnitPlatform() + def loadProperties = { + def prefix = 'score-test.' + def props = project.getProperties() + def scoreTest = new HashMap() + + scoreTest.put('keystoreName', props.getOrDefault(prefix + 'keystoreName', "$rootDir/gochain-local/data/godWallet.json")) + scoreTest.put('keystorePass', props.getOrDefault(prefix + 'keystorePass', "gochain")) + scoreTest.put('url', props.getOrDefault(prefix + 'url', 'http://localhost:9082/api/v3')) + scoreTest.put('nid', props.getOrDefault(prefix + 'nid', 3)) + + ext['scoreTest'] = scoreTest } + loadProperties() - scoreIntegrationTest.put('env.props', new File(project(':test-lib').projectDir, 'conf/env.props')) +// tasks.named('test') { +// // Use JUnit Platform for unit tests. +// useJUnitPlatform() +// } + + //TODO: add the dummy jar files here required for cps +// scoreIntegrationTest.put('env.props', new File(project(':test-lib').projectDir, 'conf/env.props')) afterEvaluate { project -> scoreIntegrationTest.put(project.name, project.getTasks().getByName("optimizedJar").outputJarName) } - tasks.named("assemble") { - if (project.tasks.findByName("compileIntTestJava")) { - finalizedBy(project.tasks.getByName("compileIntTestJava")) +// tasks.named("assemble") { +// if (project.tasks.findByName("compileIntTestJava")) { +// finalizedBy(project.tasks.getByName("compileIntTestJava")) +// } +// } + + gradle.taskGraph.beforeTask { Task task -> + if (task.name == 'integrationTest') { + scoreIntegrationTest.each { key, val -> + task.systemProperty key, val + } + task.systemProperty "DEBUG_ENABLED", true + task.systemProperty "BLOCK_INTERVAL", 50 + task.systemProperty "DEFAULT_RESULT_RETRY_WAIT", 100 } } gradle.taskGraph.whenReady { taskGraph -> - taskGraph.getAllTasks().eachWithIndex { task, n -> - if (task.name == 'integrationTest') { - scoreIntegrationTest.each { key, val -> task.systemProperty key, val } - } - } +// taskGraph.getAllTasks().eachWithIndex { task, n -> +// if (task.name == 'integrationTest') { +// scoreIntegrationTest.each { key, val -> task.systemProperty key, val } +// } +// } } } diff --git a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPFTreasuryInterface.java b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPFTreasuryInterface.java index d8b03b15..a4cd2ea1 100644 --- a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPFTreasuryInterface.java +++ b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPFTreasuryInterface.java @@ -11,8 +11,7 @@ import java.math.BigInteger; import java.util.Map; -@ScoreClient -@ScoreInterface +@ScoreInterface(suffix = "Client") public interface CPFTreasuryInterface { @External(readonly = true) String name(); diff --git a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSCoreInterface.java b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSCoreInterface.java index 0cf04fb6..ca957d82 100644 --- a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSCoreInterface.java +++ b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSCoreInterface.java @@ -12,8 +12,7 @@ import java.util.List; import java.util.Map; -@ScoreClient -@ScoreInterface +@ScoreInterface(suffix = "Client") public interface CPSCoreInterface { public static class ProposalAttributes { diff --git a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSTreasuryInterface.java b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSTreasuryInterface.java index 28c30ddc..c0acf6ff 100644 --- a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSTreasuryInterface.java +++ b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSTreasuryInterface.java @@ -11,8 +11,8 @@ import java.util.List; import java.util.Map; -@ScoreClient -@ScoreInterface +//@ScoreClient +@ScoreInterface(suffix = "Client") public interface CPSTreasuryInterface { @External(readonly = true) String name(); diff --git a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/SystemInterface.java b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/SystemInterface.java index 76d46074..c6f3da42 100644 --- a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/SystemInterface.java +++ b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/SystemInterface.java @@ -9,8 +9,8 @@ import java.math.BigInteger; import java.util.Map; -@ScoreClient -@ScoreInterface +//@ScoreClient +@ScoreInterface(suffix = "Client") public interface SystemInterface { public static class Delegation{ public Address address; diff --git a/test-lib/build.gradle b/test-lib/build.gradle index bb9b7c53..2b39f3ad 100644 --- a/test-lib/build.gradle +++ b/test-lib/build.gradle @@ -1,31 +1,31 @@ -plugins { - id 'java' -} +apply plugin: 'java-library' -version '0.1.0' +optimizedJar.enabled = false repositories { mavenCentral() } -optimizedJar.enabled = false - dependencies { - implementation "foundation.icon:icon-sdk:2.1.0" +// implementation "foundation.icon:icon-sdk:$iconsdkVersion" + implementation name: "score-client-$scoreClientVersion" + + implementation "org.junit.jupiter:junit-jupiter-api:$junitVersion" + implementation "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion" + implementation "com.github.javafaker:javafaker:$javafakerVersion" + implementation "foundation.icon:javaee-unittest:$javaeeUnittestVersion" + implementation "org.mockito:mockito-core:$mockitoVersion" + +// implementation "foundation.icon:icon-sdk:$iconsdkVersion" + implementation group: 'commons-io', name: 'commons-io', version: "$commonIOVersion" + implementation "org.bouncycastle:bcprov-jdk15on:1.60" +// implementation "foundation.icon:icon-sdk:$iconsdkVersion" + implementation("foundation.icon:icon-sdk:2.0.0") + testImplementation("foundation.icon:icon-sdk:2.0.0") + + + implementation project(':score-lib') - annotationProcessor project(':score-client') - implementation project(':score-client') - implementation "org.junit.jupiter:junit-jupiter-api:5.8.2" - implementation "com.fasterxml.jackson.core:jackson-databind:2.13.3" - implementation "foundation.icon:javaee-unittest:0.9.4" - implementation "org.junit.jupiter:junit-jupiter:5.8.2" - runtimeOnly "org.junit.jupiter:junit-jupiter-engine:5.8.2" - implementation "com.github.sink772:minimal-json:0.9.7" - implementation "org.mockito:mockito-core:4.5.1" - implementation "org.json:json:20220320" - implementation "foundation.icon:javaee-scorex:0.5.2" - - implementation "com.github.javafaker:javafaker:1.0.2" } test { diff --git a/test-lib/conf/godWallet.json b/test-lib/conf/godWallet.json deleted file mode 100644 index 2a611aa3..00000000 --- a/test-lib/conf/godWallet.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "address": "hxb6b5791be0b5ef67063b3c10b840fb81514db2fd", - "id": "87323a66-289a-4ce2-88e4-00278deb5b84", - "version": 3, - "coinType": "icx", - "crypto": { - "cipher": "aes-128-ctr", - "cipherparams": { - "iv": "069e46aaefae8f1c1f840d6b09144999" - }, - "ciphertext": "f35ff7cf4f5759cb0878088d0887574a896f7f0fc2a73898d88be1fe52977dbd", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "n": 65536, - "r": 8, - "p": 1, - "salt": "0fc9c3b24cdb8175" - }, - "mac": "1ef4ff51fdee8d4de9cf59e160da049eb0099eb691510994f5eca492f56c817a" - } -} diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java index ee46165d..4e09ab45 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java @@ -1,156 +1,139 @@ package community.icon.cps.score.test.integration; +import community.icon.cps.score.lib.interfaces.SystemInterfaceScoreClient; +import community.icon.cps.score.test.integration.model.Score; +import community.icon.cps.score.test.integration.utils.DefaultICONClient; import foundation.icon.icx.KeyWallet; import foundation.icon.icx.data.Bytes; import foundation.icon.score.client.DefaultScoreClient; -import community.icon.cps.score.lib.interfaces.CPSTreasuryInterfaceScoreClient; -import community.icon.cps.score.lib.interfaces.CPFTreasuryInterfaceScoreClient; -import community.icon.cps.score.lib.interfaces.CPSCoreInterfaceScoreInterface; -import community.icon.cps.score.lib.interfaces.DexInterfaceScoreClient; -import community.icon.cps.score.lib.interfaces.sICXInterfaceScoreClient; -import community.icon.cps.score.lib.interfaces.bnUSDInterfaceScoreClient; -import community.icon.cps.score.lib.interfaces.RouterInterfaceScoreClient; import score.Address; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; import java.math.BigInteger; + import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.Callable; + +import static community.icon.cps.score.test.integration.Environment.*; +import static community.icon.cps.score.test.integration.ScoreIntegrationTest.createWalletWithBalance; +import static community.icon.cps.score.test.integration.ScoreIntegrationTest.transfer; -import static community.icon.cps.score.test.integration.ScoreIntegrationTest.*; public class CPS { - public KeyWallet user; - public KeyWallet testUser; public KeyWallet owner; - - /* - Prep wallets loaded from test-lib/src/main/java/community/icon/cps/score/test/wallets - */ - - public KeyWallet prepWallet1; - public KeyWallet prepWallet2; - public KeyWallet prepWallet3; - public KeyWallet prepWallet4; - public KeyWallet prepWallet5; - public KeyWallet prepWallet6; - public KeyWallet prepWallet7; - public CPSClient ownerClient; - public DefaultScoreClient cpsTreasury; - public DefaultScoreClient cpfTreasury; - public DefaultScoreClient cpsCore; - - public DefaultScoreClient dex; - public DefaultScoreClient router; - public DefaultScoreClient bnusd; - public DefaultScoreClient sicx; + public CPSClient testClient; - public DefaultScoreClient governanceBalanced; + private Map addresses; + public DefaultICONClient iconClient; - public CPSTreasuryInterfaceScoreClient cpsTreasuryScore; - public CPFTreasuryInterfaceScoreClient cpfTreasuryScore; - public CPSCoreInterfaceScoreInterface cpsMainScore; + HashMap cpsClients; + private String contracts; - Map cpsClients; + public CPS(String contracts) throws Exception { - public List prepList; - - public CPS() throws Exception{ + this.contracts = contracts; cpsClients = new HashMap<>(); owner = createWalletWithBalance(BigInteger.TEN.pow(24)); - user = createWalletWithBalance(BigInteger.TEN.pow(24)); - testUser = createWalletWithBalance(BigInteger.TEN.pow(24)); - BufferedReader br = new BufferedReader(new FileReader("privateKey.txt")); -// System.out.println("Reading the content of the file in cpsMain: " + br.readLine()); - String longPrivateKey = br.readLine(); - String privateKey0 = longPrivateKey.substring(0, 66); - String privateKey1 = longPrivateKey.substring(66, 132); - String privateKey2 = longPrivateKey.substring(132, 198); - String privateKey3 = longPrivateKey.substring(198, 264); - String privateKey4 = longPrivateKey.substring(264, 330); - String privateKey5 = longPrivateKey.substring(330, 396); - String privateKey6 = longPrivateKey.substring(396, 462); - - prepWallet1 = KeyWallet.load(new Bytes(privateKey1)); - prepWallet2 = KeyWallet.load(new Bytes(privateKey2)); - prepWallet3 = KeyWallet.load(new Bytes(privateKey3)); - prepWallet4 = KeyWallet.load(new Bytes(privateKey4)); - prepWallet5 = KeyWallet.load(new Bytes(privateKey5)); - prepWallet6 = KeyWallet.load(new Bytes(privateKey6)); - prepWallet7 = KeyWallet.load(new Bytes(privateKey0)); + iconClient = new DefaultICONClient(chain); } - public void setupCPS() throws Exception{ - registerPreps(); - deployContracts(); -// setStakeOfPreps(); -// setDelegationOfPreps(); -// setBonderListOfPReps(); -// setBondOfPreps(); -// registerGodPrep(); -// setGodStake(); - } + public void setupCPS() throws Exception { + deployPrep(); + this.addresses = new ScoreDeployer(this,contracts).deployContracts(); - public void registerGodPrep(){ - registerGodClient(); + ownerClient = new CPSClient(this,owner); + testClient = new CPSClient(this, createWalletWithBalance(BigInteger.TEN.pow(24))); } - public void setGodPrep(){ - setGodStake(); - } - public void setStakeOfPreps(){ - KeyWallet[] keyWallets = {prepWallet1, prepWallet2, prepWallet3, prepWallet4, prepWallet5, prepWallet6, prepWallet7}; - setStake(keyWallets); + public CPSClient defaultClient() { + return ownerClient; } - public void setDelegationOfPreps(){ - KeyWallet[] keyWallets = {prepWallet1, prepWallet2, prepWallet3, prepWallet4, prepWallet5, prepWallet6, prepWallet7}; - setDelegation(keyWallets); + public CPSClient testClient() { + return testClient; } - public void setBondOfPreps(){ - KeyWallet[] keyWallets = {prepWallet1, prepWallet2, prepWallet3, prepWallet4, prepWallet5, prepWallet6, prepWallet7}; - setBond(keyWallets); + public void send(foundation.icon.jsonrpc.Address address, String method, Map params) { + iconClient.send(owner, address, BigInteger.ZERO, method, params, DefaultICONClient.DEFAULT_RESULT_TIMEOUT); } - public void setBonderListOfPReps(){ - KeyWallet[] keyWallets = {prepWallet1, prepWallet2, prepWallet3, prepWallet4, prepWallet5, prepWallet6, prepWallet7}; - setBonderList(keyWallets); + public foundation.icon.jsonrpc.Address deployAddressManager() { + return iconClient.deploy(owner, DefaultICONClient.ZERO_ADDRESS, getScorePath("AddressManager"), + new HashMap<>()); } - public void deployContracts(){ - cpsCore = deploy(owner, "CPSCore", null); - - Map cpsScoreAddress = Map.of("cps_score", cpsCore._address()); - cpsTreasury = deploy(owner, "CPSTreasury", cpsScoreAddress); - cpfTreasury = deploy(owner, "CPFTreasury", cpsScoreAddress); + public String getScorePath(String key) { + String path = System.getProperty(key); + if (path == null) { + throw new IllegalArgumentException("No such property: " + key); + } + return path; + } + public Callable deploy(Score score) { + return () -> _deploy(score); + } - dex = deploy(owner, "Dex", null); + public foundation.icon.jsonrpc.Address _deploy(Score score) { + return iconClient.deploy(owner, DefaultICONClient.ZERO_ADDRESS, score.getPath(), score.getParams()); + } - Map bnUSDParams = Map.of( - "_name", "Balanced Dollar", - "_symbol", "bnUSD", - "_decimals", BigInteger.valueOf(18), - "_initialSupply", BigInteger.valueOf(100000000)); - bnusd = deploy(owner, "bnUSD", bnUSDParams); + public boolean isPRepRegistered() { + try { + SYSTEM_INTERFACE = new SystemInterfaceScoreClient(godClient); + Map result = SYSTEM_INTERFACE.getPReps(BigInteger.ONE, BigInteger.valueOf(100)); + List registeredPReps = (List) result.get("preps"); + if (registeredPReps.size() >= 100) { + return true; + } + } catch (Exception e) { + + } + return false; + } - sicx = deploy(owner, "sICX", bnUSDParams); + public void deployPrep() { + if (isPRepRegistered()) { + return; + } + try { + + for (Map.Entry prep : preps.entrySet()) { + KeyWallet wallet = KeyWallet.load(new Bytes(prep.getValue())); + transfer(foundation.icon.jsonrpc.Address.of(wallet), BigInteger.TEN.pow(24)); + var client = new DefaultScoreClient( + chain.getEndpointURL(), + chain.networkId, + wallet, + DefaultScoreClient.ZERO_ADDRESS + ); + SYSTEM_INTERFACE = new SystemInterfaceScoreClient(client); + ((SystemInterfaceScoreClient) SYSTEM_INTERFACE).registerPRep( + BigInteger.valueOf(2000).multiply(BigInteger.TEN.pow(18)), prep.getKey().toString(), + "kokoa@example.com", + "USA", + "New York", "https://icon.kokoa.com", "https://icon.kokoa.com/json/details.json", + "localhost:9082"); + } + } catch (Exception e) { + + } + } - router = deploy(owner, "Router", null); + public Map getAddresses() { + return this.addresses; } - public void setScoreAddresses(){ - // CPS Main + public foundation.icon.jsonrpc.Address getAddress(String key) { + + return this.addresses.get(key); } } diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java index 14a22959..fcae09d5 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java @@ -1,25 +1,81 @@ package community.icon.cps.score.test.integration; +import community.icon.cps.score.test.integration.scores.SystemInterfaceScoreClient; +import community.icon.cps.score.test.integration.scores.CPFTreasuryInterface; +import community.icon.cps.score.test.integration.scores.CPFTreasuryInterfaceScoreClient; +import community.icon.cps.score.test.integration.scores.CPSCoreInterface; +import community.icon.cps.score.test.integration.scores.CPSCoreInterfaceScoreClient; +import community.icon.cps.score.test.integration.scores.CPSTreasuryInterface; +import community.icon.cps.score.test.integration.scores.CPSTreasuryInterfaceScoreClient; +import community.icon.cps.score.test.integration.scores.SystemInterface; import foundation.icon.icx.KeyWallet; -import foundation.icon.score.client.DefaultScoreClient; -import community.icon.cps.score.lib.interfaces.*; +import foundation.icon.jsonrpc.Address; +import foundation.icon.score.client.ScoreClient; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.NoSuchElementException; + +import static community.icon.cps.score.test.integration.Environment.chain; -import static community.icon.cps.score.test.integration.ScoreIntegrationTest.chain; public class CPSClient { private final KeyWallet wallet; - public CPSTreasuryInterfaceScoreClient cpsTreasury; - public CPFTreasuryInterfaceScoreClient cpfTreasury; + private CPS cps; + private Map addressMap; + + @ScoreClient + public CPSTreasuryInterface cpsTreasury; + + @ScoreClient + public CPFTreasuryInterface cpfTreasury; + + @ScoreClient + public CPSCoreInterface cpsCore; + + @ScoreClient + public SystemInterface systemScore; + public CPSClient(CPS cps, KeyWallet wallet){ + this.cps = cps; this.wallet = wallet; - cpsTreasury = new CPSTreasuryInterfaceScoreClient(chain.getEndpointURL(), chain.networkId, wallet, - cps.cpsTreasury._address()); - cpfTreasury = new CPFTreasuryInterfaceScoreClient(chain.getEndpointURL(), chain.networkId, wallet, cps.cpfTreasury._address()); + init(); + } + + private void init(){ + for (Entry entry : this.cps.getAddresses().entrySet()) { + switch (entry.getKey()){ + case "cpsCore": + cpsCore = new CPSCoreInterfaceScoreClient(chain.getEndpointURL(), chain.networkId, wallet, + entry.getValue()); + break; + case "cpsTreasury": + cpsTreasury = new CPSTreasuryInterfaceScoreClient(chain.getEndpointURL(), chain.networkId, wallet, + entry.getValue()); + break; + case "cpfTreasury": + cpfTreasury = new CPFTreasuryInterfaceScoreClient(chain.getEndpointURL(), chain.networkId, wallet, + entry.getValue()); + break; + case "systemScore": + systemScore = new SystemInterfaceScoreClient(chain.getEndpointURL(), chain.networkId, wallet, + entry.getValue()); + break; + default: + throw new NoSuchElementException(entry.getKey() + " score not found!!"); + + } + + } } public score.Address getAddress() { return score.Address.fromString(wallet.getAddress().toString()); } + + public KeyWallet getWallet() { + return wallet; + } } diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/Env.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/Environment.java similarity index 52% rename from test-lib/src/main/java/community/icon/cps/score/test/integration/Env.java rename to test-lib/src/main/java/community/icon/cps/score/test/integration/Environment.java index d2fbadbf..b779acb5 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/Env.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/Environment.java @@ -1,45 +1,84 @@ package community.icon.cps.score.test.integration; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import community.icon.cps.score.lib.interfaces.SystemInterface; import foundation.icon.icx.KeyWallet; import foundation.icon.icx.Wallet; import foundation.icon.icx.crypto.KeystoreException; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; +import foundation.icon.score.client.DefaultScoreClient; +import foundation.icon.score.client.ScoreClient; + +import java.io.*; import java.math.BigInteger; + import java.nio.file.Path; +import java.util.Map; import java.util.Properties; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.ClassOrderer; +import score.Address; + + + -public class Env { - private static Chain chain; +public class Environment { static { - String envFile = System.getProperty("env.props", "/Users/ibriz/icon-foundation-cps/cps_java_contracts/test-lib/conf/env.props"); + String envFile = System.getProperty("env.props","conf/env.props"); Properties props = new Properties(); try { - FileInputStream fis = new FileInputStream(envFile); - props.load(fis); - fis.close(); + InputStream is = ClassOrderer.ClassName.class.getClassLoader() + .getResourceAsStream(envFile); + props.load(is); + assert is != null; + is.close(); } catch (IOException e) { System.err.printf("'%s' does not exist\n", envFile); throw new IllegalArgumentException(e.getMessage()); } + +// FileInputStream configReader; +// try { +// configReader = new FileInputStream(envFile); +// } catch (FileNotFoundException e) { +// throw new RuntimeException(e); +// } +// Properties props = new Properties(); +// try { +// props.load(configReader); +// configReader.close(); +// } catch (IOException e) { +// throw new RuntimeException(e); +// } String confPath = Path.of(envFile).getParent().toString() + "/"; readProperties(props, confPath); } - private static void readProperties(Properties props, String confPath) { + public static Chain chain; + public static DefaultScoreClient godClient; + public static Map preps; + + @ScoreClient + public static SystemInterface SYSTEM_INTERFACE; + + private static void readProperties(Properties props, String confPath){ String chainName = "chain"; - String nid = props.getProperty(chainName + ".nid"); - if (nid == null) { + String nid = props.getProperty(chainName +".nid"); + if (nid == null){ throw new IllegalArgumentException("nid not found"); } + String godWalletPath = confPath + props.getProperty(chainName + ".godWallet"); + + String godPassword = props.getProperty(chainName + ".godPassword"); KeyWallet godWallet; try { godWallet = readWalletFromFile(godWalletPath, godPassword); + loadPREPs(confPath + "preps.json"); } catch (IOException e) { throw new IllegalArgumentException(e.getMessage()); } @@ -54,26 +93,39 @@ private static void readProperties(Properties props, String confPath) { throw new IllegalArgumentException("apiVersion not found"); } chain = new Chain(BigInteger.valueOf(Integer.parseInt(nid.substring(2), 16)), godWallet, url, apiVersion); + godClient = new DefaultScoreClient( + chain.getEndpointURL(), + chain.networkId, + chain.godWallet, + DefaultScoreClient.ZERO_ADDRESS + ); + } + + private static void loadPREPs(String path) throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + InputStream is = ClassLoader.getSystemResource(path).openStream(); + + preps = objectMapper.readValue(is, new TypeReference>() { + }); + } private static KeyWallet readWalletFromFile(String path, String password) throws IOException { + InputStream is = ClassLoader.getSystemResource(path).openStream(); try { - File file = new File(path); + File file = File.createTempFile("tmp", ".tmp"); + FileUtils.copyInputStreamToFile(is, file); return KeyWallet.load(password, file); } catch (KeystoreException e) { e.printStackTrace(); throw new IOException("Key load failed!"); + } finally { + IOUtils.closeQuietly(is); } } - public static Chain getDefaultChain() { - if (chain == null) { - throw new AssertionError("Chain not found"); - } - return chain; - } - public static class Chain { + public final BigInteger networkId; public final Wallet godWallet; private final String nodeUrl; diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreDeployer.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreDeployer.java new file mode 100644 index 00000000..52fa4edc --- /dev/null +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreDeployer.java @@ -0,0 +1,89 @@ +package community.icon.cps.score.test.integration; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import community.icon.cps.score.test.integration.model.Score; +import foundation.icon.jsonrpc.Address; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.stream.Collectors; + +public class ScoreDeployer { + + private String contracts; + private CPS cps; + + public ScoreDeployer(CPS cps, String contracts){ + this.contracts = contracts; + this.cps = cps; + } + + public Map deployContracts() throws IOException, InterruptedException { + Map> scores = readSCOREs(); + + ExecutorService exec = Executors.newFixedThreadPool(10); + + Map addresses = new HashMap<>(); + +// addresses.put("owner", foundation.icon.jsonrpc.Address.of(cps.owner)); + + for (Map.Entry> entry : scores.entrySet()) { + Map> result = new HashMap<>(); + for (Score score : entry.getValue()) { + score.setPath(cps.getScorePath(score.getContract())); + System.out.println("deploying contract " + score.getName() + " :: " + score.getPath()); + Thread.sleep(200); + Map addressParams = score.getAddressParams(); + + for (Map.Entry params : addressParams.entrySet()) { + String key = params.getKey(); + String value = params.getValue(); + score.addParams(key, addresses.get(value)); + } + + result.put(score.getName(), exec.submit(cps.deploy(score))); + } + + for (Map.Entry> futureEntry : result.entrySet()) { + try { + foundation.icon.jsonrpc.Address address = futureEntry.getValue().get(); + String name = futureEntry.getKey(); + addresses.put(name, address); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(futureEntry.getKey() + " -- " + e.getMessage()); + } + } + } + + exec.shutdown(); + + return addresses; + } + + + + private Map> readSCOREs() throws IOException { + + ObjectMapper objectMapper = new ObjectMapper(); + InputStream is = this.getClass() + .getClassLoader() + .getResourceAsStream(this.contracts); + + List list = objectMapper.readValue(is, new TypeReference>() { + }); + return list.stream() + .sorted((x, y) -> Float.compare(y.getOrder(), x.getOrder())) + .collect(Collectors.groupingBy(Score::getOrder, Collectors.toList())); + + } +} diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreIntegrationTest.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreIntegrationTest.java index 4390c289..ce1ddc91 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreIntegrationTest.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreIntegrationTest.java @@ -1,181 +1,39 @@ package community.icon.cps.score.test.integration; -import community.icon.cps.score.lib.interfaces.SystemInterface; import foundation.icon.icx.KeyWallet; import foundation.icon.icx.Wallet; -import foundation.icon.icx.data.Bytes; import foundation.icon.jsonrpc.Address; -import foundation.icon.jsonrpc.model.Hash; import foundation.icon.jsonrpc.model.TransactionResult; import foundation.icon.score.client.DefaultScoreClient; import foundation.icon.score.client.RevertedException; -import community.icon.cps.score.lib.interfaces.SystemInterfaceScoreClient; -import net.bytebuddy.pool.TypePool; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.api.function.Executable; import score.UserRevertedException; -import java.io.BufferedReader; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.PrintStream; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; -import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Random; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; -import static community.icon.cps.score.test.integration.Env.Chain; -import static community.icon.cps.score.test.integration.Env.getDefaultChain; +import static community.icon.cps.score.test.integration.Environment.godClient; +import static foundation.icon.jsonrpc.IconJsonModule.hexToBytes; import static org.junit.jupiter.api.Assertions.assertEquals; -import static community.icon.cps.score.lib.interfaces.SystemInterface.Delegation; -import static community.icon.cps.score.lib.interfaces.SystemInterface.Bond; @Tag("integration") @TestMethodOrder(value = MethodOrderer.OrderAnnotation.class) public interface ScoreIntegrationTest { - Chain chain = getDefaultChain(); - DefaultScoreClient godClient = new DefaultScoreClient(chain.getEndpointURL(), chain.networkId, chain.godWallet, - DefaultScoreClient.ZERO_ADDRESS); - DefaultScoreClient client = new DefaultScoreClient(chain.getEndpointURL(), chain.networkId, null, null); - - SystemInterfaceScoreClient systemScore = new SystemInterfaceScoreClient(godClient); - public static final BigInteger EXA = BigInteger.valueOf(1_000_000_000_000_000_000L); - - @SuppressWarnings("unchecked") - static void registerPreps() throws Exception { - - Map getPreps; - String privateKey = ""; - - try { - getPreps = systemScore.getPReps(BigInteger.ONE, BigInteger.valueOf(7)); - } catch (Exception e) { - privateKey = registerPrep(); - getPreps = systemScore.getPReps(BigInteger.ONE, BigInteger.valueOf(7)); - } - - List> prepList = (List>) getPreps.get("preps"); - int prepCount = prepList.size(); - if (prepCount >= 7) { - return; - } - int remainingPrepsToRegister = 7 - prepCount; - for (int i = 0; i < remainingPrepsToRegister; i++) { - privateKey = privateKey + registerPrep(); - } - PrintStream out = new PrintStream(new FileOutputStream("privateKey.txt")); - System.out.println("private keys: " + privateKey); - out.println(privateKey); - BufferedReader br = new BufferedReader(new FileReader("privateKey.txt")); - System.out.println("Reading the content of the file: " + br.readLine()); - } - - private static String registerPrep() throws Exception { - KeyWallet owner = createWalletWithBalance(BigInteger.TEN.pow(24)); - String privateKey = String.valueOf(owner.getPrivateKey()); -// PrintStream out = new PrintStream(new FileOutputStream("privateKey.txt")); -// System.out.println("private keys: " + privateKey); -// out.println(privateKey); - DefaultScoreClient godClient = new DefaultScoreClient(chain.getEndpointURL(), chain.networkId, owner, - DefaultScoreClient.ZERO_ADDRESS); - SystemInterfaceScoreClient systemScore = new SystemInterfaceScoreClient(godClient); - systemScore.registerPRep(BigInteger.valueOf(2000).multiply(BigInteger.TEN.pow(18)), "test", - "kokoa@example.com", "USA", "New York", "https://icon.kokoa.com", - "https://icon.kokoa.com/json/details.json", "localhost:9082"); - return privateKey; - } - - public static void registerGodClient() { - systemScore.registerPRep(BigInteger.valueOf(2000).multiply(BigInteger.TEN.pow(18)), "test", - "kokoa@example.com", "USA", "New York", "https://icon.kokoa.com", - "https://icon.kokoa.com/json/details.json", "localhost:9082"); - - } - - public static void registerPrepByPrivateKey(KeyWallet owner){ - DefaultScoreClient godClient = new DefaultScoreClient(chain.getEndpointURL(), chain.networkId, owner, - DefaultScoreClient.ZERO_ADDRESS); - SystemInterfaceScoreClient systemScore = new SystemInterfaceScoreClient(godClient); - systemScore.registerPRep(BigInteger.valueOf(2000).multiply(BigInteger.TEN.pow(18)), "test", - "kokoa@example.com", "USA", "New York", "https://icon.kokoa.com", - "https://icon.kokoa.com/json/details.json", "localhost:9082"); - } - - public static void setStake(KeyWallet[] owner) { - for (int i = 0; i < owner.length; i++) { - DefaultScoreClient godClient = new DefaultScoreClient(chain.getEndpointURL(), chain.networkId, owner[i], - DefaultScoreClient.ZERO_ADDRESS); - SystemInterfaceScoreClient systemScore = new SystemInterfaceScoreClient(godClient); - systemScore.setStake(BigInteger.valueOf(1000).multiply(EXA)); - } - } - - public static void setGodStake(){ - systemScore.setStake(BigInteger.valueOf(9000000).multiply(EXA)); - Delegation[] delegation = new Delegation[1]; - delegation[0] = new Delegation(); - delegation[0].address = score.Address.fromString(chain.godWallet.getAddress().toString()); - delegation[0].value = BigInteger.valueOf(8000000).multiply(EXA); - systemScore.setDelegation(delegation); - - score.Address[] addresses = new score.Address[1]; - addresses[0] = score.Address.fromString(chain.godWallet.getAddress().toString()); - systemScore.setBonderList(addresses); - - Bond[] bonds = new Bond[1]; - bonds[0] = new Bond(); - bonds[0].address = score.Address.fromString(chain.godWallet.getAddress().toString()); - bonds[0].value = BigInteger.valueOf(1000000).multiply(EXA); - systemScore.setBond(bonds); - } - public static void setDelegation(KeyWallet[] owner){ - for (int i = 0; i < owner.length; i++) { - Delegation[] delegations = new Delegation[1]; - delegations[0] = new Delegation(); - delegations[0].address = score.Address.fromString(owner[i].getAddress().toString()); - delegations[0].value = BigInteger.valueOf(400).multiply(EXA); - DefaultScoreClient godClient = new DefaultScoreClient(chain.getEndpointURL(), chain.networkId, owner[i], - DefaultScoreClient.ZERO_ADDRESS); - SystemInterfaceScoreClient systemScore = new SystemInterfaceScoreClient(godClient); - systemScore.setDelegation(delegations); - } - } - - public static void setBond(KeyWallet[] owner) { - for (int i = 0; i < owner.length; i++) { - Bond[] bond = new Bond[1]; - bond[0] = new Bond(); - bond[0].address = score.Address.fromString(owner[i].getAddress().toString()); - bond[0].value = BigInteger.valueOf(400).multiply(EXA); - DefaultScoreClient godClient = new DefaultScoreClient(chain.getEndpointURL(), chain.networkId, owner[i], - DefaultScoreClient.ZERO_ADDRESS); - SystemInterfaceScoreClient systemScore = new SystemInterfaceScoreClient(godClient); - systemScore.setBond(bond); - } - } - - public static void setBonderList(KeyWallet[] owner){ - for (int i = 0; i < owner.length; i++) { - score.Address[] bonderList = new score.Address[1]; - bonderList[0] = score.Address.fromString(owner[i].getAddress().toString()); - DefaultScoreClient godClient = new DefaultScoreClient(chain.getEndpointURL(), chain.networkId, owner[i], - DefaultScoreClient.ZERO_ADDRESS); - SystemInterfaceScoreClient systemScore = new SystemInterfaceScoreClient(godClient); - systemScore.setBonderList(bonderList); - } - } static KeyWallet createWalletWithBalance(BigInteger amount) throws Exception { KeyWallet wallet = KeyWallet.create(); @@ -188,28 +46,6 @@ static void transfer(Address address, BigInteger amount) { godClient._transfer(address, amount, null); } - static DefaultScoreClient deploy(Wallet wallet, String name, Map params) { - String path = getFilePath(name); - return DefaultScoreClient._deploy(chain.getEndpointURL(), chain.networkId, wallet, path, params); - } - - static Hash deployAsync(Wallet wallet, String name, Map params) { - String path = getFilePath(name); - return DefaultScoreClient._deployAsync(chain.getEndpointURL(), chain.networkId, wallet, path, params); - } - - static DefaultScoreClient getDeploymentResult(Wallet wallet, Hash hash) { - return DefaultScoreClient.getDeploymentResult(chain.getEndpointURL(), chain.networkId, wallet, hash); - } - - static String getFilePath(String key) { - String path = System.getProperty(key); - if (path == null) { - throw new IllegalArgumentException("No such property: " + key); - } - return path; - } - static int indexOf(T[] array, T value) { return indexOf(array, value::equals); } @@ -231,13 +67,19 @@ static boolean contains(Map map, String key, Predicate predica return map.containsKey(key) && predicate.test(map.get(key)); } - static List eventLogs(TransactionResult txr, String signature, Address scoreAddress, - Function mapperFunc, Predicate filter) { - Predicate predicate = (el) -> el.getIndexed().get(0).equals(signature); + static List eventLogs(TransactionResult txr, + String signature, + Address scoreAddress, + Function mapperFunc, + Predicate filter) { + Predicate predicate = + (el) -> el.getIndexed().get(0).equals(signature); if (scoreAddress != null) { - predicate = predicate.and((el) -> el.getScoreAddress().toString().equals(scoreAddress.toString())); + predicate = predicate.and((el) -> el.getScoreAddress().equals(scoreAddress)); } - Stream stream = txr.getEventLogs().stream().filter(predicate).map(mapperFunc); + Stream stream = txr.getEventLogs().stream() + .filter(predicate) + .map(mapperFunc); if (filter != null) { stream = stream.filter(filter); } @@ -245,7 +87,7 @@ static List eventLogs(TransactionResult txr, String signature, Address sc } static void waitByNumOfBlock(long numOfBlock) { - waitByHeight(client._lastBlockHeight().add(BigInteger.valueOf(numOfBlock))); + waitByHeight(godClient._lastBlockHeight().add(BigInteger.valueOf(numOfBlock))); } static void waitByHeight(long waitHeight) { @@ -253,7 +95,7 @@ static void waitByHeight(long waitHeight) { } static void waitByHeight(BigInteger waitHeight) { - BigInteger height = client._lastBlockHeight(); + BigInteger height = godClient._lastBlockHeight(); while (height.compareTo(waitHeight) < 0) { System.out.println("height: " + height + ", waitHeight: " + waitHeight); try { @@ -261,12 +103,12 @@ static void waitByHeight(BigInteger waitHeight) { } catch (InterruptedException e) { e.printStackTrace(); } - height = client._lastBlockHeight(); + height = godClient._lastBlockHeight(); } } static void balanceCheck(Address address, BigInteger value, Executable executable) { - BigInteger balance = client._balance(address); + BigInteger balance = godClient._balance(address); try { executable.execute(); } catch (UserRevertedException | RevertedException e) { @@ -274,11 +116,12 @@ static void balanceCheck(Address address, BigInteger value, Executable executabl } catch (Throwable e) { throw new RuntimeException(e); } - assertEquals(balance.add(value), client._balance(address)); + assertEquals(balance.add(value), godClient._balance(address)); } @FunctionalInterface interface EventLogsSupplier { + List apply(TransactionResult txr, Address address, Predicate filter); } @@ -293,8 +136,8 @@ static Consumer eventLogChecker( }; } - static Consumer eventLogsChecker(Address address, EventLogsSupplier supplier, - Consumer> consumer) { + static Consumer eventLogsChecker( + Address address, EventLogsSupplier supplier, Consumer> consumer) { return (txr) -> { List eventLogs = supplier.apply(txr, address, null); if (consumer != null) { @@ -303,11 +146,7 @@ static Consumer eventLogsChecker(Address address, EventLo }; } - static Consumer dummyConsumer() { - return (txr) -> { - - }; - } + Wallet tester = getOrGenerateWallet("tester.", System.getProperties()); static Wallet getOrGenerateWallet(String prefix, Properties properties) { Wallet wallet = DefaultScoreClient.wallet(prefix, properties); @@ -321,6 +160,24 @@ static KeyWallet generateWallet() { throw new RuntimeException(e); } } + + interface Faker { + + com.github.javafaker.Faker faker = new com.github.javafaker.Faker(); + Random random = new Random(); + + static Address address(Address.Type type) { + byte[] body = hexToBytes(faker.crypto().sha256().substring(0, (Address.LENGTH - 1) * 2)); + return new Address(type, body); + } + + static byte[] bytes(int length) { + byte[] bytes = new byte[length]; + random.nextBytes(bytes); + return bytes; + } + } + } diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/model/Score.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/model/Score.java new file mode 100644 index 00000000..a49e6515 --- /dev/null +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/model/Score.java @@ -0,0 +1,81 @@ +package community.icon.cps.score.test.integration.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import foundation.icon.jsonrpc.Address; +import java.util.Map; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Score { + + private String name; + private String contract; + private String path; + private Map params; + private Map addressParams; + private Address address; + private float order; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public Map getParams() { + return params; + } + + public void setParams(Map params) { + this.params = params; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + + public float getOrder() { + return order; + } + + public void setOrder(float order) { + this.order = order; + } + + public String getContract() { + return contract == null ? name : contract; + } + + public void setContract(String contract) { + this.contract = contract; + } + + public Map getAddressParams() { + if (addressParams == null) { + return Map.of(); + } + return addressParams; + } + + public void setAddressParams(Map addressParams) { + this.addressParams = addressParams; + } + + public void addParams(String key, Object value) { + this.params.put(key, value); + } +} + diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPFTreasuryInterface.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPFTreasuryInterface.java new file mode 100644 index 00000000..f03ea500 --- /dev/null +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPFTreasuryInterface.java @@ -0,0 +1,149 @@ +package community.icon.cps.score.test.integration.scores; + + +import score.Address; +import score.annotation.EventLog; +import score.annotation.External; +import score.annotation.Optional; +import score.annotation.Payable; + +import java.math.BigInteger; +import java.util.Map; + +public interface CPFTreasuryInterface { + @External(readonly = true) + String name(); + + @External + void setCpsScore(Address score); + + @External(readonly = true) + Address getCpsScore(); + + @External + void setCpsTreasuryScore(Address score); + + @External(readonly = true) + Address getCpsTreasuryScore(); + + @External + void setBnUSDScore(Address score); + + @External(readonly = true) + Address getBnUSDScore(); + + @External + void setSicxScore(Address score); + + @External(readonly = true) + Address getSicxScore(); + + @External + void setDexScore(Address score); + + @External(readonly = true) + Address getDexScore(); + + @External + void setRouterScore(Address score); + + @External(readonly = true) + Address getRouterScore(); + + @External + void setOracleAddress(Address score); + + @External(readonly = true) + Address getOracleAddress(); + + @External + void setSponsorBondPercentage(BigInteger bondValue); + + @External + void setPeriod(BigInteger applicationPeriod); + + @External + void setOnsetPayment(BigInteger paymentPercentage); + + @External(readonly = true) + int getSlippagePercentage(); + + @External(readonly = true) + BigInteger getEmergencyFund(); + + @External + void setMaximumTreasuryFundIcx(BigInteger value); + + @External + void setMaximumTreasuryFundBnusd(BigInteger value); + + @External + void setSwapLimitAmount(BigInteger value); + + @External(readonly = true) + Map getTotalFunds(); + + @External(readonly = true) + Map getRemainingSwapAmount(); + + @External + void transferProposalFundToCpsTreasury(String ipfsKey, int projectDuration, + Address sponsorAddress, Address contributorAddress, + String tokenFlag, BigInteger totalBudget); + + @External + void updateProposalFund(String ipfsKey, @Optional String flag, @Optional BigInteger addedBudget, + @Optional int totalInstallmentCount); + + @External + void withdrawFromEmergencyFund(BigInteger value, Address address, String purpose); + + @External + void allocateEmergencyFund(BigInteger value); + + @External + void setOraclePercentageDifference(int value); + + @External + @Payable + void addFund(); + + @External + void swapICXToBnUSD(BigInteger amount, @Optional BigInteger _minReceive); + + @External + void swapTokens(int _count); + + @External(readonly = true) + Map getSwapStateStatus(); + + @External + void resetSwapState(); + + @External(readonly = true) + Map getProposalDetails(@Optional int startIndex, @Optional int endIndex); + + @External + void tokenFallback(Address from, BigInteger value, byte[] _data); + + @Payable + void fallback(); + @External + void toggleSwapFlag(); + + //EventLogs + @EventLog(indexed = 1) + void FundReturned(Address _sponsor_address, String note); + + @EventLog(indexed = 1) + void ProposalFundTransferred(String _ipfs_key, String note); + + @EventLog(indexed = 1) + void ProposalDisqualified(String _ipfs_key, String note); + + @EventLog(indexed = 1) + void FundReceived(Address _sponsor_address, String note); + + @EventLog(indexed = 1) + void EmergencyFundTransferred(Address _address, BigInteger _value, String _purpose); +} diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java new file mode 100644 index 00000000..2438b81e --- /dev/null +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java @@ -0,0 +1,318 @@ +package community.icon.cps.score.test.integration.scores; + + +import foundation.icon.score.client.ScoreClient; +import foundation.icon.score.client.ScoreInterface; +import score.Address; +import score.annotation.EventLog; +import score.annotation.External; +import score.annotation.Optional; +import score.annotation.Payable; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +public interface CPSCoreInterface { + + public static class ProposalAttributes { + public String ipfs_hash; + public String project_title; + public int project_duration; + public BigInteger total_budget; + public String token; + public Address sponsor_address; + public String ipfs_link; + public int milestoneCount; + public Boolean isMilestone; + + } + + public static class ProgressReportAttributes { + public String ipfs_hash; + public String report_hash; + public String ipfs_link; + public String progress_report_title; + public Boolean budget_adjustment; + public BigInteger additional_budget; + public int additional_month; +// public int[] milestoneCompleted; + } + + public static class MilestonesAttributes { + public int id; + public int completionPeriod; + public BigInteger budget; + } + + public static class MilestoneSubmission{ + public int id; + public boolean status; + } + + public static class MilestoneVoteAttributes { + public int id; + public String vote; + } + + @External(readonly = true) + String name(); + + String proposalPrefix(String proposalKey); + + String progressReportPrefix(String progressKey); + + @External + void setCpsTreasuryScore(Address score); + + @External(readonly = true) + Address getCpsTreasuryScore(); + + @External + void setCpfTreasuryScore(Address score); + + @External(readonly = true) + Address getCpfTreasuryScore(); + + + @External + void setBnusdScore(Address score); + + + @External(readonly = true) + Address getBnusdScore(); + + + @External(readonly = true) + boolean isAdmin(Address address); + + @External + void toggleBudgetAdjustmentFeature(); + + @External(readonly = true) + boolean getBudgetAdjustmentFeature(); + + + @External + void toggleMaintenance(); + + @External(readonly = true) + boolean getMaintenanceMode(); + + @Payable + void fallback(); + + + @External + void addAdmin(Address address); + + + @External + void removeAdmin(Address address); + + + @External + void unregisterPrep(); + + + @External + void registerPrep(); + + @External(readonly = true) + boolean checkPriorityVoting(Address prep); + + @External(readonly = true) + List sortPriorityProposals(); + + @External(readonly = true) + Map getPriorityVoteResult(); + + @External + void votePriority(String[] proposals); + + + @External + void setPrepPenaltyAmount(BigInteger[] penalty); + + + @External + void setInitialBlock(); + + + @External(readonly = true) + Map loginPrep(Address address); + + + @External(readonly = true) + List
getAdmins(); + + @SuppressWarnings("unchecked") + + @External(readonly = true) + Map getRemainingFund(); + + + @External(readonly = true) + List> getPReps(); + + + @External(readonly = true) + List
getDenylist(); + + + @External(readonly = true) + Map getPeriodStatus(); + + + @External(readonly = true) + List
getContributors(); + + + @External(readonly = true) + Map checkClaimableSponsorBond(Address address); + + + @Payable + @External + void submitProposal(community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProposalAttributes proposals, community.icon.cps.score.lib.interfaces.CPSCoreInterface.MilestonesAttributes[] milestones); + + + @External + void voteProposal(String ipfsKey, String vote, String voteReason, @Optional boolean voteChange); + + + @External + void submitProgressReport(community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProgressReportAttributes progressReport, community.icon.cps.score.lib.interfaces.CPSCoreInterface.MilestoneSubmission[] milestoneSubmissions); + + + @External + void voteProgressReport(String reportKey, String voteReason, community.icon.cps.score.lib.interfaces.CPSCoreInterface.MilestoneVoteAttributes[] votes, @Optional String budgetAdjustmentVote, @Optional boolean voteChange); + + + @External(readonly = true) + List getProposalsKeysByStatus(String _status); + + + @External(readonly = true) + int checkChangeVote(Address address, String ipfsHash, String proposalType); + + + @External(readonly = true) + Map getProjectAmounts(); + + + @External(readonly = true) + Map getSponsorsRecord(); + + @External + void updatePeriod(); + + + @External(readonly = true) + Map getProposalDetails(String status, @Optional Address walletAddress, @Optional int startIndex); + + @External(readonly = true) + Map getProposalDetailsByHash(String ipfs_key); + + + @External(readonly = true) + Map getProgressReports(String status, @Optional int startIndex); + + + @External(readonly = true) + Map getProgressReportsByHash(String reportKey); + + + @External(readonly = true) + Map getProgressReportsByProposal(String ipfsKey); + + + @External(readonly = true) + Map getSponsorsRequests(String status, Address sponsorAddress, @Optional int startIndex); + + @External(readonly = true) + Map getVoteResult(String ipfsKey); + + @External(readonly = true) + Map getProgressReportResult(String reportKey); + + @External(readonly = true) + Map getBudgetAdjustmentVoteResult(String reportKey); + + @External + void tokenFallback(Address from, BigInteger value, byte[] data); + + @External + void removeDenylistPreps(); + + @External + void claimSponsorBond(); + + @External + void setSwapCount(int value); + + @External + void updateNextBlock(int blockCount); + + @External + void updateContributor(String _ipfs_key, Address _new_contributor, Address _new_sponsor); + + + @External(readonly = true) + Map getActiveProposalsList(@Optional int startIndex); + + @External(readonly = true) + Map getProposalDetailByWallet(Address walletAddress, @Optional int startIndex); + + @External(readonly = true) + Map getProposalsHistory(@Optional int startIndex); + + @External(readonly = true) + List> getRemainingMilestones(String ipfsHash); + + // EventLogs + @EventLog(indexed = 1) + void ProposalSubmitted(Address _sender_address, String note); + + @EventLog(indexed = 1) + void ProgressReportSubmitted(Address _sender_address, String _project_title); + + @EventLog(indexed = 1) + void SponsorBondReceived(Address _sender_address, String _notes); + + @EventLog(indexed = 1) + void SponsorBondRejected(Address _sender_address, String _notes); + + @EventLog(indexed = 1) + void VotedSuccessfully(Address _sender_address, String _notes); + + @EventLog(indexed = 1) + void PRepPenalty(Address _prep_address, String _notes); + + @EventLog(indexed = 1) + void UnRegisterPRep(Address _sender_address, String _notes); + + @EventLog(indexed = 1) + void RegisterPRep(Address _sender_address, String _notes); + + @EventLog(indexed = 1) + void SponsorBondReturned(Address _sender_address, String _notes); + + @EventLog(indexed = 1) + void PeriodUpdate(String _notes); + + @EventLog(indexed = 1) + void SponsorBondClaimed(Address _receiver_address, BigInteger _fund, String note); + + @EventLog(indexed = 1) + void PriorityVote(Address _address, String note); + + @EventLog(indexed = 1) + void UpdateContributorAddress(Address _old, Address _new); + + @EventLog(indexed = 1) + void UpdateSponsorAddress(Address _old, Address _new); + + @External(readonly = true) + int getPeriodCount(); +} \ No newline at end of file diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSTreasuryInterface.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSTreasuryInterface.java new file mode 100644 index 00000000..8b9cff1b --- /dev/null +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSTreasuryInterface.java @@ -0,0 +1,91 @@ +package community.icon.cps.score.test.integration.scores; + +import score.Address; +import score.annotation.EventLog; +import score.annotation.External; +import score.annotation.Payable; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +public interface CPSTreasuryInterface { + @External(readonly = true) + String name(); + + @Payable + void fallback(); + + @External + void setCpsScore(Address score); + + @External(readonly = true) + Address getCpsScore(); + + @External + void setCpfTreasuryScore(Address score); + + @External(readonly = true) + Address getCpfTreasuryScore(); + + @External + void setBnUSDScore(Address score); + + @External(readonly = true) + Address getBnUSDScore(); + + @External(readonly = true) + Map getContributorProjectedFund(Address walletAddress); + + @External(readonly = true) + List getContributorProjects(Address address); + + @External(readonly = true) + List getSponsorProjects(Address address); + + @External(readonly = true) + Map getSponsorProjectedFund(Address walletAddress); + + @External + @Payable + void updateProposalFund(String ipfsKey, BigInteger addedBudget, BigInteger addedSponsorReward, + int addedInstallmentCount); + + @External + void sendInstallmentToContributor(String ipfsKey, BigInteger milestoneBudget); + + @External + void sendRewardToSponsor(String ipfsKey, int installmentCount); + + @External + void disqualifyProject(String ipfsKey); + + @External + void claimReward(); + + @External + void tokenFallback(Address from, BigInteger value, byte[] _data); + + @External + void setOnsetPayment(BigInteger paymentPercentage); + + @External(readonly = true) + BigInteger getOnsetPayment(); + + @External + void updateContributorSponsorAddress(String _ipfs_key, Address _new_contributor_address, + Address _new_sponsor_address); + + @EventLog(indexed = 1) + void ProposalDisqualified(String _ipfs_key, String note); + + @EventLog(indexed = 1) + void ProposalFundDeposited(String _ipfs_key, String note); + + @EventLog(indexed = 1) + void ProposalFundSent(Address _receiver_address, String note); + + @EventLog(indexed = 1) + void ProposalFundWithdrawn(Address _receiver_address, String note); +} + diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/SystemInterface.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/SystemInterface.java new file mode 100644 index 00000000..f0fd1455 --- /dev/null +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/SystemInterface.java @@ -0,0 +1,48 @@ +package community.icon.cps.score.test.integration.scores; + +import java.math.BigInteger; +import java.util.Map; +import score.Address; +import score.annotation.Payable; + + +public interface SystemInterface { + + public class Delegation{ + public Address address; + public BigInteger value; + } + + public class Bond{ + public Address address; + public BigInteger value; + } + + Map getIISSInfo(); + + Map queryIScore(Address address); + + Map getStake(Address address); + + Map getDelegation(Address address); + + Map getPReps(BigInteger startRanking, BigInteger endRanking); + + @Payable + void registerPRep(String name, String email, String country, String city, String website, String details, + String p2pEndpoint); + + + void setDelegation(Delegation[] delegations); + + void setBond(Bond[] bonds); + + void setBonderList(Address[] bonderList); + + void setStake(BigInteger value); + + Map getPRep(Address address); + void initCommissionRate(BigInteger maxChangeRate,BigInteger maxRate,BigInteger rate); + void setCommissionRate(BigInteger rate); + +} diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/utils/DefaultICONClient.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/utils/DefaultICONClient.java new file mode 100644 index 00000000..cc075c5d --- /dev/null +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/utils/DefaultICONClient.java @@ -0,0 +1,197 @@ +package community.icon.cps.score.test.integration.utils; + +import static foundation.icon.score.client.DefaultScoreClient.callData; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +import community.icon.cps.score.test.integration.Environment; +import foundation.icon.icx.Wallet; +import foundation.icon.jsonrpc.Address; +import foundation.icon.jsonrpc.IconJsonModule; +import foundation.icon.jsonrpc.JsonrpcClient; +import foundation.icon.jsonrpc.SendTransactionParamSerializer; +import foundation.icon.jsonrpc.model.DeployData; +import foundation.icon.jsonrpc.model.Hash; +import foundation.icon.jsonrpc.model.SendTransactionParam; +import foundation.icon.jsonrpc.model.TransactionParam; +import foundation.icon.jsonrpc.model.TransactionResult; +import foundation.icon.score.client.RevertedException; +import java.io.IOException; +import java.math.BigInteger; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import org.apache.commons.io.IOUtils; +import score.UserRevertedException; +import org.bouncycastle.jcajce.provider.digest.SHA3; +import org.bouncycastle.util.encoders.Base64; + +/** + * inspired from foundation.icon.score.client.DefaultScoreClient + */ + +public class DefaultICONClient { + + public static final Address ZERO_ADDRESS = new Address("cx0000000000000000000000000000000000000000"); + public static final BigInteger DEFAULT_STEP_LIMIT = new BigInteger("9502f900", 16); + public static final long BLOCK_INTERVAL = 200; + public static final long DEFAULT_RESULT_RETRY_WAIT = 1000; + public static final long DEFAULT_RESULT_TIMEOUT = 1000; + + private final JsonrpcClient client; + private final BigInteger nid; + + public DefaultICONClient(Environment.Chain chain) { + client = new JsonrpcClient(chain.getEndpointURL()); + client.mapper().registerModule(new IconJsonModule()); + client.mapper().setSerializationInclusion(Include.NON_NULL); + + this.nid = chain.networkId; + + } + + public Address deploy( + Wallet wallet, Address address, + String scoreFilePath, Map params) { + return this.deploy(wallet, address, scoreFilePath, params, DEFAULT_RESULT_TIMEOUT); + } + + public Address deploy( + Wallet wallet, Address address, + String scorePath, Map params, + long timeout) { + + String contentType; + if (scorePath.endsWith(".jar")) { + contentType = "application/java"; + } else if (scorePath.endsWith(".zip")) { + contentType = "application/zip"; + } else { + throw new RuntimeException("not supported score file"); + } + + byte[] content; + try { + URI uri = getURI(scorePath); + content = IOUtils.toByteArray(uri); + } catch (IOException e) { + throw new RuntimeException(e); + } + return deploy(wallet, address, params, timeout, content, contentType); + } + + private Address deploy(Wallet wallet, Address address, Map params, + long timeout, byte[] content, String contentType) { + SendTransactionParam tx = new SendTransactionParam(nid, address, null, "deploy", + new DeployData(contentType, content, params)); + Hash txh = sendTransaction(client, wallet, tx); + waitBlockInterval(); + TransactionResult txr = result(client, txh, timeout); + System.out.println("SCORE address: " + txr.getScoreAddress()); + return txr.getScoreAddress(); + } + + + public TransactionResult send(Wallet wallet, Address address, + BigInteger valueForPayable, String method, Map params, + long timeout) { + SendTransactionParam tx = new SendTransactionParam(nid, address, valueForPayable, "call", + callData(method, params)); + Hash txh = sendTransaction(client, wallet, tx); + waitBlockInterval(); + return result(client, txh, timeout); + } + + public static URI getURI(String url) { + try { + URL obj = new URL(url); + return obj.toURI(); + } catch (MalformedURLException | URISyntaxException ignored) { + return Path.of(url).toUri(); + } + } + + public static TransactionResult result(JsonrpcClient client, Hash txh, long timeout) { + Map params = Map.of("txHash", txh); + long etime = System.currentTimeMillis() + timeout; + TransactionResult txr = null; + while (txr == null) { + try { + txr = client.request(TransactionResult.class, "icx_getTransactionResult", params); + } catch (JsonrpcClient.JsonrpcError e) { + if (e.getCode() == -31002 /* pending */ + || e.getCode() == -31003 /* executing */ + || e.getCode() == -31004 /* not found */) { + if (timeout > 0 && System.currentTimeMillis() >= etime) { + throw new RuntimeException("timeout"); + } + try { + Thread.sleep(DEFAULT_RESULT_RETRY_WAIT); + System.out.println("wait for " + txh); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } else { + throw new RuntimeException(e); + } + } + } + if (!BigInteger.ONE.equals(txr.getStatus())) { + TransactionResult.Failure failure = txr.getFailure(); + int revertCode = failure.getCode().intValue(); + String revertMessage = failure.getMessage(); + if (revertCode >= 32) { + throw new UserRevertedException(revertCode - 32, revertMessage); + } else { + throw new RevertedException(revertCode, revertMessage); + } + } + return txr; + } + + + static Hash sendTransaction(JsonrpcClient client, Wallet wallet, SendTransactionParam sendTransactionParam) { + Objects.requireNonNull(client, "client required not null"); + Objects.requireNonNull(wallet, "wallet required not null"); + Objects.requireNonNull(wallet, "sendTransactionParam required not null"); + + sendTransactionParam.setFrom(Address.of(wallet)); + if (sendTransactionParam.getTimestamp() == null) { + sendTransactionParam.setTimestamp(TransactionParam.currentTimestamp()); + } + if (sendTransactionParam.getStepLimit() == null) { + sendTransactionParam.setStepLimit(DEFAULT_STEP_LIMIT); + } + if (sendTransactionParam.getNid() == null) { + throw new IllegalArgumentException("nid could not be null"); + } + + Map params = new HashMap<>(); + String serialized; + try { + serialized = SendTransactionParamSerializer.serialize(sendTransactionParam, params); + } catch (IOException e) { + throw new RuntimeException(e); + } + byte[] digest = new SHA3.Digest256().digest(serialized.getBytes(StandardCharsets.UTF_8)); + String signature = Base64.toBase64String(wallet.sign(digest)); + params.put("signature", signature); + return client.request(Hash.class, "icx_sendTransaction", params); + } + + static void waitBlockInterval() { + System.out.printf("wait block interval %d msec%n", BLOCK_INTERVAL); + try { + Thread.sleep(BLOCK_INTERVAL); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + } +} + diff --git a/test-lib/conf/env.props b/test-lib/src/main/resources/conf/env.props similarity index 82% rename from test-lib/conf/env.props rename to test-lib/src/main/resources/conf/env.props index 6d1b17d9..6d5ac16e 100644 --- a/test-lib/conf/env.props +++ b/test-lib/src/main/resources/conf/env.props @@ -4,3 +4,5 @@ node.apiVersion=3 chain.nid=0x3 chain.godWallet=godWallet.json chain.godPassword=gochain + +preps.config=preps.json diff --git a/testinteg/build.gradle b/testinteg/build.gradle deleted file mode 100644 index ae8ec6eb..00000000 --- a/testinteg/build.gradle +++ /dev/null @@ -1,8 +0,0 @@ -apply plugin: 'java-library' - -optimizedJar.enabled = false - -dependencies { - implementation 'foundation.icon:icon-sdk:2.0.0' - implementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' -} diff --git a/testinteg/build/classes/java/main/foundation/icon/test/Constants.class b/testinteg/build/classes/java/main/foundation/icon/test/Constants.class deleted file mode 100644 index 1cf1ff974e9aea18836313bc1ad22c2d6c629bce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1131 zcma)5>rxV77=AuLS!q3hcwj6;I{}reovfsCg{5!^9Co4T53?>Su7isMi{o?wT}QW& z{IIE+E})BQdcQ?cvnKb)`#$e!-{bf5*S8-4mZ1a?#Qh;GKpMgr7CBnt=)nNl0ru&0 zfK(5;>X9Fh1w08LfMqT}74VGn=YFjCkz^QAHCZdERkf5#DXPjancLC#b!k_3wxuzpiT8x8%mw$u-rq+m3EK zWxdfcdu3wgJ%ji`DHf`7I$d;=&*!$99lNGGR@0U&!zBk2$+{%hYAv(frb5QFq9UuM zV&yb$JXOeRN?xmKl?|o3QPJKM@(iI~D-GSQORCed?D~p;7YxC3-s^H%7Vwf`FlpJA zL%9gr?$-bS diff --git a/testinteg/build/classes/java/main/foundation/icon/test/Env$Chain.class b/testinteg/build/classes/java/main/foundation/icon/test/Env$Chain.class deleted file mode 100644 index 03b618572f379297e0d9e5c42346b558649081f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1243 zcmaJ=>rN9v6#k|y-L{llm5YL0v`AZlRlK07(ZmKqlZr-eKa7{5JGM)gnPzudDPHxEBDC2Dy>OHsYa{G@U^>0Cny}o2A7s2ylm)M?8VY$ITN^j)D#!EzwPo5 zr&a8J(oTvJ{emr9i=u(Y4D&q=U4)HZ>T*BK(GN7}14c38?*K_7{u&U^_?tjH0@^wZ z5g#VaAs!=sweS^sS)Y{)R&*r z3TlppZvSfbW0G*uPLf9-BLxI%if9BkFdgt2j1td~C5{;anZ$iO!UL+FC3}K`=jq)3 E3#HQ6JN2KG;M;Dwn^ML6|tRA=fIQ}*3!z}SlU%q zt2E|nIa(m4<%R;~K2i#W9AG;(X}AmJzTtnNlsB`oB*zN%&l=6neDlrw-uLF4)hqv9 zcnQEB{98u?j)wgvA9Ff7;i~X7qc9*@)VeJb9sqZMa$oWciGd{9Rlp3v~5SbkQ;hctXx$3}ca#|1nk zR(w>$(;A-9@iBZ{#U}(B$0QDJd;ylRA9bdo~RXo># zFX79g`HE=1YN9@b{dE=JP*68GWjU?_Bk8)fKbW-&1-qaiI(+Pig7w20ujr<&!13IK zlVTItg&;BPP445$RJgLew$Wkt+*awEruF+B*9q>W+pg|Y3Sxs^+E&ms?6~%5F*jlR zC#;DqN6cX_Wo1uUz9XJXgRx-BA);Gg;Wpf$(YLMiao@|^e&7iFyPg~in9VpnmA{-}mK5^8Z2@SZJLZoX$M~;_B9y@$K zW#V&=FNOo?bE#A+~vB3T`^a@-{9I%x%~%HYCf4SYV%G(GD1 zoYh=%Su!vBS(=XpR%&|0%1ioGd{aU5h#gFcMLyjIwoiPfAS{e%$oFzXj-dZ=iL`1& zD=~JzEm-Lts(rQ}_%JY!YYO^q_9afvtHhdp7l6?VW|~ z?Pd~WL?ghwg){oWd*05V2Zs$V7URczpciZ?_PQ6 zDRUmSQX!pT{j0T%m9#_WksWVLGHS+CGs zs^&6eSqI~V;slQ%OT0jvtZBQtvOehs_M}aTvDo+pn~yBwHIOH}lL~fqC2N+l(iO21 zmb~?Z$`u@};WS*p<0}j0$`ZCLwUl^Mo^i28vCyCJtrW>vmXAY!DsAUjOimU^ZF~7>4YV`WF~`k#RBb6lQID#MsUV>)mGuh5 z8?}9MUAaY%hXIv}Zn>OQ4f8ERMx9ZxzXpX5Rgu0Ff0@=QH)PM0S$Byp!-|s#Z`FuL z$NOH#aY3c zhpZIu#u*j=Bn`u!H(kstc(xjCX;FCJJYc!$tXn9J9Ml`VVn&lQ3&MIJCI)mlFi_VPYpa__!$AE-m;H?ZVTdhr7a@;KD7qNPLN8K#U=H_{AZ zPz3`xieY|>-UvpCAd07OjJ*hVd>qHwi*mnr;LYsCxa$c#$X*@ydt=GpI8lvpOy%BP zoF64?C+YES#9qY)6+8L=8h@?StLO}$$}JQX#(&VL;?%3y91i0&*Ty3R20{{v<2w&Q z9AN(fznLs-T14wOGrw-6w{IS|T^i||#rj1U|;G z4m`q7oNQT~IKcir5-!kk1#6`UHjbN{=CJt&pD%GfRBfZQdXON-2;ijLCJLpQL{2Oz zURlp+5qn`C?N`xZZZU74$JV2Z=p3KJw&5%2=vlyaA-S$abPINR$j&Upr|%*6m3uRI(E)u*EQU!;2L%-d|$hZ2@w3=EtJ_x{p~3$bAU7n zTI#Wdz1un4$=){f62To*!EW@?x|=%fA)UR9Xa{oCkI`29ek3IwHl=DFw8VdB{jICo#ouk(JeyCwO2Y?Cs$O kar_nkz~7j+GaT=uSf^=~m8~z^f^3VjeWz?cDci684?+(u3IG5A diff --git a/testinteg/build/classes/java/main/foundation/icon/test/Log.class b/testinteg/build/classes/java/main/foundation/icon/test/Log.class deleted file mode 100644 index f235f026508c7bc42aeb45704bd0272a7ec7c128..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4001 zcma)9+fy6Y8UG!0Ss|8-Ww2w2iJUqK2xJn+wG%^e31=fgNMOtB# zG`*(j{eH`(b(^Lgzx1I^8$1(FJAF!K`qn?CubHOK@0?wP400x(@!9>p{jR_7a>T#? z|NcJ#oWY+oT#e#k7>y8E(vXiL=n>0NatwKx5v*ufjiMcEQAA-ya7{kfBPht{hSag8 zq$A&o8eWW`q@f(6i|dkqLmpew#Y#>x6?`>{ui@(vd?SKyYIs$kd1@v# zo__X9CN-DJeyx1u-!SM zP%#BsYqcgX%?jvasj1nES8}s6>Ffo8Cgqjn`5Ar`=>St;*inz2oy?}F;>$3;nUoX| z4BF$(pP$Lnj$}4ewbI$~Ny!OR&5xxkM=QD<4Ak+EzuTiIAL zOS8sOft*;z$s2_^qhv|iX9nFhi?MWOR-B5xY`B(V4_J8~u32^mGL9@q2&(J%po7{}Ml4>ZNQNR{Y26=-0OxagFkNmNC)z zQe{Qp$UeD|id9%PO9ZD$dAVV^%88)PL!Pv%YigtDZmG0WH}Ymt!b_ddvbj`YsDXmR z^H5KEpZ!6ZnXm}oP`==oH=1)QrMx+A$znzb(+N2`0uS7;bUKFc1)YnakL{qwY`52R zJcXxqT*ji1GjMqC6#5D3_!eH1cE(wUWO6vJ2_?eD5Oz8L`zNF)GIIiR8 z_=S#N;x&R8kHD^bI-RehN$J<&0?VOCg$+OnMVx>$!kJcLYq8O}|_gM_6=oI%F^FK!M z7Jeg5rL%MAGwHG3c*^U$_;rheRB_|B6E}Ano<-d-)=e(Syy4DMU}s%&%q7h1Hf_yrZ{sht(e9JF*vAjxtGn6ElQz+ zt>L$_#%~K8-^I_eH=T9UzY@G0#*Mt|l(say!-8cTXT3t8^t5f8rO|>>F3X+zdM(Vp z4X>Rp8uoI*EFbq22ltn%hI5bN>{ijNBVK!P)v2d%V$>)Ua+YfjYWO2J`o8??#U{}G z>2f&6iG7%tPBS{?H1MqxkKj>qACs4p;`h|h9sJ%~LmwrbKwnk9A4ibfL!YRj2l)N* z8u|&+Cu`^@NuR2rKTrFo@1Yyy7E-Zs?a=R8^*)FezH>?O946-i0(=8H61UNi2)~Cw z;tqlfw-I^|;lC=Cb39up1{~t=jN@oz;?I!MJw=?y2&qPlV$3%hCm`}) z=O=`Qwr9kSr!&+S$Y8?vbdJ`fCoK`~+eTy;%cx?XCKhLETxeAn8nUW!{0y?n?qnUi zp?Y@D((d4Aw>wqGZm^!+VcI?S+3oUr@^SbNn{6qH>1$lSxxM% z7Pi7M)~27uf0E@NW}+8}>=Y(d76~t?D(ch7Db!_)Nc{vQT3 zzRAioHc$Z+l~tdvgJPf9Mr?1@XNY3%J}7$r{i;jbLf*h0ib7&2QC##ESrZ%FN?g)&GlCi$&vFCL%926@MmIFe1roBK0-9SGdFTm$`VG{MmzV=Y1Q38cjO;vUkHfY zLNFH3ErepnatmQnn#lbPoid@?i{voN_5yhgxPssFDgQ3Mi9g_Xyd7QA5z-a@-~0r! CzYGKb diff --git a/testinteg/build/classes/java/main/foundation/icon/test/ResultTimeoutException.class b/testinteg/build/classes/java/main/foundation/icon/test/ResultTimeoutException.class deleted file mode 100644 index 983da11db27ffb9433ca0f6593187dcfdddca511..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1299 zcmah|T~8B16g>l_3$;Q40RcfMANE676HR=m@<1cOq^PkCKKL|j$97=5)9g-3`6vDi zO*AAt_yhb=#yh*4QfLDYduQ(5Gw0lonZN(8{s4H57bzsMXw1?K1y(08hNl+REUYsm zb@z}5O@_6~H`Vd#TubHI(g{u1CZF5;7g_`*!oHE7)O!r0x%@FhqO9tIVX7iM@uAZ? z5q^!IxD=VGD2Kbp+?U3Wg9+V~0mIIK3~_7wvj{q_uE~~A9sREBh_=atH0N@aQ-02E zmwOGns(tA-N=Dpji6G#OP;CIfkU0{%sp_A&&s#zZpOiOp1JcsDQK8|TXb4@4TawM? z?>oYfs;Z9fhy!UVUmjk^uE{Ws38ak4P~#}*?Mq=B&lslTw(hP)vwq7M7FzsFl$Gaj{YB~~?E=j`O>KI0f13s;Vj*Wz zf6lOZorm z5hm$1GWuxTWD~Tf8$$L0c`s=-|HcZJU_WUyf;8C_t-vCIm++8w=?H{LOp#{@GK4S$ zd$byCvQWIl$Zdudl3xuO<|9=<31nD$XjTZw5ih2j-P0pczce0ur_C{Ux8$sZ^G34JU70TJ~#2LJ#7 diff --git a/testinteg/build/classes/java/main/foundation/icon/test/TestBase.class b/testinteg/build/classes/java/main/foundation/icon/test/TestBase.class deleted file mode 100644 index 4b71e21db050852360431081a69597d1a42e2d68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5496 zcmb7IX?Ppe6+O?EHIh6@9LI5@q<|bk;@AlyAq22Pg6%rNMsXlgb|@K3V|!v*BW6a4 zO-pGh1iEjug_dq~arc(cI!?mUeW9iMzSEWN%dfT{Ej@2$BrCRTjK9w_Z{EDSoqOJW zSM&J)&O8d>a{M!bR^-B10W*S)$ji~qVOX#ua8Rh{qOk~W!3*W%iz2ucFII3{Jp^7F zK`m~VGcSwaAnuTtJEe{j3hs)a9=TfFfV<`8<+ZpGuaK8lDtJ`{uf}T>ytanA`M2_b zlzd%1s_=#g4&#jq?uj6VTs^AsW@-B^{>tj7BDfd#DR^rHYwmh-1&IN(kjrR}VdmmS zniog6op_3uPR-V7Wr1efy5%Gb>9lTBBHlbh#7K|EsX~jVEG=hiX{l_FZWppnyL2pQ zxnqI#&qY$8ZkO&1nVIV}OB>N0-J)^dnH`#uEm#aq^__Dxr@+_U&6TlwE_S8If~qe{ znATw2%pbNJ$H>MLhV3wt#&h@8SiZQoHceZ*b#~W1RJOG%c%Oolg7+&JSMUMa z({nZ{-jg2f)UsMGO-9}_f3RjZI5$?aBN+2u(UrltEJ2o4$UEEx#bnCNk|HH%t4HiX zS$f>s$xtY7OQ zNwZ+3^&Q-TEC(sSPF*a`sMw6lRD2khs^~zcijUw@1s_%MF??LXCsaI$PZ8Ko({ya^ z&AeA$>_tILgm6m5Bu*$~;Oz2%nWIKBwaI_=1Wr;!7&N zjIXG89A8z@j;#VqTrgY;by$`*CV8adYj{G%*YOP%-^906d>h{pIDdLoF6};-Fbck_ z;(Pdhg@x|E?&9Whw47tB_yK+x!jGh9KUVP*JR#6JUAHUZ6(h`sT+p(7Tw89?qqTpUyDs=M(uEbJ)+6Ti9&ItNrMimnUHx1@ zYOe^6%=#`i6WSnaYC|!`av+G(0J|Q6HRVqG6}?=i?=?$yvHKA?G>33gxU>YKxmw|)+VGj;=$TFsMc8Z(M%Im8fUmc8BHSOm>2?!_t~&pP%GeflV?1e& z2V$ZvMq(xAp|bLBC?`be)DP-D@9RZ-Y>)0(V=*Ha+ZeO;^u^E4tCE_UjNV`1t}TNq zHDu`;^HgJJbv;jvn|tN1S(InLA-8UNn7Ne=RB*twSk48mtia;KWo4t7okUg3B&w(6BYXo~1O;o#bcApfwsC$t|7!#vr1Gmv z>Uw;2%T6L7)t#hQ69}H67EB;CrF|hk7l0oD6ttj`;Z1qDtda%xw!Xu6^Daf3T3RO% zolr#CZLFWbf=Mjg|DYEaKYP?tKq9h&m`J!n1hE#EaQ#LsC!{fgDecF& zPDKN{@O(G+CUm=S)0pd%zz(ibP<5?>+6EVba240UhhZnKp$3WS5#9s5*R{0Loke{u z8zxXUiN(|7zk=GX#3E)z+Hdh>(1Tt+Q5x4G;YLx1UG$`itHbESZfd`d?}MCKN3Ufr z7F1IV6abgXob1H)o-?A6YD1hmau)RmPhm-4Yg-^1cyvom^_Jk$;L@50aDFtfG`Oiv z+0YVIq`#-pP=)<>1jYC>Pi{Dkr24 zy=}a1Cv;a6^6g}6Cz6Er27-GNL6ZS*V+c)H=!U8AZ5VqPocw-tqy)kd&Zk@uj`$#i zZ~%L;kJ0VtN=a>R<^X48g4Q7L43WoU4oWU`7m~r_h@Hi{gY_*nkD&En^@ilZ zKs1<~#QIa%@Ywh>cS&Y%W`cY9UCm>5FF)XckcA0l9XYdt5nM>7tS6kC319~y+)224 z30#8EUC(ifFy6>-c{&bZh-tZ<(cVemWn%Ua(gYLH#pe(;TF}V9AoUKRA8DdNEJ`Ul zfsD`76VxVoD&G!pR85a=#UP~uZfc@Xo<=zEU$nSsG4?808(#8nM629v1Q^&+m(Gg= zE}b*fr1O7({~-*QO5SSM29tjh7uVHKApQ_8k@OQ~m2VZTXE|4e5qy$&`N{GmKZ`y@ epZ<)$;V+2d80S~ex8sx?b+0dRudjEnZ~8xHz}lby diff --git a/testinteg/build/classes/java/main/foundation/icon/test/TransactionFailureException.class b/testinteg/build/classes/java/main/foundation/icon/test/TransactionFailureException.class deleted file mode 100644 index 84669153c61dd841211b97c9ee3ecb7d045e9660..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 996 zcmbVK%Wl&^6g}glabnyD6hff|QV5U+38ME;e1<7I06b zj*CpW=rS3UiGaVCBr4mDWuB{C;PLPzEs~KmI!yu{PR(h+Tn2}kOmZ38FRxWz#HKqV zc_PqwsuOLV3GDR#hhXbSpuU@ql)&;(C+cM}Iab-BJdRnpG)zMoAIVJHd{(TRv8LSZ zzy4-aZq7=bX?$@Ss<&1;#jfltGfqdZWF{xdsEj;KlOC8%Cy~JA-q!Gqd?$lgCQ(pU z334N4N`-5`8Ya?=gXcQhON@$C#wL$V`zp_6MBUy&T4bRbXgfsb%=W619@^jeSj1f) zP53^ppzY%-)_hz;Ti{XkBu*1!_Hep#Hx@vB`(%@?r9N zb|gl1#*0{jgJos|dWYWYe}U*f_yp$zGY2cQOQ_LaCt{uNcLNuhwaad@tuiBS%F1Ig zUf}uYgk2l0rQfC(^v(W9IG<5_&$uLSOzWK~sbBWYNQK=vD|7JmD!w}x&tuKUFI4fp UIe3R7Tb1j$K<|;Mg*)`EpKe{>{Qv*} diff --git a/testinteg/build/classes/java/main/foundation/icon/test/TransactionHandler.class b/testinteg/build/classes/java/main/foundation/icon/test/TransactionHandler.class deleted file mode 100644 index 043a1741d1e5a04389d4106dd918f7d77fe5c7e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11344 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 Pe`}&TM#sfLb)Elz5+F3w diff --git a/testinteg/build/classes/java/main/foundation/icon/test/score/ChainScore.class b/testinteg/build/classes/java/main/foundation/icon/test/score/ChainScore.class deleted file mode 100644 index f98501d038d468202366a7eb116398f9fa4b1221..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1020 zcma)5U2hUW6g@+cEp#gtv{r2^t=2;Q*vCF#Opw+{f~8@bKKNpW*%5}oESVh)KTCbk z=z~ANA7#9|5KY=m^a}x*Y%>fbL$R&2JeiJr z(wy<$h&-isDER1{8x`9NXVwl>#IT=!MI=Haz2<-`?Z?|XL*C97w=vYxvr-CUSbHPw zAPi2q;bUo~p-bJqw7!*-Q=obO=A#V#JWSjIyadwAqv-$fN=hP~8IUZlxTxgsv<1VcHgRfS%w z^QSt7?bO636>hnK)`aVDgjNUg-Yk{l=mS_j$4<3I8`-;q`BxHr=LUOQ4!CP?2UY`eI z71zn46cn*WU^i%gjnqU7{S}lK$cKc?$hUe>T4G<2{T2s(Bu54@dM-JvB*^YOaDjZ2 OPP62>MPogQzx^9}nHG8g diff --git a/testinteg/build/classes/java/main/foundation/icon/test/score/Score.class b/testinteg/build/classes/java/main/foundation/icon/test/score/Score.class deleted file mode 100644 index 7b327f77570b38bc81302a4c016efe5e49ece887..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8978 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 ae*p!&?k!9>IGI@jjKi0)I@2^}e)}JwOmsB> diff --git a/testinteg/build/tmp/jar/MANIFEST.MF b/testinteg/build/tmp/jar/MANIFEST.MF deleted file mode 100644 index 58630c02..00000000 --- a/testinteg/build/tmp/jar/MANIFEST.MF +++ /dev/null @@ -1,2 +0,0 @@ -Manifest-Version: 1.0 - diff --git a/testinteg/conf/env.props b/testinteg/conf/env.props deleted file mode 100644 index 80aebffc..00000000 --- a/testinteg/conf/env.props +++ /dev/null @@ -1,5 +0,0 @@ -node.url=http://localhost:9082 - -chain.nid=0x3 -chain.godWallet=godWallet.json -chain.godPassword=gochain diff --git a/testinteg/conf/godWallet.json b/testinteg/conf/godWallet.json deleted file mode 100644 index 2a611aa3..00000000 --- a/testinteg/conf/godWallet.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "address": "hxb6b5791be0b5ef67063b3c10b840fb81514db2fd", - "id": "87323a66-289a-4ce2-88e4-00278deb5b84", - "version": 3, - "coinType": "icx", - "crypto": { - "cipher": "aes-128-ctr", - "cipherparams": { - "iv": "069e46aaefae8f1c1f840d6b09144999" - }, - "ciphertext": "f35ff7cf4f5759cb0878088d0887574a896f7f0fc2a73898d88be1fe52977dbd", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "n": 65536, - "r": 8, - "p": 1, - "salt": "0fc9c3b24cdb8175" - }, - "mac": "1ef4ff51fdee8d4de9cf59e160da049eb0099eb691510994f5eca492f56c817a" - } -} diff --git a/testinteg/src/main/java/foundation/icon/test/Constants.java b/testinteg/src/main/java/foundation/icon/test/Constants.java deleted file mode 100644 index 5fba7cf3..00000000 --- a/testinteg/src/main/java/foundation/icon/test/Constants.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2019 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.test; - -import foundation.icon.icx.data.Address; - -import java.math.BigInteger; - -public class Constants { - public static final BigInteger STATUS_SUCCESS = BigInteger.ONE; - public static final BigInteger STATUS_FAILURE = BigInteger.ZERO; - - public static final BigInteger DEFAULT_STEPS = BigInteger.valueOf(100000); - public static final long DEFAULT_WAITING_TIME = 7000; - - public static final Address ZERO_ADDRESS = - new Address("cx0000000000000000000000000000000000000000"); - public static final Address TREASURY_ADDRESS = - new Address("hx1000000000000000000000000000000000000000"); - - public static final String CONTENT_TYPE_PYTHON = "application/zip"; - public static final String CONTENT_TYPE_JAVA = "application/java"; -} diff --git a/testinteg/src/main/java/foundation/icon/test/Env.java b/testinteg/src/main/java/foundation/icon/test/Env.java deleted file mode 100644 index 11416d45..00000000 --- a/testinteg/src/main/java/foundation/icon/test/Env.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2020 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.test; - -import foundation.icon.icx.KeyWallet; -import foundation.icon.icx.Wallet; -import foundation.icon.icx.crypto.KeystoreException; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.file.Path; -import java.util.Properties; - -public class Env { - public static final Log LOG = Log.getGlobal(); - private static Chain chain; - - static { - String envFile = System.getProperty("env.props", "conf/env.props"); - Properties props = new Properties(); - try { - LOG.info("Using env.props: " + envFile); - FileInputStream fis = new FileInputStream(envFile); - props.load(fis); - fis.close(); - } catch (IOException e) { - System.err.printf("'%s' does not exist\n", envFile); - throw new IllegalArgumentException(e.getMessage()); - } - String confPath = Path.of(envFile).getParent().toString() + "/"; - readProperties(props, confPath); - } - - private static void readProperties(Properties props, String confPath) { - String chainName = "chain"; - String nid = props.getProperty(chainName + ".nid"); - if (nid == null) { - throw new IllegalArgumentException("nid not found"); - } - String godWalletPath = confPath + props.getProperty(chainName + ".godWallet"); - String godPassword = props.getProperty(chainName + ".godPassword"); - KeyWallet godWallet; - try { - godWallet = readWalletFromFile(godWalletPath, godPassword); - } catch (IOException e) { - throw new IllegalArgumentException(e.getMessage()); - } - String nodeName = "node"; - String url = props.getProperty(nodeName + ".url"); - if (url == null) { - throw new IllegalArgumentException("node url not found"); - } - chain = new Chain(Integer.parseInt(nid.substring(2), 16), godWallet, url); - } - - private static KeyWallet readWalletFromFile(String path, String password) throws IOException { - try { - File file = new File(path); - return KeyWallet.load(password, file); - } catch (KeystoreException e) { - e.printStackTrace(); - throw new IOException("Key load failed!"); - } - } - - public static Chain getDefaultChain() { - if (chain == null) { - throw new AssertionError("Chain not found"); - } - return chain; - } - - public static class Chain { - public final int networkId; - public final Wallet godWallet; - private final String nodeUrl; - - public Chain(int networkId, Wallet godWallet, String url) { - this.networkId = networkId; - this.godWallet = godWallet; - this.nodeUrl = url; - } - - public String getEndpointURL(int v) { - return this.nodeUrl + "/api/v" + v; - } - } -} diff --git a/testinteg/src/main/java/foundation/icon/test/Log.java b/testinteg/src/main/java/foundation/icon/test/Log.java deleted file mode 100644 index b48cc6da..00000000 --- a/testinteg/src/main/java/foundation/icon/test/Log.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2019 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.test; - -import java.util.EmptyStackException; -import java.util.Stack; - -public class Log { - private static final String[] PREFIX_LEVELS = {null, "[S]", "[W]", null, null}; - private static final String PREFIX_STEP_IN = "--> "; - private static final String PREFIX_STEP_OUT = "<-- "; - private static final String DEPTH_STRING = " "; - - private static final int LEVEL_START = 0; - public static final int LEVEL_NONE = LEVEL_START; - public static final int LEVEL_SEVERE = LEVEL_NONE + 1; - public static final int LEVEL_WARNING = LEVEL_SEVERE + 1; - public static final int LEVEL_INFO = LEVEL_WARNING + 1; - public static final int LEVEL_DEBUG = LEVEL_INFO + 1; - private static final int LEVEL_END = LEVEL_DEBUG; - - private int level = LEVEL_INFO; - private Stack frames = new Stack<>(); - - public static Log getGlobal() { - return new Log(); - } - - public void setLevel(int newLevel) { - if (newLevel >= LEVEL_START && newLevel <= LEVEL_END) { - level = newLevel; - } - } - - private boolean isLoggable(int level) { - return this.level >= level && level > LEVEL_START; - } - - public void info(String msg) { - log(LEVEL_INFO, msg); - } - - public void warning(String msg) { - log(LEVEL_WARNING, msg); - } - - public void severe(String msg) { - log(LEVEL_SEVERE, msg); - } - - public void infoEntering(String taskName, String msg) { - if (taskName == null) { - taskName = ""; - } - if (msg == null) { - msg = ""; - } - StringBuilder buf = new StringBuilder(5 + taskName.length() + msg.length()); - buf.append(PREFIX_STEP_IN).append(taskName); - if (msg.length() > 0) { - buf.append(": ").append(msg); - } - log(LEVEL_INFO, buf.toString()); - frames.push(taskName); - } - - public void infoEntering(String taskName) { - infoEntering(taskName, null); - } - - public void infoExiting(String msg) { - if (msg == null) { - msg = ""; - } - try { - String taskName = frames.pop(); - StringBuilder buf = new StringBuilder(5 + taskName.length() + msg.length()); - buf.append(PREFIX_STEP_OUT).append(taskName); - if (msg.length() > 0) { - buf.append(": ").append(msg); - } - log(LEVEL_INFO, buf.toString()); - } catch (EmptyStackException e) { - log(LEVEL_WARNING, "(INVALID) Exiting without no entering" + msg); - } - } - - public void infoExiting() { - infoExiting(null); - } - - public void debug(String msg) { - log(LEVEL_DEBUG, msg); - } - - public void log(int level, String msg) { - if (msg != null && isLoggable(level)) { - if (PREFIX_LEVELS[level] != null || !frames.empty()) { - StringBuilder buf = new StringBuilder(msg.length() + frames.size() * 3 + 3); - for (int i = frames.size(); i > 0; i--) { - buf.append(DEPTH_STRING); - } - if (PREFIX_LEVELS[level] != null) { - buf.append(PREFIX_LEVELS[level]); - } - buf.append(msg); - msg = buf.toString(); - } - System.out.println(msg); - } - } -} diff --git a/testinteg/src/main/java/foundation/icon/test/ResultTimeoutException.java b/testinteg/src/main/java/foundation/icon/test/ResultTimeoutException.java deleted file mode 100644 index 9f4c6f0f..00000000 --- a/testinteg/src/main/java/foundation/icon/test/ResultTimeoutException.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2019 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.test; - -import foundation.icon.icx.data.Bytes; - -public class ResultTimeoutException extends Exception { - Bytes txHash; - - public ResultTimeoutException() { - super(); - } - - public ResultTimeoutException(String message) { - super(message); - } - - public ResultTimeoutException(Bytes txHash) { - super("Timeout. txHash=" + txHash); - this.txHash = txHash; - } - - public Bytes getTxHash() { - return this.txHash; - } -} diff --git a/testinteg/src/main/java/foundation/icon/test/TestBase.java b/testinteg/src/main/java/foundation/icon/test/TestBase.java deleted file mode 100644 index 0bfe3a2e..00000000 --- a/testinteg/src/main/java/foundation/icon/test/TestBase.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2020 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.test; - -import foundation.icon.icx.data.Address; -import foundation.icon.icx.data.Bytes; -import foundation.icon.icx.data.TransactionResult; -import org.opentest4j.AssertionFailedError; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; - -import static foundation.icon.test.Env.LOG; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; - -public class TestBase { - protected static final BigInteger ICX = BigInteger.TEN.pow(18); - - protected static void assertSuccess(TransactionResult result) { - assertStatus(Constants.STATUS_SUCCESS, result); - } - - protected static void assertFailure(TransactionResult result) { - assertStatus(Constants.STATUS_FAILURE, result); - LOG.info("Expected " + result.getFailure()); - } - - protected static void assertStatus(BigInteger status, TransactionResult result) { - try { - assertEquals(status, result.getStatus()); - } catch (AssertionFailedError e) { - LOG.info("Assertion Failed: result=" + result); - fail(e.getMessage()); - } - } - - protected static void transferAndCheckResult(TransactionHandler txHandler, Address to, BigInteger amount) - throws IOException, ResultTimeoutException { - Bytes txHash = txHandler.transfer(to, amount); - assertSuccess(txHandler.getResult(txHash)); - } - - protected static void transferAndCheckResult(TransactionHandler txHandler, Address[] addresses, BigInteger amount) - throws IOException, ResultTimeoutException { - List hashes = new ArrayList<>(); - for (Address to : addresses) { - hashes.add(txHandler.transfer(to, amount)); - } - for (Bytes hash : hashes) { - assertSuccess(txHandler.getResult(hash)); - } - } - - protected static void ensureIcxBalance(TransactionHandler txHandler, Address address, - BigInteger oldVal, BigInteger newVal) throws Exception { - long limitTime = System.currentTimeMillis() + Constants.DEFAULT_WAITING_TIME; - while (true) { - BigInteger icxBalance = txHandler.getBalance(address); - String msg = "ICX balance of " + address + ": " + icxBalance; - if (icxBalance.equals(oldVal)) { - if (limitTime < System.currentTimeMillis()) { - throw new ResultTimeoutException(); - } - try { - // wait until block confirmation - LOG.debug(msg + "; Retry in 1 sec."); - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } else if (icxBalance.equals(newVal)) { - LOG.info(msg); - break; - } else { - throw new IOException(String.format("ICX balance mismatch: expected <%s>, but was <%s>", - newVal, icxBalance)); - } - } - } -} diff --git a/testinteg/src/main/java/foundation/icon/test/TransactionFailureException.java b/testinteg/src/main/java/foundation/icon/test/TransactionFailureException.java deleted file mode 100644 index bd3a8887..00000000 --- a/testinteg/src/main/java/foundation/icon/test/TransactionFailureException.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2019 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.test; - -import foundation.icon.icx.data.TransactionResult; - -import java.math.BigInteger; - -public class TransactionFailureException extends Exception { - private final TransactionResult.Failure failure; - - public TransactionFailureException(TransactionResult.Failure failure) { - this.failure = failure; - } - - @Override - public String toString() { - return this.failure.toString(); - } - - public BigInteger getCode() { - return this.failure.getCode(); - } - - public String getMessage() { - return this.failure.getMessage(); - } -} diff --git a/testinteg/src/main/java/foundation/icon/test/TransactionHandler.java b/testinteg/src/main/java/foundation/icon/test/TransactionHandler.java deleted file mode 100644 index 92d999cd..00000000 --- a/testinteg/src/main/java/foundation/icon/test/TransactionHandler.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2019 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.test; - -import foundation.icon.icx.Call; -import foundation.icon.icx.IconService; -import foundation.icon.icx.SignedTransaction; -import foundation.icon.icx.Transaction; -import foundation.icon.icx.TransactionBuilder; -import foundation.icon.icx.Wallet; -import foundation.icon.icx.data.Address; -import foundation.icon.icx.data.Bytes; -import foundation.icon.icx.data.ConfirmedTransaction; -import foundation.icon.icx.data.ScoreApi; -import foundation.icon.icx.data.TransactionResult; -import foundation.icon.icx.transport.jsonrpc.RpcError; -import foundation.icon.icx.transport.jsonrpc.RpcItem; -import foundation.icon.icx.transport.jsonrpc.RpcObject; -import foundation.icon.test.score.ChainScore; -import foundation.icon.test.score.Score; -import foundation.icon.test.util.ZipFile; - -import java.io.IOException; -import java.math.BigInteger; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; - -import static foundation.icon.test.Env.LOG; - -public class TransactionHandler { - private final IconService iconService; - private final Env.Chain chain; - - public TransactionHandler(IconService iconService, Env.Chain chain) { - this.iconService = iconService; - this.chain = chain; - } - - public Score deploy(Wallet owner, String scorePath, RpcObject params) - throws IOException, ResultTimeoutException, TransactionFailureException { - return deploy(owner, scorePath, params, null); - } - - public Score deploy(Wallet owner, String scorePath, RpcObject params, BigInteger steps) - throws IOException, ResultTimeoutException, TransactionFailureException { - return deploy(owner, scorePath, Constants.ZERO_ADDRESS, params, steps); - } - - public Score deploy(Wallet owner, String scorePath, Address to, RpcObject params, BigInteger steps) - throws IOException, ResultTimeoutException, TransactionFailureException { - if (scorePath.endsWith(".jar")) { - byte[] data = Files.readAllBytes(Path.of(scorePath)); - return getScore(doDeploy(owner, data, to, params, steps, Constants.CONTENT_TYPE_JAVA)); - } else { - byte[] data = ZipFile.zipContent(scorePath); - return getScore(doDeploy(owner, data, to, params, steps, Constants.CONTENT_TYPE_PYTHON)); - } - } - - private Bytes doDeploy(Wallet owner, byte[] content, Address to, RpcObject params, - BigInteger steps, String contentType) throws IOException { - Transaction transaction = TransactionBuilder.newBuilder() - .nid(getNetworkId()) - .from(owner.getAddress()) - .to(to) - .deploy(contentType, content) - .params(params) - .build(); - if (steps == null) { - steps = estimateStep(transaction); - } - SignedTransaction signedTransaction = new SignedTransaction(transaction, owner, steps); - return iconService.sendTransaction(signedTransaction).execute(); - } - - public Score getScore(Bytes txHash) - throws IOException, ResultTimeoutException, TransactionFailureException { - TransactionResult result = getResult(txHash, Constants.DEFAULT_WAITING_TIME); - if (!Constants.STATUS_SUCCESS.equals(result.getStatus())) { - throw new TransactionFailureException(result.getFailure()); - } - return new Score(this, new Address(result.getScoreAddress())); - } - - public Env.Chain getChain() { - return this.chain; - } - - public BigInteger getNetworkId() { - return BigInteger.valueOf(chain.networkId); - } - - public BigInteger getBalance(Address address) throws IOException { - return iconService.getBalance(address).execute(); - } - - public List getScoreApi(Address scoreAddress) throws IOException { - return iconService.getScoreApi(scoreAddress).execute(); - } - - public BigInteger estimateStep(Transaction transaction) throws IOException { - try { - return iconService.estimateStep(transaction).execute(); - } catch (RpcError e) { - LOG.info("estimateStep failed(" + e.getCode() + ", " + e.getMessage() + "); use default steps."); - return Constants.DEFAULT_STEPS.multiply(BigInteger.TWO); - } - } - - public RpcItem call(Call call) throws IOException { - return this.iconService.call(call).execute(); - } - - public Bytes invoke(Wallet wallet, Transaction tx, BigInteger steps) throws IOException { - if (steps == null) { - steps = estimateStep(tx); - } - return this.iconService.sendTransaction(new SignedTransaction(tx, wallet, steps)).execute(); - } - - public TransactionResult getResult(Bytes txHash) - throws IOException, ResultTimeoutException { - return getResult(txHash, Constants.DEFAULT_WAITING_TIME); - } - - public TransactionResult getResult(Bytes txHash, long waiting) - throws IOException, ResultTimeoutException { - long limitTime = System.currentTimeMillis() + waiting; - while (true) { - try { - return iconService.getTransactionResult(txHash).execute(); - } catch (RpcError e) { - if (e.getCode() == -31002 /* pending */ - || e.getCode() == -31003 /* executing */ - || e.getCode() == -31004 /* not found */) { - if (limitTime < System.currentTimeMillis()) { - throw new ResultTimeoutException(txHash); - } - try { - // wait until block confirmation - LOG.debug("RpcError: code(" + e.getCode() + ") message(" + e.getMessage() + "); Retry in 1 sec."); - Thread.sleep(1000); - } catch (InterruptedException ex) { - ex.printStackTrace(); - } - continue; - } - LOG.warning("RpcError: code(" + e.getCode() + ") message(" + e.getMessage() + "); Retry in 1 sec."); - throw e; - } - } - } - - public Bytes transfer(Address to, BigInteger amount) throws IOException { - return transfer(chain.godWallet, to, amount); - } - - public Bytes transfer(Wallet owner, Address to, BigInteger amount) throws IOException { - return transfer(owner, to, amount, null); - } - - public Bytes transfer(Wallet owner, Address to, BigInteger amount, BigInteger steps) throws IOException { - Transaction transaction = TransactionBuilder.newBuilder() - .nid(getNetworkId()) - .from(owner.getAddress()) - .to(to) - .value(amount) - .build(); - if (steps == null) { - steps = estimateStep(transaction).add(BigInteger.valueOf(10000)); - } - SignedTransaction signedTransaction = new SignedTransaction(transaction, owner, steps); - return iconService.sendTransaction(signedTransaction).execute(); - } - - public void refundAll(Wallet owner) throws IOException { - BigInteger stepPrice = new ChainScore(this).getStepPrice(); - BigInteger remaining = getBalance(owner.getAddress()); - BigInteger fee = Constants.DEFAULT_STEPS.multiply(stepPrice); - transfer(owner, chain.godWallet.getAddress(), remaining.subtract(fee), Constants.DEFAULT_STEPS); - } - - public ConfirmedTransaction getTransaction(Bytes txHash) throws IOException { - return iconService.getTransaction(txHash).execute(); - } -} diff --git a/testinteg/src/main/java/foundation/icon/test/score/ChainScore.java b/testinteg/src/main/java/foundation/icon/test/score/ChainScore.java deleted file mode 100644 index e9f025f5..00000000 --- a/testinteg/src/main/java/foundation/icon/test/score/ChainScore.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2020 ICONLOOP Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.test.score; - -import foundation.icon.test.Constants; -import foundation.icon.test.TransactionHandler; - -import java.io.IOException; -import java.math.BigInteger; - -public class ChainScore extends Score { - - public ChainScore(TransactionHandler txHandler) { - super(txHandler, Constants.ZERO_ADDRESS); - } - - public BigInteger getStepPrice() throws IOException { - return call("getStepPrice", null).asInteger(); - } -} diff --git a/testinteg/src/main/java/foundation/icon/test/score/Score.java b/testinteg/src/main/java/foundation/icon/test/score/Score.java deleted file mode 100644 index d4230f81..00000000 --- a/testinteg/src/main/java/foundation/icon/test/score/Score.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2019 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.test.score; - -import foundation.icon.icx.Call; -import foundation.icon.icx.Transaction; -import foundation.icon.icx.TransactionBuilder; -import foundation.icon.icx.Wallet; -import foundation.icon.icx.data.Address; -import foundation.icon.icx.data.Bytes; -import foundation.icon.icx.data.TransactionResult; -import foundation.icon.icx.data.TransactionResult.EventLog; -import foundation.icon.icx.transport.jsonrpc.RpcItem; -import foundation.icon.icx.transport.jsonrpc.RpcObject; -import foundation.icon.test.Constants; -import foundation.icon.test.ResultTimeoutException; -import foundation.icon.test.TransactionHandler; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.List; - -public class Score { - private final TransactionHandler txHandler; - private final Address address; - - public Score(TransactionHandler txHandler, Address scoreAddress) { - this.txHandler = txHandler; - this.address = scoreAddress; - } - - public Score(Score other) { - this(other.txHandler, other.address); - } - - public static String getFilePath(String pkgName) { - String key = "score.path." + pkgName; - String path = System.getProperty(key); - if (path == null) { - throw new IllegalArgumentException("No such property: " + key); - } - return path; - } - - protected static EventLog findEventLog(TransactionResult result, Address scoreAddress, String funcSig) { - List eventLogs = result.getEventLogs(); - for (EventLog event : eventLogs) { - if (event.getScoreAddress().equals(scoreAddress.toString())) { - String signature = event.getIndexed().get(0).asString(); - if (funcSig.equals(signature)) { - return event; - } - } - } - return null; - } - - public RpcItem call(String method, RpcObject params) - throws IOException { - if (params == null) { - params = new RpcObject.Builder().build(); - } - Call call = new Call.Builder() - .to(getAddress()) - .method(method) - .params(params) - .build(); - return this.txHandler.call(call); - } - - public Bytes invoke(Wallet wallet, String method, RpcObject params) throws IOException { - return invoke(wallet, method, params, BigInteger.ZERO, null); - } - - public Bytes invoke(Wallet wallet, String method, RpcObject params, - BigInteger value, BigInteger steps) throws IOException { - return invoke(wallet, method, params, value, steps, null, null); - } - - public Bytes invoke(Wallet wallet, String method, RpcObject params, BigInteger value, - BigInteger steps, BigInteger timestamp, BigInteger nonce) throws IOException { - Transaction tx = getTransaction(wallet, method, params, value, timestamp, nonce); - return this.txHandler.invoke(wallet, tx, steps); - } - - private Transaction getTransaction(Wallet wallet, String method, RpcObject params, BigInteger value, - BigInteger timestamp, BigInteger nonce) { - TransactionBuilder.Builder builder = TransactionBuilder.newBuilder() - .nid(getNetworkId()) - .from(wallet.getAddress()) - .to(getAddress()); - - if ((value != null) && value.bitLength() != 0) { - builder.value(value); - } - if ((timestamp != null) && timestamp.bitLength() != 0) { - builder.timestamp(timestamp); - } - if (nonce != null) { - builder.nonce(nonce); - } - - Transaction tx; - if (params != null) { - tx = builder.call(method).params(params).build(); - } else { - tx = builder.call(method).build(); - } - return tx; - } - - public TransactionResult invokeAndWaitResult(Wallet wallet, String method, RpcObject params) - throws ResultTimeoutException, IOException { - return invokeAndWaitResult(wallet, method, params, null, null); - } - - public TransactionResult invokeAndWaitResult(Wallet wallet, String method, RpcObject params, - BigInteger steps) - throws ResultTimeoutException, IOException { - return invokeAndWaitResult(wallet, method, params, null, steps); - } - - public TransactionResult invokeAndWaitResult(Wallet wallet, String method, RpcObject params, - BigInteger value, BigInteger steps) - throws ResultTimeoutException, IOException { - Bytes txHash = this.invoke(wallet, method, params, value, steps); - return getResult(txHash); - } - - public TransactionResult getResult(Bytes txHash) throws ResultTimeoutException, IOException { - return getResult(txHash, Constants.DEFAULT_WAITING_TIME); - } - - public TransactionResult getResult(Bytes txHash, long waiting) throws ResultTimeoutException, IOException { - return this.txHandler.getResult(txHash, waiting); - } - - public Address getAddress() { - return this.address; - } - - public BigInteger getNetworkId() { - return txHandler.getNetworkId(); - } - - @Override - public String toString() { - return "SCORE(" + getAddress().toString() + ")"; - } -} diff --git a/testinteg/src/main/java/foundation/icon/test/util/ZipFile.java b/testinteg/src/main/java/foundation/icon/test/util/ZipFile.java deleted file mode 100644 index 8f351df6..00000000 --- a/testinteg/src/main/java/foundation/icon/test/util/ZipFile.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2020 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.test.util; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -public class ZipFile { - public static byte[] zipContent(String path) throws IOException { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - ZipOutputStream zos = new ZipOutputStream(outputStream); - recursiveZip(new File(path), null, zos); - zos.close(); - outputStream.close(); - return outputStream.toByteArray(); - } - - private static void recursiveZip(File source, String zipPath, ZipOutputStream zos) throws IOException { - if (source.isHidden()) { - return; - } - if (source.isDirectory()) { - String dir = source.getName(); - if (!dir.endsWith(File.separator)) { - dir = dir + File.separator; - } - zos.putNextEntry(new ZipEntry(dir)); - zos.closeEntry(); - File[] files = source.listFiles(); - if (files == null) { - return; - } - String path = zipPath == null ? dir : zipPath + dir; - for (File file : files) { - recursiveZip(file, path, zos); - } - } else { - ZipEntry ze = new ZipEntry(zipPath + source.getName()); - zos.putNextEntry(ze); - zos.write(Files.readAllBytes(source.toPath())); - zos.closeEntry(); - } - } -} From d214f59ecd81f15564afc5f1ac52ec0277eac586 Mon Sep 17 00:00:00 2001 From: naneey Date: Mon, 4 Mar 2024 13:10:15 +0545 Subject: [PATCH 02/64] chore: git module added --- .gitmodules | 4 ++++ gochain-local | 1 + 2 files changed, 5 insertions(+) create mode 100644 .gitmodules create mode 160000 gochain-local diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..4c430736 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "gochain-local"] + path = gochain-local + url = git@github.com:nightowl121/gochain-local.git + branch = master \ No newline at end of file diff --git a/gochain-local b/gochain-local new file mode 160000 index 00000000..b71ea0c8 --- /dev/null +++ b/gochain-local @@ -0,0 +1 @@ +Subproject commit b71ea0c8cf960e7247fb086808494481ad036334 From 6fe8986223a235316a88a0173e06bc28d2fbc222 Mon Sep 17 00:00:00 2001 From: naneey Date: Mon, 4 Mar 2024 13:12:51 +0545 Subject: [PATCH 03/64] chore: build.gradle optimized --- CPFTreasury/build.gradle | 25 ++++++++++++---------- CPSCore/build.gradle | 46 ++++++++++++++++++++++++++++++---------- CPSTreasury/build.gradle | 23 +++++++++++--------- score-lib/build.gradle | 38 +++++++++++++++++++++------------ settings.gradle | 37 +++++++++++++++++--------------- 5 files changed, 106 insertions(+), 63 deletions(-) diff --git a/CPFTreasury/build.gradle b/CPFTreasury/build.gradle index cbfe0f77..f92d1017 100644 --- a/CPFTreasury/build.gradle +++ b/CPFTreasury/build.gradle @@ -1,18 +1,21 @@ version = '1.2.0' dependencies { - compileOnly 'foundation.icon:javaee-api:0.9.1' - implementation project(':score-lib') - - implementation 'com.github.sink772:javaee-tokens:0.6.1' - implementation 'com.github.sink772:minimal-json:0.9.6' +// compileOnly 'foundation.icon:javaee-api:0.9.1' +// implementation project(':score-lib') +// +// implementation 'com.github.sink772:javaee-tokens:0.6.1' +// implementation 'com.github.sink772:minimal-json:0.9.6' +// +// testImplementation 'foundation.icon:javaee-unittest:0.9.2' +// implementation 'org.mockito:mockito-core:4.3.1' +// testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' +// testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' +// testImplementation('org.mockito:mockito-inline:4.3.1') +// implementation 'foundation.icon:javaee-scorex:0.5.2' - testImplementation 'foundation.icon:javaee-unittest:0.9.2' - implementation 'org.mockito:mockito-core:4.3.1' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' - testImplementation('org.mockito:mockito-inline:4.3.1') - implementation 'foundation.icon:javaee-scorex:0.5.2' + implementation project(':score-lib') + testImplementation project(':test-lib') } diff --git a/CPSCore/build.gradle b/CPSCore/build.gradle index d09e2b15..57d76811 100644 --- a/CPSCore/build.gradle +++ b/CPSCore/build.gradle @@ -1,21 +1,23 @@ version = '1.3.9' dependencies { - compileOnly 'foundation.icon:javaee-api:0.9.2' - implementation 'com.github.sink772:minimal-json:0.9.7' - implementation 'foundation.icon:javaee-scorex:0.5.3' + + +// compileOnly 'foundation.icon:javaee-api:0.9.2' +// implementation 'com.github.sink772:minimal-json:0.9.7' +// implementation 'foundation.icon:javaee-scorex:0.5.3' implementation project(':score-lib') testImplementation project(':test-lib') - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' - testImplementation('org.mockito:mockito-inline:4.8.0') - testImplementation 'foundation.icon:javaee-unittest:0.9.7' - intTestImplementation 'foundation.icon:icon-sdk:2.2.0' - intTestImplementation project(":score-client") - intTestAnnotationProcessor project(":score-client") - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' +// testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0' +// testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' +// testImplementation('org.mockito:mockito-inline:4.8.0') +// testImplementation 'foundation.icon:javaee-unittest:0.9.7' +// intTestImplementation 'foundation.icon:icon-sdk:2.2.0' +//// intTestImplementation project(":score-client") +//// intTestAnnotationProcessor project(":score-client") +// testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' } optimizedJar { @@ -23,6 +25,7 @@ optimizedJar { from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } + enableDebug = false } deployJar { @@ -65,3 +68,24 @@ test { repositories { mavenCentral() } + +task integrationTest(type: Test) { + useJUnitPlatform() + + + rootProject.allprojects { + if (it.getTasks().findByName('optimizedJar')) { + dependsOn(it.getTasks().getByName('optimizedJar')) + } + } + + options { + testLogging.showStandardStreams = true + description = 'Runs integration tests.' + group = 'verification' + + testClassesDirs = sourceSets.intTest.output.classesDirs + classpath = sourceSets.intTest.runtimeClasspath + } + +} diff --git a/CPSTreasury/build.gradle b/CPSTreasury/build.gradle index fec63b41..e39557ab 100644 --- a/CPSTreasury/build.gradle +++ b/CPSTreasury/build.gradle @@ -1,19 +1,22 @@ version = '1.3.5' dependencies { - compileOnly 'foundation.icon:javaee-api:0.9.2' +// compileOnly 'foundation.icon:javaee-api:0.9.2' + +// implementation project(':score-lib') +// implementation 'com.github.sink772:minimal-json:0.9.7' +// implementation 'foundation.icon:javaee-scorex:0.5.3' +// testImplementation project(':test-lib') +// testImplementation 'foundation.icon:javaee-unittest:0.9.7' +// testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0' +// testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' +// testImplementation('org.mockito:mockito-inline:4.8.0') +// intTestImplementation 'foundation.icon:icon-sdk:2.2.0' +// intTestImplementation project(":score-client") +// intTestAnnotationProcessor project(":score-client") implementation project(':score-lib') - implementation 'com.github.sink772:minimal-json:0.9.7' - implementation 'foundation.icon:javaee-scorex:0.5.3' testImplementation project(':test-lib') - testImplementation 'foundation.icon:javaee-unittest:0.9.7' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' - testImplementation('org.mockito:mockito-inline:4.8.0') - intTestImplementation 'foundation.icon:icon-sdk:2.2.0' - intTestImplementation project(":score-client") - intTestAnnotationProcessor project(":score-client") } optimizedJar { diff --git a/score-lib/build.gradle b/score-lib/build.gradle index 28f2129d..f86d12d6 100644 --- a/score-lib/build.gradle +++ b/score-lib/build.gradle @@ -2,7 +2,6 @@ plugins { id 'java' } -version '0.1.0' repositories { mavenCentral() @@ -11,22 +10,33 @@ repositories { optimizedJar.enabled = false dependencies { - compileOnly 'foundation.icon:javaee-api:0.9.1' - implementation 'foundation.icon:javaee-scorex:0.5.2' - implementation 'com.github.sink772:minimal-json:0.9.7' - - compileOnly 'foundation.icon:javaee-score-client:0.9.0' - annotationProcessor 'foundation.icon:javaee-score-client:0.9.0' +// compileOnly 'foundation.icon:javaee-api:0.9.1' +// implementation group: 'foundation.icon', name: 'javaee-score-json', version: '0.9.0' +// implementation 'foundation.icon:javaee-scorex:0.5.2' +// implementation 'com.github.sink772:minimal-json:0.9.7' // - implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3' - implementation 'foundation.icon:icon-sdk:2.1.0' +//// compileOnly 'foundation.icon:javaee-score-client:0.9.0' +//// annotationProcessor 'foundation.icon:javaee-score-client:0.9.0' +//// +// implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.0-rc1' +// implementation 'foundation.icon:icon-sdk:2.1.0' // +// implementation("foundation.icon:javaee-annotation-processor:0.9.0") +// implementation("com.squareup:javapoet:1.12.1") +// implementation("foundation.icon:javaee-api:0.9.0") +// implementation("foundation.icon:icon-sdk:2.0.0") +// implementation("com.fasterxml.jackson.core:jackson-databind:2.9.6") +// implementation("com.squareup.okhttp3:okhttp:3.11.0") +// implementation("org.bouncycastle:bcprov-jdk15on:1.60") +// compileOnly group: 'commons-io', name: 'commons-io', version: "2.11.0" // - testImplementation 'foundation.icon:javaee-unittest:0.9.4' - testImplementation "org.junit.jupiter:junit-jupiter:5.8.2" - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' - testImplementation 'org.mockito:mockito-core:4.5.1' - testRuntimeOnly 'org.mockito:mockito-inline:4.5.1' +//// +//// +// testImplementation 'foundation.icon:javaee-unittest:0.9.4' +// testImplementation "org.junit.jupiter:junit-jupiter:5.8.2" +// testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' +// testImplementation 'org.mockito:mockito-core:4.5.1' +// testRuntimeOnly 'org.mockito:mockito-inline:4.5.1' } test { diff --git a/settings.gradle b/settings.gradle index 0762b7ba..6914f2e9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -9,23 +9,26 @@ project(':CPSTreasury').projectDir = file("CPSTreasury") include (':CPSCore') project(':CPSCore').projectDir = file("CPSCore") -include ('score-client') - +//include ('score-client') +// include ('test-lib') +project(':test-lib').projectDir = file("test-lib") include ('score-lib') - -include (':Router') -project(':Router').projectDir = file("dummy/Router") - -include (':Dex') -project(':Dex').projectDir = file("dummy/Dex") - -include (':sICX') -project(':sICX').projectDir = file("dummy/sICX") - -include (':bnUSD') -project(':bnUSD').projectDir = file("dummy/bnUSD") - -include(':oracle') -project(':oracle').projectDir = file("dummy/oracle") \ No newline at end of file +project(':score-lib').projectDir = file("score-lib") + +// +//include (':Router') +//project(':Router').projectDir = file("dummy/Router") +// +//include (':Dex') +//project(':Dex').projectDir = file("dummy/Dex") +// +//include (':sICX') +//project(':sICX').projectDir = file("dummy/sICX") +// +//include (':bnUSD') +//project(':bnUSD').projectDir = file("dummy/bnUSD") +// +//include(':oracle') +//project(':oracle').projectDir = file("dummy/oracle") \ No newline at end of file From b49f4115da040c36666ccfd6b33f7ec1aaddb5a6 Mon Sep 17 00:00:00 2001 From: naneey Date: Mon, 4 Mar 2024 13:13:28 +0545 Subject: [PATCH 04/64] chore: dummy files ignored for now --- dummy/Dex/build.gradle | 55 -------- .../src/main/java/dummy/contract/dex/Dex.java | 126 ------------------ dummy/Router/build.gradle | 55 -------- .../java/dummy/contract/router/Router.java | 46 ------- dummy/bnUSD/build.gradle | 43 ------ .../main/java/dummy/contract/bnusd/bnUSD.java | 28 ---- dummy/oracle/build.gradle | 54 -------- .../java/dummy/contract/oracle/Oracle.java | 15 --- dummy/sICX/build.gradle | 43 ------ .../main/java/dummy/contract/sicx/sICX.java | 26 ---- .../score/lib/interfaces/DexInterface.java | 56 ++++---- .../score/lib/interfaces/RouterInterface.java | 36 ++--- .../score/lib/interfaces/bnUSDInterface.java | 20 +-- .../score/lib/interfaces/sICXInterface.java | 20 +-- 14 files changed, 66 insertions(+), 557 deletions(-) delete mode 100644 dummy/Dex/build.gradle delete mode 100644 dummy/Dex/src/main/java/dummy/contract/dex/Dex.java delete mode 100644 dummy/Router/build.gradle delete mode 100644 dummy/Router/src/main/java/dummy/contract/router/Router.java delete mode 100644 dummy/bnUSD/build.gradle delete mode 100644 dummy/bnUSD/src/main/java/dummy/contract/bnusd/bnUSD.java delete mode 100644 dummy/oracle/build.gradle delete mode 100644 dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java delete mode 100644 dummy/sICX/build.gradle delete mode 100644 dummy/sICX/src/main/java/dummy/contract/sicx/sICX.java diff --git a/dummy/Dex/build.gradle b/dummy/Dex/build.gradle deleted file mode 100644 index bed00959..00000000 --- a/dummy/Dex/build.gradle +++ /dev/null @@ -1,55 +0,0 @@ -version = '0.9.1' - -dependencies { - compileOnly 'foundation.icon:javaee-api:0.9.1' - implementation project(':score-lib') - - implementation 'com.github.sink772:javaee-tokens:0.6.1' - implementation 'com.github.sink772:minimal-json:0.9.6' - - testImplementation 'foundation.icon:javaee-unittest:0.9.2' - implementation 'org.mockito:mockito-core:4.3.1' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' - testImplementation('org.mockito:mockito-inline:4.3.1') - implementation 'foundation.icon:javaee-scorex:0.5.2' - -} - -optimizedJar { - mainClassName = 'dummy.contract.dex.Dex' - from { - configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } - } -} - -deployJar { - endpoints { - lisbon { - uri = 'https://lisbon.net.solidwallet.io/api/v3' - nid = 0x2 - } - local { - uri = 'http://localhost:9082/api/v3' - nid = 0x3 - } - sejong { - uri = 'https://sejong.net.solidwallet.io/api/v3' - nid = 0x53 - - } - berlin { - uri = 'https://berlin.net.solidwallet.io/api/v3' - nid = 0x7 - to = 'cx28ae7ed3b07ed5247a3d2f97680f8555ce7c0a92' - } - } - keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' - password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' - parameters { - } -} - -test { - useJUnitPlatform() -} diff --git a/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java b/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java deleted file mode 100644 index 439f8006..00000000 --- a/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java +++ /dev/null @@ -1,126 +0,0 @@ -package dummy.contract.dex; - -import com.eclipsesource.json.Json; -import com.eclipsesource.json.JsonObject; -import score.Address; -import score.Context; -import score.DictDB; -import score.VarDB; -import score.annotation.EventLog; -import score.annotation.External; -import scorex.util.ArrayList; - -import java.math.BigInteger; -import java.util.Arrays; -import java.util.List; - -public class Dex implements community.icon.cps.score.lib.interfaces.DexInterface { - private static final String TAG = "Balanced DEX"; - private final VarDB
sicx = Context.newVarDB("sicx", Address.class); - public static final BigInteger EXA = BigInteger.valueOf(1_000_000_000_000_000_000L); - - public Dex(){} - - @Override - @External - public void setSicxScore(Address _score){ - this.sicx.set(_score); - } - - @External(readonly = true) - public BigInteger getPrice(int poolId){ - return BigInteger.ONE; - } - - @Override - @EventLog - public void Deposit(Address from_token, Address from, BigInteger value){} - - @Override - @EventLog(indexed = 2) - public void Swap(BigInteger _id, Address _baseToken, Address _fromToken, Address _toToken, - Address _sender, Address _receiver, BigInteger _fromValue, BigInteger _toValue, - BigInteger _timestamp, BigInteger _lpFees, BigInteger _balnFees, BigInteger _poolBase, - BigInteger _poolQuote, BigInteger _endingPrice, BigInteger _effectiveFillPrice) { - } - - @Override - @External - public void tokenFallback(Address _from, BigInteger _value, byte[] _data) { - // Parse the transaction data submitted by the user - String unpackedData = new String(_data); - Context.require(!unpackedData.equals(""), "Token Fallback: Data can't be empty"); - if (Arrays.equals(_data, "None".getBytes())){ - return; - } - JsonObject json = Json.parse(unpackedData).asObject(); - - String method = json.get("method").asString(); - Address fromToken = Context.getCaller(); - - Context.require(_value.compareTo(BigInteger.ZERO) > 0, TAG + ": Invalid token transfer value"); - - // Call an internal method based on the "method" param sent in tokenFallBack - switch (method) { - case "_swap_icx": { - Context.require(fromToken.equals(sicx.get()), - TAG + ": InvalidAsset: _swap_icx can only be called with sICX"); - swapIcx(_from, _value); - break; - - } - case "_swap": { - - // Parse the slippage sent by the user in minimumReceive. - // If none is sent, use the maximum. - JsonObject params = json.get("params").asObject(); - BigInteger minimumReceive = BigInteger.ZERO; - if (params.contains("minimumReceive")) { - minimumReceive = BigInteger.valueOf(1000).multiply(EXA); - Context.require(minimumReceive.signum() >= 0, - TAG + ": Must specify a positive number for minimum to receive"); - } - - // Check if an alternative recipient of the swap is set. - Address receiver; - if (params.contains("receiver")) { - receiver = Address.fromString(params.get("receiver").asString()); - } else { - receiver = _from; - } - - // Get destination coin from the swap - Context.require(params.contains("toToken"), TAG + ": No toToken specified in swap"); - Address toToken = Address.fromString(params.get("toToken").asString()); - - // Perform the swap - exchange(fromToken, toToken, _from, receiver, _value, minimumReceive); - - break; - } - default: - // If no supported method was sent, revert the transaction - Context.revert(100, TAG + ": Unsupported method supplied"); - break; - } - } - - void swapIcx(Address sender, BigInteger value) { - Context.transfer(sender, value); - } - - void exchange(Address fromToken, Address toToken, Address sender, - Address receiver, BigInteger value, BigInteger minimumReceive) { - - if (minimumReceive == null) { - minimumReceive = BigInteger.ZERO; - } - - // Send the trader their funds - Context.call(toToken, "transfer", receiver, value); - - Swap(BigInteger.valueOf(0), fromToken, fromToken, toToken, sender, receiver, value, value, - BigInteger.valueOf(Context.getBlockTimestamp()), BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO - , BigInteger.ZERO); - } -} diff --git a/dummy/Router/build.gradle b/dummy/Router/build.gradle deleted file mode 100644 index 3a5641d7..00000000 --- a/dummy/Router/build.gradle +++ /dev/null @@ -1,55 +0,0 @@ -version = '0.9.1' - -dependencies { - compileOnly 'foundation.icon:javaee-api:0.9.1' - implementation project(':score-lib') - - implementation 'com.github.sink772:javaee-tokens:0.6.1' - implementation 'com.github.sink772:minimal-json:0.9.6' - - testImplementation 'foundation.icon:javaee-unittest:0.9.2' - implementation 'org.mockito:mockito-core:4.3.1' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' - testImplementation('org.mockito:mockito-inline:4.3.1') - implementation 'foundation.icon:javaee-scorex:0.5.2' - -} - -optimizedJar { - mainClassName = 'dummy.contract.router.Router' - from { - configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } - } -} - -deployJar { - endpoints { - lisbon { - uri = 'https://lisbon.net.solidwallet.io/api/v3' - nid = 0x2 - } - local { - uri = 'http://localhost:9082/api/v3' - nid = 0x3 - } - sejong { - uri = 'https://sejong.net.solidwallet.io/api/v3' - nid = 0x53 - - } - berlin { - uri = 'https://berlin.net.solidwallet.io/api/v3' - nid = 0x7 - to = 'cx28ae7ed3b07ed5247a3d2f97680f8555ce7c0a92' - } - } - keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' - password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' - parameters { - } -} - -test { - useJUnitPlatform() -} diff --git a/dummy/Router/src/main/java/dummy/contract/router/Router.java b/dummy/Router/src/main/java/dummy/contract/router/Router.java deleted file mode 100644 index a8bcd4f7..00000000 --- a/dummy/Router/src/main/java/dummy/contract/router/Router.java +++ /dev/null @@ -1,46 +0,0 @@ -package dummy.contract.router; - -import score.Address; -import score.Context; -import score.annotation.External; -import score.annotation.Optional; -import score.annotation.Payable; - -import java.math.BigInteger; -import community.icon.cps.score.lib.interfaces.RouterInterface; - -public class Router implements RouterInterface { - private static final String TAG = "Router"; - - public Router(){} - private void route(Address from, Address startToken, Address[] _path, BigInteger _minReceive) { - Address currentToken = _path[1]; - - - BigInteger balance = (BigInteger) Context.call(currentToken, "balanceOf", Context.getAddress()); - Context.require(balance.compareTo(_minReceive) >= 0, - TAG + ": Below minimum receive amount of " + _minReceive); - Context.call(currentToken, "transfer", from, _minReceive); - - } - - @Override - @Payable - @External - public void route(Address[] _path, @Optional BigInteger _minReceive) { - if (_minReceive == null) { - _minReceive = BigInteger.ZERO; - } - - Context.require(_minReceive.signum() >= 0, TAG + ": Must specify a positive number for minimum to receive"); - - Context.require(_path.length <= 2, - TAG + ": Passed max swaps of " + 2); - - route(Context.getCaller(), null, _path, Context.getValue()); - } - - @External - public void tokenFallback(Address _from, BigInteger _value, byte[] _data){ - } -} diff --git a/dummy/bnUSD/build.gradle b/dummy/bnUSD/build.gradle deleted file mode 100644 index f752b4aa..00000000 --- a/dummy/bnUSD/build.gradle +++ /dev/null @@ -1,43 +0,0 @@ -version = '0.9.1' - -dependencies { - compileOnly 'foundation.icon:javaee-api:0.9.2' - implementation 'com.github.sink772:javaee-tokens:0.6.1' - implementation project(':score-lib') - testImplementation 'foundation.icon:javaee-unittest:0.9.4' - testImplementation 'org.mockito:mockito-core:4.6.1' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' -} - -optimizedJar { - mainClassName = 'dummy.contract.bnusd.bnUSD' - from { - configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } - } -} - -deployJar { - endpoints { - lisbon { - uri = 'https://lisbon.net.solidwallet.io/api/v3' - nid = 0x2 - } - local { - uri = 'http://localhost:9082/api/v3' - nid = 0x3 - } - } - keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' - password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' - parameters { - arg('_name', 'Balanced Dollar') - arg('_symbol', 'bnUSD') - arg('_decimals', '0x12') - arg('_initialSupply', '0x989680') - } -} - -test { - useJUnitPlatform() -} \ No newline at end of file diff --git a/dummy/bnUSD/src/main/java/dummy/contract/bnusd/bnUSD.java b/dummy/bnUSD/src/main/java/dummy/contract/bnusd/bnUSD.java deleted file mode 100644 index 0c1560d2..00000000 --- a/dummy/bnUSD/src/main/java/dummy/contract/bnusd/bnUSD.java +++ /dev/null @@ -1,28 +0,0 @@ -package dummy.contract.bnusd; - -import community.icon.cps.score.lib.interfaces.bnUSDInterface; -import community.icon.cps.score.lib.tokens.IRC2Base; -import score.Context; - -import java.math.BigInteger; - -public class bnUSD extends IRC2Base implements bnUSDInterface { - public bnUSD(String _name, String _symbol, int _decimals, BigInteger _initialSupply) { - super(_name, _symbol, BigInteger.valueOf(_decimals)); - - // mint the initial token supply here - Context.require(_initialSupply.compareTo(BigInteger.ZERO) >= 0); - mint(Context.getCaller(), _initialSupply.multiply(pow10(_decimals))); - } - - private static BigInteger pow10(int exponent) { - BigInteger result = BigInteger.ONE; - for (int i = 0; i < exponent; i++) { - result = result.multiply(BigInteger.TEN); - } - return result; - } - - -} - diff --git a/dummy/oracle/build.gradle b/dummy/oracle/build.gradle deleted file mode 100644 index 9fde13bc..00000000 --- a/dummy/oracle/build.gradle +++ /dev/null @@ -1,54 +0,0 @@ -version = '0.9.1' - -dependencies { - compileOnly 'foundation.icon:javaee-api:0.9.1' - implementation project(':score-lib') - - implementation 'com.github.sink772:javaee-tokens:0.6.1' - implementation 'com.github.sink772:minimal-json:0.9.6' - - testImplementation 'foundation.icon:javaee-unittest:0.9.2' - implementation 'org.mockito:mockito-core:4.3.1' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' - testImplementation('org.mockito:mockito-inline:4.3.1') - implementation 'foundation.icon:javaee-scorex:0.5.2' - -} - -optimizedJar { - mainClassName = 'dummy.contract.oracle.Oracle' - from { - configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } - } -} - -deployJar { - endpoints { - lisbon { - uri = 'https://lisbon.net.solidwallet.io/api/v3' - nid = 0x2 - } - local { - uri = 'http://localhost:9082/api/v3' - nid = 0x3 - } - sejong { - uri = 'https://sejong.net.solidwallet.io/api/v3' - nid = 0x53 - - } - berlin { - uri = 'https://berlin.net.solidwallet.io/api/v3' - nid = 0x7 - } - } - keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' - password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' - parameters { - } -} - -test { - useJUnitPlatform() -} diff --git a/dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java b/dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java deleted file mode 100644 index 5b86f2e0..00000000 --- a/dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java +++ /dev/null @@ -1,15 +0,0 @@ -package dummy.contract.oracle; - -import score.annotation.External; - -import java.math.BigInteger; - -public class Oracle { - - @External(readonly = true) - public BigInteger getReferenceData(String _base, String _quote) { - return BigInteger.ONE; - } - - -} diff --git a/dummy/sICX/build.gradle b/dummy/sICX/build.gradle deleted file mode 100644 index 4f993073..00000000 --- a/dummy/sICX/build.gradle +++ /dev/null @@ -1,43 +0,0 @@ -version = '0.9.1' - -dependencies { - compileOnly 'foundation.icon:javaee-api:0.9.2' - implementation 'com.github.sink772:javaee-tokens:0.6.1' - implementation project(':score-lib') - testImplementation 'foundation.icon:javaee-unittest:0.9.4' - testImplementation 'org.mockito:mockito-core:4.6.1' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' -} - -optimizedJar { - mainClassName = 'dummy.contract.sicx.sICX' - from { - configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } - } -} - -deployJar { - endpoints { - lisbon { - uri = 'https://lisbon.net.solidwallet.io/api/v3' - nid = 0x2 - } - local { - uri = 'http://localhost:9082/api/v3' - nid = 0x3 - } - } - keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' - password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' - parameters { - arg('_name', 'Staked ICX') - arg('_symbol', 'sICX') - arg('_decimals', '0x12') - arg('_initialSupply', '0x989680') - } -} - -test { - useJUnitPlatform() -} \ No newline at end of file diff --git a/dummy/sICX/src/main/java/dummy/contract/sicx/sICX.java b/dummy/sICX/src/main/java/dummy/contract/sicx/sICX.java deleted file mode 100644 index 993e5c54..00000000 --- a/dummy/sICX/src/main/java/dummy/contract/sicx/sICX.java +++ /dev/null @@ -1,26 +0,0 @@ -package dummy.contract.sicx; - -import com.iconloop.score.token.irc2.IRC2Basic; -import community.icon.cps.score.lib.tokens.IRC2Base; -import score.Context; - -import java.math.BigInteger; - -public class sICX extends IRC2Base implements community.icon.cps.score.lib.interfaces.sICXInterface { - public sICX(String _name, String _symbol, int _decimals, BigInteger _initialSupply) { - super(_name, _symbol, BigInteger.valueOf(_decimals)); - - // mint the initial token supply here - Context.require(_initialSupply.compareTo(BigInteger.ZERO) >= 0); - mint(Context.getCaller(), _initialSupply.multiply(pow10(_decimals))); - } - - private static BigInteger pow10(int exponent) { - BigInteger result = BigInteger.ONE; - for (int i = 0; i < exponent; i++) { - result = result.multiply(BigInteger.TEN); - } - return result; - } -} - diff --git a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/DexInterface.java b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/DexInterface.java index 1be7d1a4..43f41de4 100644 --- a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/DexInterface.java +++ b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/DexInterface.java @@ -1,28 +1,28 @@ -package community.icon.cps.score.lib.interfaces; - -import foundation.icon.score.client.ScoreClient; -import foundation.icon.score.client.ScoreInterface; -import score.Address; -import score.annotation.EventLog; -import score.annotation.External; - -import java.math.BigInteger; - -@ScoreInterface -@ScoreClient -public interface DexInterface { - - @External - void setSicxScore(Address _score); - @EventLog - void Deposit(Address from_token, Address from, BigInteger value); - - @EventLog(indexed = 2) - void Swap(BigInteger _id, Address _baseToken, Address _fromToken, Address _toToken, - Address _sender, Address _receiver, BigInteger _fromValue, BigInteger _toValue, - BigInteger _timestamp, BigInteger _lpFees, BigInteger _balnFees, BigInteger _poolBase, - BigInteger _poolQuote, BigInteger _endingPrice, BigInteger _effectiveFillPrice); - - @External - void tokenFallback(Address _from, BigInteger _value, byte[] _data); -} +//package community.icon.cps.score.lib.interfaces; +// +//import foundation.icon.score.client.ScoreClient; +//import foundation.icon.score.client.ScoreInterface; +//import score.Address; +//import score.annotation.EventLog; +//import score.annotation.External; +// +//import java.math.BigInteger; +// +////@ScoreInterface(suffix = "Client") +//@ScoreClient +//public interface DexInterface { +// +// @External +// void setSicxScore(Address _score); +// @EventLog +// void Deposit(Address from_token, Address from, BigInteger value); +// +// @EventLog(indexed = 2) +// void Swap(BigInteger _id, Address _baseToken, Address _fromToken, Address _toToken, +// Address _sender, Address _receiver, BigInteger _fromValue, BigInteger _toValue, +// BigInteger _timestamp, BigInteger _lpFees, BigInteger _balnFees, BigInteger _poolBase, +// BigInteger _poolQuote, BigInteger _endingPrice, BigInteger _effectiveFillPrice); +// +// @External +// void tokenFallback(Address _from, BigInteger _value, byte[] _data); +//} diff --git a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/RouterInterface.java b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/RouterInterface.java index efb9b81b..03c903a3 100644 --- a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/RouterInterface.java +++ b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/RouterInterface.java @@ -1,18 +1,18 @@ -package community.icon.cps.score.lib.interfaces; - -import foundation.icon.score.client.ScoreClient; -import foundation.icon.score.client.ScoreInterface; -import score.Address; -import score.annotation.External; -import score.annotation.Optional; -import score.annotation.Payable; - -import java.math.BigInteger; - -@ScoreInterface -@ScoreClient -public interface RouterInterface { - @Payable - @External - void route(Address[] _path, @Optional BigInteger _minReceive); -} +//package community.icon.cps.score.lib.interfaces; +// +//import foundation.icon.score.client.ScoreClient; +//import foundation.icon.score.client.ScoreInterface; +//import score.Address; +//import score.annotation.External; +//import score.annotation.Optional; +//import score.annotation.Payable; +// +//import java.math.BigInteger; +// +////@ScoreInterface(suffix = "Client") +//@ScoreClient +//public interface RouterInterface { +// @Payable +// @External +// void route(Address[] _path, @Optional BigInteger _minReceive); +//} diff --git a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/bnUSDInterface.java b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/bnUSDInterface.java index 21c472a5..8ae0055d 100644 --- a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/bnUSDInterface.java +++ b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/bnUSDInterface.java @@ -1,10 +1,10 @@ -package community.icon.cps.score.lib.interfaces; - -import community.icon.cps.score.lib.interfaces.tokens.IRC2; -import foundation.icon.score.client.ScoreClient; -import foundation.icon.score.client.ScoreInterface; - -@ScoreInterface -@ScoreClient -public interface bnUSDInterface extends IRC2 { -} +//package community.icon.cps.score.lib.interfaces; +// +//import community.icon.cps.score.lib.interfaces.tokens.IRC2; +//import foundation.icon.score.client.ScoreClient; +//import foundation.icon.score.client.ScoreInterface; +// +//@ScoreClient +////@ScoreInterface(suffix = "Client") +//public interface bnUSDInterface extends IRC2 { +//} diff --git a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/sICXInterface.java b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/sICXInterface.java index 9433f219..82cdfee5 100644 --- a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/sICXInterface.java +++ b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/sICXInterface.java @@ -1,10 +1,10 @@ -package community.icon.cps.score.lib.interfaces; - -import community.icon.cps.score.lib.interfaces.tokens.IRC2; -import foundation.icon.score.client.ScoreClient; -import foundation.icon.score.client.ScoreInterface; - -@ScoreInterface -@ScoreClient -public interface sICXInterface extends IRC2 { -} +//package community.icon.cps.score.lib.interfaces; +// +//import community.icon.cps.score.lib.interfaces.tokens.IRC2; +//import foundation.icon.score.client.ScoreClient; +//import foundation.icon.score.client.ScoreInterface; +// +////@ScoreInterface(suffix = "Client") +//@ScoreClient +//public interface sICXInterface extends IRC2 { +//} From 553e71b2f134110cfce7269b49713d09aba9627c Mon Sep 17 00:00:00 2001 From: naneey Date: Mon, 4 Mar 2024 13:14:21 +0545 Subject: [PATCH 05/64] chore: first integration test added --- .../cps/integration/CPSCoreIntegration.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java diff --git a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java new file mode 100644 index 00000000..84de63cc --- /dev/null +++ b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java @@ -0,0 +1,28 @@ +package community.icon.cps.integration; + +import community.icon.cps.score.test.integration.CPS; +import community.icon.cps.score.test.integration.CPSClient; +import community.icon.cps.score.test.integration.ScoreIntegrationTest; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; + +public class CPSCoreIntegration implements ScoreIntegrationTest { + + private static CPSClient ownerClient; + @BeforeAll + public static void setup() throws Exception{ + String contracts = "conf/contracts.json"; + CPS cps = new CPS(contracts); + + cps.setupCPS(); + ownerClient = cps.defaultClient(); + + } + + @Test + @Order(1) + public void name(){ + ownerClient.cpsCore.name(); + } +} From 399db81a5c6cfd509584c1fd3e5fd9b6673f005a Mon Sep 17 00:00:00 2001 From: naneey Date: Mon, 4 Mar 2024 13:16:47 +0545 Subject: [PATCH 06/64] chore: score client jar file added --- jars/score-client-0.9.0.jar | Bin 0 -> 74292 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 jars/score-client-0.9.0.jar diff --git a/jars/score-client-0.9.0.jar b/jars/score-client-0.9.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..e65a271ca22d12950b3f9e0665c7075b1bc1f9d9 GIT binary patch literal 74292 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
2^N!fPODQLg z&V=eFLPZ@RZ5m5m`Zf&x7rg>mo%C02k;!$g#ZUj)`Lr=QLSg+51neWBS2oH33#{U0 z)x6qI6G)Ky`D7yX`T^3&0dURU)Z~BSkv#S5J-M?4?Q1xu?I&6xFx;oyvOFLM0h1Mx zcqt0~hxVl8dZ36$&~|BXYV?9Rr~6ip>m>Px*bRhur6kpVr1rlZm}(E|r+}$@sd?{e+d3@GXFbEv_A;v* z#IhGE!+Cz1jK$WO%|VY(ute*M`Cv^dN}x5E!#RVADYYCXw%#q2I(5efZD_ zL5?rMw*TO2atr<@(T>M8*EXjfWnWahOODXb`K70(kmj_;iv+n_8(9pc&w5&S? zjqw3Vr&}JuKhuyzq0#Yx0mEK20xIrDtjSWKkbn2~8w?FAAVydeYI{RAH0e7|mxuO8 zc6{*w*0X8yWpiq2sR9o27C0r1d6+Z^BKp6=J5X>0=qGj0d3D>0h&wB&ZU(Syv`%4L z9WJHscWE>D?j`Zo?Vj{JZ@j;)~h} z)rB<8tJ{cDatA>G!WYDUN0`q)b9r-pQ}40CKtP!OUoi6j;b8nVbnk79| zVpJ;_`YaM@CsTT{;47J8`k;}hldoL59oTTWLx|uwT*_EEO<7j;7b36JIn2L%6qDu9 zOSKxv>|+QnUx%V!F9(iq%s5F$kGCq7s58Fpxi&W0i47lXEKIrQ02I4A$ zM1#L312V^NSjU>w4e4+PjYOR0>j!M9$Qz>B{5`a&o4RhHg)}A5TU1GH3qN80dmSoi zR;|Uq>p=5e2iE^r9hA-7&757$OvOA+%p6^<9PIzI6lsaG@&kg%BfWHCu&URD5QAb4 zg76Q=pa;X2!V8&{;cv<-od8=Yok*mkVNsL)eyHoB*hRVV?dOEwX4Hv;RJX&2QH+~RinFJZ5gXUvDUabq(C96t+dgWT;kLC@yaTfX4_dtKZI z538xZ>vHpb(Eq>c@?RXj|MTHcl93q{ME-33ZFx?*Oznvr6QRs-eA=IK4=P+#78UHd zJ|eZ&xRq+E^3ULI7wK9e3Kc@9XxGTX;?W155pfr?95EiB6)zWBb%8c|samka zk1cb&?7o>*WwtGfc~K|mHIJzwO??<3lQh+gUh!g-t0+OktgH6HDI*M|kpsJgbj{m< z$&F(%ShRn$?cOL(u}hSRQ}7@rSd#UWzIcMY3nl!*;-Z0v`A4dLmM= z!`@vRTDH7N=|F?P3P`?EC~qVwUDWofG6#$-BNoBjm5#c`wc_@AEYP6eIL8KwH{YWa zN9QsBd#5wOd0SO}clho1!yxqk>h%9JKS%mn99C_k~7S=L2vWKx1vUF}lAx`wc@*5I$E;V;s!5N{Ko z69*Sp1zR=1z2<7?3Pa=NvL9H^EX{$NkjMpV!u1^1c?hd|XF+LeqRA0&nnSd%yc)Ml zjm8IUvVy0;7<>~y%>{Ove#*fhrdywWc2>i0xex;p=;nm+7t(WIxHgmKxp*fSxuB4* zcBG&q#(+9mih_7RDl^$v60*ljjA)A_d-{-nP#ik*!d}`TmU9;&@phPNh967d)w~Je zY>o*nM6p?ouH|Q7SX(b!z^jN$=(3_4ga+3mr$?OK1^P5Ya@3f zPkJMJdk0se|MAo5_@7>UD|-w2|FzvLGs!S5BSkwtHM=+|3yCs3{vuZCJ^Kx_TJ>)m-W*Y18RlyOvqPriC zwZ=Qw?}~X9NJT=@0rMx{PypU;1bh%*?^mf?!^j^js7R7&+=6w%Gx+=%92KUTm#-eDwJ3Y-C64-Q zxMge>#ixgtNK!S$dI<#`MJ!vKFRA}NbL%S95qe~yResD-HH}YDA5tVKs12!S)U>Yf zLH*Nx`XnIdmrK$Xhk_^41fdgw;z~N%smWfy~9NCl6mf zkNo)=c05Gc@atV-7L!$M(Q&8TlhWMh6!zWkxDij&_-3n^Mb9<+yH-teKD~xb#EJ3W zJ{!XZID+|GOHnf0LQ?pNFn6K($phFF%CRXxsnAR#zEdpBCV~^1AZHPI_$uF4+fOOK z4c^uvruC~yB}Hv##PN0UYb#D7$W@p#H3co=_`QKzZL)sA?+>CXtv}sK!g&rpLHr8M zG}^HHizbFOLeKL5n4+UdSR^L*rm~t~mCn|WZdeP<6!x0N0*Dwezvl)}`JIMuOig8U zVitK>ihXM%McDtu4G=72_=tT?U0pB0UvC3bPa!7dAViCtN);LXx>GZ+PC@!VNYk@; zAQ>d>4@K)ilzwYhd-!I|#l~;H53#7m9HV3LY)=qtyV9NQ0WhHybJW@+WuML>U7tp@ z$%|g6nMO$}n2<@Sx$W|x%pd(%KT2nYF#5w-@8~sXQzl58w^{KiD^83xTtqz1;#@~h zjk0VIh4oP+{{vw-j*eWdy8{N5A{^u;hto`>F7=xY^;M-F_ey!^PMC20e zsdET;n#QSTf*>Sy`SBpT>-@-?({EttkFR2tHxG%G=|$B)W}^Jc=yTVjm=E1c+2y+G z<*>>T&H;!|J6`(YTaO|P8Eg)8#J@NennvpX25;H>R(^e?5rJr`U{SrVg+{T*NWN9i z4^>qDfJ5CS#C{tU_kUgwjk0~{Zg{+79obOWBK8i@G-}@z)41mYs-(U5gg`Qbt Date: Mon, 4 Mar 2024 14:35:10 +0545 Subject: [PATCH 07/64] test: unit test passed --- .../icon/cps/score/cpscore/CPSScoreTest.java | 40 +++++++++---------- .../score/cpstreasury/CPSTreasuryTest.java | 16 ++++---- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java b/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java index fa2dcf69..b0ac027a 100644 --- a/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java +++ b/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java @@ -90,7 +90,7 @@ void addAdmin() { @Test void addAdminNotOwner() { Executable addAdminNotOwner = () -> cpsScore.invoke(testingAccount, "addAdmin", testingAccount.getAddress()); - expectErrorMessage(addAdminNotOwner, "Reverted(0): SenderNotScoreOwner: Sender=" + testingAccount.getAddress() + " Owner=" + owner.getAddress()); + expectErrorMessage(addAdminNotOwner, "SenderNotScoreOwner: Sender=" + testingAccount.getAddress() + " Owner=" + owner.getAddress()); } @Test @@ -106,7 +106,7 @@ void removeAdminNotOwner() { cpsScore.invoke(owner, "addAdmin", testingAccount.getAddress()); assertEquals(List.of(testingAccount.getAddress()), cpsScore.call("getAdmins")); Executable removeAdminNotOwner = () -> cpsScore.invoke(testingAccount, "removeAdmin", testingAccount.getAddress()); - expectErrorMessage(removeAdminNotOwner, "Reverted(0): SenderNotScoreOwner: Sender=" + testingAccount.getAddress() + " Owner=" + owner.getAddress()); + expectErrorMessage(removeAdminNotOwner, "SenderNotScoreOwner: Sender=" + testingAccount.getAddress() + " Owner=" + owner.getAddress()); } @Test @@ -114,7 +114,7 @@ void removeAdminAddressNotAdmin() { cpsScore.invoke(owner, "addAdmin", testingAccount.getAddress()); assertEquals(List.of(testingAccount.getAddress()), cpsScore.call("getAdmins")); Executable removeAdminNotOwner = () -> cpsScore.invoke(owner, "removeAdmin", testingAccount1.getAddress()); - expectErrorMessage(removeAdminNotOwner, "Reverted(0): CPS Score: Address not registered as admin."); + expectErrorMessage(removeAdminNotOwner, "CPS Score: Address not registered as admin."); } void addAdminMethod() { @@ -150,7 +150,7 @@ void registerPrepAlreadyRegistered() { cpsScore.invoke(owner, "setInitialBlock"); cpsScore.invoke(owner, "registerPrep"); Executable register = () -> cpsScore.invoke(owner, "registerPrep"); - expectErrorMessage(register, "Reverted(0): CPS Score: P-Rep is already registered."); + expectErrorMessage(register, "CPS Score: P-Rep is already registered."); } @Test @@ -175,7 +175,7 @@ void registerPrepNotAPrep() { cpsScore.invoke(owner, "toggleMaintenance"); cpsScore.invoke(owner, "setInitialBlock"); Executable register = () -> cpsScore.invoke(testingAccount9, "registerPrep"); - expectErrorMessage(register, "Reverted(0): CPS Score: Not a P-Rep."); + expectErrorMessage(register, "CPS Score: Not a P-Rep."); } @Test @@ -267,7 +267,7 @@ void unregisterPrepNotInValidPrep() { cpsScore.invoke(owner, "registerPrep"); Executable unregister = () -> cpsScore.invoke(testingAccount1, "unregisterPrep"); - expectErrorMessage(unregister, "Reverted(0): P-Rep is not registered yet."); + expectErrorMessage(unregister, "P-Rep is not registered yet."); } @Test @@ -406,7 +406,7 @@ void submitProposal() { assertEquals(owner.getAddress(), proposalDetails.get("contributor_address")); assertEquals("_sponsor_pending", proposalDetails.get("status")); assertEquals(BigInteger.valueOf(100).multiply(MULTIPLIER), proposalDetails.get("total_budget")); - Map proposalDetailsOfStatus = (Map) cpsScore.call("getProposalDetails", SPONSOR_PENDING, owner.getAddress(), 0, 10); + Map proposalDetailsOfStatus = (Map) cpsScore.call("getProposalDetails", SPONSOR_PENDING, owner.getAddress(), 0); assertEquals(1, proposalDetailsOfStatus.get(COUNT)); @@ -493,7 +493,7 @@ void sponsorVote() { "count", 1); assertEquals(amount, (projectAmounts.get(PENDING))); - Map sponosrsRequest = (Map) cpsScore.call("getSponsorsRequests", APPROVED, testingAccount.getAddress(), 0, 10); + Map sponosrsRequest = (Map) cpsScore.call("getSponsorsRequests", APPROVED, testingAccount.getAddress(), 0); System.out.println("Sponsors request" + sponosrsRequest); } @@ -844,7 +844,7 @@ void updatePeriodAfterProposalVoting() { List> activeProposalList = (List>) activeProposals.get(DATA); assertEquals(List.of(proposalDetails).size(), activeProposalList.size()); - Map sponosrsRequest = (Map) cpsScore.call("getSponsorsRequests", APPROVED, testingAccount.getAddress(), 0, 10); + Map sponosrsRequest = (Map) cpsScore.call("getSponsorsRequests", APPROVED, testingAccount.getAddress(), 0); System.out.println("Sponsors request" + sponosrsRequest); Map sponsorsRecord = (Map) cpsScore.call("getSponsorsRecord"); @@ -936,7 +936,7 @@ void submitProgressReport() { List progressKeys = (List) cpsScore.call("getProgressKeys"); assertEquals(List.of("Report 1"), progressKeys); - Map progressReports = (Map) cpsScore.call("getProgressReports", WAITING, 0, 10); + Map progressReports = (Map) cpsScore.call("getProgressReports", WAITING, 0); System.out.println("Progerss reports: " + progressReports); // assertEquals(List.of(progressReportDetails), progressReports.get(DATA)); assertEquals(1, progressReports.get(COUNT)); @@ -965,7 +965,7 @@ void voteProgressReportExceptions() { doNothing().when(scoreSpy).callScore(eq(cpfTreasury), eq("swapTokens"), eq(8)); Executable call = () -> cpsScore.invoke(owner, "voteProgressReport", "Report 1", "reason", milestoneVoteAttributesList, "_reject", false); - expectErrorMessage(call, "Reverted(0): CPS Score: Voting can only be done for milestone " + + expectErrorMessage(call, "CPS Score: Voting can only be done for milestone " + "submitted in this progress report"); } @@ -1000,7 +1000,7 @@ void voteProgressReportException() { doNothing().when(scoreSpy).callScore(eq(cpfTreasury), eq("swapTokens"), eq(8)); Executable call2 = () -> cpsScore.invoke(owner, "voteProgressReport", "Report 1", "reason", milestoneVoteAttributesList2, "_reject", false); - expectErrorMessage(call2, "Reverted(0): You should submit votes for all milestones of the progress report"); + expectErrorMessage(call2, "You should submit votes for all milestones of the progress report"); } @@ -1540,7 +1540,7 @@ void disqualifyProposal() { Map proposalDetails = getProposalDetailsByHash("Proposal 1"); assertEquals(PAUSED, proposalDetails.get(STATUS)); - Map sponosrsRequest = (Map) cpsScore.call("getSponsorsRequests", APPROVED, testingAccount.getAddress(), 0, 10); + Map sponosrsRequest = (Map) cpsScore.call("getSponsorsRequests", APPROVED, testingAccount.getAddress(), 0); System.out.println("Sponsors request::" + sponosrsRequest); Map sponsorsRecord = (Map) cpsScore.call("getSponsorsRecord"); @@ -1792,7 +1792,7 @@ void sponsorDepositsLessThanBondPercentage() { sponsorVoteParams.add("params", params); Executable bondPercentageRevert = () -> cpsScore.invoke(testingAccount, "tokenFallback", testingAccount.getAddress(), BigInteger.valueOf(10).multiply(MULTIPLIER), sponsorVoteParams.toString().getBytes()); - expectErrorMessage(bondPercentageRevert, "Reverted(0): CPS Score: Deposit 15% of the total budget of the project."); + expectErrorMessage(bondPercentageRevert, "CPS Score: Deposit 15% of the total budget of the project."); } @@ -1839,7 +1839,7 @@ void progressReportWithNotCompletedStatus() { List progressKeys = (List) cpsScore.call("getProgressKeys"); assertEquals(List.of("Report 1"), progressKeys); - Map progressReports = (Map) cpsScore.call("getProgressReports", WAITING, 0, 10); + Map progressReports = (Map) cpsScore.call("getProgressReports", WAITING, 0); System.out.println("Progerss reports: " + progressReports); assertEquals(1, progressReports.get(COUNT)); @@ -2057,22 +2057,22 @@ void setSwapCount() { @Test void bondPercentageExceptions() { Executable percentageNotAdmin = () -> cpsScore.invoke(testingAccount, "setSponsorBondPercentage", BigInteger.valueOf(15)); - expectErrorMessage(percentageNotAdmin, "Reverted(0): CPS Score: Only CPF treasury can call this method"); + expectErrorMessage(percentageNotAdmin, "CPS Score: Only CPF treasury can call this method"); doReturn(cpfTreasuryScore.getAddress()).when(scoreSpy).getCpfTreasuryScore(); Executable percentageLessTwelve = () -> cpsScore.invoke(cpfTreasuryScore, "setSponsorBondPercentage", BigInteger.valueOf(11)); - expectErrorMessage(percentageLessTwelve, "Reverted(0): CPS Score: Cannot set bond percentage less than 12%"); + expectErrorMessage(percentageLessTwelve, "CPS Score: Cannot set bond percentage less than 12%"); } @Test void setApplicationPeriodExceptions() { Executable setPeriodNotAdmin = () -> cpsScore.invoke(testingAccount, "setPeriod", BigInteger.valueOf(10)); - expectErrorMessage(setPeriodNotAdmin, "Reverted(0): CPS Score: Only CPF treasury can call this method"); + expectErrorMessage(setPeriodNotAdmin, "CPS Score: Only CPF treasury can call this method"); doReturn(cpfTreasuryScore.getAddress()).when(scoreSpy).getCpfTreasuryScore(); Executable periodis15 = () -> cpsScore.invoke(cpfTreasuryScore, "setPeriod", BigInteger.valueOf(28)); - expectErrorMessage(periodis15, "Reverted(0): CPS Score: Voting period must be more than or equal to 10 days"); + expectErrorMessage(periodis15, "CPS Score: Voting period must be more than or equal to 10 days"); } @@ -2137,7 +2137,7 @@ void updateContributorAddress() { milestoneSubmission1}; Executable call = () -> cpsScore.invoke(owner, "submitProgressReport", progressReport, milestoneSubmission); - expectErrorMessage(call, "Reverted(0): CPS Score: Sorry, You are not the contributor for this project."); + expectErrorMessage(call, "CPS Score: Sorry, You are not the contributor for this project."); contextMock.when(caller()).thenReturn(testingAccount1.getAddress()); cpsScore.invoke(testingAccount1, "submitProgressReport", progressReport, milestoneSubmission); diff --git a/CPSTreasury/src/test/java/community/icon/cps/score/cpstreasury/CPSTreasuryTest.java b/CPSTreasury/src/test/java/community/icon/cps/score/cpstreasury/CPSTreasuryTest.java index 140467b3..6e3dc618 100644 --- a/CPSTreasury/src/test/java/community/icon/cps/score/cpstreasury/CPSTreasuryTest.java +++ b/CPSTreasury/src/test/java/community/icon/cps/score/cpstreasury/CPSTreasuryTest.java @@ -167,39 +167,39 @@ void setBnUSDScoreExceptions(Boolean isAdmin, Address score_address) { void setCpsScoreNotAdmin() { setScoresMethod(); Executable setCpsScoreNotAdmin = () -> setCpsScoreExceptions(false, score_address); - expectErrorMessage(setCpsScoreNotAdmin, "Reverted(0): " + TAG + ": Only admins can call this method"); + expectErrorMessage(setCpsScoreNotAdmin, TAG + ": Only admins can call this method"); } @Test void setCpfTreasuryScoreNotAdmin() { setScoresMethod(); Executable setCpfTreasuryScoreNotAdmin = () -> setCpfTreasuryScoreExceptions(false, score_address); - expectErrorMessage(setCpfTreasuryScoreNotAdmin, "Reverted(0): " + TAG + ": Only admins can call this method"); + expectErrorMessage(setCpfTreasuryScoreNotAdmin, TAG + ": Only admins can call this method"); } @Test void setBnUSDScoreNotAdmin() { setScoresMethod(); Executable setBnUSDScoreNotAdmin = () -> setBnUSDScoreExceptions(false, score_address); - expectErrorMessage(setBnUSDScoreNotAdmin, "Reverted(0): " + TAG + ": Only admins can call this method"); + expectErrorMessage(setBnUSDScoreNotAdmin, TAG + ": Only admins can call this method"); } @Test void setCPSScoreNotContract() { Executable setCpsScoreNotAdmin = () -> setCpsScoreExceptions(true, testing_account.getAddress()); - expectErrorMessage(setCpsScoreNotAdmin, "Reverted(0): " + TAG + "Target " + testing_account.getAddress() + " is not a score."); + expectErrorMessage(setCpsScoreNotAdmin, TAG + "Target " + testing_account.getAddress() + " is not a score."); } @Test void setCPFTreasuryScoreNotContract() { Executable setCpfTreasuryScoreNotContract = () -> setCpfTreasuryScoreExceptions(true, testing_account.getAddress()); - expectErrorMessage(setCpfTreasuryScoreNotContract, "Reverted(0): " + TAG + "Target " + testing_account.getAddress() + " is not a score."); + expectErrorMessage(setCpfTreasuryScoreNotContract, TAG + "Target " + testing_account.getAddress() + " is not a score."); } @Test void setBnUSDScoreNotContract() { Executable setBnUSDScoreContract = () -> setBnUSDScoreExceptions(true, testing_account.getAddress()); - expectErrorMessage(setBnUSDScoreContract, "Reverted(0): " + TAG + "Target " + testing_account.getAddress() + " is not a score."); + expectErrorMessage(setBnUSDScoreContract, TAG + "Target " + testing_account.getAddress() + " is not a score."); } @Test @@ -268,7 +268,7 @@ void depositProposalFundProposalAlreadyExists(){ setOnsetPayment(); depositProposalFundMethod(); Executable depositProposalFundProposalAlreadyExists = () -> depositProposalFundExceptions(); - expectErrorMessage(depositProposalFundProposalAlreadyExists, "Reverted(0): " + "CPS_TREASURY: Already have this project"); + expectErrorMessage(depositProposalFundProposalAlreadyExists, "CPS_TREASURY: Already have this project"); } @Test @@ -342,7 +342,7 @@ void updateProposalFundProposalException(){ @Test void updateProposalFundProposalDoesnotExist(){ Executable updateProposalFundProposalDoesnotExist = () -> updateProposalFundProposalException(); - expectErrorMessage(updateProposalFundProposalDoesnotExist, "Reverted(0): " + "CPS_TREASURY: Invalid IPFS hash."); + expectErrorMessage(updateProposalFundProposalDoesnotExist, "CPS_TREASURY: Invalid IPFS hash."); } private void depositProposalFund_MilestoneCheck() { From c34562dccb1ba2a33f3973307fb3c54d8dbdd5b4 Mon Sep 17 00:00:00 2001 From: naneey Date: Mon, 4 Mar 2024 14:35:52 +0545 Subject: [PATCH 08/64] test: mockito inline implemented --- CPFTreasury/build.gradle | 2 +- CPSCore/build.gradle | 2 ++ CPSTreasury/build.gradle | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CPFTreasury/build.gradle b/CPFTreasury/build.gradle index f92d1017..986566d2 100644 --- a/CPFTreasury/build.gradle +++ b/CPFTreasury/build.gradle @@ -11,7 +11,7 @@ dependencies { // implementation 'org.mockito:mockito-core:4.3.1' // testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' // testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' -// testImplementation('org.mockito:mockito-inline:4.3.1') + testImplementation('org.mockito:mockito-inline:4.8.0') // implementation 'foundation.icon:javaee-scorex:0.5.2' implementation project(':score-lib') diff --git a/CPSCore/build.gradle b/CPSCore/build.gradle index 57d76811..1305b702 100644 --- a/CPSCore/build.gradle +++ b/CPSCore/build.gradle @@ -10,6 +10,8 @@ dependencies { implementation project(':score-lib') testImplementation project(':test-lib') + testImplementation('org.mockito:mockito-inline:4.8.0') + // testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0' // testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' // testImplementation('org.mockito:mockito-inline:4.8.0') diff --git a/CPSTreasury/build.gradle b/CPSTreasury/build.gradle index e39557ab..85bfca6d 100644 --- a/CPSTreasury/build.gradle +++ b/CPSTreasury/build.gradle @@ -10,7 +10,7 @@ dependencies { // testImplementation 'foundation.icon:javaee-unittest:0.9.7' // testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0' // testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' -// testImplementation('org.mockito:mockito-inline:4.8.0') + testImplementation('org.mockito:mockito-inline:4.8.0') // intTestImplementation 'foundation.icon:icon-sdk:2.2.0' // intTestImplementation project(":score-client") // intTestAnnotationProcessor project(":score-client") From e9d6ceed9b16136a8bba10b1787e1dbda63adfa0 Mon Sep 17 00:00:00 2001 From: naneey Date: Mon, 4 Mar 2024 14:38:06 +0545 Subject: [PATCH 09/64] chore: scoreClient implemented from jarFile --- score-client/build.gradle | 22 - .../java/foundation/icon/jsonrpc/Address.java | 134 ----- .../icon/jsonrpc/IconJsonModule.java | 454 ---------------- .../icon/jsonrpc/JsonrpcClient.java | 271 ---------- .../SendTransactionParamSerializer.java | 95 ---- .../jsonrpc/model/AbstractTransaction.java | 76 --- .../icon/jsonrpc/model/CallData.java | 37 -- .../icon/jsonrpc/model/CallParam.java | 52 -- .../icon/jsonrpc/model/DeployData.java | 64 --- .../foundation/icon/jsonrpc/model/Hash.java | 56 -- .../jsonrpc/model/SendTransactionParam.java | 64 --- .../icon/jsonrpc/model/TransactionParam.java | 61 --- .../icon/jsonrpc/model/TransactionResult.java | 173 ------ .../icon/score/client/DefaultScoreClient.java | 510 ------------------ .../icon/score/client/RevertedException.java | 29 - .../icon/score/client/ScoreClient.java | 28 - .../score/client/ScoreClientProcessor.java | 425 --------------- .../icon/score/client/ScoreInterface.java | 29 - .../score/client/ScoreInterfaceProcessor.java | 282 ---------- 19 files changed, 2862 deletions(-) delete mode 100644 score-client/build.gradle delete mode 100644 score-client/src/main/java/foundation/icon/jsonrpc/Address.java delete mode 100644 score-client/src/main/java/foundation/icon/jsonrpc/IconJsonModule.java delete mode 100644 score-client/src/main/java/foundation/icon/jsonrpc/JsonrpcClient.java delete mode 100644 score-client/src/main/java/foundation/icon/jsonrpc/SendTransactionParamSerializer.java delete mode 100644 score-client/src/main/java/foundation/icon/jsonrpc/model/AbstractTransaction.java delete mode 100644 score-client/src/main/java/foundation/icon/jsonrpc/model/CallData.java delete mode 100644 score-client/src/main/java/foundation/icon/jsonrpc/model/CallParam.java delete mode 100644 score-client/src/main/java/foundation/icon/jsonrpc/model/DeployData.java delete mode 100644 score-client/src/main/java/foundation/icon/jsonrpc/model/Hash.java delete mode 100644 score-client/src/main/java/foundation/icon/jsonrpc/model/SendTransactionParam.java delete mode 100644 score-client/src/main/java/foundation/icon/jsonrpc/model/TransactionParam.java delete mode 100644 score-client/src/main/java/foundation/icon/jsonrpc/model/TransactionResult.java delete mode 100644 score-client/src/main/java/foundation/icon/score/client/DefaultScoreClient.java delete mode 100644 score-client/src/main/java/foundation/icon/score/client/RevertedException.java delete mode 100644 score-client/src/main/java/foundation/icon/score/client/ScoreClient.java delete mode 100644 score-client/src/main/java/foundation/icon/score/client/ScoreClientProcessor.java delete mode 100644 score-client/src/main/java/foundation/icon/score/client/ScoreInterface.java delete mode 100644 score-client/src/main/java/foundation/icon/score/client/ScoreInterfaceProcessor.java diff --git a/score-client/build.gradle b/score-client/build.gradle deleted file mode 100644 index edbc0eda..00000000 --- a/score-client/build.gradle +++ /dev/null @@ -1,22 +0,0 @@ -apply plugin: 'java-library' - -optimizedJar.enabled = false - - -dependencies { - implementation("foundation.icon:javaee-annotation-processor:0.9.0") - implementation("com.squareup:javapoet:1.12.1") - implementation("foundation.icon:javaee-api:0.9.0") - implementation("foundation.icon:icon-sdk:2.0.0") - implementation("com.fasterxml.jackson.core:jackson-databind:2.9.6") - implementation("com.squareup.okhttp3:okhttp:3.11.0") - implementation("org.bouncycastle:bcprov-jdk15on:1.60") - - testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.2") - testImplementation("org.junit.jupiter:junit-jupiter-params:5.7.2") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.2") -} - -test { - useJUnitPlatform() -} \ No newline at end of file diff --git a/score-client/src/main/java/foundation/icon/jsonrpc/Address.java b/score-client/src/main/java/foundation/icon/jsonrpc/Address.java deleted file mode 100644 index 48bea738..00000000 --- a/score-client/src/main/java/foundation/icon/jsonrpc/Address.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.jsonrpc; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; -import foundation.icon.icx.Wallet; - -import java.util.Arrays; - -public class Address extends score.Address { - public enum Type { - EOA("hx", 0x0), - CONTRACT("cx", 0x1); - String str; - byte value; - Type(String str, int value) { - this.str = str; - this.value = (byte)value; - } - String str() { - return str; - } - byte value() { - return value; - } - static Type of(byte value) { - for(Type type : values()) { - if (type.value == value) { - return type; - } - } - throw new IllegalArgumentException(); - } - static Type of(String str) { - for(Type type : values()) { - if (type.str.equals(str)) { - return type; - } - } - throw new IllegalArgumentException(); - } - } - public static final int LENGTH = 21; - public static final int BODY_LENGTH = LENGTH - 1; - private final Type type; - private final String str; - private final byte[] bytes; - - @JsonCreator - public Address(String str) { - this(parse(str)); - } - - public Address(byte[] bytes) throws IllegalArgumentException { - super(bytes); - if (bytes == null) { - throw new IllegalArgumentException("raw could not be null"); - } - if (bytes.length != LENGTH) { - throw new IllegalArgumentException("invalid length"); - } - type = Type.of(bytes[0]); - this.bytes = bytes; - this.str = type.str() + IconJsonModule.bytesToHex(bytes).substring(2); - } - - public Address(Type type, byte[] body) throws IllegalArgumentException { - this(concat(type.value(), body)); - } - - public boolean isContract() { - return Type.CONTRACT.equals(type); - } - - public static byte[] concat(byte type, byte[] body) { - byte[] copy = new byte[LENGTH]; - copy[0] = type; - System.arraycopy(body, 0, copy, 1, BODY_LENGTH); - return copy; - } - - public byte[] toByteArray() { - return Arrays.copyOf(bytes, LENGTH); - } - - @Override - public boolean equals(Object obj) { - return this == obj || - (obj instanceof score.Address && toString().equals(obj.toString())); - } - - @JsonValue - @Override - public String toString() { - return str; - } - - public static byte[] parse(String str) { - if (str == null) { - throw new IllegalArgumentException("string could not be null"); - } - if (str.length() != LENGTH * 2) { - throw new IllegalArgumentException("invalid length"); - } - byte[] bytes = new byte[LENGTH]; - bytes[0] = Type.of(str.substring(0, 2)).value(); - System.arraycopy(IconJsonModule.hexToBytes(str.substring(2)), 0, bytes, 1, BODY_LENGTH); - return bytes; - } - - public static Address of(Wallet wallet) { - return of(wallet.getAddress()); - } - - private static Address of(foundation.icon.icx.data.Address address) { - return new Address(address.toString()); - } - -} diff --git a/score-client/src/main/java/foundation/icon/jsonrpc/IconJsonModule.java b/score-client/src/main/java/foundation/icon/jsonrpc/IconJsonModule.java deleted file mode 100644 index fc81edc8..00000000 --- a/score-client/src/main/java/foundation/icon/jsonrpc/IconJsonModule.java +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.jsonrpc; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.Version; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.core.util.VersionUtil; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.databind.type.TypeFactory; -import com.fasterxml.jackson.databind.util.Converter; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.function.Function; - -public class IconJsonModule extends SimpleModule { - public final static Version VERSION = VersionUtil.parseVersion( - "0.1.0", "foundation.icon", "javaee-score-client" - ); - - public static final String BOOLEAN_TRUE = "0x1"; - public static final String BOOLEAN_FALSE = "0x0"; - public static final String HEX_PREFIX = "0x"; - public static final String NEG_HEX_PREFIX = "-0x"; - private final boolean isIncludeNonNull; - - public static final char[] HEX_CODES = "0123456789abcdef".toCharArray(); - - public static String bytesToHex(byte[] bytes) { - if (bytes == null) { - return ""; - } - StringBuilder r = new StringBuilder(bytes.length * 2); - for (byte b : bytes) { - r.append(HEX_CODES[(b >> 4) & 0xF]); - r.append(HEX_CODES[(b & 0xF)]); - } - return r.toString(); - } - - public static byte[] hexToBytes(String hexString) { - if (hexString == null) { - return null; - } - if (hexString.length() % 2 > 0) { - throw new IllegalArgumentException("hex cannot has odd length"); - } - int l = hexString.length()/2; - int j = 0; - byte[] bytes = new byte[l]; - for (int i = 0; i < l; i++) { - bytes[i] = (byte)((Character.digit(hexString.charAt(j++), 16) << 4) | - Character.digit(hexString.charAt(j++), 16) & 0xFF); - } - return bytes; - } - - public IconJsonModule() { - super(VERSION); - this.isIncludeNonNull = true; - init(); - } - - public IconJsonModule(boolean isIncludeNonNull) { - super(VERSION); - this.isIncludeNonNull = isIncludeNonNull; - init(); - } - - private void init() { - addSerializer(char.class, CharSerializer.CHAR); - addSerializer(Character.class, CharSerializer.CHAR); - addSerializer(byte.class, NumberSerializer.BYTE); - addSerializer(Byte.class, NumberSerializer.BYTE); - addSerializer(long.class, NumberSerializer.LONG); - addSerializer(Long.class, NumberSerializer.LONG); - addSerializer(int.class, NumberSerializer.INTEGER); - addSerializer(Integer.class, NumberSerializer.INTEGER); - addSerializer(short.class, NumberSerializer.SHORT); - addSerializer(Short.class, NumberSerializer.SHORT); - addSerializer(BigInteger.class, NumberSerializer.BIG_INTEGER); - addSerializer(boolean.class, BooleanSerializer.BOOLEAN); - addSerializer(Boolean.class, BooleanSerializer.BOOLEAN); - addSerializer(byte[].class, ByteArraySerializer.BYTE_ARRAY); - addSerializer(score.Address.class, AddressSerializer.SCORE_ADDRESS); -// addSerializer(foundation.icon.icx.data.Address.class, AddressSerializer.SDK_ADDRESS); - - addDeserializer(char.class, CharDeserializer.CHAR); - addDeserializer(Character.class, CharDeserializer.CHAR); - addDeserializer(byte.class, NumberDeserializer.BYTE); - addDeserializer(Byte.class, NumberDeserializer.BYTE); - addDeserializer(long.class, NumberDeserializer.LONG); - addDeserializer(Long.class, NumberDeserializer.LONG); - addDeserializer(int.class, NumberDeserializer.INTEGER); - addDeserializer(Integer.class, NumberDeserializer.INTEGER); - addDeserializer(short.class, NumberDeserializer.SHORT); - addDeserializer(Short.class, NumberDeserializer.SHORT); - addDeserializer(BigInteger.class, NumberDeserializer.BIG_INTEGER); - addDeserializer(boolean.class, BooleanDeserializer.BOOLEAN); - addDeserializer(Boolean.class, BooleanDeserializer.BOOLEAN); - addDeserializer(byte[].class, ByteArrayDeserializer.BYTE_ARRAY); - addDeserializer(score.Address.class, AddressDeserializer.SCORE_ADDRESS); -// addDeserializer(foundation.icon.icx.data.Address.class, AddressDeserializer.SDK_ADDRESS); - } - - @Override - public void setupModule(SetupContext context) { - super.setupModule(context); - if (isIncludeNonNull) { - JsonInclude.Value value = JsonInclude.Value.construct(JsonInclude.Include.NON_NULL, JsonInclude.Include.NON_NULL); - context.configOverride(Long.class).setInclude(value); - context.configOverride(Integer.class).setInclude(value); - context.configOverride(Short.class).setInclude(value); - context.configOverride(BigInteger.class).setInclude(value); - context.configOverride(Boolean.class).setInclude(value); - context.configOverride(byte[].class).setInclude(value); - } - } - - public static class NumberSerializer extends JsonSerializer implements Converter { - public static final NumberSerializer BYTE = new NumberSerializer<>(); - public static final NumberSerializer SHORT = new NumberSerializer<>(); - public static final NumberSerializer INTEGER = new NumberSerializer<>(); - public static final NumberSerializer LONG = new NumberSerializer<>(); - public static final NumberSerializer BIG_INTEGER = new NumberSerializer<>(); - - @Override - public String convert(T t) { - BigInteger bi; - if (t instanceof BigInteger) { - bi = (BigInteger) t; - } else { - bi = BigInteger.valueOf(t.longValue()); - } - String prefix = (bi.signum() == -1) ? NEG_HEX_PREFIX : HEX_PREFIX; - return prefix + bi.abs().toString(16); - } - - @Override - public JavaType getInputType(TypeFactory typeFactory) { - return typeFactory.constructType(new TypeReference(){}); - } - - @Override - public JavaType getOutputType(TypeFactory typeFactory) { - return typeFactory.constructType(String.class); - } - - @Override - public void serialize(T value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - gen.writeString(convert(value)); - } - } - - public static class CharSerializer extends JsonSerializer implements Converter { - public static final CharSerializer CHAR = new CharSerializer(); - - @Override - public String convert(Character value) { - return NumberSerializer.INTEGER.convert((int)value); - } - - @Override - public JavaType getInputType(TypeFactory typeFactory) { - return typeFactory.constructType(Character.class); - } - - @Override - public JavaType getOutputType(TypeFactory typeFactory) { - return typeFactory.constructType(String.class); - } - - @Override - public void serialize(Character value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - gen.writeString(convert(value)); - } - } - - public static class BooleanSerializer extends JsonSerializer implements Converter { - public static final BooleanSerializer BOOLEAN = new BooleanSerializer(); - - @Override - public String convert(Boolean value) { - return value ? BOOLEAN_TRUE : BOOLEAN_FALSE; - } - - @Override - public JavaType getInputType(TypeFactory typeFactory) { - return typeFactory.constructType(Boolean.class); - } - - @Override - public JavaType getOutputType(TypeFactory typeFactory) { - return typeFactory.constructType(String.class); - } - - @Override - public void serialize(Boolean value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - if (value != null) { - gen.writeString(convert(value)); - } - } - } - - public static class ByteArraySerializer extends JsonSerializer implements Converter { - public static final ByteArraySerializer BYTE_ARRAY = new ByteArraySerializer(); - - @Override - public void serialize(byte[] value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - gen.writeString(convert(value)); - } - - @Override - public String convert(byte[] value) { - return HEX_PREFIX + bytesToHex(value); - } - - @Override - public JavaType getInputType(TypeFactory typeFactory) { - return typeFactory.constructArrayType(byte.class); - } - - @Override - public JavaType getOutputType(TypeFactory typeFactory) { - return typeFactory.constructType(String.class); - } - } - - public static class AddressSerializer extends JsonSerializer implements Converter { - public static final AddressSerializer SCORE_ADDRESS = new AddressSerializer<>(); - public static final AddressSerializer SDK_ADDRESS = new AddressSerializer<>(); - - @Override - public String convert(T value) { - return value.toString(); - } - - @Override - public JavaType getInputType(TypeFactory typeFactory) { - return typeFactory.constructType(new TypeReference(){}); - } - - @Override - public JavaType getOutputType(TypeFactory typeFactory) { - return typeFactory.constructType(String.class); - } - - @Override - public void serialize(T address, JsonGenerator gen, SerializerProvider serializers) throws IOException { - gen.writeString(convert(address)); - } - } - - public static class NumberDeserializer extends JsonDeserializer implements Converter{ - public static final NumberDeserializer BYTE = new NumberDeserializer<>(BigInteger::byteValue); - public static final NumberDeserializer SHORT = new NumberDeserializer<>(BigInteger::shortValue); - public static final NumberDeserializer INTEGER = new NumberDeserializer<>(BigInteger::intValue); - public static final NumberDeserializer LONG = new NumberDeserializer<>(BigInteger::longValue); - public static final NumberDeserializer BIG_INTEGER = new NumberDeserializer<>(bi -> bi); - - private final Function parseFunc; - - public NumberDeserializer(Function parseFunc) { - this.parseFunc = parseFunc; - } - - @Override - public T convert(String s) { - if (s.startsWith(HEX_PREFIX)) { - return parseFunc.apply(new BigInteger(s.substring(2), 16)); - } else if (s.startsWith(NEG_HEX_PREFIX)) { - return parseFunc.apply(new BigInteger(s.substring(3), 16).negate()); - } else { -// throw new IllegalArgumentException(String.format("invalid prefix loc:%s", p.getCurrentLocation().toString())); - return parseFunc.apply(new BigInteger(s, 16)); - } - } - - @Override - public JavaType getInputType(TypeFactory typeFactory) { - return typeFactory.constructType(String.class); - } - - @Override - public JavaType getOutputType(TypeFactory typeFactory) { - return typeFactory.constructType(new TypeReference(){}); - } - - @SuppressWarnings("unchecked") - @Override - public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { - if (p.currentToken().isNumeric()) { - return parseFunc.apply(p.getBigIntegerValue()); - } else { - return convert(p.getValueAsString()); - } - } - } - - public static class CharDeserializer extends JsonDeserializer implements Converter { - public static final CharDeserializer CHAR = new CharDeserializer(); - - @Override - public Character convert(String value) { - return (char) NumberDeserializer.INTEGER.convert(value).intValue(); - } - - @Override - public JavaType getInputType(TypeFactory typeFactory) { - return typeFactory.constructType(Boolean.class); - } - - @Override - public JavaType getOutputType(TypeFactory typeFactory) { - return typeFactory.constructType(String.class); - } - - @Override - public Character deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { - if (p.currentToken().isNumeric()) { - return (char)p.getIntValue(); - } else { - return convert(p.getValueAsString()); - } - } - } - - public static class BooleanDeserializer extends JsonDeserializer implements Converter { - public static final BooleanDeserializer BOOLEAN = new BooleanDeserializer(); - - @Override - public Boolean convert(String value) { - if (BOOLEAN_TRUE.equals(value)) { - return Boolean.TRUE; - } else if (BOOLEAN_FALSE.equals(value)) { - return Boolean.FALSE; - } - throw new IllegalArgumentException("invalid value:"+value); - } - - @Override - public JavaType getInputType(TypeFactory typeFactory) { - return typeFactory.constructType(Boolean.class); - } - - @Override - public JavaType getOutputType(TypeFactory typeFactory) { - return typeFactory.constructType(String.class); - } - - @Override - public Boolean deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { - try{ - return convert(p.getValueAsString()); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException( - String.format("fail to deserialize loc:%s err:%s", - p.getCurrentLocation().toString(), e.getMessage()),e); - } - } - } - - public static class ByteArrayDeserializer extends JsonDeserializer implements Converter{ - public static final ByteArrayDeserializer BYTE_ARRAY = new ByteArrayDeserializer(); - - @Override - public byte[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { - try{ - return convert(p.getValueAsString()); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException( - String.format("fail to deserialize loc:%s err:%s", - p.getCurrentLocation().toString(), e.getMessage()),e); - } - } - - @Override - public byte[] convert(String s) { - if (s.length() % 2 == 0) { - if (s.startsWith(HEX_PREFIX)) { - s = s.substring(2); - } - return hexToBytes(s); - } else { - throw new IllegalArgumentException("hex string length must be even"); - } - } - - @Override - public JavaType getInputType(TypeFactory typeFactory) { - return typeFactory.constructType(String.class); - } - - @Override - public JavaType getOutputType(TypeFactory typeFactory) { - return typeFactory.constructArrayType(byte.class); - } - } - - public static class AddressDeserializer extends JsonDeserializer implements Converter { - public static final AddressDeserializer SCORE_ADDRESS = new AddressDeserializer<>(Address::new); - public static final AddressDeserializer SDK_ADDRESS = new AddressDeserializer<>(foundation.icon.icx.data.Address::new); - - private final Function parseFunc; - - public AddressDeserializer(Function parseFunc) { - this.parseFunc = parseFunc; - } - - @Override - public T convert(String value) { - return parseFunc.apply(value); - } - - @Override - public JavaType getInputType(TypeFactory typeFactory) { - return typeFactory.constructType(String.class); - } - - @Override - public JavaType getOutputType(TypeFactory typeFactory) { - return typeFactory.constructType(new TypeReference(){}); - } - - @Override - public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - return convert(p.getValueAsString()); - } - } - -} diff --git a/score-client/src/main/java/foundation/icon/jsonrpc/JsonrpcClient.java b/score-client/src/main/java/foundation/icon/jsonrpc/JsonrpcClient.java deleted file mode 100644 index 4975e581..00000000 --- a/score-client/src/main/java/foundation/icon/jsonrpc/JsonrpcClient.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.jsonrpc; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.deser.std.NumberDeserializers; -import okhttp3.Headers; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; -import okhttp3.ResponseBody; -import okio.BufferedSink; - -import java.io.IOException; - -public class JsonrpcClient { - public static MediaType APPLICATION_JSON = MediaType.parse("application/json"); - - protected final String endpoint; - protected final OkHttpClient httpClient; - protected final ObjectMapper mapper; - protected Headers customHeaders; - protected boolean dumpJson; - - public JsonrpcClient(String endpoint) { - this(endpoint, new OkHttpClient.Builder().build()); - } - - public JsonrpcClient(String endpoint, OkHttpClient httpClient) { - this(endpoint, httpClient, new ObjectMapper()); - } - - public JsonrpcClient(String endpoint, ObjectMapper mapper) { - this(endpoint, new OkHttpClient.Builder().build(), mapper); - } - - public JsonrpcClient(String endpoint, OkHttpClient httpClient, ObjectMapper mapper) { - this.endpoint = endpoint; - this.httpClient = httpClient; - this.mapper = mapper; - } - - public String endpoint() { - return endpoint; - } - - public OkHttpClient httpClient() { - return httpClient; - } - - public ObjectMapper mapper() { - return mapper; - } - - public boolean isDumpJson() { - return dumpJson; - } - - public void setDumpJson(boolean dumpJson) { - this.dumpJson = dumpJson; - } - - public Headers getCustomHeaders() { - return customHeaders; - } - - public void setCustomHeaders(Headers customHeaders) { - this.customHeaders = customHeaders; - } - - private Headers.Builder customHeadersBuilder() { - return customHeaders == null ? new Headers.Builder() : customHeaders.newBuilder(); - } - - public void addCustomHeader(String name) { - customHeaders = customHeadersBuilder().add(name).build(); - } - - public void addCustomHeader(String name, String value) { - customHeaders = customHeadersBuilder().add(name, value).build(); - } - - public void setCustomHeader(String name, String value) { - customHeaders = customHeadersBuilder().set(name, value).build(); - } - - public Object request(String method, Object param) { - return request(Object.class, method, param); - } - - public T request(Class resultType, String method, Object params) { - return request(mapper.getTypeFactory().constructType(resultType), method, params); - } - - public T request(TypeReference resultType, String method, Object params) { - return request(mapper.getTypeFactory().constructType(resultType), method, params); - } - - public T request(JavaType resultType, String method, Object params) { - Request.Builder builder = new Request.Builder() - .url(endpoint) - .post(new JsonrpcRequest(method, params, mapper, dumpJson)); - if (customHeaders != null) { - builder.headers(customHeaders); - } - return request(builder.build(), resultType); - } - - protected T request(Request request, JavaType resultType) { - Response response = null; - try { - response = httpClient.newCall(request).execute(); - } catch (IOException e) { - throw new RuntimeException(e); - } - ResponseBody responseBody = response.body(); - if (responseBody != null) { - JsonrpcResponse jsonrpcResponse = null; - try { - String json = responseBody.string(); - if (dumpJson) { - System.out.println(json); - } - jsonrpcResponse = mapper.readValue(json, - mapper.getTypeFactory().constructParametricType(JsonrpcResponse.class, resultType)); - } catch (IOException e) { - throw new RuntimeException(e); - } - JsonrpcError error = jsonrpcResponse.getError(); - if (error != null) { - throw error; - } - return jsonrpcResponse.result; - } else { - throw new RuntimeException("empty body"); - } - } - - public static class JsonrpcRequest extends RequestBody { - @JsonIgnore - ObjectMapper mapper; - @JsonIgnore - boolean dumpJson; - String jsonrpc = "2.0"; - @JsonSerialize(using = LongLikeSerializer.class) - @JsonDeserialize(using = NumberDeserializers.NumberDeserializer.class) - long id; - String method; - @JsonInclude(JsonInclude.Include.NON_NULL) - Object params; - - JsonrpcRequest(String method, Object params, ObjectMapper mapper, boolean dumpJson) { - this.id = System.currentTimeMillis(); - this.method = method; - this.params = params; - this.mapper = mapper; - this.dumpJson = dumpJson; - } - - @Override - public MediaType contentType() { - return APPLICATION_JSON; - } - - @Override - public void writeTo(BufferedSink bufferedSink) throws IOException { - if (dumpJson) { - byte[] bytes = mapper.writeValueAsBytes(this); - bufferedSink.write(bytes); - System.out.println(new String(bytes)); - } else { - mapper.writeValue(bufferedSink.outputStream(), this); - } - } - - public String getJsonrpc() { - return jsonrpc; - } - - public long getId() { - return id; - } - - public String getMethod() { - return method; - } - - public Object getParams() { - return params; - } - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static class JsonrpcResponse { - String jsonrpc = "2.0"; - @JsonSerialize(using = LongLikeSerializer.class) - @JsonDeserialize(using = NumberDeserializers.NumberDeserializer.class) - long id; - T result; - JsonrpcError error; - - public String getJsonrpc() { - return jsonrpc; - } - - public long getId() { - return id; - } - - public T getResult() { - return result; - } - - public JsonrpcError getError() { - return error; - } - } - - public static class JsonrpcError extends RuntimeException { - @JsonSerialize(using = LongLikeSerializer.class) - @JsonDeserialize(using = NumberDeserializers.NumberDeserializer.class) - private long code; - private String message; - private byte[] data; - - public long getCode() { - return code; - } - - public String getMessage() { - return message; - } - - public byte[] getData() { - return data; - } - } - - public static class LongLikeSerializer extends JsonSerializer { - @Override - public void serialize(Long aLong, JsonGenerator gen, SerializerProvider serializers) throws IOException { - gen.writeNumber(((Number) aLong).intValue()); - } - } -} diff --git a/score-client/src/main/java/foundation/icon/jsonrpc/SendTransactionParamSerializer.java b/score-client/src/main/java/foundation/icon/jsonrpc/SendTransactionParamSerializer.java deleted file mode 100644 index 898ea823..00000000 --- a/score-client/src/main/java/foundation/icon/jsonrpc/SendTransactionParamSerializer.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.jsonrpc; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import foundation.icon.jsonrpc.model.SendTransactionParam; - -import java.io.IOException; -import java.util.Collection; -import java.util.Map; -import java.util.StringJoiner; -import java.util.TreeSet; - -public class SendTransactionParamSerializer { - static final String PREFIX = "icx_sendTransaction."; - - static ObjectMapper iconMapper = new ObjectMapper(); - static { - iconMapper.registerModule(new IconJsonModule()); - iconMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - } - static ObjectMapper mapper = new ObjectMapper(); - - public static String serialize(SendTransactionParam sendTransactionParam) throws IOException { - return serialize(sendTransactionParam, null); - } - - public static String serialize(SendTransactionParam sendTransactionParam, Map buffer) throws IOException { - String json = iconMapper.writeValueAsString(sendTransactionParam); - Map params = mapper.readValue(json, new TypeReference>() {}); - if (buffer != null) { - buffer.putAll(params); - } - return PREFIX + serializeMap(params); - } - - public static String serializeObject(Object object) { - if (object == null) { - return "\\0"; - } else if (object instanceof Map) { - // noinspection unchecked - return "{" + serializeMap((Map) object) + "}"; - } else if (object instanceof Collection) { - return "[" + serializeArray(object) + "]"; - } else if (object instanceof String) { - return escape((String) object); - } else { - throw new RuntimeException(String.format("not supported class:%s", object.getClass().getName())); - } - } - - public static String serializeMap(Map map) { - StringJoiner joiner = new StringJoiner("."); - TreeSet keys = new TreeSet<>(map.keySet()); - for (String key : keys) { - joiner.add(key); - joiner.add(serializeObject(map.get(key))); - } - return joiner.toString(); - } - - public static String serializeArray(Object arrayOrCollection) { - StringJoiner joiner = new StringJoiner("."); - if (arrayOrCollection instanceof Collection) { - Collection collection = ((Collection) arrayOrCollection); - for (Object element : collection) { - joiner.add(serializeObject(element)); - } - } else { - throw new RuntimeException(String.format("not supported class:%s", arrayOrCollection.getClass().getName())); - } - return joiner.toString(); - } - - public static String escape(String string) { - return string.replaceAll("([\\\\.{}\\[\\]])", "\\\\$1"); - } - -} diff --git a/score-client/src/main/java/foundation/icon/jsonrpc/model/AbstractTransaction.java b/score-client/src/main/java/foundation/icon/jsonrpc/model/AbstractTransaction.java deleted file mode 100644 index a86f2f75..00000000 --- a/score-client/src/main/java/foundation/icon/jsonrpc/model/AbstractTransaction.java +++ /dev/null @@ -1,76 +0,0 @@ -package foundation.icon.jsonrpc.model; - -import com.fasterxml.jackson.annotation.JsonInclude; -import foundation.icon.jsonrpc.Address; - -import java.math.BigInteger; - -public abstract class AbstractTransaction { - protected BigInteger version = new BigInteger("3"); - protected Address from; - protected Address to; - @JsonInclude(JsonInclude.Include.NON_NULL) - protected BigInteger value; - protected BigInteger timestamp; - protected BigInteger nid; - @JsonInclude(JsonInclude.Include.NON_NULL) - protected BigInteger nonce; - @JsonInclude(JsonInclude.Include.NON_NULL) - protected String dataType; - @JsonInclude(JsonInclude.Include.NON_NULL) - protected Object data; - - public BigInteger getVersion() { - return version; - } - - public Address getFrom() { - return from; - } - - public Address getTo() { - return to; - } - - public BigInteger getValue() { - return value; - } - - public BigInteger getTimestamp() { - return timestamp; - } - - public BigInteger getNid() { - return nid; - } - - public BigInteger getNonce() { - return nonce; - } - - public String getDataType() { - return dataType; - } - - public Object getData() { - return data; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("AbstractTransaction{"); - sb.append("version=").append(version); - sb.append(", from=").append(from); - sb.append(", to=").append(to); - sb.append(", value=").append(value); - sb.append(", timestamp=").append(timestamp); - sb.append(", nid=").append(nid); - sb.append(", nonce=").append(nonce); - sb.append(", dataType='").append(dataType).append('\''); - sb.append(", data=").append(data); - sb.append('}'); - return sb.toString(); - } - -} - diff --git a/score-client/src/main/java/foundation/icon/jsonrpc/model/CallData.java b/score-client/src/main/java/foundation/icon/jsonrpc/model/CallData.java deleted file mode 100644 index 27e909a2..00000000 --- a/score-client/src/main/java/foundation/icon/jsonrpc/model/CallData.java +++ /dev/null @@ -1,37 +0,0 @@ -package foundation.icon.jsonrpc.model; - -import java.util.Map; -import java.util.Objects; - -public class CallData { - private String method; - private Map params; - - public CallData(String method, Map params) { - Objects.requireNonNull(method, "method required not null"); - if (method.isEmpty()) { - throw new IllegalArgumentException("method required not empty"); - } - this.method = method; - this.params = params; - } - - public String getMethod() { - return method; - } - - public Map getParams() { - return params; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("CallData{"); - sb.append("method='").append(method).append('\''); - sb.append(", params=").append(params); - sb.append('}'); - return sb.toString(); - } -} - - diff --git a/score-client/src/main/java/foundation/icon/jsonrpc/model/CallParam.java b/score-client/src/main/java/foundation/icon/jsonrpc/model/CallParam.java deleted file mode 100644 index fe44e131..00000000 --- a/score-client/src/main/java/foundation/icon/jsonrpc/model/CallParam.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.jsonrpc.model; - -import foundation.icon.jsonrpc.Address; - -public class CallParam { - private Address to; - private String dataType = "call"; - private CallData data; - - public CallParam(Address to, CallData data) { - this.to = to; - this.data = data; - } - - public Address getTo() { - return to; - } - - public String getDataType() { - return dataType; - } - - public CallData getData() { - return data; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("CallParam{"); - sb.append("to=").append(to); - sb.append(", dataType='").append(dataType).append('\''); - sb.append(", data=").append(data); - sb.append('}'); - return sb.toString(); - } -} diff --git a/score-client/src/main/java/foundation/icon/jsonrpc/model/DeployData.java b/score-client/src/main/java/foundation/icon/jsonrpc/model/DeployData.java deleted file mode 100644 index c3bd4aa5..00000000 --- a/score-client/src/main/java/foundation/icon/jsonrpc/model/DeployData.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.jsonrpc.model; - -import foundation.icon.jsonrpc.IconJsonModule; - -import java.util.Map; -import java.util.Objects; - -public class DeployData { - private String contentType; - private byte[] content; - private Map params; - - public DeployData(String contentType, byte[] content, Map params) { - Objects.requireNonNull(contentType, "contentType required not null"); - if (contentType.isEmpty()) { - throw new IllegalArgumentException("contentType required not empty"); - } - Objects.requireNonNull(content, "content required not null"); - if (content.length == 0) { - throw new IllegalArgumentException("content required not empty"); - } - this.contentType = contentType; - this.content = content; - this.params = params; - } - - public String getContentType() { - return contentType; - } - - public byte[] getContent() { - return content; - } - - public Map getParams() { - return params; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("DeployData{"); - sb.append("contentType='").append(contentType).append('\''); - sb.append(", content=").append(IconJsonModule.bytesToHex(content)); - sb.append(", params=").append(params); - sb.append('}'); - return sb.toString(); - } -} diff --git a/score-client/src/main/java/foundation/icon/jsonrpc/model/Hash.java b/score-client/src/main/java/foundation/icon/jsonrpc/model/Hash.java deleted file mode 100644 index d7544148..00000000 --- a/score-client/src/main/java/foundation/icon/jsonrpc/model/Hash.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.jsonrpc.model; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; -import foundation.icon.jsonrpc.IconJsonModule; - - -public class Hash { - public static final String HEX_PREFIX = "0x"; - - private final byte[] bytes; - - public Hash(byte[] bytes) { - if (bytes == null) { - throw new IllegalArgumentException("bytes could not be null"); - } - this.bytes = bytes; - } - - @JsonCreator - public Hash(String string) { - if (string == null) { - throw new IllegalArgumentException("string could not be null"); - } - if (string.startsWith(HEX_PREFIX)) { - string = string.substring(2); - } - this.bytes = IconJsonModule.hexToBytes(string); - } - - public byte[] toBytes() { - return bytes; - } - - @JsonValue - @Override - public String toString() { - return HEX_PREFIX + IconJsonModule.bytesToHex(bytes); - } -} diff --git a/score-client/src/main/java/foundation/icon/jsonrpc/model/SendTransactionParam.java b/score-client/src/main/java/foundation/icon/jsonrpc/model/SendTransactionParam.java deleted file mode 100644 index 31482694..00000000 --- a/score-client/src/main/java/foundation/icon/jsonrpc/model/SendTransactionParam.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.jsonrpc.model; - -import foundation.icon.jsonrpc.Address; - -import java.math.BigInteger; -import java.util.Objects; - -public class SendTransactionParam extends TransactionParam { - private BigInteger stepLimit; - - public SendTransactionParam(BigInteger nid, Address to, BigInteger value, String dataType, Object data) { - super(nid, to, value, dataType, data); - Objects.requireNonNull(nid, "nid required not null"); - Objects.requireNonNull(to, "to Address required not null"); - if (value != null && value.signum() == -1) { - throw new IllegalArgumentException("nid must be positive"); - } - } - - public BigInteger getStepLimit() { - return stepLimit; - } - - public void setStepLimit(BigInteger stepLimit) { - this.stepLimit = stepLimit; - } - - public void setFrom(Address from) { - this.from = from; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("SendTransactionParam{"); - sb.append("stepLimit=").append(stepLimit); - sb.append(", version=").append(version); - sb.append(", from=").append(from); - sb.append(", to=").append(to); - sb.append(", value=").append(value); - sb.append(", timestamp=").append(timestamp); - sb.append(", nid=").append(nid); - sb.append(", nonce=").append(nonce); - sb.append(", dataType='").append(dataType).append('\''); - sb.append(", data=").append(data); - sb.append('}'); - return sb.toString(); - } -} diff --git a/score-client/src/main/java/foundation/icon/jsonrpc/model/TransactionParam.java b/score-client/src/main/java/foundation/icon/jsonrpc/model/TransactionParam.java deleted file mode 100644 index 28ae9e75..00000000 --- a/score-client/src/main/java/foundation/icon/jsonrpc/model/TransactionParam.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.jsonrpc.model; - -import foundation.icon.jsonrpc.Address; - -import java.math.BigInteger; - -public class TransactionParam extends AbstractTransaction { - public static final BigInteger TIMESTAMP_MSEC_SCALE = BigInteger.valueOf(1000); - public static BigInteger currentTimestamp() { - return TIMESTAMP_MSEC_SCALE.multiply(BigInteger.valueOf(System.currentTimeMillis())); - } - - public TransactionParam(BigInteger nid, Address to, BigInteger value, String dataType, Object data) { - super(); - this.nid = nid; - this.to = to; - this.value = value; - this.dataType = dataType; - this.data = data; - } - - public void setFrom(Address from) { - this.from = from; - } - - public void setTimestamp(BigInteger timestamp) { - this.timestamp = timestamp; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("TransactionParam{"); - sb.append("version=").append(version); - sb.append(", from=").append(from); - sb.append(", to=").append(to); - sb.append(", value=").append(value); - sb.append(", timestamp=").append(timestamp); - sb.append(", nid=").append(nid); - sb.append(", nonce=").append(nonce); - sb.append(", dataType='").append(dataType).append('\''); - sb.append(", data=").append(data); - sb.append('}'); - return sb.toString(); - } -} diff --git a/score-client/src/main/java/foundation/icon/jsonrpc/model/TransactionResult.java b/score-client/src/main/java/foundation/icon/jsonrpc/model/TransactionResult.java deleted file mode 100644 index c9adb3d6..00000000 --- a/score-client/src/main/java/foundation/icon/jsonrpc/model/TransactionResult.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.jsonrpc.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import foundation.icon.jsonrpc.Address; -import foundation.icon.jsonrpc.IconJsonModule; - -import java.math.BigInteger; -import java.util.List; - -@JsonIgnoreProperties(ignoreUnknown = true) -public class TransactionResult { - private Address to; - private BigInteger cumulativeStepUsed; - private BigInteger stepUsed; - private BigInteger stepPrice; - private List eventLogs; - private byte[] logsBloom; - private BigInteger status; - @JsonInclude(JsonInclude.Include.NON_NULL) - private Failure failure; - @JsonInclude(JsonInclude.Include.NON_NULL) - private Address scoreAddress; - private Hash blockHash; - private BigInteger blockHeight; - private BigInteger txIndex; - private Hash txHash; - @JsonInclude(JsonInclude.Include.NON_NULL) - private Object stepUsedDetails; //[]feePayment - - public Address getTo() { - return to; - } - - public BigInteger getCumulativeStepUsed() { - return cumulativeStepUsed; - } - - public BigInteger getStepUsed() { - return stepUsed; - } - - public BigInteger getStepPrice() { - return stepPrice; - } - - public List getEventLogs() { - return eventLogs; - } - - public byte[] getLogsBloom() { - return logsBloom; - } - - public BigInteger getStatus() { - return status; - } - - public Failure getFailure() { - return failure; - } - - public Address getScoreAddress() { - return scoreAddress; - } - - public Hash getBlockHash() { - return blockHash; - } - - public BigInteger getBlockHeight() { - return blockHeight; - } - - public BigInteger getTxIndex() { - return txIndex; - } - - public Hash getTxHash() { - return txHash; - } - - public Object getStepUsedDetails() { - return stepUsedDetails; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("TransactionResult{"); - sb.append("to=").append(to); - sb.append(", cumulativeStepUsed=").append(cumulativeStepUsed); - sb.append(", stepUsed=").append(stepUsed); - sb.append(", stepPrice=").append(stepPrice); - sb.append(", eventLogs=").append(eventLogs); - sb.append(", logsBloom=").append(IconJsonModule.bytesToHex(logsBloom)); - sb.append(", status=").append(status); - sb.append(", failure=").append(failure); - sb.append(", scoreAddress=").append(scoreAddress); - sb.append(", blockHash=").append(blockHash); - sb.append(", blockHeight=").append(blockHeight); - sb.append(", txIndex=").append(txIndex); - sb.append(", txHash=").append(txHash); - sb.append(", stepUsedDetails=").append(stepUsedDetails); - sb.append('}'); - return sb.toString(); - } - - public static class EventLog { - private Address scoreAddress; - private List indexed; - private List data; - - public Address getScoreAddress() { - return scoreAddress; - } - - public List getIndexed() { - return indexed; - } - - public List getData() { - return data; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("EventLog{"); - sb.append("scoreAddress=").append(scoreAddress); - sb.append(", indexed=").append(indexed); - sb.append(", data=").append(data); - sb.append('}'); - return sb.toString(); - } - } - - public static class Failure { - private BigInteger code; - private String message; - - public BigInteger getCode() { - return code; - } - - public String getMessage() { - return message; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("Failure{"); - sb.append("code=").append(code); - sb.append(", message='").append(message).append('\''); - sb.append('}'); - return sb.toString(); - } - } -} diff --git a/score-client/src/main/java/foundation/icon/score/client/DefaultScoreClient.java b/score-client/src/main/java/foundation/icon/score/client/DefaultScoreClient.java deleted file mode 100644 index 34593d68..00000000 --- a/score-client/src/main/java/foundation/icon/score/client/DefaultScoreClient.java +++ /dev/null @@ -1,510 +0,0 @@ -/* - * Copyright (c) 2022-2022 Balanced.network. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.score.client; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.type.TypeReference; -import foundation.icon.icx.KeyWallet; -import foundation.icon.icx.Wallet; -import foundation.icon.icx.crypto.KeystoreException; -import foundation.icon.jsonrpc.Address; -import foundation.icon.jsonrpc.IconJsonModule; -import foundation.icon.jsonrpc.JsonrpcClient; -import foundation.icon.jsonrpc.SendTransactionParamSerializer; -import foundation.icon.jsonrpc.model.CallData; -import foundation.icon.jsonrpc.model.CallParam; -import foundation.icon.jsonrpc.model.DeployData; -import foundation.icon.jsonrpc.model.Hash; -import foundation.icon.jsonrpc.model.SendTransactionParam; -import foundation.icon.jsonrpc.model.TransactionParam; -import foundation.icon.jsonrpc.model.TransactionResult; -import org.bouncycastle.jcajce.provider.digest.SHA3; -import org.bouncycastle.util.encoders.Base64; -import score.UserRevertedException; - -import java.io.File; -import java.io.IOException; -import java.math.BigInteger; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Properties; - -public class DefaultScoreClient extends JsonrpcClient { - public static final Address ZERO_ADDRESS = new Address("cx0000000000000000000000000000000000000000"); - public static final BigInteger DEFAULT_STEP_LIMIT = new BigInteger("9502f900", 16); - public static final long BLOCK_INTERVAL = 1; - public static final long DEFAULT_RESULT_RETRY_WAIT = 0; - public static final long DEFAULT_RESULT_TIMEOUT = 10000; - - protected final BigInteger nid; - protected final Wallet wallet; - protected final Address address; - protected BigInteger stepLimit = DEFAULT_STEP_LIMIT; - protected long resultTimeout = DEFAULT_RESULT_TIMEOUT; - - public DefaultScoreClient(String url, String nid, String keyStorePath, String keyStorePassword, String address) { - this(url, nid(nid), wallet(keyStorePath, keyStorePassword), new Address(address)); - } - - public DefaultScoreClient(String url, BigInteger nid, Wallet wallet, Address address) { - super(url); - initialize(this); - - this.nid = nid; - this.wallet = wallet; - this.address = address; - } - - public DefaultScoreClient(DefaultScoreClient client) { - super(client.endpoint); - initialize(this); - - this.nid = client._nid(); - this.wallet = client._wallet(); - this.address = client._address(); - this.stepLimit = client._stepLimit(); - this.resultTimeout = client._resultTimeout(); - } - - static void initialize(JsonrpcClient client) { - client.mapper().registerModule(new IconJsonModule()); - client.mapper().setSerializationInclusion(JsonInclude.Include.NON_NULL); - } - - public static DefaultScoreClient _deploy(String url, String nid, String keyStorePath, String keyStorePassword, String scoreFilePath, Map params) { - return _deploy(url, nid(nid), wallet(keyStorePath, keyStorePassword), scoreFilePath, params); - } - - public static DefaultScoreClient _deploy(String url, BigInteger nid, Wallet wallet, String scoreFilePath, Map params) { - JsonrpcClient client = new JsonrpcClient(url); - initialize(client); - Address address = deploy(client, nid, wallet, DEFAULT_STEP_LIMIT, ZERO_ADDRESS, scoreFilePath, params, DEFAULT_RESULT_TIMEOUT); - return new DefaultScoreClient(url, nid, wallet, address); - } - - public static Hash _deployAsync(String url, BigInteger nid, Wallet wallet, String scoreFilePath, Map params) { - JsonrpcClient client = new JsonrpcClient(url); - initialize(client); - return deployAsync(client, nid, wallet, DEFAULT_STEP_LIMIT, ZERO_ADDRESS, scoreFilePath, params); - } - - public static DefaultScoreClient getDeploymentResult(String url, BigInteger nid, Wallet wallet, Hash hash) { - JsonrpcClient client = new JsonrpcClient(url); - initialize(client); - TransactionResult txr = result(client, hash, DEFAULT_RESULT_TIMEOUT); - Address address = txr.getScoreAddress(); - return new DefaultScoreClient(url, nid, wallet, address); - } - - public void _update(String scoreFilePath, Map params) { - deploy(this, nid, wallet, DEFAULT_STEP_LIMIT, address, scoreFilePath, params, DEFAULT_RESULT_TIMEOUT); - } - - public BigInteger _nid() { - return nid; - } - - public Wallet _wallet() { - return wallet; - } - - public Address _address() { - return address; - } - - public BigInteger _stepLimit() { - return stepLimit; - } - - public void _stepLimit(BigInteger stepLimit) { - this.stepLimit = stepLimit; - } - - public long _resultTimeout() { - return resultTimeout; - } - - public void _resultTimeout(long resultTimeout) { - this.resultTimeout = resultTimeout; - } - - public T _call(Class responseType, String method, Map params) { - return call(this, responseType, address, method, params); - } - - public T _call(TypeReference responseType, String method, Map params) { - return call(this, responseType, address, method, params); - } - - public TransactionResult _send(String method, Map params) { - return send(this, nid, wallet, stepLimit, address, null, method, params, resultTimeout); - } - - public TransactionResult _send(BigInteger valueForPayable, String method, Map params) { - return send(this, nid, wallet, stepLimit, address, valueForPayable, method, params, resultTimeout); - } - - public TransactionResult _transfer(Address to, BigInteger value, String message) { - return transfer(this, nid, wallet, stepLimit, to, value, message, resultTimeout); - } - - public BigInteger _balance() { - return balance(this, address); - } - - public BigInteger _balance(Address address) { - return balance(this, address); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - static class BlockHeight { - BigInteger height; - - public BigInteger getHeight() { - return height; - } - } - - public BigInteger _lastBlockHeight() { - return lastBlock(this, BlockHeight.class).height; - } - - - public static DefaultScoreClient of(Properties properties) { - return of("", properties); - } - - public static DefaultScoreClient of(Properties properties, Map params) { - return of("", properties, params); - } - - public static DefaultScoreClient of(String prefix, Properties properties) { - return of(prefix, properties, null); - } - - public static DefaultScoreClient of(String prefix, Properties properties, Map params) { - String url = url(prefix, properties); - BigInteger nid = nid(prefix, properties); - Wallet wallet = wallet(prefix, properties); - Address address = address(prefix, properties); - String scoreFilePath = scoreFilePath(prefix, properties); - Map deployParams = params(prefix, properties, params); - if (address == null) { - System.out.printf("deploy prefix: %s, url: %s, nid: %s, keyStorePath: %s, scoreFilePath: %s, params: %s%n", - prefix, url, nid, wallet != null ? wallet.getAddress() : wallet, scoreFilePath, deployParams); - return _deploy(url, nid, wallet, scoreFilePath, deployParams); - } else { - System.out.printf("prefix: %s, url: %s, nid: %s, wallet: %s, address: %s%n", - prefix, url, nid, wallet != null ? wallet.getAddress() : wallet, address); - DefaultScoreClient client = new DefaultScoreClient(url, nid, wallet, address); - if (isUpdate(prefix, properties) && scoreFilePath != null && !scoreFilePath.isEmpty()) { - System.out.printf("update scoreFilePath: %s, params: %s%n", scoreFilePath, deployParams); - client._update(scoreFilePath, deployParams); - } - return client; - } - } - - public static String url(Properties properties) { - return url("", properties); - } - - public static String url(String prefix, Properties properties) { - return properties.getProperty(prefix+"url"); - } - - public static BigInteger nid(Properties properties) { - return nid("", properties); - } - - public static BigInteger nid(String prefix, Properties properties) { - return nid(properties.getProperty(prefix+"nid")); - } - - public static BigInteger nid(String nid) { - if (nid.startsWith("0x")) { - return new BigInteger(nid.substring(2), 16); - } else { - return new BigInteger(nid); - } - } - - public static Wallet wallet(Properties properties) { - return wallet("", properties); - } - - public static Wallet wallet(String prefix, Properties properties) { - String keyStore = properties.getProperty(prefix+"keyStore"); - if (keyStore == null || keyStore.isEmpty()) { - return null; - } - String keyPassword = properties.getProperty(prefix+"keyPassword"); - if (keyPassword == null || keyPassword.isEmpty()) { - String keySecret = properties.getProperty(prefix+"keySecret"); - try { - System.out.println("using keySecret "+keySecret); - keyPassword = Files.readString(Path.of(keySecret)); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - return wallet(keyStore, keyPassword); - } - - public static Wallet wallet(String keyStorePath, String keyStorePassword) { - try { - System.out.println("load wallet "+keyStorePath); - return KeyWallet.load(keyStorePassword, new File(keyStorePath)); - } catch (IOException | KeystoreException e) { - throw new RuntimeException(e); - } - } - - public static Address address(Properties properties) { - return address("", properties); - } - - public static Address address(String prefix, Properties properties) { - String address = properties.getProperty(prefix+"address"); - if (address == null || address.isEmpty()) { - return null; - } - return address(address); - } - - public static Address address(String address) { - return new Address(address); - } - - public static boolean isUpdate(Properties properties) { - return isUpdate("", properties); - } - - public static boolean isUpdate(String prefix, Properties properties) { - return Boolean.parseBoolean( - (String)properties.getOrDefault(prefix+"isUpdate", - Boolean.FALSE.toString())); - } - - public static String scoreFilePath(Properties properties) { - return scoreFilePath("", properties); - } - - public static String scoreFilePath(String prefix, Properties properties) { - return properties.getProperty(prefix+"scoreFilePath"); - } - - public static Map params(Properties properties) { - return params("", properties); - } - - public static Map params(String prefix, Properties properties) { - return params(prefix, properties, null); - } - - public static Map params(String prefix, Properties properties, Map overwrite) { - String paramsKey = prefix+"params."; - Map params = new HashMap<>(); - for(Map.Entry entry : properties.entrySet()) { - String key = ((String)entry.getKey()); - if (key.startsWith(paramsKey)) { - params.put(key.substring(paramsKey.length()), entry.getValue()); - } - } - if (overwrite != null) { - for(Map.Entry entry : overwrite.entrySet()) { - params.put(entry.getKey(), entry.getValue()); - } - } - return params.isEmpty() ? null : params; - } - - - public static CallData callData(String method, Map params) { - return new CallData(method, params != null && !params.isEmpty() ? params : null); - } - - public static T call( - JsonrpcClient client, Class responseType, Address address, - String method, Map params) { - return client.request(responseType, "icx_call", new CallParam(address, callData(method, params))); - } - - public static T call( - JsonrpcClient client, TypeReference responseType, Address address, - String method, Map params) { - return client.request(responseType, "icx_call", new CallParam(address, callData(method, params))); - } - - static Hash sendTransaction(JsonrpcClient client, Wallet wallet, SendTransactionParam sendTransactionParam) { - Objects.requireNonNull(client, "client required not null"); - Objects.requireNonNull(wallet, "wallet required not null"); - Objects.requireNonNull(wallet, "sendTransactionParam required not null"); - - sendTransactionParam.setFrom(Address.of(wallet)); - if (sendTransactionParam.getTimestamp() == null) { - sendTransactionParam.setTimestamp(TransactionParam.currentTimestamp()); - } - if (sendTransactionParam.getStepLimit() == null) { - sendTransactionParam.setStepLimit(DEFAULT_STEP_LIMIT); - } - if (sendTransactionParam.getNid() == null) { - throw new IllegalArgumentException("nid could not be null"); - } - - Map params = new HashMap<>(); - String serialized; - try { - serialized = SendTransactionParamSerializer.serialize(sendTransactionParam, params); - } catch (IOException e) { - throw new RuntimeException(e); - } - byte[] digest = new SHA3.Digest256().digest(serialized.getBytes(StandardCharsets.UTF_8)); - String signature = Base64.toBase64String(wallet.sign(digest)); - params.put("signature", signature); - return client.request(Hash.class, "icx_sendTransaction", params); - } - - static void waitBlockInterval() { - // System.out.printf("wait block interval %d msec%n", BLOCK_INTERVAL); - // try { - // Thread.sleep(BLOCK_INTERVAL); - // } catch (InterruptedException ie) { - // ie.printStackTrace(); - // } - } - - public static TransactionResult send( - JsonrpcClient client, BigInteger nid, Wallet wallet, BigInteger stepLimit, Address address, - BigInteger valueForPayable, String method, Map params, - long timeout) { - SendTransactionParam tx = new SendTransactionParam(nid, address, valueForPayable, "call", callData(method, params)); - Hash txh = sendTransaction(client, wallet, tx); - waitBlockInterval(); - System.out.println("tx hash is: "+txh); - return result(client, txh, timeout); - } - - public static Address deploy( - JsonrpcClient client, BigInteger nid, Wallet wallet, BigInteger stepLimit, Address address, - String scoreFilePath, Map params, - long timeout) { - - byte[] content; - try { - content = Files.readAllBytes(Path.of(scoreFilePath)); - } catch (IOException e) { - throw new RuntimeException(e); - } - String contentType; - if (scoreFilePath.endsWith(".jar")) { - contentType = "application/java"; - } else if (scoreFilePath.endsWith(".zip")) { - contentType = "application/zip"; - } else { - throw new RuntimeException("not supported score file"); - } - SendTransactionParam tx = new SendTransactionParam(nid, address,null,"deploy", new DeployData(contentType, content, params)); - Hash txh = sendTransaction(client, wallet, tx); - waitBlockInterval(); - TransactionResult txr = result(client, txh, timeout); - System.out.println("SCORE address: "+txr.getScoreAddress()); - return txr.getScoreAddress(); - } - - public static Hash deployAsync( - JsonrpcClient client, BigInteger nid, Wallet wallet, BigInteger stepLimit, Address address, - String scoreFilePath, Map params) { - byte[] content; - try { - content = Files.readAllBytes(Path.of(scoreFilePath)); - } catch (IOException e) { - throw new RuntimeException(e); - } - String contentType; - if (scoreFilePath.endsWith(".jar")) { - contentType = "application/java"; - } else if (scoreFilePath.endsWith(".zip")) { - contentType = "application/zip"; - } else { - throw new RuntimeException("not supported score file"); - } - - SendTransactionParam tx = new SendTransactionParam(nid, address,null,"deploy", new DeployData(contentType, content, params)); - return sendTransaction(client, wallet, tx); - } - - public static TransactionResult transfer( - JsonrpcClient client, BigInteger nid, Wallet wallet, BigInteger stepLimit, Address address, - BigInteger value, String message, long timeout) { - SendTransactionParam tx; - if (message != null) { - tx = new SendTransactionParam(nid, address, value, "message", message.getBytes(StandardCharsets.UTF_8)); - } else { - tx = new SendTransactionParam(nid, address, value, null, null); - } - Hash txh = sendTransaction(client, wallet, tx); - waitBlockInterval(); - return result(client, txh, timeout); - } - - public static TransactionResult result(JsonrpcClient client, Hash txh, long timeout) { - Map params = Map.of("txHash", txh); - long etime = System.currentTimeMillis() + timeout; - TransactionResult txr = null; - while(txr == null) { - try { - txr = client.request(TransactionResult.class, "icx_getTransactionResult", params); - } catch (JsonrpcError e) { - if (e.getCode() == -31002 /* pending */ - || e.getCode() == -31003 /* executing */ - || e.getCode() == -31004 /* not found */) { - if (timeout > 0 && System.currentTimeMillis() >= etime) { - throw new RuntimeException("timeout"); - } - } else { - throw new RuntimeException(e); - } - } - } - if (!BigInteger.ONE.equals(txr.getStatus())) { - TransactionResult.Failure failure = txr.getFailure(); - int revertCode = failure.getCode().intValue(); - String revertMessage = failure.getMessage(); - if (revertCode >= 32) { - throw new UserRevertedException(revertCode - 32, revertMessage); - } else { - throw new RevertedException(revertCode, revertMessage); - } - } - return txr; - } - - public static BigInteger balance(JsonrpcClient client, Address address) { - return client.request(BigInteger.class, "icx_getBalance", Map.of("address", address)); - } - - public static T lastBlock(JsonrpcClient client, Class blockType) { - return client.request(blockType, "icx_getLastBlock", null); - } - -} diff --git a/score-client/src/main/java/foundation/icon/score/client/RevertedException.java b/score-client/src/main/java/foundation/icon/score/client/RevertedException.java deleted file mode 100644 index b6af28d5..00000000 --- a/score-client/src/main/java/foundation/icon/score/client/RevertedException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.score.client; - -public class RevertedException extends score.RevertedException { - private int code; - public RevertedException(int code, String message) { - super(message); - this.code = code; - } - - public int getCode() { - return code; - } -} diff --git a/score-client/src/main/java/foundation/icon/score/client/ScoreClient.java b/score-client/src/main/java/foundation/icon/score/client/ScoreClient.java deleted file mode 100644 index 7ab6d42b..00000000 --- a/score-client/src/main/java/foundation/icon/score/client/ScoreClient.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.score.client; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target({ElementType.TYPE, ElementType.FIELD}) -@Retention(RetentionPolicy.SOURCE) -public @interface ScoreClient { - String suffix() default "ScoreClient"; -} diff --git a/score-client/src/main/java/foundation/icon/score/client/ScoreClientProcessor.java b/score-client/src/main/java/foundation/icon/score/client/ScoreClientProcessor.java deleted file mode 100644 index d185410b..00000000 --- a/score-client/src/main/java/foundation/icon/score/client/ScoreClientProcessor.java +++ /dev/null @@ -1,425 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.score.client; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.CodeBlock; -import com.squareup.javapoet.JavaFile; -import com.squareup.javapoet.MethodSpec; -import com.squareup.javapoet.ParameterSpec; -import com.squareup.javapoet.ParameterizedTypeName; -import com.squareup.javapoet.TypeName; -import com.squareup.javapoet.TypeSpec; -import foundation.icon.annotation_processor.AbstractProcessor; -import foundation.icon.annotation_processor.ProcessorUtil; -import foundation.icon.icx.Wallet; -import foundation.icon.jsonrpc.Address; -import foundation.icon.jsonrpc.model.TransactionResult; -import score.annotation.EventLog; -import score.annotation.External; -import score.annotation.Payable; - -import javax.annotation.processing.Filer; -import javax.annotation.processing.ProcessingEnvironment; -import javax.annotation.processing.RoundEnvironment; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; -import java.io.IOException; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.function.Consumer; - -public class ScoreClientProcessor extends AbstractProcessor { - static final String METHOD_OF = "_of"; - static final String PARAM_PROPERTEIS = "properties"; - static final String PARAM_PREFIX = "prefix"; - static final String METHOD_DEPLOY = "_deploy"; - static final String PARAM_URL = "url"; - static final String PARAM_NID = "nid"; - static final String PARAM_WALLET = "wallet"; - static final String PARAM_ADDRESS = "address"; - static final String PARAM_CLIENT = "client"; - static final String PARAM_SCORE_FILE_PATH = "scoreFilePath"; - static final String PARAM_PARAMS = "params"; - // - static final String PARAM_PAYABLE_VALUE = "valueForPayable"; - static final String PARAM_CONSUMER = "consumerFunc"; - static final String PARAM_STEP_LIMIT = "stepLimit"; - - @Override - public synchronized void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - } - - @Override - public Set getSupportedAnnotationTypes() { - Set s = new HashSet<>(); - s.add(ScoreClient.class.getCanonicalName()); - return s; - } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latestSupported(); - } - - @Override - public boolean process(Set annotations, RoundEnvironment roundEnv) { - boolean ret = false; - for (TypeElement annotation : annotations) { - Set annotationElements = roundEnv.getElementsAnnotatedWith(annotation); - for (Element element : annotationElements) { - if (element.getKind().isInterface() || element.getKind().isClass() || element.getKind().isField()) { - messager.noteMessage("process %s %s", element.getKind(), element.asType(), element.getSimpleName()); - generateImplementClass(processingEnv.getFiler(), element); - ret = true; - } else { - throw new RuntimeException("not support"); - } - } - } - return ret; - } - - private void generateImplementClass(Filer filer, Element element) { - TypeElement typeElement; - if (element instanceof TypeElement) { - typeElement = (TypeElement) element; - } else if (element instanceof VariableElement) { - typeElement = super.getTypeElement(element.asType()); - } else { - throw new RuntimeException("not support"); - } - - ClassName elementClassName = ClassName.get(typeElement); - ScoreClient ann = element.getAnnotation(ScoreClient.class); - ClassName className = ClassName.get(elementClassName.packageName(), elementClassName.simpleName() + ann.suffix()); - TypeSpec typeSpec = typeSpec(className, typeElement); - JavaFile javaFile = JavaFile.builder(className.packageName(), typeSpec).build(); - try { - javaFile.writeTo(filer); - } catch (IOException e) { - messager.warningMessage("create javaFile error : %s", e.getMessage()); - } - } - - private TypeSpec typeSpec(ClassName className, TypeElement element) { - TypeSpec.Builder builder = TypeSpec - .classBuilder(className) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .superclass(DefaultScoreClient.class) - .addSuperinterfaces(ProcessorUtil.getSuperinterfaces(element)); - - if (element.getKind().isInterface()) { - builder.addSuperinterface(element.asType()); - builder.addMethod(deployMethodSpec(className, null)); - } - - //Constructor - builder.addMethod(MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC) - .addParameter(ParameterSpec.builder(String.class, PARAM_URL).build()) - .addParameter(ParameterSpec.builder(BigInteger.class, PARAM_NID).build()) - .addParameter(ParameterSpec.builder(Wallet.class, PARAM_WALLET).build()) - .addParameter(ParameterSpec.builder(Address.class, PARAM_ADDRESS).build()) - .addStatement("super($L, $L, $L, $L)", - PARAM_URL, PARAM_NID, PARAM_WALLET, PARAM_ADDRESS).build()); - builder.addMethod(MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC) - .addParameter(ParameterSpec.builder(DefaultScoreClient.class, PARAM_CLIENT).build()) - .addStatement("super($L)", PARAM_CLIENT).build()); - - //_of(Properties) - builder.addMethod(MethodSpec.methodBuilder(METHOD_OF) - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .addParameter(ParameterSpec.builder(Properties.class, PARAM_PROPERTEIS).build()) - .addStatement("return _of(\"\", $L)", PARAM_PROPERTEIS) - .returns(className) - .build()); - //_of(String prefix, Properties) - builder.addMethod(MethodSpec.methodBuilder(METHOD_OF) - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .addParameter(ParameterSpec.builder(String.class, PARAM_PREFIX).build()) - .addParameter(ParameterSpec.builder(Properties.class, PARAM_PROPERTEIS).build()) - .addStatement("return new $T($T.of($L, $L))", className, DefaultScoreClient.class, PARAM_PREFIX, PARAM_PROPERTEIS) - .returns(className) - .build()); - - builder.addMethods(overrideMethods(element)); - builder.addMethods(deployMethods(className, element)); - return builder.build(); - } - - private List overrideMethods(TypeElement element) { - List methods = new ArrayList<>(); - TypeMirror superClass = element.getSuperclass(); - if (!superClass.getKind().equals(TypeKind.NONE) && !superClass.toString().equals(Object.class.getName())) { - messager.noteMessage("superClass[kind:%s, name:%s]", superClass.getKind().name(), superClass.toString()); - List superMethods = overrideMethods(super.getTypeElement(element.getSuperclass())); - methods.addAll(superMethods); - } - - for (TypeMirror inf : element.getInterfaces()) { - TypeElement infElement = super.getTypeElement(inf); - List infMethods = overrideMethods(infElement); - methods.addAll(infMethods); - } - - boolean mustGenerate = element.getKind().isInterface(); - for (Element enclosedElement : element.getEnclosedElements()) { - if (ElementKind.METHOD.equals(enclosedElement.getKind()) && - ProcessorUtil.hasModifier(enclosedElement, Modifier.PUBLIC) && - !ProcessorUtil.hasModifier(enclosedElement, Modifier.STATIC)) { - ExecutableElement ee = (ExecutableElement) enclosedElement; - External external = ee.getAnnotation(External.class); - - if (external != null || mustGenerate) { - CodeBlock paramsCodeblock = paramsCodeblock(ee); - MethodSpec methodSpec = methodSpec(ee, paramsCodeblock); - addMethod(methods, methodSpec, element); - boolean isExternal = external != null ? - !external.readonly() : - methodSpec.returnType.equals(TypeName.VOID); - if (isExternal) { - addMethod(methods, consumerMethodSpec(methodSpec, paramsCodeblock, false), element); - if (ee.getAnnotation(Payable.class) != null) { - addMethod(methods, payableMethodSpec(methodSpec, paramsCodeblock), element); - addMethod(methods, consumerMethodSpec(methodSpec, paramsCodeblock, true), element); - } - } - } - } - } - return methods; - } - - private void addMethod(List methods, MethodSpec methodSpec, TypeElement element) { - if (methodSpec != null) { - MethodSpec conflictMethod = ProcessorUtil.getConflictMethod(methods, methodSpec); - if (conflictMethod != null) { - methods.remove(conflictMethod); - if (element.getKind().isInterface()) { - messager.warningMessage( - "Redeclare '%s %s(%s)' in %s", - conflictMethod.returnType.toString(), - conflictMethod.name, - ProcessorUtil.parameterSpecToString(conflictMethod.parameters), - element.getQualifiedName()); - } - } - methods.add(methodSpec); - } - } - - private CodeBlock paramsCodeblock(ExecutableElement element) { - if (element == null || element.getParameters() == null || element.getParameters().size() == 0) { - return null; - } - CodeBlock.Builder builder = CodeBlock.builder(); - builder.addStatement("$T<$T,$T> $L = new $T<>()", - Map.class, String.class, Object.class, PARAM_PARAMS, HashMap.class); - for (VariableElement ve : element.getParameters()) { - ParameterSpec ps = ParameterSpec.get(ve); - builder.addStatement("$L.put(\"$L\",$L)", PARAM_PARAMS, ps.name, ps.name); - } - return builder.build(); - } - - static Map wrapperTypeNames = Map.of( - TypeKind.BOOLEAN, TypeName.get(Boolean.class), - TypeKind.BYTE, TypeName.get(Boolean.class), - TypeKind.SHORT, TypeName.get(Byte.class), - TypeKind.INT, TypeName.get(Integer.class), - TypeKind.LONG, TypeName.get(Long.class), - TypeKind.CHAR, TypeName.get(Character.class), - TypeKind.FLOAT, TypeName.get(Float.class), - TypeKind.DOUBLE, TypeName.get(Double.class)); - - private MethodSpec methodSpec(ExecutableElement ee, CodeBlock paramsCodeblock) { - if (ee.getAnnotation(EventLog.class) != null) { - return notSupportedMethod(ee, "not supported EventLog method", null); - } - - String methodName = ee.getSimpleName().toString(); - TypeMirror returnType = ee.getReturnType(); - TypeName returnTypeName = TypeName.get(returnType); - External external = ee.getAnnotation(External.class); - - MethodSpec.Builder builder = MethodSpec - .methodBuilder(methodName) - .addModifiers(ProcessorUtil.getModifiers(ee, Modifier.ABSTRACT)) - .addParameters(ProcessorUtil.getParameterSpecs(ee)) - .returns(returnTypeName); -// .addAnnotation(Override.class); - - String params = "null"; - if (paramsCodeblock != null) { - builder.addCode(paramsCodeblock); - params = PARAM_PARAMS; - } - - boolean isVoid = returnTypeName.equals(TypeName.VOID); - boolean isExternal = external != null ? !external.readonly() : isVoid; - if (isExternal) { - if (isVoid) { - builder.addStatement("super._send(\"$L\", $L)", methodName, params); - if (ee.getAnnotation(Payable.class) != null) { - builder.addJavadoc("To payable, use $L($T $L, ...)", methodName, BigInteger.class, PARAM_PAYABLE_VALUE); - } - } else { - return notSupportedMethod(ee, "not supported response of writable method in ScoreClient", - CodeBlock.builder().add("$L($T<$T> $L, ...)", - methodName, Consumer.class, TransactionResult.class, PARAM_CONSUMER).build()); - } - } else { - if (!isVoid) { - if (returnType.getKind().isPrimitive()) { - builder.addStatement("return super._call($T.class, \"$L\", $L)", - wrapperTypeNames.get(returnType.getKind()), methodName, params); - } else { - if (returnType.getKind().equals(TypeKind.DECLARED) && - ((DeclaredType)returnType).getTypeArguments().size() > 0) { - builder.addStatement("return super._call(new $T<$T>(){}, \"$L\", $L)", - TypeReference.class, returnTypeName, methodName, params); - } else { - builder.addStatement("return super._call($T.class, \"$L\", $L)", - returnTypeName, methodName, params); - } - } - } else { - return notSupportedMethod(ee, "not supported, void of readonly method in ScoreClient", null); - } - } - return builder.build(); - } - - private MethodSpec payableMethodSpec(MethodSpec methodSpec, CodeBlock paramsCodeblock) { - MethodSpec.Builder builder = MethodSpec.methodBuilder(methodSpec.name) - .addModifiers(methodSpec.modifiers) - .addParameter(BigInteger.class, PARAM_PAYABLE_VALUE) - .addParameters(methodSpec.parameters) - .returns(TypeName.VOID); - - String params = "null"; - if (paramsCodeblock != null) { - builder.addCode(paramsCodeblock); - params = PARAM_PARAMS; - } - builder.addStatement("super._send($L, \"$L\", $L)", PARAM_PAYABLE_VALUE, methodSpec.name, params); - return builder.build(); - } - - private MethodSpec consumerMethodSpec(MethodSpec methodSpec, CodeBlock paramsCodeblock, boolean isPayable) { - MethodSpec.Builder builder = MethodSpec.methodBuilder(methodSpec.name) - .addModifiers(methodSpec.modifiers) - .addParameter(ParameterSpec.builder( - ParameterizedTypeName.get(Consumer.class, TransactionResult.class), PARAM_CONSUMER).build()) - .returns(TypeName.VOID); - - String params = "null"; - if (paramsCodeblock != null) { - builder.addCode(paramsCodeblock); - params = PARAM_PARAMS; - } - if (isPayable) { - builder.addParameter(BigInteger.class, PARAM_PAYABLE_VALUE) - .addStatement("$L.accept(super._send($L, \"$L\", $L))", - PARAM_CONSUMER, PARAM_PAYABLE_VALUE, methodSpec.name, params); - } else { - builder.addStatement("$L.accept(super._send(\"$L\", $L))", PARAM_CONSUMER, methodSpec.name, params); - } - return builder.addParameters(methodSpec.parameters).build(); - } - - private MethodSpec notSupportedMethod(ExecutableElement ee, String msg, CodeBlock instead) { - String methodName = ee.getSimpleName().toString(); - TypeName returnTypeName = TypeName.get(ee.getReturnType()); - return MethodSpec.methodBuilder(methodName) - .addModifiers(ProcessorUtil.getModifiers(ee, Modifier.ABSTRACT)) - .addParameters(ProcessorUtil.getParameterSpecs(ee)) - .returns(returnTypeName) - .addStatement("throw new $T(\"$L\")", RuntimeException.class, msg) - .addJavadoc("@deprecated Do not use this method, this is generated only for preventing compile error.\n Instead, use $L\n", - instead != null ? instead : "N/A") - .addJavadoc("@throws $L(\"$L\")", RuntimeException.class.getName(), msg) - .addAnnotation(Deprecated.class) - .build(); - } - - private List deployMethods(ClassName className, TypeElement element) { - List methods = new ArrayList<>(); - TypeMirror superClass = element.getSuperclass(); - if (!superClass.getKind().equals(TypeKind.NONE) && !superClass.toString().equals(Object.class.getName())) { - messager.noteMessage("superClass[kind:%s, name:%s]", superClass.getKind().name(), superClass.toString()); - List superMethods = deployMethods(className, super.getTypeElement(element.getSuperclass())); - methods.addAll(superMethods); - } - - for (Element enclosedElement : element.getEnclosedElements()) { - if (ElementKind.CONSTRUCTOR.equals(enclosedElement.getKind()) && - ProcessorUtil.hasModifier(enclosedElement, Modifier.PUBLIC)) { - methods.add(deployMethodSpec(className, (ExecutableElement) enclosedElement)); - } - } - return methods; - } - - private MethodSpec deployMethodSpec(ClassName className, ExecutableElement element) { - MethodSpec.Builder builder = MethodSpec.methodBuilder(METHOD_DEPLOY) - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .addParameter(ParameterSpec.builder(String.class, PARAM_URL).build()) - .addParameter(ParameterSpec.builder(BigInteger.class, PARAM_NID).build()) - .addParameter(ParameterSpec.builder(Wallet.class, PARAM_WALLET).build()) - .addParameter(ParameterSpec.builder(String.class, PARAM_SCORE_FILE_PATH).build()) - .returns(className); - - if (element != null) { - builder.addParameters(ProcessorUtil.getParameterSpecs(element)); - } else { - builder.addParameter(ParameterSpec.builder( - ParameterizedTypeName.get(Map.class, String.class, Object.class), PARAM_PARAMS).build()); - } - - CodeBlock paramsCodeblock = paramsCodeblock(element); - if (paramsCodeblock != null) { - builder.addCode(paramsCodeblock); - } - builder - .addStatement("return new $T($T._deploy($L,$L,$L,$L,$L))", - className, DefaultScoreClient.class, - PARAM_URL, PARAM_NID, PARAM_WALLET, PARAM_SCORE_FILE_PATH, - paramsCodeblock != null || element == null ? PARAM_PARAMS : "null") - .build(); - return builder.build(); - } - -} diff --git a/score-client/src/main/java/foundation/icon/score/client/ScoreInterface.java b/score-client/src/main/java/foundation/icon/score/client/ScoreInterface.java deleted file mode 100644 index 7bfa3b1a..00000000 --- a/score-client/src/main/java/foundation/icon/score/client/ScoreInterface.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.score.client; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.SOURCE) -public @interface ScoreInterface { - String suffix() default "ScoreInterface"; - String addressGetter() default "_address"; -} diff --git a/score-client/src/main/java/foundation/icon/score/client/ScoreInterfaceProcessor.java b/score-client/src/main/java/foundation/icon/score/client/ScoreInterfaceProcessor.java deleted file mode 100644 index 70aa69c2..00000000 --- a/score-client/src/main/java/foundation/icon/score/client/ScoreInterfaceProcessor.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package foundation.icon.score.client; - -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.JavaFile; -import com.squareup.javapoet.MethodSpec; -import com.squareup.javapoet.ParameterSpec; -import com.squareup.javapoet.TypeName; -import com.squareup.javapoet.TypeSpec; -import foundation.icon.annotation_processor.AbstractProcessor; -import foundation.icon.annotation_processor.ProcessorUtil; -import score.Address; -import score.Context; -import score.annotation.EventLog; -import score.annotation.External; -import score.annotation.Payable; - -import javax.annotation.processing.Filer; -import javax.annotation.processing.ProcessingEnvironment; -import javax.annotation.processing.RoundEnvironment; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; -import java.io.IOException; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.StringJoiner; - -/* - * TODO generate exception each Method - * GenericPredefinedException - * - Status.OutOfStep - * - Status.StackOverflow - * handle IllegalArgumentException - * - Status.ContractNotFound - * - Status.MethodNotFound - * - Status.MethodNotPayable - * - Status.InvalidParameter - * - Status.OutOfBalance - * - Status.PackageError - * handle RevertedException - * - Status.UnknownFailure - * - s < Status.UserReversionStart - * handle UserRevertedException - * - Status.UserReversionStart <= s < Status.UserReversionEnd - * - * Exception extends score.UserRevertException - * Exception extends Exception - */ -public class ScoreInterfaceProcessor extends AbstractProcessor { - static final String MEMBER_ADDRESS = "address"; - static final String PARAM_PAYABLE_VALUE = "valueForPayable"; - - @Override - public synchronized void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - } - - @Override - public Set getSupportedAnnotationTypes() { - Set s = new HashSet<>(); - s.add(ScoreInterface.class.getCanonicalName()); - return s; - } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latestSupported(); - } - - @Override - public boolean process(Set annotations, RoundEnvironment roundEnv) { - boolean ret = false; - for (TypeElement annotation : annotations) { - Set annotationElements = roundEnv.getElementsAnnotatedWith(annotation); - for (Element element : annotationElements) { - if (element.getKind().isInterface() || element.getKind().isClass()) { - messager.noteMessage("process %s %s", element.getKind(), element.asType(), element.getSimpleName()); - generateImplementClass(processingEnv.getFiler(), (TypeElement) element); - ret = true; - } else { - throw new RuntimeException("not support"); - } - } - } - return ret; - } - - private void generateImplementClass(Filer filer, TypeElement element) { - ClassName interfaceClassName = ClassName.get(element); - TypeSpec typeSpec = typeSpec(element); - JavaFile javaFile = JavaFile.builder(interfaceClassName.packageName(), typeSpec).build(); - try { - javaFile.writeTo(filer); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private TypeSpec typeSpec(TypeElement element) { - ClassName interfaceClassName = ClassName.get(element); - ScoreInterface scoreInterface = element.getAnnotation(ScoreInterface.class); - ClassName className = ClassName.get(interfaceClassName.packageName(), interfaceClassName.simpleName() + scoreInterface.suffix()); - TypeSpec.Builder builder = TypeSpec - .classBuilder(ClassName.get(interfaceClassName.packageName(), className.simpleName())) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL); - - if (element.getKind().isInterface()) { - builder.addSuperinterface(element.asType()); - } - - //Fields - builder.addField(Address.class, MEMBER_ADDRESS, Modifier.PROTECTED, Modifier.FINAL); - - //Constructor - builder.addMethod(MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC) - .addParameter(ParameterSpec.builder(Address.class, MEMBER_ADDRESS).build()) - .addStatement("this.$L = $L", MEMBER_ADDRESS, MEMBER_ADDRESS).build()); - - //addressGetter - builder.addMethod(MethodSpec.methodBuilder(scoreInterface.addressGetter()) - .addModifiers(Modifier.PUBLIC) - .returns(Address.class) - .addStatement("return this.$L", MEMBER_ADDRESS).build()); - - List methods = overrideMethods(element); - builder.addMethods(methods); - return builder.build(); - } - - private List overrideMethods(TypeElement element) { - List methods = new ArrayList<>(); - TypeMirror superClass = element.getSuperclass(); - if (!superClass.getKind().equals(TypeKind.NONE) && !superClass.toString().equals(Object.class.getName())) { - messager.noteMessage("superClass[kind:%s, name:%s]", superClass.getKind().name(), superClass.toString()); - List superMethods = overrideMethods(super.getTypeElement(element.getSuperclass())); - methods.addAll(superMethods); - } - - for (TypeMirror inf : element.getInterfaces()) { - TypeElement infElement = super.getTypeElement(inf); - List infMethods = overrideMethods(infElement); - methods.addAll(infMethods); - } - - boolean mustGenerate = element.getKind().isInterface(); - for (Element enclosedElement : element.getEnclosedElements()) { - if (ElementKind.METHOD.equals(enclosedElement.getKind()) && - ProcessorUtil.hasModifier(enclosedElement, Modifier.PUBLIC) && - !ProcessorUtil.hasModifier(enclosedElement, Modifier.STATIC)) { - ExecutableElement ee = (ExecutableElement) enclosedElement; - External external = ee.getAnnotation(External.class); - if (external != null || mustGenerate) { - MethodSpec methodSpec = methodSpec(ee, mustGenerate); - addMethod(methods, methodSpec, element); - if (external != null && !external.readonly() && ee.getAnnotation(Payable.class) != null) { - addMethod(methods, payableMethodSpec(ee, methodSpec), element); - } - } - } - } - return methods; - } - - private void addMethod(List methods, MethodSpec methodSpec, TypeElement element) { - if (methodSpec != null) { - MethodSpec conflictMethod = ProcessorUtil.getConflictMethod(methods, methodSpec); - if (conflictMethod != null) { - methods.remove(conflictMethod); - messager.warningMessage( - "Redeclare '%s %s(%s)' in %s", - conflictMethod.returnType.toString(), - conflictMethod.name, - ProcessorUtil.parameterSpecToString(conflictMethod.parameters), - element.getQualifiedName()); - } - methods.add(methodSpec); - } - } - - private String callParameters(ExecutableElement element) { - StringJoiner variables = new StringJoiner(", "); - variables.add(String.format("this.%s", MEMBER_ADDRESS)); - variables.add(String.format("\"%s\"", element.getSimpleName().toString())); - for (VariableElement variableElement : element.getParameters()) { - variables.add(variableElement.getSimpleName().toString()); - } - return variables.toString(); - } - - private MethodSpec methodSpec(ExecutableElement ee, boolean mustGenerate) { - if (ee.getAnnotation(EventLog.class) != null) { - return notSupportedMethod(ee, "not supported EventLog method"); - } - - String methodName = ee.getSimpleName().toString(); - TypeMirror returnType = ee.getReturnType(); - TypeName returnTypeName = TypeName.get(returnType); - - MethodSpec.Builder builder = MethodSpec - .methodBuilder(methodName) -// .addAnnotation(Override.class) - .addModifiers(ProcessorUtil.getModifiers(ee, Modifier.ABSTRACT)) - .addParameters(ProcessorUtil.getParameterSpecs(ee)) - .returns(returnTypeName); - - String callParameters = callParameters(ee); - if (returnTypeName.equals(TypeName.VOID)) { - builder.addStatement("$T.call($L)", Context.class, callParameters); - } else { - if (returnType.getKind().equals(TypeKind.DECLARED) && - ((DeclaredType)returnType).getTypeArguments().size() > 0) { - builder.addStatement("return ($T)$T.call($L)", returnTypeName, Context.class, callParameters); - } else { - builder.addStatement("return $T.call($T.class, $L)", Context.class, returnTypeName, callParameters); - } - } - return builder.build(); - } - - private MethodSpec payableMethodSpec(ExecutableElement ee, MethodSpec methodSpec) { - MethodSpec.Builder builder = MethodSpec.methodBuilder(methodSpec.name) - .addModifiers(methodSpec.modifiers) - .addParameter(BigInteger.class, PARAM_PAYABLE_VALUE) - .addParameters(methodSpec.parameters) - .returns(methodSpec.returnType); - - String callParameters = callParameters(ee); - TypeMirror returnType = ee.getReturnType(); - if (methodSpec.returnType.equals(TypeName.VOID)) { - builder.addStatement("$T.call($L, $L)", Context.class, PARAM_PAYABLE_VALUE, callParameters); - } else { - if (returnType.getKind().equals(TypeKind.DECLARED) && - ((DeclaredType)returnType).getTypeArguments().size() > 0) { - builder.addStatement("return ($T)$T.call($L, $L)", methodSpec.returnType, Context.class, PARAM_PAYABLE_VALUE, callParameters); - } else { - builder.addStatement("return $T.call($T.class, $L, $L)", Context.class, methodSpec.returnType, PARAM_PAYABLE_VALUE, callParameters); - } - } - return builder.build(); - } - - private MethodSpec notSupportedMethod(ExecutableElement ee, String msg) { - String methodName = ee.getSimpleName().toString(); - TypeName returnTypeName = TypeName.get(ee.getReturnType()); - return MethodSpec.methodBuilder(methodName) - .addModifiers(ProcessorUtil.getModifiers(ee, Modifier.ABSTRACT)) - .addParameters(ProcessorUtil.getParameterSpecs(ee)) - .returns(returnTypeName) - .addStatement("throw new $T(\"$L\")", RuntimeException.class, msg) - .addJavadoc("@deprecated Do not use this method, this is generated only for preventing compile error. $L\n", msg) - .addJavadoc("@throws $L", RuntimeException.class.getName()) - .addAnnotation(Deprecated.class) - .build(); - } -} From 70396d393d7b9502af1aebc7ca2355d8f689c12f Mon Sep 17 00:00:00 2001 From: naneey Date: Wed, 6 Mar 2024 10:46:14 +0545 Subject: [PATCH 10/64] chore: pushing json files --- .../src/main/resources/conf/contracts.json | 30 +++++ .../src/main/resources/conf/godWallet.json | 22 ++++ test-lib/src/main/resources/conf/preps.json | 108 ++++++++++++++++++ 3 files changed, 160 insertions(+) create mode 100644 test-lib/src/main/resources/conf/contracts.json create mode 100644 test-lib/src/main/resources/conf/godWallet.json create mode 100644 test-lib/src/main/resources/conf/preps.json diff --git a/test-lib/src/main/resources/conf/contracts.json b/test-lib/src/main/resources/conf/contracts.json new file mode 100644 index 00000000..940c5ee1 --- /dev/null +++ b/test-lib/src/main/resources/conf/contracts.json @@ -0,0 +1,30 @@ +[ + { + "name": "cpsCore", + "contract": "CPSCore", + "params": { + "applicationPeriod": "20" + }, + "order":1.0 + }, + { + "name": "cpsTreasury", + "contract": "CPSTreasury", + "params": { + }, + "addressParams": { + "cpsScore": "cpsCore" + }, + "order":2.0 + }, + { + "name": "cpfTreasury", + "contract": "CPFTreasury", + "params": { + }, + "addressParams": { + "cpsScore": "cpsCore" + }, + "order":2.0 + } +] \ No newline at end of file diff --git a/test-lib/src/main/resources/conf/godWallet.json b/test-lib/src/main/resources/conf/godWallet.json new file mode 100644 index 00000000..2a611aa3 --- /dev/null +++ b/test-lib/src/main/resources/conf/godWallet.json @@ -0,0 +1,22 @@ +{ + "address": "hxb6b5791be0b5ef67063b3c10b840fb81514db2fd", + "id": "87323a66-289a-4ce2-88e4-00278deb5b84", + "version": 3, + "coinType": "icx", + "crypto": { + "cipher": "aes-128-ctr", + "cipherparams": { + "iv": "069e46aaefae8f1c1f840d6b09144999" + }, + "ciphertext": "f35ff7cf4f5759cb0878088d0887574a896f7f0fc2a73898d88be1fe52977dbd", + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 65536, + "r": 8, + "p": 1, + "salt": "0fc9c3b24cdb8175" + }, + "mac": "1ef4ff51fdee8d4de9cf59e160da049eb0099eb691510994f5eca492f56c817a" + } +} diff --git a/test-lib/src/main/resources/conf/preps.json b/test-lib/src/main/resources/conf/preps.json new file mode 100644 index 00000000..3f0a68fc --- /dev/null +++ b/test-lib/src/main/resources/conf/preps.json @@ -0,0 +1,108 @@ +{ + "hxb6b5791be0b5ef67063b3c10b840fb81514db2fd": "573b555367d6734ea0fecd0653ba02659fa19f7dc6ee5b93ec781350bda27376", + "hx6636c7747d4e3045253dd9fb65ae2d5e54094592": "393f6548d472787138ebc6ac54ee38ace1b8a4dd46c3edfb3122b35db589286f", + "hxe7edbaf218b7709f67b7660aad99ae7b96b9008b": "f639b497bbf871d4f0bdeb6b86a72282edb1bfb30f6ee7e78cfdc95a6ddc5d43", + "hx28715c1fa884875df8c6f912a02f0ad4d4846d2a": "6736efad6c84269c6615921c43d3885cf2c6be20e8358ada8e776ada6a26a2dd", + "hxa2beea062cfb76ed3d1f5dca0c6bf5cadca17cde": "860d07529b385759c211cbfebf4478c1b463c19591fd1e8bb6f481dcf97c3f74", + "hx03d3b8eab81a03fe7ddfc5c8b670fe003becfe98": "2ba7a948c87ed651c5d2d54705ffd05f8211b61a905c114292fb70ae8f0af620", + "hx7af05c5da0fd57b7ea74a92d9c2b8d04e8ef99b3": "ab9c733168ab087d138a763090c30e4bdc82321a216b25fd010304dfe92442cb", + "hxa90662439dffd09dee16ec993c0dd40398ec5fb0": "f5482ae4aec8a73a65e660f873f08c296b021df157847f94b9f2a3fd35d1adf6", + "hxfa710d212608482f4dbf7c917a7921a5dfb3c043": "a5316f06638c327799088fc801138c4ac3508fe5f4c4bfda2adbae6ff832b50e", + "hxff66fa360b39f7ae05d16a39a2c49ced3dc60c77": "e0029c32345d1fa03a2f3934befb75c1a5ba1561c17bb6d722cd2cfbb494e43a", + "hxab187ea842d181150dc92548e872bde0e27fe3bc": "553d0da919be0b848336c1233389f5b8ca7a9807476714922513f23d43ad1dae", + "hxb66e5890effa8662f59e92f239317acadd901097": "ef5307bab1d6ceed8a779c99ecd1daef752f0877ea84797a8b0618900edf4f57", + "hxb9de3f9bd24884e045dd33481a90abcae001de27": "77e01c5f3b91b197ac529d67d7ccf84a7b8384c1cda144eee87abec93ac7397a", + "hx36338f4269195fcd79a62d6316150ea8af81ccd2": "052a6351cd45f3c3f82685f4d9f72a5ba2320b63e4fdac854a63f607337e0d3a", + "hxeeeeaf20e4122d807e0ea47e1b7b62e1063fd69a": "de29f744619cd6ebfcb815e7d48bacc118b120192b63cbe85e611eb4792fcb7d", + "hx6c70314a246c03ba59bd462d1d42fd54d5510cf0": "fc1c750e6e02f8d68d86ae2b28e25632ad427a7b60eab63cc4a43f61054f7457", + "hx3c9ab844bcf7d473c3f797c7b3004260d561cd72": "df9f518ea7c6f72ffb43414633887fe32f9deef072cf1e9c8b46add774573e42", + "hx83c00fcd9164b925eb48a5ddb65c55aa3877be1d": "1accdc447c56345839c9d9e0afe8dad1ac7afc938053c6ef34e3affd81e9d7d1", + "hxc1230b7498bcbc04daf95233f2da8cf36baac625": "af74ae1fe4355f9b12030282f5f5ae2ae72e01ac8d36041e4aa73ac4672cdce4", + "hx1849adbe91b7aefc9f84320f96fec0fda6f24654": "b34b033d527341fdcdec151d693b0f6943886b6733bd5fdf73c7779006b4e344", + "hxbfe3974f1491c134b68363989e09e17cc641a84c": "e49de438fbd33a3e88371178d76b29d03a4af9ac9cdfc91ed0e9a3f0d38752fc", + "hx9b1a5055c02f180eeb3e2ce1e97a000520eec3cf": "fff396bcf81cc56636db0c29f9c2d2f078f1d16392c2ea711595c98899a1d41c", + "hx93772d3ea28aadc5428c608a86144045d440a059": "40c4c0a26c05c849cd26a2150cf98d0a04d4229e042dbdc38b95fbc0dd86e432", + "hxc1d8673163360b18207623b18531c4d6d00167e0": "10e02b1da084418ee1c6231d7b902ef5f2c1f2d1705868a9b72268aeb531f23c", + "hxdb617a70f0e180e458c520b498c9cc5c1d79c2d3": "6953d7f021446d66caf8e2e5712446ae73cff5db1e37228c5ad9378450375899", + "hx97992a0b424b6bb31e3000620ef998ecd3a136f2": "1be95816e171ab56a2d390f4cc4b56d30884eb97e946976a524c913dc1f511a2", + "hxe80c59c99e6b9edd40a3e299f4086705654f671e": "18a8cd1857993b7b0496e3ed8ee030e0012923089e62089d885cf6214806882e", + "hx9973edc14286f19bfef673e1cd19eec8cbc988e8": "325e06ed2319af4d806d2ae9099daf91ffbcbfd5b3946b026dd11637b141a899", + "hxe80f04b7c2fdaafe2d7b1e9a304a827fdabf79a7": "b3e3baad508c4f47e7b4395f56bdd751a924f4148f2ddde2686f8adb0c80f7b1", + "hxf57ef33184c3fee6c43ec60df057769c1605c9a2": "741b555357f358bcc7c9b62498829d813f473e0b36c1c8510aaffc5858a584df", + "hx9c4298fc042210ab828fe4050fdcef033ecca326": "a1b948cb104d02a6bac54bb137b84f614cad8cf73da1919615c0cac4e5bd9789", + "hx068d880060b58abcf41436460fd92c6589c13c34": "0ab150bdadfdd607723ce6ef302ee3a331d45391b593cb4f28a936157188db51", + "hx72552d36897a700a684df2ce7974735c89e4ee24": "96ed02df17bff24802646f527ed26c2eb3c95806a649545b5f607ab060bd4174", + "hxe4e71d6807a7610294a2325fae87ce384f57a5b6": "6128d69aaad2238cbd42128169d4cd42c5b6db497679a7655e8427396796fb22", + "hx1991ca745d3c4b6ffab5ad92ea3d0c067b5f75e5": "baa5024dd1ceeb5af07a9ed7dfebfcb7f55eddc2c78b8db6345acb78f0c07203", + "hx43946dd08fb3fa7c9905df10afc30077c3c7975a": "553751e0338948f6ebfacde61f476fd2d9f4ffdae2b87b0ce36c7d90b20538ff", + "hx05a2c1eee05c927dda0f14a384b70c5b3e77c8ef": "8c68a066a6a769f69bac5fcb1a69a847ab4d528d092973d48f87e32ba6a68ceb", + "hx2ef7f7035a86bb39db8b6957394ebbe34b6b06fd": "8f6be89b5e2b21538cdd5410f08fe1307ae0d9d43e7b9d3a551577c0d925db3e", + "hxcf34dfb66faaa17bb96e66039a8d9164f7c0cac4": "a2d48ceddf8cd9f7e5d710fceac7eea1809b8dfda4659fe228b24dec9c5f2102", + "hx1e5614bde3be064f6ebe204007c967c8f08e0528": "61ed6c34822da8577f766f51ebe8a8539b7322fe2697acf239312f87b3d6c1bf", + "hx53d867d0ea96f6d2121b86da81b4b338b153c29c": "8e779fddcf0e63e9a7d6acf59f548ca23abde83004edf40e3bb42c61c3ef1ce5", + "hxcfdcd6d312afadf1826fa01f88a5e34fd1f539ce": "e31b323f4146f4274feddb3abf8b5e30c916b1bf04398cd1a08e6ac0b9055c8d", + "hx00ae4f48b64f3230f998a658d32cec9b5a9ee1e5": "4302f800c4f2ef8b881b7080b386366ab2088c2e8d9042b3c8946b3d0c338637", + "hx254010613e06e67378a6338f3d1fd0f700c882f6": "bd642909546f2c9e5f2d75b542269458a698cc18993ec0ccbf3da96f7ceaaf1d", + "hx2e9aae6b81c497a5af752f9285755488c8d291c7": "2ad9982a66c7248d960717e9109818cc5e46c5b7122ce62b5d3fd1c1584197c8", + "hx53bf8da223d199922e517e4306e0d2776d0793db": "67202e3581fe91af90d2f892aef51dc77bb0eba15111db367774b96b7290f2f3", + "hx8daf83576eb39507a1e1d5ce993036239d843e9d": "e18a19dbaa7192be847135a9e6d0eada0eb63bc393342c39858dd895dcd443c8", + "hxc862db463151c07f9a895bd9caeb6c5ae0969d86": "b830975dbadde629d07fcce49fe95c165c721ae3510489e9fc413dd632b60fb0", + "hx13df39540bddc6451f61689296ef564a0e8b21c9": "395bff275b62fa8f509738f2c25e7aebeed2bbe93d096d7773a410dd47ce1ca8", + "hx0b20a8e403ee06f87c2b967ee7e1ac9527d67913": "ded83336b4a0b7c8e81e0a96e8b813df374b28b0d702f6f5b9edab89dac1eff1", + "hx657726fdbac8bf6329d7c4a0d7c7489a57d9000d": "b69801a720c2796f04199134e409f73c3e23d3ac9394595ca2f8875bedfc3dff", + "hx35cb5d9c994ea6ee9bc66a8443fc8d63f539bba1": "b5efd48bf5262a86d723f050662933ef3a7a247820ca932ccecc4b79406191fa", + "hx6d21e5a05e1d79c53d08d9d37519fd8050051968": "83f4cdd3a5fccabb023ba68d9b0b0efbb1cbe3afdb6663ec550b1656f8cdea00", + "hx77b9f82d58ef154c7c092f2f0d82498002ef531e": "eec3a2a7116e5a9ae7a980319e086acd72e46d840345cc5ab76ffb089cf43fb0", + "hxe7786d1bcc22a0318ab170b5baa89f5b0a8e489d": "116030a7c079fdf60c602b6533323c03a61760428e1fc6d1658124e97f7775a3", + "hx7cf047eb75051019893de4b2ae94f0c43d018c7e": "4ebe9f3f1cd49110ceff08df4be92a4e28acf68fa9739ee5eb0a71de961c108a", + "hx9a7d29e6d251bca4a5811a426b9c27eb616b69f4": "8069f2a64762e4b7395c825958dd62629dba5c1c31d43e1ef69df38528708bd9", + "hxe6398003d4be27cd439c3892df4ae88527e9557d": "4f6f1316a12ba098478b3e081701c63350fde59781f274ec62fc3d3ee02d9370", + "hx7c5d9900892a346db84b6859759c382910a98bc0": "16c948e4e4a64b4a507586553410f0922b3fd8217566f8ec873821e12c5eeb33", + "hxa1f147deec635fe8a9f6ea3d02ac9e933e24909d": "89f2856612da91d6be1334e6a5d55119f53a639ea45da5aa12e1ece4278bdb41", + "hx454604142bd696bad4d1a7ba43707d4c92ad318c": "930a912d5425eede6707518668fb44302f3a9a04bfd3604336c7621cc998f18b", + "hx04c6f4443128869d874e1cd85080020a139e5ec1": "f0cd8083119fed78a6261388c4755222af8b8b47a87d6139ac1d1e3b69468619", + "hxd087d79e31e2417ad37b64085bc304b4f23bdb48": "1d6b8dabed1425925398e54f97c0e95a7ce5eebf94f07799d1d0ba97b8e88d92", + "hx192939a9f187b39ed7f08013fc86a6873a57706d": "aaf526bcd3a65e18c62e3b193c414401acd949e6f5aa7d73ccf8caa742c52834", + "hx3b146925c3f93e9ab7b6f99b1a8755aa76c9b5f4": "c95ff03e7f52e6473b957aff0f6942daf441c7c1327772fd56a89b22d13dc5f2", + "hxebc6282520de4275fedf16ee02abf86b39d10fb0": "62579b57d8123adf16bed7ad8c07f7116e42a690c30801d9c889085e1f6fcd4f", + "hxd6850304c0c63b5feb6d280a5b5a8732eacd79ec": "7340382aa2bb3c9fe693740485a908a9f52cd3d14696458a1e54117e8fe4d114", + "hxbfda75139dc9b6fdf0702d9a7ec3b9d37e5b1a8f": "375a6af5fdb9f31b77bcff9a4c5194190e72fd484f863f353c57057f2b560195", + "hxc707fe573bec0d3f79162303e45fba571766a73b": "93572fc6bd19475208e4724345432c63da4792e475021af5fd4e82794b448bd8", + "hx1ef8be9f98f831168298a168858127155fbbf855": "4936bdae329626253a2b16077d6f27964f2e5fea47bfc000afbe315a73150525", + "hx51c835949506a005a1ca8f612c8225e229a44695": "0f21de53aa85c4747f9bd0377c09b1e9e86473bbbb8267d527e517cd4cb45f86", + "hx25828f58f936e5135ddd970bcaa9e21a5254bb3a": "e6f31635efe681e8320bda2d1811656ea211f7cac684a0b2db4e28d66bc5d9db", + "hx33151e6d1d5e314cea00b6731e1cccf430d14c69": "0ac82dc2f456a4f69633de7177a196eab0daddd8fc1995ea151d1619d426e4b7", + "hxc24ff906776a486da1f553d0a3f75c3886ee3dd1": "9fa3fd3655cefe35dc8dde05d5e4a646133705cea775b7fa8199d477f42c4ae9", + "hxdb69ac6830a3d4af942057d09203c0b85e75e412": "295b9588123a0d222e59a2d39b304baebbda1f69ece6a27881d696b4a90d0db4", + "hx6d49b95e9d2694781fa1821b6c940791942746fd": "948ffb8f246885d7912704bd9db55bbfaa3a3a66dcb8a537c886178b495a8e8f", + "hx56bf6eedc7399530562a87ff020c0aea50e83e44": "12e47c0fd51bbb6498d6a7854e9e43ea2af69955ca99b0a3daa0da518f750501", + "hx7854d878952f4eefa7d657d802878c61746d659a": "736e73e266704b0bb3d08fcec1978f82a19c87b56dc606aaf075b0086fe235e3", + "hx08865f68914ec2abee8896c214396c34b99f47f6": "b4da40c2c83782fd416ee4890d5336a83858f43a17acb58f3b7e00d135a51a03", + "hxf6b7066bdeb27ade9e9e995b0a06ad814b7e4f61": "68ce7931dcbf00b184a327c5e84bec8ccea2054425b249973fd8a7dd2ed41050", + "hx67daa5605280f1c19399bf39b4a4cc9cafea3299": "64e87cb647203f02be78090c5d2e1cc089d49921961ed9ad122093a59f55d11c", + "hx6fcf5ca62512d490c7775f33cc12ce236dece1b4": "279640083f5393e37ff15b0bc680a8a785e4492cc8669bdbe1c5cd1f9be20f93", + "hxb76477d89baf57f2c17e98955e851e258472725b": "b336b8cf3750dbe59124658e6c1549dd2d97cad2fd42c47d7a43104d983399a9", + "hx34b146115b9c8a4fb53ba57792bb00e7b8a613d0": "d0e4aecaa2df9472045e47996c86d6c70b7e598df02801282670ad9928d37043", + "hx72d9a56d45e414311813359adc1ed9e2b012796a": "7e53a199296dc663431b109ddc2433efad477bc2c6137d28ad2c780861b4cb45", + "hxe8c5ad611a582e8df48bc75f98705c53c750e144": "cb0b36ca42f0e02b95c9b068aaa3f7671e3eb5810ad40a636f18a49cf70307a9", + "hx22926175cdba85f17e721730832f83545fb8c978": "765d1b6276e82cb31caa3e7f65e0421af80913061cb55c866a52949661ea2c12", + "hxda694f573b4e400b622bb83231078a964806d019": "87c3f5131224bcee566eff40d802978c3e9175e2810dff9247bcb8b79cec19ad", + "hx76bd1d301d145e9f44f4829a7a55c6e9c5465517": "86148add5b919241d6506283531a7e8e7b5ab57753fe622c225dc4424d6eb7e2", + "hxfc24ae3cd3fff914f800d746b65cef38808e62ae": "c13c849ebe47d65b4b263ffc117b7c921e762c654174d179d6e5ef668c06d6b6", + "hxed9e74c5bf92974867e6ceac399e42766e3c6d70": "2d49758aa02284ce381f960200a722a31034bafb9b145c1aebbbaa7eb5d885f8", + "hx4ba269f1ad0363ed886d96d2cf2fc9b02bd4add3": "fa3fe9bee9037efa00798bb5e3d7e3bb0e4a31285348f5161c7e178f9f97e22a", + "hx359097eeb9a034408dde077cc17427061eba58f6": "6e66fbbcfb5d000a761ca2a3c50bfa19dd758c4af5d046add1562625a9197b4b", + "hxa6f4b6586db9d7d7d2d09c3cad2eaadb8a8e570f": "b63d0e9214e0ad85bbacddd562f7b145d0cee9c47efdfca09b71e61823a2e036", + "hx1baacdc1831abcfed4cfd632f78ba581858515a1": "fb6b7f96bdea75c77199cb9c3b3a19df678aec38e9ed95d3b9a99ba6270832b4", + "hxfb1ef73510861d8759fd6f05db78ccc704979ad6": "6285c3f09c183248c63b4da22b4f1fe3c79488e589bf2b3805ce08eb8a1fd3c8", + "hx27ed4f60d48a93b93776c11ffa215103d2cb827c": "bd3f9fd19fed74c24ae7d2f380113484a7a8a0ff8e629132e9d3b1ae3dfad3c6", + "hxbba0f33fb754bdb287e199eead2c0f2ca4e8914f": "26d3033febc327dfb6fb61cd47dd569700aed15215898f4b0e38e539705dc3fe", + "hx37764062fc3f073cda91d2ce839870d53e987c82": "f16de08a347054b082be78d9b148c1f9a04227ce5f034cdd2dde5dc6cb5147a5", + "hxf1fec4f23a0dce8376efa6a880531c9c862dbcce": "433812a444251331e514f185dab31d8539b9ec85e0a30483d47680b32bdab63e", + "hx4a227dd1eccdd1196e135a0eea100bb1b95a3098": "c1a627565ed2f9c3675cda8f49caa8ffe5ef139e8b4da4df0d11b6ce5da85b4c", + "hx387350216461e0d206048ce7e58945ce4bc30b23": "0e50a9d67db39e15aa10a3051e75df9e64164c1978acc7da48ef38591969d803", + "hxfbd0abfa0079fa9ae51dd7331e0852a04f5a8cb5": "38af9fe413ae82199bab686c5ce79955a7b1b347a9323525512fd2dd9073a9ed", + "hxe95832467255889c39d78429b9ea2a22ef8e1951": "4dd5970a8d476f102a0d1dbbd0bd0523ce56128f76a5f6f8333bdd395676f274", + "hx8ce11c6a023aa95b2daef897f156d3cc52eb82de": "8ffc192824dc9c2bfc75979bb98da8e0cb50f06d7f9834379209627063613d55" + +} \ No newline at end of file From e3ab05d5b447b2baca36bcd360a5e5a6e8529eb5 Mon Sep 17 00:00:00 2001 From: naneey Date: Thu, 14 Mar 2024 13:29:23 +0545 Subject: [PATCH 11/64] chore: cps score is set from constructor --- .../community/icon/cps/score/cpftreasury/CPFTreasury.java | 5 ++++- .../community/icon/cps/score/cpstreasury/CPSTreasury.java | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java index abbbe140..1a2b33a9 100644 --- a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java +++ b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java @@ -39,13 +39,16 @@ public class CPFTreasury extends SetterGetter implements CPFTreasuryInterface { private final VarDB swapFlag = Context.newVarDB(SWAP_FLAG, Boolean.class); private final VarDB swapLimitAmount = Context.newVarDB(SWAP_LIMIT_AMOUNT, BigInteger.class); - public CPFTreasury() { + public CPFTreasury(@Optional Address cpsScore) { if (treasuryFund.get() == null) { treasuryFund.set(BigInteger.valueOf(1000000).multiply(EXA)); swapCount.set(SwapReset); swapState.set(SwapReset); swapFlag.set(false); } + if (CPFTreasury.cpsScore.get() == null){ + CPFTreasury.cpsScore.set(cpsScore); + } } private boolean proposalExists(String ipfsKey) { diff --git a/CPSTreasury/src/main/java/community/icon/cps/score/cpstreasury/CPSTreasury.java b/CPSTreasury/src/main/java/community/icon/cps/score/cpstreasury/CPSTreasury.java index 5df88454..d2d6d783 100644 --- a/CPSTreasury/src/main/java/community/icon/cps/score/cpstreasury/CPSTreasury.java +++ b/CPSTreasury/src/main/java/community/icon/cps/score/cpstreasury/CPSTreasury.java @@ -55,10 +55,13 @@ public class CPSTreasury extends ProposalData implements CPSTreasuryInterface { private static final BigInteger HUNDRED = BigInteger.valueOf(100); public static final BigInteger MAX_ONSET_PAYMENT = BigInteger.valueOf(20); - public CPSTreasury() { + public CPSTreasury(@Optional Address cpsScore) { if (onsetPaymentPercentage.get() == null) { onsetPaymentPercentage.set(BigInteger.TEN); } + if (this.cpsScore.get() == null){ + this.cpsScore.set(cpsScore); + } } @Override From 027481ea47c0c462bfc0f7839ef5cf0ef8cb4e81 Mon Sep 17 00:00:00 2001 From: naneey Date: Thu, 14 Mar 2024 13:30:39 +0545 Subject: [PATCH 12/64] chore: chain decentralized --- .../icon/cps/score/test/integration/CPS.java | 166 +++++++++++++++++- .../cps/score/test/integration/CPSClient.java | 12 ++ .../score/test/integration/Environment.java | 2 +- .../integration/scores/SystemInterface.java | 3 + 4 files changed, 181 insertions(+), 2 deletions(-) diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java index 4e09ab45..8f1cae0d 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java @@ -1,7 +1,8 @@ package community.icon.cps.score.test.integration; -import community.icon.cps.score.lib.interfaces.SystemInterfaceScoreClient; +import community.icon.cps.score.test.integration.scores.SystemInterfaceScoreClient; import community.icon.cps.score.test.integration.model.Score; +import community.icon.cps.score.test.integration.scores.SystemInterface; import community.icon.cps.score.test.integration.utils.DefaultICONClient; import foundation.icon.icx.KeyWallet; import foundation.icon.icx.data.Bytes; @@ -46,12 +47,163 @@ public CPS(String contracts) throws Exception { public void setupCPS() throws Exception { deployPrep(); + decentralizeChain(); this.addresses = new ScoreDeployer(this,contracts).deployContracts(); ownerClient = new CPSClient(this,owner); testClient = new CPSClient(this, createWalletWithBalance(BigInteger.TEN.pow(24))); } + private void decentralizeChain(){ + if (isPRepRegistered()) { + return; + } + setStake(); + setDelegationOfPreps(); + setBonderList(); + setBondsofPreps(); + setGodStake(); + } + + public void setGodStake(){ + SYSTEM_INTERFACE = new SystemInterfaceScoreClient(godClient); + SYSTEM_INTERFACE.setStake(BigInteger.valueOf(9_000_000).multiply(BigInteger.TEN.pow(18))); + SystemInterface.Delegation[] delegation = new SystemInterface.Delegation[1]; + delegation[0] = new SystemInterface.Delegation(); + delegation[0].address = score.Address.fromString(chain.godWallet.getAddress().toString()); + delegation[0].value = BigInteger.valueOf(8000000).multiply(BigInteger.TEN.pow(18)); + SYSTEM_INTERFACE.setDelegation(delegation); + + score.Address[] addresses = new score.Address[1]; + addresses[0] = score.Address.fromString(chain.godWallet.getAddress().toString()); + SYSTEM_INTERFACE.setBonderList(addresses); + + SystemInterface.Bond[] bonds = new SystemInterface.Bond[1]; + bonds[0] = new SystemInterface.Bond(); + bonds[0].address = score.Address.fromString(chain.godWallet.getAddress().toString()); + bonds[0].value = BigInteger.valueOf(1000000).multiply(BigInteger.TEN.pow(18)); + SYSTEM_INTERFACE.setBond(bonds); + System.out.println("god wallet setup done"); + } + + private void setStake(){ + int count = 0; + for (Map.Entry prep : preps.entrySet()) { +// if (prep.getKey().equals(Address.fromString("hxb6b5791be0b5ef67063b3c10b840fb81514db2fd"))){ +// continue; +// } + if (count < 7) { + KeyWallet wallet = KeyWallet.load(new Bytes(prep.getValue())); + var client = new DefaultScoreClient( + chain.getEndpointURL(), + chain.networkId, + wallet, + DefaultScoreClient.ZERO_ADDRESS + ); + SYSTEM_INTERFACE = new SystemInterfaceScoreClient(client); + SYSTEM_INTERFACE.setStake(BigInteger.valueOf(100_000).multiply(BigInteger.TEN.pow(18))); + count++; + } + else { + break; + } + } + System.out.println("set is done"); + } + + public void setDelegationOfPreps(){ + int count = 0; + for (Map.Entry prep : preps.entrySet()) { +// if (prep.getKey().equals(Address.fromString("hxb6b5791be0b5ef67063b3c10b840fb81514db2fd"))){ +// continue; +// } + if (count < 7) { + KeyWallet wallet = KeyWallet.load(new Bytes(prep.getValue())); + SystemInterface.Delegation[] delegations = new SystemInterface.Delegation[1]; + delegations[0] = new SystemInterface.Delegation(); + delegations[0].address = score.Address.fromString(prep.getKey().toString()); + delegations[0].value = BigInteger.valueOf(80_000).multiply(BigInteger.TEN.pow(18)); + var client = new DefaultScoreClient( + chain.getEndpointURL(), + chain.networkId, + wallet, + DefaultScoreClient.ZERO_ADDRESS + ); + SYSTEM_INTERFACE = new SystemInterfaceScoreClient(client); + SYSTEM_INTERFACE.setDelegation(delegations); + count++; + } + else { + break; + } + } + + + System.out.println("delegation of preps done "); + } + + public void setBonderList(){ + int count = 0; + for (Map.Entry prep : preps.entrySet()) { +// if (prep.getKey().equals(Address.fromString("hxb6b5791be0b5ef67063b3c10b840fb81514db2fd"))){ +// continue; +// } + if (count < 7) { + KeyWallet wallet = KeyWallet.load(new Bytes(prep.getValue())); + score.Address[] bonderList = new score.Address[1]; + bonderList[0] = score.Address.fromString(prep.getKey().toString()); + var client = new DefaultScoreClient( + chain.getEndpointURL(), + chain.networkId, + wallet, + DefaultScoreClient.ZERO_ADDRESS + ); + SYSTEM_INTERFACE = new SystemInterfaceScoreClient(client); + SYSTEM_INTERFACE.setBonderList(bonderList); + count++; + + + + } + else { + break; + } + + + } + System.out.println("the bonder list"); + + } + + public void setBondsofPreps(){ + int count = 0; + for (Map.Entry prep : preps.entrySet()) { +// if (prep.getKey().equals(Address.fromString("hxb6b5791be0b5ef67063b3c10b840fb81514db2fd"))){ +// continue; +// } + if (count < 7){ + KeyWallet wallet = KeyWallet.load(new Bytes(prep.getValue())); + SystemInterface.Bond[] bond = new SystemInterface.Bond[1]; + bond[0] = new SystemInterface.Bond(); + bond[0].address = score.Address.fromString(prep.getKey().toString()); + bond[0].value = BigInteger.valueOf(10_000).multiply(BigInteger.TEN.pow(18)); + var client = new DefaultScoreClient( + chain.getEndpointURL(), + chain.networkId, + wallet, + DefaultScoreClient.ZERO_ADDRESS + ); + SYSTEM_INTERFACE = new SystemInterfaceScoreClient(client); + SYSTEM_INTERFACE.setBond(bond); + count++; + } + else { + break; + } + } + + System.out.println("bond of preps done "); + } public CPSClient defaultClient() { return ownerClient; @@ -100,6 +252,18 @@ public boolean isPRepRegistered() { return false; } + public CPSClient newClient(BigInteger balance) throws Exception { + CPSClient client = new CPSClient(this, createWalletWithBalance(balance)); + cpsClients.put(client.getAddress(), client); + return client; + } + + public CPSClient customClient(String privateKey){ + CPSClient client = new CPSClient(this,KeyWallet.load(new Bytes(privateKey))); + cpsClients.put(client.getAddress(),client); + return client; + } + public void deployPrep() { if (isPRepRegistered()) { return; diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java index fcae09d5..8c73c790 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java @@ -16,6 +16,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.NoSuchElementException; +import java.util.stream.Collectors; import static community.icon.cps.score.test.integration.Environment.chain; @@ -46,6 +47,7 @@ public CPSClient(CPS cps, KeyWallet wallet){ private void init(){ for (Entry entry : this.cps.getAddresses().entrySet()) { + System.out.println("---------------is system queried----------------" + entry.getKey()); switch (entry.getKey()){ case "cpsCore": cpsCore = new CPSCoreInterfaceScoreClient(chain.getEndpointURL(), chain.networkId, wallet, @@ -71,6 +73,16 @@ private void init(){ } } + public Map getContractAddresses() { + if (addressMap == null) { + addressMap = this.cps.getAddresses().entrySet() + .stream() + .collect(Collectors.toMap(Entry::getKey, + entry -> score.Address.fromString(entry.getValue().toString()))); + } + return addressMap; + } + public score.Address getAddress() { return score.Address.fromString(wallet.getAddress().toString()); } diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/Environment.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/Environment.java index b779acb5..b49ae961 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/Environment.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/Environment.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import community.icon.cps.score.lib.interfaces.SystemInterface; +import community.icon.cps.score.test.integration.scores.SystemInterface; import foundation.icon.icx.KeyWallet; import foundation.icon.icx.Wallet; import foundation.icon.icx.crypto.KeystoreException; diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/SystemInterface.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/SystemInterface.java index f0fd1455..7645ce44 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/SystemInterface.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/SystemInterface.java @@ -36,12 +36,15 @@ void registerPRep(String name, String email, String country, String city, String void setDelegation(Delegation[] delegations); void setBond(Bond[] bonds); + Map getBonderList(Address address); void setBonderList(Address[] bonderList); void setStake(BigInteger value); Map getPRep(Address address); + + Map getPRepTerm(); void initCommissionRate(BigInteger maxChangeRate,BigInteger maxRate,BigInteger rate); void setCommissionRate(BigInteger rate); From 76337509cf70aa5c3d914237d577472d76c7a9da Mon Sep 17 00:00:00 2001 From: naneey Date: Thu, 14 Mar 2024 14:10:48 +0545 Subject: [PATCH 13/64] chore: register prep int test added --- .../cps/integration/CPSCoreIntegration.java | 136 ++++++++++++++++++ .../integration/scores/CPSCoreInterface.java | 3 + 2 files changed, 139 insertions(+) diff --git a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java index 84de63cc..21a1ea4e 100644 --- a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java +++ b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java @@ -3,13 +3,35 @@ import community.icon.cps.score.test.integration.CPS; import community.icon.cps.score.test.integration.CPSClient; import community.icon.cps.score.test.integration.ScoreIntegrationTest; +import community.icon.cps.score.test.integration.config.BaseConfig; +import foundation.icon.score.client.RevertedException; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import score.Address; + +import static community.icon.cps.score.cpscore.utils.Constants.*; +import static community.icon.cps.score.test.AssertRevertedException.assertReverted; +import static community.icon.cps.score.test.AssertRevertedException.assertUserRevert; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.math.BigInteger; +import java.util.*; + +import static community.icon.cps.score.test.integration.Environment.preps; +import static community.icon.cps.score.test.integration.Environment.SYSTEM_INTERFACE; +import static community.icon.cps.score.test.integration.Environment.godClient; +import community.icon.cps.score.test.integration.scores.SystemInterfaceScoreClient; +import score.UserRevertException; public class CPSCoreIntegration implements ScoreIntegrationTest { private static CPSClient ownerClient; + private static CPSClient readerClient; + static Set> prepSet = preps.entrySet(); + + + public static Map cpsClients = new HashMap<>(); @BeforeAll public static void setup() throws Exception{ String contracts = "conf/contracts.json"; @@ -17,6 +39,15 @@ public static void setup() throws Exception{ cps.setupCPS(); ownerClient = cps.defaultClient(); + readerClient = cps.testClient(); + BaseConfig config = new BaseConfig(ownerClient); + config.call(); + + for (int i = 0; i < 7; i++) { + String privKey = prepSet.toArray()[i].toString().substring(43); + cpsClients.put(i,cps.customClient(privKey)); + + } } @@ -25,4 +56,109 @@ public static void setup() throws Exception{ public void name(){ ownerClient.cpsCore.name(); } + + + + @Test + @Order(1) + public void registerPrep(){ + + // expected Prep address + List expectedPrepAddress = new ArrayList<>(cpsClients.size()); + for (CPSClient prepClient:cpsClients.values()){ + prepClient.cpsCore.registerPrep(); + expectedPrepAddress.add(prepClient.getAddress().toString()); + + } + + // actual prep address + List> preps = ownerClient.cpsCore.getPReps(); + List actualPrepAddress = new ArrayList<>(preps.size()); + for (Map prep : preps) { + actualPrepAddress.add((String) prep.get("address")); + } + + assertEquals(expectedPrepAddress,actualPrepAddress); +// SYSTEM_INTERFACE = new SystemInterfaceScoreClient(godClient); +// System.out.println(SYSTEM_INTERFACE.getPRepTerm()); + } + + @Test + @Order(2) + public void registerPrepExceptions(){ + + // readerClient tries to be registered as prep + assertUserRevert(new UserRevertException(TAG+": Not a P-Rep"), + () -> readerClient.cpsCore.registerPrep(),null); + + // registered prep registers again + CPSClient registeredPrep = cpsClients.get(0); + + assertUserRevert(new UserRevertException(TAG+": P-Rep is already registered."), + () -> registeredPrep.cpsCore.registerPrep(),null); + + // TODO: handle deny list + } + + @Test + @Order(2) + public void unregisterPrep(){ + CPSClient prep1 = cpsClients.get(0); + prep1.cpsCore.unregisterPrep(); + + // expected unregistered prep status + Map expectedPrepData = unregisteredPrepData(); + + Map actualPrepData = loginPrep(prep1.getAddress()); + assertEquals(expectedPrepData,actualPrepData); + + prep1.cpsCore.registerPrep(); + } + + + @Test + @Order(3) + public void loginAsPrep(){ + // query period status + Map periodStatus = getPeriodStatus(); + assertEquals(periodStatus.get(PERIOD_NAME),"Application Period"); + + CPSClient prep1 = cpsClients.get(0); + // expected prep1 status + Map expectedPrepData = votingPrepData(); + + Map actualPrepData = loginPrep(prep1.getAddress()); + assertEquals(expectedPrepData,actualPrepData); + } + + private Map getPeriodStatus(){ + return readerClient.cpsCore.getPeriodStatus(); + } + + private Map loginPrep(Address prepAddress){ + return readerClient.cpsCore.loginPrep(prepAddress); + } + + private Map unregisteredPrepData(){ + return Map.of(IS_PREP, BigInteger.ONE, + IS_REGISTERED, BigInteger.ZERO, + PAY_PENALTY, BigInteger.ZERO, + VOTING_PREP, BigInteger.ZERO); + } + + private Map votingPrepData(){ + return Map.of(IS_PREP, BigInteger.ONE, + IS_REGISTERED, BigInteger.ONE, + PAY_PENALTY, BigInteger.ZERO, + VOTING_PREP, BigInteger.ONE); + } + + private Map registerPrepData(){ + return Map.of(IS_PREP, BigInteger.ONE, + IS_REGISTERED, BigInteger.ONE, + PAY_PENALTY, BigInteger.ZERO, + VOTING_PREP, BigInteger.ZERO); + } + + } diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java index 2438b81e..7666ddea 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java @@ -248,6 +248,9 @@ public static class MilestoneVoteAttributes { @External void claimSponsorBond(); + @External + void setPeriod(BigInteger applicationPeriod); + @External void setSwapCount(int value); From e19c8f2aab94fe9eec288d433f40426302beb07a Mon Sep 17 00:00:00 2001 From: naneey Date: Thu, 14 Mar 2024 19:02:39 +0545 Subject: [PATCH 14/64] chore: configured assertions --- .../cps/integration/CPSCoreIntegration.java | 44 ++++++++- .../score/test/AssertRevertedException.java | 96 +++++++++++++++++++ .../test/integration/config/BaseConfig.java | 38 ++++++++ 3 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 test-lib/src/main/java/community/icon/cps/score/test/AssertRevertedException.java create mode 100644 test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java diff --git a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java index 21a1ea4e..7294019a 100644 --- a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java +++ b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java @@ -1,5 +1,6 @@ package community.icon.cps.integration; +import community.icon.cps.score.lib.interfaces.CPSCoreInterface; import community.icon.cps.score.test.integration.CPS; import community.icon.cps.score.test.integration.CPSClient; import community.icon.cps.score.test.integration.ScoreIntegrationTest; @@ -27,9 +28,12 @@ public class CPSCoreIntegration implements ScoreIntegrationTest { private static CPSClient ownerClient; + private static CPSClient testClient; private static CPSClient readerClient; static Set> prepSet = preps.entrySet(); + private BigInteger ICX = BigInteger.valueOf(10).pow(18); + public static Map cpsClients = new HashMap<>(); @BeforeAll @@ -39,7 +43,8 @@ public static void setup() throws Exception{ cps.setupCPS(); ownerClient = cps.defaultClient(); - readerClient = cps.testClient(); + readerClient = cps.newClient(BigInteger.TEN.pow(24)); + testClient = cps.testClient(); BaseConfig config = new BaseConfig(ownerClient); config.call(); @@ -131,6 +136,43 @@ public void loginAsPrep(){ assertEquals(expectedPrepData,actualPrepData); } + @Test + @Order(4) + public void submitProposal(){ + CPSClient prep1 = cpsClients.get(0); + CPSCoreInterface.ProposalAttributes proposalAttributes = new CPSCoreInterface.ProposalAttributes(); + + proposalAttributes.ipfs_hash = "Test_Proposal_1"; + proposalAttributes.project_title = "Proposal_1"; + proposalAttributes.project_duration = 3; + proposalAttributes.total_budget = BigInteger.valueOf(100).multiply(ICX); + proposalAttributes.token = bnUSD; + proposalAttributes.sponsor_address = prep1.getAddress(); + proposalAttributes.ipfs_link ="https://proposal_1"; + proposalAttributes.milestoneCount = 3; + proposalAttributes.isMilestone = true; + + CPSCoreInterface.MilestonesAttributes milestonesAttributes1 = new CPSCoreInterface.MilestonesAttributes(); + milestonesAttributes1.completionPeriod = 1; + milestonesAttributes1.budget = BigInteger.valueOf(30).multiply(ICX); + milestonesAttributes1.id = 1; + + CPSCoreInterface.MilestonesAttributes milestonesAttributes2 = new CPSCoreInterface.MilestonesAttributes(); + milestonesAttributes2.completionPeriod = 2; + milestonesAttributes2.budget = BigInteger.valueOf(40).multiply(ICX); + milestonesAttributes2.id = 2; + + CPSCoreInterface.MilestonesAttributes milestonesAttributes3 = new CPSCoreInterface.MilestonesAttributes(); + milestonesAttributes3.completionPeriod = 3; + milestonesAttributes3.budget = BigInteger.valueOf(20).multiply(ICX); + milestonesAttributes3.id = 3; // TODO: check if same id is sent + + CPSCoreInterface.MilestonesAttributes[] milestonesAttributes =new CPSCoreInterface.MilestonesAttributes[] + {milestonesAttributes1, milestonesAttributes2,milestonesAttributes3}; + testClient.cpsCore.submitProposal(proposalAttributes,milestonesAttributes); + } + + private Map getPeriodStatus(){ return readerClient.cpsCore.getPeriodStatus(); } diff --git a/test-lib/src/main/java/community/icon/cps/score/test/AssertRevertedException.java b/test-lib/src/main/java/community/icon/cps/score/test/AssertRevertedException.java new file mode 100644 index 00000000..3a1c7c52 --- /dev/null +++ b/test-lib/src/main/java/community/icon/cps/score/test/AssertRevertedException.java @@ -0,0 +1,96 @@ +/* + * Copyright 2021 ICON Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package community.icon.cps.score.test; + + +import foundation.icon.jsonrpc.JsonrpcClient; +import foundation.icon.score.client.RevertedException; +import org.junit.jupiter.api.function.Executable; +import score.UserRevertException; +import score.UserRevertedException; + +import java.util.function.Function; + +import static org.junit.jupiter.api.Assertions.*; + +public class AssertRevertedException { + + public static RevertedException assertReverted(int expected, Executable executable) { + return assertReverted(new RevertedException(expected, ""), executable); + } + + public static RevertedException assertReverted(RevertedException expected, Executable executable) { + RevertedException e = assertThrows(RevertedException.class, executable); + assertEquals(expected.getCode(), e.getCode(), + String.format("assertReverted expected: %d, actual: %d", expected.getCode(), e.getCode())); + return e; + } + + public static UserRevertedException assertUserReverted(int expected, Executable executable) { + return assertUserReverted(expected, executable, null); + } + + public static UserRevertedException assertUserReverted(int expected, Executable executable, + Function messageSupplier) { + return assertUserReverted(new UserRevertedException(expected), executable, messageSupplier); + } + + public static UserRevertedException assertUserReverted(T expected, + Executable executable, + Function messageSupplier) { + UserRevertedException e = assertThrows(UserRevertedException.class, executable); + assertEquals(expected.getCode(), e.getCode(), messageSupplier == null ? + () -> String.format("assertUserReverted expected: %d, actual: %d", expected.getCode(), e.getCode()) : + () -> messageSupplier.apply(e)); + return e; + } + + public static UserRevertedException assertUserRevert(T expected, + Executable executable, + Function messageSupplier) { + return assertUserReverted(expected.getCode(), executable, messageSupplier == null ? + (e) -> String.format("assertUserRevertException expected:%s, actual: %s", expected, e.toString()) : + messageSupplier); + } + + public static UserRevertedException assertUserRevertedFromJsonrpcError(int expected, Executable executable, + Function messageSupplier) { + return assertUserRevertedFromJsonrpcError(new UserRevertedException(expected), executable, messageSupplier); + } + + public static UserRevertedException assertUserRevertedFromJsonrpcError(T expected, Executable executable, Function messageSupplier) { + JsonrpcClient.JsonrpcError rpcError = assertThrows(JsonrpcClient.JsonrpcError.class, executable); + //ErrorCodeScore(30000) + UserReverted(32) + assertTrue(rpcError.getCode() <= -30032 && rpcError.getCode() > -31000); + UserRevertedException e = new UserRevertedException(-1 * ((int) rpcError.getCode() + 30032), + rpcError.getMessage()); + assertEquals(expected.getCode(), e.getCode(), messageSupplier == null ? + () -> String.format("assertUserRevertedFromJsonrpcError expected: %d, actual: %d", expected.getCode() + , e.getCode()) : + () -> messageSupplier.apply(e)); + return e; + } + + public static UserRevertedException assertUserRevertFromJsonrpcError(T expected, + Executable executable, Function messageSupplier) { + return assertUserRevertedFromJsonrpcError(expected.getCode(), executable, messageSupplier == null ? + (e) -> String.format("assertUserRevertFromJsonrpcError expected:%s, actual: %s", expected, + e.toString()) : + messageSupplier); + } +} + diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java new file mode 100644 index 00000000..9dd33c70 --- /dev/null +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java @@ -0,0 +1,38 @@ +package community.icon.cps.score.test.integration.config; + +import community.icon.cps.score.test.integration.CPS; +import community.icon.cps.score.test.integration.CPSClient; +import community.icon.cps.score.test.integration.Environment; +import score.Address; + +import java.math.BigInteger; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import static community.icon.cps.score.test.integration.Environment.preps; + +public class BaseConfig { + + protected Map addressMap; + protected CPSClient cpsClient; + + public BaseConfig(CPSClient cpsClient){ + this.cpsClient = cpsClient; + this.addressMap = cpsClient.getContractAddresses(); + } + + + public void call(){ + System.out.println("--------init base setup for cps-----------"); + this.cpsClient.cpsCore.addAdmin(this.cpsClient.getAddress()); + System.out.println("--------admin set -----------"); + cpsClient.cpsCore.toggleMaintenance(); + cpsClient.cpsCore.setInitialBlock(); + + System.out.println("------setting scores in cpscore------"); + cpsClient.cpsCore.setCpsTreasuryScore(addressMap.get("cpsTreasury")); + cpsClient.cpsCore.setCpfTreasuryScore(addressMap.get("cpfTreasury")); + + } +} From 5d6cc8fbe3e2ddfa26f8d9cccc963d40f8883615 Mon Sep 17 00:00:00 2001 From: naneey Date: Mon, 18 Mar 2024 17:58:42 +0545 Subject: [PATCH 15/64] chore: bnusd and dex configured --- .../cps/integration/CPSCoreIntegration.java | 5 +- .../cps/score/test/integration/CPSClient.java | 21 +++++-- .../test/integration/config/BaseConfig.java | 11 ++++ .../integration/scores/BalancedDollar.java | 25 +++++++++ .../test/integration/scores/DummyDex.java | 56 +++++++++++++++++++ .../src/main/resources/conf/contracts.json | 17 ++++++ 6 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 test-lib/src/main/java/community/icon/cps/score/test/integration/scores/BalancedDollar.java create mode 100644 test-lib/src/main/java/community/icon/cps/score/test/integration/scores/DummyDex.java diff --git a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java index 7294019a..673047a1 100644 --- a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java +++ b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java @@ -5,14 +5,12 @@ import community.icon.cps.score.test.integration.CPSClient; import community.icon.cps.score.test.integration.ScoreIntegrationTest; import community.icon.cps.score.test.integration.config.BaseConfig; -import foundation.icon.score.client.RevertedException; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import score.Address; import static community.icon.cps.score.cpscore.utils.Constants.*; -import static community.icon.cps.score.test.AssertRevertedException.assertReverted; import static community.icon.cps.score.test.AssertRevertedException.assertUserRevert; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -169,7 +167,8 @@ public void submitProposal(){ CPSCoreInterface.MilestonesAttributes[] milestonesAttributes =new CPSCoreInterface.MilestonesAttributes[] {milestonesAttributes1, milestonesAttributes2,milestonesAttributes3}; - testClient.cpsCore.submitProposal(proposalAttributes,milestonesAttributes); + ((CPSCoreInterfaceScoreClient) testClient.cpsCore).submitProposal(BigInteger.valueOf(50).multiply(ICX),proposalAttributes,milestonesAttributes); +// testClient.cpsCore.submitProposal(proposalAttributes,milestonesAttributes); } diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java index 8c73c790..396a412c 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java @@ -1,13 +1,12 @@ package community.icon.cps.score.test.integration; +import community.icon.cps.score.test.integration.scores.*; import community.icon.cps.score.test.integration.scores.SystemInterfaceScoreClient; -import community.icon.cps.score.test.integration.scores.CPFTreasuryInterface; import community.icon.cps.score.test.integration.scores.CPFTreasuryInterfaceScoreClient; -import community.icon.cps.score.test.integration.scores.CPSCoreInterface; import community.icon.cps.score.test.integration.scores.CPSCoreInterfaceScoreClient; -import community.icon.cps.score.test.integration.scores.CPSTreasuryInterface; import community.icon.cps.score.test.integration.scores.CPSTreasuryInterfaceScoreClient; -import community.icon.cps.score.test.integration.scores.SystemInterface; +import community.icon.cps.score.test.integration.scores.DummyDexScoreClient; +import community.icon.cps.score.test.integration.scores.BalancedDollarScoreClient; import foundation.icon.icx.KeyWallet; import foundation.icon.jsonrpc.Address; @@ -35,6 +34,12 @@ public class CPSClient { @ScoreClient public CPSCoreInterface cpsCore; + @ScoreClient + public BalancedDollar bnUSD; + + @ScoreClient + public DummyDex dex; + @ScoreClient public SystemInterface systemScore; @@ -61,6 +66,14 @@ private void init(){ cpfTreasury = new CPFTreasuryInterfaceScoreClient(chain.getEndpointURL(), chain.networkId, wallet, entry.getValue()); break; + case "bnUSD": + bnUSD = new BalancedDollarScoreClient(chain.getEndpointURL(), chain.networkId, wallet, + entry.getValue()); + break; + case "dex": + dex = new DummyDexScoreClient(chain.getEndpointURL(), chain.networkId, wallet, + entry.getValue()); + break; case "systemScore": systemScore = new SystemInterfaceScoreClient(chain.getEndpointURL(), chain.networkId, wallet, entry.getValue()); diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java index 9dd33c70..4124ac7e 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java @@ -17,6 +17,7 @@ public class BaseConfig { protected Map addressMap; protected CPSClient cpsClient; + public static final BigInteger EXA = BigInteger.valueOf(1000000000000000000L); public BaseConfig(CPSClient cpsClient){ this.cpsClient = cpsClient; this.addressMap = cpsClient.getContractAddresses(); @@ -34,5 +35,15 @@ public void call(){ cpsClient.cpsCore.setCpsTreasuryScore(addressMap.get("cpsTreasury")); cpsClient.cpsCore.setCpfTreasuryScore(addressMap.get("cpfTreasury")); + System.out.println("--------setting score in cpf treasury -------"); + cpsClient.cpfTreasury.setBnUSDScore(addressMap.get("bnUSD")); + cpsClient.cpfTreasury.setDexScore(addressMap.get("dex")); + + System.out.println("------setting funds--------"); + cpsClient.cpfTreasury.setMaximumTreasuryFundBnusd(BigInteger.valueOf(1000).multiply(EXA)); + this.cpsClient.bnUSD.setMinter(this.cpsClient.getAddress()); + this.cpsClient.bnUSD.mint(BigInteger.valueOf(1000000),new byte[0] ); + System.out.println("------system score------- " + addressMap.get("systemScore")); + } } diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/BalancedDollar.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/BalancedDollar.java new file mode 100644 index 00000000..991f15c6 --- /dev/null +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/BalancedDollar.java @@ -0,0 +1,25 @@ +package community.icon.cps.score.test.integration.scores; + +import score.Address; +import score.annotation.External; +import score.annotation.Optional; + +import java.math.BigInteger; + +public interface BalancedDollar { + + @External(readonly = true) + BigInteger balanceOf(Address _owner); + + @External + void mint(BigInteger _amount, @Optional byte[] _data); + + @External + void mintTo(Address _account, BigInteger _amount, @Optional byte[] _data); + + @External + void setMinter(Address _address); + + @External(readonly = true) + Address getMinter(); +} diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/DummyDex.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/DummyDex.java new file mode 100644 index 00000000..4de1ce77 --- /dev/null +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/DummyDex.java @@ -0,0 +1,56 @@ +package community.icon.cps.score.test.integration.scores; + +import score.Address; +import score.annotation.External; +import score.annotation.Optional; + +import java.math.BigInteger; +import java.util.Map; + +public interface DummyDex { + + void mint(BigInteger _id, BigInteger _supply); + + void mintTo(BigInteger _id, Address _account, BigInteger _supply); + + Map getPoolStats(BigInteger _id); + + BigInteger getPriceByName(String _name); + + BigInteger lookupPid(String _name); + + BigInteger getBalnPrice(); + + @External(readonly = true) + BigInteger getPrice(BigInteger _id); + + void transfer(Address _to, BigInteger _value, BigInteger _id, @Optional byte[] _data); + BigInteger balanceOf(Address _owner, BigInteger _id); + + + BigInteger[] balanceOfBatch(Address[] _owners, BigInteger[] _ids); + + String tokenURI(BigInteger _id); + + void transferFrom(Address _from, Address _to, BigInteger _id, BigInteger _value, @Optional byte[] _data); + + void transferFromBatch(Address _from, Address _to, BigInteger[] _ids, BigInteger[] _values, @Optional byte[] _data); + + + void setApprovalForAll(Address _operator, boolean _approved); + + + boolean isApprovedForAll(Address _owner, Address _operator); + + + + void TransferSingle(Address _operator, Address _from, Address _to, BigInteger _id, BigInteger _value); + + void TransferBatch(Address _operator, Address _from, Address _to, byte[] _ids, byte[] _values); + + + void ApprovalForAll(Address _owner, Address _operator, boolean _approved); + + + void URI(BigInteger _id, String _value); +} diff --git a/test-lib/src/main/resources/conf/contracts.json b/test-lib/src/main/resources/conf/contracts.json index 940c5ee1..81234bdf 100644 --- a/test-lib/src/main/resources/conf/contracts.json +++ b/test-lib/src/main/resources/conf/contracts.json @@ -7,6 +7,23 @@ }, "order":1.0 }, + { + "name": "bnUSD", + "contract": "bnUSD", + "params": { + "name": "Balanced Stable Coin", + "symbol": "bnUSD", + "decimals": 18 + }, + "order": 1.0 + }, + { + "name": "dex", + "contract": "DEX", + "params": { + }, + "order": 1.0 + }, { "name": "cpsTreasury", "contract": "CPSTreasury", From b9bd389a202a72c9646cd6f9cdde415ca73b0207 Mon Sep 17 00:00:00 2001 From: naneey Date: Tue, 19 Mar 2024 11:30:08 +0545 Subject: [PATCH 16/64] chore: bnusd and dex configured --- .../cps/integration/CPSCoreIntegration.java | 3 +- build.gradle | 5 ++-- .../icon/cps/score/test/integration/CPS.java | 30 +++++++++---------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java index 673047a1..c9e7062b 100644 --- a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java +++ b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java @@ -1,6 +1,7 @@ package community.icon.cps.integration; import community.icon.cps.score.lib.interfaces.CPSCoreInterface; +import community.icon.cps.score.test.integration.scores.CPSCoreInterfaceScoreClient; import community.icon.cps.score.test.integration.CPS; import community.icon.cps.score.test.integration.CPSClient; import community.icon.cps.score.test.integration.ScoreIntegrationTest; @@ -143,7 +144,7 @@ public void submitProposal(){ proposalAttributes.ipfs_hash = "Test_Proposal_1"; proposalAttributes.project_title = "Proposal_1"; proposalAttributes.project_duration = 3; - proposalAttributes.total_budget = BigInteger.valueOf(100).multiply(ICX); + proposalAttributes.total_budget = BigInteger.valueOf(100); proposalAttributes.token = bnUSD; proposalAttributes.sponsor_address = prep1.getAddress(); proposalAttributes.ipfs_link ="https://proposal_1"; diff --git a/build.gradle b/build.gradle index ddd57cc3..ccff86a8 100644 --- a/build.gradle +++ b/build.gradle @@ -77,10 +77,7 @@ subprojects { testImplementation "org.junit.jupiter:junit-jupiter:$junitVersion" testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion" testImplementation "org.mockito:mockito-core:$mockitoVersion" -// testImplementation "foundation.icon:icon-sdk:$iconsdkVersion" - testImplementation group: "org.json", name: "json", version: "20211205" - // TODO: need to find the import for WALLET in foundation.icon.icx } @@ -116,6 +113,8 @@ subprojects { //TODO: add the dummy jar files here required for cps // scoreIntegrationTest.put('env.props', new File(project(':test-lib').projectDir, 'conf/env.props')) + scoreIntegrationTest.put('bnUSD', "https://raw.githubusercontent.com/naneey/cps-scores/main/dummy/IRC2Token.jar") + scoreIntegrationTest.put('DEX', "https://raw.githubusercontent.com/openmoneymarket/omm-scores/master/dummy/dex.jar") afterEvaluate { project -> scoreIntegrationTest.put(project.name, project.getTasks().getByName("optimizedJar").outputJarName) diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java index 8f1cae0d..c2226d55 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java @@ -55,9 +55,9 @@ public void setupCPS() throws Exception { } private void decentralizeChain(){ - if (isPRepRegistered()) { - return; - } +// if (isPRepRegistered()) { +// return; +// } setStake(); setDelegationOfPreps(); setBonderList(); @@ -89,9 +89,9 @@ public void setGodStake(){ private void setStake(){ int count = 0; for (Map.Entry prep : preps.entrySet()) { -// if (prep.getKey().equals(Address.fromString("hxb6b5791be0b5ef67063b3c10b840fb81514db2fd"))){ -// continue; -// } + if (prep.getKey().equals(Address.fromString("hxb6b5791be0b5ef67063b3c10b840fb81514db2fd"))){ + continue; + } if (count < 7) { KeyWallet wallet = KeyWallet.load(new Bytes(prep.getValue())); var client = new DefaultScoreClient( @@ -114,9 +114,9 @@ private void setStake(){ public void setDelegationOfPreps(){ int count = 0; for (Map.Entry prep : preps.entrySet()) { -// if (prep.getKey().equals(Address.fromString("hxb6b5791be0b5ef67063b3c10b840fb81514db2fd"))){ -// continue; -// } + if (prep.getKey().equals(Address.fromString("hxb6b5791be0b5ef67063b3c10b840fb81514db2fd"))){ + continue; + } if (count < 7) { KeyWallet wallet = KeyWallet.load(new Bytes(prep.getValue())); SystemInterface.Delegation[] delegations = new SystemInterface.Delegation[1]; @@ -145,9 +145,9 @@ public void setDelegationOfPreps(){ public void setBonderList(){ int count = 0; for (Map.Entry prep : preps.entrySet()) { -// if (prep.getKey().equals(Address.fromString("hxb6b5791be0b5ef67063b3c10b840fb81514db2fd"))){ -// continue; -// } + if (prep.getKey().equals(Address.fromString("hxb6b5791be0b5ef67063b3c10b840fb81514db2fd"))){ + continue; + } if (count < 7) { KeyWallet wallet = KeyWallet.load(new Bytes(prep.getValue())); score.Address[] bonderList = new score.Address[1]; @@ -178,9 +178,9 @@ public void setBonderList(){ public void setBondsofPreps(){ int count = 0; for (Map.Entry prep : preps.entrySet()) { -// if (prep.getKey().equals(Address.fromString("hxb6b5791be0b5ef67063b3c10b840fb81514db2fd"))){ -// continue; -// } + if (prep.getKey().equals(Address.fromString("hxb6b5791be0b5ef67063b3c10b840fb81514db2fd"))){ + continue; + } if (count < 7){ KeyWallet wallet = KeyWallet.load(new Bytes(prep.getValue())); SystemInterface.Bond[] bond = new SystemInterface.Bond[1]; From bb2907430a6c6b70747a58b14489288469adb190 Mon Sep 17 00:00:00 2001 From: naneey Date: Tue, 19 Mar 2024 11:32:08 +0545 Subject: [PATCH 17/64] chore: git file updated --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 6151cd4b..68f9b533 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,6 @@ gradle.properties .classpath .settings **/bin/ + +*.ipynb +*.csv \ No newline at end of file From 5a0124056ead7020c65ad8005095cdc821563009 Mon Sep 17 00:00:00 2001 From: naneey Date: Tue, 19 Mar 2024 21:31:39 +0545 Subject: [PATCH 18/64] chore: oracle and router setup --- build.gradle | 10 ++++++--- .../cps/score/test/integration/CPSClient.java | 16 ++++++++++++++ .../score/test/integration/scores/Oracle.java | 4 ++++ .../score/test/integration/scores/Router.java | 4 ++++ .../src/main/resources/conf/contracts.json | 21 ++++++++++++++++--- 5 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 test-lib/src/main/java/community/icon/cps/score/test/integration/scores/Oracle.java create mode 100644 test-lib/src/main/java/community/icon/cps/score/test/integration/scores/Router.java diff --git a/build.gradle b/build.gradle index ccff86a8..7e34de6a 100644 --- a/build.gradle +++ b/build.gradle @@ -112,9 +112,13 @@ subprojects { // } //TODO: add the dummy jar files here required for cps -// scoreIntegrationTest.put('env.props', new File(project(':test-lib').projectDir, 'conf/env.props')) - scoreIntegrationTest.put('bnUSD', "https://raw.githubusercontent.com/naneey/cps-scores/main/dummy/IRC2Token.jar") - scoreIntegrationTest.put('DEX', "https://raw.githubusercontent.com/openmoneymarket/omm-scores/master/dummy/dex.jar") +// scoreIntegrationTest.put('bnUSD', "https://raw.githubusercontent.com/naneey/cps-scores/main/dummy/IRC2Token.jar") + scoreIntegrationTest.put('bnUSD', "$rootProject.projectDir/dummyJarFiles/bnUSD-0.9.1-optimized.jar") + scoreIntegrationTest.put('DEX', "$rootProject.projectDir/dummyJarFiles/Dex-0.9.1-optimized.jar") + scoreIntegrationTest.put('ROUTER', "$rootProject.projectDir/dummyJarFiles/Router-0.9.1-optimized.jar") + scoreIntegrationTest.put('ORACLE', "$rootProject.projectDir/dummyJarFiles/oracle-0.9.1-optimized.jar") +// scoreIntegrationTest.put('sICX', "$rootProject.projectDir/dummyJarFiles/sICX-0.9.1-optimized.jar") +// scoreIntegrationTest.put('DEX', "https://raw.githubusercontent.com/openmoneymarket/omm-scores/master/dummy/dex.jar") afterEvaluate { project -> scoreIntegrationTest.put(project.name, project.getTasks().getByName("optimizedJar").outputJarName) diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java index 396a412c..7742f8fd 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java @@ -7,6 +7,8 @@ import community.icon.cps.score.test.integration.scores.CPSTreasuryInterfaceScoreClient; import community.icon.cps.score.test.integration.scores.DummyDexScoreClient; import community.icon.cps.score.test.integration.scores.BalancedDollarScoreClient; +import community.icon.cps.score.test.integration.scores.OracleScoreClient; +import community.icon.cps.score.test.integration.scores.RouterScoreClient; import foundation.icon.icx.KeyWallet; import foundation.icon.jsonrpc.Address; @@ -40,6 +42,12 @@ public class CPSClient { @ScoreClient public DummyDex dex; + @ScoreClient + public Router router; + + @ScoreClient + public Oracle oracle; + @ScoreClient public SystemInterface systemScore; @@ -74,6 +82,14 @@ private void init(){ dex = new DummyDexScoreClient(chain.getEndpointURL(), chain.networkId, wallet, entry.getValue()); break; + case "router": + router = new RouterScoreClient(chain.getEndpointURL(), chain.networkId, wallet, + entry.getValue()); + break; + case "oracle": + oracle = new OracleScoreClient(chain.getEndpointURL(), chain.networkId, wallet, + entry.getValue()); + break; case "systemScore": systemScore = new SystemInterfaceScoreClient(chain.getEndpointURL(), chain.networkId, wallet, entry.getValue()); diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/Oracle.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/Oracle.java new file mode 100644 index 00000000..1063ead4 --- /dev/null +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/Oracle.java @@ -0,0 +1,4 @@ +package community.icon.cps.score.test.integration.scores; + +public interface Oracle { +} diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/Router.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/Router.java new file mode 100644 index 00000000..b75b9432 --- /dev/null +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/Router.java @@ -0,0 +1,4 @@ +package community.icon.cps.score.test.integration.scores; + +public interface Router { +} diff --git a/test-lib/src/main/resources/conf/contracts.json b/test-lib/src/main/resources/conf/contracts.json index 81234bdf..befd7e36 100644 --- a/test-lib/src/main/resources/conf/contracts.json +++ b/test-lib/src/main/resources/conf/contracts.json @@ -11,9 +11,10 @@ "name": "bnUSD", "contract": "bnUSD", "params": { - "name": "Balanced Stable Coin", - "symbol": "bnUSD", - "decimals": 18 + "_name": "Balanced Stable Coin", + "_symbol": "bnUSD", + "_decimals": 18, + "_initialSupply": 100000000000000000000 }, "order": 1.0 }, @@ -24,6 +25,20 @@ }, "order": 1.0 }, + { + "name": "router", + "contract": "ROUTER", + "params": { + }, + "order": 1.0 + }, + { + "name": "oracle", + "contract": "ORACLE", + "params": { + }, + "order": 1.0 + }, { "name": "cpsTreasury", "contract": "CPSTreasury", From 969482a421fe192f9d160a1021825a79b7688d7a Mon Sep 17 00:00:00 2001 From: naneey Date: Tue, 19 Mar 2024 21:34:27 +0545 Subject: [PATCH 19/64] chore: minted to cpf contract --- .../icon/cps/score/test/integration/config/BaseConfig.java | 4 ++-- .../cps/score/test/integration/scores/BalancedDollar.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java index 4124ac7e..44258bdc 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java @@ -41,8 +41,8 @@ public void call(){ System.out.println("------setting funds--------"); cpsClient.cpfTreasury.setMaximumTreasuryFundBnusd(BigInteger.valueOf(1000).multiply(EXA)); - this.cpsClient.bnUSD.setMinter(this.cpsClient.getAddress()); - this.cpsClient.bnUSD.mint(BigInteger.valueOf(1000000),new byte[0] ); +// this.cpsClient.bnUSD.setMinter(this.cpsClient.getAddress()); + this.cpsClient.bnUSD.mintTo(addressMap.get("cpfTreasury"),BigInteger.valueOf(1000000) ); System.out.println("------system score------- " + addressMap.get("systemScore")); } diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/BalancedDollar.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/BalancedDollar.java index 991f15c6..6530a8c1 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/BalancedDollar.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/BalancedDollar.java @@ -15,7 +15,7 @@ public interface BalancedDollar { void mint(BigInteger _amount, @Optional byte[] _data); @External - void mintTo(Address _account, BigInteger _amount, @Optional byte[] _data); + void mintTo(Address to, BigInteger amount); @External void setMinter(Address _address); From bcfa046617239ffdb991744ec0c662929c305c02 Mon Sep 17 00:00:00 2001 From: naneey Date: Thu, 21 Mar 2024 09:53:36 +0545 Subject: [PATCH 20/64] chore: sicx setup complete --- build.gradle | 4 +-- .../cps/score/test/integration/CPSClient.java | 9 +++++++ .../score/test/integration/ScoreDeployer.java | 4 ++- .../test/integration/config/BaseConfig.java | 25 +++++++++++++++---- .../integration/scores/BalancedDollar.java | 4 +++ .../score/test/integration/scores/sICX.java | 4 +++ .../src/main/resources/conf/contracts.json | 11 ++++++++ 7 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 test-lib/src/main/java/community/icon/cps/score/test/integration/scores/sICX.java diff --git a/build.gradle b/build.gradle index 7e34de6a..2e780642 100644 --- a/build.gradle +++ b/build.gradle @@ -111,14 +111,12 @@ subprojects { // useJUnitPlatform() // } - //TODO: add the dummy jar files here required for cps // scoreIntegrationTest.put('bnUSD', "https://raw.githubusercontent.com/naneey/cps-scores/main/dummy/IRC2Token.jar") scoreIntegrationTest.put('bnUSD', "$rootProject.projectDir/dummyJarFiles/bnUSD-0.9.1-optimized.jar") scoreIntegrationTest.put('DEX', "$rootProject.projectDir/dummyJarFiles/Dex-0.9.1-optimized.jar") scoreIntegrationTest.put('ROUTER', "$rootProject.projectDir/dummyJarFiles/Router-0.9.1-optimized.jar") scoreIntegrationTest.put('ORACLE', "$rootProject.projectDir/dummyJarFiles/oracle-0.9.1-optimized.jar") -// scoreIntegrationTest.put('sICX', "$rootProject.projectDir/dummyJarFiles/sICX-0.9.1-optimized.jar") -// scoreIntegrationTest.put('DEX', "https://raw.githubusercontent.com/openmoneymarket/omm-scores/master/dummy/dex.jar") + scoreIntegrationTest.put('sICX', "$rootProject.projectDir/dummyJarFiles/Sicx-0.0.1-optimized.jar") afterEvaluate { project -> scoreIntegrationTest.put(project.name, project.getTasks().getByName("optimizedJar").outputJarName) diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java index 7742f8fd..7a8b24f2 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java @@ -48,6 +48,9 @@ public class CPSClient { @ScoreClient public Oracle oracle; + @ScoreClient + public sICX sICX; + @ScoreClient public SystemInterface systemScore; @@ -90,10 +93,16 @@ private void init(){ oracle = new OracleScoreClient(chain.getEndpointURL(), chain.networkId, wallet, entry.getValue()); break; + case "sICX": + sICX = new sICXScoreClient(chain.getEndpointURL(), chain.networkId, wallet, + entry.getValue()); + break; case "systemScore": systemScore = new SystemInterfaceScoreClient(chain.getEndpointURL(), chain.networkId, wallet, entry.getValue()); break; + case "owner": + break; default: throw new NoSuchElementException(entry.getKey() + " score not found!!"); diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreDeployer.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreDeployer.java index 52fa4edc..618b0c43 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreDeployer.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreDeployer.java @@ -35,7 +35,7 @@ public Map deployContracts() throws IOException, InterruptedExc Map addresses = new HashMap<>(); -// addresses.put("owner", foundation.icon.jsonrpc.Address.of(cps.owner)); + addresses.put("owner", foundation.icon.jsonrpc.Address.of(cps.owner)); for (Map.Entry> entry : scores.entrySet()) { Map> result = new HashMap<>(); @@ -44,6 +44,8 @@ public Map deployContracts() throws IOException, InterruptedExc System.out.println("deploying contract " + score.getName() + " :: " + score.getPath()); Thread.sleep(200); Map addressParams = score.getAddressParams(); + System.out.println("the adress params " + addressParams.entrySet()); + System.out.println("the adress params " + addresses.get("owner")); for (Map.Entry params : addressParams.entrySet()) { String key = params.getKey(); diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java index 44258bdc..1ef63f4e 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java @@ -26,23 +26,38 @@ public BaseConfig(CPSClient cpsClient){ public void call(){ System.out.println("--------init base setup for cps-----------"); - this.cpsClient.cpsCore.addAdmin(this.cpsClient.getAddress()); System.out.println("--------admin set -----------"); - cpsClient.cpsCore.toggleMaintenance(); - cpsClient.cpsCore.setInitialBlock(); + this.cpsClient.cpsCore.addAdmin(this.cpsClient.getAddress()); + System.out.println("------setting scores in cpscore------"); cpsClient.cpsCore.setCpsTreasuryScore(addressMap.get("cpsTreasury")); cpsClient.cpsCore.setCpfTreasuryScore(addressMap.get("cpfTreasury")); + cpsClient.cpsCore.setBnusdScore(addressMap.get("bnUSD")); + + System.out.println("------setting scores in cps treasury-----"); + cpsClient.cpsTreasury.setCpfTreasuryScore(addressMap.get("cpfTreasury")); + cpsClient.cpsTreasury.setBnUSDScore(addressMap.get("bnUSD")); System.out.println("--------setting score in cpf treasury -------"); + cpsClient.cpfTreasury.setCpsTreasuryScore(addressMap.get("cpsTreasury")); cpsClient.cpfTreasury.setBnUSDScore(addressMap.get("bnUSD")); cpsClient.cpfTreasury.setDexScore(addressMap.get("dex")); + cpsClient.cpfTreasury.setOracleAddress(addressMap.get("oracle")); + cpsClient.cpfTreasury.setRouterScore(addressMap.get("router")); + cpsClient.cpfTreasury.setSicxScore(addressMap.get("sICX")); System.out.println("------setting funds--------"); - cpsClient.cpfTreasury.setMaximumTreasuryFundBnusd(BigInteger.valueOf(1000).multiply(EXA)); + cpsClient.cpfTreasury.setMaximumTreasuryFundIcx(BigInteger.valueOf(1000).multiply(EXA)); + cpsClient.cpfTreasury.setMaximumTreasuryFundBnusd(BigInteger.valueOf(10000).multiply(EXA)); // this.cpsClient.bnUSD.setMinter(this.cpsClient.getAddress()); - this.cpsClient.bnUSD.mintTo(addressMap.get("cpfTreasury"),BigInteger.valueOf(1000000) ); + cpsClient.bnUSD.mintTo(addressMap.get("cpfTreasury"),BigInteger.valueOf(5000).multiply(EXA) ); + cpsClient.cpfTreasury.toggleSwapFlag(); + + cpsClient.cpsCore.toggleMaintenance(); + cpsClient.cpsCore.setInitialBlock(); + + System.out.println("------system score------- " + addressMap.get("systemScore")); } diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/BalancedDollar.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/BalancedDollar.java index 6530a8c1..e2af737a 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/BalancedDollar.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/BalancedDollar.java @@ -22,4 +22,8 @@ public interface BalancedDollar { @External(readonly = true) Address getMinter(); + + @External + void transfer(Address _to, BigInteger _value, @Optional byte[] _data); + } diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/sICX.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/sICX.java new file mode 100644 index 00000000..0b5296fb --- /dev/null +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/sICX.java @@ -0,0 +1,4 @@ +package community.icon.cps.score.test.integration.scores; + +public interface sICX { +} diff --git a/test-lib/src/main/resources/conf/contracts.json b/test-lib/src/main/resources/conf/contracts.json index befd7e36..1312f531 100644 --- a/test-lib/src/main/resources/conf/contracts.json +++ b/test-lib/src/main/resources/conf/contracts.json @@ -3,6 +3,7 @@ "name": "cpsCore", "contract": "CPSCore", "params": { + "bondValue": 15, "applicationPeriod": "20" }, "order":1.0 @@ -58,5 +59,15 @@ "cpsScore": "cpsCore" }, "order":2.0 + }, + { + "name": "sICX", + "contract": "sICX", + "params": { + }, + "addressParams": { + "_admin": "owner" + }, + "order": 2.0 } ] \ No newline at end of file From bf644c6319abe8ee6210688b50cf0dfe2f047ce8 Mon Sep 17 00:00:00 2001 From: naneey Date: Thu, 21 Mar 2024 09:54:33 +0545 Subject: [PATCH 21/64] chore: happy flow developed in test --- .../cps/integration/CPSCoreIntegration.java | 200 +++++++++++++++++- .../lib/interfaces/CPSCoreInterface.java | 7 +- .../integration/scores/CPSCoreInterface.java | 15 +- 3 files changed, 215 insertions(+), 7 deletions(-) diff --git a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java index c9e7062b..5dbd1584 100644 --- a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java +++ b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java @@ -1,6 +1,8 @@ package community.icon.cps.integration; +import com.eclipsesource.json.JsonObject; import community.icon.cps.score.lib.interfaces.CPSCoreInterface; +import community.icon.cps.score.lib.interfaces.CPSCoreInterface.MilestoneVoteAttributes; import community.icon.cps.score.test.integration.scores.CPSCoreInterfaceScoreClient; import community.icon.cps.score.test.integration.CPS; import community.icon.cps.score.test.integration.CPSClient; @@ -23,6 +25,7 @@ import static community.icon.cps.score.test.integration.Environment.godClient; import community.icon.cps.score.test.integration.scores.SystemInterfaceScoreClient; import score.UserRevertException; +import score.annotation.Optional; public class CPSCoreIntegration implements ScoreIntegrationTest { @@ -31,9 +34,9 @@ public class CPSCoreIntegration implements ScoreIntegrationTest { private static CPSClient readerClient; static Set> prepSet = preps.entrySet(); - private BigInteger ICX = BigInteger.valueOf(10).pow(18); - + private final BigInteger ICX = BigInteger.valueOf(10).pow(18); + private static Map addressMap; public static Map cpsClients = new HashMap<>(); @BeforeAll public static void setup() throws Exception{ @@ -41,6 +44,7 @@ public static void setup() throws Exception{ CPS cps = new CPS(contracts); cps.setupCPS(); + addressMap = cps.getAddresses(); ownerClient = cps.defaultClient(); readerClient = cps.newClient(BigInteger.TEN.pow(24)); testClient = cps.testClient(); @@ -169,7 +173,197 @@ public void submitProposal(){ CPSCoreInterface.MilestonesAttributes[] milestonesAttributes =new CPSCoreInterface.MilestonesAttributes[] {milestonesAttributes1, milestonesAttributes2,milestonesAttributes3}; ((CPSCoreInterfaceScoreClient) testClient.cpsCore).submitProposal(BigInteger.valueOf(50).multiply(ICX),proposalAttributes,milestonesAttributes); -// testClient.cpsCore.submitProposal(proposalAttributes,milestonesAttributes); + + List proposalsIpfs = readerClient.cpsCore.getProposalsKeysByStatus(SPONSOR_PENDING); + assertEquals(proposalsIpfs.size(),1); + assertEquals(proposalsIpfs.get(0),proposalAttributes.ipfs_hash); + + verifyProposalDetails(proposalAttributes); + } + + private void verifyProposalDetails(CPSCoreInterface.ProposalAttributes expectedDetails){ + Map actualDetails = getProposalDetails(expectedDetails.ipfs_hash); + assertEquals(actualDetails.get("project_title"), expectedDetails.project_title); + assertEquals(actualDetails.get("sponsor_address"), expectedDetails.sponsor_address.toString()); + assertEquals(actualDetails.get("ipfs_hash"), expectedDetails.ipfs_hash); +// assertEquals(actualDetails.get("project_duration"), expectedDetails.project_duration); +// assertEquals(actualDetails.get("milestoneCount"), expectedDetails.milestoneCount); +// assertEquals( actualDetails.get("total_budget"), expectedDetails.total_budget); + + } + + + + @Test + @Order(5) + public void submitSponsorVote(){ + CPSClient sponsorPrep = cpsClients.get(0); + + bnUSDMint(sponsorPrep.getAddress(),BigInteger.valueOf(50).multiply(ICX)); + + byte[] data = createByteArray("sponsorVote", "Test_Proposal_1",ACCEPT, + "Proposal looks good"); + BigInteger sponsorBond = BigInteger.valueOf(15).multiply(ICX); + sponsorPrep.bnUSD.transfer(addressMap.get("cpsCore"),sponsorBond,data); + + List proposalsIpfs = readerClient.cpsCore.getProposalsKeysByStatus(PENDING); + assertEquals(proposalsIpfs.size(),1); + assertEquals(proposalsIpfs.get(0),"Test_Proposal_1"); + } + + @Test() + @Order(6) + public void voteProposal(){ + // update Period + updateNextBlock(); + ownerClient.cpsCore.updatePeriod(); + + Map periodStatus = getPeriodStatus(); + assertEquals(periodStatus.get(PERIOD_NAME),"Voting Period"); + + Map proposalVote = getProposalVote("Test_Proposal_1"); + assertEquals(toInt((String)proposalVote.get("total_voters")),0); + assertEquals(toInt((String)proposalVote.get("approve_voters")),0); + assertEquals(toInt((String)proposalVote.get("reject_voters")),0); + + for (CPSClient prepClient:cpsClients.values()){ + voteByPrep(prepClient,"Test_Proposal_1",APPROVE,"Seems fruitful",false); + prepClient.cpsCore.votePriority(new String[]{"Test_Proposal_1"}); + + } + proposalVote = getProposalVote("Test_Proposal_1"); + assertEquals(toInt((String)proposalVote.get("total_voters")),7); + assertEquals(toInt((String)proposalVote.get("approve_voters")),7); + assertEquals(toInt((String)proposalVote.get("reject_voters")),0); + // TODO: approved votes does not match up +// assertEquals(toBigInt((String)proposalVote.get("approved_votes")),BigInteger.valueOf(9540000).multiply(ICX)); + } + + @Test + @Order(7) + public void submitMilestoneReport(){ + updateToApplicationPeriod(); + Map periodStatus = getPeriodStatus(); + assertEquals(periodStatus.get(PERIOD_NAME),"Application Period"); + + List proposalsIpfs = readerClient.cpsCore.getProposalsKeysByStatus(ACTIVE); + assertEquals(proposalsIpfs.size(),1); + assertEquals(proposalsIpfs.get(0),"Test_Proposal_1"); + + CPSCoreInterface.ProgressReportAttributes progressReportAttributes = new CPSCoreInterface.ProgressReportAttributes(); + progressReportAttributes.ipfs_hash = "Test_Proposal_1"; + progressReportAttributes.progress_report_title = "Report_1"; + progressReportAttributes.report_hash ="Report_Proposal_1"; + progressReportAttributes.ipfs_link = "https://proposal_1"; + progressReportAttributes.budget_adjustment = false; + progressReportAttributes.additional_budget = BigInteger.ZERO; + progressReportAttributes.additional_month = 0; + + CPSCoreInterface.MilestoneSubmission submission = new CPSCoreInterface.MilestoneSubmission(); + submission.id = 1; + submission.status = true; + CPSCoreInterface.MilestoneSubmission[] milestoneSubmissions = new CPSCoreInterface.MilestoneSubmission[]{submission}; + + testClient.cpsCore.submitProgressReport(progressReportAttributes,milestoneSubmissions); + + List> activeProposal = readerClient.cpsCore.getActiveProposals(testClient.getAddress()); + + System.out.println(activeProposal.get(0)); + } + + @Test + @Order(8) + public void voteOnMilestone(){ + updateNextBlock(); + ownerClient.cpsCore.updatePeriod(); + Map periodStatus = getPeriodStatus(); + assertEquals(periodStatus.get(PERIOD_NAME),"Voting Period"); + + MilestoneVoteAttributes[] voteAttributes = new MilestoneVoteAttributes[]{vote(1,APPROVE)}; + for (int i = 0; i < cpsClients.size(); i++) { + cpsClients.get(i).cpsCore.voteProgressReport("Report_Proposal_1","Working well", + voteAttributes,null,false); + } + } + + @Test + @Order(9) + public void submitSecondProgressReport(){ + updateToApplicationPeriod(); + Map periodStatus = getPeriodStatus(); + assertEquals(periodStatus.get(PERIOD_NAME),"Application Period"); + +// MilestoneVoteAttributes[] voteAttributes = new MilestoneVoteAttributes[]{vote(1,APPROVE)}; +// for (int i = 0; i < cpsClients.size(); i++) { +// cpsClients.get(i).cpsCore.voteProgressReport("Report_Proposal_1","Working well", +// voteAttributes,null,false); +// } + } + + private MilestoneVoteAttributes vote(int id, String vote){ + + MilestoneVoteAttributes milestoneVoteAttributes = new MilestoneVoteAttributes(); + milestoneVoteAttributes.id = id; + milestoneVoteAttributes.vote = vote; + return milestoneVoteAttributes; + } + + + + private void updateToApplicationPeriod(){ + updateNextBlock(); + ownerClient.cpsCore.updatePeriod(); + ownerClient.cpsCore.updatePeriod(); + ownerClient.cpsCore.updatePeriod(); + ownerClient.cpsCore.updatePeriod(); + } + + + private BigInteger toBigInt(String inputString) { + return new BigInteger(inputString.substring(2), 16); + } + + private Integer toInt(String inputString) { + return Integer.parseInt(inputString.substring(2)); + } + + + + private void voteByPrep(CPSClient caller, String ipfsKey, String vote, String voteReason, + @Optional boolean voteChange){ + + caller.cpsCore.voteProposal(ipfsKey,vote,voteReason,voteChange); + } + + private Map getProposalDetails(String ipfsHash){ + return readerClient.cpsCore.getProposalDetailsByHash(ipfsHash); + } + + private Map getProposalVote(String ipfsHash){ + return readerClient.cpsCore.getVoteResult(ipfsHash); + } + + private void updateNextBlock(){ + ownerClient.cpsCore.updateNextBlock(1); + } + + private byte[] createByteArray(String methodName, String ipfsHash, String vote, String voteReason) { + + JsonObject internalParameters = new JsonObject() + .add("ipfs_hash", String.valueOf(ipfsHash)) + .add("vote", String.valueOf(vote)) + .add("vote_reason", String.valueOf(voteReason)); + + + JsonObject jsonData = new JsonObject() + .add("method", methodName) + .add("params", internalParameters); + + return jsonData.toString().getBytes(); + } + + private void bnUSDMint(Address to, BigInteger amount){ + ownerClient.bnUSD.mintTo(to,amount); } diff --git a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSCoreInterface.java b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSCoreInterface.java index ca957d82..5d7c5e64 100644 --- a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSCoreInterface.java +++ b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSCoreInterface.java @@ -212,7 +212,7 @@ public static class MilestoneVoteAttributes { Map getProposalDetails(String status, @Optional Address walletAddress, @Optional int startIndex); @External(readonly = true) - Map getProposalDetailsByHash(String ipfs_key); + Map getProposalDetailsByHash(String ipfsKey); @External(readonly = true) @@ -269,6 +269,11 @@ public static class MilestoneVoteAttributes { @External(readonly = true) List> getRemainingMilestones(String ipfsHash); + @External + void setSponsorBondPercentage(BigInteger bondValue); + + @External(readonly = true) + BigInteger getSponsorBondPercentage(); // EventLogs @EventLog(indexed = 1) diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java index 7666ddea..04493a7d 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java @@ -128,7 +128,10 @@ public static class MilestoneVoteAttributes { Map getPriorityVoteResult(); @External - void votePriority(String[] proposals); + void votePriority(String[] _proposals); + + @External(readonly = true) + List> getActiveProposals(Address walletAddress); @External @@ -190,7 +193,7 @@ public static class MilestoneVoteAttributes { @External(readonly = true) - List getProposalsKeysByStatus(String _status); + List getProposalsKeysByStatus(String status); @External(readonly = true) @@ -212,7 +215,7 @@ public static class MilestoneVoteAttributes { Map getProposalDetails(String status, @Optional Address walletAddress, @Optional int startIndex); @External(readonly = true) - Map getProposalDetailsByHash(String ipfs_key); + Map getProposalDetailsByHash(String ipfsKey); @External(readonly = true) @@ -318,4 +321,10 @@ public static class MilestoneVoteAttributes { @External(readonly = true) int getPeriodCount(); + + @External + void setSponsorBondPercentage(BigInteger bondValue); + + @External(readonly = true) + BigInteger getSponsorBondPercentage(); } \ No newline at end of file From 6a761123de8d8eb9ec495d579e0524698e8e6c13 Mon Sep 17 00:00:00 2001 From: naneey Date: Thu, 21 Mar 2024 15:04:08 +0545 Subject: [PATCH 22/64] chore: assertions added in happy flow --- .../cps/integration/CPSCoreIntegration.java | 144 +++++++++++++++--- .../cps/score/test/integration/CPSClient.java | 13 +- .../score/test/integration/ScoreDeployer.java | 2 - .../integration/scores/CPSCoreInterface.java | 6 + 4 files changed, 141 insertions(+), 24 deletions(-) diff --git a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java index 5dbd1584..9e048d86 100644 --- a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java +++ b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java @@ -3,12 +3,15 @@ import com.eclipsesource.json.JsonObject; import community.icon.cps.score.lib.interfaces.CPSCoreInterface; import community.icon.cps.score.lib.interfaces.CPSCoreInterface.MilestoneVoteAttributes; +import community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProposalAttributes; +import community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProgressReportAttributes; import community.icon.cps.score.test.integration.scores.CPSCoreInterfaceScoreClient; import community.icon.cps.score.test.integration.CPS; import community.icon.cps.score.test.integration.CPSClient; import community.icon.cps.score.test.integration.ScoreIntegrationTest; import community.icon.cps.score.test.integration.config.BaseConfig; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import score.Address; @@ -186,9 +189,9 @@ private void verifyProposalDetails(CPSCoreInterface.ProposalAttributes expectedD assertEquals(actualDetails.get("project_title"), expectedDetails.project_title); assertEquals(actualDetails.get("sponsor_address"), expectedDetails.sponsor_address.toString()); assertEquals(actualDetails.get("ipfs_hash"), expectedDetails.ipfs_hash); -// assertEquals(actualDetails.get("project_duration"), expectedDetails.project_duration); -// assertEquals(actualDetails.get("milestoneCount"), expectedDetails.milestoneCount); -// assertEquals( actualDetails.get("total_budget"), expectedDetails.total_budget); + assertEquals(toInt((String)actualDetails.get("project_duration")), expectedDetails.project_duration); + assertEquals(toInt((String)actualDetails.get("milestoneCount")), expectedDetails.milestoneCount); + assertEquals(toBigInt((String)actualDetails.get("total_budget")), expectedDetails.total_budget.multiply(ICX)); } @@ -209,11 +212,16 @@ public void submitSponsorVote(){ List proposalsIpfs = readerClient.cpsCore.getProposalsKeysByStatus(PENDING); assertEquals(proposalsIpfs.size(),1); assertEquals(proposalsIpfs.get(0),"Test_Proposal_1"); + + + Map proposalDetails = getProposalDetails("Test_Proposal_1"); + assertEquals(sponsorBond, toBigInt((String) proposalDetails.get(SPONSOR_DEPOSIT_AMOUNT))); + assertEquals(BOND_RECEIVED, proposalDetails.get(SPONSOR_DEPOSIT_STATUS)); } @Test() @Order(6) - public void voteProposal(){ + public void voteProposal() throws InterruptedException { // update Period updateNextBlock(); ownerClient.cpsCore.updatePeriod(); @@ -241,7 +249,7 @@ public void voteProposal(){ @Test @Order(7) - public void submitMilestoneReport(){ + public void submitMilestoneReport() throws InterruptedException { updateToApplicationPeriod(); Map periodStatus = getPeriodStatus(); assertEquals(periodStatus.get(PERIOD_NAME),"Application Period"); @@ -250,14 +258,10 @@ public void submitMilestoneReport(){ assertEquals(proposalsIpfs.size(),1); assertEquals(proposalsIpfs.get(0),"Test_Proposal_1"); - CPSCoreInterface.ProgressReportAttributes progressReportAttributes = new CPSCoreInterface.ProgressReportAttributes(); - progressReportAttributes.ipfs_hash = "Test_Proposal_1"; - progressReportAttributes.progress_report_title = "Report_1"; - progressReportAttributes.report_hash ="Report_Proposal_1"; - progressReportAttributes.ipfs_link = "https://proposal_1"; - progressReportAttributes.budget_adjustment = false; - progressReportAttributes.additional_budget = BigInteger.ZERO; - progressReportAttributes.additional_month = 0; + List> activeProposal = readerClient.cpsCore.getActiveProposals(testClient.getAddress()); + assertEquals( "0x0", activeProposal.get(0).get("new_progress_report")); + + CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("1"); CPSCoreInterface.MilestoneSubmission submission = new CPSCoreInterface.MilestoneSubmission(); submission.id = 1; @@ -266,33 +270,132 @@ public void submitMilestoneReport(){ testClient.cpsCore.submitProgressReport(progressReportAttributes,milestoneSubmissions); - List> activeProposal = readerClient.cpsCore.getActiveProposals(testClient.getAddress()); + activeProposal = readerClient.cpsCore.getActiveProposals(testClient.getAddress()); + assertEquals( "0x1", activeProposal.get(0).get("new_progress_report")); + + Map progressReportDetails = getProgressReportDetails("Report_Proposal_1"); + assertEquals(1,toInt((String) progressReportDetails.get(MILESTONE_SUBMITTED_COUNT))); + assertEquals(WAITING,progressReportDetails.get(STATUS)); + assertEquals("Report_1",progressReportDetails.get(PROGRESS_REPORT_TITLE)); + assertEquals("Report_Proposal_1",progressReportDetails.get(REPORT_HASH)); + + int milestoneStatus = getMilestoneStatus("Test_Proposal_1",1); + assertEquals(MILESTONE_REPORT_COMPLETED,milestoneStatus); + } + + private ProgressReportAttributes createProgressReport(String no){ + ProgressReportAttributes progressReportAttributes = new ProgressReportAttributes(); + progressReportAttributes.ipfs_hash = "Test_Proposal_1"; + progressReportAttributes.progress_report_title = "Report_"+no; + progressReportAttributes.report_hash ="Report_Proposal_"+no; + progressReportAttributes.ipfs_link = "https://proposal_"+ no; + progressReportAttributes.budget_adjustment = false; + progressReportAttributes.additional_budget = BigInteger.ZERO; + progressReportAttributes.additional_month = 0; + + return progressReportAttributes; - System.out.println(activeProposal.get(0)); } + @Test @Order(8) - public void voteOnMilestone(){ + public void voteOnMilestone() throws InterruptedException { updateNextBlock(); ownerClient.cpsCore.updatePeriod(); + + Thread.sleep(2000); Map periodStatus = getPeriodStatus(); assertEquals(periodStatus.get(PERIOD_NAME),"Voting Period"); MilestoneVoteAttributes[] voteAttributes = new MilestoneVoteAttributes[]{vote(1,APPROVE)}; + + List> expectedMilestoneData = new ArrayList<>(7); for (int i = 0; i < cpsClients.size(); i++) { - cpsClients.get(i).cpsCore.voteProgressReport("Report_Proposal_1","Working well", + cpsClients.get(i).cpsCore.voteProgressReport("Report_Proposal_1","Working well " + i, voteAttributes,null,false); + expectedMilestoneData.add(Map.of( + ADDRESS,cpsClients.get(i).getAddress(), + PREP_NAME,cpsClients.get(i).getAddress(), + VOTE_REASON,"Working well "+ i, + VOTE,APPROVE)); } + + Map progressReportVote = getProgressReportVote("Report_Proposal_1"); + assertEquals(toInt((String) progressReportVote.get("total_voters")),7); + + Map milestoneVoteResult = getMilestoneReport("Report_Proposal_1", 1); + assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)),7); + assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)),0); + +// assertEquals(milestoneVoteResult.get(DATA),expectedMilestoneData); + List> actualMilestoneData = (List>) milestoneVoteResult.get(DATA); + + + for (int i = 0; i < 7; i++) { + assertEquals(expectedMilestoneData.get(0).get(ADDRESS).toString(),actualMilestoneData.get(0).get(ADDRESS)); + } + + int milestoneStatus = getMilestoneStatus("Test_Proposal_1",1); + assertEquals(MILESTONE_REPORT_COMPLETED,milestoneStatus); + + + } + + private int getMilestoneStatus(String ipfsHash, int milestoneId){ + return readerClient.cpsCore.getMileststoneStatusOf(ipfsHash,milestoneId); + } + + private Map getMilestoneReport(String reportHash, int milestoneId){ + return readerClient.cpsCore.getMilestoneVoteResult(reportHash,milestoneId); + } + + private Map getProgressReportDetails(String reportHash){ + return readerClient.cpsCore.getProgressReportsByHash(reportHash); + } + + private Map getProgressReportVote(String reportHash){ + return readerClient.cpsCore.getProgressReportResult(reportHash); } + @DisplayName("submitting all remaining milestones") @Test @Order(9) - public void submitSecondProgressReport(){ + public void submitAllMilestoneReport() throws InterruptedException { updateToApplicationPeriod(); Map periodStatus = getPeriodStatus(); assertEquals(periodStatus.get(PERIOD_NAME),"Application Period"); + int milestoneStatus = getMilestoneStatus("Test_Proposal_1",1); + assertEquals(MILESTONE_REPORT_APPROVED,milestoneStatus); + + CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("2"); + + CPSCoreInterface.MilestoneSubmission submissionNo2 = new CPSCoreInterface.MilestoneSubmission(); + submissionNo2.id = 2; + submissionNo2.status = true; + + CPSCoreInterface.MilestoneSubmission submissionNo3 = new CPSCoreInterface.MilestoneSubmission(); + submissionNo3.id = 3; + submissionNo3.status = true; + + CPSCoreInterface.MilestoneSubmission[] milestoneSubmissions = new CPSCoreInterface.MilestoneSubmission[]{ + submissionNo2,submissionNo3}; + + testClient.cpsCore.submitProgressReport(progressReportAttributes,milestoneSubmissions); + + + Map progressReportDetails = getProgressReportDetails("Report_Proposal_2"); + System.out.println("-----details"+progressReportDetails); + assertEquals(2,toInt((String) progressReportDetails.get(MILESTONE_SUBMITTED_COUNT))); +// assertEquals(new String[]{"0x2","0x3"},progressReportDetails.get("milestoneId")); + assertEquals(WAITING,progressReportDetails.get(STATUS)); + assertEquals("Report_2",progressReportDetails.get(PROGRESS_REPORT_TITLE)); + assertEquals("Report_Proposal_2",progressReportDetails.get(REPORT_HASH)); + + + + // MilestoneVoteAttributes[] voteAttributes = new MilestoneVoteAttributes[]{vote(1,APPROVE)}; // for (int i = 0; i < cpsClients.size(); i++) { // cpsClients.get(i).cpsCore.voteProgressReport("Report_Proposal_1","Working well", @@ -310,7 +413,7 @@ private MilestoneVoteAttributes vote(int id, String vote){ - private void updateToApplicationPeriod(){ + private void updateToApplicationPeriod() throws InterruptedException { updateNextBlock(); ownerClient.cpsCore.updatePeriod(); ownerClient.cpsCore.updatePeriod(); @@ -343,8 +446,9 @@ private Map getProposalVote(String ipfsHash){ return readerClient.cpsCore.getVoteResult(ipfsHash); } - private void updateNextBlock(){ + private void updateNextBlock() throws InterruptedException { ownerClient.cpsCore.updateNextBlock(1); + Thread.sleep(2000); } private byte[] createByteArray(String methodName, String ipfsHash, String vote, String voteReason) { diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java index 7a8b24f2..24796969 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPSClient.java @@ -1,14 +1,24 @@ package community.icon.cps.score.test.integration; -import community.icon.cps.score.test.integration.scores.*; +import community.icon.cps.score.test.integration.scores.SystemInterface; import community.icon.cps.score.test.integration.scores.SystemInterfaceScoreClient; +import community.icon.cps.score.test.integration.scores.CPFTreasuryInterface; import community.icon.cps.score.test.integration.scores.CPFTreasuryInterfaceScoreClient; +import community.icon.cps.score.test.integration.scores.CPSCoreInterface; import community.icon.cps.score.test.integration.scores.CPSCoreInterfaceScoreClient; +import community.icon.cps.score.test.integration.scores.CPSTreasuryInterface; import community.icon.cps.score.test.integration.scores.CPSTreasuryInterfaceScoreClient; +import community.icon.cps.score.test.integration.scores.DummyDex; import community.icon.cps.score.test.integration.scores.DummyDexScoreClient; +import community.icon.cps.score.test.integration.scores.BalancedDollar; import community.icon.cps.score.test.integration.scores.BalancedDollarScoreClient; +import community.icon.cps.score.test.integration.scores.Oracle; import community.icon.cps.score.test.integration.scores.OracleScoreClient; +import community.icon.cps.score.test.integration.scores.Router; import community.icon.cps.score.test.integration.scores.RouterScoreClient; +import community.icon.cps.score.test.integration.scores.sICX; +import community.icon.cps.score.test.integration.scores.sICXScoreClient; + import foundation.icon.icx.KeyWallet; import foundation.icon.jsonrpc.Address; @@ -63,7 +73,6 @@ public CPSClient(CPS cps, KeyWallet wallet){ private void init(){ for (Entry entry : this.cps.getAddresses().entrySet()) { - System.out.println("---------------is system queried----------------" + entry.getKey()); switch (entry.getKey()){ case "cpsCore": cpsCore = new CPSCoreInterfaceScoreClient(chain.getEndpointURL(), chain.networkId, wallet, diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreDeployer.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreDeployer.java index 618b0c43..cd5555ec 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreDeployer.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/ScoreDeployer.java @@ -44,8 +44,6 @@ public Map deployContracts() throws IOException, InterruptedExc System.out.println("deploying contract " + score.getName() + " :: " + score.getPath()); Thread.sleep(200); Map addressParams = score.getAddressParams(); - System.out.println("the adress params " + addressParams.entrySet()); - System.out.println("the adress params " + addresses.get("owner")); for (Map.Entry params : addressParams.entrySet()) { String key = params.getKey(); diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java index 04493a7d..26ab21eb 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java @@ -195,6 +195,12 @@ public static class MilestoneVoteAttributes { @External(readonly = true) List getProposalsKeysByStatus(String status); + @External(readonly = true) + Map getMilestoneVoteResult(String reportKey, int milestoneId); + + @External(readonly = true) + int getMileststoneStatusOf(String proposalKey, int milestoneId); + @External(readonly = true) int checkChangeVote(Address address, String ipfsHash, String proposalType); From 50183b218f8fd09aa74b33af9b340bf4cbcf176a Mon Sep 17 00:00:00 2001 From: naneey Date: Fri, 22 Mar 2024 09:42:06 +0545 Subject: [PATCH 23/64] chore: submodule updated --- .gitmodules | 7 +++---- cps-gochain-local | 1 + docker-compose.yml | 8 ++++---- gochain-local | 1 - 4 files changed, 8 insertions(+), 9 deletions(-) create mode 160000 cps-gochain-local delete mode 160000 gochain-local diff --git a/.gitmodules b/.gitmodules index 4c430736..e2636d58 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,3 @@ -[submodule "gochain-local"] - path = gochain-local - url = git@github.com:nightowl121/gochain-local.git - branch = master \ No newline at end of file +[submodule "cps-gochain-local"] + path = cps-gochain-local + url = git@github.com:naneey/cps-gochain-local.git diff --git a/cps-gochain-local b/cps-gochain-local new file mode 160000 index 00000000..fc7b5425 --- /dev/null +++ b/cps-gochain-local @@ -0,0 +1 @@ +Subproject commit fc7b5425dd9e0e51b2f5355e0a8a00143a29b725 diff --git a/docker-compose.yml b/docker-compose.yml index 9375516f..309edaf9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,10 +4,10 @@ services: container_name: gochain-iconee image: public.ecr.aws/f5d2t1f5/goloop-gochain-icon:latest env_file: - - ./gochain-local/data/single/iconee.env + - ./cps-gochain-local/data/single/iconee.env volumes: - - ./gochain-local/data/single:/goloop/data - - ./gochain-local/data/governance:/goloop/data/gov - - ./gochain-local/chain:/testsuite/chain + - ./cps-gochain-local/data/single:/goloop/data + - ./cps-gochain-local/data/governance:/goloop/data/gov + - ./cps-gochain-local/chain:/testsuite/chain ports: - "9082:9082" \ No newline at end of file diff --git a/gochain-local b/gochain-local deleted file mode 160000 index b71ea0c8..00000000 --- a/gochain-local +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b71ea0c8cf960e7247fb086808494481ad036334 From 713e93041307472c0bbd2f18a49a9cc8211db72a Mon Sep 17 00:00:00 2001 From: naneey Date: Fri, 22 Mar 2024 09:44:21 +0545 Subject: [PATCH 24/64] chore: jar files for integration test --- dummyJarFiles/Dex-0.9.1-optimized.jar | Bin 0 -> 24933 bytes dummyJarFiles/Router-0.9.1-optimized.jar | Bin 0 -> 1827 bytes dummyJarFiles/Sicx-0.0.1-optimized.jar | Bin 0 -> 7310 bytes dummyJarFiles/bnUSD-0.9.1-optimized.jar | Bin 0 -> 3713 bytes dummyJarFiles/oracle-0.9.1-optimized.jar | Bin 0 -> 805 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 dummyJarFiles/Dex-0.9.1-optimized.jar create mode 100644 dummyJarFiles/Router-0.9.1-optimized.jar create mode 100644 dummyJarFiles/Sicx-0.0.1-optimized.jar create mode 100644 dummyJarFiles/bnUSD-0.9.1-optimized.jar create mode 100644 dummyJarFiles/oracle-0.9.1-optimized.jar diff --git a/dummyJarFiles/Dex-0.9.1-optimized.jar b/dummyJarFiles/Dex-0.9.1-optimized.jar new file mode 100644 index 0000000000000000000000000000000000000000..45befdee3a02ac1f850a218ad32286dc8747f149 GIT binary patch literal 24933 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�|5X4 z`QwKE|NY5-Ofr$b$O$KE5-LC*K6v_Inx=71%&eHkVU=_(%)h)OSB7d{iag%{wNte` zR|IZGNW>8fowo~P>eWln7QoRBBmy*SC*_m|w!DEi_}qx1UY4I|MJw&7E~}KRR~y-R zmIg8%?*b!}zL6g$%M^rSD=gMl9I4M;>du(EH-?Iv> z4SltZm^kgv)*RD;=f$G3<=)A>syh&Lm?KxkWLtJ@`U`^4A7Au3`R3oDEFM3W@+@?7 zU71c?{cK%!U&8;2E6g4527JXC#!e)WNz|N6(m6&lakY0L1K!9jnc$N!-__Q2OxGNd zC4MpjLw3k=Z;20;LMoHm$L=LL2z#&iE#DsV4w%kqvYpQ8;$pw}yW>~LJ8-bGL`__L z!|=PKnY`0vp?#t#;F{h)2(j(cmpJ%yb$I-v)&Kn{i2a2SZ`E~2tVN7(9P{7FzZ;3D zYLQG~T@ZoW*4SqNx>#b2uoTwwMh2WW{Fdj2*3@+=<|rG@Tao7k>1LoCl7e`XB+AkF z3YqYQxcT2_Zl(3!@E&U6xF2vx1-wjMNw^XwqdJc-TtBm}Ke}umud8i+!FCuv()?v2 z^kMpi_JNgtC6`O;iO&9dpQ6!GO&r=0FBnNchNYQj`;8Knw|d(fF97D-nFryYcc^QG zV3QDibU()FdwHk{cKma?Ba9Txpw84uIVhI@5d8-&Gb!05%3JKbZ+0(F;b}U9U`(&u z2{$NI$dnYsP8=F-0|WN_Olp%|xY;upt~)1?VpOoRr29HFuBi zQo~Ro!7F}+UK7X|cIuau6Us6&Q)J?gTG?a~U|Vr3d%-DW?z^qIprOHz9~dEKHNg0Y)M8iNUteA&6|s zjtR5)=&d3acVzGHN%Mkl=%0ISO}@ub=BP0(i*iXJx=L za9y>3Z>`;IAmO8T=asa=c%d@XClTG!3%mnWYi5~JGFPBcbe@%?;2V(71doqk5(K7s zcaJ<^mEX!M)60$`Jc(#8xBg`Y7K-uQ&_~2D)u`|+b zi^A1}hw{RW=kz@y2>OyCz1hvwV^jpVunV)NQWVB!;GE-&>@hN2JlhcVdAA5Oq)B6wd&2@c(`XV)Oz)jJ5&UNso(WAx-!`uG9d_csR-8GAj03Fm?Iwkkwk z1PF0X63vt}>dYzAkyRSSTVp%^aJ}on+kqEba(BS0nu@mkp<3pp(07~uBtD?{%l@b{ zeefHb%l(I7hfuc=kY4X$ix8jpS~sJueMQP+U6ylZ9qzF}@PgfObX!BR;^8+*=86K_ z5lJH5+5MY(Wb!f)KPZP*drc@oDrkZ+?jxPqdfz}tYj^aueTcMomm{2PO~Fr@g3N3c zUUq3-c$n7%n)FVB8#~ zvTvYcWnW?fs|yD{xvOGJ*Dtk%7IPZWKHos8m9P(_J?EB8tX)PQcAQu60Xe&P1JXCh zgeXF8+DcRvB0!}G- zBjW?KP|4))F|O7(f{kEt*nBm7p`9!#&v?fuk5%{Bf!>mE5QjoY>*DTF8MCaz(PBcA zyK_76s;#xYwGYyz;)1VWM%~Ovb-R3qvI?>rMx4}{4o=Sco{nr8 zJ`$8~-uf9$8KIyZS~pXnSs5>zHtWsO>)Y#1z%FbLBWycN?K`A7zmU9izh=+Cm?Esi zYJZ6GD%Rs%TYJ>I$WlV+@w5n>6L|26K8Z~pCm!9yx#ck1)a6YtvHhcyF@XkOXJ7yT zc(DJblj48rq_v`@6qW!ok86Q!-KubOHK{dA*K#3?%(gzcczMYHxNwlyMn!?u#?{!B z@LRnm6d0x%AL?6yxy%zdlzhVH8fqr4M4NzJ#{$soG2+UFiMxaf?Uz(V%t4J8-Mz5_z1?bL8(YHvy<)z;kC`oyoCeF-m%n88zET=FhnAvSqeTdk4 zezwzZ4sTQg3b)6KO#(_@THwi1J*$^(89h=dLE1V2k2!|2OvGlMX-h7>0bpGQYz{BE zDzo@h*~{#=4OMrUm-#opVIT8BakC110RNNi{?XItnm<*M;lEZz5`SgeSy@YIT@;TI z{#WvrtwtKB8b#Kf%xqSrc^bK&@z4fbvNRj}XI3nawD z;<|RdS7eqnM+{aFT6(gWB}=0*Fq57-ePnr=+FMRk5Ua-$jk`OCDMg{_l)YG8||$-s2+A~ z$L6MDJ0+<@zs^f*z=Wa4&xWW{MqE4h7tW}rX_msQG^u1HsqY^J zQNPt5Da8-k1{tAMRfx;gM^$cq67Vo;51mz;X;m1~uxSchxfMp4R-57N_q6rFP}0%&%=e>w+-UJ|L3&K>unDF%-qb0snvsWmj7mh; zYd>mN3mze^qg;IWZ^}0btwJ6el6y8LM(xmlSg`M{$(~{c>Ogj%e*b3{>HxIu684YR z!2PG8_unsAl7CT&i2S-NrU3ev2_Twkjay$t6HvCxs_@lAKvDQ=LwE}&5{zVv=81Tb z4r)D&=+`d*N3+cs2xCt|DqE;CK{(9%xZm{6bC1? z2>!E=2OF+XMU!)>Q3yE^Smh!8gcpK;oE`?E$#^ZMFhiv%CfFR<-bi7*FeNA~p7=h} zCU@P2W^!I33{@AJ6O~xkbbGchx=Sbz?uczOjt`9p-%RaD4LppeH7@EvE7~0WQt3!iTfhAIpDQlEYGd z76|2%fmmj_QuE6G(RLB$tp2+{<{~0(fQQbC(CX5Sa+SwYT>=VroS5+)I{!; zKih86*N@PB_%!cS@=V4IjYvB0!St7W%oIzysCz(b-DlVZ&%&=hZi=Ez?>TZ=2H(&L z=#+HmR!G(DyKbbaEE;ZueNfH$>|FMkfC=)TNd;NRjBDKTpd|3q$08jcewTnOd*t7} z5lbLr%=^SM|6_8S&$F3l|B(sYf0YTTzjFIqdD{_51^LUSE<+|I<46@NxAsu1BE3)? zItf*>R1ic$qLihOrHI{Teg=$5LZ&&4{p~<+7m0o1MzdUWSOL%5?jsT#oagu|VTk}E zv^L9e>Ur~hlV`irldYTY^;8W&>4l$PyBQy30q3}iN!1ne+z7hdwG3rhP#&MPdC`ix z*}|sLIRTWoTP_}Y?yLX^FjN%ikh(xc7Dd)FvnTMCbAYX?I7!*PJ|r!)#tf(#}F#%h->GX zx+`15b>;wZkyYj(M|z1Bd!GAk8BG&DC8k$zF#DPwdH{dnazJo|#N8prkp39DzC zT5|o?h!(el2q9R8+>tfpVO}Pv)}Ei(9U=nUW?USuhZx~mo-4^4x06!-wvbcQZkpt# zFTt!;eeEG9tm|m0?K~HA-6RX;Q?h6BS&>$O#2m7A@!f1kz5BdI<^9jR*3B~I>ZLQ4 zI`mvLh!yb}*;A7|VQN2mdqz?AURCF0pXj&7>1u{<%I>Fg&K}nQ3+a7!o>y-{@Y7Ym zt6#5xp-ctaM7OXn(>+q?`4~$B-ZI4ZIEV$-9TyT~nxu9?cO&;fLDcV8BU&6H zh$4OtE5aElN$>?wxTNy&|3q8HC2ELl#Yy1tYm9Ukl#t6$@c8LJqu@KRL=+j6kBI^y z!c2KpGBa&LQKA|_B4mvwRfI{GBA99B!eOwfR!c`3@tYnA)|K=9G!z^Dt}ggIO#J~b ze1_~37pHA20^&Rt_ho#;GLG6OGT7TI_~nCl3%{!+wmA&#$^MtyEyi$h4yOsS>an=f zWw-FL1aol`YIOaHvY1ndNQbF&le!`Si^Qs;Qqt=x2}<4|i7{2^9bluRMj6y$iDtn@ zaaoel87qtWQ&mO}&1azL*MCYt-awiA>_5$`pa06+(tn+8YXuqGd470rtm^#%34H&M z8P<@LyIpqvSbhO*>Nsi?f+SXKk6u{SvjqoA*T@%~56~Z(R047Gi&Ti+kOW(p1(Yh* z?xtH4o=o-odcHoHKyE?cK!)=H@Mf}oaJwFeMf;D-?TKcE)aXEs%^DT?7kRQ!Nqvy7 z{($0U4bw)$Xykm6^Xfck^c!0>F_>qp7_bf$2{toWbKXXIDq<)uC?wh_H5)j55X|3< zYph1gAkst3t(P|0(M<9hnK3zMZuedbeTeI13Y@B*?(exVwAfhVEd(>Ixf9EY3)F;zUjDS^eX-I91(6rzHiw@4D!2X-zsi3C|9Hd zPm!?&C;WrNNH9fWtK=RSWbxX@WTVc%YJwPBtXnwBZuWUkex)5RrJf=*nt@iHdJq3L zIuWzmBR%E(Og%unOn*j!=2LjqL?k<6qc*dm_Fa2&5SyCenEH(?2b>?y`}NsM<=%NN z(&?g5efAjrWuDiEp<&^WvDM*K8|Mn;E;DZ0!qH#p2l6d5uRDvN2;{B?2%PRDjU_{6UWw)Hk9(E^cDO$& z9>WF|xS@A?9u4~U)8GQoj5QEV&HIec2=!Y}(RY8xvI++9s0QN)#U45oSZGug33itU z>~xn*TTo;lgqUAzEO_KwL}M|(^o?R(c)@>QnBs^UTK#Y}^WNX~(#|~PrDmF0E8ywg z+_kU-L2bjfuD@Nou*x@``JbcGRsjpY`lrJH{U8pcAS}quh4}3UbAYYbGJKm!blQ1@ zyN)qmY90##+qvFB)943Y0`ZGdV2RJkGtcQT;%b%X-fa2VWmqf5Hr8ZaOvv#}BZkIE zpf`VIOR=#1&)6xUvY^U$>>9j(xy1H0qZcs@9?}_P-wDj`jBVozcn79$ebgAQN{_j! z)h~=}Dz^xvK3fb$*HM9x(_=lin|ZHG>8a{R zVhJyy1RH3!LpmXzK4!XlcZGzLIPw-*gxj1#x1SV8z6DM|L1m2RgmqK06jiTFbV-&JZZi!lnSjj{RD_Mb5y7^obFyTMPebK!QD<(dFA4MY{U zoS_YrQhE1^7uu2g$@1{}ubOX(sk7?jbK~(8#h^3Q1zye!n!A)!Stw?Hi#ZIlyDY)2 zQvY11k>Vm3_y2&y^k0VoWd8z)vyy-q59(TVq?&g)M1`_7B$?O)pf z+`_^Boin}YjAS2CYT8$ilytFj7cmP6#^P)up;BUQ;FJ^ayTwVf@;yo!`eA%7f1Eo4 zc?)LDBLty_pST#}z2X8wYy8+AhzJ#!;$Y;K_z1ZyAwkI291b10LR~*utJfepRLX{N zYe87iBh&?ns^sr*Enjv`gmdjP;yy z9IMaQd}=8M^tmf&UGBOE`tS2PgT9Jhs|!^eYlWlRZPw#m7JE>elvacdSYotb&WVo^ zIgqW{#QN8XPTw|)o1HIPkC>BNK3yhsJPse{62|qEM5j|&e!UB8yh~lQCPr+FNytq8 zoC)YVZ92#jh=hZCt(7`f)`}9tX}>BFI!c3|`$fbHlXO!nCbU@6PF`nm6;x-jX|9rq3MIBQgcTgMhYIZ~yLmSpe0L1F`(Be;cw zETo%Ku{Ri&m=?0z-hvilO^HOJ)jWm=KVNi+7ba4?gr;t+dA*qTffJuHwpGj`AfO{k z&z84!ViWKR>2yidaN?xvo%6(O=rQpEsw8$m@rmokKLugPj-P=)_oEWa_di!G;<1hmTvrPr1ooO4*x%RIxC)Lf`_= z2O{U5i`alD-h+jR2RhMMkdI0|oyEmuIz|0_Ts^G^xY273WDNyhjslo0@0~d?J9MJ5 zj7NLvVapw`2Mf{2V%{J~ch<~#N+0%SEx4--4|?h?*#E|6Ws9UdzQw8#WWe7K+4rHh zFhmZMGa!)k)*ou?`GpU=C!Q-^LagD#B%Y376j34>lHdu6S?8xES;6f_j+l!zu;^3A)8BH%2P+ zx*ONsz`^Qf@~UcEYW?Y+$ofbZFcRb4rw!W!l57gwoYt{PhTRT!MV;9mRL!`OBp{_( z{;E*-`ml{{<*tojeQ0+nb@F7Oz+l=JIfysC10s4mWn20x*p?I8HjZcc)dh``$dBU~ zpy(a=kgkNgTm~oiY0{q0z=dwSv)2^mAwvS0;M?PfH@p>clG!rhU`lMlhyN?9&-^H5 z7tB)Q_rcf;FYSe~Uj{YiahCC}vuw*5Qk7v$C-+nh@h^G-Zhgk&#`BizJWHc1Ew$k( z-l|sW>%v{1&^lU3RHlTb7rP%gWiv9YHnn;D-~XxUAWGx3&;Rhy=YLi3f7;>le*;Bn zRdL}@JKPl&h+t==%+D`^6FP&6Jgkn39yl-%e?-a;8DtoS7z2uL5Kdmt&5trzuq=tK z`~$wbPf;!b5QA7nV*6^{`|TkCue;j|bS4-SFg^hv1QYQ#dmz27)a9qL(QhIf%c8c_ zSr7B8^E@?eLH^u5UpPn+phF|or4u%pN9*=|0(kMp2RLzZgqu<Ok*Uz8us*B7Fbap}HMFr3YP zMhAP5Fz1A)YirM^Tx5@Q1ZZkg4XS99F>RhEX0d=;^u;T&4BxvbR`EUeS%w8*wVdh) zgP!$O+;Bt0nkk1wp<@kxp#>xDGb^Pf%m^^h?y?Ss1hmVFUGHR1fQ7`0Y5I}nN%3o{ zR6<&hyMXs5;O;3uo&5UPaVb6_l}@U;!c#H;!r}jw1_H77)TBgXH$uL z+^3?FOPo`MSR6|qLA#lc&o#9@aF$ldalKRH=TJk(A3Cv`(wY;sIVy4HX}BnQ)|aHA z?s`?kMDJ=m! zJuRq+^%h$tI6I=me42frd4puB1#Wnu$J(?P(!G;Pf-!1Jy2$tV zl9WWiYIZ*63JzsjCbE=)guqDhKS2Ca0+WCwXz}GB$frOGR~s6dne1$W%67mKq+u%l zBOPOjSrPGnO4qvoIv@k}4ktR|>Iq8Y-}6S5NkO9mJ@2@v5`;x;dWK-kdc8B5eC*YW}gkiggQ5wK>j; zj_!aQwH|g`7k^4@nExd~{`nkl&lvFSchp@*AG+E-_9Q(=Pdal%EIQi~9)kh5(Hrg^ z0f!ufiF&vS3oiX_fP0_yNX=nf8dTb@tx4KVOfr|mDGG;0SagW`gj=7cyoplqPPrjE znAn^$!wmZpuuAuT(n@&cOr7$F=wttt=#~CLsdN0eED!^F@H89*V+^62PzMMST7c*; z+M$*>aqS(FnAzZRPG)tCwNdHYJJPNYXrsP9@SD6S9A(1-$_U-4ZckcVAQ!)U3miBbO^BN$d9rU>; z3uoR*^pf^6SMh6Tt=@#C846o@!DM~&~Tc7zy`Rtm@su^np)~fJDeZA7QSAkMMZU8^fzl^6;8IBiRqb;rmnW}zE|VvwmkC}4I#tF*543_r!ZDz?Y|p!f+o7G|nd%atDIq{@ z=;Z~gXIe~X$2lj)`T_qefVfrN_bB)RE1a*x26^W#{G-gS9^aP0K|FXJ$ zw@(6{?A&l5h@x^r-|)z22iYraAZLiNL_1P6ivW@UB^&xLpyM4Gs)@p)ez`0Pu-CvhA8z~i4x;qw)7u|z{j5VJI2Q-bOgU+_&h*f<(j39H z;6HLbQYL#)bEN>Ma&0kUD9$J*h8&PhjNLfMk^dC^yfnF7LT}k&HV>z)MRWF&dB&~C zp*)mG$AsfzN`)#+r_p(Jg11Fs;@x8rpd6t&&!4USd}fthi*F5^d*rTITb zQ))OpTA2xAL!CK-ok3q~e&y?2+VopOS=QGrIi9#NP@HyKQ5esnqyKl;{>_Y41P$?oa*=I$=P4I zG*mK+9hLNrv{zL>7fz$fg+hy;5QqX8%;hDpWf^rO ze?=_`7nr9o;|0w~*G{ZyZ8rhZlrq|h3Fx#&Tx+u=+c~QzYYAtm0a2Cc4A!5@5-gb1 zw&x+;hAMYxS)!Rs)S5wRn}#E4Xi8j~dk%nIri^Z(8s5IEHd+eg4|WIt&)DGeGY)~4Nsf>e`ik?fNq(WcqOgghtN z2seTeG&kwVea#7g9IeTc4JwwrEt| z-l#-sIIbd3ORxz~blKDsrjn&bz~%+A6+fR^s}n{@Z=nodn9L^@X@s~onvx&SMH90m z%TASj4L?w5jJU^biDIG%Ul>qUkIrn2ef6LB1=XJ6rgtT7jMbsfFA|$3tJ(`1Iu5)) zy1F!;wS0fy@GKy0xjfl+=C!apcxpVjK)v0R;ADC4GoO9Dc(QXRey3Z6cqYzLUD(mO7Nk+0nrZgv;|>jWtJvNO*~;VZMd)nX{WO~7~L}SST%KKR@XrSb(P*4JFXRb zLiKUJ`B;j(&5R2qjbaR|QyAlTve+=S!!5c$L4U~onfTK$TLUP^h+Dlno2Mk!MoUhD z7vhtH_iF^WLcN)i=I_<5uPNF3iU-FTSLAZn7T{NM;Engwdojfo6_}TN=}4f;7LAzP z;`Z;`PWpDB0D8&1T{E265NWeo=uk3KIyRp&sTRld-mb1M-n0-{_VvI})|n*D7F>+Q zrH;OxBs+2Vp~L${0TbPv76UHpCivY@xV$jOJyWXZRw`b^yf1K~4Zf7RA}DB|xec<} zH;586q^@93MZ4J^##^tc88|X(8zi>>5C>83I~^(T{vh=gE<&PUGCAru^_= zzt@c*T(#hhwEiV`{wA@E2FP?oo-~Z^5)}p& zvG#*1&MNH3Wu5I+%Za^~Gj>4Bdvr7RHolDC;NFTD-=t~$<*@;PXJmg9G4$X{kl!N4 zQ;3M6`AftI{w-qM6jqFZ34SRUGOxxk2j3@+<=1zDbtMuA6i}-cFGuphx{ZBVx`GO* z%%~)&=;qeuNdMI$a*hv_3?Vwiqkq*RZq-SBxT6Y7_^RHni5I?}qJn~;CA}Z*Q_v-s z$}FoG83hb4#6rjNMseU8*H_tZ_Ox04Rj=|n0Sgr-ym9*bY=Ax)*IKzsIEfNCxPLk6;=@96w7aMcmPMW4fmWvH08# z3V9s3T|sK&!9nU=8T!z7UCJZoVf}c!4hm~{k@8a6@!l9}N{x*Ez&pX7M^qY~Luy-2 zZ4EtV%iOgg=rplg3JlNiBg)KOZf<~jaya>k_l1q6Ed#)0iIDg2Bw?*@STLlnm4leQ{{1be0o>^mi0@YqktPZowyglKH~$>i57(x$31|>c)g$qiWw<@oP2Bd}$av%A`L( zSz4x7Kbhu#7VjmZSUJGbxk8YQG9K%_#r?*tf6uZxh|niUeS^o`lkBXeodf!qK>qbAqjq*A-iGehawrkWwt=t8FY zCNRwf6rN!;BpY z0t+71N0Canmi5dKY)zPBB!BRW9Wg(NIu+wr$y_G-?Q;EQ>zE0dd;tl?&$| zZ$3^hXFMif)!YwLXFO$=q7x54mB-5->E-W6Gl=;y7-=w~ zBGqjLTYr}G`7c!m6qh|}4>?PF|DQAUM}mO1ng*d3k%Wun&)zeKuhPV&FYJZ~RFPCj zoIr)0hDa@?7E9&TULz!#`l2B>VKlUkEp&-VO|)C8mulTUyY4VnE>5GPmc}ivYnY|Dwgobp8iL(PV z##8k68mqh`6^8NQI)17wqw{{4IJK~0J8yc03K6BaWfo?9oR<{A=LG>^zwW+dk{=7` z$#W`vn>_H`5@RND7>l8;hX%2JO*adXQHx@u&~b`=XUmnZS>So@!{^_#yZ3y?aLi7d zls;h1ApR~KRU zDaT)0W&CZ{IPXVbgjk#MVX;xxqFbFY+2Gpe3&$!EG4mc=b&H29i!6>FTN-nE0|&P+mxNdG$jA#IaB*Q?^V3Z0l#ZFXG*CIjLPAeGDsk;y9f z+4nIY(tZM~A5BZVLTu%mX|4q`M3v=f)|Vlzxru8HB{BM&uA){3m_;3-b%FBopl1RC zoo=r-8I0$&-84Et?=%Yw$j8JEm3KO$l6cvN?JJQS1kH!A&q771mw-9D80${K7R6!) zG}}Wj8InD%Nqi{=4cEq~2sM0by$1DnSUrT`Jl~Aa0o=HCx;v;>d1nJdSZH2(@pA#l70b&Z3e23BCn60+O6L4MY2XQ%JGd;u?-5*wn)br zeX5SejW;dUvpSfR+dUJ7j^9BI9N`>h>=Ui>?`kqwr4U#rz@R5`?x(znG^c8mY%}Yj z`hsb_aW}ZOO7^^;)o95dQl!SUr^qsRDwBK{xQDk8lWkRAH1GMqF}&u2i>%+wl5Q$> z0rVEUseO}~UbNDHLY}eQRL9Q}Il1O^hRyVsek@@lBMYucBEG zef3=9NEp>mcIySv@%RcWr2pK~Cw=R!^B`BZ=)b<~x^;X#U^IfesXJ+^sdPXbU!(PE zgrgLnz8m0B`;~IlKfq-Rljlc$@hW=J?HeseQE-A;8bEGC|IoG7N5G;D^I_sz2#Dgrdol~#z<*gWUrG5W1(Lt~ip zZaxjkXATh>f5lbNsEC%1!ipdA@wc7fT$0~TH)i8wY1*PLSwBT+!1J*)&&*7%(#_)o57u#QQt^n%MNIyP#`#<0gCdX2S8K(rcLscNQBDxU z@{X78(Z+H6fgYI1SGbaO4EtD(vYaRkqeeWLTv<%3)5{v0Y_pI3PpAFeePTOA$Qq&X z*W1DaMj7}tD;wMK*PTt~>S~jMUTu4)>1$|7^p$$rAW%64? zXO?S$7>$o-i%ClaY7O2u#a%wmD&cP8Svd>dke<47Q1CdI()Cd()88J3#pr#2%( zN7dKCvrI7N?s`H$NxGKI^E_Pog93$>%_#3VJBm@Shl{R>EGIICPUz=oe}Yj9>;%UrxXe~&t}z#2?N$efs*A-OME07^r>jd)*hs|?Rb4_ z8;F+NY$~6Deev_NZ!(>ql}rOquwx7^oC?0G&1fg!76dV3c##*+n^L~E#FwWFd_^bl z{o_+E=NJhSHTzxK4cdfFj$A(JOZxjX#F8Y0CB>@DTa3%00g6*xy^IHJTvF1qV%;F- zJFfDhaS6ihTL6!UdF=2fh07iXo#tRdT)!WT+u=jluq$;E0GUBJQFleKz zXq#qZo2I`9h%cq5Q^73?^k{OnXxi!9QvMl1^4Bd1 zZ8nmY8!}<7{?!R|J7JX>4dEtiWzw&QknjaDKAUNaA!AKr&9dGe&(cL()s!ZCe#CF) zJZHlRJSj$?43ZfcnUw*vrIFaXg3OwPq|R!WY}d$EW2Yt=-3n3MS>RcZU5RywFERPz z{30SAz`d0JLPW@KFkD;nP*64ONR|P#QW>V88&g7!s)3}i=6J+P_WGd-JJXcJ`gVov zpsH@n@@q_`YLk!JY{aQPEHmv%Sfpr_hQb^4QM#C@IQV|;(f<^d%?RSWa~g1{^rH{g;Ae$b%iO%Xv^ik`*gULCR;pS@A~)AK zwd1|qwbwXt#T;B&M-Rz9y^F~Dme!76MR?Kn1QDx%IJIm~Y|CrW-Y+=9^J$Igu7Jt& zfkyi<4-+Hi2_~JhAAox&G_5y{2#>Dag1+F0k5K2D*_x&LeR?_{OMKHa8!rB~p-=n+ zoqH#5P6AJ(z;1$&ZFuwG$F?97rT1Z*2Ff3<_PeHc?8JC<78XmZKRykl0Bm(@7NruibzKuzS-ToSytf>M!9CSACZTRu;%@^|Pe}{vK zLWUm$Ivem-3i!PpK|Tb0rY}4V9TW#kH$jGiUw`3g=!h^_dJ_u(fOkj0)6j`furwDW z=McUmfTy7&TVQE_JV?zAH<#gQ=o}PSnw%K$N5~624V{qzOCyp1{zy)Nr=dHCVQEH) z`~;t>0Z&7BqQcUuGynj6uQ5Cg-Fya1i_!rA@V%?>G<16tEFH!K0Km7a!PC$U6tJ`f z3jhG$5Cu;|o9$s~2@U`NzU2a*hIXXiuJ*q-4KBd{V$X-?p$*Hhd$;3;%+$YJZP0#H zSUQRa0D!kR!|xl~qzFrI@IoG>{<3dqe-L}eRTq{{6$b#|%_Q(NwE7B5lPduL@H#L& z4K4n`($x?eUay6xp=B;u+F1p1x&Gy(K}#>NUwgYMWNG|U7=zzEbRiErfTQ}a0sgi) zL)S^L1DI(-7O6k0fA}MSE)!tqtBek0jr^myg6E;1`(O_sME92eqqKk@0QxBa_5cp_ eAxqsK4~v>AD3CCS+kd4%2VjS!h%p)6{`EgQ{^ke( literal 0 HcmV?d00001 diff --git a/dummyJarFiles/Router-0.9.1-optimized.jar b/dummyJarFiles/Router-0.9.1-optimized.jar new file mode 100644 index 0000000000000000000000000000000000000000..7c4c1232aef8e2e18a8744b0a0c564321c4be552 GIT binary patch literal 1827 zcmWIWW@Zs#;Nak3U|>)LVgwLj;AQZ24RO@<^mEhqb@cOea}5sB^K}aiVP#+hDf@Sd zf#I|7nbSVrx_TFRy>+$DojJcb$l!|cgQuT-&z!kjdd^cvZ(C5oqo=@t~47aiLtRq*GgGj@}z?IS^eEbP4J2{xbx0WdC*ZNL= zEb;h-B?~*hfQF09#YJCrtRmWWFZlcav#IXO=RO8o6_%`vzI1X=h{aZ^yRPa1?d}pH zg?blb)jE$X`jF-pzqqH9_t*)o8dmoe2hO%#`6?O9-72y)eXs5!{fRQlKV`J}ns!C2 z&Rj4rm+kGcPa;RTEbcqbxpgl5?rEFd{}%`^{=I@J?%&rl1!@Z($o%SCX%F(P>{ZU1 zRY0F!!|Pjipl_Y@l5-M^i{bv98WJ5Y9V+sV&&MdyBdX)eq^!cMKw*X6M@zkKaUBd= z;klB<@xbkqPgHz7pBG#>zhui$DaPbjp)pq0bb2ImT z-~N63e%t#0zn^F}ycXcmNpCXjv3gQzJt-`Bk&WVowI%Nfy{p?#Q5}Jiwk2|({u{`G4*mr-D%4GMDgW5b{p)2xa z+CHYda(SU~?%|$R&X@!PnYh)4YgE_|+0TEU_fIAIX2}0g5zd%P8{<=FNQ5+Xo(^eJ ze$D%?oA=}dk9k3_vP9M&-e%CLeSX!OW$BN!oL3$GvuCcb>CX%6guj1HyZfzG`3`g9 z=Uq8fr>2R{cKx7s_)6irb>#}*UAG%3oqL!y)7tA-yV||99RbgOFDl;qbd_xtx5#&q z!k>pf*S>MnysO#QZrAf%`dwSI?(4pD1)J61IT;6(T@dJtw%oGw?u5qGTlSn> ztx~gF>2La}@J;IfILsvUzB}D{?x=98Y_9#L=Jq{;FJ{i@Zjk5>V4S_@n#wEvZ$WRL zzxB>}eQCuPj$=AJ54C5xyZ-t-ZRHQ4@^81Bs%IX1`>bSf(%y-$lBB&i`9!Z-p%K<- zZdS3Zu9DvB!2UMtd8ewc>mt9&c9e` zb(W+0J4d{HbKjvJm&4bXtS`6yVY^?Zn7qYA<@Lu0Tjr~sx{!Qu!m_W|>Ot9mN%ECX z2bmcdblLG0cA)IjvP3|z}Ul+ z<1neSQ50MVn*}NeMFESXL~yah$RxsmDF2ZQXi)i&3JBH)0p6&_A(w!lQXK&*flRn@ zC}ljl8OXs13M>Rj2i8L9B`3OWWY41NPGe=j2>1YRRyL6NEI`N)H2oh?4FdxJ=Z(La literal 0 HcmV?d00001 diff --git a/dummyJarFiles/Sicx-0.0.1-optimized.jar b/dummyJarFiles/Sicx-0.0.1-optimized.jar new file mode 100644 index 0000000000000000000000000000000000000000..6e220f0353495174c32ffdf9d819b166b2eb7d20 GIT binary patch literal 7310 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 AS^xk5 literal 0 HcmV?d00001 diff --git a/dummyJarFiles/bnUSD-0.9.1-optimized.jar b/dummyJarFiles/bnUSD-0.9.1-optimized.jar new file mode 100644 index 0000000000000000000000000000000000000000..b0e7041fe6e47abda556d9da02f559fef19f855b GIT binary patch literal 3713 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 literal 0 HcmV?d00001 diff --git a/dummyJarFiles/oracle-0.9.1-optimized.jar b/dummyJarFiles/oracle-0.9.1-optimized.jar new file mode 100644 index 0000000000000000000000000000000000000000..1fcd24128721fb80546569f432d2edc2963afdd0 GIT binary patch literal 805 zcmWIWW@Zs#;Nak3U|>)LVgwLj;AQZ24RO@<^mEhqb@cOea}5sB^K}aiVP#+hDf@Sd zf#I|7nbSVrx_TFRy>+$DojJcb$l!|cgQuT-&z!kjdd^cvZ(C5olc$fKGBE^rvvX)4 z+Ha}_)Tsf)0XQw@W#B|u>=@t~47YK%NpIpz-?X^2PFd!|Eu5Dn%$6*l#^p0diJj&~i_*#dVM&pT>im-8cGVSl2ByXBGQHfWdHNBz_h;`7-hL@} z*aXk{>YTh#e#+-P_i zjd#wyThFQfyVsDfFvOjkQ&C3$xlhKKY1-32_i9SmhCF$=No&EU`j^Lzwz7I|sQT6U z>vx%BPsY0^E(QWT_801Iubi9f@s%AEi8|p?4G)1q;{{9v0p5&EA`FQ1gB-!2^n(fr zrY3abkYfUrDiEL&$b=h*l19+YKz1%D&JaKz=mGQ?4De=U1F2vJ!izxKjtRsA0C3~% AB>(^b literal 0 HcmV?d00001 From a04beeac8b0aa1a1912d1c8396e6fcec6f425358 Mon Sep 17 00:00:00 2001 From: naneey Date: Fri, 22 Mar 2024 10:45:35 +0545 Subject: [PATCH 25/64] chore:completed happy flow --- .../cps/integration/CPSCoreIntegration.java | 78 +++++++++++++++++-- 1 file changed, 73 insertions(+), 5 deletions(-) diff --git a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java index 9e048d86..0f61b4cd 100644 --- a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java +++ b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java @@ -21,11 +21,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import java.math.BigInteger; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import static community.icon.cps.score.test.integration.Environment.preps; -import static community.icon.cps.score.test.integration.Environment.SYSTEM_INTERFACE; -import static community.icon.cps.score.test.integration.Environment.godClient; + import community.icon.cps.score.test.integration.scores.SystemInterfaceScoreClient; import score.UserRevertException; import score.annotation.Optional; @@ -146,7 +149,7 @@ public void loginAsPrep(){ @Order(4) public void submitProposal(){ CPSClient prep1 = cpsClients.get(0); - CPSCoreInterface.ProposalAttributes proposalAttributes = new CPSCoreInterface.ProposalAttributes(); + ProposalAttributes proposalAttributes = new ProposalAttributes(); proposalAttributes.ipfs_hash = "Test_Proposal_1"; proposalAttributes.project_title = "Proposal_1"; @@ -184,7 +187,7 @@ public void submitProposal(){ verifyProposalDetails(proposalAttributes); } - private void verifyProposalDetails(CPSCoreInterface.ProposalAttributes expectedDetails){ + private void verifyProposalDetails(ProposalAttributes expectedDetails){ Map actualDetails = getProposalDetails(expectedDetails.ipfs_hash); assertEquals(actualDetails.get("project_title"), expectedDetails.project_title); assertEquals(actualDetails.get("sponsor_address"), expectedDetails.sponsor_address.toString()); @@ -403,6 +406,71 @@ public void submitAllMilestoneReport() throws InterruptedException { // } } + + @Test + @Order(10) + public void voteOnAllMilestone() throws InterruptedException { + + updateNextBlock(); + ownerClient.cpsCore.updatePeriod(); + + Thread.sleep(2000); + Map periodStatus = getPeriodStatus(); + assertEquals(periodStatus.get(PERIOD_NAME),"Voting Period"); + + MilestoneVoteAttributes[] voteAttributes = new MilestoneVoteAttributes[]{vote(2,APPROVE), vote(3,APPROVE)}; + + List> expectedMilestoneData = new ArrayList<>(7); + for (int i = 0; i < cpsClients.size(); i++) { + cpsClients.get(i).cpsCore.voteProgressReport("Report_Proposal_2","Project is completed " + i, + voteAttributes,null,false); + expectedMilestoneData.add(Map.of( + ADDRESS,cpsClients.get(i).getAddress(), + PREP_NAME,cpsClients.get(i).getAddress(), + VOTE_REASON,"Project is completed "+ i, + VOTE,APPROVE)); + } + + Map progressReportVote = getProgressReportVote("Report_Proposal_2"); + assertEquals(toInt((String) progressReportVote.get("total_voters")),7); + + Map milestoneVoteResult = getMilestoneReport("Report_Proposal_2", 2); + assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)),7); + assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)),0); + +// assertEquals(milestoneVoteResult.get(DATA),expectedMilestoneData); + List> actualMilestoneData = (List>) milestoneVoteResult.get(DATA); + + + for (int i = 0; i < 7; i++) { + assertEquals(expectedMilestoneData.get(0).get(ADDRESS).toString(),actualMilestoneData.get(0).get(ADDRESS)); + assertEquals(expectedMilestoneData.get(0).get(PREP_NAME).toString(),actualMilestoneData.get(0).get(PREP_NAME)); + assertEquals(expectedMilestoneData.get(0).get(VOTE_REASON),actualMilestoneData.get(0).get(VOTE_REASON)); + assertEquals(expectedMilestoneData.get(0).get(VOTE),actualMilestoneData.get(0).get(VOTE)); + + } + + int milestoneStatus = getMilestoneStatus("Test_Proposal_1",2); + assertEquals(MILESTONE_REPORT_COMPLETED,milestoneStatus); + + } + + @Test + @Order(11) + public void completeProposal1() throws InterruptedException { + updateToApplicationPeriod(); + + int milestoneStatus = getMilestoneStatus("Test_Proposal_1",3); + assertEquals(MILESTONE_REPORT_APPROVED,milestoneStatus); + + List proposalsIpfs = readerClient.cpsCore.getProposalsKeysByStatus(COMPLETED); + assertEquals(proposalsIpfs.size(),1); + assertEquals(proposalsIpfs.get(0),"Test_Proposal_1"); + } + + + + private MilestoneVoteAttributes vote(int id, String vote){ MilestoneVoteAttributes milestoneVoteAttributes = new MilestoneVoteAttributes(); From 7218852eff77a76b595feede7df05314c0f2762e Mon Sep 17 00:00:00 2001 From: naneey Date: Sun, 24 Mar 2024 11:42:53 +0545 Subject: [PATCH 26/64] chore:added checks in happy flow --- .../cps/integration/CPSCoreIntegration.java | 106 +++++++++++++++--- 1 file changed, 90 insertions(+), 16 deletions(-) diff --git a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java index 0f61b4cd..7b0f1814 100644 --- a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java +++ b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java @@ -2,6 +2,7 @@ import com.eclipsesource.json.JsonObject; import community.icon.cps.score.lib.interfaces.CPSCoreInterface; +import community.icon.cps.score.lib.interfaces.CPSCoreInterface.MilestonesAttributes; import community.icon.cps.score.lib.interfaces.CPSCoreInterface.MilestoneVoteAttributes; import community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProposalAttributes; import community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProgressReportAttributes; @@ -12,8 +13,11 @@ import community.icon.cps.score.test.integration.config.BaseConfig; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; import score.Address; import static community.icon.cps.score.cpscore.utils.Constants.*; @@ -73,6 +77,7 @@ public void name(){ + @DisplayName("register all preps") @Test @Order(1) public void registerPrep(){ @@ -114,6 +119,7 @@ public void registerPrepExceptions(){ // TODO: handle deny list } + @DisplayName("unregister prep") @Test @Order(2) public void unregisterPrep(){ @@ -130,6 +136,7 @@ public void unregisterPrep(){ } + @DisplayName("check prep data") @Test @Order(3) public void loginAsPrep(){ @@ -145,6 +152,7 @@ public void loginAsPrep(){ assertEquals(expectedPrepData,actualPrepData); } + @DisplayName("submit proposal 1") @Test @Order(4) public void submitProposal(){ @@ -199,7 +207,7 @@ private void verifyProposalDetails(ProposalAttributes expectedDetails){ } - + @DisplayName("submit sponsor vote on first proposal") @Test @Order(5) public void submitSponsorVote(){ @@ -220,8 +228,11 @@ public void submitSponsorVote(){ Map proposalDetails = getProposalDetails("Test_Proposal_1"); assertEquals(sponsorBond, toBigInt((String) proposalDetails.get(SPONSOR_DEPOSIT_AMOUNT))); assertEquals(BOND_RECEIVED, proposalDetails.get(SPONSOR_DEPOSIT_STATUS)); + + assertEquals(BigInteger.valueOf(35).multiply(ICX),readerClient.bnUSD.balanceOf(sponsorPrep.getAddress())); } + @DisplayName("vote on first proposal") @Test() @Order(6) public void voteProposal() throws InterruptedException { @@ -250,13 +261,48 @@ public void voteProposal() throws InterruptedException { // assertEquals(toBigInt((String)proposalVote.get("approved_votes")),BigInteger.valueOf(9540000).multiply(ICX)); } + @DisplayName("pass proposal 1 and send the initial payement") @Test @Order(7) - public void submitMilestoneReport() throws InterruptedException { + public void transferFundsToProposal() throws InterruptedException { updateToApplicationPeriod(); Map periodStatus = getPeriodStatus(); assertEquals(periodStatus.get(PERIOD_NAME),"Application Period"); + Map contributorProject = getContributorFunds(testClient.getAddress()); + List> contributorData = (List> )contributorProject.get("data"); + + assertEquals(toBigInt((String) contributorData.get(0).get("installment_amount")),BigInteger.valueOf(30).multiply(ICX)); + assertEquals(toBigInt((String) contributorData.get(0).get("total_budget")),BigInteger.valueOf(100).multiply(ICX)); + assertEquals( contributorData.get(0).get("total_installment_count"),"0x3"); + assertEquals(toBigInt((String) contributorData.get(0).get("total_installment_paid")),BigInteger.valueOf(10).multiply(ICX)); + assertEquals(contributorProject.get("project_count"),"0x1"); + + + Map sponsorProject = getSponsorFunds(cpsClients.get(0).getAddress()); + + List> sponsorData = (List> )sponsorProject.get("data"); + assertEquals(toBigInt((String) sponsorData.get(0).get("installment_amount")),BigInteger.valueOf(6).multiply(ICX).divide(BigInteger.TEN)); + assertEquals(toBigInt((String) sponsorData.get(0).get("sponsor_bond_amount")),BigInteger.valueOf(15).multiply(ICX)); + assertEquals( sponsorData.get(0).get("total_installment_count"),"0x3"); + assertEquals(toBigInt((String) sponsorData.get(0).get("total_installment_paid")),BigInteger.valueOf(2).multiply(ICX).divide(BigInteger.TEN)); + assertEquals(toBigInt((String) sponsorProject.get("withdraw_amount_bnUSD")),BigInteger.valueOf(2).multiply(ICX).divide(BigInteger.TEN)); + } + + + + private Map getContributorFunds(Address contributorAddr){ + return readerClient.cpsTreasury.getContributorProjectedFund(contributorAddr); + } + + private Map getSponsorFunds(Address sponsorAddr){ + return readerClient.cpsTreasury.getSponsorProjectedFund(sponsorAddr); + } + @DisplayName("submit first milestone") + @Test + @Order(8) + public void submitMilestoneReport(){ + List proposalsIpfs = readerClient.cpsCore.getProposalsKeysByStatus(ACTIVE); assertEquals(proposalsIpfs.size(),1); assertEquals(proposalsIpfs.get(0),"Test_Proposal_1"); @@ -301,8 +347,9 @@ private ProgressReportAttributes createProgressReport(String no){ } + @DisplayName("vote on first progress report") @Test - @Order(8) + @Order(9) public void voteOnMilestone() throws InterruptedException { updateNextBlock(); ownerClient.cpsCore.updatePeriod(); @@ -331,7 +378,6 @@ public void voteOnMilestone() throws InterruptedException { assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)),7); assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)),0); -// assertEquals(milestoneVoteResult.get(DATA),expectedMilestoneData); List> actualMilestoneData = (List>) milestoneVoteResult.get(DATA); @@ -363,7 +409,7 @@ private Map getProgressReportVote(String reportHash){ @DisplayName("submitting all remaining milestones") @Test - @Order(9) + @Order(10) public void submitAllMilestoneReport() throws InterruptedException { updateToApplicationPeriod(); Map periodStatus = getPeriodStatus(); @@ -372,6 +418,26 @@ public void submitAllMilestoneReport() throws InterruptedException { int milestoneStatus = getMilestoneStatus("Test_Proposal_1",1); assertEquals(MILESTONE_REPORT_APPROVED,milestoneStatus); + + // verifying installment count and funds record + Map contributorProject = getContributorFunds(testClient.getAddress()); + List> contributorData = (List> )contributorProject.get("data"); + assertEquals(toBigInt((String) contributorData.get(0).get("installment_amount")),BigInteger.valueOf(40).multiply(ICX)); + assertEquals(toBigInt((String) contributorData.get(0).get("total_installment_paid")),BigInteger.valueOf(40).multiply(ICX)); + assertEquals( contributorData.get(0).get("total_times_installment_paid"),"0x1"); + assertEquals(contributorProject.get("project_count"),"0x1"); + assertEquals(toBigInt((String) contributorProject.get("withdraw_amount_bnUSD")),BigInteger.valueOf(40).multiply(ICX)); + + + + Map sponsorProject = getSponsorFunds(cpsClients.get(0).getAddress()); + List> sponsorData = (List> )sponsorProject.get("data"); + assertEquals(toBigInt((String) sponsorData.get(0).get("installment_amount")),BigInteger.valueOf(6).multiply(ICX).divide(BigInteger.TEN)); + assertEquals(toBigInt((String) sponsorData.get(0).get("total_installment_paid")),BigInteger.valueOf(8).multiply(ICX).divide(BigInteger.TEN)); + assertEquals( sponsorData.get(0).get("total_times_installment_paid"),"0x1"); + assertEquals(toBigInt((String) sponsorProject.get("withdraw_amount_bnUSD")),BigInteger.valueOf(8).multiply(ICX).divide(BigInteger.TEN)); + + CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("2"); CPSCoreInterface.MilestoneSubmission submissionNo2 = new CPSCoreInterface.MilestoneSubmission(); @@ -389,26 +455,18 @@ public void submitAllMilestoneReport() throws InterruptedException { Map progressReportDetails = getProgressReportDetails("Report_Proposal_2"); - System.out.println("-----details"+progressReportDetails); assertEquals(2,toInt((String) progressReportDetails.get(MILESTONE_SUBMITTED_COUNT))); // assertEquals(new String[]{"0x2","0x3"},progressReportDetails.get("milestoneId")); assertEquals(WAITING,progressReportDetails.get(STATUS)); assertEquals("Report_2",progressReportDetails.get(PROGRESS_REPORT_TITLE)); assertEquals("Report_Proposal_2",progressReportDetails.get(REPORT_HASH)); - - - -// MilestoneVoteAttributes[] voteAttributes = new MilestoneVoteAttributes[]{vote(1,APPROVE)}; -// for (int i = 0; i < cpsClients.size(); i++) { -// cpsClients.get(i).cpsCore.voteProgressReport("Report_Proposal_1","Working well", -// voteAttributes,null,false); -// } } + @DisplayName("vote on progress report 2") @Test - @Order(10) + @Order(11) public void voteOnAllMilestone() throws InterruptedException { updateNextBlock(); @@ -455,17 +513,33 @@ public void voteOnAllMilestone() throws InterruptedException { } + @DisplayName("proposal 1 is completed and user claims reward") @Test - @Order(11) + @Order(12) public void completeProposal1() throws InterruptedException { updateToApplicationPeriod(); int milestoneStatus = getMilestoneStatus("Test_Proposal_1",3); assertEquals(MILESTONE_REPORT_APPROVED,milestoneStatus); + milestoneStatus = getMilestoneStatus("Test_Proposal_1",2); + assertEquals(MILESTONE_REPORT_APPROVED,milestoneStatus); + List proposalsIpfs = readerClient.cpsCore.getProposalsKeysByStatus(COMPLETED); assertEquals(proposalsIpfs.size(),1); assertEquals(proposalsIpfs.get(0),"Test_Proposal_1"); + + + assertEquals(BigInteger.ZERO,readerClient.bnUSD.balanceOf(testClient.getAddress())); + testClient.cpsTreasury.claimReward(); + assertEquals(BigInteger.valueOf(100).multiply(ICX),readerClient.bnUSD.balanceOf(testClient.getAddress())); + + CPSClient sponsorClient = cpsClients.get(0); + assertEquals(BigInteger.valueOf(35).multiply(ICX),readerClient.bnUSD.balanceOf(sponsorClient.getAddress())); + sponsorClient.cpsTreasury.claimReward(); + assertEquals(BigInteger.valueOf(37).multiply(ICX),readerClient.bnUSD.balanceOf(sponsorClient.getAddress())); + + } From 7e922d87457be8b20b8bbbe37647fb099f8dc5b6 Mon Sep 17 00:00:00 2001 From: naneey Date: Wed, 27 Mar 2024 15:15:03 +0545 Subject: [PATCH 27/64] chore:interface added --- .../cps/score/lib/interfaces/CPSCoreInterface.java | 8 +++++++- .../score/test/integration/config/BaseConfig.java | 1 + .../test/integration/scores/CPSCoreInterface.java | 8 +++++++- .../icon/cps/score/test/integration/scores/sICX.java | 12 ++++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSCoreInterface.java b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSCoreInterface.java index 5d7c5e64..e0cec7bd 100644 --- a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSCoreInterface.java +++ b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/CPSCoreInterface.java @@ -119,7 +119,7 @@ public static class MilestoneVoteAttributes { void registerPrep(); @External(readonly = true) - boolean checkPriorityVoting(Address prep); + boolean checkPriorityVoting(Address _prep); @External(readonly = true) List sortPriorityProposals(); @@ -192,6 +192,9 @@ public static class MilestoneVoteAttributes { @External(readonly = true) List getProposalsKeysByStatus(String _status); + @External(readonly = true) + Map getMilestonesReport(String ipfsKey, int milestoneId); + @External(readonly = true) int checkChangeVote(Address address, String ipfsHash, String proposalType); @@ -254,6 +257,9 @@ public static class MilestoneVoteAttributes { @External void updateNextBlock(int blockCount); + @External(readonly = true) + List> getRemainingProject(String projectType, Address walletAddress); + @External void updateContributor(String _ipfs_key, Address _new_contributor, Address _new_sponsor); diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java index 1ef63f4e..f33a68f2 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java @@ -56,6 +56,7 @@ public void call(){ cpsClient.cpsCore.toggleMaintenance(); cpsClient.cpsCore.setInitialBlock(); + cpsClient.cpsCore.setPrepPenaltyAmount(new BigInteger[]{BigInteger.valueOf(2),BigInteger.valueOf(5),BigInteger.TEN}); System.out.println("------system score------- " + addressMap.get("systemScore")); diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java index 26ab21eb..844dfb7a 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java @@ -119,7 +119,7 @@ public static class MilestoneVoteAttributes { void registerPrep(); @External(readonly = true) - boolean checkPriorityVoting(Address prep); + boolean checkPriorityVoting(Address _prep); @External(readonly = true) List sortPriorityProposals(); @@ -201,6 +201,9 @@ public static class MilestoneVoteAttributes { @External(readonly = true) int getMileststoneStatusOf(String proposalKey, int milestoneId); + @External(readonly = true) + Map getMilestonesReport(String ipfsKey, int milestoneId); + @External(readonly = true) int checkChangeVote(Address address, String ipfsHash, String proposalType); @@ -266,6 +269,9 @@ public static class MilestoneVoteAttributes { @External void updateNextBlock(int blockCount); + @External(readonly = true) + List> getRemainingProject(String projectType, Address walletAddress); + @External void updateContributor(String _ipfs_key, Address _new_contributor, Address _new_sponsor); diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/sICX.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/sICX.java index 0b5296fb..f96b124b 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/sICX.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/sICX.java @@ -1,4 +1,16 @@ package community.icon.cps.score.test.integration.scores; +import score.Address; +import score.annotation.External; +import score.annotation.Optional; + +import java.math.BigInteger; + public interface sICX { + + @External + void mintTo(Address _account, BigInteger _amount); + + @External + void transfer(Address _to, BigInteger _value, @Optional byte[] _data); } From ec3d6b81297de699fa34c50e4736b201c5ba56a2 Mon Sep 17 00:00:00 2001 From: naneey Date: Wed, 27 Mar 2024 15:19:11 +0545 Subject: [PATCH 28/64] chore:linter fixes --- .../cps/integration/CPSCoreIntegration.java | 373 +++++++++--------- 1 file changed, 189 insertions(+), 184 deletions(-) diff --git a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java index 7b0f1814..e9ffc5c0 100644 --- a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java +++ b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java @@ -47,9 +47,10 @@ public class CPSCoreIntegration implements ScoreIntegrationTest { private final BigInteger ICX = BigInteger.valueOf(10).pow(18); private static Map addressMap; - public static Map cpsClients = new HashMap<>(); + public static Map cpsClients = new HashMap<>(); + @BeforeAll - public static void setup() throws Exception{ + public static void setup() throws Exception { String contracts = "conf/contracts.json"; CPS cps = new CPS(contracts); @@ -63,7 +64,7 @@ public static void setup() throws Exception{ for (int i = 0; i < 7; i++) { String privKey = prepSet.toArray()[i].toString().substring(43); - cpsClients.put(i,cps.customClient(privKey)); + cpsClients.put(i, cps.customClient(privKey)); } @@ -71,20 +72,19 @@ public static void setup() throws Exception{ @Test @Order(1) - public void name(){ + public void name() { ownerClient.cpsCore.name(); } - @DisplayName("register all preps") @Test @Order(1) - public void registerPrep(){ + public void registerPrep() { // expected Prep address List expectedPrepAddress = new ArrayList<>(cpsClients.size()); - for (CPSClient prepClient:cpsClients.values()){ + for (CPSClient prepClient : cpsClients.values()) { prepClient.cpsCore.registerPrep(); expectedPrepAddress.add(prepClient.getAddress().toString()); @@ -97,32 +97,32 @@ public void registerPrep(){ actualPrepAddress.add((String) prep.get("address")); } - assertEquals(expectedPrepAddress,actualPrepAddress); + assertEquals(expectedPrepAddress, actualPrepAddress); // SYSTEM_INTERFACE = new SystemInterfaceScoreClient(godClient); // System.out.println(SYSTEM_INTERFACE.getPRepTerm()); } @Test @Order(2) - public void registerPrepExceptions(){ + public void registerPrepExceptions() { // readerClient tries to be registered as prep - assertUserRevert(new UserRevertException(TAG+": Not a P-Rep"), - () -> readerClient.cpsCore.registerPrep(),null); + assertUserRevert(new UserRevertException(TAG + ": Not a P-Rep"), + () -> readerClient.cpsCore.registerPrep(), null); // registered prep registers again CPSClient registeredPrep = cpsClients.get(0); - assertUserRevert(new UserRevertException(TAG+": P-Rep is already registered."), - () -> registeredPrep.cpsCore.registerPrep(),null); + assertUserRevert(new UserRevertException(TAG + ": P-Rep is already registered."), + () -> registeredPrep.cpsCore.registerPrep(), null); + - // TODO: handle deny list } @DisplayName("unregister prep") @Test @Order(2) - public void unregisterPrep(){ + public void unregisterPrep() { CPSClient prep1 = cpsClients.get(0); prep1.cpsCore.unregisterPrep(); @@ -130,7 +130,7 @@ public void unregisterPrep(){ Map expectedPrepData = unregisteredPrepData(); Map actualPrepData = loginPrep(prep1.getAddress()); - assertEquals(expectedPrepData,actualPrepData); + assertEquals(expectedPrepData, actualPrepData); prep1.cpsCore.registerPrep(); } @@ -139,23 +139,23 @@ public void unregisterPrep(){ @DisplayName("check prep data") @Test @Order(3) - public void loginAsPrep(){ + public void loginAsPrep() { // query period status - Map periodStatus = getPeriodStatus(); - assertEquals(periodStatus.get(PERIOD_NAME),"Application Period"); + Map periodStatus = getPeriodStatus(); + assertEquals(periodStatus.get(PERIOD_NAME), "Application Period"); CPSClient prep1 = cpsClients.get(0); // expected prep1 status Map expectedPrepData = votingPrepData(); Map actualPrepData = loginPrep(prep1.getAddress()); - assertEquals(expectedPrepData,actualPrepData); + assertEquals(expectedPrepData, actualPrepData); } @DisplayName("submit proposal 1") @Test @Order(4) - public void submitProposal(){ + public void submitProposal() { CPSClient prep1 = cpsClients.get(0); ProposalAttributes proposalAttributes = new ProposalAttributes(); @@ -165,7 +165,7 @@ public void submitProposal(){ proposalAttributes.total_budget = BigInteger.valueOf(100); proposalAttributes.token = bnUSD; proposalAttributes.sponsor_address = prep1.getAddress(); - proposalAttributes.ipfs_link ="https://proposal_1"; + proposalAttributes.ipfs_link = "https://proposal_1"; proposalAttributes.milestoneCount = 3; proposalAttributes.isMilestone = true; @@ -184,25 +184,25 @@ public void submitProposal(){ milestonesAttributes3.budget = BigInteger.valueOf(20).multiply(ICX); milestonesAttributes3.id = 3; // TODO: check if same id is sent - CPSCoreInterface.MilestonesAttributes[] milestonesAttributes =new CPSCoreInterface.MilestonesAttributes[] - {milestonesAttributes1, milestonesAttributes2,milestonesAttributes3}; - ((CPSCoreInterfaceScoreClient) testClient.cpsCore).submitProposal(BigInteger.valueOf(50).multiply(ICX),proposalAttributes,milestonesAttributes); + CPSCoreInterface.MilestonesAttributes[] milestonesAttributes = new CPSCoreInterface.MilestonesAttributes[] + {milestonesAttributes1, milestonesAttributes2, milestonesAttributes3}; + ((CPSCoreInterfaceScoreClient) testClient.cpsCore).submitProposal(BigInteger.valueOf(50).multiply(ICX), proposalAttributes, milestonesAttributes); List proposalsIpfs = readerClient.cpsCore.getProposalsKeysByStatus(SPONSOR_PENDING); - assertEquals(proposalsIpfs.size(),1); - assertEquals(proposalsIpfs.get(0),proposalAttributes.ipfs_hash); + assertEquals(proposalsIpfs.size(), 1); + assertEquals(proposalsIpfs.get(0), proposalAttributes.ipfs_hash); verifyProposalDetails(proposalAttributes); } - private void verifyProposalDetails(ProposalAttributes expectedDetails){ - Map actualDetails = getProposalDetails(expectedDetails.ipfs_hash); + private void verifyProposalDetails(ProposalAttributes expectedDetails) { + Map actualDetails = getProposalDetails(expectedDetails.ipfs_hash); assertEquals(actualDetails.get("project_title"), expectedDetails.project_title); assertEquals(actualDetails.get("sponsor_address"), expectedDetails.sponsor_address.toString()); assertEquals(actualDetails.get("ipfs_hash"), expectedDetails.ipfs_hash); - assertEquals(toInt((String)actualDetails.get("project_duration")), expectedDetails.project_duration); - assertEquals(toInt((String)actualDetails.get("milestoneCount")), expectedDetails.milestoneCount); - assertEquals(toBigInt((String)actualDetails.get("total_budget")), expectedDetails.total_budget.multiply(ICX)); + assertEquals(toInt((String) actualDetails.get("project_duration")), expectedDetails.project_duration); + assertEquals(toInt((String) actualDetails.get("milestoneCount")), expectedDetails.milestoneCount); + assertEquals(toBigInt((String) actualDetails.get("total_budget")), expectedDetails.total_budget.multiply(ICX)); } @@ -210,26 +210,26 @@ private void verifyProposalDetails(ProposalAttributes expectedDetails){ @DisplayName("submit sponsor vote on first proposal") @Test @Order(5) - public void submitSponsorVote(){ + public void submitSponsorVote() { CPSClient sponsorPrep = cpsClients.get(0); - bnUSDMint(sponsorPrep.getAddress(),BigInteger.valueOf(50).multiply(ICX)); + bnUSDMint(sponsorPrep.getAddress(), BigInteger.valueOf(50).multiply(ICX)); - byte[] data = createByteArray("sponsorVote", "Test_Proposal_1",ACCEPT, + byte[] data = createByteArray("sponsorVote", "Test_Proposal_1", ACCEPT, "Proposal looks good"); BigInteger sponsorBond = BigInteger.valueOf(15).multiply(ICX); - sponsorPrep.bnUSD.transfer(addressMap.get("cpsCore"),sponsorBond,data); + sponsorPrep.bnUSD.transfer(addressMap.get("cpsCore"), sponsorBond, data); List proposalsIpfs = readerClient.cpsCore.getProposalsKeysByStatus(PENDING); - assertEquals(proposalsIpfs.size(),1); - assertEquals(proposalsIpfs.get(0),"Test_Proposal_1"); + assertEquals(proposalsIpfs.size(), 1); + assertEquals(proposalsIpfs.get(0), "Test_Proposal_1"); - Map proposalDetails = getProposalDetails("Test_Proposal_1"); + Map proposalDetails = getProposalDetails("Test_Proposal_1"); assertEquals(sponsorBond, toBigInt((String) proposalDetails.get(SPONSOR_DEPOSIT_AMOUNT))); assertEquals(BOND_RECEIVED, proposalDetails.get(SPONSOR_DEPOSIT_STATUS)); - assertEquals(BigInteger.valueOf(35).multiply(ICX),readerClient.bnUSD.balanceOf(sponsorPrep.getAddress())); + assertEquals(BigInteger.valueOf(35).multiply(ICX), readerClient.bnUSD.balanceOf(sponsorPrep.getAddress())); } @DisplayName("vote on first proposal") @@ -240,23 +240,23 @@ public void voteProposal() throws InterruptedException { updateNextBlock(); ownerClient.cpsCore.updatePeriod(); - Map periodStatus = getPeriodStatus(); - assertEquals(periodStatus.get(PERIOD_NAME),"Voting Period"); + Map periodStatus = getPeriodStatus(); + assertEquals(periodStatus.get(PERIOD_NAME), "Voting Period"); - Map proposalVote = getProposalVote("Test_Proposal_1"); - assertEquals(toInt((String)proposalVote.get("total_voters")),0); - assertEquals(toInt((String)proposalVote.get("approve_voters")),0); - assertEquals(toInt((String)proposalVote.get("reject_voters")),0); + Map proposalVote = getProposalVote("Test_Proposal_1"); + assertEquals(toInt((String) proposalVote.get("total_voters")), 0); + assertEquals(toInt((String) proposalVote.get("approve_voters")), 0); + assertEquals(toInt((String) proposalVote.get("reject_voters")), 0); - for (CPSClient prepClient:cpsClients.values()){ - voteByPrep(prepClient,"Test_Proposal_1",APPROVE,"Seems fruitful",false); + for (CPSClient prepClient : cpsClients.values()) { + voteByPrep(prepClient, "Test_Proposal_1", APPROVE, "Seems fruitful", false); prepClient.cpsCore.votePriority(new String[]{"Test_Proposal_1"}); } proposalVote = getProposalVote("Test_Proposal_1"); - assertEquals(toInt((String)proposalVote.get("total_voters")),7); - assertEquals(toInt((String)proposalVote.get("approve_voters")),7); - assertEquals(toInt((String)proposalVote.get("reject_voters")),0); + assertEquals(toInt((String) proposalVote.get("total_voters")), 7); + assertEquals(toInt((String) proposalVote.get("approve_voters")), 7); + assertEquals(toInt((String) proposalVote.get("reject_voters")), 0); // TODO: approved votes does not match up // assertEquals(toBigInt((String)proposalVote.get("approved_votes")),BigInteger.valueOf(9540000).multiply(ICX)); } @@ -266,78 +266,78 @@ public void voteProposal() throws InterruptedException { @Order(7) public void transferFundsToProposal() throws InterruptedException { updateToApplicationPeriod(); - Map periodStatus = getPeriodStatus(); - assertEquals(periodStatus.get(PERIOD_NAME),"Application Period"); + Map periodStatus = getPeriodStatus(); + assertEquals(periodStatus.get(PERIOD_NAME), "Application Period"); - Map contributorProject = getContributorFunds(testClient.getAddress()); - List> contributorData = (List> )contributorProject.get("data"); + Map contributorProject = getContributorFunds(testClient.getAddress()); + List> contributorData = (List>) contributorProject.get("data"); - assertEquals(toBigInt((String) contributorData.get(0).get("installment_amount")),BigInteger.valueOf(30).multiply(ICX)); - assertEquals(toBigInt((String) contributorData.get(0).get("total_budget")),BigInteger.valueOf(100).multiply(ICX)); - assertEquals( contributorData.get(0).get("total_installment_count"),"0x3"); - assertEquals(toBigInt((String) contributorData.get(0).get("total_installment_paid")),BigInteger.valueOf(10).multiply(ICX)); - assertEquals(contributorProject.get("project_count"),"0x1"); + assertEquals(toBigInt((String) contributorData.get(0).get("installment_amount")), BigInteger.valueOf(30).multiply(ICX)); + assertEquals(toBigInt((String) contributorData.get(0).get("total_budget")), BigInteger.valueOf(100).multiply(ICX)); + assertEquals(contributorData.get(0).get("total_installment_count"), "0x3"); + assertEquals(toBigInt((String) contributorData.get(0).get("total_installment_paid")), BigInteger.valueOf(10).multiply(ICX)); + assertEquals(contributorProject.get("project_count"), "0x1"); - Map sponsorProject = getSponsorFunds(cpsClients.get(0).getAddress()); + Map sponsorProject = getSponsorFunds(cpsClients.get(0).getAddress()); - List> sponsorData = (List> )sponsorProject.get("data"); - assertEquals(toBigInt((String) sponsorData.get(0).get("installment_amount")),BigInteger.valueOf(6).multiply(ICX).divide(BigInteger.TEN)); - assertEquals(toBigInt((String) sponsorData.get(0).get("sponsor_bond_amount")),BigInteger.valueOf(15).multiply(ICX)); - assertEquals( sponsorData.get(0).get("total_installment_count"),"0x3"); - assertEquals(toBigInt((String) sponsorData.get(0).get("total_installment_paid")),BigInteger.valueOf(2).multiply(ICX).divide(BigInteger.TEN)); - assertEquals(toBigInt((String) sponsorProject.get("withdraw_amount_bnUSD")),BigInteger.valueOf(2).multiply(ICX).divide(BigInteger.TEN)); + List> sponsorData = (List>) sponsorProject.get("data"); + assertEquals(toBigInt((String) sponsorData.get(0).get("installment_amount")), BigInteger.valueOf(6).multiply(ICX).divide(BigInteger.TEN)); + assertEquals(toBigInt((String) sponsorData.get(0).get("sponsor_bond_amount")), BigInteger.valueOf(15).multiply(ICX)); + assertEquals(sponsorData.get(0).get("total_installment_count"), "0x3"); + assertEquals(toBigInt((String) sponsorData.get(0).get("total_installment_paid")), BigInteger.valueOf(2).multiply(ICX).divide(BigInteger.TEN)); + assertEquals(toBigInt((String) sponsorProject.get("withdraw_amount_bnUSD")), BigInteger.valueOf(2).multiply(ICX).divide(BigInteger.TEN)); } - - private Map getContributorFunds(Address contributorAddr){ + private Map getContributorFunds(Address contributorAddr) { return readerClient.cpsTreasury.getContributorProjectedFund(contributorAddr); } - private Map getSponsorFunds(Address sponsorAddr){ + private Map getSponsorFunds(Address sponsorAddr) { return readerClient.cpsTreasury.getSponsorProjectedFund(sponsorAddr); } + @DisplayName("submit first milestone") @Test @Order(8) - public void submitMilestoneReport(){ + public void submitMilestoneReport() { List proposalsIpfs = readerClient.cpsCore.getProposalsKeysByStatus(ACTIVE); - assertEquals(proposalsIpfs.size(),1); - assertEquals(proposalsIpfs.get(0),"Test_Proposal_1"); + assertEquals(proposalsIpfs.size(), 1); + assertEquals(proposalsIpfs.get(0), "Test_Proposal_1"); List> activeProposal = readerClient.cpsCore.getActiveProposals(testClient.getAddress()); - assertEquals( "0x0", activeProposal.get(0).get("new_progress_report")); + assertEquals("0x0", activeProposal.get(0).get("new_progress_report")); - CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("1"); + CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("1", "Test_Proposal_1"); CPSCoreInterface.MilestoneSubmission submission = new CPSCoreInterface.MilestoneSubmission(); submission.id = 1; submission.status = true; CPSCoreInterface.MilestoneSubmission[] milestoneSubmissions = new CPSCoreInterface.MilestoneSubmission[]{submission}; - testClient.cpsCore.submitProgressReport(progressReportAttributes,milestoneSubmissions); + testClient.cpsCore.submitProgressReport(progressReportAttributes, milestoneSubmissions); activeProposal = readerClient.cpsCore.getActiveProposals(testClient.getAddress()); - assertEquals( "0x1", activeProposal.get(0).get("new_progress_report")); + assertEquals("0x1", activeProposal.get(0).get("new_progress_report")); - Map progressReportDetails = getProgressReportDetails("Report_Proposal_1"); - assertEquals(1,toInt((String) progressReportDetails.get(MILESTONE_SUBMITTED_COUNT))); - assertEquals(WAITING,progressReportDetails.get(STATUS)); - assertEquals("Report_1",progressReportDetails.get(PROGRESS_REPORT_TITLE)); - assertEquals("Report_Proposal_1",progressReportDetails.get(REPORT_HASH)); + Map progressReportDetails = getProgressReportDetails("Test_Proposal_1_Report_Proposal_1"); + assertEquals(1, toInt((String) progressReportDetails.get(MILESTONE_SUBMITTED_COUNT))); + assertEquals(WAITING, progressReportDetails.get(STATUS)); + assertEquals("Test_Proposal_1_Report_1", progressReportDetails.get(PROGRESS_REPORT_TITLE)); + assertEquals("Test_Proposal_1_Report_Proposal_1", progressReportDetails.get(REPORT_HASH)); - int milestoneStatus = getMilestoneStatus("Test_Proposal_1",1); - assertEquals(MILESTONE_REPORT_COMPLETED,milestoneStatus); + int milestoneStatus = getMilestoneStatus("Test_Proposal_1", 1); + assertEquals(MILESTONE_REPORT_COMPLETED, milestoneStatus); } - private ProgressReportAttributes createProgressReport(String no){ + private ProgressReportAttributes createProgressReport(String no, String ipfsHash) { ProgressReportAttributes progressReportAttributes = new ProgressReportAttributes(); - progressReportAttributes.ipfs_hash = "Test_Proposal_1"; - progressReportAttributes.progress_report_title = "Report_"+no; - progressReportAttributes.report_hash ="Report_Proposal_"+no; - progressReportAttributes.ipfs_link = "https://proposal_"+ no; + progressReportAttributes.ipfs_hash = ipfsHash; + progressReportAttributes.progress_report_title = ipfsHash + "_Report_" + no; + progressReportAttributes.report_hash = ipfsHash + "_Report_Proposal_" + no; + progressReportAttributes.ipfs_link = "https://proposal_" + no; progressReportAttributes.budget_adjustment = false; progressReportAttributes.additional_budget = BigInteger.ZERO; progressReportAttributes.additional_month = 0; @@ -355,55 +355,55 @@ public void voteOnMilestone() throws InterruptedException { ownerClient.cpsCore.updatePeriod(); Thread.sleep(2000); - Map periodStatus = getPeriodStatus(); - assertEquals(periodStatus.get(PERIOD_NAME),"Voting Period"); + Map periodStatus = getPeriodStatus(); + assertEquals(periodStatus.get(PERIOD_NAME), "Voting Period"); - MilestoneVoteAttributes[] voteAttributes = new MilestoneVoteAttributes[]{vote(1,APPROVE)}; + MilestoneVoteAttributes[] voteAttributes = new MilestoneVoteAttributes[]{vote(1, APPROVE)}; - List> expectedMilestoneData = new ArrayList<>(7); + List> expectedMilestoneData = new ArrayList<>(7); for (int i = 0; i < cpsClients.size(); i++) { - cpsClients.get(i).cpsCore.voteProgressReport("Report_Proposal_1","Working well " + i, - voteAttributes,null,false); + cpsClients.get(i).cpsCore.voteProgressReport("Test_Proposal_1_Report_Proposal_1", "Working well " + i, + voteAttributes, null, false); expectedMilestoneData.add(Map.of( - ADDRESS,cpsClients.get(i).getAddress(), - PREP_NAME,cpsClients.get(i).getAddress(), - VOTE_REASON,"Working well "+ i, - VOTE,APPROVE)); + ADDRESS, cpsClients.get(i).getAddress(), + PREP_NAME, cpsClients.get(i).getAddress(), + VOTE_REASON, "Working well " + i, + VOTE, APPROVE)); } - Map progressReportVote = getProgressReportVote("Report_Proposal_1"); - assertEquals(toInt((String) progressReportVote.get("total_voters")),7); + Map progressReportVote = getProgressReportVote("Test_Proposal_1_Report_Proposal_1"); + assertEquals(toInt((String) progressReportVote.get("total_voters")), 7); - Map milestoneVoteResult = getMilestoneReport("Report_Proposal_1", 1); - assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)),7); - assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)),0); + Map milestoneVoteResult = getMilestoneReport("Test_Proposal_1_Report_Proposal_1", 1); + assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)), 7); + assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)), 0); - List> actualMilestoneData = (List>) milestoneVoteResult.get(DATA); + List> actualMilestoneData = (List>) milestoneVoteResult.get(DATA); for (int i = 0; i < 7; i++) { - assertEquals(expectedMilestoneData.get(0).get(ADDRESS).toString(),actualMilestoneData.get(0).get(ADDRESS)); + assertEquals(expectedMilestoneData.get(0).get(ADDRESS).toString(), actualMilestoneData.get(0).get(ADDRESS)); } - int milestoneStatus = getMilestoneStatus("Test_Proposal_1",1); - assertEquals(MILESTONE_REPORT_COMPLETED,milestoneStatus); + int milestoneStatus = getMilestoneStatus("Test_Proposal_1", 1); + assertEquals(MILESTONE_REPORT_COMPLETED, milestoneStatus); } - private int getMilestoneStatus(String ipfsHash, int milestoneId){ - return readerClient.cpsCore.getMileststoneStatusOf(ipfsHash,milestoneId); + private int getMilestoneStatus(String ipfsHash, int milestoneId) { + return readerClient.cpsCore.getMileststoneStatusOf(ipfsHash, milestoneId); } - private Map getMilestoneReport(String reportHash, int milestoneId){ - return readerClient.cpsCore.getMilestoneVoteResult(reportHash,milestoneId); + private Map getMilestoneReport(String reportHash, int milestoneId) { + return readerClient.cpsCore.getMilestoneVoteResult(reportHash, milestoneId); } - private Map getProgressReportDetails(String reportHash){ + private Map getProgressReportDetails(String reportHash) { return readerClient.cpsCore.getProgressReportsByHash(reportHash); } - private Map getProgressReportVote(String reportHash){ + private Map getProgressReportVote(String reportHash) { return readerClient.cpsCore.getProgressReportResult(reportHash); } @@ -412,33 +412,32 @@ private Map getProgressReportVote(String reportHash){ @Order(10) public void submitAllMilestoneReport() throws InterruptedException { updateToApplicationPeriod(); - Map periodStatus = getPeriodStatus(); - assertEquals(periodStatus.get(PERIOD_NAME),"Application Period"); + Map periodStatus = getPeriodStatus(); + assertEquals(periodStatus.get(PERIOD_NAME), "Application Period"); - int milestoneStatus = getMilestoneStatus("Test_Proposal_1",1); - assertEquals(MILESTONE_REPORT_APPROVED,milestoneStatus); + int milestoneStatus = getMilestoneStatus("Test_Proposal_1", 1); + assertEquals(MILESTONE_REPORT_APPROVED, milestoneStatus); // verifying installment count and funds record - Map contributorProject = getContributorFunds(testClient.getAddress()); - List> contributorData = (List> )contributorProject.get("data"); - assertEquals(toBigInt((String) contributorData.get(0).get("installment_amount")),BigInteger.valueOf(40).multiply(ICX)); - assertEquals(toBigInt((String) contributorData.get(0).get("total_installment_paid")),BigInteger.valueOf(40).multiply(ICX)); - assertEquals( contributorData.get(0).get("total_times_installment_paid"),"0x1"); - assertEquals(contributorProject.get("project_count"),"0x1"); - assertEquals(toBigInt((String) contributorProject.get("withdraw_amount_bnUSD")),BigInteger.valueOf(40).multiply(ICX)); - + Map contributorProject = getContributorFunds(testClient.getAddress()); + List> contributorData = (List>) contributorProject.get("data"); + assertEquals(toBigInt((String) contributorData.get(0).get("installment_amount")), BigInteger.valueOf(40).multiply(ICX)); + assertEquals(toBigInt((String) contributorData.get(0).get("total_installment_paid")), BigInteger.valueOf(40).multiply(ICX)); + assertEquals(contributorData.get(0).get("total_times_installment_paid"), "0x1"); + assertEquals(contributorProject.get("project_count"), "0x1"); + assertEquals(toBigInt((String) contributorProject.get("withdraw_amount_bnUSD")), BigInteger.valueOf(40).multiply(ICX)); - Map sponsorProject = getSponsorFunds(cpsClients.get(0).getAddress()); - List> sponsorData = (List> )sponsorProject.get("data"); - assertEquals(toBigInt((String) sponsorData.get(0).get("installment_amount")),BigInteger.valueOf(6).multiply(ICX).divide(BigInteger.TEN)); - assertEquals(toBigInt((String) sponsorData.get(0).get("total_installment_paid")),BigInteger.valueOf(8).multiply(ICX).divide(BigInteger.TEN)); - assertEquals( sponsorData.get(0).get("total_times_installment_paid"),"0x1"); - assertEquals(toBigInt((String) sponsorProject.get("withdraw_amount_bnUSD")),BigInteger.valueOf(8).multiply(ICX).divide(BigInteger.TEN)); + Map sponsorProject = getSponsorFunds(cpsClients.get(0).getAddress()); + List> sponsorData = (List>) sponsorProject.get("data"); + assertEquals(toBigInt((String) sponsorData.get(0).get("installment_amount")), BigInteger.valueOf(6).multiply(ICX).divide(BigInteger.TEN)); + assertEquals(toBigInt((String) sponsorData.get(0).get("total_installment_paid")), BigInteger.valueOf(8).multiply(ICX).divide(BigInteger.TEN)); + assertEquals(sponsorData.get(0).get("total_times_installment_paid"), "0x1"); + assertEquals(toBigInt((String) sponsorProject.get("withdraw_amount_bnUSD")), BigInteger.valueOf(8).multiply(ICX).divide(BigInteger.TEN)); - CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("2"); + CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("2", "Test_Proposal_1"); CPSCoreInterface.MilestoneSubmission submissionNo2 = new CPSCoreInterface.MilestoneSubmission(); submissionNo2.id = 2; @@ -449,17 +448,17 @@ public void submitAllMilestoneReport() throws InterruptedException { submissionNo3.status = true; CPSCoreInterface.MilestoneSubmission[] milestoneSubmissions = new CPSCoreInterface.MilestoneSubmission[]{ - submissionNo2,submissionNo3}; + submissionNo2, submissionNo3}; - testClient.cpsCore.submitProgressReport(progressReportAttributes,milestoneSubmissions); + testClient.cpsCore.submitProgressReport(progressReportAttributes, milestoneSubmissions); - Map progressReportDetails = getProgressReportDetails("Report_Proposal_2"); - assertEquals(2,toInt((String) progressReportDetails.get(MILESTONE_SUBMITTED_COUNT))); + Map progressReportDetails = getProgressReportDetails("Test_Proposal_1_Report_Proposal_2"); + assertEquals(2, toInt((String) progressReportDetails.get(MILESTONE_SUBMITTED_COUNT))); // assertEquals(new String[]{"0x2","0x3"},progressReportDetails.get("milestoneId")); - assertEquals(WAITING,progressReportDetails.get(STATUS)); - assertEquals("Report_2",progressReportDetails.get(PROGRESS_REPORT_TITLE)); - assertEquals("Report_Proposal_2",progressReportDetails.get(REPORT_HASH)); + assertEquals(WAITING, progressReportDetails.get(STATUS)); + assertEquals("Test_Proposal_1_Report_2", progressReportDetails.get(PROGRESS_REPORT_TITLE)); + assertEquals("Test_Proposal_1_Report_Proposal_2", progressReportDetails.get(REPORT_HASH)); } @@ -473,43 +472,43 @@ public void voteOnAllMilestone() throws InterruptedException { ownerClient.cpsCore.updatePeriod(); Thread.sleep(2000); - Map periodStatus = getPeriodStatus(); - assertEquals(periodStatus.get(PERIOD_NAME),"Voting Period"); + Map periodStatus = getPeriodStatus(); + assertEquals(periodStatus.get(PERIOD_NAME), "Voting Period"); - MilestoneVoteAttributes[] voteAttributes = new MilestoneVoteAttributes[]{vote(2,APPROVE), vote(3,APPROVE)}; + MilestoneVoteAttributes[] voteAttributes = new MilestoneVoteAttributes[]{vote(2, APPROVE), vote(3, APPROVE)}; - List> expectedMilestoneData = new ArrayList<>(7); + List> expectedMilestoneData = new ArrayList<>(7); for (int i = 0; i < cpsClients.size(); i++) { - cpsClients.get(i).cpsCore.voteProgressReport("Report_Proposal_2","Project is completed " + i, - voteAttributes,null,false); + cpsClients.get(i).cpsCore.voteProgressReport("Test_Proposal_1_Report_Proposal_2", "Project is completed " + i, + voteAttributes, null, false); expectedMilestoneData.add(Map.of( - ADDRESS,cpsClients.get(i).getAddress(), - PREP_NAME,cpsClients.get(i).getAddress(), - VOTE_REASON,"Project is completed "+ i, - VOTE,APPROVE)); + ADDRESS, cpsClients.get(i).getAddress(), + PREP_NAME, cpsClients.get(i).getAddress(), + VOTE_REASON, "Project is completed " + i, + VOTE, APPROVE)); } - Map progressReportVote = getProgressReportVote("Report_Proposal_2"); - assertEquals(toInt((String) progressReportVote.get("total_voters")),7); + Map progressReportVote = getProgressReportVote("Test_Proposal_1_Report_Proposal_2"); + assertEquals(toInt((String) progressReportVote.get("total_voters")), 7); - Map milestoneVoteResult = getMilestoneReport("Report_Proposal_2", 2); - assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)),7); - assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)),0); + Map milestoneVoteResult = getMilestoneReport("Test_Proposal_1_Report_Proposal_2", 2); + assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)), 7); + assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)), 0); // assertEquals(milestoneVoteResult.get(DATA),expectedMilestoneData); - List> actualMilestoneData = (List>) milestoneVoteResult.get(DATA); + List> actualMilestoneData = (List>) milestoneVoteResult.get(DATA); for (int i = 0; i < 7; i++) { - assertEquals(expectedMilestoneData.get(0).get(ADDRESS).toString(),actualMilestoneData.get(0).get(ADDRESS)); - assertEquals(expectedMilestoneData.get(0).get(PREP_NAME).toString(),actualMilestoneData.get(0).get(PREP_NAME)); - assertEquals(expectedMilestoneData.get(0).get(VOTE_REASON),actualMilestoneData.get(0).get(VOTE_REASON)); - assertEquals(expectedMilestoneData.get(0).get(VOTE),actualMilestoneData.get(0).get(VOTE)); + assertEquals(expectedMilestoneData.get(0).get(ADDRESS).toString(), actualMilestoneData.get(0).get(ADDRESS)); + assertEquals(expectedMilestoneData.get(0).get(PREP_NAME).toString(), actualMilestoneData.get(0).get(PREP_NAME)); + assertEquals(expectedMilestoneData.get(0).get(VOTE_REASON), actualMilestoneData.get(0).get(VOTE_REASON)); + assertEquals(expectedMilestoneData.get(0).get(VOTE), actualMilestoneData.get(0).get(VOTE)); } - int milestoneStatus = getMilestoneStatus("Test_Proposal_1",2); - assertEquals(MILESTONE_REPORT_COMPLETED,milestoneStatus); + int milestoneStatus = getMilestoneStatus("Test_Proposal_1", 2); + assertEquals(MILESTONE_REPORT_COMPLETED, milestoneStatus); } @@ -519,25 +518,25 @@ public void voteOnAllMilestone() throws InterruptedException { public void completeProposal1() throws InterruptedException { updateToApplicationPeriod(); - int milestoneStatus = getMilestoneStatus("Test_Proposal_1",3); - assertEquals(MILESTONE_REPORT_APPROVED,milestoneStatus); + int milestoneStatus = getMilestoneStatus("Test_Proposal_1", 3); + assertEquals(MILESTONE_REPORT_APPROVED, milestoneStatus); - milestoneStatus = getMilestoneStatus("Test_Proposal_1",2); - assertEquals(MILESTONE_REPORT_APPROVED,milestoneStatus); + milestoneStatus = getMilestoneStatus("Test_Proposal_1", 2); + assertEquals(MILESTONE_REPORT_APPROVED, milestoneStatus); List proposalsIpfs = readerClient.cpsCore.getProposalsKeysByStatus(COMPLETED); - assertEquals(proposalsIpfs.size(),1); - assertEquals(proposalsIpfs.get(0),"Test_Proposal_1"); + assertEquals(proposalsIpfs.size(), 1); + assertEquals(proposalsIpfs.get(0), "Test_Proposal_1"); - assertEquals(BigInteger.ZERO,readerClient.bnUSD.balanceOf(testClient.getAddress())); + assertEquals(BigInteger.ZERO, readerClient.bnUSD.balanceOf(testClient.getAddress())); testClient.cpsTreasury.claimReward(); - assertEquals(BigInteger.valueOf(100).multiply(ICX),readerClient.bnUSD.balanceOf(testClient.getAddress())); + assertEquals(BigInteger.valueOf(100).multiply(ICX), readerClient.bnUSD.balanceOf(testClient.getAddress())); CPSClient sponsorClient = cpsClients.get(0); - assertEquals(BigInteger.valueOf(35).multiply(ICX),readerClient.bnUSD.balanceOf(sponsorClient.getAddress())); + assertEquals(BigInteger.valueOf(35).multiply(ICX), readerClient.bnUSD.balanceOf(sponsorClient.getAddress())); sponsorClient.cpsTreasury.claimReward(); - assertEquals(BigInteger.valueOf(37).multiply(ICX),readerClient.bnUSD.balanceOf(sponsorClient.getAddress())); + assertEquals(BigInteger.valueOf(37).multiply(ICX), readerClient.bnUSD.balanceOf(sponsorClient.getAddress())); } @@ -545,7 +544,7 @@ public void completeProposal1() throws InterruptedException { - private MilestoneVoteAttributes vote(int id, String vote){ + private MilestoneVoteAttributes vote(int id, String vote) { MilestoneVoteAttributes milestoneVoteAttributes = new MilestoneVoteAttributes(); milestoneVoteAttributes.id = id; @@ -554,7 +553,6 @@ private MilestoneVoteAttributes vote(int id, String vote){ } - private void updateToApplicationPeriod() throws InterruptedException { updateNextBlock(); ownerClient.cpsCore.updatePeriod(); @@ -573,18 +571,17 @@ private Integer toInt(String inputString) { } - private void voteByPrep(CPSClient caller, String ipfsKey, String vote, String voteReason, - @Optional boolean voteChange){ + @Optional boolean voteChange) { - caller.cpsCore.voteProposal(ipfsKey,vote,voteReason,voteChange); + caller.cpsCore.voteProposal(ipfsKey, vote, voteReason, voteChange); } - private Map getProposalDetails(String ipfsHash){ + private Map getProposalDetails(String ipfsHash) { return readerClient.cpsCore.getProposalDetailsByHash(ipfsHash); } - private Map getProposalVote(String ipfsHash){ + private Map getProposalVote(String ipfsHash) { return readerClient.cpsCore.getVoteResult(ipfsHash); } @@ -613,34 +610,42 @@ private void bnUSDMint(Address to, BigInteger amount){ } - private Map getPeriodStatus(){ + private Map getPeriodStatus() { return readerClient.cpsCore.getPeriodStatus(); } - private Map loginPrep(Address prepAddress){ + private Map loginPrep(Address prepAddress) { return readerClient.cpsCore.loginPrep(prepAddress); } - private Map unregisteredPrepData(){ + private Map unregisteredPrepData() { return Map.of(IS_PREP, BigInteger.ONE, IS_REGISTERED, BigInteger.ZERO, PAY_PENALTY, BigInteger.ZERO, VOTING_PREP, BigInteger.ZERO); } - private Map votingPrepData(){ + private Map votingPrepData() { return Map.of(IS_PREP, BigInteger.ONE, IS_REGISTERED, BigInteger.ONE, PAY_PENALTY, BigInteger.ZERO, VOTING_PREP, BigInteger.ONE); } - private Map registerPrepData(){ + private Map registerPrepData() { return Map.of(IS_PREP, BigInteger.ONE, IS_REGISTERED, BigInteger.ONE, PAY_PENALTY, BigInteger.ZERO, VOTING_PREP, BigInteger.ZERO); } + private Map denyPrepData() { + return Map.of(IS_PREP, BigInteger.ONE, + IS_REGISTERED, BigInteger.ZERO, + PAY_PENALTY, BigInteger.ONE, + PENALTY_AMOUNT1, (BigInteger.TWO.multiply(ICX)).divide(BigInteger.valueOf(100)), + VOTING_PREP, BigInteger.ZERO); + } + } From f9211c725a50b76e60e93e178a8a800d12b35584 Mon Sep 17 00:00:00 2001 From: naneey Date: Wed, 27 Mar 2024 15:21:17 +0545 Subject: [PATCH 29/64] chore: exception cases tests added --- .../cps/integration/CPSCoreIntegration.java | 1114 ++++++++++++++++- 1 file changed, 1112 insertions(+), 2 deletions(-) diff --git a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java index 7b0f1814..a5c34134 100644 --- a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java +++ b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java @@ -32,6 +32,7 @@ import java.util.Set; import static community.icon.cps.score.test.integration.Environment.preps; +import static org.junit.jupiter.api.Assertions.assertTrue; import community.icon.cps.score.test.integration.scores.SystemInterfaceScoreClient; import score.UserRevertException; @@ -539,10 +540,1109 @@ public void completeProposal1() throws InterruptedException { sponsorClient.cpsTreasury.claimReward(); assertEquals(BigInteger.valueOf(37).multiply(ICX),readerClient.bnUSD.balanceOf(sponsorClient.getAddress())); + // sponsor bond is returned after completion of project + sponsorClient.cpsCore.claimSponsorBond(); + assertEquals(BigInteger.valueOf(52).multiply(ICX), readerClient.bnUSD.balanceOf(sponsorClient.getAddress())); + } + // @DisplayName("proposal with greater milestone than project duration") + @DisplayName("submit proposal in different conditions") + @Nested + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class submitProposal { + CPSClient sponsorPrep = cpsClients.get(0); + + @DisplayName("proposal with zero milestone") + @Test + @Order(1) + public void zeroMilestoneProposal() { + CPSClient sponsorPrep = cpsClients.get(0); + + ProposalAttributes proposalAttributes = new ProposalAttributes(); + + proposalAttributes.ipfs_hash = "Test_Proposal_2"; + proposalAttributes.project_title = "Proposal_2"; + proposalAttributes.project_duration = 3; + proposalAttributes.total_budget = BigInteger.valueOf(100); + proposalAttributes.token = bnUSD; + proposalAttributes.sponsor_address = sponsorPrep.getAddress(); + proposalAttributes.ipfs_link = "https://proposal_1"; + proposalAttributes.milestoneCount = 3; + proposalAttributes.isMilestone = true; + ; + + CPSCoreInterface.MilestonesAttributes[] milestonesAttributes = new MilestonesAttributes[] + {}; + + assertUserRevert(new UserRevertException(TAG + ": Milestone count mismatch"), + () -> ((CPSCoreInterfaceScoreClient) testClient.cpsCore).submitProposal(BigInteger.valueOf(50).multiply(ICX), proposalAttributes, milestonesAttributes), + null); + } + + @DisplayName("submit proposal when maintenance is on") + @Test + @Order(1) + public void maintenanceModeOff() { + + ownerClient.cpsCore.toggleMaintenance(); + + CPSClient sponsorPrep = cpsClients.get(0); + + ProposalAttributes proposalAttributes = new ProposalAttributes(); + + proposalAttributes.ipfs_hash = "Test_Proposal_2"; + proposalAttributes.project_title = "Proposal_2"; + proposalAttributes.project_duration = 1; + proposalAttributes.total_budget = BigInteger.valueOf(50); + proposalAttributes.token = bnUSD; + proposalAttributes.sponsor_address = sponsorPrep.getAddress(); + proposalAttributes.ipfs_link = "https://proposal_1"; + proposalAttributes.milestoneCount = 1; + proposalAttributes.isMilestone = true; + + CPSCoreInterface.MilestonesAttributes milestonesAttributes1 = new CPSCoreInterface.MilestonesAttributes(); + milestonesAttributes1.completionPeriod = 1; + milestonesAttributes1.budget = BigInteger.valueOf(50).multiply(ICX); + milestonesAttributes1.id = 1; + + CPSCoreInterface.MilestonesAttributes[] milestonesAttributes = new MilestonesAttributes[] + {milestonesAttributes1}; + + assertUserRevert(new UserRevertException(TAG + ": Maintenance mode is on. Will resume soon."), + () -> ((CPSCoreInterfaceScoreClient) testClient.cpsCore).submitProposal(BigInteger.valueOf(50).multiply(ICX), proposalAttributes, milestonesAttributes), + null); + + } + + @DisplayName("submit proposal when same milestone id") + @Test + @Order(1) + public void milestoneWithSameId() { + + ownerClient.cpsCore.toggleMaintenance(); + + CPSClient sponsorPrep = cpsClients.get(0); + + ProposalAttributes proposalAttributes = new ProposalAttributes(); + + proposalAttributes.ipfs_hash = "Test_Proposal_2"; + proposalAttributes.project_title = "Proposal_2"; + proposalAttributes.project_duration = 2; + proposalAttributes.total_budget = BigInteger.valueOf(50); + proposalAttributes.token = bnUSD; + proposalAttributes.sponsor_address = sponsorPrep.getAddress(); + proposalAttributes.ipfs_link = "https://proposal_1"; + proposalAttributes.milestoneCount = 2; + proposalAttributes.isMilestone = true; + + CPSCoreInterface.MilestonesAttributes milestonesAttributes1 = new CPSCoreInterface.MilestonesAttributes(); + milestonesAttributes1.completionPeriod = 1; + milestonesAttributes1.budget = BigInteger.valueOf(50).multiply(ICX); + milestonesAttributes1.id = 1; + + CPSCoreInterface.MilestonesAttributes milestonesAttributes2 = new CPSCoreInterface.MilestonesAttributes(); + milestonesAttributes2.completionPeriod = 2; + milestonesAttributes2.budget = BigInteger.valueOf(40).multiply(ICX); + milestonesAttributes2.id = 1; + + CPSCoreInterface.MilestonesAttributes[] milestonesAttributes = new MilestonesAttributes[] + {milestonesAttributes1, milestonesAttributes2}; + + assertUserRevert(new UserRevertException(TAG + ":: Total milestone budget and project budget is not equal"), + () -> ((CPSCoreInterfaceScoreClient) testClient.cpsCore).submitProposal(BigInteger.valueOf(50).multiply(ICX), proposalAttributes, milestonesAttributes), + null); + + } + + @DisplayName("submit proposal when with higher milestone count than project duration") + @Test + @Order(2) + public void proposalWithMoreMilestone() { + +// ownerClient.cpsCore.toggleMaintenance(); + + CPSClient sponsorPrep = cpsClients.get(0); + + ProposalAttributes proposalAttributes = new ProposalAttributes(); + + proposalAttributes.ipfs_hash = "Test_Proposal_2"; + proposalAttributes.project_title = "Proposal_2"; + proposalAttributes.project_duration = 2; + proposalAttributes.total_budget = BigInteger.valueOf(100); + proposalAttributes.token = bnUSD; + proposalAttributes.sponsor_address = sponsorPrep.getAddress(); + proposalAttributes.ipfs_link = "https://proposal_1"; + proposalAttributes.milestoneCount = 3; + proposalAttributes.isMilestone = true; + + CPSCoreInterface.MilestonesAttributes milestonesAttributes1 = new CPSCoreInterface.MilestonesAttributes(); + milestonesAttributes1.completionPeriod = 1; + milestonesAttributes1.budget = BigInteger.valueOf(30).multiply(ICX); + milestonesAttributes1.id = 1; + + CPSCoreInterface.MilestonesAttributes milestonesAttributes2 = new CPSCoreInterface.MilestonesAttributes(); + milestonesAttributes2.completionPeriod = 2; + milestonesAttributes2.budget = BigInteger.valueOf(40).multiply(ICX); + milestonesAttributes2.id = 2; + + CPSCoreInterface.MilestonesAttributes milestonesAttributes3 = new CPSCoreInterface.MilestonesAttributes(); + milestonesAttributes3.completionPeriod = 3; + milestonesAttributes3.budget = BigInteger.valueOf(20).multiply(ICX); + milestonesAttributes3.id = 3; + + + CPSCoreInterface.MilestonesAttributes[] milestonesAttributes = new MilestonesAttributes[] + {milestonesAttributes1, milestonesAttributes2, milestonesAttributes3}; + + ((CPSCoreInterfaceScoreClient) testClient.cpsCore).submitProposal(BigInteger.valueOf(50).multiply(ICX), + proposalAttributes, milestonesAttributes); + } + + @DisplayName("proposal with higher fund than in treasury") + @Test + @Order(2) + public void proposalWithHighBudget() { + + + BigInteger treasuryBalance = readerClient.bnUSD.balanceOf(addressMap.get("cpfTreasury")); + BigInteger totalBudget = BigInteger.valueOf(6000); + + assertTrue(treasuryBalance.compareTo(totalBudget.multiply(ICX)) < 0); + + ProposalAttributes proposalAttributes = new ProposalAttributes(); + + proposalAttributes.ipfs_hash = "Test_Proposal_3"; + proposalAttributes.project_title = "Proposal_3"; + proposalAttributes.project_duration = 3; + proposalAttributes.total_budget = totalBudget; + proposalAttributes.token = bnUSD; + proposalAttributes.sponsor_address = sponsorPrep.getAddress(); + proposalAttributes.ipfs_link = "https://proposal_1"; + proposalAttributes.milestoneCount = 3; + proposalAttributes.isMilestone = true; + + CPSCoreInterface.MilestonesAttributes milestonesAttributes1 = new CPSCoreInterface.MilestonesAttributes(); + milestonesAttributes1.completionPeriod = 1; + milestonesAttributes1.budget = BigInteger.valueOf(3000).multiply(ICX); + milestonesAttributes1.id = 1; + + CPSCoreInterface.MilestonesAttributes milestonesAttributes2 = new CPSCoreInterface.MilestonesAttributes(); + milestonesAttributes2.completionPeriod = 2; + milestonesAttributes2.budget = BigInteger.valueOf(2000).multiply(ICX); + milestonesAttributes2.id = 2; + + CPSCoreInterface.MilestonesAttributes milestonesAttributes3 = new CPSCoreInterface.MilestonesAttributes(); + milestonesAttributes3.completionPeriod = 3; + milestonesAttributes3.budget = BigInteger.valueOf(400).multiply(ICX); + milestonesAttributes3.id = 3; + + + CPSCoreInterface.MilestonesAttributes[] milestonesAttributes = new MilestonesAttributes[] + {milestonesAttributes1, milestonesAttributes2, milestonesAttributes3}; + + ((CPSCoreInterfaceScoreClient) testClient.cpsCore).submitProposal(BigInteger.valueOf(50).multiply(ICX), + proposalAttributes, milestonesAttributes); + } + + @DisplayName("proposal rejected by sponsor") + @Test + @Order(2) + public void proposalRejectedBySponsor() { + + + ProposalAttributes proposalAttributes = new ProposalAttributes(); + + proposalAttributes.ipfs_hash = "Test_Proposal_4"; + proposalAttributes.project_title = "Proposal_4"; + proposalAttributes.project_duration = 1; + proposalAttributes.total_budget = BigInteger.valueOf(100); + proposalAttributes.token = bnUSD; + proposalAttributes.sponsor_address = sponsorPrep.getAddress(); + proposalAttributes.ipfs_link = "https://proposal_1"; + proposalAttributes.milestoneCount = 1; + proposalAttributes.isMilestone = true; + + CPSCoreInterface.MilestonesAttributes milestonesAttributes1 = new CPSCoreInterface.MilestonesAttributes(); + milestonesAttributes1.completionPeriod = 1; + milestonesAttributes1.budget = BigInteger.valueOf(90).multiply(ICX); + milestonesAttributes1.id = 1; + + + CPSCoreInterface.MilestonesAttributes[] milestonesAttributes = new MilestonesAttributes[] + {milestonesAttributes1}; + + ((CPSCoreInterfaceScoreClient) testClient.cpsCore).submitProposal(BigInteger.valueOf(50).multiply(ICX), + proposalAttributes, milestonesAttributes); + } + + @DisplayName("proposal which is not sincere") + @Test + @Order(2) + public void proposalWillBeRejected() { + ProposalAttributes proposalAttributes = new ProposalAttributes(); + + proposalAttributes.ipfs_hash = "Test_Proposal_5"; + proposalAttributes.project_title = "Proposal_5"; + proposalAttributes.project_duration = 1; + proposalAttributes.total_budget = BigInteger.valueOf(100); + proposalAttributes.token = bnUSD; + proposalAttributes.sponsor_address = sponsorPrep.getAddress(); + proposalAttributes.ipfs_link = "https://proposal_1"; + proposalAttributes.milestoneCount = 1; + proposalAttributes.isMilestone = true; + + CPSCoreInterface.MilestonesAttributes milestonesAttributes1 = new CPSCoreInterface.MilestonesAttributes(); + milestonesAttributes1.completionPeriod = 1; + milestonesAttributes1.budget = BigInteger.valueOf(90).multiply(ICX); + milestonesAttributes1.id = 1; + + + CPSCoreInterface.MilestonesAttributes[] milestonesAttributes = new MilestonesAttributes[] + {milestonesAttributes1}; + + ((CPSCoreInterfaceScoreClient) testClient.cpsCore).submitProposal(BigInteger.valueOf(50).multiply(ICX), + proposalAttributes, milestonesAttributes); + } + + + @DisplayName("sponsor vote on the proposal") + @Test + @Order(3) + public void sponsorBondsWithProposals() { + + bnUSDMint(sponsorPrep.getAddress(), BigInteger.valueOf(1000).multiply(ICX)); + + BigInteger beforeBalance = readerClient.bnUSD.balanceOf(addressMap.get("cpsCore")); + + byte[] data = createByteArray("sponsorVote", "Test_Proposal_2", ACCEPT, + "Bonding with proposal 2"); + BigInteger sponsorBond = BigInteger.valueOf(15).multiply(ICX); + sponsorPrep.bnUSD.transfer(addressMap.get("cpsCore"), sponsorBond, data); + + BigInteger afterBalance = readerClient.bnUSD.balanceOf(addressMap.get("cpsCore")); + assertEquals(beforeBalance.add(sponsorBond), afterBalance); + + beforeBalance = afterBalance; + data = createByteArray("sponsorVote", "Test_Proposal_3", ACCEPT, + "Bonding with proposal 3"); + sponsorBond = BigInteger.valueOf(900).multiply(ICX); + sponsorPrep.bnUSD.transfer(addressMap.get("cpsCore"), sponsorBond, data); + + afterBalance = readerClient.bnUSD.balanceOf(addressMap.get("cpsCore")); + assertEquals(beforeBalance.add(sponsorBond), afterBalance); + + + beforeBalance = afterBalance; + data = createByteArray("sponsorVote", "Test_Proposal_4", REJECT, + "Rejecting proposal 4"); + sponsorBond = BigInteger.ZERO; + sponsorPrep.bnUSD.transfer(addressMap.get("cpsCore"), sponsorBond, data); + + afterBalance = readerClient.bnUSD.balanceOf(addressMap.get("cpsCore")); + assertEquals(beforeBalance.add(sponsorBond), afterBalance); + + beforeBalance = afterBalance; + data = createByteArray("sponsorVote", "Test_Proposal_5", ACCEPT, + "Bonding with proposal 5"); + sponsorBond = BigInteger.valueOf(15).multiply(ICX); + sponsorPrep.bnUSD.transfer(addressMap.get("cpsCore"), sponsorBond, data); + afterBalance = readerClient.bnUSD.balanceOf(addressMap.get("cpsCore")); + assertEquals(beforeBalance.add(sponsorBond), afterBalance); + + } + + + @DisplayName("voting on proposal conditions") + @Nested + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class voteProposal { + + String[] votingProposal = new String[]{"Test_Proposal_2", "Test_Proposal_5", "Test_Proposal_3"}; + + @DisplayName("verify proposal which are active") + @Test + @Order(3) + public void verifyPendingProposal() { + + List proposalKey = getProposalByStatus(PENDING); + + for (String key : votingProposal) { + assertTrue(proposalKey.contains(key)); + } + + } + + @DisplayName("vote on proposal with higher milestone count than project duration") + @Test + @Order(3) + public void voteOnProposalWithMoreMilestone() throws InterruptedException { + updateNextBlock(); + ownerClient.cpsCore.updatePeriod(); + + Thread.sleep(2000); + verifyPeriod("Voting Period"); + + for (CPSClient prepClient : cpsClients.values()) { + voteByPrep(prepClient, "Test_Proposal_2", APPROVE, "Passing Proposal_2", false); + } + } + + @DisplayName("vote on proposal with higher fund than in treasury") + @Test + @Order(4) + public void voteOnProposalWithHighBudget() { + + for (CPSClient prepClient : cpsClients.values()) { + voteByPrep(prepClient, "Test_Proposal_3", APPROVE, "Passing Proposal_3", false); + } + } + + @DisplayName("reject proposal") + @Test + @Order(4) + public void rejectProposal() { + for (CPSClient prepClient : cpsClients.values()) { + + if (prepClient.equals(cpsClients.get(0))) { + voteByPrep(prepClient, "Test_Proposal_5", APPROVE, "Looks good", false); + continue; + } + voteByPrep(prepClient, "Test_Proposal_5", REJECT, "Rejecting Proposal_5", false); + + } + + Map proposalVote = getProposalVote("Test_Proposal_5"); + assertEquals(toInt((String) proposalVote.get(APPROVE_VOTERS)), 1); + assertEquals(toInt((String) proposalVote.get(REJECT_VOTERS)), 6); + assertEquals(toInt((String) proposalVote.get(TOTAL_VOTERS)), 7); + + // one of the prep change their vote to abstain + voteByPrep(cpsClients.get(4), "Test_Proposal_5", ABSTAIN, "Changing vote", true); + + proposalVote = getProposalVote("Test_Proposal_5"); + assertEquals(toInt((String) proposalVote.get(APPROVE_VOTERS)), 1); + assertEquals(toInt((String) proposalVote.get(REJECT_VOTERS)), 5); + assertEquals(toInt((String) proposalVote.get(ABSTAIN_VOTERS)), 1); + assertEquals(toInt((String) proposalVote.get(TOTAL_VOTERS)), 7); + + } + + @DisplayName("vote priority txn except one ") + @Test + @Order(4) + public void votePriority() { + for (CPSClient prepClient : cpsClients.values()) { + if (prepClient.equals(cpsClients.get(2))) { + continue; + } + prepClient.cpsCore.votePriority(votingProposal); + + } + + // trying to Register by deny prep TODO + } + + + @DisplayName("updating to application period") + @Nested + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class applicationChecks { + + /* Test_Proposal_2 is approved, Test_Proposal_5 is rejected, Test_Proposal_3 is still in pending + * */ + + @DisplayName("update to application period") + @Test + @Order(5) + public void checkAfterUpdatePeriod() throws InterruptedException { + + Map sponsorBalance = claimableSponsorBond(cpsClients.get(0).getAddress()); + assertEquals(BigInteger.ZERO, sponsorBalance.get(bnUSD)); + + + updateToApplicationPeriod(); + + Map activeProposal = readerClient.cpsCore.getActiveProposalsList(0); + + List> proposalData = (List>) activeProposal.get(DATA); + assertEquals(proposalData.get(0).get(IPFS_HASH), "Test_Proposal_2"); + + List pendingProposal = getProposalByStatus(PENDING); + assertTrue(pendingProposal.contains("Test_Proposal_3")); + + List activeProposals = getProposalByStatus(ACTIVE); + assertTrue(activeProposals.contains("Test_Proposal_2")); + + List rejectedProposals = getProposalByStatus(REJECTED); + assertTrue(rejectedProposals.contains("Test_Proposal_4")); + assertTrue(rejectedProposals.contains("Test_Proposal_5")); + + BigInteger sponsorBondOnProposal5 = BigInteger.valueOf(15).multiply(ICX); + sponsorBalance = claimableSponsorBond(cpsClients.get(0).getAddress()); + assertEquals(sponsorBondOnProposal5, sponsorBalance.get(bnUSD)); + + + List
denyList = readerClient.cpsCore.getDenylist(); + assertTrue(denyList.contains(cpsClients.get(2).getAddress())); + + Address prep = cpsClients.get(2).getAddress(); + Map prepData = loginPrep(prep); + assertEquals(prepData, denyPrepData()); + } + + @DisplayName("prep pays penalty and registers") + @Test + @Order(6) + public void prepPayPenalty() { + CPSClient prep = cpsClients.get(2); + BigInteger penaltyAmount = (BigInteger.TWO.multiply(ICX)).divide(BigInteger.valueOf(100)); + + bnUSDMint(prep.getAddress(), BigInteger.TWO.multiply(ICX)); + + byte[] data = penaltyByteArray("payPrepPenalty"); + // TODO: pay the penalty + ownerClient.cpsCore.removeDenylistPreps(); +// prep.bnUSD.transfer(addressMap.get("cpsCore"),penaltyAmount,data); + + + Map prepData = loginPrep(prep.getAddress()); + assertEquals(prepData, unregisteredPrepData()); + + + prep.cpsCore.registerPrep(); + Map prepData2 = loginPrep(prep.getAddress()); + + assertEquals(prepData2, votingPrepData()); + } + + + @DisplayName("submit progress reports") + @Nested + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class submitProgressReport { + + @DisplayName("submit progress report with not completed status") + @Order(7) + @Test + public void progressReportNotCompleted() { + + CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("1", + "Test_Proposal_2"); + + assertEquals(getMilestoneStatus("Test_Proposal_2", 1), 0); + + + CPSCoreInterface.MilestoneSubmission submission = new CPSCoreInterface.MilestoneSubmission(); + submission.id = 1; + submission.status = false; + CPSCoreInterface.MilestoneSubmission[] milestoneSubmissions = new CPSCoreInterface.MilestoneSubmission[]{submission}; + + testClient.cpsCore.submitProgressReport(progressReportAttributes, milestoneSubmissions); + + assertEquals(getMilestoneStatus("Test_Proposal_2", 1), MILESTONE_REPORT_NOT_COMPLETED); + + System.out.println("-----boom----" + readerClient.cpsCore.getMilestonesReport("Test_Proposal_2", 1)); + + } + + @DisplayName("vote progress reports and proposal") + @Nested + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class voteOnProposalAndPR { + + @Test + @Order(8) + public void toVotingPeriod() throws InterruptedException { + // minting bnUSD on cpfTreasury to pass proposal 3 + bnUSDMint(addressMap.get("cpfTreasury"), BigInteger.valueOf(5000).multiply(ICX)); + + updateNextBlock(); + ownerClient.cpsCore.updatePeriod(); + } + + @DisplayName("vote on PR and proposal 3") + @Test + @Order(9) + public void votePRandProposal() { + for (CPSClient prepClient : cpsClients.values()) { + // proposal voting + voteByPrep(prepClient, "Test_Proposal_3", APPROVE, "Voting Again", false); + prepClient.cpsCore.votePriority(new String[]{"Test_Proposal_3"}); + + + MilestoneVoteAttributes[] voteAttributes = new MilestoneVoteAttributes[]{vote(1, APPROVE)}; + prepClient.cpsCore.voteProgressReport("Test_Proposal_2_Report_Proposal_1", + "Seems right ", + voteAttributes, null, false); + + } + + Map proposalVote = getProposalVote("Test_Proposal_3"); + assertEquals(toInt((String) proposalVote.get(APPROVE_VOTERS)), 7); + assertEquals(toInt((String) proposalVote.get(REJECT_VOTERS)), 0); + assertEquals(toInt((String) proposalVote.get(TOTAL_VOTERS)), 7); + + Map milestoneVoteResult = getMilestoneReport("Test_Proposal_2_Report_Proposal_1", 1); + assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)), 7); + assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)), 0); + +// MilestoneVoteAttributes[] voteAttributes = new MilestoneVoteAttributes[]{vote(1,REJECT)}; + + // one of the prep changes their vote on the progress report +// cpsClients.get(0).cpsCore.voteProgressReport("Test_Proposal_2_Report_Proposal_1", +// "Changing vote ", +// voteAttributes,null,true); +// +// milestoneVoteResult = getMilestoneReport("Test_Proposal_2_Report_Proposal_1", 1); +// assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)),6); +// assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)),1); + } + + + @DisplayName("submit progress report for proposal 2 and 3 ") + @Nested + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class SecondProgressReport { + + @DisplayName("update to application period and assert values") + @Order(10) + @Test + public void checksInApplicationPeriod() throws InterruptedException { + + String proposal2 = "Test_Proposal_2"; + Map proposalDetails = getProposalDetails(proposal2); + assertEquals(toInt((String) proposalDetails.get(PROJECT_DURATION)), 2); + + Map milestoneDetails = getMilestonesReport(proposal2, 1); + assertEquals(milestoneDetails.get(EXTENSION_FLAG), "0x0"); + assertEquals(toInt((String) milestoneDetails.get(COMPLETION_PERIOD)), 1); + + + updateToApplicationPeriod(); + verifyPeriod(APPLICATION_PERIOD); + + // milestone completion period and project duration increases + milestoneDetails = getMilestonesReport(proposal2, 1); + assertEquals(milestoneDetails.get(EXTENSION_FLAG), "0x1"); + assertEquals(toInt((String) milestoneDetails.get(COMPLETION_PERIOD)), 2); + + proposalDetails = getProposalDetails(proposal2); + assertEquals(toInt((String) proposalDetails.get(PROJECT_DURATION)), 3); + + List activeProposals = getProposalByStatus(ACTIVE); + + assertTrue(activeProposals.contains("Test_Proposal_2")); + assertTrue(activeProposals.contains("Test_Proposal_3")); + + } + + @DisplayName("submit progress report with completed status ") + @Order(11) + @Test + public void progressReportCompleted() { + CPSCoreInterface.MilestoneSubmission submission = new CPSCoreInterface.MilestoneSubmission(); + submission.id = 1; + submission.status = true; + CPSCoreInterface.MilestoneSubmission[] milestoneSubmissions = new CPSCoreInterface.MilestoneSubmission[]{submission}; + + // for proposal 2 + String proposal2 = "Test_Proposal_2"; + assertEquals(getMilestoneStatus("Test_Proposal_2", 1), MILESTONE_REPORT_NOT_COMPLETED); + CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("2", proposal2); + + testClient.cpsCore.submitProgressReport(progressReportAttributes, milestoneSubmissions); + + assertEquals(getMilestoneStatus("Test_Proposal_2", 1), MILESTONE_REPORT_COMPLETED); + + // for proposal 3 + String proposal3 = "Test_Proposal_3"; + assertEquals(getMilestoneStatus("Test_Proposal_3", 1), 0); + + progressReportAttributes = createProgressReport("1", proposal3); + + testClient.cpsCore.submitProgressReport(progressReportAttributes, milestoneSubmissions); + + assertEquals(getMilestoneStatus("Test_Proposal_3", 1), MILESTONE_REPORT_COMPLETED); + + } + + @DisplayName("vote progress report for proposal 2 and 3. ") + @Nested + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class voteSecondReport { + /* Progress report for proposal 2 will be accepted and proposal 3 will be rejected */ + @DisplayName("to voting period") + @Order(12) + @Test + public void updateToVotingPeriod() throws InterruptedException { + updateNextBlock(); + ownerClient.cpsCore.updatePeriod(); + verifyPeriod(VOTING_PERIOD); + // vote on progress report 2 with acceptance + } + + @DisplayName("vote on progress reports") + @Order(12) + @Test + public void voteProgressReport() { + String reportForPropsoal2 = "Test_Proposal_2_Report_Proposal_2"; + String reportForPropsoal3 = "Test_Proposal_3_Report_Proposal_1"; + + + MilestoneVoteAttributes[] voteAttributes = new MilestoneVoteAttributes[]{vote(1, APPROVE)}; + for (CPSClient prepClient : cpsClients.values()) { + prepClient.cpsCore.voteProgressReport(reportForPropsoal2, + "Seems right ", + voteAttributes, null, false); + + prepClient.cpsCore.voteProgressReport(reportForPropsoal3, + "Looks legit ", + voteAttributes, null, false); + } + + MilestoneVoteAttributes[] rejectVoteAttributes = new MilestoneVoteAttributes[]{vote(1, REJECT)}; + cpsClients.get(0).cpsCore.voteProgressReport(reportForPropsoal3, "I reject", + rejectVoteAttributes, null, true); + + // verify the votes + Map milestoneVoteResult = getMilestoneReport(reportForPropsoal2, 1); + assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)), 7); + assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)), 0); + + milestoneVoteResult = getMilestoneReport(reportForPropsoal3, 1); + assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)), 6); + assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)), 1); + + // vote on progress report 2 with acceptance + } + + @DisplayName("submit third progress report ") + @Nested + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class thirdReport { + + @DisplayName("update to application period and assert values") + @Order(13) + @Test + public void checks() throws InterruptedException { + + Map contributorProject2 = getContributorFunds(testClient.getAddress()); + List> contributorData2 = (List>) contributorProject2.get("data"); + + BigInteger milestoneBudget = toBigInt((String) contributorData2.get(0).get("installment_amount")); + BigInteger installPaidTillDate = toBigInt((String) contributorData2.get(0).get("total_installment_paid")); + + + updateToApplicationPeriod(); + verifyPeriod(APPLICATION_PERIOD); + + String proposal2 = "Test_Proposal_2"; + int milestoneStatus = getMilestoneStatus(proposal2, 1); + assertEquals(milestoneStatus, MILESTONE_REPORT_APPROVED); + + Map milestoneDetails = getMilestonesReport(proposal2, 1); + System.out.println("milestone details " + milestoneDetails); + + + Map proposalDetails = getProposalDetails(proposal2); + assertEquals(toInt((String) proposalDetails.get(APPROVED_REPORTS)), 1); + + List activeProposals = getProposalByStatus(ACTIVE); + assertTrue(activeProposals.contains(proposal2)); + + // check contributor's fund + Map contributorProject = getContributorFunds(testClient.getAddress()); + List> contributorData = (List>) contributorProject.get("data"); + BigInteger installmentPaidNow = toBigInt((String) contributorData.get(0).get("total_installment_paid")); + assertEquals(installmentPaidNow, installPaidTillDate.add(milestoneBudget)); + + + String proposal3 = "Test_Proposal_3"; + milestoneStatus = getMilestoneStatus(proposal3, 1); + assertEquals(milestoneStatus, MILESTONE_REPORT_REJECTED); + + + proposalDetails = getProposalDetails(proposal3); + assertEquals(toInt((String) proposalDetails.get(APPROVED_REPORTS)), 0); + + List pausedProposal = getProposalByStatus(PAUSED); + + assertTrue(pausedProposal.contains("Test_Proposal_3")); + + } + + @DisplayName("one of the milestone is rejected on this progress report") + @Order(14) + @Test + public void submitProgressReport() { + + List> activeProposal = readerClient.cpsCore.getActiveProposals(testClient.getAddress()); + System.out.println("active proposal " + activeProposal); + assertEquals("Test_Proposal_2", activeProposal.get(1).get("ipfs_hash")); + assertEquals("0x0", activeProposal.get(1).get("new_progress_report")); + assertEquals("0x1", activeProposal.get(1).get("last_progress_report")); + + // submit progress report for proposal 2 + CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("3", + "Test_Proposal_2"); + + assertEquals(getMilestoneStatus("Test_Proposal_2", 2), 0); + assertEquals(getMilestoneStatus("Test_Proposal_2", 3), 0); + + CPSCoreInterface.MilestoneSubmission submission2 = new CPSCoreInterface.MilestoneSubmission(); + submission2.id = 2; + submission2.status = true; + + CPSCoreInterface.MilestoneSubmission submission3 = new CPSCoreInterface.MilestoneSubmission(); + submission3.id = 3; + submission3.status = true; + CPSCoreInterface.MilestoneSubmission[] milestoneSubmissions = new CPSCoreInterface.MilestoneSubmission[]{ + submission2, submission3 + }; + + testClient.cpsCore.submitProgressReport(progressReportAttributes, milestoneSubmissions); + + + Map progressReport = getProgressReportDetails("Test_Proposal_2_Report_Proposal_3"); + assertEquals(progressReport.get("milestone_submitted_count"), "0x2"); + + assertEquals(getMilestoneStatus("Test_Proposal_2", 2), MILESTONE_REPORT_COMPLETED); + assertEquals(getMilestoneStatus("Test_Proposal_2", 3), MILESTONE_REPORT_COMPLETED); + + } + + @DisplayName("submit progress report with all milestones of a project") + @Order(14) + @Test + public void withAllMilestones() { + + CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("2", + "Test_Proposal_3"); + + assertEquals(getMilestoneStatus("Test_Proposal_3", 2), 0); + + CPSCoreInterface.MilestoneSubmission submission2 = new CPSCoreInterface.MilestoneSubmission(); + submission2.id = 2; + submission2.status = true; + + CPSCoreInterface.MilestoneSubmission submission3 = new CPSCoreInterface.MilestoneSubmission(); + submission3.id = 3; + submission3.status = true; + CPSCoreInterface.MilestoneSubmission[] milestoneSubmissions = new CPSCoreInterface.MilestoneSubmission[]{ + submission2, submission3 + }; + + testClient.cpsCore.submitProgressReport(progressReportAttributes, milestoneSubmissions); + + + assertEquals(getMilestoneStatus("Test_Proposal_3", 2), MILESTONE_REPORT_COMPLETED); + + } + + @DisplayName("vote on third progress report. ") + @Nested + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class voteReport { + @DisplayName("to voting period") + @Order(15) + @Test + public void updateToVotingPeriod() throws InterruptedException { + updateNextBlock(); + ownerClient.cpsCore.updatePeriod(); + verifyPeriod(VOTING_PERIOD); + // vote on progress report 2 with acceptance + } + + @DisplayName("vote on progress reports") + @Order(16) + @Test + public void voteProgressReport() { + + String reportForPropsoal2 = "Test_Proposal_2_Report_Proposal_3"; + String reportForPropsoal3 = "Test_Proposal_3_Report_Proposal_2"; + + + MilestoneVoteAttributes[] voteAttributes = new MilestoneVoteAttributes[]{ + vote(2, APPROVE), vote(3, REJECT)}; + for (CPSClient prepClient : cpsClients.values()) { + prepClient.cpsCore.voteProgressReport(reportForPropsoal2, + "Progress not satisfactory ", + voteAttributes, null, false); + + prepClient.cpsCore.voteProgressReport(reportForPropsoal3, + "no ", + voteAttributes, null, false); + } + + // verify the votes + Map milestoneVoteResult = getMilestoneReport(reportForPropsoal2, 2); + assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)), 7); + assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)), 0); + + milestoneVoteResult = getMilestoneReport(reportForPropsoal2, 3); + assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)), 0); + assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)), 7); + + milestoneVoteResult = getMilestoneReport(reportForPropsoal3, 2); + assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)), 7); + assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)), 0); + + } + + + @DisplayName("submit final progress report of both proposals. ") + @Nested + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class finalReports { + + @DisplayName("update to application period and assert values") + @Order(17) + @Test + public void checksInApplicationPeriod() throws InterruptedException { + + Map contributorProject2 = getContributorFunds(testClient.getAddress()); + List> contributorData2 = (List>) contributorProject2.get("data"); + + BigInteger installPaidTillDate = toBigInt((String) contributorData2.get(0).get("total_installment_paid")); + + + updateToApplicationPeriod(); + verifyPeriod(APPLICATION_PERIOD); + + String proposal2 = "Test_Proposal_2"; + int milestoneStatus = getMilestoneStatus(proposal2, 2); + assertEquals(milestoneStatus, MILESTONE_REPORT_APPROVED); + + milestoneStatus = getMilestoneStatus(proposal2, 3); + assertEquals(milestoneStatus, MILESTONE_REPORT_REJECTED); + + Map milestoneDetails = getMilestonesReport(proposal2, 2); + BigInteger milestoneBudget = toBigInt((String) milestoneDetails.get(BUDGET)); + + + Map proposalDetails = getProposalDetails(proposal2); + assertEquals(toInt((String) proposalDetails.get(APPROVED_REPORTS)), 2); + + // proposal 2 submitted the last progress report and the milestone got rejected + // so proposal 2 will be in paused state + List pausedProposal = getProposalByStatus(PAUSED); + assertTrue(pausedProposal.contains(proposal2)); + + // check contributor's fund + Map contributorProject = getContributorFunds(testClient.getAddress()); + List> contributorData = (List>) contributorProject.get("data"); + BigInteger installmentPaidNow = toBigInt((String) contributorData.get(0).get("total_installment_paid")); + assertEquals(installmentPaidNow, installPaidTillDate.add(milestoneBudget)); + + + String proposal3 = "Test_Proposal_3"; + + milestoneStatus = getMilestoneStatus(proposal3, 2); + assertEquals(milestoneStatus, MILESTONE_REPORT_APPROVED); + + milestoneStatus = getMilestoneStatus(proposal3, 3); + assertEquals(milestoneStatus, MILESTONE_REPORT_REJECTED); + + + proposalDetails = getProposalDetails(proposal3); + assertEquals(toInt((String) proposalDetails.get(APPROVED_REPORTS)), 1); + + + List activeProposals = getProposalByStatus(ACTIVE); + assertTrue(activeProposals.contains("Test_Proposal_3")); + + } + + @DisplayName("report for proposal 2 ") + @Order(18) + @Test + public void finalReport() { + // proposal 2 ko milestone 2 + // proposal 3 ko milestone 1 and 3 + + CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("4", + "Test_Proposal_2"); + + assertEquals(getMilestoneStatus("Test_Proposal_2", 3), MILESTONE_REPORT_REJECTED); + + CPSCoreInterface.MilestoneSubmission submission3 = new CPSCoreInterface.MilestoneSubmission(); + submission3.id = 3; + submission3.status = true; + CPSCoreInterface.MilestoneSubmission[] milestoneSubmissions = new CPSCoreInterface.MilestoneSubmission[]{ + submission3 + }; + + testClient.cpsCore.submitProgressReport(progressReportAttributes, milestoneSubmissions); + + + Map progressReport = getProgressReportDetails("Test_Proposal_2_Report_Proposal_4"); + + + } + + @DisplayName("report for proposal 3 ") + @Order(18) + @Test + public void finalReport2() { + + List> activeProposal = readerClient.cpsCore.getActiveProposals(testClient.getAddress()); + System.out.println("the milestone deadlines are " + activeProposal.get(1).get("milestoneDeadlines")); + CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("3", + "Test_Proposal_3"); + + assertEquals(getMilestoneStatus("Test_Proposal_3", 1), MILESTONE_REPORT_REJECTED); + assertEquals(getMilestoneStatus("Test_Proposal_3", 3), MILESTONE_REPORT_REJECTED); + + CPSCoreInterface.MilestoneSubmission submission1 = new CPSCoreInterface.MilestoneSubmission(); + submission1.id = 1; + submission1.status = true; + + CPSCoreInterface.MilestoneSubmission submission3 = new CPSCoreInterface.MilestoneSubmission(); + submission3.id = 3; + submission3.status = true; + CPSCoreInterface.MilestoneSubmission[] milestoneSubmissions = new CPSCoreInterface.MilestoneSubmission[]{ + submission1, submission3 + }; + + testClient.cpsCore.submitProgressReport(progressReportAttributes, milestoneSubmissions); + + + Map progressReport = getProgressReportDetails("Test_Proposal_3_Report_Proposal_3"); + + assertEquals(getMilestoneStatus("Test_Proposal_3", 1), MILESTONE_REPORT_COMPLETED); + + + } + + @DisplayName("vote on reports of proposals ") + @Nested + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + class voteFinalReport { + @DisplayName("update to voting period") + @Order(19) + @Test + public void updateToVotingPeriod() throws InterruptedException { + updateNextBlock(); + ownerClient.cpsCore.updatePeriod(); + verifyPeriod(VOTING_PERIOD); + } + + @DisplayName("vote on final report") + @Order(20) + @Test + public void voteFinalReports() { + // proposal 3 reject + + String reportForPropsoal2 = "Test_Proposal_2_Report_Proposal_4"; + String reportForPropsoal3 = "Test_Proposal_3_Report_Proposal_3"; + + + MilestoneVoteAttributes[] voteForProposal2 = new MilestoneVoteAttributes[]{ + vote(3, APPROVE)}; + + MilestoneVoteAttributes[] voteForProposal3 = new MilestoneVoteAttributes[]{ + vote(1, REJECT), vote(3, APPROVE)}; + for (CPSClient prepClient : cpsClients.values()) { + prepClient.cpsCore.voteProgressReport(reportForPropsoal2, + "Looks good ", + voteForProposal2, null, false); + + prepClient.cpsCore.voteProgressReport(reportForPropsoal3, + "can only approve one of them ", + voteForProposal3, null, false); + } + + // verify the votes + Map milestoneVoteResult = getMilestoneReport(reportForPropsoal2, 3); + assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)), 7); + assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)), 0); + + milestoneVoteResult = getMilestoneReport(reportForPropsoal3, 1); + assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)), 0); + assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)), 7); + + milestoneVoteResult = getMilestoneReport(reportForPropsoal3, 3); + assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)), 7); + assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)), 0); + + } + + @DisplayName("completeAllProject") + @Order(21) + @Test + public void completionOfProjects() throws InterruptedException { + + Map claimableBond = claimableSponsorBond( + cpsClients.get(0).getAddress()); + BigInteger sponsorBondBefore = claimableBond.get(bnUSD); + System.out.println("sponsorBo" + sponsorBondBefore); + + updateToApplicationPeriod(); + + // check the contributors and sponsor's balance + + Map milestoneReport = getMilestonesReport("Test_Proposal_3", 1); + assertEquals(milestoneReport.get("extensionFlag"), "0x0"); + assertEquals(toInt((String) milestoneReport.get("status")), MILESTONE_REPORT_REJECTED); + + milestoneReport = getMilestonesReport("Test_Proposal_3", 3); + assertEquals(milestoneReport.get("extensionFlag"), "0x0"); + assertEquals(toInt((String) milestoneReport.get("status")), MILESTONE_REPORT_APPROVED); + + List activeProposals = getProposalByStatus(ACTIVE); + assertTrue(activeProposals.contains("Test_Proposal_3")); + + List completedProposals = getProposalByStatus(COMPLETED); + assertTrue(completedProposals.contains("Test_Proposal_2")); + + // check the sponsor bond is return + Map sponsorBondAfter = claimableSponsorBond( + cpsClients.get(0).getAddress()); + Map proposalDetail = getProposalDetails("Test_Proposal_2"); + BigInteger sponsorBondAmount = toBigInt((String) proposalDetail.get(SPONSOR_DEPOSIT_AMOUNT)); + assertEquals(sponsorBondAmount.add(sponsorBondBefore), sponsorBondAfter.get(bnUSD)); + } + } + + + } + } + + + } + } + + + } + + } + } + } + } + + + } + + private Map getMilestonesReport(String ipfsHash, int id) { + return readerClient.cpsCore.getMilestonesReport(ipfsHash, id); + } + + private Map claimableSponsorBond(Address prepAddress) { + return readerClient.cpsCore.checkClaimableSponsorBond(prepAddress); + } + + private List getProposalByStatus(String status) { + return readerClient.cpsCore.getProposalsKeysByStatus(status); + } + + + private void verifyPeriod(String period) { + Map periodStatus = getPeriodStatus(); + assertEquals(periodStatus.get(PERIOD_NAME), period); + } private MilestoneVoteAttributes vote(int id, String vote){ @@ -608,8 +1708,18 @@ private byte[] createByteArray(String methodName, String ipfsHash, String vote, return jsonData.toString().getBytes(); } - private void bnUSDMint(Address to, BigInteger amount){ - ownerClient.bnUSD.mintTo(to,amount); + private byte[] penaltyByteArray(String methodName) { + + JsonObject jsonData = new JsonObject() + .add("method", methodName) + .add("params", new JsonObject()); + + + return jsonData.toString().getBytes(); + } + + private void bnUSDMint(Address to, BigInteger amount) { + ownerClient.bnUSD.mintTo(to, amount); } From a64bfdf00ea8f62c90a48de3f1bccee5fceb5d2a Mon Sep 17 00:00:00 2001 From: naneey Date: Thu, 28 Mar 2024 11:02:19 +0545 Subject: [PATCH 30/64] chore: added tests on cps treasury --- .../score/cpstreasury/CPSTreasuryTest.java | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/CPSTreasury/src/test/java/community/icon/cps/score/cpstreasury/CPSTreasuryTest.java b/CPSTreasury/src/test/java/community/icon/cps/score/cpstreasury/CPSTreasuryTest.java index 6e3dc618..46efae32 100644 --- a/CPSTreasury/src/test/java/community/icon/cps/score/cpstreasury/CPSTreasuryTest.java +++ b/CPSTreasury/src/test/java/community/icon/cps/score/cpstreasury/CPSTreasuryTest.java @@ -51,7 +51,7 @@ public class CPSTreasuryTest extends TestBase { @BeforeEach public void setup() throws Exception { - tokenScore = sm.deploy(owner, CPSTreasury.class); + tokenScore = sm.deploy(owner, CPSTreasury.class, score_address); CPSTreasury instance = (CPSTreasury) tokenScore.getInstance(); scoreSpy = spy(instance); tokenScore.setInstance(scoreSpy); @@ -569,4 +569,47 @@ void claimReward(){ } + + @Test + void updateAddress(){ + setOnsetPayment(); + setCpsScoreMethod(); + + contextMock.when(caller()).thenReturn(score_address); + depositProposalFundMethod(); + + Address newContributorAddress = sm.createAccount().getAddress(); + Address newSponsorAddress = sm.createAccount().getAddress(); + + contextMock.when(caller()).thenReturn(score_address); + tokenScore.invoke(testing_account,"updateContributorSponsorAddress", "Proposal 1", + newContributorAddress,newSponsorAddress); + + + Map oldContributorData = (Map) tokenScore.call("getContributorProjectedFund", testing_account2.getAddress()); + System.out.println("The data is empty: "+oldContributorData.get(DATA)); + + Map oldSponsorData = (Map) tokenScore.call("getSponsorProjectedFund", testing_account.getAddress()); + System.out.println("The data is empty: "+oldSponsorData.get(DATA)); + + doReturn(List.of(Map.of( + BUDGET,BigInteger.valueOf(50).multiply(ICX) + ))).when(scoreSpy).callScore(List.class,score_address,"getRemainingMilestones","Proposal 1"); + Map newContributorData = (Map) tokenScore.call("getContributorProjectedFund", newContributorAddress); + + List> data = (List>) newContributorData.get(DATA); + assertEquals(data.get(0).get("ipfs_hash"),"Proposal 1"); + assertEquals(data.get(0).get("total_installment_paid"), new BigInteger("10000000000000000000")); + + + Map newSponsorData = (Map) tokenScore.call("getSponsorProjectedFund", newSponsorAddress); + System.out.println(newSponsorData); + data = (List>) newSponsorData.get(DATA); + assertEquals(data.get(0).get("ipfs_hash"),"Proposal 1"); + assertEquals(data.get(0).get("total_installment_paid"), new BigInteger("200000000000000000")); + assertEquals(data.get(0).get("sponsor_bond_amount"), new BigInteger("15000000000000000000")); + + + } + } \ No newline at end of file From 328b76d00b6a1b17275d57a647ea7058ea350549 Mon Sep 17 00:00:00 2001 From: naneey Date: Thu, 28 Mar 2024 11:56:58 +0545 Subject: [PATCH 31/64] chore:fixed test for treasury --- .../score/cpftreasury/CPFTTreasuryTest.java | 26 +++---------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java b/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java index 86629044..e26ddb1a 100644 --- a/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java +++ b/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java @@ -36,6 +36,8 @@ public class CPFTTreasuryTest extends TestBase { public static final String TAG = "CPF_TREASURY"; private static final BigInteger MULTIPLIER = new BigInteger("1000000000000000000"); + VarDB
cpsScore = mock(VarDB.class); + private static final ServiceManager sm = getServiceManager(); private static final Account owner = sm.createAccount(); @@ -49,7 +51,7 @@ public class CPFTTreasuryTest extends TestBase { @BeforeEach public void setup() throws Exception { - tokenScore = sm.deploy(owner, CPFTreasury.class); + tokenScore = sm.deploy(owner, CPFTreasury.class,cpsScore.get()); } @Test @@ -76,7 +78,6 @@ public void setMaximumTreasuryFundBNUSDExceptions(Account address) { @Test void setCPSScore() { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner, "setCpsScore", score_address); @@ -86,7 +87,6 @@ void setCPSScore() { @Test void setCPSTreasuryScore() { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner, "setCpsTreasuryScore", score_address); @@ -96,7 +96,6 @@ void setCPSTreasuryScore() { @Test void setBMUSDScore() { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner, "setBnUSDScore", score_address); @@ -106,7 +105,6 @@ void setBMUSDScore() { @Test void setSICXScore() { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner, "setSicxScore", score_address); @@ -116,7 +114,6 @@ void setSICXScore() { @Test void setDEXScore() { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner, "setDexScore", score_address); @@ -126,7 +123,6 @@ void setDEXScore() { @Test void setRouterScore() { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner, "setRouterScore", score_address); @@ -175,7 +171,6 @@ void setDEXScoreExceptions(Account address, Address _score) { } void setRouterScoreExceptions(Account address, Address _score) { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(false); tokenScore.invoke(address, "setRouterScore", _score); @@ -186,7 +181,6 @@ void setRouterScoreExceptions(Account address, Address _score) { @Test void setCPSScoreNotAdmin() { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)){ theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(false); tokenScore.invoke(testing_account, "setCpsScore", score_address); @@ -290,7 +284,6 @@ void updateProposalFund() { } void setMaxCapIcxAndBnusd() { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner, "setMaximumTreasuryFundIcx", BigInteger.valueOf(2000).multiply(MULTIPLIER)); @@ -301,7 +294,6 @@ void setMaxCapIcxAndBnusd() { @Test void setMaxCapIcxAndBnusdTest() { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner, "setMaximumTreasuryFundIcx", BigInteger.valueOf(2000).multiply(MULTIPLIER)); @@ -313,7 +305,6 @@ void setMaxCapIcxAndBnusdTest() { void swapIcxBnusd() { setSICXScoreMethod(sicxScore); setBNUSDScoreMethod(bnUSDScore); - VarDB
cpsScore = mock(VarDB.class); VarDB
routerScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); @@ -687,7 +678,6 @@ void fallbackSenderIsNotDex() { @Test void toggleSwapFlag(){ - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner,"toggleSwapFlag"); @@ -697,7 +687,6 @@ void toggleSwapFlag(){ @Test void transferToEmergencyFund(){ - VarDB
cpsScore = mock(VarDB.class); VarDB
balanceDollar = mock(VarDB.class); BigInteger emergencyFund = BigInteger.valueOf(10).multiply(ICX); try (MockedStatic theMock = Mockito.mockStatic(Context.class)){ @@ -712,7 +701,6 @@ void transferToEmergencyFund(){ @Test void withdrawFromEmergencyFund(){ transferToEmergencyFund(); - VarDB
cpsScore = mock(VarDB.class); VarDB
balanceDollar = mock(VarDB.class); BigInteger withdrawAmount = BigInteger.valueOf(4).multiply(ICX); try (MockedStatic theMock = Mockito.mockStatic(Context.class)){ @@ -727,7 +715,6 @@ void withdrawFromEmergencyFund(){ @Test void slippagePercentage() { - VarDB
cpsScore = mock(VarDB.class); int value = 10; try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); @@ -746,7 +733,6 @@ public void expectErrorMessage(Executable contractCall, String errorMessage) { } void setCPSScoreMethod(Address scoreAddress) { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner, "setCpsScore", scoreAddress); @@ -754,7 +740,6 @@ void setCPSScoreMethod(Address scoreAddress) { } void setCPSTreasuryScoreMetod(Address scoreAddress) { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner, "setCpsTreasuryScore", scoreAddress); @@ -762,7 +747,6 @@ void setCPSTreasuryScoreMetod(Address scoreAddress) { } void setBNUSDScoreMethod(Address scoreAddress) { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner, "setBnUSDScore", scoreAddress); @@ -770,7 +754,6 @@ void setBNUSDScoreMethod(Address scoreAddress) { } void setOracleAddressMethod(Address scoreAddress) { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner, "setOracleAddress", scoreAddress); @@ -778,7 +761,6 @@ void setOracleAddressMethod(Address scoreAddress) { } void setSICXScoreMethod(Address scoreAddress) { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner, "setSicxScore", scoreAddress); @@ -786,7 +768,6 @@ void setSICXScoreMethod(Address scoreAddress) { } void setDEXScoreMethod(Address scoreAddress) { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner, "setDexScore", scoreAddress); @@ -794,7 +775,6 @@ void setDEXScoreMethod(Address scoreAddress) { } void setRouterScoreMethod(Address scoreAddress) { - VarDB
cpsScore = mock(VarDB.class); try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); tokenScore.invoke(owner, "setRouterScore", score_address); From dbda28c11fd595d261a23bbba162d7e96de96818 Mon Sep 17 00:00:00 2001 From: naneey Date: Thu, 28 Mar 2024 12:40:37 +0545 Subject: [PATCH 32/64] chore:fixed integration test --- .../cps/integration/CPSCoreIntegration.java | 46 +++++++++++-------- .../test/integration/config/BaseConfig.java | 1 + .../integration/scores/CPSCoreInterface.java | 3 ++ 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java index a5c34134..f2aab45d 100644 --- a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java +++ b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java @@ -311,7 +311,7 @@ public void submitMilestoneReport(){ List> activeProposal = readerClient.cpsCore.getActiveProposals(testClient.getAddress()); assertEquals( "0x0", activeProposal.get(0).get("new_progress_report")); - CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("1"); + CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("1", "Test_Proposal_1"); CPSCoreInterface.MilestoneSubmission submission = new CPSCoreInterface.MilestoneSubmission(); submission.id = 1; @@ -323,22 +323,22 @@ public void submitMilestoneReport(){ activeProposal = readerClient.cpsCore.getActiveProposals(testClient.getAddress()); assertEquals( "0x1", activeProposal.get(0).get("new_progress_report")); - Map progressReportDetails = getProgressReportDetails("Report_Proposal_1"); + Map progressReportDetails = getProgressReportDetails("Test_Proposal_1_Report_Proposal_1"); assertEquals(1,toInt((String) progressReportDetails.get(MILESTONE_SUBMITTED_COUNT))); assertEquals(WAITING,progressReportDetails.get(STATUS)); - assertEquals("Report_1",progressReportDetails.get(PROGRESS_REPORT_TITLE)); - assertEquals("Report_Proposal_1",progressReportDetails.get(REPORT_HASH)); + assertEquals("Test_Proposal_1_Report_1",progressReportDetails.get(PROGRESS_REPORT_TITLE)); + assertEquals("Test_Proposal_1_Report_Proposal_1",progressReportDetails.get(REPORT_HASH)); int milestoneStatus = getMilestoneStatus("Test_Proposal_1",1); assertEquals(MILESTONE_REPORT_COMPLETED,milestoneStatus); } - private ProgressReportAttributes createProgressReport(String no){ + private ProgressReportAttributes createProgressReport(String no, String ipfsHash) { ProgressReportAttributes progressReportAttributes = new ProgressReportAttributes(); - progressReportAttributes.ipfs_hash = "Test_Proposal_1"; - progressReportAttributes.progress_report_title = "Report_"+no; - progressReportAttributes.report_hash ="Report_Proposal_"+no; - progressReportAttributes.ipfs_link = "https://proposal_"+ no; + progressReportAttributes.ipfs_hash = ipfsHash; + progressReportAttributes.progress_report_title = ipfsHash + "_Report_" + no; + progressReportAttributes.report_hash = ipfsHash + "_Report_Proposal_" + no; + progressReportAttributes.ipfs_link = "https://proposal_" + no; progressReportAttributes.budget_adjustment = false; progressReportAttributes.additional_budget = BigInteger.ZERO; progressReportAttributes.additional_month = 0; @@ -363,7 +363,7 @@ public void voteOnMilestone() throws InterruptedException { List> expectedMilestoneData = new ArrayList<>(7); for (int i = 0; i < cpsClients.size(); i++) { - cpsClients.get(i).cpsCore.voteProgressReport("Report_Proposal_1","Working well " + i, + cpsClients.get(i).cpsCore.voteProgressReport("Test_Proposal_1_Report_Proposal_1","Working well " + i, voteAttributes,null,false); expectedMilestoneData.add(Map.of( ADDRESS,cpsClients.get(i).getAddress(), @@ -372,10 +372,10 @@ public void voteOnMilestone() throws InterruptedException { VOTE,APPROVE)); } - Map progressReportVote = getProgressReportVote("Report_Proposal_1"); + Map progressReportVote = getProgressReportVote("Test_Proposal_1_Report_Proposal_1"); assertEquals(toInt((String) progressReportVote.get("total_voters")),7); - Map milestoneVoteResult = getMilestoneReport("Report_Proposal_1", 1); + Map milestoneVoteResult = getMilestoneReport("Test_Proposal_1_Report_Proposal_1", 1); assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)),7); assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)),0); @@ -439,7 +439,7 @@ public void submitAllMilestoneReport() throws InterruptedException { assertEquals(toBigInt((String) sponsorProject.get("withdraw_amount_bnUSD")),BigInteger.valueOf(8).multiply(ICX).divide(BigInteger.TEN)); - CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("2"); + CPSCoreInterface.ProgressReportAttributes progressReportAttributes = createProgressReport("2", "Test_Proposal_1"); CPSCoreInterface.MilestoneSubmission submissionNo2 = new CPSCoreInterface.MilestoneSubmission(); submissionNo2.id = 2; @@ -455,12 +455,12 @@ public void submitAllMilestoneReport() throws InterruptedException { testClient.cpsCore.submitProgressReport(progressReportAttributes,milestoneSubmissions); - Map progressReportDetails = getProgressReportDetails("Report_Proposal_2"); + Map progressReportDetails = getProgressReportDetails("Test_Proposal_1_Report_Proposal_2"); assertEquals(2,toInt((String) progressReportDetails.get(MILESTONE_SUBMITTED_COUNT))); // assertEquals(new String[]{"0x2","0x3"},progressReportDetails.get("milestoneId")); assertEquals(WAITING,progressReportDetails.get(STATUS)); - assertEquals("Report_2",progressReportDetails.get(PROGRESS_REPORT_TITLE)); - assertEquals("Report_Proposal_2",progressReportDetails.get(REPORT_HASH)); + assertEquals("Test_Proposal_1_Report_2",progressReportDetails.get(PROGRESS_REPORT_TITLE)); + assertEquals("Test_Proposal_1_Report_Proposal_2",progressReportDetails.get(REPORT_HASH)); } @@ -481,7 +481,7 @@ public void voteOnAllMilestone() throws InterruptedException { List> expectedMilestoneData = new ArrayList<>(7); for (int i = 0; i < cpsClients.size(); i++) { - cpsClients.get(i).cpsCore.voteProgressReport("Report_Proposal_2","Project is completed " + i, + cpsClients.get(i).cpsCore.voteProgressReport("Test_Proposal_1_Report_Proposal_2","Project is completed " + i, voteAttributes,null,false); expectedMilestoneData.add(Map.of( ADDRESS,cpsClients.get(i).getAddress(), @@ -490,10 +490,10 @@ public void voteOnAllMilestone() throws InterruptedException { VOTE,APPROVE)); } - Map progressReportVote = getProgressReportVote("Report_Proposal_2"); + Map progressReportVote = getProgressReportVote("Test_Proposal_1_Report_Proposal_2"); assertEquals(toInt((String) progressReportVote.get("total_voters")),7); - Map milestoneVoteResult = getMilestoneReport("Report_Proposal_2", 2); + Map milestoneVoteResult = getMilestoneReport("Test_Proposal_1_Report_Proposal_2", 2); assertEquals(toInt((String) milestoneVoteResult.get(APPROVE_VOTERS)),7); assertEquals(toInt((String) milestoneVoteResult.get(REJECT_VOTERS)),0); @@ -1752,5 +1752,13 @@ private Map registerPrepData(){ VOTING_PREP, BigInteger.ZERO); } + private Map denyPrepData() { + return Map.of(IS_PREP, BigInteger.ONE, + IS_REGISTERED, BigInteger.ZERO, + PAY_PENALTY, BigInteger.ONE, + PENALTY_AMOUNT1, (BigInteger.TWO.multiply(ICX)).divide(BigInteger.valueOf(100)), + VOTING_PREP, BigInteger.ZERO); + } + } diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java index 1ef63f4e..f33a68f2 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java @@ -56,6 +56,7 @@ public void call(){ cpsClient.cpsCore.toggleMaintenance(); cpsClient.cpsCore.setInitialBlock(); + cpsClient.cpsCore.setPrepPenaltyAmount(new BigInteger[]{BigInteger.valueOf(2),BigInteger.valueOf(5),BigInteger.TEN}); System.out.println("------system score------- " + addressMap.get("systemScore")); diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java index 26ab21eb..00a9f17a 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java @@ -127,6 +127,9 @@ public static class MilestoneVoteAttributes { @External(readonly = true) Map getPriorityVoteResult(); + @External(readonly = true) + Map getMilestonesReport(String ipfsKey, int milestoneId); + @External void votePriority(String[] _proposals); From d7f82395dad352a0a238c0b69f7dd4ad969b7636 Mon Sep 17 00:00:00 2001 From: naneey Date: Thu, 28 Mar 2024 16:32:01 +0545 Subject: [PATCH 33/64] chore: dummy contracts configured --- build.gradle | 8 +- dummy/Dex/build.gradle | 46 ++++++ .../src/main/java/dummy/contract/dex/Dex.java | 132 ++++++++++++++++++ dummy/Router/build.gradle | 44 ++++++ .../java/dummy/contract/router/Router.java | 53 +++++++ dummy/bnUSD/build.gradle | 39 ++++++ .../main/java/dummy/contract/bnusd/bnUSD.java | 35 +++++ dummy/oracle/build.gradle | 57 ++++++++ .../java/dummy/contract/oracle/Oracle.java | 15 ++ dummy/sICX/build.gradle | 38 +++++ .../main/java/dummy/contract/sicx/sICX.java | 123 ++++++++++++++++ .../score/lib/interfaces/DexInterface.java | 55 ++++---- .../score/lib/interfaces/RouterInterface.java | 34 +++-- .../score/lib/interfaces/bnUSDInterface.java | 19 ++- .../score/lib/interfaces/sICXInterface.java | 18 ++- settings.gradle | 43 +++--- .../test/integration/scores/DummyDex.java | 2 + .../score/test/integration/scores/sICX.java | 11 ++ .../src/main/resources/conf/contracts.json | 12 +- 19 files changed, 686 insertions(+), 98 deletions(-) create mode 100644 dummy/Dex/build.gradle create mode 100644 dummy/Dex/src/main/java/dummy/contract/dex/Dex.java create mode 100644 dummy/Router/build.gradle create mode 100644 dummy/Router/src/main/java/dummy/contract/router/Router.java create mode 100644 dummy/bnUSD/build.gradle create mode 100644 dummy/bnUSD/src/main/java/dummy/contract/bnusd/bnUSD.java create mode 100644 dummy/oracle/build.gradle create mode 100644 dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java create mode 100644 dummy/sICX/build.gradle create mode 100644 dummy/sICX/src/main/java/dummy/contract/sicx/sICX.java diff --git a/build.gradle b/build.gradle index 2e780642..400d42b1 100644 --- a/build.gradle +++ b/build.gradle @@ -113,10 +113,10 @@ subprojects { // scoreIntegrationTest.put('bnUSD', "https://raw.githubusercontent.com/naneey/cps-scores/main/dummy/IRC2Token.jar") scoreIntegrationTest.put('bnUSD', "$rootProject.projectDir/dummyJarFiles/bnUSD-0.9.1-optimized.jar") - scoreIntegrationTest.put('DEX', "$rootProject.projectDir/dummyJarFiles/Dex-0.9.1-optimized.jar") - scoreIntegrationTest.put('ROUTER', "$rootProject.projectDir/dummyJarFiles/Router-0.9.1-optimized.jar") - scoreIntegrationTest.put('ORACLE', "$rootProject.projectDir/dummyJarFiles/oracle-0.9.1-optimized.jar") - scoreIntegrationTest.put('sICX', "$rootProject.projectDir/dummyJarFiles/Sicx-0.0.1-optimized.jar") +// scoreIntegrationTest.put('DEX', "$rootProject.projectDir/dummyJarFiles/Dex-0.9.1-optimized.jar") +// scoreIntegrationTest.put('ROUTER', "$rootProject.projectDir/dummyJarFiles/Router-0.9.1-optimized.jar") +// scoreIntegrationTest.put('ORACLE', "$rootProject.projectDir/dummyJarFiles/oracle-0.9.1-optimized.jar") +// scoreIntegrationTest.put('sICX', "$rootProject.projectDir/dummyJarFiles/Sicx-0.0.1-optimized.jar") afterEvaluate { project -> scoreIntegrationTest.put(project.name, project.getTasks().getByName("optimizedJar").outputJarName) diff --git a/dummy/Dex/build.gradle b/dummy/Dex/build.gradle new file mode 100644 index 00000000..9f955982 --- /dev/null +++ b/dummy/Dex/build.gradle @@ -0,0 +1,46 @@ +version = '0.9.1' + +dependencies { + + implementation project(':score-lib') + testImplementation project(':test-lib') + +} + +optimizedJar { + mainClassName = 'dummy.contract.dex.Dex' + from { + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } +} + +deployJar { + endpoints { + lisbon { + uri = 'https://lisbon.net.solidwallet.io/api/v3' + nid = 0x2 + } + local { + uri = 'http://localhost:9082/api/v3' + nid = 0x3 + } + sejong { + uri = 'https://sejong.net.solidwallet.io/api/v3' + nid = 0x53 + + } + berlin { + uri = 'https://berlin.net.solidwallet.io/api/v3' + nid = 0x7 + to = 'cx28ae7ed3b07ed5247a3d2f97680f8555ce7c0a92' + } + } + keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' + password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' + parameters { + } +} + +test { + useJUnitPlatform() +} diff --git a/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java b/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java new file mode 100644 index 00000000..f045a1bd --- /dev/null +++ b/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java @@ -0,0 +1,132 @@ +package dummy.contract.dex; + +import com.eclipsesource.json.Json; +import com.eclipsesource.json.JsonObject; +import score.Address; +import score.Context; +import score.VarDB; +import score.annotation.EventLog; +import score.annotation.External; + +import java.math.BigInteger; +import java.util.Arrays; + +import community.icon.cps.score.lib.interfaces.DexInterface; + +public class Dex implements DexInterface { + private static final String TAG = "Balanced DEX"; + private final VarDB
sicx = Context.newVarDB("sicx", Address.class); + public static final BigInteger EXA = BigInteger.valueOf(1_000_000_000_000_000_000L); + + public Dex() { + } + + @Override + @External + public void setSicxScore(Address _score) { + this.sicx.set(_score); + } + + @External(readonly = true) + public BigInteger getPrice(int poolId) { + return BigInteger.ONE; + } + + @Override + @EventLog + public void Deposit(Address from_token, Address from, BigInteger value) { + } + + @Override + @EventLog(indexed = 2) + public void Swap(BigInteger _id, Address _baseToken, Address _fromToken, Address _toToken, + Address _sender, Address _receiver, BigInteger _fromValue, BigInteger _toValue, + BigInteger _timestamp, BigInteger _lpFees, BigInteger _balnFees, BigInteger _poolBase, + BigInteger _poolQuote, BigInteger _endingPrice, BigInteger _effectiveFillPrice) { + } + + @Override + @External + public void tokenFallback(Address _from, BigInteger _value, byte[] _data) { + // Parse the transaction data submitted by the user + String unpackedData = new String(_data); + Context.require(!unpackedData.equals(""), "Token Fallback: Data can't be empty"); + if (Arrays.equals(_data, "None".getBytes())) { + return; + } + JsonObject json = Json.parse(unpackedData).asObject(); + + String method = json.get("method").asString(); + Address fromToken = Context.getCaller(); + + Context.require(_value.compareTo(BigInteger.ZERO) > 0, TAG + ": Invalid token transfer value"); + + // Call an internal method based on the "method" param sent in tokenFallBack + switch (method) { + case "_swap_icx": { + Context.println("the sicx is " + sicx.get()); + Context.require(fromToken.equals(sicx.get()), + TAG + ": InvalidAsset: _swap_icx can only be called with sICX"); + swapIcx(_from, _value); + break; + + } + case "_swap": { + + // Parse the slippage sent by the user in minimumReceive. + // If none is sent, use the maximum. + JsonObject params = json.get("params").asObject(); + BigInteger minimumReceive = BigInteger.ZERO; + if (params.contains("minimumReceive")) { + minimumReceive = BigInteger.valueOf(1000).multiply(EXA); + Context.require(minimumReceive.signum() >= 0, + TAG + ": Must specify a positive number for minimum to receive"); + } + + // Check if an alternative recipient of the swap is set. + Address receiver; + if (params.contains("receiver")) { + receiver = Address.fromString(params.get("receiver").asString()); + } else { + receiver = _from; + } + + // Get destination coin from the swap + Context.require(params.contains("toToken"), TAG + ": No toToken specified in swap"); + Address toToken = Address.fromString(params.get("toToken").asString()); + + // Perform the swap + exchange(fromToken, toToken, _from, receiver, _value, minimumReceive); + + break; + } + case "_dex":{ + break; + } + default: + // If no supported method was sent, revert the transaction + Context.revert(100, TAG + ": Unsupported method supplied"); + break; + } + } + + void swapIcx(Address sender, BigInteger value) { + Context.println("the sender is "+ sender); + Context.transfer(sender, value); + } + + void exchange(Address fromToken, Address toToken, Address sender, + Address receiver, BigInteger value, BigInteger minimumReceive) { + + if (minimumReceive == null) { + minimumReceive = BigInteger.ZERO; + } + + // Send the trader their funds + Context.call(toToken, "transfer", receiver, value); + + Swap(BigInteger.valueOf(0), fromToken, fromToken, toToken, sender, receiver, value, value, + BigInteger.valueOf(Context.getBlockTimestamp()), BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO + , BigInteger.ZERO); + } +} diff --git a/dummy/Router/build.gradle b/dummy/Router/build.gradle new file mode 100644 index 00000000..53ac1ea8 --- /dev/null +++ b/dummy/Router/build.gradle @@ -0,0 +1,44 @@ +version = '0.9.1' + +dependencies { + implementation project(':score-lib') + testImplementation project(':test-lib') +} + +optimizedJar { + mainClassName = 'dummy.contract.router.Router' + from { + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } +} + +deployJar { + endpoints { + lisbon { + uri = 'https://lisbon.net.solidwallet.io/api/v3' + nid = 0x2 + } + local { + uri = 'http://localhost:9082/api/v3' + nid = 0x3 + } + sejong { + uri = 'https://sejong.net.solidwallet.io/api/v3' + nid = 0x53 + + } + berlin { + uri = 'https://berlin.net.solidwallet.io/api/v3' + nid = 0x7 + to = 'cx28ae7ed3b07ed5247a3d2f97680f8555ce7c0a92' + } + } + keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' + password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' + parameters { + } +} + +test { + useJUnitPlatform() +} diff --git a/dummy/Router/src/main/java/dummy/contract/router/Router.java b/dummy/Router/src/main/java/dummy/contract/router/Router.java new file mode 100644 index 00000000..0a53dd66 --- /dev/null +++ b/dummy/Router/src/main/java/dummy/contract/router/Router.java @@ -0,0 +1,53 @@ +package dummy.contract.router; + +import score.Address; +import score.Context; +import score.annotation.External; +import score.annotation.Optional; +import score.annotation.Payable; + +import java.math.BigInteger; + +import community.icon.cps.score.lib.interfaces.RouterInterface; + +public class Router implements RouterInterface { + private static final String TAG = "Router"; + + public Router() { + } + + private void route(String from, Address startToken, Address[] _path, BigInteger _minReceive) { + Address currentToken = _path[1]; + + + BigInteger balance = (BigInteger) Context.call(currentToken, "balanceOf", Context.getAddress()); + Context.require(balance.compareTo(_minReceive) >= 0, + TAG + ": Below minimum receive amount of " + _minReceive); + Context.call(currentToken, "transfer", Address.fromString(from), _minReceive); + + } + + @Override + @Payable + @External + public void route(Address[] _path, @Optional BigInteger _minReceive, @Optional String _receiver) { + if (_minReceive == null) { + _minReceive = BigInteger.ZERO; + } + + if (_receiver == null || _receiver.equals("")) { + _receiver = Context.getCaller().toString(); + } + + Context.require(_minReceive.signum() >= 0, TAG + ": Must specify a positive number for minimum to receive"); + + Context.require(_path.length <= 2, + TAG + ": Passed max swaps of " + 2); + + route(_receiver, null, _path, Context.getValue()); + } + + @External + public void tokenFallback(Address _from, BigInteger _value, byte[] _data) { + } +} diff --git a/dummy/bnUSD/build.gradle b/dummy/bnUSD/build.gradle new file mode 100644 index 00000000..0f76e01b --- /dev/null +++ b/dummy/bnUSD/build.gradle @@ -0,0 +1,39 @@ +version = '0.0.1' + +dependencies { + + implementation project(':score-lib') + testImplementation project(':test-lib') +} + +optimizedJar { + mainClassName = 'dummy.contract.bnusd.bnUSD' + from { + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } +} + +deployJar { + endpoints { + lisbon { + uri = 'https://lisbon.net.solidwallet.io/api/v3' + nid = 0x2 + } + local { + uri = 'http://localhost:9082/api/v3' + nid = 0x3 + } + } + keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' + password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' + parameters { + arg('_name', 'Balanced Dollar') + arg('_symbol', 'bnUSD') + arg('_decimals', '0x12') + arg('_initialSupply', '0x989680') + } +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/dummy/bnUSD/src/main/java/dummy/contract/bnusd/bnUSD.java b/dummy/bnUSD/src/main/java/dummy/contract/bnusd/bnUSD.java new file mode 100644 index 00000000..e30aab2d --- /dev/null +++ b/dummy/bnUSD/src/main/java/dummy/contract/bnusd/bnUSD.java @@ -0,0 +1,35 @@ +package dummy.contract.bnusd; + +import community.icon.cps.score.lib.interfaces.bnUSDInterface; +import community.icon.cps.score.lib.tokens.IRC2Base; +import score.Address; +import score.Context; +import score.annotation.External; + +import java.math.BigInteger; + +public class bnUSD extends IRC2Base implements bnUSDInterface { + public bnUSD(String _name, String _symbol, int _decimals, BigInteger _initialSupply) { + super(_name, _symbol, BigInteger.valueOf(_decimals)); + + // mint the initial token supply here + Context.require(_initialSupply.compareTo(BigInteger.ZERO) >= 0); + mint(Context.getCaller(), _initialSupply); + } + + @External + public void mintTo(Address to, BigInteger amount) { + mint(to, amount); + } + + private static BigInteger pow10(int exponent) { + BigInteger result = BigInteger.ONE; + for (int i = 0; i < exponent; i++) { + result = result.multiply(BigInteger.TEN); + } + return result; + } + + +} + diff --git a/dummy/oracle/build.gradle b/dummy/oracle/build.gradle new file mode 100644 index 00000000..0541f98a --- /dev/null +++ b/dummy/oracle/build.gradle @@ -0,0 +1,57 @@ +version = '0.9.1' + +dependencies { +// compileOnly 'foundation.icon:javaee-api:0.9.1' +// implementation project(':score-lib') +// +// implementation 'com.github.sink772:javaee-tokens:0.6.1' +// implementation 'com.github.sink772:minimal-json:0.9.6' +// +// testImplementation 'foundation.icon:javaee-unittest:0.9.2' +// implementation 'org.mockito:mockito-core:4.3.1' +// testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' +// testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' +// testImplementation('org.mockito:mockito-inline:4.3.1') +// implementation 'foundation.icon:javaee-scorex:0.5.2' + + implementation project(':score-lib') + testImplementation project(':test-lib') + +} + +optimizedJar { + mainClassName = 'dummy.contract.oracle.Oracle' + from { + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } +} + +deployJar { + endpoints { + lisbon { + uri = 'https://lisbon.net.solidwallet.io/api/v3' + nid = 0x2 + } + local { + uri = 'http://localhost:9082/api/v3' + nid = 0x3 + } + sejong { + uri = 'https://sejong.net.solidwallet.io/api/v3' + nid = 0x53 + + } + berlin { + uri = 'https://berlin.net.solidwallet.io/api/v3' + nid = 0x7 + } + } + keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' + password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' + parameters { + } +} + +test { + useJUnitPlatform() +} diff --git a/dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java b/dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java new file mode 100644 index 00000000..5b86f2e0 --- /dev/null +++ b/dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java @@ -0,0 +1,15 @@ +package dummy.contract.oracle; + +import score.annotation.External; + +import java.math.BigInteger; + +public class Oracle { + + @External(readonly = true) + public BigInteger getReferenceData(String _base, String _quote) { + return BigInteger.ONE; + } + + +} diff --git a/dummy/sICX/build.gradle b/dummy/sICX/build.gradle new file mode 100644 index 00000000..42db9671 --- /dev/null +++ b/dummy/sICX/build.gradle @@ -0,0 +1,38 @@ +version = '0.9.1' + +dependencies { + implementation project(':score-lib') + testImplementation project(':test-lib') +} + +optimizedJar { + mainClassName = 'dummy.contract.sicx.sICX' + from { + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } +} + +deployJar { + endpoints { + lisbon { + uri = 'https://lisbon.net.solidwallet.io/api/v3' + nid = 0x2 + } + local { + uri = 'http://localhost:9082/api/v3' + nid = 0x3 + } + } + keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' + password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' + parameters { + arg('_name', 'Staked ICX') + arg('_symbol', 'sICX') + arg('_decimals', '0x12') + arg('_initialSupply', '0x989680') + } +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/dummy/sICX/src/main/java/dummy/contract/sicx/sICX.java b/dummy/sICX/src/main/java/dummy/contract/sicx/sICX.java new file mode 100644 index 00000000..9511215b --- /dev/null +++ b/dummy/sICX/src/main/java/dummy/contract/sicx/sICX.java @@ -0,0 +1,123 @@ +package dummy.contract.sicx; + +import community.icon.cps.score.lib.tokens.IRC2Base; +import score.annotation.External; +import score.Address; +import score.Context; +import community.icon.cps.score.lib.interfaces.sICXInterface; +import score.VarDB; +import score.annotation.Optional; + + +import java.math.BigInteger; + +public class sICX extends IRC2Base implements sICXInterface { + + private static final String TAG = "sICX"; + private static final String TOKEN_NAME = "Staked ICX"; + private static final String SYMBOL_NAME = "sICX"; + private static final BigInteger DECIMALS = BigInteger.valueOf(18); + private static final String STAKING = "staking"; + public static final String STATUS_MANAGER = "status_manager"; + private static final String VERSION = "version"; + private static final String SICX_VERSION = "v0.0.1"; + + static final Address ZERO_ADDRESS = new Address(new byte[Address.LENGTH]); + + private static final VarDB
stakingAddress = Context.newVarDB(STAKING, Address.class); + private final VarDB
statusManager = Context.newVarDB(STATUS_MANAGER, Address.class); + + private final VarDB currentVersion = Context.newVarDB(VERSION, String.class); + + public sICX(Address _admin) { + super(TOKEN_NAME, SYMBOL_NAME, DECIMALS); + if (stakingAddress.get() == null) { + stakingAddress.set(_admin); + } + + if (currentVersion.getOrDefault("").equals(SICX_VERSION)) { + Context.revert("Can't Update same version of code"); + } + currentVersion.set(SICX_VERSION); + } + + @External(readonly = true) + public String version() { + return currentVersion.getOrDefault(""); + } + + @External(readonly = true) + public String getPeg() { + return TAG; + } + + @External + public void setStaking(Address _address) { + onlyOwner(); + stakingAddress.set(_address); + } + + @External(readonly = true) + public Address getStaking() { + return stakingAddress.get(); + } + + @External + public void setEmergencyManager(Address _address) { + onlyOwner(); + statusManager.set(_address); + } + + @External(readonly = true) + public Address getEmergencyManager() { + return statusManager.get(); + } + + @External(readonly = true) + public BigInteger priceInLoop() { + return (BigInteger) Context.call(stakingAddress.get(), "getTodayRate"); + } + + @External(readonly = true) + public BigInteger lastPriceInLoop() { + return priceInLoop(); + } + + @External + public void govTransfer(Address _from, Address _to, BigInteger _value, @Optional byte[] _data) { + onlyOwner(); + _transfer(_from, _to, _value, _data); + } + + @Override + @External + public void transfer(Address _to, BigInteger _value, @Optional byte[] _data) { + _transfer(Context.getCaller(), _to, _value, _data); + } + + private void _transfer(Address _from, Address _to, BigInteger _value, @Optional byte[] _data) { + Address _stakingAddress = stakingAddress.get(); + +// if (!_to.equals(_stakingAddress)) { +// Context.call(_stakingAddress, "transferUpdateDelegations", _from, _to, _value); +// } + transfer(_from, _to, _value, _data); + } + + public static void onlyOwner() { + Address caller = Context.getCaller(); + Address owner = Context.getOwner(); + Context.require(caller.equals(owner), "SenderNotScoreOwner: Sender=" + caller + "Owner=" + owner); + } + + @External + public void mintWithTokenFallBack(Address _to, BigInteger _amount, byte[] _data){ + onlyOwner(); + mint(_to,_amount); + byte[] data = (_data == null) ? new byte[0] : _data; + if (_to.isContract()) { + Context.call(_to, "tokenFallback", ZERO_ADDRESS, _amount, data); + } + } +} + diff --git a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/DexInterface.java b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/DexInterface.java index 43f41de4..c44520f7 100644 --- a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/DexInterface.java +++ b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/DexInterface.java @@ -1,28 +1,27 @@ -//package community.icon.cps.score.lib.interfaces; -// -//import foundation.icon.score.client.ScoreClient; -//import foundation.icon.score.client.ScoreInterface; -//import score.Address; -//import score.annotation.EventLog; -//import score.annotation.External; -// -//import java.math.BigInteger; -// -////@ScoreInterface(suffix = "Client") -//@ScoreClient -//public interface DexInterface { -// -// @External -// void setSicxScore(Address _score); -// @EventLog -// void Deposit(Address from_token, Address from, BigInteger value); -// -// @EventLog(indexed = 2) -// void Swap(BigInteger _id, Address _baseToken, Address _fromToken, Address _toToken, -// Address _sender, Address _receiver, BigInteger _fromValue, BigInteger _toValue, -// BigInteger _timestamp, BigInteger _lpFees, BigInteger _balnFees, BigInteger _poolBase, -// BigInteger _poolQuote, BigInteger _endingPrice, BigInteger _effectiveFillPrice); -// -// @External -// void tokenFallback(Address _from, BigInteger _value, byte[] _data); -//} +package community.icon.cps.score.lib.interfaces; + +import foundation.icon.score.client.ScoreInterface; +import score.Address; +import score.annotation.EventLog; +import score.annotation.External; + +import java.math.BigInteger; + + +@ScoreInterface(suffix = "Client") +public interface DexInterface { + + @External + void setSicxScore(Address _score); + @EventLog + void Deposit(Address from_token, Address from, BigInteger value); + + @EventLog(indexed = 2) + void Swap(BigInteger _id, Address _baseToken, Address _fromToken, Address _toToken, + Address _sender, Address _receiver, BigInteger _fromValue, BigInteger _toValue, + BigInteger _timestamp, BigInteger _lpFees, BigInteger _balnFees, BigInteger _poolBase, + BigInteger _poolQuote, BigInteger _endingPrice, BigInteger _effectiveFillPrice); + + @External + void tokenFallback(Address _from, BigInteger _value, byte[] _data); +} diff --git a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/RouterInterface.java b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/RouterInterface.java index 03c903a3..3300534e 100644 --- a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/RouterInterface.java +++ b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/RouterInterface.java @@ -1,18 +1,16 @@ -//package community.icon.cps.score.lib.interfaces; -// -//import foundation.icon.score.client.ScoreClient; -//import foundation.icon.score.client.ScoreInterface; -//import score.Address; -//import score.annotation.External; -//import score.annotation.Optional; -//import score.annotation.Payable; -// -//import java.math.BigInteger; -// -////@ScoreInterface(suffix = "Client") -//@ScoreClient -//public interface RouterInterface { -// @Payable -// @External -// void route(Address[] _path, @Optional BigInteger _minReceive); -//} +package community.icon.cps.score.lib.interfaces; + +import foundation.icon.score.client.ScoreInterface; +import score.Address; +import score.annotation.External; +import score.annotation.Optional; +import score.annotation.Payable; + +import java.math.BigInteger; + +@ScoreInterface(suffix = "Client") +public interface RouterInterface { + @Payable + @External + void route(Address[] _path, @Optional BigInteger _minReceive,@Optional String _receiver); +} diff --git a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/bnUSDInterface.java b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/bnUSDInterface.java index 8ae0055d..7d426077 100644 --- a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/bnUSDInterface.java +++ b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/bnUSDInterface.java @@ -1,10 +1,9 @@ -//package community.icon.cps.score.lib.interfaces; -// -//import community.icon.cps.score.lib.interfaces.tokens.IRC2; -//import foundation.icon.score.client.ScoreClient; -//import foundation.icon.score.client.ScoreInterface; -// -//@ScoreClient -////@ScoreInterface(suffix = "Client") -//public interface bnUSDInterface extends IRC2 { -//} +package community.icon.cps.score.lib.interfaces; + +import community.icon.cps.score.lib.interfaces.tokens.IRC2; +import foundation.icon.score.client.ScoreInterface; + + +@ScoreInterface(suffix = "Client") +public interface bnUSDInterface extends IRC2 { +} diff --git a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/sICXInterface.java b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/sICXInterface.java index 82cdfee5..ae700d7f 100644 --- a/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/sICXInterface.java +++ b/score-lib/src/main/java/community/icon/cps/score/lib/interfaces/sICXInterface.java @@ -1,10 +1,8 @@ -//package community.icon.cps.score.lib.interfaces; -// -//import community.icon.cps.score.lib.interfaces.tokens.IRC2; -//import foundation.icon.score.client.ScoreClient; -//import foundation.icon.score.client.ScoreInterface; -// -////@ScoreInterface(suffix = "Client") -//@ScoreClient -//public interface sICXInterface extends IRC2 { -//} +package community.icon.cps.score.lib.interfaces; + +import community.icon.cps.score.lib.interfaces.tokens.IRC2; +import foundation.icon.score.client.ScoreInterface; + +@ScoreInterface(suffix = "Client") +public interface sICXInterface extends IRC2 { +} diff --git a/settings.gradle b/settings.gradle index 6914f2e9..5a429622 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,34 +1,33 @@ rootProject.name = 'cps_java_contracts' -include (':CPFTreasury') +include(':CPFTreasury') project(':CPFTreasury').projectDir = file("CPFTreasury") -include (':CPSTreasury') +include(':CPSTreasury') project(':CPSTreasury').projectDir = file("CPSTreasury") -include (':CPSCore') +include(':CPSCore') project(':CPSCore').projectDir = file("CPSCore") -//include ('score-client') -// -include ('test-lib') + +include('test-lib') project(':test-lib').projectDir = file("test-lib") -include ('score-lib') +include('score-lib') project(':score-lib').projectDir = file("score-lib") -// -//include (':Router') -//project(':Router').projectDir = file("dummy/Router") -// -//include (':Dex') -//project(':Dex').projectDir = file("dummy/Dex") -// -//include (':sICX') -//project(':sICX').projectDir = file("dummy/sICX") -// -//include (':bnUSD') -//project(':bnUSD').projectDir = file("dummy/bnUSD") -// -//include(':oracle') -//project(':oracle').projectDir = file("dummy/oracle") \ No newline at end of file + +include(':Router') +project(':Router').projectDir = file("dummy/Router") + +include(':Dex') +project(':Dex').projectDir = file("dummy/Dex") + +include(':sICX') +project(':sICX').projectDir = file("dummy/sICX") + +include(':bnUSD') +project(':bnUSD').projectDir = file("dummy/bnUSD") + +include(':oracle') +project(':oracle').projectDir = file("dummy/oracle") \ No newline at end of file diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/DummyDex.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/DummyDex.java index 4de1ce77..c245d67c 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/DummyDex.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/DummyDex.java @@ -53,4 +53,6 @@ public interface DummyDex { void URI(BigInteger _id, String _value); + + void setSicxScore(Address _score); } diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/sICX.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/sICX.java index 0b5296fb..e63bbc29 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/sICX.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/sICX.java @@ -1,4 +1,15 @@ package community.icon.cps.score.test.integration.scores; +import score.Address; +import score.annotation.External; + +import java.math.BigInteger; + public interface sICX { + + @External + void mintWithTokenFallBack(Address _to, BigInteger _amount, byte[] _data); + + @External(readonly = true) + BigInteger balanceOf(Address _owner); } diff --git a/test-lib/src/main/resources/conf/contracts.json b/test-lib/src/main/resources/conf/contracts.json index 1312f531..241e653f 100644 --- a/test-lib/src/main/resources/conf/contracts.json +++ b/test-lib/src/main/resources/conf/contracts.json @@ -6,7 +6,7 @@ "bondValue": 15, "applicationPeriod": "20" }, - "order":1.0 + "order": 1.0 }, { "name": "bnUSD", @@ -21,21 +21,21 @@ }, { "name": "dex", - "contract": "DEX", + "contract": "Dex", "params": { }, "order": 1.0 }, { "name": "router", - "contract": "ROUTER", + "contract": "Router", "params": { }, "order": 1.0 }, { "name": "oracle", - "contract": "ORACLE", + "contract": "oracle", "params": { }, "order": 1.0 @@ -48,7 +48,7 @@ "addressParams": { "cpsScore": "cpsCore" }, - "order":2.0 + "order": 2.0 }, { "name": "cpfTreasury", @@ -58,7 +58,7 @@ "addressParams": { "cpsScore": "cpsCore" }, - "order":2.0 + "order": 2.0 }, { "name": "sICX", From d09eb5f14ee749d9a3f465583c5e191edf2dab00 Mon Sep 17 00:00:00 2001 From: naneey Date: Thu, 28 Mar 2024 16:32:58 +0545 Subject: [PATCH 34/64] chore: setters in config file --- .../icon/cps/score/test/integration/CPS.java | 5 +---- .../score/test/integration/config/BaseConfig.java | 13 +++++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java index c2226d55..36d40b9a 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java @@ -217,10 +217,7 @@ public void send(foundation.icon.jsonrpc.Address address, String method, Map()); - } + public String getScorePath(String key) { String path = System.getProperty(key); diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java index f33a68f2..1ae48a7e 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/config/BaseConfig.java @@ -1,5 +1,6 @@ package community.icon.cps.score.test.integration.config; +import com.eclipsesource.json.JsonObject; import community.icon.cps.score.test.integration.CPS; import community.icon.cps.score.test.integration.CPSClient; import community.icon.cps.score.test.integration.Environment; @@ -47,11 +48,23 @@ public void call(){ cpsClient.cpfTreasury.setRouterScore(addressMap.get("router")); cpsClient.cpfTreasury.setSicxScore(addressMap.get("sICX")); + System.out.println("----setting in dex----------"); + cpsClient.dex.setSicxScore(addressMap.get("sICX")); + System.out.println("------setting funds--------"); cpsClient.cpfTreasury.setMaximumTreasuryFundIcx(BigInteger.valueOf(1000).multiply(EXA)); cpsClient.cpfTreasury.setMaximumTreasuryFundBnusd(BigInteger.valueOf(10000).multiply(EXA)); // this.cpsClient.bnUSD.setMinter(this.cpsClient.getAddress()); cpsClient.bnUSD.mintTo(addressMap.get("cpfTreasury"),BigInteger.valueOf(5000).multiply(EXA) ); + + JsonObject burnTokens = new JsonObject(); + burnTokens.add("method","_dex"); + + cpsClient.sICX.mintWithTokenFallBack(addressMap.get("dex"),BigInteger.valueOf(10000).multiply(EXA),burnTokens.toString().getBytes()); +// cpsClient.sICX.mintWithTokenFallBack(addressMap.get("cpfTreasury"),BigInteger.valueOf(100).multiply(EXA),"None".getBytes()); + + System.out.println(cpsClient.sICX.balanceOf(addressMap.get("dex"))); + cpsClient.cpfTreasury.toggleSwapFlag(); cpsClient.cpsCore.toggleMaintenance(); From bc2a1192216b6a95a8e600726cc589f8517fd79a Mon Sep 17 00:00:00 2001 From: naneey Date: Wed, 10 Apr 2024 09:02:10 +0545 Subject: [PATCH 35/64] chore: prep penalty paid --- .../cps/integration/CPSCoreIntegration.java | 31 ++++++++++++------- .../src/main/java/dummy/contract/dex/Dex.java | 17 ++++++++++ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java index f2aab45d..b0aad6de 100644 --- a/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java +++ b/CPSCore/src/intTest/java/community/icon/cps/integration/CPSCoreIntegration.java @@ -22,6 +22,7 @@ import static community.icon.cps.score.cpscore.utils.Constants.*; import static community.icon.cps.score.test.AssertRevertedException.assertUserRevert; +import static community.icon.cps.score.test.integration.Environment.godClient; import static org.junit.jupiter.api.Assertions.assertEquals; import java.math.BigInteger; @@ -67,6 +68,8 @@ public static void setup() throws Exception{ cpsClients.put(i,cps.customClient(privKey)); } + // ICX swap purpose + godClient._transfer(addressMap.get("dex"),BigInteger.valueOf(200).multiply(EXA),"transferICX to dex"); } @@ -117,7 +120,6 @@ public void registerPrepExceptions(){ assertUserRevert(new UserRevertException(TAG+": P-Rep is already registered."), () -> registeredPrep.cpsCore.registerPrep(),null); - // TODO: handle deny list } @DisplayName("unregister prep") @@ -183,7 +185,7 @@ public void submitProposal(){ CPSCoreInterface.MilestonesAttributes milestonesAttributes3 = new CPSCoreInterface.MilestonesAttributes(); milestonesAttributes3.completionPeriod = 3; milestonesAttributes3.budget = BigInteger.valueOf(20).multiply(ICX); - milestonesAttributes3.id = 3; // TODO: check if same id is sent + milestonesAttributes3.id = 3; CPSCoreInterface.MilestonesAttributes[] milestonesAttributes =new CPSCoreInterface.MilestonesAttributes[] {milestonesAttributes1, milestonesAttributes2,milestonesAttributes3}; @@ -258,7 +260,6 @@ public void voteProposal() throws InterruptedException { assertEquals(toInt((String)proposalVote.get("total_voters")),7); assertEquals(toInt((String)proposalVote.get("approve_voters")),7); assertEquals(toInt((String)proposalVote.get("reject_voters")),0); - // TODO: approved votes does not match up // assertEquals(toBigInt((String)proposalVote.get("approved_votes")),BigInteger.valueOf(9540000).multiply(ICX)); } @@ -941,7 +942,6 @@ public void votePriority() { } - // trying to Register by deny prep TODO } @@ -1002,19 +1002,19 @@ public void prepPayPenalty() { bnUSDMint(prep.getAddress(), BigInteger.TWO.multiply(ICX)); byte[] data = penaltyByteArray("payPrepPenalty"); - // TODO: pay the penalty - ownerClient.cpsCore.removeDenylistPreps(); -// prep.bnUSD.transfer(addressMap.get("cpsCore"),penaltyAmount,data); +// ownerClient.cpsCore.removeDenylistPreps(); + prep.bnUSD.transfer(addressMap.get("cpsCore"),penaltyAmount,data); - Map prepData = loginPrep(prep.getAddress()); - assertEquals(prepData, unregisteredPrepData()); + Map prepData = loginPrep(prep.getAddress()); + assertEquals(prepData, votingPrepData()); - prep.cpsCore.registerPrep(); - Map prepData2 = loginPrep(prep.getAddress()); - assertEquals(prepData2, votingPrepData()); +// prep.cpsCore.registerPrep(); +// Map prepData2 = loginPrep(prep.getAddress()); +// +// assertEquals(prepData2, votingPrepData()); } @@ -1738,6 +1738,13 @@ private Map unregisteredPrepData(){ VOTING_PREP, BigInteger.ZERO); } + private Map normalPrepData(){ + return Map.of(IS_PREP, BigInteger.ONE, + IS_REGISTERED, BigInteger.ZERO, + PAY_PENALTY, BigInteger.ZERO, + VOTING_PREP, BigInteger.ZERO); + } + private Map votingPrepData(){ return Map.of(IS_PREP, BigInteger.ONE, IS_REGISTERED, BigInteger.ONE, diff --git a/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java b/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java index f045a1bd..c5709c5a 100644 --- a/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java +++ b/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java @@ -12,6 +12,7 @@ import java.util.Arrays; import community.icon.cps.score.lib.interfaces.DexInterface; +import score.annotation.Payable; public class Dex implements DexInterface { private static final String TAG = "Balanced DEX"; @@ -45,6 +46,12 @@ public void Swap(BigInteger _id, Address _baseToken, Address _fromToken, Address BigInteger _poolQuote, BigInteger _endingPrice, BigInteger _effectiveFillPrice) { } + + @Payable + public void fallback(){ + + } + @Override @External public void tokenFallback(Address _from, BigInteger _value, byte[] _data) { @@ -72,6 +79,7 @@ public void tokenFallback(Address _from, BigInteger _value, byte[] _data) { } case "_swap": { + Context.println("the thus us called"); // Parse the slippage sent by the user in minimumReceive. // If none is sent, use the maximum. @@ -96,7 +104,12 @@ public void tokenFallback(Address _from, BigInteger _value, byte[] _data) { Address toToken = Address.fromString(params.get("toToken").asString()); // Perform the swap + Context.println("from token "+ fromToken); + Context.println("from token "+ toToken); + Context.println("from "+ _from); + Context.println("receiver "+ receiver); exchange(fromToken, toToken, _from, receiver, _value, minimumReceive); + Context.println("after the exchange "); break; } @@ -123,7 +136,11 @@ void exchange(Address fromToken, Address toToken, Address sender, } // Send the trader their funds + Context.println("is it heree?"); + Context.println("roe "+ toToken); + Context.println("roe "+ receiver); Context.call(toToken, "transfer", receiver, value); + Context.println("lets check this " + Context.getAddress()); Swap(BigInteger.valueOf(0), fromToken, fromToken, toToken, sender, receiver, value, value, BigInteger.valueOf(Context.getBlockTimestamp()), BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO From dc9a7ed51d92ab58fcfc808d53bc6e62b15eeca1 Mon Sep 17 00:00:00 2001 From: naneey Date: Wed, 10 Apr 2024 09:09:10 +0545 Subject: [PATCH 36/64] chore: sleep added --- .../main/java/community/icon/cps/score/test/integration/CPS.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java index 36d40b9a..7b4a6721 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java @@ -48,6 +48,7 @@ public CPS(String contracts) throws Exception { public void setupCPS() throws Exception { deployPrep(); decentralizeChain(); + Thread.sleep(200000); this.addresses = new ScoreDeployer(this,contracts).deployContracts(); ownerClient = new CPSClient(this,owner); From 743a3b57a1e709d6f70d7227766338d274e9bf57 Mon Sep 17 00:00:00 2001 From: naneey Date: Wed, 10 Apr 2024 10:35:49 +0545 Subject: [PATCH 37/64] chore: score client configured --- test-lib/build.gradle | 1 + .../cps/score/test/integration/scores/CPSCoreInterface.java | 2 -- .../cps/score/test/integration/scores/SystemInterface.java | 3 +++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test-lib/build.gradle b/test-lib/build.gradle index 2b39f3ad..002e452e 100644 --- a/test-lib/build.gradle +++ b/test-lib/build.gradle @@ -9,6 +9,7 @@ repositories { dependencies { // implementation "foundation.icon:icon-sdk:$iconsdkVersion" implementation name: "score-client-$scoreClientVersion" + annotationProcessor name: "score-client-$scoreClientVersion" implementation "org.junit.jupiter:junit-jupiter-api:$junitVersion" implementation "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion" diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java index a586c1aa..11c3ffe9 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/CPSCoreInterface.java @@ -204,8 +204,6 @@ public static class MilestoneVoteAttributes { @External(readonly = true) int getMileststoneStatusOf(String proposalKey, int milestoneId); - @External(readonly = true) - Map getMilestonesReport(String ipfsKey, int milestoneId); @External(readonly = true) diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/SystemInterface.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/SystemInterface.java index 7645ce44..200acd6b 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/SystemInterface.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/scores/SystemInterface.java @@ -2,10 +2,13 @@ import java.math.BigInteger; import java.util.Map; + +import foundation.icon.score.client.ScoreClient; import score.Address; import score.annotation.Payable; +@ScoreClient public interface SystemInterface { public class Delegation{ From 4dfe2e3c6e4dc0ab4e21e6289a53153710c93529 Mon Sep 17 00:00:00 2001 From: naneey Date: Wed, 10 Apr 2024 10:36:24 +0545 Subject: [PATCH 38/64] chore: sleep time reduced --- .../java/community/icon/cps/score/test/integration/CPS.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java index 7b4a6721..65905c21 100644 --- a/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java +++ b/test-lib/src/main/java/community/icon/cps/score/test/integration/CPS.java @@ -48,7 +48,7 @@ public CPS(String contracts) throws Exception { public void setupCPS() throws Exception { deployPrep(); decentralizeChain(); - Thread.sleep(200000); + Thread.sleep(120000); this.addresses = new ScoreDeployer(this,contracts).deployContracts(); ownerClient = new CPSClient(this,owner); From 761adb7dff7122bac2096fe5d5c737ba886485da Mon Sep 17 00:00:00 2001 From: naneey Date: Fri, 12 Apr 2024 11:11:52 +0545 Subject: [PATCH 39/64] chore: deployment script added --- script/const.sh | 39 +++ .../contracts/contracts_20240412_103742.txt | 8 + script/deploy.sh | 312 ++++++++++++++++++ 3 files changed, 359 insertions(+) create mode 100644 script/const.sh create mode 100644 script/contracts/contracts_20240412_103742.txt create mode 100644 script/deploy.sh diff --git a/script/const.sh b/script/const.sh new file mode 100644 index 00000000..ac856fd8 --- /dev/null +++ b/script/const.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +export SCRIPTS_DIR=$PWD +export CPS_JAVA_SCORE="$SCRIPTS_DIR/.." +export DUMMY_SCORE="$SCRIPTS_DIR/../dummy" +export CONTRACT_FILE_NAME="contracts_$(date +"%Y%m%d_%H%M%S").txt" +export CONTRACT_ADDRESS="$SCRIPTS_DIR/contracts/$CONTRACT_FILE_NAME" + +#--------------------------------------------------------------------- +#-----------------CHANGE THIS BY REQUIREMENT-------------------------- +#--------------------------------------------------------------------- + +export ICON=icon +export ICON_NET=local ## [local, testnet, mainnet ] + +export SICX_ADMIN="hxb6b5791be0b5ef67063b3c10b840fb81514db2fd" +export DEPLOYER_ADDRESS="hxb6b5791be0b5ef67063b3c10b840fb81514db2fd" + +export ICON_WALLET_NAME=godWallet +export ICON_WALLET=$CPS_JAVA_SCORE/cps-gochain-local/data/godWallet.json +export ICON_PASSWORD=gochain + +case $ICON_NET in + "local" ) + export ICON_NID=3 + export ICON_NODE=http://localhost:9082/api/v3/ + export ICON_DEBUG_NODE=http://localhost:9082/api/v3d + ;; + "testnet" ) + export ICON_NID=2 + export ICON_NODE=https://lisbon.net.solidwallet.io/api/v3/ + export ICON_DEBUG_NODE=https://lisbon.net.solidwallet.io/api/v3d + ;; +esac + +export ICON_COMMON_ARGS="--uri $ICON_NODE --nid $ICON_NID --step_limit 2500000000 --key_store $ICON_WALLET \ +--key_password $ICON_PASSWORD " + +export GOVERNANCE_SCORE=cx0000000000000000000000000000000000000000 \ No newline at end of file diff --git a/script/contracts/contracts_20240412_103742.txt b/script/contracts/contracts_20240412_103742.txt new file mode 100644 index 00000000..17f9dce2 --- /dev/null +++ b/script/contracts/contracts_20240412_103742.txt @@ -0,0 +1,8 @@ +CPSCore: cxd1872a8d7c65f6e05f32a81c0a1084b1a4e90a53 +CPSTreasury: cx91814b2698b27c3923f8d1aa5795fb2daebeead4 +CPFTreasury: cxd4473c8c026de126f968693129fadf7c3dad7b6b +bnUSD: cx0f2d7893bac7e308667cc2ebb67b6e3fed3aba08 +Dex: cx9673aed808682dc29b27f4e41ecf48df937b24f5 +oracle: cx68df1a3e30fc9f44bbc2fb73f7b39f211c47c1e1 +Router: cx7c40a5be786b187972886e495f933756f210e083 +sICX: cxc631f59377d412c8ffe17cd9aa52a8f670623f9e diff --git a/script/deploy.sh b/script/deploy.sh new file mode 100644 index 00000000..e1ba6736 --- /dev/null +++ b/script/deploy.sh @@ -0,0 +1,312 @@ +#!/bin/bash + +source const.sh + +function icon_wait_tx() { + local ret=1 + local tx_hash=$1 + while :; do + goloop rpc \ + --uri "$ICON_NODE" \ + txresult "$tx_hash" &>/dev/null && break || sleep 1 + done + + local res=$(goloop rpc \ + --uri $ICON_NODE \ + txresult "$tx_hash") + local status=$(jq <<<"$res" -r .status) + + echo "status : $status" + [ "$status" == 0x0 ] && echo $res && exit 0 + [ "$status" == 0x1 ] && ret=0 + + return $ret +} + +function save_address() { + local ret=1 + local tx_hash=$1 + local addrLoc=$2 + local fileName=$3 + local res=$(goloop rpc \ + --uri $ICON_NODE \ + txresult "$tx_hash" 2>/dev/null) + + local score_address=$(jq <<<"$res" -r .scoreAddress) + echo "contract address : $score_address" + echo "$fileName: $score_address" >> $addrLoc +} + + +function deploy_contract() { + local jarFile=$1 + local addrLoc=$2 + + + local contractName=$(basename "$jarFile" | cut -d'-' -f1) + echo "deploying contract $contractName" + + local params=() + for i in "${@:3}"; do params+=("--param $i"); done + + local tx_hash=$( + goloop rpc sendtx deploy $jarFile \ + --content_type application/java \ + --to $GOVERNANCE_SCORE \ + $ICON_COMMON_ARGS \ + ${params[@]} | jq -r . + ) + icon_wait_tx $tx_hash + save_address $tx_hash $addrLoc $contractName + +} + +function icon_send_tx() { + local address=$1 + local method=$2 + + local params=() + for i in "${@:3}"; do params+=("--param $i"); done + local tx_hash=$( + goloop rpc sendtx call \ + --to "$address" \ + --method "$method" \ + $ICON_COMMON_ARGS \ + ${params[@]} | jq -r . + ) + icon_wait_tx "$tx_hash" +} + +function setPrepPenaltyAmount() { + local param="{\"params\":{\"penalty\":[\"2\",\"5\",\"10\"]}}" + local address=$(grep 'CPSCore' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + local method="setPrepPenaltyAmount" + local tx_hash=$(goloop rpc sendtx call \ + --to "$address" \ + --method "$method" \ + --raw $param\ + $ICON_COMMON_ARGS | jq -r . + ) + icon_wait_tx $tx_hash +} + +function icon_transfer_icx() { + local address=$1 + local val=$2 + + local params=() + for i in "${@:3}"; do params+=("--param $i"); done + + local tx_hash=$( + goloop rpc sendtx transfer \ + --to "$address" \ + --value "$val" \ + $ICON_COMMON_ARGS \ + ${params[@]} | jq -r . + ) + icon_wait_tx "$tx_hash" +} + + +function deploy_cps_contracts() { + + echo "-------------------------------------------------------------------" + echo "--------------------------DEPLOY CONTRACTS-------------------------" + echo "-------------------------------------------------------------------" + local CPS_CORE_FILE=$CPS_JAVA_SCORE/CPSCore/build/libs/CPSCore-[0-9].[0-9].[0-9]-optimized.jar + deploy_contract $CPS_CORE_FILE $CONTRACT_ADDRESS bondValue="2" applicationPeriod="15" + + local cps_score_addr=$(grep 'CPSCore' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + local CPS_TREASURY_FILE=$CPS_JAVA_SCORE/CPSTreasury/build/libs/CPSTreasury-[0-9].[0-9].[0-9]-optimized.jar + deploy_contract $CPS_TREASURY_FILE $CONTRACT_ADDRESS cpsScore=$cps_score_addr + + local CPF_TREASURY_FILE=$CPS_JAVA_SCORE/CPFTreasury/build/libs/CPFTreasury-[0-9].[0-9].[0-9]-optimized.jar + deploy_contract $CPF_TREASURY_FILE $CONTRACT_ADDRESS cpsScore=$cps_score_addr + + local BNUSD_FILE=$DUMMY_SCORE/bnUSD/build/libs/bnUSD-[0-9].[0-9].[0-9]-optimized.jar + deploy_contract $BNUSD_FILE $CONTRACT_ADDRESS _name="Dummy_Stable_Coin" _symbol="bnUSD" _decimals="18" _initialSupply="100000000000000000000" + + local DEX_FILE=$DUMMY_SCORE/Dex/build/libs/Dex-[0-9].[0-9].[0-9]-optimized.jar + deploy_contract $DEX_FILE $CONTRACT_ADDRESS + + local ORACLE_FILE=$DUMMY_SCORE/oracle/build/libs/oracle-[0-9].[0-9].[0-9]-optimized.jar + deploy_contract $ORACLE_FILE $CONTRACT_ADDRESS + + local ROUTER_FILE=$DUMMY_SCORE/Router/build/libs/Router-[0-9].[0-9].[0-9]-optimized.jar + deploy_contract $ROUTER_FILE $CONTRACT_ADDRESS + + local SICX_FILE=$DUMMY_SCORE/sICX/build/libs/sICX-[0-9].[0-9].[0-9]-optimized.jar + deploy_contract $SICX_FILE $CONTRACT_ADDRESS _admin=$SICX_ADMIN + +} + +function setters_in_cps_score() { + echo "-------------------------------------------------------------------" + echo "--------------------SET CONTRACTS IN CPS SCORE---------------------" + echo "-------------------------------------------------------------------" + + local cps_score_addr=$(grep 'CPSCore' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + + echo "setting admin address" + icon_send_tx $cps_score_addr "addAdmin" address=$SICX_ADMIN + + echo "setting cps treasury address" + local cps_treasury_addr=$(grep 'CPSTreasury' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + icon_send_tx $cps_score_addr "setCpsTreasuryScore" score=$cps_treasury_addr + + echo "setting cpf treasury address" + local cpf_treasury_addr=$(grep 'CPFTreasury' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + icon_send_tx $cps_score_addr "setCpfTreasuryScore" score=$cpf_treasury_addr + + echo "setting bnUSD address" + local bnUSD_addr=$(grep 'bnUSD' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + icon_send_tx $cps_score_addr "setBnusdScore" score=$bnUSD_addr + +} + +function setter_in_cpf_treasury() { + echo "-------------------------------------------------------------------" + echo "-----------------SET CONTRACTS IN CPF TREASURY---------------------" + echo "-------------------------------------------------------------------" + + local cpf_treasury_addr=$(grep 'CPFTreasury' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + + echo "setting cps treasury address" + local cps_treasury_addr=$(grep 'CPSTreasury' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + icon_send_tx $cpf_treasury_addr "setCpsTreasuryScore" score=$cps_treasury_addr + + echo "setting bnUSD address" + local bnUSD_addr=$(grep 'bnUSD' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + icon_send_tx $cpf_treasury_addr "setBnUSDScore" score=$bnUSD_addr + + echo "setting dex address" + local dex_addr=$(grep 'Dex' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + icon_send_tx $cpf_treasury_addr "setDexScore" score=$dex_addr + + echo "setting oracle address" + local oracle_addr=$(grep 'oracle' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + icon_send_tx $cpf_treasury_addr "setOracleAddress" score=$oracle_addr + + echo "setting router address" + local router_addr=$(grep 'Router' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + icon_send_tx $cpf_treasury_addr "setRouterScore" score=$router_addr + + echo "setting sICX address" + local sICX_addr=$(grep 'sICX' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + icon_send_tx $cpf_treasury_addr "setSicxScore" score=$sICX_addr +} + +function setters_in_cps_treasury() { + echo "-------------------------------------------------------------------" + echo "-----------------SET CONTRACTS IN CPS TREASURY---------------------" + echo "-------------------------------------------------------------------" + + local cps_treasury_addr=$(grep 'CPSTreasury' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + + echo "setting cpf treasury address" + local cpf_treasury_addr=$(grep 'CPFTreasury' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + icon_send_tx $cps_treasury_addr "setCpfTreasuryScore" score=$cpf_treasury_addr + + echo "setting bnUSD address" + local bnUSD_addr=$(grep 'bnUSD' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + icon_send_tx $cps_treasury_addr "setBnUSDScore" score=$bnUSD_addr + +} + +function setters_in_dex() { + echo "-------------------------------------------------------------------" + echo "-----------------SET CONTRACTS IN DEX------------------------------" + echo "-------------------------------------------------------------------" + + local dex=$(grep 'Dex' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + + local sICX_addr=$(grep 'sICX' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + icon_send_tx $dex "setSicxScore" _score=$sICX_addr + +} + +function add_funds() { + echo "-------------------------------------------------------------------" + echo "-----------------ADD FUND IN TREASURY------------------------------" + echo "-------------------------------------------------------------------" + + local cpf_treasury_addr=$(grep 'CPFTreasury' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + + echo "set treasury fund limit" + icon_send_tx $cpf_treasury_addr "setMaximumTreasuryFundIcx" value="10000000000000000000000" + icon_send_tx $cpf_treasury_addr "setMaximumTreasuryFundBnusd" value="10000000000000000000000" + + echo "send fund to treasury" + local bnUSD_addr=$(grep 'bnUSD' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + icon_send_tx $bnUSD_addr "mintTo" to=$cpf_treasury_addr amount="5000000000000000000000" + + echo "send sicx to dex for swap" + local sICX_addr=$(grep 'sICX' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + local dex_addr=$(grep 'Dex' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + icon_send_tx $sICX_addr "mintWithTokenFallBack" _to=$dex_addr _amount="1000000000000000000000" \ + _data="0x7b0a2020226d6574686f64223a20225f646578220a7d" + + echo "send ICX to dex" + icon_transfer_icx $dex_addr "100000000000000000000" + + +} + +function configure_system() { + echo "-------------------------------------------------------------------" + echo "-----------------SET SYSTEM CONFIGURATION--------------------------" + echo "-------------------------------------------------------------------" + local cps_score_addr=$(grep 'CPSCore' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + + echo "turn off maintainance mode" + icon_send_tx $cps_score_addr "toggleMaintenance" + + echo "set initial block" + icon_send_tx $cps_score_addr "setInitialBlock" + + echo "set prep's penalty amount" + setPrepPenaltyAmount + + local cpf_treasury_addr=$(grep 'CPFTreasury' "$CONTRACT_ADDRESS" | cut -d' ' -f2) + + echo "toggle swap flag" + icon_send_tx $cpf_treasury_addr "toggleSwapFlag" + +} + + + +function set_contracts() { + setters_in_cps_score + setters_in_cps_treasury + setter_in_cpf_treasury + setters_in_dex + +} + +function configure_fund_and_system() { +# add_funds + configure_system +} + +SHORT=adsc +LONG=all,deploy-contracts,set-contracts,configure-system + +options=$(getopt -o $SHORT --long $LONG -n 'deploy.sh' -- "$@") +if [ $? -ne 0 ]; then + echo "Usage: $0 [-a] [-d] [-s] [-c]" >&2 + exit 1 +fi + +eval set -- "$options" + +while true; do + case "$1" in + -a|--all) deploy_cps_contracts; set_contracts; configure_fund_and_system; shift ;; + -d|--deploy-contracts) deploy_cps_contracts; shift ;; + -s|--set-contracts) set_contracts; shift ;; + -c|--configure-system) configure_fund_and_system; shift ;; + --) shift; break ;; + *) echo "Internal error!"; exit 1 ;; + esac +done \ No newline at end of file From b11eff22c7631c4708caac63b6d21702a46242f8 Mon Sep 17 00:00:00 2001 From: naneey Date: Fri, 12 Apr 2024 11:12:50 +0545 Subject: [PATCH 40/64] chore: docs on running test added --- README.md | 33 ++++++++++++++++++- .../src/main/java/dummy/contract/dex/Dex.java | 14 ++------ 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index c6928651..fdfc9f7b 100644 --- a/README.md +++ b/README.md @@ -1 +1,32 @@ -# cps_java_contracts \ No newline at end of file +# CPS JAVA CONTRACTS + +This repository contains the smart contracts for CPS in Java. + +### Requirement +- JDK 11+ + +### Setting up Local Environment + +- Clone submodule + +```git submodule update --init``` + +- Run unit tests + +```./gradlew clean build optimizedJar``` + +### Run integration tests + +- Install [docker](https://docs.docker.com/engine/install/) and [docker compose](https://docs.docker.com/compose/install/) +- Start local blockchain + +```docker compose up -d``` + + +- execute following command + +```./gradlew intTestClasses``` + +```./gradlew assemble``` + +```./gradlew integrationTest``` \ No newline at end of file diff --git a/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java b/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java index c5709c5a..7f4f2859 100644 --- a/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java +++ b/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java @@ -71,7 +71,6 @@ public void tokenFallback(Address _from, BigInteger _value, byte[] _data) { // Call an internal method based on the "method" param sent in tokenFallBack switch (method) { case "_swap_icx": { - Context.println("the sicx is " + sicx.get()); Context.require(fromToken.equals(sicx.get()), TAG + ": InvalidAsset: _swap_icx can only be called with sICX"); swapIcx(_from, _value); @@ -79,7 +78,6 @@ public void tokenFallback(Address _from, BigInteger _value, byte[] _data) { } case "_swap": { - Context.println("the thus us called"); // Parse the slippage sent by the user in minimumReceive. // If none is sent, use the maximum. @@ -104,12 +102,8 @@ public void tokenFallback(Address _from, BigInteger _value, byte[] _data) { Address toToken = Address.fromString(params.get("toToken").asString()); // Perform the swap - Context.println("from token "+ fromToken); - Context.println("from token "+ toToken); - Context.println("from "+ _from); - Context.println("receiver "+ receiver); + exchange(fromToken, toToken, _from, receiver, _value, minimumReceive); - Context.println("after the exchange "); break; } @@ -124,7 +118,6 @@ public void tokenFallback(Address _from, BigInteger _value, byte[] _data) { } void swapIcx(Address sender, BigInteger value) { - Context.println("the sender is "+ sender); Context.transfer(sender, value); } @@ -136,11 +129,8 @@ void exchange(Address fromToken, Address toToken, Address sender, } // Send the trader their funds - Context.println("is it heree?"); - Context.println("roe "+ toToken); - Context.println("roe "+ receiver); + Context.call(toToken, "transfer", receiver, value); - Context.println("lets check this " + Context.getAddress()); Swap(BigInteger.valueOf(0), fromToken, fromToken, toToken, sender, receiver, value, value, BigInteger.valueOf(Context.getBlockTimestamp()), BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO From 3d78091da04be9cd25e67a84cf0dd71241605f1c Mon Sep 17 00:00:00 2001 From: naneey Date: Fri, 12 Apr 2024 11:45:23 +0545 Subject: [PATCH 41/64] chore: readme for script added --- script/README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 script/README.md diff --git a/script/README.md b/script/README.md new file mode 100644 index 00000000..745f8d1f --- /dev/null +++ b/script/README.md @@ -0,0 +1,33 @@ +# DEPLOYMENT SCRIPT + +The script contains scripts to +- deploy required contracts +- configure contracts +- add funds to the system + +## Prerequisites + +Install [go](https://go.dev/doc/install) + +- ### goloop +```sh +go install github.com/icon-project/goloop/cmd/goloop@latest +``` + +- ### jq +Install jq +```sh +sudo apt install jq +brew install jq +sudo pacman -S jq +``` + +## Usage + +The constants are defined in `const.sh`. Wallet and environment can be changed +from here. +`deploy.sh` contains all the deployment and configuration script.Invoke with `-a` flag to +complete all transaction. +```sh +bash deploy.sh -a +``` From a7723f78d698082decc3ce6a0d09723fe08f9867 Mon Sep 17 00:00:00 2001 From: naneey Date: Wed, 17 Apr 2024 14:31:47 +0545 Subject: [PATCH 42/64] chore: parameters changed for deployement script --- .../java/dummy/contract/oracle/Oracle.java | 5 +++-- script/README.md | 2 ++ script/const.sh | 2 +- script/deploy.sh | 20 +++++++++++-------- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java b/dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java index 5b86f2e0..8fa8e1d5 100644 --- a/dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java +++ b/dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java @@ -3,12 +3,13 @@ import score.annotation.External; import java.math.BigInteger; +import java.util.Map; public class Oracle { @External(readonly = true) - public BigInteger getReferenceData(String _base, String _quote) { - return BigInteger.ONE; + public Map getReferenceData(String _base, String _quote) { + return Map.of("rate",BigInteger.ONE); } diff --git a/script/README.md b/script/README.md index 745f8d1f..7eefdd3a 100644 --- a/script/README.md +++ b/script/README.md @@ -31,3 +31,5 @@ complete all transaction. ```sh bash deploy.sh -a ``` + +Note: make sure optimized jar is created/updated before running the script diff --git a/script/const.sh b/script/const.sh index ac856fd8..66d6d683 100644 --- a/script/const.sh +++ b/script/const.sh @@ -26,7 +26,7 @@ case $ICON_NET in export ICON_NODE=http://localhost:9082/api/v3/ export ICON_DEBUG_NODE=http://localhost:9082/api/v3d ;; - "testnet" ) + "lisbon" ) export ICON_NID=2 export ICON_NODE=https://lisbon.net.solidwallet.io/api/v3/ export ICON_DEBUG_NODE=https://lisbon.net.solidwallet.io/api/v3d diff --git a/script/deploy.sh b/script/deploy.sh index e1ba6736..7b20e669 100644 --- a/script/deploy.sh +++ b/script/deploy.sh @@ -114,7 +114,7 @@ function deploy_cps_contracts() { echo "--------------------------DEPLOY CONTRACTS-------------------------" echo "-------------------------------------------------------------------" local CPS_CORE_FILE=$CPS_JAVA_SCORE/CPSCore/build/libs/CPSCore-[0-9].[0-9].[0-9]-optimized.jar - deploy_contract $CPS_CORE_FILE $CONTRACT_ADDRESS bondValue="2" applicationPeriod="15" + deploy_contract $CPS_CORE_FILE $CONTRACT_ADDRESS bondValue="15" applicationPeriod="15" local cps_score_addr=$(grep 'CPSCore' "$CONTRACT_ADDRESS" | cut -d' ' -f2) local CPS_TREASURY_FILE=$CPS_JAVA_SCORE/CPSTreasury/build/libs/CPSTreasury-[0-9].[0-9].[0-9]-optimized.jar @@ -124,7 +124,7 @@ function deploy_cps_contracts() { deploy_contract $CPF_TREASURY_FILE $CONTRACT_ADDRESS cpsScore=$cps_score_addr local BNUSD_FILE=$DUMMY_SCORE/bnUSD/build/libs/bnUSD-[0-9].[0-9].[0-9]-optimized.jar - deploy_contract $BNUSD_FILE $CONTRACT_ADDRESS _name="Dummy_Stable_Coin" _symbol="bnUSD" _decimals="18" _initialSupply="100000000000000000000" + deploy_contract $BNUSD_FILE $CONTRACT_ADDRESS _name="Dummy_bnUSD_Coin" _symbol="bnUSD" _decimals="18" _initialSupply="1000000000000000000000" local DEX_FILE=$DUMMY_SCORE/Dex/build/libs/Dex-[0-9].[0-9].[0-9]-optimized.jar deploy_contract $DEX_FILE $CONTRACT_ADDRESS @@ -233,21 +233,21 @@ function add_funds() { local cpf_treasury_addr=$(grep 'CPFTreasury' "$CONTRACT_ADDRESS" | cut -d' ' -f2) echo "set treasury fund limit" - icon_send_tx $cpf_treasury_addr "setMaximumTreasuryFundIcx" value="10000000000000000000000" - icon_send_tx $cpf_treasury_addr "setMaximumTreasuryFundBnusd" value="10000000000000000000000" + icon_send_tx $cpf_treasury_addr "setMaximumTreasuryFundIcx" value="0xd3c21bcecceda0000000" + icon_send_tx $cpf_treasury_addr "setMaximumTreasuryFundBnusd" value="0xd3c21bcecceda0000000" echo "send fund to treasury" local bnUSD_addr=$(grep 'bnUSD' "$CONTRACT_ADDRESS" | cut -d' ' -f2) - icon_send_tx $bnUSD_addr "mintTo" to=$cpf_treasury_addr amount="5000000000000000000000" + icon_send_tx $bnUSD_addr "mintTo" to=$cpf_treasury_addr amount="50000000000000000000000" echo "send sicx to dex for swap" local sICX_addr=$(grep 'sICX' "$CONTRACT_ADDRESS" | cut -d' ' -f2) local dex_addr=$(grep 'Dex' "$CONTRACT_ADDRESS" | cut -d' ' -f2) - icon_send_tx $sICX_addr "mintWithTokenFallBack" _to=$dex_addr _amount="1000000000000000000000" \ + icon_send_tx $sICX_addr "mintWithTokenFallBack" _to=$dex_addr _amount="10000000000000000000000" \ _data="0x7b0a2020226d6574686f64223a20225f646578220a7d" echo "send ICX to dex" - icon_transfer_icx $dex_addr "100000000000000000000" + icon_transfer_icx $dex_addr "1000000000000000000000" } @@ -272,6 +272,10 @@ function configure_system() { echo "toggle swap flag" icon_send_tx $cpf_treasury_addr "toggleSwapFlag" + echo "set oracle slippage percentage" + icon_send_tx $cpf_treasury_addr "setOraclePercentageDifference" value="3" +# icon_send_tx $cps_score_addr "toggleBudgetAdjustmentFeature" + } @@ -285,7 +289,7 @@ function set_contracts() { } function configure_fund_and_system() { -# add_funds + add_funds configure_system } From 9e3a18da0ac480d79cad762053ac589eca1a5a34 Mon Sep 17 00:00:00 2001 From: naneey Date: Wed, 17 Apr 2024 14:32:10 +0545 Subject: [PATCH 43/64] chore: cps score set on constructor --- .../java/community/icon/cps/score/cpftreasury/CPFTreasury.java | 2 -- .../java/community/icon/cps/score/cpstreasury/CPSTreasury.java | 2 -- 2 files changed, 4 deletions(-) diff --git a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java index 1a2b33a9..10665354 100644 --- a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java +++ b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java @@ -45,8 +45,6 @@ public CPFTreasury(@Optional Address cpsScore) { swapCount.set(SwapReset); swapState.set(SwapReset); swapFlag.set(false); - } - if (CPFTreasury.cpsScore.get() == null){ CPFTreasury.cpsScore.set(cpsScore); } } diff --git a/CPSTreasury/src/main/java/community/icon/cps/score/cpstreasury/CPSTreasury.java b/CPSTreasury/src/main/java/community/icon/cps/score/cpstreasury/CPSTreasury.java index d2d6d783..c58c20a4 100644 --- a/CPSTreasury/src/main/java/community/icon/cps/score/cpstreasury/CPSTreasury.java +++ b/CPSTreasury/src/main/java/community/icon/cps/score/cpstreasury/CPSTreasury.java @@ -58,8 +58,6 @@ public class CPSTreasury extends ProposalData implements CPSTreasuryInterface { public CPSTreasury(@Optional Address cpsScore) { if (onsetPaymentPercentage.get() == null) { onsetPaymentPercentage.set(BigInteger.TEN); - } - if (this.cpsScore.get() == null){ this.cpsScore.set(cpsScore); } } From 8a292979167ffc1d803b5033fc896be17329674a Mon Sep 17 00:00:00 2001 From: naneey Date: Wed, 17 Apr 2024 14:32:51 +0545 Subject: [PATCH 44/64] chore: filename changed --- .../{contracts_20240412_103742.txt => sample_contracts.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename script/contracts/{contracts_20240412_103742.txt => sample_contracts.txt} (100%) diff --git a/script/contracts/contracts_20240412_103742.txt b/script/contracts/sample_contracts.txt similarity index 100% rename from script/contracts/contracts_20240412_103742.txt rename to script/contracts/sample_contracts.txt From aed121da9053d1058c017907226026e87e6be475 Mon Sep 17 00:00:00 2001 From: naneey Date: Wed, 17 Apr 2024 14:54:07 +0545 Subject: [PATCH 45/64] chore: oracle method name fixed --- dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java b/dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java index 8fa8e1d5..028449d4 100644 --- a/dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java +++ b/dummy/oracle/src/main/java/dummy/contract/oracle/Oracle.java @@ -8,7 +8,7 @@ public class Oracle { @External(readonly = true) - public Map getReferenceData(String _base, String _quote) { + public Map get_reference_data(String _base, String _quote) { return Map.of("rate",BigInteger.ONE); } From 63f48e42890bfb9956046c5519b5efcea777a532 Mon Sep 17 00:00:00 2001 From: Swastik Chaudhary Date: Thu, 15 Aug 2024 14:45:37 +0545 Subject: [PATCH 46/64] two thirds test pass --- .../cps/score/cpftreasury/CPFTreasury.java | 23 +++ .../icon/cps/score/cpftreasury/Constants.java | 2 + .../icon/cps/score/cpscore/CPSCore.java | 82 ++++++++-- .../cps/score/cpscore/db/MilestoneDb.java | 9 +- .../cps/score/cpscore/db/ProposalDataDb.java | 14 +- .../cps/score/cpscore/utils/Constants.java | 4 + .../icon/cps/score/cpscore/CPSScoreTest.java | 152 ++++++++++++++++++ 7 files changed, 268 insertions(+), 18 deletions(-) diff --git a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java index 10665354..dc363dfe 100644 --- a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java +++ b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java @@ -39,6 +39,8 @@ public class CPFTreasury extends SetterGetter implements CPFTreasuryInterface { private final VarDB swapFlag = Context.newVarDB(SWAP_FLAG, Boolean.class); private final VarDB swapLimitAmount = Context.newVarDB(SWAP_LIMIT_AMOUNT, BigInteger.class); + private final VarDB councilFlag = Context.newVarDB(COUNCIL_FLAG, Boolean.class); + public CPFTreasury(@Optional Address cpsScore) { if (treasuryFund.get() == null) { treasuryFund.set(BigInteger.valueOf(1000000).multiply(EXA)); @@ -499,6 +501,27 @@ public void migrateOldHashToNewHash(String oldHash, String newHash){ proposalBudgets.set(newHash,totalBudget); } + @External + public void toggleCouncilFlag() { + validateAdmins(); + councilFlag.set(!councilFlag.getOrDefault(false)); + } + + @External(readonly = true) + public boolean getCouncilFlag() { + return councilFlag.getOrDefault(false); + } + + // @External + // public List
setCouncilManagers() { + // validateAdmins(); + + // } + + // @External + // public List
getCouncilManagers() { + + // } //EventLogs @Override diff --git a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java index a440ebdb..49c3c30f 100644 --- a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java +++ b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java @@ -49,6 +49,8 @@ public class Constants { public static final String STATE = "state"; public static final Address SYSTEM_ADDRESS = Address.fromString("cx0000000000000000000000000000000000000000"); + public static final String COUNCIL_FLAG = "council_flag"; + public static final int sICXICXPoolID = 1; public static final int sICXBNUSDPoolID = 2; diff --git a/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java b/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java index 482c270f..91a4ef9d 100644 --- a/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java +++ b/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java @@ -66,28 +66,28 @@ public CPSCore(@Optional BigInteger bondValue, @Optional BigInteger applicationP // Fix for ICON Dashboard Proposal not being able to submit progress report being rejected - String progressReport = "bafybeic4jhoowlgeyewjqkcpgbm3fs7mgtxzhqd5kbguihoehm4cwwwzcq"; - String proposalKey = "bafybeidoxysex3jloigzi4pvdeqgy35a4nykd46w66pobxrkephpawyjoi"; + // String progressReport = "bafybeic4jhoowlgeyewjqkcpgbm3fs7mgtxzhqd5kbguihoehm4cwwwzcq"; + // String proposalKey = "bafybeidoxysex3jloigzi4pvdeqgy35a4nykd46w66pobxrkephpawyjoi"; - String proposalPrefix = proposalPrefix(proposalKey); - String progressReportPrefix = progressReportPrefix(progressReport); + // String proposalPrefix = proposalPrefix(proposalKey); + // String progressReportPrefix = progressReportPrefix(progressReport); - ProposalDataDb.submitProgressReport.at(proposalPrefix).set(Boolean.FALSE); + // ProposalDataDb.submitProgressReport.at(proposalPrefix).set(Boolean.FALSE); - ProgressReportDataDb.status.at(progressReportPrefix).set(PROGRESS_REPORT_REJECTED); - ProgressReportDataDb.timestamp.at(progressReportPrefix).set(BigInteger.valueOf(1706244342109937L)); - Status status = new Status(); - status.progressReportStatus.get(PROGRESS_REPORT_REJECTED).add(progressReport); + // ProgressReportDataDb.status.at(progressReportPrefix).set(PROGRESS_REPORT_REJECTED); + // ProgressReportDataDb.timestamp.at(progressReportPrefix).set(BigInteger.valueOf(1706244342109937L)); + // Status status = new Status(); + // status.progressReportStatus.get(PROGRESS_REPORT_REJECTED).add(progressReport); // End of fix // Migrate sponsor bond from Techiast- to Techiast - Address oldAddr = Address.fromString("hxdc4b3fb5b47d6c14c7f9a0bac8eea9f3f48d3288"); - Address address = Address.fromString("hxfe0256b41f1db0186f9e6cbebf8c71cf006d5d17"); - DictDB userAmounts = sponsorBondReturn.at(oldAddr.toString()); + // Address oldAddr = Address.fromString("hxdc4b3fb5b47d6c14c7f9a0bac8eea9f3f48d3288"); + // Address address = Address.fromString("hxfe0256b41f1db0186f9e6cbebf8c71cf006d5d17"); + // DictDB userAmounts = sponsorBondReturn.at(oldAddr.toString()); - BigInteger bnUSDAmount = userAmounts.getOrDefault(bnUSD, BigInteger.ZERO); - sponsorBondReturn.at(address.toString()).set(bnUSD, bnUSDAmount); + // BigInteger bnUSDAmount = userAmounts.getOrDefault(bnUSD, BigInteger.ZERO); + // sponsorBondReturn.at(address.toString()).set(bnUSD, bnUSDAmount); } @@ -723,7 +723,15 @@ public void voteProposal(String ipfsKey, String vote, String voteReason, @Option TAG + ": Proposals can be voted only on Voting Period."); Address caller = Context.getCaller(); PReps pReps = new PReps(); - Context.require(ArrayDBUtils.containsInArrayDb(caller, pReps.validPreps), + + List
callLocation; + if (getCouncilFlag()) { + callLocation = getCouncilManagers(); + } else { + callLocation = ArrayDBUtils.arrayDBtoList(pReps.validPreps); + } + + Context.require(ArrayDBUtils.containsInList(caller, callLocation), TAG + ": Voting can only be done by registered P-Reps."); Context.require(List.of(APPROVE, REJECT, ABSTAIN).contains(vote), TAG + ": Vote should be either _approve, _reject or _abstain"); @@ -976,9 +984,17 @@ public void voteProgressReport(String reportKey, String voteReason, MilestoneVot TAG + ": Progress Reports can be voted only on Voting Period."); Address caller = Context.getCaller(); PReps pReps = new PReps(); + + List
callLocation = new ArrayList<>(); + if (getCouncilFlag()) { + callLocation = getCouncilManagers(); + } else { + callLocation = ArrayDBUtils.arrayDBtoList(pReps.validPreps); + } + Context.require(!ArrayDBUtils.containsInArrayDb(caller, blockAddresses), TAG + ": You are blocked from CPS."); - Context.require(ArrayDBUtils.containsInArrayDb(caller, pReps.validPreps), + Context.require(ArrayDBUtils.containsInList(caller, callLocation), TAG + ": Voting can only be done by registered P-Reps."); String progressReportPrefix = progressReportPrefix(reportKey); ArrayDB submittedMilestones = milestoneSubmitted.at(progressReportPrefix);// CAN TAKE FROM READONLY METHOD @@ -2656,6 +2672,35 @@ public Map getProposalsHistory(@Optional int startIndex) { return milestoneIdList; } + @External(readonly = true) + public Boolean hasTwoThirdsMajority(String key, boolean isMilestone) { + //can also use if else if this doesnt work as intended + + //error: milestonedb doesnt have total votes or voters + + Map milestoneDbData = MilestoneDb.getDataFromMilestoneDB(key); + BigInteger totalVotes = isMilestone ? (BigInteger)milestoneDbData.get(TOTAL_VOTES) : ProgressReportDataDb.totalVotes.at(key).getOrDefault(BigInteger.ZERO); + int totalVoters = isMilestone ? (Integer)milestoneDbData.get(TOTAL_VOTERS) : ProgressReportDataDb.totalVoters.at(key).getOrDefault(0); + + BigInteger approveVotes = isMilestone ? MilestoneDb.approvedVotes.at(key).getOrDefault(BigInteger.ZERO) : ProgressReportDataDb.approvedVotes.at(key).getOrDefault(BigInteger.ZERO); + int approveVoters = isMilestone ? MilestoneDb.approveVoters.at(key).size() : ProgressReportDataDb.approveVoters.at(key).size(); + + //need to give vote weights = 100 (arbitrary) + boolean voteWeightCheck = approveVotes.multiply(BigInteger.valueOf(3)).compareTo(totalVotes.multiply(BigInteger.valueOf(2))) >= 0; + boolean voterCountCheck = approveVoters * 3 >= totalVoters * 2; + + return voteWeightCheck && voterCountCheck; + } + + public List
getCouncilManagers() { + return callScore(List.class, getCpfTreasuryScore(), "getCouncilManagers"); + } + + + public boolean getCouncilFlag() { + return callScore(boolean.class, getCpfTreasuryScore(), "getCouncilFlag"); + } + // =====================================TEMPORARY MIGRATIONS METHODS=============================================== @External @@ -2864,5 +2909,10 @@ public void onlyCPFTreasury() { Context.require(Context.getCaller().equals(getCpfTreasuryScore()), TAG + ": Only CPF treasury can call this method"); } + public void callScore(Class eq, Class eq2, String eq3, String eq4) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'callScore'"); + } + // =====================================Checkers=============================================== } \ No newline at end of file diff --git a/CPSCore/src/main/java/community/icon/cps/score/cpscore/db/MilestoneDb.java b/CPSCore/src/main/java/community/icon/cps/score/cpscore/db/MilestoneDb.java index 4fe94274..b6698f87 100644 --- a/CPSCore/src/main/java/community/icon/cps/score/cpscore/db/MilestoneDb.java +++ b/CPSCore/src/main/java/community/icon/cps/score/cpscore/db/MilestoneDb.java @@ -23,6 +23,8 @@ public class MilestoneDb { public static final BranchDB>> votersListIndices = Context.newBranchDB(VOTERS_LIST_INDEXES, Integer.class); + public static final BranchDB> majorityFlag = Context.newBranchDB(MAJORITY_FLAG, Boolean.class); + public static void addDataToMilestoneDb(CPSCoreInterface.MilestonesAttributes milestoneData, String prefix) { id.at(prefix).set(milestoneData.id); approvedVotes.at(prefix).set(BigInteger.ZERO); @@ -30,6 +32,8 @@ public static void addDataToMilestoneDb(CPSCoreInterface.MilestonesAttributes mi completionPeriod.at(prefix).set(milestoneData.completionPeriod); budget.at(prefix).set(milestoneData.budget); + majorityFlag.at(prefix).set(false); + } public static Map getDataFromMilestoneDB(String prefix) { @@ -46,7 +50,10 @@ public static Map getDataFromMilestoneDB(String prefix) { Map.entry(TOTAL_VOTERS, ProgressReportDataDb.totalVoters.at(progressReportPrefix(reportHash)).getOrDefault(0)), Map.entry(APPROVE_VOTERS, approveVoters.at(prefix).size()), Map.entry(REJECT_VOTERS, rejectVoters.at(prefix).size()), - Map.entry(EXTENSION_FLAG, extensionFlag.at(prefix).getOrDefault(false))); + Map.entry(EXTENSION_FLAG, extensionFlag.at(prefix).getOrDefault(false)), + + Map.entry(MAJORITY_FLAG, majorityFlag.at(prefix).getOrDefault(false))); + } public static String progressReportPrefix(String progressHash) { diff --git a/CPSCore/src/main/java/community/icon/cps/score/cpscore/db/ProposalDataDb.java b/CPSCore/src/main/java/community/icon/cps/score/cpscore/db/ProposalDataDb.java index c0fa6cbe..e866b9cf 100644 --- a/CPSCore/src/main/java/community/icon/cps/score/cpscore/db/ProposalDataDb.java +++ b/CPSCore/src/main/java/community/icon/cps/score/cpscore/db/ProposalDataDb.java @@ -5,6 +5,8 @@ import java.math.BigInteger; import java.util.Map; +import community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProposalAttributes; + import static community.icon.cps.score.cpscore.utils.ArrayDBUtils.recordTxHash; import static community.icon.cps.score.cpscore.utils.Constants.*; import static community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProposalAttributes; @@ -46,6 +48,9 @@ public class ProposalDataDb { public static final BranchDB> proposalPeriod = Context.newBranchDB(PROPOSAL_PERIOD, Integer.class); public static final BranchDB> milestoneIds = Context.newBranchDB("milestoneIds", Integer.class); + public static final BranchDB> majorityFlag = Context.newBranchDB(MAJORITY_FLAG, Boolean.class); + public static final BranchDB> councilFlag = Context.newBranchDB(COUNCIL_FLAG, Boolean.class); + public static void addDataToProposalDB(ProposalAttributes proposalData, String prefix) { ipfsHash.at(prefix).set(proposalData.ipfs_hash); projectTitle.at(prefix).set(proposalData.project_title); @@ -69,6 +74,9 @@ public static void addDataToProposalDB(ProposalAttributes proposalData, String p milestoneCount.at(prefix).set(proposalData.milestoneCount); isMilestone.at(prefix).set(true); + majorityFlag.at(prefix).set(false); + councilFlag.at(prefix).set(false); + } public static void updatePercentageCompleted(String prefix, int percentage) { @@ -96,7 +104,11 @@ public static Map getDataFromProposalDB(String prefix) { Map.entry(IS_MILESTONE,isMilestone.at(prefix).getOrDefault(false)), Map.entry(PERCENTAGE_COMPLETED,percentageCompleted.at(prefix).getOrDefault(0)), Map.entry(SUBMIT_PROGRESS_REPORT, submitProgressReport.at(prefix).getOrDefault(false)), - Map.entry(PROPOSAL_PERIOD,proposalPeriod.at(prefix).getOrDefault(0))); + Map.entry(PROPOSAL_PERIOD,proposalPeriod.at(prefix).getOrDefault(0)), + + Map.entry(MAJORITY_FLAG, majorityFlag.at(prefix).getOrDefault(false)), + Map.entry(COUNCIL_FLAG, councilFlag.at(prefix).getOrDefault(false))); + } public static int getMilestoneCount(String prefix) { diff --git a/CPSCore/src/main/java/community/icon/cps/score/cpscore/utils/Constants.java b/CPSCore/src/main/java/community/icon/cps/score/cpscore/utils/Constants.java index 6643dc30..a18e3aff 100644 --- a/CPSCore/src/main/java/community/icon/cps/score/cpscore/utils/Constants.java +++ b/CPSCore/src/main/java/community/icon/cps/score/cpscore/utils/Constants.java @@ -209,6 +209,10 @@ public class Constants { public static final Integer MILESTONE_REPORT_APPROVED = 3; public static final Integer MILESTONE_REPORT_NOT_COMPLETED = 4; + // new flags + + public static final String MAJORITY_FLAG = "majority_flag"; + public static final String COUNCIL_FLAG = "council_flag"; public static final BigInteger TOTAL_PERIOD = BigInteger.valueOf(30); } \ No newline at end of file diff --git a/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java b/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java index b0ac027a..a728836d 100644 --- a/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java +++ b/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java @@ -5,12 +5,18 @@ import com.iconloop.score.test.Score; import com.iconloop.score.test.ServiceManager; import com.iconloop.score.test.TestBase; + +import community.icon.cps.score.cpscore.db.MilestoneDb; import community.icon.cps.score.cpscore.utils.Constants; import community.icon.cps.score.lib.interfaces.CPSCoreInterface; +import community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProgressReportAttributes; +import community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProposalAttributes; + import org.junit.jupiter.api.*; import org.junit.jupiter.api.function.Executable; import org.mockito.MockedStatic; import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; import org.mockito.stubbing.Answer; import score.Address; import score.ArrayDB; @@ -20,12 +26,17 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import scorex.util.HashMap; + import static community.icon.cps.score.cpscore.utils.Constants.*; import static community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProgressReportAttributes; import static community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProposalAttributes; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; @@ -499,6 +510,9 @@ void sponsorVote() { void submitAndSponsorVote() { submitProposalMethod(); + + doReturn(false).when(scoreSpy).getCouncilFlag(); + contextMock.when(caller()).thenReturn(bnUSDScore); JsonObject sponsorVoteParams = new JsonObject(); sponsorVoteParams.add("method", "sponsorVote"); @@ -604,6 +618,14 @@ void voteProposal2() { } void voteProposalMethod() { + + // doReturn(List.of(cpfTreasury)).when(scoreSpy).callScore(cpfTreasury, "getCouncilManagers"); + + doReturn(List.of(cpfTreasury)).when(scoreSpy).callScore(List.class, cpfTreasury, "getCouncilManagers"); + doReturn(false).when(scoreSpy).getCouncilFlag(); + + //mockito void method cannot be stubbed. + submitAndSponsorVote(); contextMock.when(caller()).thenReturn(owner.getAddress()); updateNextBlock(); @@ -720,6 +742,9 @@ void voteMultipleProposals() { String[] proposal = new String[]{"Proposal 0", "Proposal 1", "Proposal 2", "Proposal 3", "Proposal 4", "Proposal 5", "Proposal 6", "Proposal 7", "Proposal 8", "Proposal 9"}; + + doReturn(false).when(scoreSpy).getCouncilFlag(); + for (int i = 0; i < 10; i++) { contextMock.when(caller()).thenReturn(owner.getAddress()); cpsScore.invoke(owner, "voteProposal", "Proposal " + i, APPROVE, "reason", false); @@ -768,6 +793,9 @@ void voteMultipleProposals() { void voteProposalMethodReject() { submitAndSponsorVote(); + + doReturn(false).when(scoreSpy).getCouncilFlag(); + contextMock.when(caller()).thenReturn(owner.getAddress()); updateNextBlock(); doReturn(BigInteger.valueOf(15)).when(scoreSpy).getApplicationPeriod(); @@ -2046,6 +2074,130 @@ void submitProgressReportBeforeDeadline() { } + //begin +// @Test +// void testhasTwoThirdsMajority(){ +// String key="test"; + +// doReturn(BigInteger.valueOf(15)).when(scoreSpy).getSponsorBondPercentage(); +// registerPrepsMethod(); + + +// //need attributes? + +// //set flag to true for mock test +// //doReturn(true).when(cpsScore).call(Boolean.class, ((Object) cpfTreasury).get(), "getCouncilFlag"); +// // boolean councilFlag = true; +// doReturn(true).when(scoreSpy).getCouncilFlag(); + +// // sponsor address sponsor voter valid prep ma exist huna paryo +// //votes 3 wota weight 100= constant 100x10=1000 + +// setMilestoneVotes(key, BigInteger.valueOf(1000), 10); +// setApprovedVotes(key, BigInteger.valueOf(700), 7,true); + +// Boolean result = call(Boolean.class, cpsScore.getAddress(), "hasTwoThirdsMajority", key); +// assertTrue(result, "Should meet 2/3 majority"); + +// contextMock.when(caller()).thenReturn(testingAccount.getAddress()); +// setMilestoneVotes(key, BigInteger.valueOf(1000), 10); +// setApprovedVotes(key, BigInteger.valueOf(300), 3, true); + +// result = call(Boolean.class, cpsScore.getAddress(), "hasTwoThirdsMajority", key); +// assertFalse(result, "Should meet 2/3 majority"); + +// //flag to false +// // doReturn(false).when(cpsScore).call(Boolean.class, ((Object) cpfTreasury).get(), "getCouncilFlag"); +// // councilFlag = false; +// doReturn(false).when(scoreSpy).getCouncilFlag(); + +// contextMock.when(caller()).thenReturn(testingAccount1.getAddress()); +// setMilestoneVotes(key, BigInteger.valueOf(1000), 10); +// setApprovedVotes(key, BigInteger.valueOf(700), 7, true); + +// result = call(Boolean.class, cpsScore.getAddress(), "hasTwoThirdsMajority", key); +// assertTrue(result, "Should meet 2/3 majority"); + +// contextMock.when(caller()).thenReturn(testingAccount.getAddress()); +// setMilestoneVotes(key, BigInteger.valueOf(1000), 10); +// setApprovedVotes(key, BigInteger.valueOf(300), 3, true); + +// result = call(Boolean.class, cpsScore.getAddress(), "hasTwoThirdsMajority", key); +// assertFalse(result, "Should meet 2/3 majority"); + +// } + +// private Boolean call(Class returnType, Address address, String method, String key) { +// return Context.call(returnType, address, method, key); +// } + +// void setMilestoneVotes(String key, BigInteger totalVotes, int totalVoters) { +// cpsScore.invoke(owner, "setTotalVotes", key, totalVotes, totalVoters, true); +// } + +// void setProposalVotes(String key, BigInteger totalVotes, int totalVoters) { +// cpsScore.invoke(owner, "setTotalVotes", key, totalVotes, totalVoters, false); +// } + +// void setApprovedVotes(String key, BigInteger approvedVotes, int approveVoters, boolean isMilestone) { +// cpsScore.invoke(owner, "setApprovedVotes", key, approvedVotes, approveVoters, isMilestone); +// } + + public class VotingTest { + + private void commonSetup() { + + // Mock methods and setup initial conditions + doReturn(BigInteger.valueOf(3)).when(scoreSpy).callScore(eq(BigInteger.class), any(), eq("getTotalVotes"), any()); + doReturn(BigInteger.ZERO).when(scoreSpy).callScore(eq(BigInteger.class), any(), eq("getApprovedVotes"), any()); + doReturn(3).when(scoreSpy).callScore(eq(Integer.class), any(), eq("getTotalVoters"), any()); + } + + @Test + public void testVotingProcess() { + // Setup required for this specific test + commonSetup(); + + // Simulate the first voter + CPSCoreInterface.MilestoneVoteAttributes firstVote = new CPSCoreInterface.MilestoneVoteAttributes(); + firstVote.vote = APPROVE; + firstVote.id = 1; + + // Invoke the voting method for the first voter + cpsScore.invoke(owner, "voteProposal", "Proposal 1", firstVote, false); + + // Check if the majority is met after the first vote + boolean isMajorityAfterFirstVote = (Boolean)cpsScore.call("hasTwoThirdsMajority","Proposal 1", true); + assertFalse(isMajorityAfterFirstVote); // Expecting false + + // Simulate the second voter + CPSCoreInterface.MilestoneVoteAttributes secondVote = new CPSCoreInterface.MilestoneVoteAttributes(); + secondVote.vote = APPROVE; + secondVote.id = 2; + + // Invoke the voting method for the second voter + cpsScore.invoke(owner, "voteProposal", "Proposal 1", secondVote, false); + + // Check if the majority is met after the second vote + boolean isMajorityAfterSecondVote = (Boolean)cpsScore.call("hasTwoThirdsMajority","Proposal 1", true); + assertTrue(isMajorityAfterSecondVote); // Expecting true + + // Simulate the third voter + CPSCoreInterface.MilestoneVoteAttributes thirdVote = new CPSCoreInterface.MilestoneVoteAttributes(); + thirdVote.vote = APPROVE; + thirdVote.id = 3; + + // Invoke the voting method for the third voter + cpsScore.invoke(owner, "voteProposal", "Proposal 1", thirdVote, false); + + // Check if the majority is met after the third vote + Boolean isMajorityAfterThirdVote = (Boolean)cpsScore.call("hasTwoThirdsMajority","Proposal 1", true); + assertTrue(isMajorityAfterThirdVote); // Expecting true + } + + +} + //end @Test void setSwapCount() { From ab200f44198dddef19961970000b26ce3256d755 Mon Sep 17 00:00:00 2001 From: Swastik Chaudhary Date: Fri, 30 Aug 2024 14:39:03 +0545 Subject: [PATCH 47/64] council manager in cpftreasury --- .../cps/score/cpftreasury/CPFTreasury.java | 44 +++++++++++++++---- .../icon/cps/score/cpftreasury/Constants.java | 1 + .../icon/cps/score/cpscore/CPSScoreTest.java | 4 +- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java index dc363dfe..4d30f3e8 100644 --- a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java +++ b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java @@ -40,6 +40,8 @@ public class CPFTreasury extends SetterGetter implements CPFTreasuryInterface { private final VarDB swapLimitAmount = Context.newVarDB(SWAP_LIMIT_AMOUNT, BigInteger.class); private final VarDB councilFlag = Context.newVarDB(COUNCIL_FLAG, Boolean.class); + private final ArrayDB
councilManagers = Context.newArrayDB(COUNCIL_MANAGERS, Address.class); + public CPFTreasury(@Optional Address cpsScore) { if (treasuryFund.get() == null) { @@ -512,17 +514,43 @@ public boolean getCouncilFlag() { return councilFlag.getOrDefault(false); } - // @External - // public List
setCouncilManagers() { - // validateAdmins(); + @External + public void setCouncilManagers(Address[] newCouncilManagers) { + //todo governance only + int sizeOfCouncilManagers = councilManagers.size(); + Context.require(sizeOfCouncilManagers >= 3,"council managers should be greater than 3"); + Context.require(sizeOfCouncilManagers%2 == 1,"council managers should be an odd number"); + if (sizeOfCouncilManagers>0){ + clearArrayDb(councilManagers); + } + int sizeOfNewManagers= newCouncilManagers.length; + for(int i =0; i getCouncilManagers() { + //todo governance only + return arrayDBtoList(councilManagers); + } - // @External - // public List
getCouncilManagers() { - - // } + List arrayDBtoList(ArrayDB arraydb) { + List list = new ArrayList<>(); + for (int i = 0; i < arraydb.size(); i++) { + list.add(arraydb.get(i)); + } + return list; + } + + void clearArrayDb(ArrayDB array_db) { + int size = array_db.size(); + for (int i = 0; i < size; i++) { + array_db.pop(); + } + } + //EventLogs @Override @EventLog(indexed = 1) diff --git a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java index 49c3c30f..0645ebcd 100644 --- a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java +++ b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java @@ -50,6 +50,7 @@ public class Constants { public static final Address SYSTEM_ADDRESS = Address.fromString("cx0000000000000000000000000000000000000000"); public static final String COUNCIL_FLAG = "council_flag"; + public static final String COUNCIL_MANAGERS = "council_managers"; public static final int sICXICXPoolID = 1; public static final int sICXBNUSDPoolID = 2; diff --git a/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java b/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java index a728836d..50e53811 100644 --- a/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java +++ b/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java @@ -2172,7 +2172,7 @@ public void testVotingProcess() { // Simulate the second voter CPSCoreInterface.MilestoneVoteAttributes secondVote = new CPSCoreInterface.MilestoneVoteAttributes(); - secondVote.vote = APPROVE; + secondVote.vote = REJECT; secondVote.id = 2; // Invoke the voting method for the second voter @@ -2180,7 +2180,7 @@ public void testVotingProcess() { // Check if the majority is met after the second vote boolean isMajorityAfterSecondVote = (Boolean)cpsScore.call("hasTwoThirdsMajority","Proposal 1", true); - assertTrue(isMajorityAfterSecondVote); // Expecting true + assertFalse(isMajorityAfterSecondVote); // Expecting false // Simulate the third voter CPSCoreInterface.MilestoneVoteAttributes thirdVote = new CPSCoreInterface.MilestoneVoteAttributes(); From 0074adcfe26b3e630bdfd95fb9bfe270aef7d430 Mon Sep 17 00:00:00 2001 From: sdp_ibriz Date: Thu, 5 Sep 2024 10:24:30 +0545 Subject: [PATCH 48/64] fix cpfTresury fixes for FMC setter/getters --- .../cps/score/cpftreasury/CPFTreasury.java | 50 +-------------- .../cps/score/cpftreasury/SetterGetter.java | 63 ++++++++++++++++++- .../icon/cps/score/cpscore/CPSCore.java | 13 ++-- 3 files changed, 67 insertions(+), 59 deletions(-) diff --git a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java index 4d30f3e8..28a60e14 100644 --- a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java +++ b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java @@ -39,8 +39,8 @@ public class CPFTreasury extends SetterGetter implements CPFTreasuryInterface { private final VarDB swapFlag = Context.newVarDB(SWAP_FLAG, Boolean.class); private final VarDB swapLimitAmount = Context.newVarDB(SWAP_LIMIT_AMOUNT, BigInteger.class); - private final VarDB councilFlag = Context.newVarDB(COUNCIL_FLAG, Boolean.class); - private final ArrayDB
councilManagers = Context.newArrayDB(COUNCIL_MANAGERS, Address.class); + public static final VarDB councilFlag = Context.newVarDB(COUNCIL_FLAG, Boolean.class); + public static final ArrayDB
councilManagers = Context.newArrayDB(COUNCIL_MANAGERS, Address.class); public CPFTreasury(@Optional Address cpsScore) { @@ -503,53 +503,7 @@ public void migrateOldHashToNewHash(String oldHash, String newHash){ proposalBudgets.set(newHash,totalBudget); } - @External - public void toggleCouncilFlag() { - validateAdmins(); - councilFlag.set(!councilFlag.getOrDefault(false)); - } - - @External(readonly = true) - public boolean getCouncilFlag() { - return councilFlag.getOrDefault(false); - } - - @External - public void setCouncilManagers(Address[] newCouncilManagers) { - //todo governance only - int sizeOfCouncilManagers = councilManagers.size(); - Context.require(sizeOfCouncilManagers >= 3,"council managers should be greater than 3"); - Context.require(sizeOfCouncilManagers%2 == 1,"council managers should be an odd number"); - if (sizeOfCouncilManagers>0){ - clearArrayDb(councilManagers); - } - int sizeOfNewManagers= newCouncilManagers.length; - for(int i =0; i getCouncilManagers() { - //todo governance only - return arrayDBtoList(councilManagers); - } - - List arrayDBtoList(ArrayDB arraydb) { - List list = new ArrayList<>(); - for (int i = 0; i < arraydb.size(); i++) { - list.add(arraydb.get(i)); - } - return list; - } - - void clearArrayDb(ArrayDB array_db) { - int size = array_db.size(); - for (int i = 0; i < size; i++) { - array_db.pop(); - } - - } //EventLogs @Override diff --git a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/SetterGetter.java b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/SetterGetter.java index 41808227..4ff51a1d 100644 --- a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/SetterGetter.java +++ b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/SetterGetter.java @@ -1,11 +1,18 @@ package community.icon.cps.score.cpftreasury; import score.Address; +import score.ArrayDB; import score.Context; import score.annotation.External; +import scorex.util.ArrayList; import java.math.BigInteger; +import java.util.List; +import static community.icon.cps.score.cpftreasury.CPFTreasury.councilFlag; +import static community.icon.cps.score.cpftreasury.CPFTreasury.councilManagers; +import static community.icon.cps.score.cpftreasury.Constants.TAG; +import static community.icon.cps.score.cpftreasury.Validations.validateAdmins; import static community.icon.cps.score.cpftreasury.Validations.validateGovernanceContract; public class SetterGetter { @@ -154,19 +161,69 @@ public Address getOracleAddress() { @External public void setSponsorBondPercentage(BigInteger bondValue) { validateGovernanceContract(); - Context.call( getCpsScore(), "setSponsorBondPercentage",bondValue); + Context.call(getCpsScore(), "setSponsorBondPercentage", bondValue); } @External public void setPeriod(BigInteger applicationPeriod) { validateGovernanceContract(); - Context.call(getCpsScore(), "setPeriod",applicationPeriod); + Context.call(getCpsScore(), "setPeriod", applicationPeriod); } @External public void setOnsetPayment(BigInteger paymentPercentage) { validateGovernanceContract(); - Context.call(getCpsTreasuryScore(), "setOnsetPayment",paymentPercentage); + Context.call(getCpsTreasuryScore(), "setOnsetPayment", paymentPercentage); + } + + + @External + public void toggleCouncilFlag() { + // todo add governance + validateAdmins(); + councilFlag.set(!councilFlag.getOrDefault(false)); + } + + @External(readonly = true) + public boolean getCouncilFlag() { + return councilFlag.getOrDefault(false); + } + + @External + public void setCouncilManagers(Address[] newCouncilManagers) { + //todo governance only + int sizeOfCouncilManagers = councilManagers.size(); + Context.require(sizeOfCouncilManagers >= 3, TAG + ":: council managers should be greater than 3"); + Context.require(sizeOfCouncilManagers % 2 == 1, TAG + ":: council managers should be an odd number"); + if (sizeOfCouncilManagers > 0) { + clearArrayDb(councilManagers); + } + int sizeOfNewManagers = newCouncilManagers.length; + for (int i = 0; i < sizeOfNewManagers; i++) { + councilManagers.add(newCouncilManagers[i]); + } + } + + @External + public List
getCouncilManagers() { + return arrayDBtoList(councilManagers); + } + + + List arrayDBtoList(ArrayDB arraydb) { + List list = new ArrayList<>(); + for (int i = 0; i < arraydb.size(); i++) { + list.add(arraydb.get(i)); + } + return list; + } + + void clearArrayDb(ArrayDB array_db) { + int size = array_db.size(); + for (int i = 0; i < size; i++) { + array_db.pop(); + } + } } diff --git a/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java b/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java index 91a4ef9d..1adcb304 100644 --- a/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java +++ b/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java @@ -985,7 +985,7 @@ public void voteProgressReport(String reportKey, String voteReason, MilestoneVot Address caller = Context.getCaller(); PReps pReps = new PReps(); - List
callLocation = new ArrayList<>(); + List
callLocation; if (getCouncilFlag()) { callLocation = getCouncilManagers(); } else { @@ -1429,10 +1429,10 @@ private void updateProgressReportResult() { int proposalPeriod = ProposalDataDb.proposalPeriod.at(proposal_prefix).getOrDefault(0); boolean extended = MilestoneDb.extensionFlag.at(milestonePrefix).getOrDefault(false); - if (getPeriodCount() == (proposalPeriod + completionPeriod)) { - if (extended) { - updateProposalStatus(_ipfs_hash, _proposal_details); - } else { + int finalPeriodToSubmit = proposalPeriod + completionPeriod; + if (getPeriodCount() < finalPeriodToSubmit){ + milestonePassed +=1; + }else if (getPeriodCount() >= finalPeriodToSubmit && !extended) { milestonePassed += 1; String proposalPrefix = proposalPrefix(_ipfs_hash); int project_duration = (int) _proposal_details.get(PROJECT_DURATION); @@ -1440,11 +1440,8 @@ private void updateProgressReportResult() { ProposalDataDb.projectDuration.at(proposalPrefix).set(project_duration + 1); MilestoneDb.completionPeriod.at(milestonePrefix).set(completionPeriod + 1); } - } updateMilestoneDB(milestonePrefix); - } - } else { MilestoneDb.status.at(milestonePrefix).set(MILESTONE_REPORT_REJECTED); updateMilestoneDB(milestonePrefix); From 6b447c5b844e3404d08b887a4b7832b6df45b03e Mon Sep 17 00:00:00 2001 From: Swastik Chaudhary Date: Thu, 5 Sep 2024 19:54:20 +0545 Subject: [PATCH 49/64] council managers and flag test --- .../score/cpftreasury/CPFTTreasuryTest.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java b/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java index e26ddb1a..6aa1949c 100644 --- a/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java +++ b/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java @@ -726,6 +726,34 @@ void slippagePercentage() { } } + @Test + void toggleCouncilFlag(){ + try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { + theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); + tokenScore.invoke(owner,"toggleCouncilFlag"); + assertEquals(true,tokenScore.call("getCouncilFlag")); + } + } + + @Test +void setCouncilManagers() { + Address A = Address.fromString("cx0000000000000000000000000000000000000007"); + Address B = Address.fromString("cx0000000000000000000000000000000000000008"); + Address C = Address.fromString("cx0000000000000000000000000000000000000009"); + + Address[] CManagers = {A, B, C}; + + try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { + theMock.when(() -> Context.call(cpsScore.get(), "isAdmin", Context.getCaller())).thenReturn(true); + tokenScore.invoke(owner, "setCouncilManagers", (Object) CManagers); + + List
returnedManagers = (List
) tokenScore.call("getCouncilManagers"); + + for (int i = 0; i < CManagers.length; i++) { + assertEquals(CManagers[i], returnedManagers.get(i)); + } + } +} public void expectErrorMessage(Executable contractCall, String errorMessage) { AssertionError e = Assertions.assertThrows(AssertionError.class, contractCall); From a29afc76fe170669a92fd56fc00a8cde9464d318 Mon Sep 17 00:00:00 2001 From: sdp_ibriz Date: Mon, 16 Sep 2024 17:00:46 +0545 Subject: [PATCH 50/64] update FundManagers reward pool --- .../cps/score/cpftreasury/CPFTreasury.java | 103 +++++++++++++++++- .../icon/cps/score/cpftreasury/Constants.java | 6 + .../icon/cps/score/cpscore/CPSCore.java | 37 ++++--- 3 files changed, 123 insertions(+), 23 deletions(-) diff --git a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java index 28a60e14..55d82b22 100644 --- a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java +++ b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java @@ -26,10 +26,14 @@ public class CPFTreasury extends SetterGetter implements CPFTreasuryInterface { public static final VarDB
sICXScore = Context.newVarDB(SICX_SCORE, Address.class); public static final VarDB
routerScore = Context.newVarDB(ROUTER_SCORE, Address.class); public static final VarDB
oracleAddress = Context.newVarDB(ORACLE_ADDRESS, Address.class); + private final ArrayDB proposalsKeys = Context.newArrayDB(PROPOSALS_KEYS, String.class); private final DictDB proposalBudgets = Context.newDictDB(PROPOSAL_BUDGETS, BigInteger.class); + private final VarDB treasuryFund = Context.newVarDB(TREASURY_FUND, BigInteger.class); private final VarDB emergencyFund = Context.newVarDB(EMERGENCY_FUND, BigInteger.class); + private final DictDB rewardPool = Context.newDictDB(REWARD_POOL, BigInteger.class); + private final VarDB treasuryFundbnUSD = Context.newVarDB(TREASURY_FUND_BNUSD, BigInteger.class); private final VarDB swapState = Context.newVarDB(SWAP_STATE, Integer.class); @@ -41,6 +45,7 @@ public class CPFTreasury extends SetterGetter implements CPFTreasuryInterface { public static final VarDB councilFlag = Context.newVarDB(COUNCIL_FLAG, Boolean.class); public static final ArrayDB
councilManagers = Context.newArrayDB(COUNCIL_MANAGERS, Address.class); + public static final DictDB councilManagersReward = Context.newDictDB(COUNCIL_MANAGERS_REWARD, BigInteger.class); public CPFTreasury(@Optional Address cpsScore) { @@ -278,7 +283,7 @@ private void swapIcxBnusd(BigInteger amount, BigInteger _minReceive) { } Context.call(amount, routerScore.get(), "route", path, _minReceive); } catch (Exception e) { - Context.println("Ignoring Errors from Router. Error Message: " + e.getMessage()); + Context.println("Ignoring Errors from Router. Error Message: " + e.getMessage()); } } } @@ -336,7 +341,7 @@ public void withdrawFromEmergencyFund(BigInteger value, Address address, String Address balancedDollar = CPFTreasury.balancedDollar.get(); Context.call(balancedDollar, TRANSFER, address, value, "".getBytes()); - EmergencyFundTransferred(address, value,purpose); + EmergencyFundTransferred(address, value, purpose); } @@ -399,6 +404,70 @@ public void setOraclePercentageDifference(int value) { oraclePerDiff.set(value); } + @External + public void setRewardPool(String key) { + validateCpsScore(); + Context.require(key.equals(INITIAL_FUND) || key.equals(FINAL_FUND), TAG + ": incorrectKeyForPool"); + rewardPool.set(key, getTotalFundBNUSD().get(AVAILABLE_BALANCE)); + } + + @External(readonly = true) + public Map getRewardPool() { + BigInteger finalFund = rewardPool.getOrDefault(FINAL_FUND, BigInteger.ZERO); + BigInteger initialFund = rewardPool.getOrDefault(INITIAL_FUND, BigInteger.ZERO); + BigInteger rewardPool = finalFund.subtract(initialFund).multiply(BigInteger.valueOf(2).divide(BigInteger.valueOf(100))); + return Map.of(INITIAL_FUND, initialFund, + FINAL_FUND, finalFund, + "rewardPool", rewardPool); + } + + @External + public void distributeRewardToFundManagers() { + validateCpsScore(); + + try { + Map rewardPool = getRewardPool(); + BigInteger initialFund = rewardPool.get(INITIAL_FUND); + BigInteger finalFund = rewardPool.get(FINAL_FUND); + + Context.require((initialFund.compareTo(BigInteger.ZERO) > 0 && finalFund.compareTo(BigInteger.ZERO) > 0), + TAG + ": RewardPoolIsEmpty"); + + BigInteger rewardPoolAmount = rewardPool.get("rewardPool"); + + + int len = councilManagers.size(); + BigInteger rewardAmount = rewardPoolAmount.divide(BigInteger.valueOf(len)); + + for (int i = 0; i < len; i++) { + Address manager = councilManagers.get(i); + councilManagersReward.set(manager, councilManagersReward.getOrDefault(manager, BigInteger.ZERO).add(rewardAmount)); + FundManagerRewardSet(manager, rewardAmount); + } + + } catch (Exception e) { + Context.println("Error in distributeRewardToFundManagers: " + e.getMessage()); + } + setRewardPool(INITIAL_FUND); + } + + @External(readonly = true) + public BigInteger getRewardAmountForManager(Address manager) { + return councilManagersReward.getOrDefault(manager, BigInteger.ZERO); + } + + @External + public void claimFundManagerReward() { + Address manager = Context.getCaller(); + BigInteger rewardAmount = councilManagersReward.getOrDefault(manager, BigInteger.ZERO); + Context.require(rewardAmount.compareTo(BigInteger.ZERO) > 0, TAG + ": No reward to claim."); + + councilManagersReward.set(manager, BigInteger.ZERO); + Context.call(balancedDollar.get(), TRANSFER, manager, rewardAmount, "".getBytes()); + FundManagerRewardClaimed(manager, rewardAmount); + + } + @Override @External(readonly = true) public Map getProposalDetails(@Optional int startIndex, @Optional int endIndex) { @@ -489,7 +558,7 @@ public void fallback() { } @External - public void migrateOldHashToNewHash(String oldHash, String newHash){ + public void migrateOldHashToNewHash(String oldHash, String newHash) { validateCpsScore(); int size = proposalsKeys.size(); for (int i = 0; i < size; i++) { @@ -499,12 +568,26 @@ public void migrateOldHashToNewHash(String oldHash, String newHash){ } BigInteger totalBudget = proposalBudgets.get(oldHash); - proposalBudgets.set(oldHash,null); - proposalBudgets.set(newHash,totalBudget); + proposalBudgets.set(oldHash, null); + proposalBudgets.set(newHash, totalBudget); + } + + private static boolean containsInArrayDb(T value, ArrayDB array) { + boolean contains = false; + if (array == null || value == null) { + return contains; + } + + for (int i = 0; i < array.size(); i++) { + if (array.get(i) != null && array.get(i).equals(value)) { + contains = true; + break; + } + } + return contains; } - //EventLogs @Override @EventLog(indexed = 1) @@ -529,4 +612,12 @@ public void FundReceived(Address _sponsor_address, String note) { @EventLog(indexed = 1) public void EmergencyFundTransferred(Address _address, BigInteger _value, String _purpose) { } + + @EventLog(indexed = 1) + public void FundManagerRewardSet(Address _address, BigInteger _value) { + } + + @EventLog(indexed = 1) + public void FundManagerRewardClaimed(Address _address, BigInteger _value) { + } } diff --git a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java index 0645ebcd..072d01be 100644 --- a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java +++ b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java @@ -17,6 +17,11 @@ public class Constants { public static final String PROPOSALS_KEYS = "_proposals_keys"; public static final String TREASURY_FUND = "treasury_fund"; public static final String EMERGENCY_FUND = "emergencyFund"; + public static final String REWARD_POOL = "rewardPool"; + + public static final String INITIAL_FUND = "initialFund"; + public static final String FINAL_FUND = "finalFund"; + public static final String AVAILABLE_BALANCE = "availableBalance"; public static final String TREASURY_FUND_BNUSD = "treasury_fund_bnusd"; @@ -51,6 +56,7 @@ public class Constants { public static final String COUNCIL_FLAG = "council_flag"; public static final String COUNCIL_MANAGERS = "council_managers"; + public static final String COUNCIL_MANAGERS_REWARD = "councilManagersReward"; public static final int sICXICXPoolID = 1; public static final int sICXBNUSDPoolID = 2; diff --git a/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java b/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java index 1adcb304..3687cabd 100644 --- a/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java +++ b/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java @@ -1260,6 +1260,7 @@ public void updatePeriod() { period.periodName.set(TRANSITION_PERIOD); period.previousPeriodName.set(APPLICATION_PERIOD); period.updatePeriodIndex.set(updateIndex + 1); + callScore(getCpfTreasuryScore(), "setRewardPool", "finalFund"); updateProposalsResult(); PeriodUpdate("Period Update State 1/4. Period Updated to Transition Period. " + @@ -1292,6 +1293,8 @@ public void updatePeriod() { period.periodCount.set(period.periodCount.getOrDefault(0) + 1); burn(proposalFees.get(), null); proposalFees.set(BigInteger.ZERO); + callScore(getCpfTreasuryScore(), "distributeRewardToFundManagers"); + } } @@ -1430,16 +1433,16 @@ private void updateProgressReportResult() { boolean extended = MilestoneDb.extensionFlag.at(milestonePrefix).getOrDefault(false); int finalPeriodToSubmit = proposalPeriod + completionPeriod; - if (getPeriodCount() < finalPeriodToSubmit){ - milestonePassed +=1; - }else if (getPeriodCount() >= finalPeriodToSubmit && !extended) { - milestonePassed += 1; - String proposalPrefix = proposalPrefix(_ipfs_hash); - int project_duration = (int) _proposal_details.get(PROJECT_DURATION); - MilestoneDb.extensionFlag.at(milestonePrefix).set(true); - ProposalDataDb.projectDuration.at(proposalPrefix).set(project_duration + 1); - MilestoneDb.completionPeriod.at(milestonePrefix).set(completionPeriod + 1); - } + if (getPeriodCount() < finalPeriodToSubmit) { + milestonePassed += 1; + } else if (getPeriodCount() >= finalPeriodToSubmit && !extended) { + milestonePassed += 1; + String proposalPrefix = proposalPrefix(_ipfs_hash); + int project_duration = (int) _proposal_details.get(PROJECT_DURATION); + MilestoneDb.extensionFlag.at(milestonePrefix).set(true); + ProposalDataDb.projectDuration.at(proposalPrefix).set(project_duration + 1); + MilestoneDb.completionPeriod.at(milestonePrefix).set(completionPeriod + 1); + } updateMilestoneDB(milestonePrefix); } } else { @@ -2676,24 +2679,24 @@ public Boolean hasTwoThirdsMajority(String key, boolean isMilestone) { //error: milestonedb doesnt have total votes or voters Map milestoneDbData = MilestoneDb.getDataFromMilestoneDB(key); - BigInteger totalVotes = isMilestone ? (BigInteger)milestoneDbData.get(TOTAL_VOTES) : ProgressReportDataDb.totalVotes.at(key).getOrDefault(BigInteger.ZERO); - int totalVoters = isMilestone ? (Integer)milestoneDbData.get(TOTAL_VOTERS) : ProgressReportDataDb.totalVoters.at(key).getOrDefault(0); - + BigInteger totalVotes = isMilestone ? (BigInteger) milestoneDbData.get(TOTAL_VOTES) : ProgressReportDataDb.totalVotes.at(key).getOrDefault(BigInteger.ZERO); + int totalVoters = isMilestone ? (Integer) milestoneDbData.get(TOTAL_VOTERS) : ProgressReportDataDb.totalVoters.at(key).getOrDefault(0); + BigInteger approveVotes = isMilestone ? MilestoneDb.approvedVotes.at(key).getOrDefault(BigInteger.ZERO) : ProgressReportDataDb.approvedVotes.at(key).getOrDefault(BigInteger.ZERO); int approveVoters = isMilestone ? MilestoneDb.approveVoters.at(key).size() : ProgressReportDataDb.approveVoters.at(key).size(); - + //need to give vote weights = 100 (arbitrary) boolean voteWeightCheck = approveVotes.multiply(BigInteger.valueOf(3)).compareTo(totalVotes.multiply(BigInteger.valueOf(2))) >= 0; boolean voterCountCheck = approveVoters * 3 >= totalVoters * 2; - + return voteWeightCheck && voterCountCheck; } - + public List
getCouncilManagers() { return callScore(List.class, getCpfTreasuryScore(), "getCouncilManagers"); } - + public boolean getCouncilFlag() { return callScore(boolean.class, getCpfTreasuryScore(), "getCouncilFlag"); } From 0c190bbcd66d5a10beed03660e57f18e268e5748 Mon Sep 17 00:00:00 2001 From: Swastik Chaudhary Date: Tue, 24 Sep 2024 13:22:01 +0545 Subject: [PATCH 51/64] added reward vote test fixed some issues --- .../score/cpftreasury/CPFTTreasuryTest.java | 95 ++++++++++++++++++- 1 file changed, 92 insertions(+), 3 deletions(-) diff --git a/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java b/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java index 6aa1949c..a742405c 100644 --- a/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java +++ b/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java @@ -15,15 +15,25 @@ import score.Context; import score.DictDB; import score.VarDB; +import scorex.util.HashMap; +import java.util.Arrays; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class CPFTTreasuryTest extends TestBase { private static final Address score_address = Address.fromString("cx0000000000000000000000000000000000000000"); @@ -737,9 +747,9 @@ void toggleCouncilFlag(){ @Test void setCouncilManagers() { - Address A = Address.fromString("cx0000000000000000000000000000000000000007"); - Address B = Address.fromString("cx0000000000000000000000000000000000000008"); - Address C = Address.fromString("cx0000000000000000000000000000000000000009"); + Address A = Address.fromString("hx0000000000000000000000000000000000000007"); + Address B = Address.fromString("hx0000000000000000000000000000000000000008"); + Address C = Address.fromString("hx0000000000000000000000000000000000000009"); Address[] CManagers = {A, B, C}; @@ -755,6 +765,85 @@ void setCouncilManagers() { } } +// @Test +// public void testSetRewardPool() { +// final String AVAILABLE_BALANCE = "availableBalance"; + +// String initialFundKey = "INITIAL_FUND"; +// String finalFundKey = "FINAL_FUND"; +// String invalidKey = "INVALID_KEY"; +// BigInteger availableBalance = BigInteger.valueOf(1000); + +// Map totalFund = new HashMap<>(); +// totalFund.put(AVAILABLE_BALANCE, availableBalance); + +// VarDB rewardPoolMock = mock(VarDB.class); + +// CPFTreasury cpsScore = mock(CPFTreasury.class); +// when(((CPFTreasury) cpsScore).getTotalFundBNUSD()).thenReturn(totalFund); + +// ((CPFTreasury) cpsScore).setRewardPool(initialFundKey); +// verify(rewardPoolMock).set(availableBalance); + +// ((CPFTreasury) cpsScore).setRewardPool(finalFundKey); +// verify(rewardPoolMock).set(availableBalance); + +// IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { +// ((CPFTreasury) cpsScore).setRewardPool(invalidKey); +// }); +// assertTrue(exception.getMessage().contains("incorrectKeyForPool")); +// } + +public class RewardVoteTest { + + private final BigInteger EXA = BigInteger.valueOf(1_000_000_000_000_000_000L); + + @Test + public void testRewardVote() { + MockedStatic contextMock = mockStatic(Context.class); + + BigInteger newFunds = BigInteger.valueOf(400).multiply(EXA); + + contextMock.when(() -> getRemainingFund()).thenReturn(newFunds); + + Address A = Address.fromString("hx0000000000000000000000000000000000000001"); + Address B = Address.fromString("hx0000000000000000000000000000000000000002"); + List
councilManagers = Arrays.asList(A, B); + contextMock.when(() -> getCouncilManagers()).thenReturn(councilManagers); + + rewardVote(); + + BigInteger expectedRewardPerManager = BigInteger.valueOf(4).multiply(EXA); + contextMock.verify(() -> Context.call(A, "distributeRewardToFundManagers", expectedRewardPerManager)); + contextMock.verify(() -> Context.call(B, "distributeRewardToFundManagers", expectedRewardPerManager)); + + contextMock.close(); + } + + private BigInteger getRemainingFund() { + return BigInteger.ZERO; + } + + private List
getCouncilManagers() { + return Arrays.asList(); + } + + private void rewardVote() { + BigInteger initialFund = getRemainingFund(); + BigInteger finalFund = BigInteger.valueOf(400).multiply(EXA); + + BigInteger rewardPool = finalFund.subtract(initialFund).multiply(BigInteger.valueOf(2)).divide(BigInteger.valueOf(100)); + List
councilManagers = getCouncilManagers(); + BigInteger rewardPerManager = rewardPool.divide(BigInteger.valueOf(councilManagers.size())); + + for (Address manager : councilManagers) { + Context.call(manager, "distributeRewardToFundManagers", rewardPerManager); + } + } +} + + + public void expectErrorMessage(Executable contractCall, String errorMessage) { AssertionError e = Assertions.assertThrows(AssertionError.class, contractCall); assertEquals(errorMessage, e.getMessage()); From 5bf3add02d5444eb112dc9a422d6bdf4e6316bd4 Mon Sep 17 00:00:00 2001 From: Swastik Chaudhary Date: Wed, 25 Sep 2024 21:15:58 +0545 Subject: [PATCH 52/64] cpsScore and update period fix --- .../score/cpftreasury/CPFTTreasuryTest.java | 3 + .../icon/cps/score/cpscore/CPSCore.java | 2 - .../icon/cps/score/cpscore/CPSScoreTest.java | 72 +------------------ 3 files changed, 6 insertions(+), 71 deletions(-) diff --git a/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java b/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java index a742405c..a7491af9 100644 --- a/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java +++ b/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java @@ -767,6 +767,8 @@ void setCouncilManagers() { // @Test // public void testSetRewardPool() { + // setCPSScoreMethod(score_address); + // final String AVAILABLE_BALANCE = "availableBalance"; // String initialFundKey = "INITIAL_FUND"; @@ -800,6 +802,7 @@ public class RewardVoteTest { @Test public void testRewardVote() { + setCPSScoreMethod(score_address); MockedStatic contextMock = mockStatic(Context.class); BigInteger newFunds = BigInteger.valueOf(400).multiply(EXA); diff --git a/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java b/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java index 3687cabd..77bf889b 100644 --- a/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java +++ b/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java @@ -1262,7 +1262,6 @@ public void updatePeriod() { period.updatePeriodIndex.set(updateIndex + 1); callScore(getCpfTreasuryScore(), "setRewardPool", "finalFund"); updateProposalsResult(); - PeriodUpdate("Period Update State 1/4. Period Updated to Transition Period. " + "After all the calculations are completed, " + "Period will change to " + APPLICATION_PERIOD); @@ -1294,7 +1293,6 @@ public void updatePeriod() { burn(proposalFees.get(), null); proposalFees.set(BigInteger.ZERO); callScore(getCpfTreasuryScore(), "distributeRewardToFundManagers"); - } } diff --git a/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java b/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java index 50e53811..21ff95bb 100644 --- a/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java +++ b/CPSCore/src/test/java/community/icon/cps/score/cpscore/CPSScoreTest.java @@ -834,6 +834,8 @@ void voteProposalMethodReject() { } void updatePeriods() { + doNothing().when(scoreSpy).callScore(eq(cpfTreasury), eq("distributeRewardToFundManagers")); + doNothing().when(scoreSpy).callScore(eq(cpfTreasury), eq("setRewardPool"), any()); // 1/4 cpsScore.invoke(owner, "updatePeriod"); // 2/4 @@ -864,6 +866,7 @@ void updatePeriodAfterProposalVoting() { doNothing().when(scoreSpy).callScore(eq(cpfTreasury), eq("resetSwapState")); doReturn(BigInteger.valueOf(15)).when(scoreSpy).getVotingPeriod(); + updatePeriods(); Map proposalDetails = getProposalDetailsByHash("Proposal 1"); @@ -2075,73 +2078,6 @@ void submitProgressReportBeforeDeadline() { } //begin -// @Test -// void testhasTwoThirdsMajority(){ -// String key="test"; - -// doReturn(BigInteger.valueOf(15)).when(scoreSpy).getSponsorBondPercentage(); -// registerPrepsMethod(); - - -// //need attributes? - -// //set flag to true for mock test -// //doReturn(true).when(cpsScore).call(Boolean.class, ((Object) cpfTreasury).get(), "getCouncilFlag"); -// // boolean councilFlag = true; -// doReturn(true).when(scoreSpy).getCouncilFlag(); - -// // sponsor address sponsor voter valid prep ma exist huna paryo -// //votes 3 wota weight 100= constant 100x10=1000 - -// setMilestoneVotes(key, BigInteger.valueOf(1000), 10); -// setApprovedVotes(key, BigInteger.valueOf(700), 7,true); - -// Boolean result = call(Boolean.class, cpsScore.getAddress(), "hasTwoThirdsMajority", key); -// assertTrue(result, "Should meet 2/3 majority"); - -// contextMock.when(caller()).thenReturn(testingAccount.getAddress()); -// setMilestoneVotes(key, BigInteger.valueOf(1000), 10); -// setApprovedVotes(key, BigInteger.valueOf(300), 3, true); - -// result = call(Boolean.class, cpsScore.getAddress(), "hasTwoThirdsMajority", key); -// assertFalse(result, "Should meet 2/3 majority"); - -// //flag to false -// // doReturn(false).when(cpsScore).call(Boolean.class, ((Object) cpfTreasury).get(), "getCouncilFlag"); -// // councilFlag = false; -// doReturn(false).when(scoreSpy).getCouncilFlag(); - -// contextMock.when(caller()).thenReturn(testingAccount1.getAddress()); -// setMilestoneVotes(key, BigInteger.valueOf(1000), 10); -// setApprovedVotes(key, BigInteger.valueOf(700), 7, true); - -// result = call(Boolean.class, cpsScore.getAddress(), "hasTwoThirdsMajority", key); -// assertTrue(result, "Should meet 2/3 majority"); - -// contextMock.when(caller()).thenReturn(testingAccount.getAddress()); -// setMilestoneVotes(key, BigInteger.valueOf(1000), 10); -// setApprovedVotes(key, BigInteger.valueOf(300), 3, true); - -// result = call(Boolean.class, cpsScore.getAddress(), "hasTwoThirdsMajority", key); -// assertFalse(result, "Should meet 2/3 majority"); - -// } - -// private Boolean call(Class returnType, Address address, String method, String key) { -// return Context.call(returnType, address, method, key); -// } - -// void setMilestoneVotes(String key, BigInteger totalVotes, int totalVoters) { -// cpsScore.invoke(owner, "setTotalVotes", key, totalVotes, totalVoters, true); -// } - -// void setProposalVotes(String key, BigInteger totalVotes, int totalVoters) { -// cpsScore.invoke(owner, "setTotalVotes", key, totalVotes, totalVoters, false); -// } - -// void setApprovedVotes(String key, BigInteger approvedVotes, int approveVoters, boolean isMilestone) { -// cpsScore.invoke(owner, "setApprovedVotes", key, approvedVotes, approveVoters, isMilestone); -// } public class VotingTest { @@ -2194,8 +2130,6 @@ public void testVotingProcess() { Boolean isMajorityAfterThirdVote = (Boolean)cpsScore.call("hasTwoThirdsMajority","Proposal 1", true); assertTrue(isMajorityAfterThirdVote); // Expecting true } - - } //end From 0cf0d9fafd86e22c1f14cfcf59cef5c3e8c29b5c Mon Sep 17 00:00:00 2001 From: Swastik Chaudhary Date: Thu, 26 Sep 2024 00:01:19 +0545 Subject: [PATCH 53/64] set reward pool --- .../score/cpftreasury/CPFTTreasuryTest.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java b/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java index a7491af9..27333ee7 100644 --- a/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java +++ b/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java @@ -27,7 +27,9 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockStatic; @@ -765,6 +767,72 @@ void setCouncilManagers() { } } +@Test +public void testSetRewardPool() { + setCPSScoreMethod(score_address); + + final String AVAILABLE_BALANCE = "availableBalance"; + + String initialFundKey = "INITIAL_FUND"; + String finalFundKey = "FINAL_FUND"; + String invalidKey = "INVALID_KEY"; + BigInteger availableBalance = BigInteger.valueOf(1000); + + Map totalFund = new HashMap<>(); + totalFund.put(AVAILABLE_BALANCE, availableBalance); + + VarDB rewardPoolMock = mock(VarDB.class); + + CPFTreasury cpsScore = mock(CPFTreasury.class); + + when(rewardPoolMock.get()).thenReturn(availableBalance); + + cpsScore.setRewardPool(initialFundKey); + + assertEquals(availableBalance, rewardPoolMock.get()); + + cpsScore.setRewardPool(finalFundKey); + + assertEquals(availableBalance, rewardPoolMock.get()); + + // IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { + // cpsScore.setRewardPool(invalidKey); + // }); + // assertTrue(exception.getMessage().contains("incorrectKeyForPool")); +} + +// @Test +// void setRewardPoolTest() { +// String validKeyInitial = "INITIAL_FUND"; +// String validKeyFinal = "FINAL_FUND"; +// String invalidKey = "INVALID_FUND"; + +// try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { + +// // Mock the valid key scenario for INITIAL_FUND +// theMock.when(() -> Context.require(validKeyInitial.equals("INITIAL_FUND") || validKeyInitial.equals("FINAL_FUND"), "TAG: incorrectKeyForPool")) +// .thenAnswer(invocation -> null); // Just pass + +// // Invoke the method with valid INITIAL_FUND key +// tokenScore.invoke(owner, "setRewardPool", validKeyInitial); + +// // Mock the valid key scenario for FINAL_FUND +// theMock.when(() -> Context.require(validKeyFinal.equals("INITIAL_FUND") || validKeyFinal.equals("FINAL_FUND"), "TAG: incorrectKeyForPool")) +// .thenAnswer(invocation -> null); // Just pass + +// // Invoke the method with valid FINAL_FUND key +// tokenScore.invoke(owner, "setRewardPool", validKeyFinal); + +// // Mock the invalid key scenario +// theMock.when(() -> Context.require(invalidKey.equals("INITIAL_FUND") || invalidKey.equals("FINAL_FUND"), "TAG: incorrectKeyForPool")) +// .thenThrow(new AssertionError("TAG: incorrectKeyForPool")); + +// // Test the invalid key and expect an AssertionError +// assertThrows(AssertionError.class, () -> tokenScore.invoke(owner, "setRewardPool", invalidKey)); +// } +// } + + // @Test // public void testSetRewardPool() { // setCPSScoreMethod(score_address); From c8919634145fa79bbc9914f0eec710a8b86c6ad6 Mon Sep 17 00:00:00 2001 From: Swastik Chaudhary Date: Thu, 26 Sep 2024 00:06:12 +0545 Subject: [PATCH 54/64] remove unnecessary comments --- .../score/cpftreasury/CPFTTreasuryTest.java | 62 ------------------- 1 file changed, 62 deletions(-) diff --git a/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java b/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java index 27333ee7..2cc6a6af 100644 --- a/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java +++ b/CPFTreasury/src/test/java/community/icon/cps/score/cpftreasury/CPFTTreasuryTest.java @@ -801,68 +801,6 @@ public void testSetRewardPool() { // assertTrue(exception.getMessage().contains("incorrectKeyForPool")); } -// @Test -// void setRewardPoolTest() { -// String validKeyInitial = "INITIAL_FUND"; -// String validKeyFinal = "FINAL_FUND"; -// String invalidKey = "INVALID_FUND"; - -// try (MockedStatic theMock = Mockito.mockStatic(Context.class)) { - -// // Mock the valid key scenario for INITIAL_FUND -// theMock.when(() -> Context.require(validKeyInitial.equals("INITIAL_FUND") || validKeyInitial.equals("FINAL_FUND"), "TAG: incorrectKeyForPool")) -// .thenAnswer(invocation -> null); // Just pass - -// // Invoke the method with valid INITIAL_FUND key -// tokenScore.invoke(owner, "setRewardPool", validKeyInitial); - -// // Mock the valid key scenario for FINAL_FUND -// theMock.when(() -> Context.require(validKeyFinal.equals("INITIAL_FUND") || validKeyFinal.equals("FINAL_FUND"), "TAG: incorrectKeyForPool")) -// .thenAnswer(invocation -> null); // Just pass - -// // Invoke the method with valid FINAL_FUND key -// tokenScore.invoke(owner, "setRewardPool", validKeyFinal); - -// // Mock the invalid key scenario -// theMock.when(() -> Context.require(invalidKey.equals("INITIAL_FUND") || invalidKey.equals("FINAL_FUND"), "TAG: incorrectKeyForPool")) -// .thenThrow(new AssertionError("TAG: incorrectKeyForPool")); - -// // Test the invalid key and expect an AssertionError -// assertThrows(AssertionError.class, () -> tokenScore.invoke(owner, "setRewardPool", invalidKey)); -// } -// } - - -// @Test -// public void testSetRewardPool() { - // setCPSScoreMethod(score_address); - -// final String AVAILABLE_BALANCE = "availableBalance"; - -// String initialFundKey = "INITIAL_FUND"; -// String finalFundKey = "FINAL_FUND"; -// String invalidKey = "INVALID_KEY"; -// BigInteger availableBalance = BigInteger.valueOf(1000); - -// Map totalFund = new HashMap<>(); -// totalFund.put(AVAILABLE_BALANCE, availableBalance); - -// VarDB rewardPoolMock = mock(VarDB.class); - -// CPFTreasury cpsScore = mock(CPFTreasury.class); -// when(((CPFTreasury) cpsScore).getTotalFundBNUSD()).thenReturn(totalFund); - -// ((CPFTreasury) cpsScore).setRewardPool(initialFundKey); -// verify(rewardPoolMock).set(availableBalance); - -// ((CPFTreasury) cpsScore).setRewardPool(finalFundKey); -// verify(rewardPoolMock).set(availableBalance); - -// IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { -// ((CPFTreasury) cpsScore).setRewardPool(invalidKey); -// }); -// assertTrue(exception.getMessage().contains("incorrectKeyForPool")); -// } public class RewardVoteTest { From 0e7689d62e1c87f646a3e527ed4604bf1311b185 Mon Sep 17 00:00:00 2001 From: Swastik Chaudhary Date: Wed, 16 Oct 2024 09:09:28 +0545 Subject: [PATCH 55/64] ready to push to testnet --- .../src/main/java/community/icon/cps/score/cpscore/CPSCore.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java b/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java index 77bf889b..9b5a6940 100644 --- a/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java +++ b/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java @@ -2671,7 +2671,7 @@ public Map getProposalsHistory(@Optional int startIndex) { } @External(readonly = true) - public Boolean hasTwoThirdsMajority(String key, boolean isMilestone) { + public boolean hasTwoThirdsMajority(String key, boolean isMilestone) { //can also use if else if this doesnt work as intended //error: milestonedb doesnt have total votes or voters From abe381f700d264addc7a1171b1837b9949e73d3e Mon Sep 17 00:00:00 2001 From: sdp_ibriz Date: Wed, 23 Oct 2024 13:55:21 +0545 Subject: [PATCH 56/64] update validateGovernanceContract to the owner of the contract --- .../community/icon/cps/score/cpftreasury/Validations.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Validations.java b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Validations.java index d3defdab..3fd3d6eb 100644 --- a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Validations.java +++ b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Validations.java @@ -3,7 +3,6 @@ import score.Address; import score.Context; -import static community.icon.cps.score.cpftreasury.Constants.SYSTEM_ADDRESS; import static community.icon.cps.score.cpftreasury.Constants.TAG; public class Validations { @@ -14,7 +13,9 @@ public static void validateAdmins() { } public static void validateGovernanceContract() { - Context.require(Context.getCaller().equals(SYSTEM_ADDRESS), + Address caller = Context.getCaller(); + Address owner = Context.getOwner(); + Context.require(caller.equals(owner), TAG + ": Only Admins can call this method"); } From b85a3aca543ad879ed86e84f83abcd50dd476911 Mon Sep 17 00:00:00 2001 From: sdp_ibriz Date: Wed, 23 Oct 2024 13:56:25 +0545 Subject: [PATCH 57/64] update fixes for the CPFTreasury getter after final tests --- .../cps/score/cpftreasury/SetterGetter.java | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/SetterGetter.java b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/SetterGetter.java index 4ff51a1d..1698c965 100644 --- a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/SetterGetter.java +++ b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/SetterGetter.java @@ -160,7 +160,7 @@ public Address getOracleAddress() { @External public void setSponsorBondPercentage(BigInteger bondValue) { - validateGovernanceContract(); + validateAdmins(); Context.call(getCpsScore(), "setSponsorBondPercentage", bondValue); } @@ -176,11 +176,9 @@ public void setOnsetPayment(BigInteger paymentPercentage) { Context.call(getCpsTreasuryScore(), "setOnsetPayment", paymentPercentage); } - @External public void toggleCouncilFlag() { - // todo add governance - validateAdmins(); + validateGovernanceContract(); councilFlag.set(!councilFlag.getOrDefault(false)); } @@ -191,20 +189,19 @@ public boolean getCouncilFlag() { @External public void setCouncilManagers(Address[] newCouncilManagers) { - //todo governance only - int sizeOfCouncilManagers = councilManagers.size(); + validateGovernanceContract(); + int sizeOfCouncilManagers = newCouncilManagers.length; Context.require(sizeOfCouncilManagers >= 3, TAG + ":: council managers should be greater than 3"); Context.require(sizeOfCouncilManagers % 2 == 1, TAG + ":: council managers should be an odd number"); - if (sizeOfCouncilManagers > 0) { + if (councilManagers.size() > 0) { clearArrayDb(councilManagers); } - int sizeOfNewManagers = newCouncilManagers.length; - for (int i = 0; i < sizeOfNewManagers; i++) { - councilManagers.add(newCouncilManagers[i]); + for (Address newCouncilManager : newCouncilManagers) { + councilManagers.add(newCouncilManager); } } - @External + @External(readonly = true) public List
getCouncilManagers() { return arrayDBtoList(councilManagers); } From 36bdcbe8e1a28b31489ce1d0bd37ebe7292fe592 Mon Sep 17 00:00:00 2001 From: sdp_ibriz Date: Wed, 23 Oct 2024 13:58:05 +0545 Subject: [PATCH 58/64] fix dex with dev version --- dummy/Dex/src/main/java/dummy/contract/dex/Dex.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java b/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java index 7f4f2859..aade21f1 100644 --- a/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java +++ b/dummy/Dex/src/main/java/dummy/contract/dex/Dex.java @@ -2,18 +2,17 @@ import com.eclipsesource.json.Json; import com.eclipsesource.json.JsonObject; +import community.icon.cps.score.lib.interfaces.DexInterface; import score.Address; import score.Context; import score.VarDB; import score.annotation.EventLog; import score.annotation.External; +import score.annotation.Payable; import java.math.BigInteger; import java.util.Arrays; -import community.icon.cps.score.lib.interfaces.DexInterface; -import score.annotation.Payable; - public class Dex implements DexInterface { private static final String TAG = "Balanced DEX"; private final VarDB
sicx = Context.newVarDB("sicx", Address.class); @@ -29,7 +28,7 @@ public void setSicxScore(Address _score) { } @External(readonly = true) - public BigInteger getPrice(int poolId) { + public BigInteger getPrice(int _id) { return BigInteger.ONE; } From 03d5a775013523cc750871f8ba8b82470156352f Mon Sep 17 00:00:00 2001 From: sdp_ibriz Date: Wed, 23 Oct 2024 13:58:37 +0545 Subject: [PATCH 59/64] update buildgradle for dummy contracts --- dummy/Dex/build.gradle | 13 ++++--------- dummy/Router/build.gradle | 13 ++++--------- dummy/bnUSD/build.gradle | 6 +++++- dummy/oracle/build.gradle | 11 +++-------- dummy/sICX/build.gradle | 9 +++++---- 5 files changed, 21 insertions(+), 31 deletions(-) diff --git a/dummy/Dex/build.gradle b/dummy/Dex/build.gradle index 9f955982..7c3d12e6 100644 --- a/dummy/Dex/build.gradle +++ b/dummy/Dex/build.gradle @@ -24,16 +24,11 @@ deployJar { uri = 'http://localhost:9082/api/v3' nid = 0x3 } - sejong { - uri = 'https://sejong.net.solidwallet.io/api/v3' - nid = 0x53 - - } - berlin { - uri = 'https://berlin.net.solidwallet.io/api/v3' - nid = 0x7 - to = 'cx28ae7ed3b07ed5247a3d2f97680f8555ce7c0a92' + devnet{ + uri = "https://tt.net.solidwallet.io/api/v3" + nid = 0x3 } + } keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' diff --git a/dummy/Router/build.gradle b/dummy/Router/build.gradle index 53ac1ea8..7c596974 100644 --- a/dummy/Router/build.gradle +++ b/dummy/Router/build.gradle @@ -22,16 +22,11 @@ deployJar { uri = 'http://localhost:9082/api/v3' nid = 0x3 } - sejong { - uri = 'https://sejong.net.solidwallet.io/api/v3' - nid = 0x53 - - } - berlin { - uri = 'https://berlin.net.solidwallet.io/api/v3' - nid = 0x7 - to = 'cx28ae7ed3b07ed5247a3d2f97680f8555ce7c0a92' + devnet{ + uri = "https://tt.net.solidwallet.io/api/v3" + nid = 0x3 } + } keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' diff --git a/dummy/bnUSD/build.gradle b/dummy/bnUSD/build.gradle index 0f76e01b..5063bd83 100644 --- a/dummy/bnUSD/build.gradle +++ b/dummy/bnUSD/build.gradle @@ -23,6 +23,10 @@ deployJar { uri = 'http://localhost:9082/api/v3' nid = 0x3 } + devnet{ + uri = "https://tt.net.solidwallet.io/api/v3" + nid = 0x3 + } } keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' @@ -30,7 +34,7 @@ deployJar { arg('_name', 'Balanced Dollar') arg('_symbol', 'bnUSD') arg('_decimals', '0x12') - arg('_initialSupply', '0x989680') + arg('_initialSupply', '0x152D02C7E14AF6800000') } } diff --git a/dummy/oracle/build.gradle b/dummy/oracle/build.gradle index 0541f98a..9a451779 100644 --- a/dummy/oracle/build.gradle +++ b/dummy/oracle/build.gradle @@ -36,14 +36,9 @@ deployJar { uri = 'http://localhost:9082/api/v3' nid = 0x3 } - sejong { - uri = 'https://sejong.net.solidwallet.io/api/v3' - nid = 0x53 - - } - berlin { - uri = 'https://berlin.net.solidwallet.io/api/v3' - nid = 0x7 + devnet{ + uri = "https://tt.net.solidwallet.io/api/v3" + nid = 0x3 } } keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' diff --git a/dummy/sICX/build.gradle b/dummy/sICX/build.gradle index 42db9671..2b021494 100644 --- a/dummy/sICX/build.gradle +++ b/dummy/sICX/build.gradle @@ -22,14 +22,15 @@ deployJar { uri = 'http://localhost:9082/api/v3' nid = 0x3 } + devnet{ + uri = "https://tt.net.solidwallet.io/api/v3" + nid = 0x3 + } } keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' parameters { - arg('_name', 'Staked ICX') - arg('_symbol', 'sICX') - arg('_decimals', '0x12') - arg('_initialSupply', '0x989680') + arg('_admin', 'hx2eec32d4469cbdc24fac4ea0c3859b7c3f2729ee') } } From db8a6eb67404b3268a3de1b15fbe15b38694de75 Mon Sep 17 00:00:00 2001 From: sdp_ibriz Date: Wed, 23 Oct 2024 14:00:48 +0545 Subject: [PATCH 60/64] fixes - fundManager reward disbursement logic - remove unused methods - add constants variables for reward sharing - update gradle for deployment --- CPFTreasury/build.gradle | 22 ++-- .../cps/score/cpftreasury/CPFTreasury.java | 107 +++++++++--------- .../icon/cps/score/cpftreasury/Constants.java | 1 + 3 files changed, 64 insertions(+), 66 deletions(-) diff --git a/CPFTreasury/build.gradle b/CPFTreasury/build.gradle index 986566d2..fdbdfcef 100644 --- a/CPFTreasury/build.gradle +++ b/CPFTreasury/build.gradle @@ -1,4 +1,4 @@ -version = '1.2.0' +version = '1.5.0' dependencies { // compileOnly 'foundation.icon:javaee-api:0.9.1' @@ -31,27 +31,29 @@ deployJar { lisbon { uri = 'https://lisbon.net.solidwallet.io/api/v3' nid = 0x2 - to = 'cx3d4182c0e783b7ef97ba63409c4bdf808853bd9f' - } - local { - uri = 'http://localhost:9082/api/v3' - nid = 0x3 - } - berlin { - uri = 'https://berlin.net.solidwallet.io/api/v3' - nid = 0x7 + to = "cxd19ed92de2050a87c709097b6297aadf5f8d7432" } + mainnet { uri = 'https://ctz.solidwallet.io/api/v3' nid = 0x1 to = 'cxdca1178010b5368aea929ad5c06abee64b91acc2' } + devnet{ + uri = "https://tt.net.solidwallet.io/api/v3" + nid = 0x3 + to = "cx0d0638e5764ede3ed2c9eadd179bc67785868842" + } } keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' + parameters { + arg("cpsScore", "cx5100c8b221cc373939d8a720ecfbd90440c75ed3") + } } + test { useJUnitPlatform() } diff --git a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java index 55d82b22..3e4d6415 100644 --- a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java +++ b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/CPFTreasury.java @@ -32,7 +32,7 @@ public class CPFTreasury extends SetterGetter implements CPFTreasuryInterface { private final VarDB treasuryFund = Context.newVarDB(TREASURY_FUND, BigInteger.class); private final VarDB emergencyFund = Context.newVarDB(EMERGENCY_FUND, BigInteger.class); - private final DictDB rewardPool = Context.newDictDB(REWARD_POOL, BigInteger.class); + public static final DictDB rewardPool = Context.newDictDB(REWARD_POOL, BigInteger.class); private final VarDB treasuryFundbnUSD = Context.newVarDB(TREASURY_FUND_BNUSD, BigInteger.class); @@ -45,17 +45,27 @@ public class CPFTreasury extends SetterGetter implements CPFTreasuryInterface { public static final VarDB councilFlag = Context.newVarDB(COUNCIL_FLAG, Boolean.class); public static final ArrayDB
councilManagers = Context.newArrayDB(COUNCIL_MANAGERS, Address.class); + + public static final VarDB councilManagerRewardPercentage = Context.newVarDB(COUNCIL_MANAGERS_REWARD_PERCENTAGE, Integer.class); public static final DictDB councilManagersReward = Context.newDictDB(COUNCIL_MANAGERS_REWARD, BigInteger.class); public CPFTreasury(@Optional Address cpsScore) { if (treasuryFund.get() == null) { - treasuryFund.set(BigInteger.valueOf(1000000).multiply(EXA)); + treasuryFund.set(BigInteger.valueOf(5000000).multiply(EXA)); swapCount.set(SwapReset); swapState.set(SwapReset); swapFlag.set(false); + treasuryFundbnUSD.set(BigInteger.valueOf(5000000).multiply(EXA)); CPFTreasury.cpsScore.set(cpsScore); } + + councilFlag.set(true); + councilManagers.add(Address.fromString("hxd4eb0a6c591b5e7a76e9a6677da055ebfdd897da")); + councilManagers.add(Address.fromString("hx9fa9d224306b0722099d30471b3c2306421aead7")); + councilManagers.add(Address.fromString("hx03907c67a68e8d6948cff58f49d39b3d7c8d95ad")); + councilManagerRewardPercentage.set(0); + } private boolean proposalExists(String ipfsKey) { @@ -112,8 +122,7 @@ private void burn(BigInteger amount) { @Override @External(readonly = true) public Map getTotalFunds() { - return Map.of(ICX, Context.getBalance(Context.getAddress()), - bnUSD, getBNUSDAvailableBalance()); + return Map.of(ICX, Context.getBalance(Context.getAddress()), bnUSD, getBNUSDAvailableBalance()); } @External(readonly = true) @@ -126,22 +135,32 @@ public BigInteger getEmergencyFund() { return getTotalFundBNUSD().get(EMERGENCY_FUND); } + @External + public void setFundManagersRewards(int paymentPercentage) { +// validateGovernanceContract(); + validateAdmins(); + Context.require(paymentPercentage >= 0 && paymentPercentage <= 100, TAG + " :InvalidPercentage"); + councilManagerRewardPercentage.set(paymentPercentage); + setRewardPool(INITIAL_FUND); + } + + @External(readonly = true) + public int getFundManagersRewards() { + return councilManagerRewardPercentage.getOrDefault(0); + } private Map getTotalFundBNUSD() { BigInteger bnusdBalance = (BigInteger) Context.call(balancedDollar.get(), "balanceOf", Context.getAddress()); BigInteger emergencyFund = this.emergencyFund.getOrDefault(BigInteger.ZERO); BigInteger availableBalance = bnusdBalance.subtract(emergencyFund); - return Map.of(BNUSD_BALANCE, bnusdBalance, - EMERGENCY_FUND, emergencyFund, - AVAILABLE_BALANCE, availableBalance); + return Map.of(BNUSD_BALANCE, bnusdBalance, EMERGENCY_FUND, emergencyFund, AVAILABLE_BALANCE, availableBalance); } @Override @External(readonly = true) public Map getRemainingSwapAmount() { BigInteger maxCap = treasuryFundbnUSD.get(); - return Map.of(MAX_CAP, maxCap, - REMAINING_TO_SWAP, maxCap.subtract(getBNUSDAvailableBalance())); + return Map.of(MAX_CAP, maxCap, REMAINING_TO_SWAP, maxCap.subtract(getBNUSDAvailableBalance())); } private void returnFundAmount(Address address, BigInteger value) { @@ -152,9 +171,7 @@ private void returnFundAmount(Address address, BigInteger value) { @Override @External - public void transferProposalFundToCpsTreasury(String ipfsKey, int projectDuration, - Address sponsorAddress, Address contributorAddress, - String tokenFlag, BigInteger totalBudget) { + public void transferProposalFundToCpsTreasury(String ipfsKey, int projectDuration, Address sponsorAddress, Address contributorAddress, String tokenFlag, BigInteger totalBudget) { validateCpsScore(); Context.require(!proposalExists(ipfsKey), TAG + ": Project already exists. Invalid IPFS Hash"); Context.require(tokenFlag.equals(bnUSD), TAG + ": " + tokenFlag + " is not supported. Only " + bnUSD + " token available."); @@ -186,8 +203,7 @@ public void transferProposalFundToCpsTreasury(String ipfsKey, int projectDuratio @Override @External - public void updateProposalFund(String ipfsKey, @Optional String flag, @Optional BigInteger addedBudget, - @Optional int totalInstallmentCount) { + public void updateProposalFund(String ipfsKey, @Optional String flag, @Optional BigInteger addedBudget, @Optional int totalInstallmentCount) { validateCpsScore(); Context.require(proposalExists(ipfsKey), TAG + ": IPFS hash does not exist."); Context.require(flag != null && flag.equals(bnUSD), TAG + ": Unsupported token. " + flag); @@ -415,40 +431,37 @@ public void setRewardPool(String key) { public Map getRewardPool() { BigInteger finalFund = rewardPool.getOrDefault(FINAL_FUND, BigInteger.ZERO); BigInteger initialFund = rewardPool.getOrDefault(INITIAL_FUND, BigInteger.ZERO); - BigInteger rewardPool = finalFund.subtract(initialFund).multiply(BigInteger.valueOf(2).divide(BigInteger.valueOf(100))); - return Map.of(INITIAL_FUND, initialFund, - FINAL_FUND, finalFund, - "rewardPool", rewardPool); + BigInteger fundDiff = finalFund.subtract(initialFund); + BigInteger rewardPool = fundDiff.multiply(BigInteger.valueOf(getFundManagersRewards())).divide(BigInteger.valueOf(100)); + return Map.of(INITIAL_FUND, initialFund, FINAL_FUND, finalFund, REWARD_POOL, rewardPool); } @External public void distributeRewardToFundManagers() { validateCpsScore(); + if (getFundManagersRewards() > 0) { + try { + Map rewardPool = getRewardPool(); + BigInteger initialFund = rewardPool.get(INITIAL_FUND); + BigInteger finalFund = rewardPool.get(FINAL_FUND); - try { - Map rewardPool = getRewardPool(); - BigInteger initialFund = rewardPool.get(INITIAL_FUND); - BigInteger finalFund = rewardPool.get(FINAL_FUND); - - Context.require((initialFund.compareTo(BigInteger.ZERO) > 0 && finalFund.compareTo(BigInteger.ZERO) > 0), - TAG + ": RewardPoolIsEmpty"); - - BigInteger rewardPoolAmount = rewardPool.get("rewardPool"); + Context.require((initialFund.compareTo(BigInteger.ZERO) > 0 && finalFund.compareTo(BigInteger.ZERO) > 0), TAG + ": RewardPoolIsEmpty"); + BigInteger rewardPoolAmount = rewardPool.get(REWARD_POOL); + int len = councilManagers.size(); + BigInteger rewardAmount = rewardPoolAmount.divide(BigInteger.valueOf(len)); - int len = councilManagers.size(); - BigInteger rewardAmount = rewardPoolAmount.divide(BigInteger.valueOf(len)); + for (int i = 0; i < len; i++) { + Address manager = councilManagers.get(i); + councilManagersReward.set(manager, councilManagersReward.getOrDefault(manager, BigInteger.ZERO).add(rewardAmount)); + FundManagerRewardSet(manager, rewardAmount); + } - for (int i = 0; i < len; i++) { - Address manager = councilManagers.get(i); - councilManagersReward.set(manager, councilManagersReward.getOrDefault(manager, BigInteger.ZERO).add(rewardAmount)); - FundManagerRewardSet(manager, rewardAmount); + } catch (Exception e) { + Context.println("Error in distributeRewardToFundManagers: " + e.getMessage()); } - - } catch (Exception e) { - Context.println("Error in distributeRewardToFundManagers: " + e.getMessage()); + setRewardPool(INITIAL_FUND); } - setRewardPool(INITIAL_FUND); } @External(readonly = true) @@ -465,7 +478,6 @@ public void claimFundManagerReward() { councilManagersReward.set(manager, BigInteger.ZERO); Context.call(balancedDollar.get(), TRANSFER, manager, rewardAmount, "".getBytes()); FundManagerRewardClaimed(manager, rewardAmount); - } @Override @@ -507,8 +519,7 @@ public void tokenFallback(Address _from, BigInteger _value, byte[] _data) { Address sICX = sICXScore.get(); Address caller = Context.getCaller(); - Context.require(caller.equals(bnUSDScore) || caller.equals(sICX), TAG + - " Only " + bnUSDScore + " and " + sICX + " can send tokens to CPF Treasury."); + Context.require(caller.equals(bnUSDScore) || caller.equals(sICX), TAG + " Only " + bnUSDScore + " and " + sICX + " can send tokens to CPF Treasury."); if (caller.equals(sICX)) { if (_from.equals(dexScore.get())) { JsonObject swapICX = new JsonObject(); @@ -518,7 +529,6 @@ public void tokenFallback(Address _from, BigInteger _value, byte[] _data) { Context.revert(TAG + ": sICX can be approved only from Balanced DEX."); } } else { - if (_data == null || new String(_data).equalsIgnoreCase("none")) { _data = "{}".getBytes(); } @@ -572,21 +582,6 @@ public void migrateOldHashToNewHash(String oldHash, String newHash) { proposalBudgets.set(newHash, totalBudget); } - private static boolean containsInArrayDb(T value, ArrayDB array) { - boolean contains = false; - if (array == null || value == null) { - return contains; - } - - for (int i = 0; i < array.size(); i++) { - if (array.get(i) != null && array.get(i).equals(value)) { - contains = true; - break; - } - } - return contains; - } - //EventLogs @Override diff --git a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java index 072d01be..ff084bda 100644 --- a/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java +++ b/CPFTreasury/src/main/java/community/icon/cps/score/cpftreasury/Constants.java @@ -57,6 +57,7 @@ public class Constants { public static final String COUNCIL_FLAG = "council_flag"; public static final String COUNCIL_MANAGERS = "council_managers"; public static final String COUNCIL_MANAGERS_REWARD = "councilManagersReward"; + public static final String COUNCIL_MANAGERS_REWARD_PERCENTAGE = "councilManagersRewardPercentage"; public static final int sICXICXPoolID = 1; public static final int sICXBNUSDPoolID = 2; From 1c5919fa29bae1533ebad6464dc3bd4131d04486 Mon Sep 17 00:00:00 2001 From: sdp_ibriz Date: Wed, 23 Oct 2024 14:01:59 +0545 Subject: [PATCH 61/64] update - fix majority rate to 0.66 --- .../community/icon/cps/score/cpscore/utils/Constants.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CPSCore/src/main/java/community/icon/cps/score/cpscore/utils/Constants.java b/CPSCore/src/main/java/community/icon/cps/score/cpscore/utils/Constants.java index a18e3aff..b68308ff 100644 --- a/CPSCore/src/main/java/community/icon/cps/score/cpscore/utils/Constants.java +++ b/CPSCore/src/main/java/community/icon/cps/score/cpscore/utils/Constants.java @@ -10,10 +10,9 @@ public class Constants { public static final BigInteger EXA = BigInteger.valueOf(1000000000000000000L); - public static final Integer MINIMUM_PREPS = 7; public static final Integer MAX_PROJECT_PERIOD = 12; - public static final double MAJORITY = 0.67; + public static final double MAJORITY = 0.66; public static final BigInteger DAY_COUNT = BigInteger.valueOf(15); public static final BigInteger BLOCKS_DAY_COUNT = BigInteger.valueOf(43120); @@ -140,6 +139,7 @@ public class Constants { public static final String PAY_PENALTY = "payPenalty"; public static final String IS_REGISTERED = "isRegistered"; public static final String IS_PREP = "isPRep"; + public static final String IS_COUNCIL_MANAGER = "isCouncilManager"; public static final String PENALTY_AMOUNT1 = "penaltyAmount"; public static final String TRANSFER = "transfer"; public static final String METHOD = "method"; From e2f334070ac9c83d4080e522b8914a943b177bf1 Mon Sep 17 00:00:00 2001 From: sdp_ibriz Date: Wed, 23 Oct 2024 14:04:43 +0545 Subject: [PATCH 62/64] update - budgetAdjustment feature default to false (not using it soon) - support councilMangers on getPrep(), getPrepName(), getDelegations() - fix checkPriorityVoting logics for refinement - support council mangers to vote on Proposals, progress-reports and Priority voting - remove unused comments --- .../icon/cps/score/cpscore/CPSCore.java | 287 +++++++++++------- 1 file changed, 176 insertions(+), 111 deletions(-) diff --git a/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java b/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java index 9b5a6940..2d113a7a 100644 --- a/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java +++ b/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java @@ -62,33 +62,8 @@ public CPSCore(@Optional BigInteger bondValue, @Optional BigInteger applicationP sponsorBondPercentage.set(bondValue); this.period.set(APPLICATION_PERIOD, applicationPeriod); this.period.set(VOTING_PERIOD, TOTAL_PERIOD.subtract(applicationPeriod)); + admins.add(Context.getOwner()); } - - // Fix for ICON Dashboard Proposal not being able to submit progress report being rejected - - // String progressReport = "bafybeic4jhoowlgeyewjqkcpgbm3fs7mgtxzhqd5kbguihoehm4cwwwzcq"; - // String proposalKey = "bafybeidoxysex3jloigzi4pvdeqgy35a4nykd46w66pobxrkephpawyjoi"; - - // String proposalPrefix = proposalPrefix(proposalKey); - // String progressReportPrefix = progressReportPrefix(progressReport); - - // ProposalDataDb.submitProgressReport.at(proposalPrefix).set(Boolean.FALSE); - - // ProgressReportDataDb.status.at(progressReportPrefix).set(PROGRESS_REPORT_REJECTED); - // ProgressReportDataDb.timestamp.at(progressReportPrefix).set(BigInteger.valueOf(1706244342109937L)); - // Status status = new Status(); - // status.progressReportStatus.get(PROGRESS_REPORT_REJECTED).add(progressReport); - - // End of fix - - // Migrate sponsor bond from Techiast- to Techiast - // Address oldAddr = Address.fromString("hxdc4b3fb5b47d6c14c7f9a0bac8eea9f3f48d3288"); - // Address address = Address.fromString("hxfe0256b41f1db0186f9e6cbebf8c71cf006d5d17"); - // DictDB userAmounts = sponsorBondReturn.at(oldAddr.toString()); - - // BigInteger bnUSDAmount = userAmounts.getOrDefault(bnUSD, BigInteger.ZERO); - // sponsorBondReturn.at(address.toString()).set(bnUSD, bnUSDAmount); - } @Override @@ -225,7 +200,7 @@ public void toggleBudgetAdjustmentFeature() { @External(readonly = true) public boolean getBudgetAdjustmentFeature() { SetterGetter setterGetter = new SetterGetter(); - return setterGetter.budgetAdjustment.getOrDefault(true); + return setterGetter.budgetAdjustment.getOrDefault(false); } @External @@ -365,15 +340,27 @@ private List
getPrepsAddress() { } private String getPrepName(Address address) { + if (getCouncilFlag() && getCouncilManagers().contains(address)) { + int index = getCouncilManagers().indexOf(address); + return "Council Manager " + (index + 1); + } return (String) getPRepInfo(address).get("name"); } private BigInteger getStake(Address address) { - return (BigInteger) getPRepInfo(address).get("power"); + if (getCouncilFlag() && getCouncilManagers().contains(address)) { + return EXA.multiply(BigInteger.ONE); + } else { + return (BigInteger) getPRepInfo(address).get("power"); + } } private BigInteger getDelegation(Address address) { - return delegationSnapshot.get(address); + if (getCouncilFlag() && getCouncilManagers().contains(address)) { + return EXA.multiply(BigInteger.ONE); + } else { + return delegationSnapshot.get(address); + } } private void setPreps() { @@ -441,7 +428,8 @@ private BigInteger getPenaltyAmount(Address address) { @Override @External(readonly = true) public boolean checkPriorityVoting(Address _prep) { - int count = (int) getActiveProposalsList(0).get(COUNT); + Status status = new Status(); + int count = status.pending.size(); if (count > 0) { return ArrayDBUtils.containsInArrayDb(_prep, priorityVotedPreps); } @@ -484,7 +472,11 @@ public void votePriority(String[] _proposals) { Context.require(period.periodName.get().equals(VOTING_PERIOD), TAG + ": Voting can only be done in Voting Period."); Address caller = Context.getCaller(); PReps pReps = new PReps(); - Context.require(ArrayDBUtils.containsInArrayDb(caller, pReps.validPreps), "Voting can only be done by registered P-Reps"); + if (getCouncilFlag()) { + Context.require(getCouncilManagers().contains(caller), "Voting can only be done by Council Managers."); + } else { + Context.require(ArrayDBUtils.containsInArrayDb(caller, pReps.validPreps), "Voting can only be done by registered P-Reps"); + } Context.require(!checkPriorityVoting(caller), "Already voted for Priority Ranking."); priorityVotedPreps.add(caller); @@ -541,11 +533,17 @@ public Map loginPrep(Address address) { allPreps = ArrayDBUtils.arrayDBtoList(pReps.validPreps); } + loginData.put(IS_COUNCIL_MANAGER, BigInteger.ZERO); loginData.put(IS_PREP, BigInteger.ZERO); loginData.put(IS_REGISTERED, BigInteger.ZERO); loginData.put(PAY_PENALTY, BigInteger.ZERO); loginData.put(VOTING_PREP, BigInteger.ZERO); + if (getCouncilFlag() && getCouncilManagers().contains(address)) { + loginData.put(IS_COUNCIL_MANAGER, BigInteger.ONE); + loginData.put(VOTING_PREP, BigInteger.ONE); + } + if (allPreps.contains(address)) { loginData.put(IS_PREP, BigInteger.ONE); if (ArrayDBUtils.containsInArrayDb(address, pReps.denylist)) { @@ -553,12 +551,10 @@ public Map loginPrep(Address address) { loginData.put(PENALTY_AMOUNT1, getPenaltyAmount(address)); } else if (ArrayDBUtils.containsInArrayDb(address, pReps.registeredPreps)) { loginData.put(IS_REGISTERED, BigInteger.ONE); - - if (ArrayDBUtils.containsInArrayDb(address, pReps.validPreps)) { + if (!getCouncilFlag() && ArrayDBUtils.containsInArrayDb(address, pReps.validPreps)) { loginData.put(VOTING_PREP, BigInteger.ONE); } } - } return loginData; } @@ -576,7 +572,6 @@ public List
getAdmins() { @External(readonly = true) public Map getRemainingFund() { SetterGetter setterGetter = new SetterGetter(); - //noinspection unchecked return callScore(Map.class, setterGetter.cpfScore.get(), "getTotalFunds"); } @@ -602,6 +597,7 @@ public List> getPReps() { public List
getDenylist() { List
denyList = new ArrayList<>(); PReps pReps = new PReps(); + for (int i = 0; i < pReps.denylist.size(); i++) { denyList.add(pReps.denylist.get(i)); } @@ -759,12 +755,16 @@ public void voteProposal(String ipfsKey, String vote, String voteReason, @Option BigInteger abstainedVotes = (BigInteger) proposalVoteDetails.get(ABSTAINED_VOTES); Integer totalVoter = (Integer) proposalVoteDetails.get(TOTAL_VOTERS); if (totalVoter == 0 || totalVotes.equals(BigInteger.ZERO)) { - ProposalDataDb.totalVoters.at(proposalPrefix).set(pReps.validPreps.size()); - ProposalDataDb.totalVotes.at(proposalPrefix).set(totalDelegationSnapshot.getOrDefault(BigInteger.ZERO)); + if (getCouncilFlag()) { + ProposalDataDb.totalVotes.at(proposalPrefix).set(EXA.multiply(BigInteger.valueOf(getCouncilManagers().size()))); + ProposalDataDb.totalVoters.at(proposalPrefix).set(getCouncilManagers().size()); + } else { + ProposalDataDb.totalVotes.at(proposalPrefix).set(totalDelegationSnapshot.getOrDefault(BigInteger.ZERO)); + ProposalDataDb.totalVoters.at(proposalPrefix).set(pReps.validPreps.size()); + } } DictDB votersIndexDb = votersListIndex.at(proposalPrefix).at(caller); - if (!voteChange) { ProposalDataDb.votersList.at(proposalPrefix).add(caller); votersIndexDb.set(INDEX, ProposalDataDb.votersList.at(proposalPrefix).size()); @@ -811,20 +811,26 @@ public void voteProposal(String ipfsKey, String vote, String voteReason, @Option votersIndexDb.set(VOTE, ABSTAIN_); ProposalDataDb.abstainedVotes.at(proposalPrefix).set(abstainedVotes.add(voterStake)); } + + if (hasTwoThirdsMajority(ipfsKey, 0)) { + ProposalDataDb.majorityFlag.at(proposalPrefix).set(true); + } + + VotedSuccessfully(caller, "Proposal Vote for " + proposalDetails.get(PROJECT_TITLE) + " Successful."); swapBNUsdToken(); } private List getMilestoneDeadline(String ipfsHash) { - String ipfsHAshPRefix = proposalPrefix(ipfsHash); - ArrayDB milestoneIDs = milestoneIds.at(ipfsHAshPRefix); + String proposalPrefix = proposalPrefix(ipfsHash); + ArrayDB milestoneIDs = milestoneIds.at(proposalPrefix); List milestoneIdList = new ArrayList<>(); for (int i = 0; i < milestoneIDs.size(); i++) { int milestoneId = milestoneIDs.get(i); String milestonePrefix = mileStonePrefix(ipfsHash, milestoneId); - int proposalTotalPeriod = proposalPeriod.at(ipfsHAshPRefix).getOrDefault(0); + int proposalTotalPeriod = proposalPeriod.at(proposalPrefix).getOrDefault(0); int completionPeriod = MilestoneDb.completionPeriod.at(milestonePrefix).getOrDefault(0); int computedCompletionPeriod = proposalTotalPeriod + completionPeriod; @@ -888,30 +894,45 @@ public void submitProgressReport(ProgressReportAttributes progressReport, Milest Context.revert(TAG + ":: Submit progress report for all milestones."); } - Context.require(milestoneSubmissions.length + approvedReports <= totalMilestoneCount, TAG + ":: Submitted milestone is greater than recorded on proposal."); - List milestoneDeadlineIDs = getMilestoneDeadline(ipfsHash); - if (!milestoneDeadlineIDs.isEmpty()) { - boolean isMilestoneSubmitted = checkContainsMilestone(milestoneSubmissions, milestoneDeadlineIDs); - Context.require(isMilestoneSubmitted, TAG + ": Submit milestone report for milestone id. " + milestoneDeadlineIDs); - } for (MilestoneSubmission milestoneAttr : milestoneSubmissions) { + String milestonePrefix = mileStonePrefix(ipfsHash, milestoneAttr.id); int milestoneStatus = getMileststoneStatusOf(ipfsHash, milestoneAttr.id); + int milestoneCompletionPeriod = MilestoneDb.completionPeriod.at(milestonePrefix).get(); + + for (int i = 0; i < getRemainingMilestones(ipfsHash).size(); i++) { + Map milestoneIdsMap = getRemainingMilestones(ipfsHash).get(i); + int milestoneId = (int) milestoneIdsMap.get(MILESTONE_ID); + + String milestonePrefix1 = mileStonePrefix(ipfsHash, milestoneId); + int milestoneCompletionPeriod1 = MilestoneDb.completionPeriod.at(milestonePrefix1).get(); + if (milestoneCompletionPeriod1 < milestoneCompletionPeriod) { + MilestoneDb.completionPeriod.at(milestonePrefix1).set(milestoneCompletionPeriod1 + 1); + MilestoneDb.completionPeriod.at(milestonePrefix).set(milestoneCompletionPeriod - 1); + } + } + if (milestoneStatus == MILESTONE_REPORT_APPROVED || milestoneStatus == MILESTONE_REPORT_COMPLETED) { Context.revert(TAG + " Milestone already completed/submitted " + milestoneStatus); } + int stats = MILESTONE_REPORT_NOT_COMPLETED; if (milestoneAttr.status) { stats = MILESTONE_REPORT_COMPLETED; } - String milestonePrefix = mileStonePrefix(ipfsHash, milestoneAttr.id); MilestoneDb.status.at(milestonePrefix).set(stats); MilestoneDb.progressReportHash.at(milestonePrefix).set(reportHash); milestoneSubmitted.at(reportHashPrefix).add(milestoneAttr.id); } + List milestoneDeadlineIDs = getMilestoneDeadline(ipfsHash); + if (!milestoneDeadlineIDs.isEmpty()) { + boolean isMilestoneSubmitted = checkContainsMilestone(milestoneSubmissions, milestoneDeadlineIDs); + Context.require(isMilestoneSubmitted, TAG + ": Submit milestone report for milestone id. " + milestoneDeadlineIDs); + } + } if (progressReport.budget_adjustment) { @@ -995,7 +1016,7 @@ public void voteProgressReport(String reportKey, String voteReason, MilestoneVot Context.require(!ArrayDBUtils.containsInArrayDb(caller, blockAddresses), TAG + ": You are blocked from CPS."); Context.require(ArrayDBUtils.containsInList(caller, callLocation), - TAG + ": Voting can only be done by registered P-Reps."); + TAG + ": Voting can only be done by registered P-Reps or Council Managers."); String progressReportPrefix = progressReportPrefix(reportKey); ArrayDB submittedMilestones = milestoneSubmitted.at(progressReportPrefix);// CAN TAKE FROM READONLY METHOD for (MilestoneVoteAttributes milestoneVote : votes) { @@ -1027,8 +1048,13 @@ public void voteProgressReport(String reportKey, String voteReason, MilestoneVot Integer totalVoter = ProgressReportDataDb.totalVoters.at(progressReportPrefix).getOrDefault(0); if (totalVoter == 0 || totalVotes.equals(BigInteger.ZERO)) { - ProgressReportDataDb.totalVoters.at(progressReportPrefix).set(pReps.validPreps.size()); - ProgressReportDataDb.totalVotes.at(progressReportPrefix).set(this.totalDelegationSnapshot.getOrDefault(BigInteger.ZERO)); + if (getCouncilFlag()) { + ProgressReportDataDb.totalVotes.at(progressReportPrefix).set(EXA.multiply(BigInteger.valueOf(getCouncilManagers().size()))); + ProgressReportDataDb.totalVoters.at(progressReportPrefix).set(getCouncilManagers().size()); + } else { + ProgressReportDataDb.totalVotes.at(progressReportPrefix).set(this.totalDelegationSnapshot.getOrDefault(BigInteger.ZERO)); + ProgressReportDataDb.totalVoters.at(progressReportPrefix).set(pReps.validPreps.size()); + } } DictDB voteChanged = ProgressReportDataDb.voteChange.at(progressReportPrefix); @@ -1073,6 +1099,7 @@ public void voteProgressReport(String reportKey, String voteReason, MilestoneVot } } + boolean budgetAdjustment = (boolean) progressReportDetails.get(BUDGET_ADJUSTMENT); if (budgetAdjustment && getBudgetAdjustmentFeature()) { // budgetAdjustment(reportKey, budgetAdjustmentVote, voteChange); @@ -1094,6 +1121,10 @@ public void voteProgressReport(String reportKey, String voteReason, MilestoneVot budgetAdjustment(reportKey, budgetAdjustmentVote, voteChange); } + + if (hasTwoThirdsMajority(proposalKey, milestoneVote.id)) { + MilestoneDb.majorityFlag.at(milestonePrefix).set(true); + } VotedSuccessfully(caller, "Progress Report Vote for " + progressReportDetails.get(PROGRESS_REPORT_TITLE) + " Successful."); swapBNUsdToken(); } @@ -1292,6 +1323,7 @@ public void updatePeriod() { period.periodCount.set(period.periodCount.getOrDefault(0) + 1); burn(proposalFees.get(), null); proposalFees.set(BigInteger.ZERO); + callScore(getCpfTreasuryScore(), "distributeRewardToFundManagers"); } @@ -1328,6 +1360,7 @@ private void updateMilestoneDB(String milestonePrefix) { DictDB prepVote = MilestoneDb.votersListIndices.at(milestonePrefix).at(prep); prepVote.set(INDEX, 0); prepVote.set(VOTE, 0); + MilestoneDb.majorityFlag.at(milestonePrefix).set(false); } clearArrayDb(MilestoneDb.votersList.at(milestonePrefix)); } @@ -1354,7 +1387,6 @@ private void updateProgressReportResult() { boolean _budget_adjustment = (boolean) _report_result.get(BUDGET_ADJUSTMENT); - // If a progress report have any budget_adjustment, then it checks the budget adjustment first if (_budget_adjustment && getBudgetAdjustmentFeature()) { updateBudgetAdjustments(_reports); @@ -1368,8 +1400,6 @@ private void updateProgressReportResult() { BigInteger _sponsor_deposit_amount = (BigInteger) _proposal_details.get(SPONSOR_DEPOSIT_AMOUNT); String flag = (String) _proposal_details.get(TOKEN); - List
_main_preps_list = arrayDBtoList(pReps.validPreps); - ArrayDB milestoneSubmitted = ProgressReportDataDb.milestoneSubmitted.at(progressPrefix); int milestonePassed = 0; @@ -1385,18 +1415,26 @@ private void updateProgressReportResult() { Map _milestone_details = getDataFromMilestoneDB(milestonePrefix); int milestoneStatus = (int) _milestone_details.get(STATUS); - int _approve_voters = (int) _milestone_details.get(APPROVE_VOTERS); - BigInteger _approved_votes = (BigInteger) _milestone_details.get(APPROVED_VOTES); + boolean majorityFlag = (boolean) _milestone_details.get(MAJORITY_FLAG); BigInteger _total_votes = ProgressReportDataDb.totalVotes.at(progressPrefix).get(); int _total_voters = ProgressReportDataDb.totalVoters.at(progressPrefix).getOrDefault(0); - if (_total_voters == 0 || _total_votes.equals(BigInteger.ZERO) || _main_preps_list.size() < MINIMUM_PREPS) { + int votersCount; + int minimumVoters; + + if (getCouncilFlag()) { + minimumVoters = 3; + votersCount = getCouncilManagers().size(); + } else { + minimumVoters = 7; + votersCount = pReps.validPreps.size(); + } + + if (_total_voters == 0 || _total_votes.equals(BigInteger.ZERO) || votersCount < minimumVoters) { MilestoneDb.status.at(milestonePrefix).set(MILESTONE_REPORT_REJECTED); updateMilestoneDB(milestonePrefix); } else { - double votersRatio = (double) _approve_voters / _total_voters; - double votesRatio = _approved_votes.doubleValue() / _total_votes.doubleValue(); - if (votersRatio >= MAJORITY && votesRatio >= MAJORITY) { + if (majorityFlag) { _approved_reports_count += 1; if (milestoneStatus == MILESTONE_REPORT_COMPLETED) { @@ -1472,7 +1510,6 @@ private void updateProgressReportResult() { } } } - } @@ -1570,7 +1607,19 @@ private void updateBudgetAdjustments(String _budget_key) { BigInteger _total_votes = (BigInteger) _vote_result.get(TOTAL_VOTES); PReps pReps = new PReps(); double votersRatio = (double) _approve_voters / _total_voters; - if (_total_voters == 0 || _total_votes.equals(BigInteger.ZERO) || pReps.validPreps.size() < MINIMUM_PREPS) { + + int votersCount; + int minimumVoters; + + if (getCouncilFlag()) { + minimumVoters = 3; + votersCount = getCouncilManagers().size(); + } else { + minimumVoters = 7; + votersCount = pReps.validPreps.size(); + } + + if (_total_votes.equals(BigInteger.ZERO) || votersCount < minimumVoters) { budgetAdjustmentStatus.at(_prefix).set(REJECTED); } else if (votersRatio >= MAJORITY && (_approved_votes.doubleValue() / _total_votes.doubleValue()) >= MAJORITY) { String _ipfs_hash = (String) _report_result.get(IPFS_HASH); @@ -1586,7 +1635,6 @@ private void updateBudgetAdjustments(String _budget_key) { totalBudget.at(proposal_prefix).set(_total_budget.add(_additional_budget)); budgetAdjustmentStatus.at(_prefix).set(APPROVED); - // After the budget adjustment is approved, Request new added fund to CPF callScore(getCpfTreasuryScore(), "updateProposalFund", _ipfs_hash, token_flag, _additional_budget, _additional_duration); } else { @@ -1607,8 +1655,6 @@ private void updateProposalsResult() { BigInteger totalBudget = (BigInteger) proposalDetails.get(TOTAL_BUDGET); int projectDuration = (int) proposalDetails.get(MILESTONE_COUNT); BigInteger sponsorDepositAmount = (BigInteger) proposalDetails.get(SPONSOR_DEPOSIT_AMOUNT); - int approvedVoters = (int) proposalVoteDetails.get(APPROVE_VOTERS); - BigInteger approvedVotes = (BigInteger) proposalVoteDetails.get(APPROVED_VOTES); BigInteger totalVotes = (BigInteger) proposalVoteDetails.get(TOTAL_VOTES); int totalVoters = (int) proposalVoteDetails.get(TOTAL_VOTERS); String flag = (String) proposalDetails.get(TOKEN); @@ -1617,15 +1663,22 @@ private void updateProposalsResult() { checkInactivePreps(ProposalDataDb.votersList.at(proposalPrefix)); - double voters_ratio = 0; - if (totalVoters != 0) { - voters_ratio = (double) approvedVoters / totalVoters; + int votersCount; + int minimumVoters; + + if (getCouncilFlag()) { + minimumVoters = 3; + votersCount = getCouncilManagers().size(); + } else { + minimumVoters = 7; + votersCount = pReps.validPreps.size(); } - if (totalVoters == 0 || totalVotes.equals(BigInteger.ZERO) || pReps.validPreps.size() < MINIMUM_PREPS) { + + + if (totalVoters == 0 || totalVotes.equals(BigInteger.ZERO) || votersCount < minimumVoters) { updateProposalStatus(proposal, REJECTED); updatedStatus = REJECTED; - } else if ((voters_ratio) >= MAJORITY && - (approvedVotes.doubleValue() / totalVotes.doubleValue()) >= MAJORITY) { + } else if (majorityFlag.at(proposalPrefix).getOrDefault(false)) { if (totalBudget.multiply(BigInteger.valueOf(102)).divide(BigInteger.valueOf(100)). // total budget + 2% of sponsor compareTo(distributionAmount) < 0) { updateProposalStatus(proposal, ACTIVE); @@ -1710,10 +1763,16 @@ private void updateProgressReportStatus(String progressHash, String progressStat private void checkInactivePreps(ArrayDB
prepList) { PReps pReps = new PReps(); - for (int i = 0; i < pReps.validPreps.size(); i++) { - Address prep = pReps.validPreps.get(i); - if (!containsInArrayDb(prep, prepList) && !containsInArrayDb(prep, pReps.inactivePreps)) { - pReps.inactivePreps.add(prep); + List
voters; + if (getCouncilFlag()) { + voters = getCouncilManagers(); + } else { + voters = ArrayDBUtils.arrayDBtoList(pReps.validPreps); + } + + for (Address voter : voters) { + if (!containsInArrayDb(voter, prepList) && !containsInArrayDb(voter, pReps.inactivePreps)) { + pReps.inactivePreps.add(voter); } } } @@ -1887,17 +1946,6 @@ public Map getProgressReportsByHash(String reportKey) { return Map.of(); } - private Map getMilestoneReport(String reportKey, String ipfsHash) { - Map milestoneReport = new HashMap<>(); - ArrayDB mileSubmitted = milestoneSubmitted.at(progressReportPrefix(reportKey)); - for (int i = 0; i < mileSubmitted.size(); i++) { - int count = mileSubmitted.get(i); - milestoneReport.put("milestone_" + count, getMilestonesReport(ipfsHash, count)); - } - return milestoneReport; - } - - @Override @External(readonly = true) public Map getProgressReportsByProposal(String ipfsKey) { @@ -2010,8 +2058,8 @@ public List> getRemainingProject(String projectType, Address String ipfsHash = ProgressReportDataDb.ipfsHash.at(prefix).get(); ArrayDB milestoneSubmittedOf = milestoneSubmitted.at(prefix); - for (int j = 0; j < milestoneSubmittedOf.size(); j++) { - int milestoneID = milestoneSubmittedOf.get(j); + if (milestoneSubmittedOf.size() > 0) { + int milestoneID = milestoneSubmittedOf.get(0); String milestonePrefix = mileStonePrefix(ipfsHash, milestoneID); ArrayDB
voterList = MilestoneDb.votersList.at(milestonePrefix); @@ -2021,6 +2069,7 @@ public List> getRemainingProject(String projectType, Address _remaining_progress_report.add(progressReportDetails); } } + } return _remaining_progress_report; } @@ -2313,7 +2362,19 @@ private void updateApplicationResult() { PReps pReps = new PReps(); Status status = new Status(); PeriodController period = new PeriodController(); - if (pReps.validPreps.size() < MINIMUM_PREPS) { + + int votersCount; + int minimumVoters; + + if (getCouncilFlag()) { + minimumVoters = 3; + votersCount = getCouncilManagers().size(); + } else { + minimumVoters = 7; + votersCount = pReps.validPreps.size(); + } + + if (votersCount < minimumVoters) { period.periodName.set(APPLICATION_PERIOD); PeriodUpdate("Period Updated back to Application Period due to less Registered P-Reps Count"); @@ -2391,8 +2452,6 @@ public void tokenFallback(Address from, BigInteger value, byte[] data) { } else { Context.revert(TAG + " Not supported method. Token transfer fails."); } - - } private void sponsorVote(String ipfsKey, String vote, String voteReason, Address from, BigInteger value) { @@ -2670,31 +2729,43 @@ public Map getProposalsHistory(@Optional int startIndex) { return milestoneIdList; } - @External(readonly = true) - public boolean hasTwoThirdsMajority(String key, boolean isMilestone) { - //can also use if else if this doesnt work as intended - - //error: milestonedb doesnt have total votes or voters + private boolean hasTwoThirdsMajority(String ipfsHash, int milestoneId) { + String ipfsHashPrefix = proposalPrefix(ipfsHash); + boolean isMilestone = milestoneId > 0; + BigInteger totalVotes; + BigInteger approvedVotes; + int approvedVoters; + int totalVoters; - Map milestoneDbData = MilestoneDb.getDataFromMilestoneDB(key); - BigInteger totalVotes = isMilestone ? (BigInteger) milestoneDbData.get(TOTAL_VOTES) : ProgressReportDataDb.totalVotes.at(key).getOrDefault(BigInteger.ZERO); - int totalVoters = isMilestone ? (Integer) milestoneDbData.get(TOTAL_VOTERS) : ProgressReportDataDb.totalVoters.at(key).getOrDefault(0); + if (isMilestone) { + String milestonePrefix = mileStonePrefix(ipfsHash, milestoneId); + Map dataFromMilestoneDB = getDataFromMilestoneDB(milestonePrefix); + totalVotes = (BigInteger) dataFromMilestoneDB.get(TOTAL_VOTES); + totalVoters = (Integer) dataFromMilestoneDB.get(TOTAL_VOTERS); + approvedVotes = MilestoneDb.approvedVotes.at(milestonePrefix).getOrDefault(BigInteger.ZERO); + approvedVoters = MilestoneDb.approveVoters.at(milestonePrefix).size(); - BigInteger approveVotes = isMilestone ? MilestoneDb.approvedVotes.at(key).getOrDefault(BigInteger.ZERO) : ProgressReportDataDb.approvedVotes.at(key).getOrDefault(BigInteger.ZERO); - int approveVoters = isMilestone ? MilestoneDb.approveVoters.at(key).size() : ProgressReportDataDb.approveVoters.at(key).size(); + } else { + totalVotes = ProposalDataDb.totalVotes.at(ipfsHashPrefix).getOrDefault(BigInteger.ZERO); + totalVoters = ProposalDataDb.totalVoters.at(ipfsHashPrefix).getOrDefault(0); + approvedVotes = ProposalDataDb.approvedVotes.at(ipfsHashPrefix).getOrDefault(BigInteger.ZERO); + approvedVoters = ProposalDataDb.approveVoters.at(ipfsHashPrefix).size(); + } - //need to give vote weights = 100 (arbitrary) - boolean voteWeightCheck = approveVotes.multiply(BigInteger.valueOf(3)).compareTo(totalVotes.multiply(BigInteger.valueOf(2))) >= 0; - boolean voterCountCheck = approveVoters * 3 >= totalVoters * 2; + double voteWeight = approvedVotes.doubleValue() / totalVotes.doubleValue(); + double voters_ratio = (double) approvedVoters / totalVoters; - return voteWeightCheck && voterCountCheck; + return voters_ratio >= MAJORITY && voteWeight > MAJORITY; } + + @External(readonly = true) public List
getCouncilManagers() { return callScore(List.class, getCpfTreasuryScore(), "getCouncilManagers"); } + @External(readonly = true) public boolean getCouncilFlag() { return callScore(boolean.class, getCpfTreasuryScore(), "getCouncilFlag"); } @@ -2894,7 +2965,6 @@ public void callScore(BigInteger amount, Address address, String method, Object. public void validateAdmins() { Context.require(isAdmin(Context.getCaller()), TAG + ": Only Admins can call this method"); - } public void validateAdminScore(Address scoreAddress) { @@ -2907,10 +2977,5 @@ public void onlyCPFTreasury() { Context.require(Context.getCaller().equals(getCpfTreasuryScore()), TAG + ": Only CPF treasury can call this method"); } - public void callScore(Class eq, Class eq2, String eq3, String eq4) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'callScore'"); - } - // =====================================Checkers=============================================== } \ No newline at end of file From 1d22f39a5107aecf55d5e8e367ec23efd3fa5d8f Mon Sep 17 00:00:00 2001 From: sdp_ibriz Date: Wed, 23 Oct 2024 14:05:17 +0545 Subject: [PATCH 63/64] fix build.gradle for cpsCore and CPSTreasury to support devnet --- CPSCore/build.gradle | 26 ++++++++++---------------- CPSTreasury/build.gradle | 23 +++++++---------------- 2 files changed, 17 insertions(+), 32 deletions(-) diff --git a/CPSCore/build.gradle b/CPSCore/build.gradle index 1305b702..bcacd745 100644 --- a/CPSCore/build.gradle +++ b/CPSCore/build.gradle @@ -1,4 +1,4 @@ -version = '1.3.9' +version = '1.5.5' dependencies { @@ -35,31 +35,25 @@ deployJar { lisbon { uri = 'https://lisbon.net.solidwallet.io/api/v3' nid = 0x2 - to = 'cx8e21d3b7a70aeeaca45d4a70c31a6b959f5823bd' - } - local { - uri = 'http://localhost:9082/api/v3' - nid = 0x3 - } - berlin { - uri = 'https://berlin.net.solidwallet.io/api/v3' - nid = 0x7 - } - sejong { - uri = 'https://sejong.net.solidwallet.io/api/v3' - nid = 0x53 - to = 'cx2b214d56805531b9c878c4d4ff0e53d961c60834' + to = "cx1a7a9bde78fe14e2aeea03966c6d7260575627f5" } mainnet { uri = 'https://ctz.solidwallet.io/api/v3' nid = 0x1 to = 'cx9f4ab72f854d3ccdc59aa6f2c3e2215dd62e879f' } - + devnet{ + uri = "https://tt.net.solidwallet.io/api/v3" + nid = 0x3 + to = "cx5100c8b221cc373939d8a720ecfbd90440c75ed3" + } } keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' parameters { + arg("applicationPeriod", "15") + arg("bondValue", "15") + } } diff --git a/CPSTreasury/build.gradle b/CPSTreasury/build.gradle index 85bfca6d..669f7650 100644 --- a/CPSTreasury/build.gradle +++ b/CPSTreasury/build.gradle @@ -1,4 +1,4 @@ -version = '1.3.5' +version = '1.4' dependencies { // compileOnly 'foundation.icon:javaee-api:0.9.2' @@ -31,31 +31,22 @@ deployJar { lisbon { uri = 'https://lisbon.net.solidwallet.io/api/v3' nid = 0x2 - to = 'cxabc97ed26cb147eeef55b1728102aea25af8f62f' - } - local { - uri = 'http://localhost:9082/api/v3' - nid = 0x3 - } - sejong{ - uri = 'https://sejong.net.solidwallet.io/api/v3' - nid = 0x53 - to = 'cxb33f0187a22a41c3ecb05a9756af320e98badb7d' - } - berlin{ - uri = 'https://berlin.net.solidwallet.io/api/v3' - nid = 0x7 - to = 'cx3e2a9648e4365added55bfa6a84e515d99f1bb67' + to = "cxe2179d6409a4920ac6e6ee272d79a3bcfea969df" } mainnet { uri = 'https://ctz.solidwallet.io/api/v3' nid = 0x1 to = 'cxd965531d1cce5daad1d1d3ee1efb39ce68f442fc' } + devnet{ + uri = "https://tt.net.solidwallet.io/api/v3" + nid = 0x3 + } } keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : '' password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : '' parameters { + arg("cpsScore", "cx5100c8b221cc373939d8a720ecfbd90440c75ed3") } } From fabf351bafe3a6ce59f1018cb7e15c334d7ecd6d Mon Sep 17 00:00:00 2001 From: sdp_ibriz Date: Wed, 23 Oct 2024 16:16:26 +0545 Subject: [PATCH 64/64] fix councilFlag set at initialize of proposal --- .../java/community/icon/cps/score/cpscore/CPSCore.java | 6 ++++-- .../icon/cps/score/cpscore/db/ProposalDataDb.java | 7 +------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java b/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java index 2d113a7a..6e5db456 100644 --- a/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java +++ b/CPSCore/src/main/java/community/icon/cps/score/cpscore/CPSCore.java @@ -344,7 +344,9 @@ private String getPrepName(Address address) { int index = getCouncilManagers().indexOf(address); return "Council Manager " + (index + 1); } - return (String) getPRepInfo(address).get("name"); + else { + return (String) getPRepInfo(address).get("name"); + } } private BigInteger getStake(Address address) { @@ -678,6 +680,7 @@ public void submitProposal(ProposalAttributes proposals, MilestonesAttributes[] String ipfsHashPrefix = proposalPrefix(ipfsHash); addDataToProposalDB(proposals, ipfsHashPrefix); + councilFlag.at(ipfsHashPrefix).set(getCouncilFlag()); BigInteger initialPaymentPercentage = callScore(BigInteger.class, getCpsTreasuryScore(), "getOnsetPayment"); BigInteger totalBudget = proposals.total_budget.multiply(EXA); @@ -1436,7 +1439,6 @@ private void updateProgressReportResult() { } else { if (majorityFlag) { _approved_reports_count += 1; - if (milestoneStatus == MILESTONE_REPORT_COMPLETED) { milestonePassed += 1; milestoneBudget = milestoneBudget.add(MilestoneDb.budget.at(milestonePrefix).getOrDefault(BigInteger.ZERO)); diff --git a/CPSCore/src/main/java/community/icon/cps/score/cpscore/db/ProposalDataDb.java b/CPSCore/src/main/java/community/icon/cps/score/cpscore/db/ProposalDataDb.java index e866b9cf..78a26017 100644 --- a/CPSCore/src/main/java/community/icon/cps/score/cpscore/db/ProposalDataDb.java +++ b/CPSCore/src/main/java/community/icon/cps/score/cpscore/db/ProposalDataDb.java @@ -1,15 +1,13 @@ package community.icon.cps.score.cpscore.db; +import community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProposalAttributes; import score.*; import java.math.BigInteger; import java.util.Map; -import community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProposalAttributes; - import static community.icon.cps.score.cpscore.utils.ArrayDBUtils.recordTxHash; import static community.icon.cps.score.cpscore.utils.Constants.*; -import static community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProposalAttributes; public class ProposalDataDb { public static final BranchDB> ipfsHash = Context.newBranchDB(IPFS_HASH, String.class); @@ -73,10 +71,7 @@ public static void addDataToProposalDB(ProposalAttributes proposalData, String p token.at(prefix).set(proposalData.token); milestoneCount.at(prefix).set(proposalData.milestoneCount); isMilestone.at(prefix).set(true); - majorityFlag.at(prefix).set(false); - councilFlag.at(prefix).set(false); - } public static void updatePercentageCompleted(String prefix, int percentage) {