From c0e15fc59eeef62994c13881bbf14abf0f0e1318 Mon Sep 17 00:00:00 2001 From: nanfengpo Date: Thu, 23 Aug 2018 13:07:26 +0800 Subject: [PATCH 01/10] test: add ExchangeCreateActuator test --- .../actuator/ExchangeCreateActuatorTest.java | 308 ++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100644 src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java diff --git a/src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java b/src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java new file mode 100644 index 00000000000..6f52873e5b1 --- /dev/null +++ b/src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java @@ -0,0 +1,308 @@ +package org.tron.core.actuator; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import java.io.File; +import java.util.Arrays; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.ExchangeCapsule; +import org.tron.core.capsule.TransactionResultCapsule; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.ItemNotFoundException; +import org.tron.protos.Contract; +import org.tron.protos.Protocol.AccountType; +import org.tron.protos.Protocol.Transaction.Result.code; + +@Slf4j + +public class ExchangeCreateActuatorTest { + + private static AnnotationConfigApplicationContext context; + private static Manager dbManager; + private static final String dbPath = "output_ExchangeCreate_test"; + private static final String ACCOUNT_NAME_FIRST = "ownerF"; + private static final String OWNER_ADDRESS_FIRST; + private static final String ACCOUNT_NAME_SECOND = "ownerS"; + private static final String OWNER_ADDRESS_SECOND; + private static final String URL = "https://tron.network"; + private static final String OWNER_ADDRESS_INVALID = "aaaa"; + private static final String OWNER_ADDRESS_NOACCOUNT; + private static final String OWNER_ADDRESS_BALANCENOTSUFFIENT; + + static { + Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + context = new AnnotationConfigApplicationContext(DefaultConfig.class); + OWNER_ADDRESS_FIRST = + Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + OWNER_ADDRESS_SECOND = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; + OWNER_ADDRESS_NOACCOUNT = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1aed"; + OWNER_ADDRESS_BALANCENOTSUFFIENT = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e06d4271a1ced"; + } + + /** + * Init data. + */ + @BeforeClass + public static void init() { + dbManager = context.getBean(Manager.class); + } + + /** + * Release resources. + */ + @AfterClass + public static void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } + + /** + * create temp Capsule test need. + */ + @Before + public void initTest() { + AccountCapsule ownerAccountFirstCapsule = + new AccountCapsule( + ByteString.copyFromUtf8(ACCOUNT_NAME_FIRST), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_FIRST)), + AccountType.Normal, + 300_000_000L); + AccountCapsule ownerAccountSecondCapsule = + new AccountCapsule( + ByteString.copyFromUtf8(ACCOUNT_NAME_SECOND), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_SECOND)), + AccountType.Normal, + 200_000_000_000L); + + dbManager.getAccountStore() + .put(ownerAccountFirstCapsule.getAddress().toByteArray(), ownerAccountFirstCapsule); + dbManager.getAccountStore() + .put(ownerAccountSecondCapsule.getAddress().toByteArray(), ownerAccountSecondCapsule); + + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(1000000); + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(10); + dbManager.getDynamicPropertiesStore().saveNextMaintenanceTime(2000000); + } + + private Any getContract(String address, String firstTokenId, long firstTokenBalance, + String secondTokenId, long secondTokenBalance) { + return Any.pack( + Contract.ExchangeCreateContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(address))) + .setFirstTokenId(ByteString.copyFrom(firstTokenId.getBytes())) + .setFirstTokenBalance(firstTokenBalance) + .setSecondTokenId(ByteString.copyFrom(secondTokenId.getBytes())) + .setSecondTokenBalance(secondTokenBalance) + .build()); + } + + /** + * first createExchange,result is success. + */ + @Test + public void successExchangeCreate() { + String firstTokenId = "abc"; + long firstTokenBalance = 100000000L; + String secondTokenId = "def"; + long secondTokenBalance = 100000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenBalance); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenBalance); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeCreateActuator actuator = new ExchangeCreateActuator(getContract( + OWNER_ADDRESS_FIRST, firstTokenId, firstTokenBalance, secondTokenId, secondTokenBalance), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), 0); + try { + actuator.validate(); + actuator.execute(ret); + Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + long id = 1; + ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore().get(ByteArray.fromLong(id)); + Assert.assertNotNull(exchangeCapsule); + Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), id); + + Assert.assertEquals(ByteString.copyFrom(ownerAddress), exchangeCapsule.getCreatorAddress()); + Assert.assertEquals(id, exchangeCapsule.getID()); + Assert.assertEquals(1000000, exchangeCapsule.getCreateTime()); + Assert.assertTrue(Arrays.equals(firstTokenId.getBytes(), exchangeCapsule.getFirstTokenId())); +// Assert.assertEquals(firstTokenId.getBytes(), exchangeCapsule.getFirstTokenId()); + Assert.assertEquals(firstTokenId, ByteArray.toStr(exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(firstTokenBalance, exchangeCapsule.getFirstTokenBalance()); + Assert.assertEquals(secondTokenId, ByteArray.toStr(exchangeCapsule.getSecondTokenId())); + Assert.assertEquals(secondTokenBalance, exchangeCapsule.getSecondTokenBalance()); + + } catch (ContractValidateException e) { + Assert.assertFalse(e instanceof ContractValidateException); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } catch (ItemNotFoundException e) { + Assert.assertFalse(e instanceof ItemNotFoundException); + } + } + +// /** +// * use Invalid Address, result is failed, exception is "Invalid address". +// */ +// @Test +// public void invalidAddress() { +// HashMap paras = new HashMap<>(); +// paras.put(0L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_INVALID, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("Invalid address"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Invalid address", e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// } +// +// /** +// * use AccountStore not exists, result is failed, exception is "account not exists". +// */ +// @Test +// public void noAccount() { +// HashMap paras = new HashMap<>(); +// paras.put(0L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_NOACCOUNT, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("account[+OWNER_ADDRESS_NOACCOUNT+] not exists"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("account[" + OWNER_ADDRESS_NOACCOUNT + "] not exists", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// } +// +// /** +// * use WitnessStore not exists Address,result is failed,exception is "witness not exists". +// */ +// @Test +// public void noWitness() { +// HashMap paras = new HashMap<>(); +// paras.put(0L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_SECOND, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("witness[+OWNER_ADDRESS_NOWITNESS+] not exists"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Witness[" + OWNER_ADDRESS_SECOND + "] not exists", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// } +// +// /** +// * use invalid parameter, result is failed, exception is "Bad chain parameter id". +// */ +// @Test +// public void invalidPara() { +// HashMap paras = new HashMap<>(); +// paras.put(17L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("Bad chain parameter id"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Bad chain parameter id", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// +// paras = new HashMap<>(); +// paras.put(3L, 1 + 100_000_000_000_000_000L); +// actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// +// paras = new HashMap<>(); +// paras.put(10L, -1L); +// actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(-1); +// try { +// actuator.validate(); +// fail("This exchange has been executed before and is only allowed to be executed once"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals( +// "This exchange has been executed before and is only allowed to be executed once", +// e.getMessage()); +// } +// +// paras.put(10L, -1L); +// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); +// actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); +// try { +// actuator.validate(); +// fail("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1", +// e.getMessage()); +// } +// } + +} \ No newline at end of file From 830f48431d857dc1571033e4c7cd57c4d8a62855 Mon Sep 17 00:00:00 2001 From: nanfengpo Date: Thu, 23 Aug 2018 13:44:09 +0800 Subject: [PATCH 02/10] fix: exchangecreate fee --- .../core/actuator/ExchangeCreateActuator.java | 2 + .../actuator/ExchangeCreateActuatorTest.java | 7 + .../actuator/ExchangeInjectActuatorTest.java | 308 ++++++++++++++++++ 3 files changed, 317 insertions(+) create mode 100644 src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java diff --git a/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java b/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java index 7f31961519c..f77a3601c95 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java @@ -39,6 +39,8 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException long newBalance = accountCapsule.getBalance() - calcFee(); + accountCapsule.setBalance(newBalance); + if (firstTokenID == "_".getBytes()) { accountCapsule.setBalance(newBalance - firstTokenBalance); } else { diff --git a/src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java b/src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java index 6f52873e5b1..9a8695b9bd6 100644 --- a/src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java @@ -4,6 +4,7 @@ import com.google.protobuf.ByteString; import java.io.File; import java.util.Arrays; +import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.junit.AfterClass; import org.junit.Assert; @@ -160,6 +161,12 @@ public void successExchangeCreate() { Assert.assertEquals(secondTokenId, ByteArray.toStr(exchangeCapsule.getSecondTokenId())); Assert.assertEquals(secondTokenBalance, exchangeCapsule.getSecondTokenBalance()); + accountCapsule = dbManager.getAccountStore().get(ownerAddress); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(10000_000000L - 1024_000000L, accountCapsule.getBalance()); + Assert.assertEquals(0L, assetMap.get(firstTokenId).longValue()); + Assert.assertEquals(0L, assetMap.get(secondTokenId).longValue()); + } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { diff --git a/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java b/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java new file mode 100644 index 00000000000..54ebcb116a2 --- /dev/null +++ b/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java @@ -0,0 +1,308 @@ +package org.tron.core.actuator; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import java.io.File; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.ExchangeCapsule; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.protos.Contract; +import org.tron.protos.Protocol.AccountType; + +@Slf4j + +public class ExchangeInjectActuatorTest { + + private static AnnotationConfigApplicationContext context; + private static Manager dbManager; + private static final String dbPath = "output_ExchangeCreate_test"; + private static final String ACCOUNT_NAME_FIRST = "ownerF"; + private static final String OWNER_ADDRESS_FIRST; + private static final String ACCOUNT_NAME_SECOND = "ownerS"; + private static final String OWNER_ADDRESS_SECOND; + private static final String URL = "https://tron.network"; + private static final String OWNER_ADDRESS_INVALID = "aaaa"; + private static final String OWNER_ADDRESS_NOACCOUNT; + private static final String OWNER_ADDRESS_BALANCENOTSUFFIENT; + + static { + Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + context = new AnnotationConfigApplicationContext(DefaultConfig.class); + OWNER_ADDRESS_FIRST = + Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + OWNER_ADDRESS_SECOND = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; + OWNER_ADDRESS_NOACCOUNT = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1aed"; + OWNER_ADDRESS_BALANCENOTSUFFIENT = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e06d4271a1ced"; + } + + /** + * Init data. + */ + @BeforeClass + public static void init() { + dbManager = context.getBean(Manager.class); + } + + /** + * Release resources. + */ + @AfterClass + public static void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } + + /** + * create temp Capsule test need. + */ + @Before + public void initTest() { + AccountCapsule ownerAccountFirstCapsule = + new AccountCapsule( + ByteString.copyFromUtf8(ACCOUNT_NAME_FIRST), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_FIRST)), + AccountType.Normal, + 300_000_000L); + AccountCapsule ownerAccountSecondCapsule = + new AccountCapsule( + ByteString.copyFromUtf8(ACCOUNT_NAME_SECOND), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_SECOND)), + AccountType.Normal, + 200_000_000_000L); + ExchangeCapsule exchangeCapsule = + new ExchangeCapsule( + ByteString.copyFromUtf8(ACCOUNT_NAME_FIRST), + 1, + 1000000, + "abc".getBytes(), + "def".getBytes()); + exchangeCapsule.setBalance(100000000L, 200000000L); + + dbManager.getAccountStore() + .put(ownerAccountFirstCapsule.getAddress().toByteArray(), ownerAccountFirstCapsule); + dbManager.getAccountStore() + .put(ownerAccountSecondCapsule.getAddress().toByteArray(), ownerAccountSecondCapsule); + dbManager.getExchangeStore() + .put(exchangeCapsule.createDbKey(), exchangeCapsule); + + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(1000000); + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(10); + dbManager.getDynamicPropertiesStore().saveNextMaintenanceTime(2000000); + } + + private Any getContract(String address, long exchangeId, String tokenId, long quant) { + return Any.pack( + Contract.ExchangeInjectContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(address))) + .setExchangeId(exchangeId) + .setTokenId(ByteString.copyFrom(tokenId.getBytes())) + .setQuant(quant) + .build()); + } + + /** + * first createExchange,result is success. + */ +// @Test +// public void successExchangeInject() { +// String firstTokenId = "abc"; +// long firstTokenQuant = 100000000L; +// String secondTokenId = "def"; +// long secondTokenQuant = 200000000L; +// +// byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); +// AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); +// accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenQuant); +// accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); +// accountCapsule.setBalance(10000_000000L); +// dbManager.getAccountStore().put(ownerAddress, accountCapsule); +// +// ExchangeCreateActuator actuator = new ExchangeCreateActuator(getContract( +// OWNER_ADDRESS_FIRST, firstTokenId, firstTokenBalance, secondTokenId, secondTokenBalance), +// dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), 0); +// try { +// actuator.validate(); +// actuator.execute(ret); +// Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); +// long id = 1; +// ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore().get(ByteArray.fromLong(id)); +// Assert.assertNotNull(exchangeCapsule); +// Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), id); +// +// Assert.assertEquals(ByteString.copyFrom(ownerAddress), exchangeCapsule.getCreatorAddress()); +// Assert.assertEquals(id, exchangeCapsule.getID()); +// Assert.assertEquals(1000000, exchangeCapsule.getCreateTime()); +// Assert.assertTrue(Arrays.equals(firstTokenId.getBytes(), exchangeCapsule.getFirstTokenId())); +//// Assert.assertEquals(firstTokenId.getBytes(), exchangeCapsule.getFirstTokenId()); +// Assert.assertEquals(firstTokenId, ByteArray.toStr(exchangeCapsule.getFirstTokenId())); +// Assert.assertEquals(firstTokenBalance, exchangeCapsule.getFirstTokenBalance()); +// Assert.assertEquals(secondTokenId, ByteArray.toStr(exchangeCapsule.getSecondTokenId())); +// Assert.assertEquals(secondTokenBalance, exchangeCapsule.getSecondTokenBalance()); +// +// } catch (ContractValidateException e) { +// Assert.assertFalse(e instanceof ContractValidateException); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } catch (ItemNotFoundException e) { +// Assert.assertFalse(e instanceof ItemNotFoundException); +// } +// } + +// /** +// * use Invalid Address, result is failed, exception is "Invalid address". +// */ +// @Test +// public void invalidAddress() { +// HashMap paras = new HashMap<>(); +// paras.put(0L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_INVALID, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("Invalid address"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Invalid address", e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// } +// +// /** +// * use AccountStore not exists, result is failed, exception is "account not exists". +// */ +// @Test +// public void noAccount() { +// HashMap paras = new HashMap<>(); +// paras.put(0L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_NOACCOUNT, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("account[+OWNER_ADDRESS_NOACCOUNT+] not exists"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("account[" + OWNER_ADDRESS_NOACCOUNT + "] not exists", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// } +// +// /** +// * use WitnessStore not exists Address,result is failed,exception is "witness not exists". +// */ +// @Test +// public void noWitness() { +// HashMap paras = new HashMap<>(); +// paras.put(0L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_SECOND, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("witness[+OWNER_ADDRESS_NOWITNESS+] not exists"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Witness[" + OWNER_ADDRESS_SECOND + "] not exists", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// } +// +// /** +// * use invalid parameter, result is failed, exception is "Bad chain parameter id". +// */ +// @Test +// public void invalidPara() { +// HashMap paras = new HashMap<>(); +// paras.put(17L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("Bad chain parameter id"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Bad chain parameter id", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// +// paras = new HashMap<>(); +// paras.put(3L, 1 + 100_000_000_000_000_000L); +// actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// +// paras = new HashMap<>(); +// paras.put(10L, -1L); +// actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(-1); +// try { +// actuator.validate(); +// fail("This exchange has been executed before and is only allowed to be executed once"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals( +// "This exchange has been executed before and is only allowed to be executed once", +// e.getMessage()); +// } +// +// paras.put(10L, -1L); +// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); +// actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); +// try { +// actuator.validate(); +// fail("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1", +// e.getMessage()); +// } +// } + +} \ No newline at end of file From d724a7ea65b2856a85a67cd308f04ebd2246b0e9 Mon Sep 17 00:00:00 2001 From: nanfengpo Date: Thu, 23 Aug 2018 14:06:22 +0800 Subject: [PATCH 03/10] test: add ExchangeInjectActuator test --- .../actuator/ExchangeInjectActuatorTest.java | 111 ++++++++++-------- 1 file changed, 63 insertions(+), 48 deletions(-) diff --git a/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java b/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java index 54ebcb116a2..dcafa97472c 100644 --- a/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java @@ -3,10 +3,14 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; import java.io.File; +import java.util.Arrays; +import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; +import org.junit.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; @@ -14,11 +18,16 @@ import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.ExchangeCapsule; +import org.tron.core.capsule.TransactionResultCapsule; import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.ItemNotFoundException; import org.tron.protos.Contract; import org.tron.protos.Protocol.AccountType; +import org.tron.protos.Protocol.Transaction.Result.code; @Slf4j @@ -90,7 +99,7 @@ public void initTest() { 200_000_000_000L); ExchangeCapsule exchangeCapsule = new ExchangeCapsule( - ByteString.copyFromUtf8(ACCOUNT_NAME_FIRST), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_FIRST)), 1, 1000000, "abc".getBytes(), @@ -120,54 +129,60 @@ private Any getContract(String address, long exchangeId, String tokenId, long qu } /** - * first createExchange,result is success. + * first inject Exchange,result is success. */ -// @Test -// public void successExchangeInject() { -// String firstTokenId = "abc"; -// long firstTokenQuant = 100000000L; -// String secondTokenId = "def"; -// long secondTokenQuant = 200000000L; -// -// byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); -// AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); -// accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenQuant); -// accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); -// accountCapsule.setBalance(10000_000000L); -// dbManager.getAccountStore().put(ownerAddress, accountCapsule); -// -// ExchangeCreateActuator actuator = new ExchangeCreateActuator(getContract( -// OWNER_ADDRESS_FIRST, firstTokenId, firstTokenBalance, secondTokenId, secondTokenBalance), -// dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), 0); -// try { -// actuator.validate(); -// actuator.execute(ret); -// Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); -// long id = 1; -// ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore().get(ByteArray.fromLong(id)); -// Assert.assertNotNull(exchangeCapsule); -// Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), id); -// -// Assert.assertEquals(ByteString.copyFrom(ownerAddress), exchangeCapsule.getCreatorAddress()); -// Assert.assertEquals(id, exchangeCapsule.getID()); -// Assert.assertEquals(1000000, exchangeCapsule.getCreateTime()); -// Assert.assertTrue(Arrays.equals(firstTokenId.getBytes(), exchangeCapsule.getFirstTokenId())); -//// Assert.assertEquals(firstTokenId.getBytes(), exchangeCapsule.getFirstTokenId()); -// Assert.assertEquals(firstTokenId, ByteArray.toStr(exchangeCapsule.getFirstTokenId())); -// Assert.assertEquals(firstTokenBalance, exchangeCapsule.getFirstTokenBalance()); -// Assert.assertEquals(secondTokenId, ByteArray.toStr(exchangeCapsule.getSecondTokenId())); -// Assert.assertEquals(secondTokenBalance, exchangeCapsule.getSecondTokenBalance()); -// -// } catch (ContractValidateException e) { -// Assert.assertFalse(e instanceof ContractValidateException); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } catch (ItemNotFoundException e) { -// Assert.assertFalse(e instanceof ItemNotFoundException); -// } -// } + @Test + public void successExchangeInject() { + long exchangeId = 1; + String firstTokenId = "abc"; + long firstTokenQuant = 200000000L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenQuant); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeInjectActuator actuator = new ExchangeInjectActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + long id = 1; + ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore().get(ByteArray.fromLong(id)); + Assert.assertNotNull(exchangeCapsule); + + Assert.assertEquals(ByteString.copyFrom(ownerAddress), exchangeCapsule.getCreatorAddress()); + Assert.assertEquals(id, exchangeCapsule.getID()); + Assert.assertEquals(1000000, exchangeCapsule.getCreateTime()); + Assert.assertTrue(Arrays.equals(firstTokenId.getBytes(), exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(firstTokenId, ByteArray.toStr(exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(300000000L, exchangeCapsule.getFirstTokenBalance()); + Assert.assertEquals(secondTokenId, ByteArray.toStr(exchangeCapsule.getSecondTokenId())); + Assert.assertEquals(600000000L, exchangeCapsule.getSecondTokenBalance()); + + accountCapsule = dbManager.getAccountStore().get(ownerAddress); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(10000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(0L, assetMap.get(firstTokenId).longValue()); + Assert.assertEquals(0L, assetMap.get(secondTokenId).longValue()); + + } catch (ContractValidateException e) { + logger.info(e.getMessage()); + Assert.assertFalse(e instanceof ContractValidateException); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } catch (ItemNotFoundException e) { + Assert.assertFalse(e instanceof ItemNotFoundException); + } + } // /** // * use Invalid Address, result is failed, exception is "Invalid address". From 57c766ec02862331c79091e18ae7655765938ad9 Mon Sep 17 00:00:00 2001 From: nanfengpo Date: Thu, 23 Aug 2018 15:33:28 +0800 Subject: [PATCH 04/10] fix: bytearray equal in exchange actuators --- .../core/actuator/ExchangeCreateActuator.java | 15 +- .../core/actuator/ExchangeInjectActuator.java | 12 +- .../actuator/ExchangeTransactionActuator.java | 13 +- .../actuator/ExchangeWithdrawActuator.java | 8 +- .../actuator/ExchangeInjectActuatorTest.java | 2 +- .../ExchangeTransactionActuatorTest.java | 329 ++++++++++++++++++ .../ExchangeWithdrawActuatorTest.java | 323 +++++++++++++++++ 7 files changed, 670 insertions(+), 32 deletions(-) create mode 100644 src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java create mode 100644 src/test/java/org/tron/core/actuator/ExchangeWithdrawActuatorTest.java diff --git a/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java b/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java index f77a3601c95..31050bc36fa 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java @@ -3,6 +3,7 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; +import java.util.Arrays; import lombok.extern.slf4j.Slf4j; import org.tron.common.utils.StringUtil; import org.tron.core.Wallet; @@ -41,13 +42,13 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException accountCapsule.setBalance(newBalance); - if (firstTokenID == "_".getBytes()) { + if (Arrays.equals(firstTokenID, "_".getBytes())) { accountCapsule.setBalance(newBalance - firstTokenBalance); } else { accountCapsule.reduceAssetAmount(firstTokenID, firstTokenBalance); } - if (secondTokenID == "_".getBytes()) { + if (Arrays.equals(secondTokenID, "_".getBytes())) { accountCapsule.setBalance(newBalance - secondTokenBalance); } else { accountCapsule.reduceAssetAmount(secondTokenID, secondTokenBalance); @@ -121,7 +122,7 @@ public boolean validate() throws ContractValidateException { long firstTokenBalance = contract.getFirstTokenBalance(); long secondTokenBalance = contract.getSecondTokenBalance(); - if (firstTokenID == secondTokenID) { + if (Arrays.equals(firstTokenID, secondTokenID)) { throw new ContractValidateException("cannot exchange same tokens"); } @@ -134,7 +135,7 @@ public boolean validate() throws ContractValidateException { throw new ContractValidateException("token balance must less than " + balanceLimit); } - if (firstTokenID == "_".getBytes()) { + if (Arrays.equals(firstTokenID, "_".getBytes())) { if (accountCapsule.getBalance() < (firstTokenBalance + calcFee())) { throw new ContractValidateException("balance is not enough"); } @@ -144,7 +145,7 @@ public boolean validate() throws ContractValidateException { } } - if (secondTokenID == "_".getBytes()) { + if (Arrays.equals(secondTokenID, "_".getBytes())) { if (accountCapsule.getBalance() < (secondTokenBalance + calcFee())) { throw new ContractValidateException("balance is not enough"); } @@ -168,8 +169,4 @@ public long calcFee() { return dbManager.getDynamicPropertiesStore().getExchangeCreateFee(); } - private boolean validKey(long idx) { - return idx >= 0 && idx < ChainParameters.values().length; - } - } diff --git a/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java b/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java index 24b97b11e3b..4a4a2122e5c 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java @@ -65,13 +65,13 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException long newBalance = accountCapsule.getBalance() - calcFee(); - if (tokenID == "_".getBytes()) { + if (Arrays.equals(tokenID, "_".getBytes())) { accountCapsule.setBalance(newBalance - tokenQuant); } else { accountCapsule.reduceAssetAmount(tokenID, tokenQuant); } - if (anotherTokenID == "_".getBytes()) { + if (Arrays.equals(anotherTokenID, "_".getBytes())) { accountCapsule.setBalance(newBalance - anotherTokenQuant); } else { accountCapsule.reduceAssetAmount(anotherTokenID, anotherTokenQuant); @@ -191,7 +191,7 @@ public boolean validate() throws ContractValidateException { throw new ContractValidateException("token balance must less than " + balanceLimit); } - if (tokenID == "_".getBytes()) { + if (Arrays.equals(tokenID, "_".getBytes())) { if (accountCapsule.getBalance() < (tokenQuant + calcFee())) { throw new ContractValidateException("balance is not enough"); } @@ -201,7 +201,7 @@ public boolean validate() throws ContractValidateException { } } - if (anotherTokenID == "_".getBytes()) { + if (Arrays.equals(anotherTokenID, "_".getBytes())) { if (accountCapsule.getBalance() < (anotherTokenQuant + calcFee())) { throw new ContractValidateException("balance is not enough"); } @@ -225,8 +225,4 @@ public long calcFee() { return 0; } - private boolean validKey(long idx) { - return idx >= 0 && idx < ChainParameters.values().length; - } - } diff --git a/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java b/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java index 3361ca973d3..e58452cd009 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java @@ -55,13 +55,13 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException long newBalance = accountCapsule.getBalance() - calcFee(); - if (tokenID == "_".getBytes()) { + if (Arrays.equals(tokenID, "_".getBytes())) { accountCapsule.setBalance(newBalance - tokenQuant); } else { accountCapsule.reduceAssetAmount(tokenID, tokenQuant); } - if (anotherTokenID == "_".getBytes()) { + if (Arrays.equals(anotherTokenID, "_".getBytes())) { accountCapsule.setBalance(newBalance + anotherTokenQuant); } else { accountCapsule.addAssetAmount(anotherTokenID, anotherTokenQuant); @@ -146,13 +146,14 @@ public boolean validate() throws ContractValidateException { } long balanceLimit = dbManager.getDynamicPropertiesStore().getExchangeBalanceLimit(); - long tokenBalance = (tokenID == firstTokenID ? firstTokenBalance : secondTokenBalance); + long tokenBalance = (Arrays.equals(tokenID, firstTokenID) ? firstTokenBalance + : secondTokenBalance); tokenBalance += tokenQuant; if (tokenBalance > balanceLimit) { throw new ContractValidateException("token balance must less than " + balanceLimit); } - if (tokenID == "_".getBytes()) { + if (Arrays.equals(tokenID, "_".getBytes())) { if (accountCapsule.getBalance() < (tokenQuant + calcFee())) { throw new ContractValidateException("balance is not enough"); } @@ -181,8 +182,4 @@ public long calcFee() { return 0; } - private boolean validKey(long idx) { - return idx >= 0 && idx < ChainParameters.values().length; - } - } diff --git a/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java b/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java index 301931445cd..ddfb154e8ec 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java @@ -65,13 +65,13 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException long newBalance = accountCapsule.getBalance() - calcFee(); - if (tokenID == "_".getBytes()) { + if (Arrays.equals(tokenID, "_".getBytes())) { accountCapsule.setBalance(newBalance + tokenQuant); } else { accountCapsule.addAssetAmount(tokenID, tokenQuant); } - if (anotherTokenID == "_".getBytes()) { + if (Arrays.equals(anotherTokenID, "_".getBytes())) { accountCapsule.setBalance(newBalance + anotherTokenQuant); } else { accountCapsule.addAssetAmount(anotherTokenID, anotherTokenQuant); @@ -193,8 +193,4 @@ public long calcFee() { return 0; } - private boolean validKey(long idx) { - return idx >= 0 && idx < ChainParameters.values().length; - } - } diff --git a/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java b/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java index dcafa97472c..e5bb8c8f74f 100644 --- a/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java @@ -35,7 +35,7 @@ public class ExchangeInjectActuatorTest { private static AnnotationConfigApplicationContext context; private static Manager dbManager; - private static final String dbPath = "output_ExchangeCreate_test"; + private static final String dbPath = "output_ExchangeInject_test"; private static final String ACCOUNT_NAME_FIRST = "ownerF"; private static final String OWNER_ADDRESS_FIRST; private static final String ACCOUNT_NAME_SECOND = "ownerS"; diff --git a/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java b/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java new file mode 100644 index 00000000000..693edc026db --- /dev/null +++ b/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java @@ -0,0 +1,329 @@ +package org.tron.core.actuator; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import java.io.File; +import java.util.Arrays; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.ExchangeCapsule; +import org.tron.core.capsule.TransactionResultCapsule; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.ItemNotFoundException; +import org.tron.protos.Contract; +import org.tron.protos.Protocol.AccountType; +import org.tron.protos.Protocol.Transaction.Result.code; + +@Slf4j + +public class ExchangeTransactionActuatorTest { + + private static AnnotationConfigApplicationContext context; + private static Manager dbManager; + private static final String dbPath = "output_ExchangeTransaction_test"; + private static final String ACCOUNT_NAME_FIRST = "ownerF"; + private static final String OWNER_ADDRESS_FIRST; + private static final String ACCOUNT_NAME_SECOND = "ownerS"; + private static final String OWNER_ADDRESS_SECOND; + private static final String URL = "https://tron.network"; + private static final String OWNER_ADDRESS_INVALID = "aaaa"; + private static final String OWNER_ADDRESS_NOACCOUNT; + private static final String OWNER_ADDRESS_BALANCENOTSUFFIENT; + + static { + Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + context = new AnnotationConfigApplicationContext(DefaultConfig.class); + OWNER_ADDRESS_FIRST = + Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + OWNER_ADDRESS_SECOND = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; + OWNER_ADDRESS_NOACCOUNT = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1aed"; + OWNER_ADDRESS_BALANCENOTSUFFIENT = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e06d4271a1ced"; + } + + /** + * Init data. + */ + @BeforeClass + public static void init() { + dbManager = context.getBean(Manager.class); + } + + /** + * Release resources. + */ + @AfterClass + public static void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } + + /** + * create temp Capsule test need. + */ + @Before + public void initTest() { + AccountCapsule ownerAccountFirstCapsule = + new AccountCapsule( + ByteString.copyFromUtf8(ACCOUNT_NAME_FIRST), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_FIRST)), + AccountType.Normal, + 10000_000_000L); + AccountCapsule ownerAccountSecondCapsule = + new AccountCapsule( + ByteString.copyFromUtf8(ACCOUNT_NAME_SECOND), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_SECOND)), + AccountType.Normal, + 20000_000_000L); + ExchangeCapsule exchangeCapsule = + new ExchangeCapsule( + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_FIRST)), + 1, + 1000000, + "_".getBytes(), + "abc".getBytes()); + exchangeCapsule.setBalance(1_000_000_000_000L, 10_000_000L); // 1M TRX == 10M abc + + dbManager.getAccountStore() + .put(ownerAccountFirstCapsule.getAddress().toByteArray(), ownerAccountFirstCapsule); + dbManager.getAccountStore() + .put(ownerAccountSecondCapsule.getAddress().toByteArray(), ownerAccountSecondCapsule); + dbManager.getExchangeStore() + .put(exchangeCapsule.createDbKey(), exchangeCapsule); + + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(1000000); + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(10); + dbManager.getDynamicPropertiesStore().saveNextMaintenanceTime(2000000); + } + + private Any getContract(String address, long exchangeId, String tokenId, long quant) { + return Any.pack( + Contract.ExchangeTransactionContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(address))) + .setExchangeId(exchangeId) + .setTokenId(ByteString.copyFrom(tokenId.getBytes())) + .setQuant(quant) + .build()); + } + + /** + * first transaction Exchange,result is success. + */ + @Test + public void successExchangeTransaction() { + long exchangeId = 1; + String tokenId = "_"; + long quant = 100_000_000L; // use 100 TRX to buy abc + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_SECOND); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(20000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(tokenId)); + + ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore() + .get(ByteArray.fromLong(exchangeId)); + Assert.assertNotNull(exchangeCapsule); + long firstTokenBalance = exchangeCapsule.getFirstTokenBalance(); + long secondTokenBalance = exchangeCapsule.getSecondTokenBalance(); + + Assert.assertEquals(exchangeId, exchangeCapsule.getID()); + Assert.assertEquals(tokenId, ByteArray.toStr(exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(1_000_000_000_000L, firstTokenBalance); + Assert.assertEquals("abc", ByteArray.toStr(exchangeCapsule.getSecondTokenId())); + Assert.assertEquals(10_000_000L, secondTokenBalance); + + actuator.validate(); + actuator.execute(ret); + Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + exchangeCapsule = dbManager.getExchangeStore().get(ByteArray.fromLong(exchangeId)); + Assert.assertNotNull(exchangeCapsule); + + Assert.assertEquals(exchangeId, exchangeCapsule.getID()); + Assert.assertEquals(1000000, exchangeCapsule.getCreateTime()); + Assert.assertTrue(Arrays.equals(tokenId.getBytes(), exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(tokenId, ByteArray.toStr(exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(firstTokenBalance + quant, exchangeCapsule.getFirstTokenBalance()); + Assert.assertEquals("abc", ByteArray.toStr(exchangeCapsule.getSecondTokenId())); + Assert.assertEquals(9999001L, exchangeCapsule.getSecondTokenBalance()); + + accountCapsule = dbManager.getAccountStore().get(ownerAddress); + assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(20000_000000L - quant, accountCapsule.getBalance()); + Assert.assertEquals(999L, assetMap.get("abc").longValue()); + + } catch (ContractValidateException e) { + logger.info(e.getMessage()); + Assert.assertFalse(e instanceof ContractValidateException); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } catch (ItemNotFoundException e) { + Assert.assertFalse(e instanceof ItemNotFoundException); + } + } + +// /** +// * use Invalid Address, result is failed, exception is "Invalid address". +// */ +// @Test +// public void invalidAddress() { +// HashMap paras = new HashMap<>(); +// paras.put(0L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_INVALID, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("Invalid address"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Invalid address", e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// } +// +// /** +// * use AccountStore not exists, result is failed, exception is "account not exists". +// */ +// @Test +// public void noAccount() { +// HashMap paras = new HashMap<>(); +// paras.put(0L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_NOACCOUNT, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("account[+OWNER_ADDRESS_NOACCOUNT+] not exists"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("account[" + OWNER_ADDRESS_NOACCOUNT + "] not exists", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// } +// +// /** +// * use WitnessStore not exists Address,result is failed,exception is "witness not exists". +// */ +// @Test +// public void noWitness() { +// HashMap paras = new HashMap<>(); +// paras.put(0L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_SECOND, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("witness[+OWNER_ADDRESS_NOWITNESS+] not exists"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Witness[" + OWNER_ADDRESS_SECOND + "] not exists", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// } +// +// /** +// * use invalid parameter, result is failed, exception is "Bad chain parameter id". +// */ +// @Test +// public void invalidPara() { +// HashMap paras = new HashMap<>(); +// paras.put(17L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("Bad chain parameter id"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Bad chain parameter id", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// +// paras = new HashMap<>(); +// paras.put(3L, 1 + 100_000_000_000_000_000L); +// actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// +// paras = new HashMap<>(); +// paras.put(10L, -1L); +// actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(-1); +// try { +// actuator.validate(); +// fail("This exchange has been executed before and is only allowed to be executed once"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals( +// "This exchange has been executed before and is only allowed to be executed once", +// e.getMessage()); +// } +// +// paras.put(10L, -1L); +// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); +// actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); +// try { +// actuator.validate(); +// fail("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1", +// e.getMessage()); +// } +// } + +} \ No newline at end of file diff --git a/src/test/java/org/tron/core/actuator/ExchangeWithdrawActuatorTest.java b/src/test/java/org/tron/core/actuator/ExchangeWithdrawActuatorTest.java new file mode 100644 index 00000000000..1b5a46fe35b --- /dev/null +++ b/src/test/java/org/tron/core/actuator/ExchangeWithdrawActuatorTest.java @@ -0,0 +1,323 @@ +package org.tron.core.actuator; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import java.io.File; +import java.util.Arrays; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.ExchangeCapsule; +import org.tron.core.capsule.TransactionResultCapsule; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.ItemNotFoundException; +import org.tron.protos.Contract; +import org.tron.protos.Protocol.AccountType; +import org.tron.protos.Protocol.Transaction.Result.code; + +@Slf4j + +public class ExchangeWithdrawActuatorTest { + + private static AnnotationConfigApplicationContext context; + private static Manager dbManager; + private static final String dbPath = "output_ExchangeWithdraw_test"; + private static final String ACCOUNT_NAME_FIRST = "ownerF"; + private static final String OWNER_ADDRESS_FIRST; + private static final String ACCOUNT_NAME_SECOND = "ownerS"; + private static final String OWNER_ADDRESS_SECOND; + private static final String URL = "https://tron.network"; + private static final String OWNER_ADDRESS_INVALID = "aaaa"; + private static final String OWNER_ADDRESS_NOACCOUNT; + private static final String OWNER_ADDRESS_BALANCENOTSUFFIENT; + + static { + Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + context = new AnnotationConfigApplicationContext(DefaultConfig.class); + OWNER_ADDRESS_FIRST = + Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + OWNER_ADDRESS_SECOND = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; + OWNER_ADDRESS_NOACCOUNT = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1aed"; + OWNER_ADDRESS_BALANCENOTSUFFIENT = + Wallet.getAddressPreFixString() + "548794500882809695a8a687866e06d4271a1ced"; + } + + /** + * Init data. + */ + @BeforeClass + public static void init() { + dbManager = context.getBean(Manager.class); + } + + /** + * Release resources. + */ + @AfterClass + public static void destroy() { + Args.clearParam(); + if (FileUtil.deleteDir(new File(dbPath))) { + logger.info("Release resources successful."); + } else { + logger.info("Release resources failure."); + } + context.destroy(); + } + + /** + * create temp Capsule test need. + */ + @Before + public void initTest() { + AccountCapsule ownerAccountFirstCapsule = + new AccountCapsule( + ByteString.copyFromUtf8(ACCOUNT_NAME_FIRST), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_FIRST)), + AccountType.Normal, + 10000_000_000L); + AccountCapsule ownerAccountSecondCapsule = + new AccountCapsule( + ByteString.copyFromUtf8(ACCOUNT_NAME_SECOND), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_SECOND)), + AccountType.Normal, + 20000_000_000L); + ExchangeCapsule exchangeCapsule = + new ExchangeCapsule( + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_FIRST)), + 1, + 1000000, + "abc".getBytes(), + "def".getBytes()); + exchangeCapsule.setBalance(100000000L, 200000000L); + + dbManager.getAccountStore() + .put(ownerAccountFirstCapsule.getAddress().toByteArray(), ownerAccountFirstCapsule); + dbManager.getAccountStore() + .put(ownerAccountSecondCapsule.getAddress().toByteArray(), ownerAccountSecondCapsule); + dbManager.getExchangeStore() + .put(exchangeCapsule.createDbKey(), exchangeCapsule); + + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(1000000); + dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(10); + dbManager.getDynamicPropertiesStore().saveNextMaintenanceTime(2000000); + } + + private Any getContract(String address, long exchangeId, String tokenId, long quant) { + return Any.pack( + Contract.ExchangeWithdrawContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(address))) + .setExchangeId(exchangeId) + .setTokenId(ByteString.copyFrom(tokenId.getBytes())) + .setQuant(quant) + .build()); + } + + /** + * first withdraw Exchange,result is success. + */ + @Test + public void successExchangeWithdraw() { + long exchangeId = 1; + String firstTokenId = "abc"; + long firstTokenQuant = 100000000L; + String secondTokenId = "def"; + long secondTokenQuant = 200000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(10000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(firstTokenId)); + Assert.assertEquals(null, assetMap.get(secondTokenId)); + + ExchangeWithdrawActuator actuator = new ExchangeWithdrawActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + long id = 1; + ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore().get(ByteArray.fromLong(id)); + Assert.assertNotNull(exchangeCapsule); + + Assert.assertEquals(ByteString.copyFrom(ownerAddress), exchangeCapsule.getCreatorAddress()); + Assert.assertEquals(id, exchangeCapsule.getID()); + Assert.assertEquals(1000000, exchangeCapsule.getCreateTime()); + Assert.assertTrue(Arrays.equals(firstTokenId.getBytes(), exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(firstTokenId, ByteArray.toStr(exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(0L, exchangeCapsule.getFirstTokenBalance()); + Assert.assertEquals(secondTokenId, ByteArray.toStr(exchangeCapsule.getSecondTokenId())); + Assert.assertEquals(0L, exchangeCapsule.getSecondTokenBalance()); + + accountCapsule = dbManager.getAccountStore().get(ownerAddress); + assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(10000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(firstTokenQuant, assetMap.get(firstTokenId).longValue()); + Assert.assertEquals(secondTokenQuant, assetMap.get(secondTokenId).longValue()); + + } catch (ContractValidateException e) { + logger.info(e.getMessage()); + Assert.assertFalse(e instanceof ContractValidateException); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } catch (ItemNotFoundException e) { + Assert.assertFalse(e instanceof ItemNotFoundException); + } + } + +// /** +// * use Invalid Address, result is failed, exception is "Invalid address". +// */ +// @Test +// public void invalidAddress() { +// HashMap paras = new HashMap<>(); +// paras.put(0L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_INVALID, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("Invalid address"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Invalid address", e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// } +// +// /** +// * use AccountStore not exists, result is failed, exception is "account not exists". +// */ +// @Test +// public void noAccount() { +// HashMap paras = new HashMap<>(); +// paras.put(0L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_NOACCOUNT, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("account[+OWNER_ADDRESS_NOACCOUNT+] not exists"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("account[" + OWNER_ADDRESS_NOACCOUNT + "] not exists", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// } +// +// /** +// * use WitnessStore not exists Address,result is failed,exception is "witness not exists". +// */ +// @Test +// public void noWitness() { +// HashMap paras = new HashMap<>(); +// paras.put(0L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_SECOND, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("witness[+OWNER_ADDRESS_NOWITNESS+] not exists"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Witness[" + OWNER_ADDRESS_SECOND + "] not exists", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// } +// +// /** +// * use invalid parameter, result is failed, exception is "Bad chain parameter id". +// */ +// @Test +// public void invalidPara() { +// HashMap paras = new HashMap<>(); +// paras.put(17L, 10000L); +// ExchangeCreateActuator actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// TransactionResultCapsule ret = new TransactionResultCapsule(); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("Bad chain parameter id"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Bad chain parameter id", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// +// paras = new HashMap<>(); +// paras.put(3L, 1 + 100_000_000_000_000_000L); +// actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// try { +// actuator.validate(); +// actuator.execute(ret); +// fail("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]", +// e.getMessage()); +// } catch (ContractExeException e) { +// Assert.assertFalse(e instanceof ContractExeException); +// } +// +// paras = new HashMap<>(); +// paras.put(10L, -1L); +// actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(-1); +// try { +// actuator.validate(); +// fail("This exchange has been executed before and is only allowed to be executed once"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals( +// "This exchange has been executed before and is only allowed to be executed once", +// e.getMessage()); +// } +// +// paras.put(10L, -1L); +// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); +// actuator = +// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); +// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); +// try { +// actuator.validate(); +// fail("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1"); +// } catch (ContractValidateException e) { +// Assert.assertTrue(e instanceof ContractValidateException); +// Assert.assertEquals("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1", +// e.getMessage()); +// } +// } + +} \ No newline at end of file From 74dd9671c3b34179effd166d4830d712d7644d28 Mon Sep 17 00:00:00 2001 From: nanfengpo Date: Thu, 23 Aug 2018 15:34:26 +0800 Subject: [PATCH 05/10] minor change --- src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java | 1 - src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java | 1 - .../java/org/tron/core/actuator/ExchangeTransactionActuator.java | 1 - .../java/org/tron/core/actuator/ExchangeWithdrawActuator.java | 1 - 4 files changed, 4 deletions(-) diff --git a/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java b/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java index 31050bc36fa..76660fbaa1a 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeCreateActuator.java @@ -10,7 +10,6 @@ import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.ExchangeCapsule; import org.tron.core.capsule.TransactionResultCapsule; -import org.tron.core.config.Parameter.ChainParameters; import org.tron.core.db.Manager; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; diff --git a/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java b/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java index 4a4a2122e5c..35cf7861d27 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java @@ -11,7 +11,6 @@ import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.ExchangeCapsule; import org.tron.core.capsule.TransactionResultCapsule; -import org.tron.core.config.Parameter.ChainParameters; import org.tron.core.db.Manager; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; diff --git a/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java b/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java index e58452cd009..d2e61827a55 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java @@ -11,7 +11,6 @@ import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.ExchangeCapsule; import org.tron.core.capsule.TransactionResultCapsule; -import org.tron.core.config.Parameter.ChainParameters; import org.tron.core.db.Manager; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; diff --git a/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java b/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java index ddfb154e8ec..09ae34d7579 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java @@ -11,7 +11,6 @@ import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.ExchangeCapsule; import org.tron.core.capsule.TransactionResultCapsule; -import org.tron.core.config.Parameter.ChainParameters; import org.tron.core.db.Manager; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; From d9768241c68b1a6e6fd9a174726a5c6db396383d Mon Sep 17 00:00:00 2001 From: nanfengpo Date: Thu, 23 Aug 2018 17:07:33 +0800 Subject: [PATCH 06/10] test: exchangecreateactuator test --- .../actuator/ExchangeCreateActuatorTest.java | 528 +++++++++++++----- 1 file changed, 393 insertions(+), 135 deletions(-) diff --git a/src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java b/src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java index 9a8695b9bd6..f4284ca91e4 100644 --- a/src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java @@ -1,5 +1,7 @@ package org.tron.core.actuator; +import static org.testng.Assert.fail; + import com.google.protobuf.Any; import com.google.protobuf.ByteString; import java.io.File; @@ -106,6 +108,8 @@ public void initTest() { dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(1000000); dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(10); dbManager.getDynamicPropertiesStore().saveNextMaintenanceTime(2000000); + dbManager.getDynamicPropertiesStore().saveLatestExchangeNum(0); + } private Any getContract(String address, String firstTokenId, long firstTokenBalance, @@ -176,140 +180,394 @@ public void successExchangeCreate() { } } -// /** -// * use Invalid Address, result is failed, exception is "Invalid address". -// */ -// @Test -// public void invalidAddress() { -// HashMap paras = new HashMap<>(); -// paras.put(0L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_INVALID, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("Invalid address"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Invalid address", e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// } -// -// /** -// * use AccountStore not exists, result is failed, exception is "account not exists". -// */ -// @Test -// public void noAccount() { -// HashMap paras = new HashMap<>(); -// paras.put(0L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_NOACCOUNT, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("account[+OWNER_ADDRESS_NOACCOUNT+] not exists"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("account[" + OWNER_ADDRESS_NOACCOUNT + "] not exists", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// } -// -// /** -// * use WitnessStore not exists Address,result is failed,exception is "witness not exists". -// */ -// @Test -// public void noWitness() { -// HashMap paras = new HashMap<>(); -// paras.put(0L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_SECOND, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("witness[+OWNER_ADDRESS_NOWITNESS+] not exists"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Witness[" + OWNER_ADDRESS_SECOND + "] not exists", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// } -// -// /** -// * use invalid parameter, result is failed, exception is "Bad chain parameter id". -// */ -// @Test -// public void invalidPara() { -// HashMap paras = new HashMap<>(); -// paras.put(17L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("Bad chain parameter id"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Bad chain parameter id", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// -// paras = new HashMap<>(); -// paras.put(3L, 1 + 100_000_000_000_000_000L); -// actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// -// paras = new HashMap<>(); -// paras.put(10L, -1L); -// actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(-1); -// try { -// actuator.validate(); -// fail("This exchange has been executed before and is only allowed to be executed once"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals( -// "This exchange has been executed before and is only allowed to be executed once", -// e.getMessage()); -// } -// -// paras.put(10L, -1L); -// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); -// actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); -// try { -// actuator.validate(); -// fail("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1", -// e.getMessage()); -// } -// } + /** + * second create Exchange, result is success. + */ + @Test + public void successExchangeCreate2() { + String firstTokenId = "_"; + long firstTokenBalance = 100_000_000_000000L; + String secondTokenId = "abc"; + long secondTokenBalance = 100_000_000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.setBalance(200_000_000_000000L); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), 200_000_000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeCreateActuator actuator = new ExchangeCreateActuator(getContract( + OWNER_ADDRESS_FIRST, firstTokenId, firstTokenBalance, secondTokenId, secondTokenBalance), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), 0); + try { + actuator.validate(); + actuator.execute(ret); + Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + long id = 1; + ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore().get(ByteArray.fromLong(id)); + Assert.assertNotNull(exchangeCapsule); + Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), id); + + Assert.assertEquals(ByteString.copyFrom(ownerAddress), exchangeCapsule.getCreatorAddress()); + Assert.assertEquals(id, exchangeCapsule.getID()); + Assert.assertEquals(1000000, exchangeCapsule.getCreateTime()); + Assert.assertTrue(Arrays.equals(firstTokenId.getBytes(), exchangeCapsule.getFirstTokenId())); +// Assert.assertEquals(firstTokenId.getBytes(), exchangeCapsule.getFirstTokenId()); + Assert.assertEquals(firstTokenId, ByteArray.toStr(exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(firstTokenBalance, exchangeCapsule.getFirstTokenBalance()); + Assert.assertEquals(secondTokenId, ByteArray.toStr(exchangeCapsule.getSecondTokenId())); + Assert.assertEquals(secondTokenBalance, exchangeCapsule.getSecondTokenBalance()); + + accountCapsule = dbManager.getAccountStore().get(ownerAddress); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(200_000_000_000000L - 1024_000000L - firstTokenBalance, + accountCapsule.getBalance()); + Assert.assertEquals(100_000_000L, assetMap.get(secondTokenId).longValue()); + + } catch (ContractValidateException e) { + Assert.assertFalse(e instanceof ContractValidateException); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } catch (ItemNotFoundException e) { + Assert.assertFalse(e instanceof ItemNotFoundException); + } + } + + /** + * use Invalid Address, result is failed, exception is "Invalid address". + */ + @Test + public void invalidAddress() { + String firstTokenId = "_"; + long firstTokenBalance = 100_000_000_000000L; + String secondTokenId = "abc"; + long secondTokenBalance = 100_000_000L; + + ExchangeCreateActuator actuator = new ExchangeCreateActuator(getContract( + OWNER_ADDRESS_INVALID, firstTokenId, firstTokenBalance, secondTokenId, secondTokenBalance), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), 0); + + try { + actuator.validate(); + actuator.execute(ret); + fail("Invalid address"); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("Invalid address", e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * use AccountStore not exists, result is failed, exception is "account not exists". + */ + @Test + public void noAccount() { + String firstTokenId = "_"; + long firstTokenBalance = 100_000_000_000000L; + String secondTokenId = "abc"; + long secondTokenBalance = 100_000_000L; + + ExchangeCreateActuator actuator = new ExchangeCreateActuator(getContract( + OWNER_ADDRESS_NOACCOUNT, firstTokenId, firstTokenBalance, secondTokenId, + secondTokenBalance), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), 0); + + try { + actuator.validate(); + actuator.execute(ret); + fail("account[+OWNER_ADDRESS_NOACCOUNT+] not exists"); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("account[" + OWNER_ADDRESS_NOACCOUNT + "] not exists", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * No enough balance + */ + @Test + public void noEnoughBalance() { + String firstTokenId = "abc"; + long firstTokenBalance = 100000000L; + String secondTokenId = "def"; + long secondTokenBalance = 100000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenBalance); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenBalance); + accountCapsule.setBalance(1000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeCreateActuator actuator = new ExchangeCreateActuator(getContract( + OWNER_ADDRESS_FIRST, firstTokenId, firstTokenBalance, secondTokenId, secondTokenBalance), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), 0); + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("No enough balance for exchange create fee!", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * exchange same tokens + */ + @Test + public void sameTokens() { + String firstTokenId = "abc"; + long firstTokenBalance = 100000000L; + String secondTokenId = "abc"; + long secondTokenBalance = 100000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenBalance); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenBalance); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeCreateActuator actuator = new ExchangeCreateActuator(getContract( + OWNER_ADDRESS_FIRST, firstTokenId, firstTokenBalance, secondTokenId, secondTokenBalance), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), 0); + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("cannot exchange same tokens", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * token balance less than zero + */ + @Test + public void lessToken() { + String firstTokenId = "abc"; + long firstTokenBalance = 0L; + String secondTokenId = "def"; + long secondTokenBalance = 0L; + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), 1000); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), 1000); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeCreateActuator actuator = new ExchangeCreateActuator(getContract( + OWNER_ADDRESS_FIRST, firstTokenId, firstTokenBalance, secondTokenId, secondTokenBalance), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), 0); + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("token balance must greater than zero", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * token balance must less than balanceLimit + */ + @Test + public void moreThanBalanceLimit() { + String firstTokenId = "abc"; + long firstTokenBalance = 1_000_000_000_000_001L; + String secondTokenId = "def"; + long secondTokenBalance = 100000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenBalance); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenBalance); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeCreateActuator actuator = new ExchangeCreateActuator(getContract( + OWNER_ADDRESS_FIRST, firstTokenId, firstTokenBalance, secondTokenId, secondTokenBalance), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), 0); + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("token balance must less than 1000000000000000", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * balance is not enough + */ + @Test + public void balanceNotEnough() { + String firstTokenId = "_"; + long firstTokenBalance = 100_000_000_000000L; + String secondTokenId = "abc"; + long secondTokenBalance = 100_000_000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.setBalance(firstTokenBalance + 1000L); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), 200_000_000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeCreateActuator actuator = new ExchangeCreateActuator(getContract( + OWNER_ADDRESS_FIRST, firstTokenId, firstTokenBalance, secondTokenId, secondTokenBalance), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), 0); + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("balance is not enough", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * first token balance is not enough + */ + @Test + public void firstTokenBalanceNotEnough() { + String firstTokenId = "abc"; + long firstTokenBalance = 100_000_000_000000L; + String secondTokenId = "def"; + long secondTokenBalance = 100_000_000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenBalance - 1000L); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), 200_000_000L); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeCreateActuator actuator = new ExchangeCreateActuator(getContract( + OWNER_ADDRESS_FIRST, firstTokenId, firstTokenBalance, secondTokenId, secondTokenBalance), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), 0); + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("first token balance is not enough", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * balance is not enough + */ + @Test + public void balanceNotEnough2() { + String firstTokenId = "abc"; + long firstTokenBalance = 100_000_000L; + String secondTokenId = "_"; + long secondTokenBalance = 100_000_000_000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.setBalance(secondTokenBalance + 1000L); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), 200_000_000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeCreateActuator actuator = new ExchangeCreateActuator(getContract( + OWNER_ADDRESS_FIRST, firstTokenId, firstTokenBalance, secondTokenId, secondTokenBalance), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), 0); + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("balance is not enough", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * first token balance is not enough + */ + @Test + public void secondTokenBalanceNotEnough() { + String firstTokenId = "abc"; + long firstTokenBalance = 100_000_000_000000L; + String secondTokenId = "def"; + long secondTokenBalance = 100_000_000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenBalance); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), 90_000_000L); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeCreateActuator actuator = new ExchangeCreateActuator(getContract( + OWNER_ADDRESS_FIRST, firstTokenId, firstTokenBalance, secondTokenId, secondTokenBalance), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + Assert.assertEquals(dbManager.getDynamicPropertiesStore().getLatestExchangeNum(), 0); + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("second token balance is not enough", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } } \ No newline at end of file From a602185cf80cd2f3c6bebf02b5ad60355836ddc6 Mon Sep 17 00:00:00 2001 From: nanfengpo Date: Thu, 23 Aug 2018 19:41:21 +0800 Subject: [PATCH 07/10] test: exchangeinjectactuator test --- .../core/actuator/ExchangeInjectActuator.java | 20 +- .../actuator/ExchangeWithdrawActuator.java | 16 +- .../actuator/ExchangeInjectActuatorTest.java | 651 ++++++++++++++---- .../capsule/utils/ExchangeProcessorTest.java | 36 + 4 files changed, 578 insertions(+), 145 deletions(-) diff --git a/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java b/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java index 35cf7861d27..e1fa57ee0e7 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java @@ -3,6 +3,7 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; +import java.math.BigInteger; import java.util.Arrays; import lombok.extern.slf4j.Slf4j; import org.tron.common.utils.ByteArray; @@ -163,26 +164,33 @@ public boolean validate() throws ContractValidateException { } if (tokenQuant <= 0) { - throw new ContractValidateException("injected token balance must greater than zero"); + throw new ContractValidateException("injected token quant must greater than zero"); } + BigInteger bigFirstTokenBalance = new BigInteger(String.valueOf(firstTokenBalance)); + BigInteger bigSecondTokenBalance = new BigInteger(String.valueOf(secondTokenBalance)); + BigInteger bigTokenQuant = new BigInteger(String.valueOf(tokenQuant)); long newTokenBalance, newAnotherTokenBalance; if (Arrays.equals(tokenID, firstTokenID)) { anotherTokenID = secondTokenID; - anotherTokenQuant = Math - .floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance); +// anotherTokenQuant = Math +// .floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance); + anotherTokenQuant = bigSecondTokenBalance.multiply(bigTokenQuant) + .divide(bigFirstTokenBalance).longValue(); newTokenBalance = firstTokenBalance + tokenQuant; newAnotherTokenBalance = secondTokenBalance + anotherTokenQuant; } else { anotherTokenID = firstTokenID; - anotherTokenQuant = Math - .floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance); +// anotherTokenQuant = Math +// .floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance); + anotherTokenQuant = bigFirstTokenBalance.multiply(bigTokenQuant) + .divide(bigSecondTokenBalance).longValue(); newTokenBalance = secondTokenBalance + tokenQuant; newAnotherTokenBalance = firstTokenBalance + anotherTokenQuant; } if (anotherTokenQuant <= 0) { - throw new ContractValidateException(" The calculated Token Quant must be larger than 0"); + throw new ContractValidateException("the calculated token quant must be greater than 0"); } long balanceLimit = dbManager.getDynamicPropertiesStore().getExchangeBalanceLimit(); diff --git a/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java b/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java index 09ae34d7579..0e61ecbd33d 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java @@ -3,6 +3,7 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; +import java.math.BigInteger; import java.util.Arrays; import lombok.extern.slf4j.Slf4j; import org.tron.common.utils.ByteArray; @@ -48,16 +49,23 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException byte[] anotherTokenID; long anotherTokenQuant; + BigInteger bigFirstTokenBalance = new BigInteger(String.valueOf(firstTokenBalance)); + BigInteger bigSecondTokenBalance = new BigInteger(String.valueOf(secondTokenBalance)); + BigInteger bigTokenQuant = new BigInteger(String.valueOf(tokenQuant)); if (Arrays.equals(tokenID, firstTokenID)) { anotherTokenID = secondTokenID; - anotherTokenQuant = Math - .floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance); +// anotherTokenQuant = Math +// .floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance); + anotherTokenQuant = bigSecondTokenBalance.multiply(bigTokenQuant) + .divide(bigFirstTokenBalance).longValue(); exchangeCapsule.setBalance(firstTokenBalance - tokenQuant, secondTokenBalance - anotherTokenQuant); } else { anotherTokenID = firstTokenID; - anotherTokenQuant = Math - .floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance); +// anotherTokenQuant = Math +// .floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance); + anotherTokenQuant = bigFirstTokenBalance.multiply(bigTokenQuant) + .divide(bigSecondTokenBalance).longValue(); exchangeCapsule.setBalance(firstTokenBalance - anotherTokenQuant, secondTokenBalance - tokenQuant); } diff --git a/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java b/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java index e5bb8c8f74f..c2751feb1b7 100644 --- a/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java @@ -1,5 +1,7 @@ package org.tron.core.actuator; +import static org.testng.Assert.fail; + import com.google.protobuf.Any; import com.google.protobuf.ByteString; import java.io.File; @@ -105,6 +107,14 @@ public void initTest() { "abc".getBytes(), "def".getBytes()); exchangeCapsule.setBalance(100000000L, 200000000L); + ExchangeCapsule exchangeCapsule2 = + new ExchangeCapsule( + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_FIRST)), + 2, + 1000000, + "_".getBytes(), + "def".getBytes()); + exchangeCapsule2.setBalance(1_000_000_000000L, 10_000_000L); dbManager.getAccountStore() .put(ownerAccountFirstCapsule.getAddress().toByteArray(), ownerAccountFirstCapsule); @@ -112,6 +122,8 @@ public void initTest() { .put(ownerAccountSecondCapsule.getAddress().toByteArray(), ownerAccountSecondCapsule); dbManager.getExchangeStore() .put(exchangeCapsule.createDbKey(), exchangeCapsule); + dbManager.getExchangeStore() + .put(exchangeCapsule2.createDbKey(), exchangeCapsule2); dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(1000000); dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(10); @@ -184,140 +196,509 @@ public void successExchangeInject() { } } -// /** -// * use Invalid Address, result is failed, exception is "Invalid address". -// */ -// @Test -// public void invalidAddress() { -// HashMap paras = new HashMap<>(); -// paras.put(0L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_INVALID, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("Invalid address"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Invalid address", e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// } -// -// /** -// * use AccountStore not exists, result is failed, exception is "account not exists". -// */ -// @Test -// public void noAccount() { -// HashMap paras = new HashMap<>(); -// paras.put(0L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_NOACCOUNT, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("account[+OWNER_ADDRESS_NOACCOUNT+] not exists"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("account[" + OWNER_ADDRESS_NOACCOUNT + "] not exists", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// } -// -// /** -// * use WitnessStore not exists Address,result is failed,exception is "witness not exists". -// */ -// @Test -// public void noWitness() { -// HashMap paras = new HashMap<>(); -// paras.put(0L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_SECOND, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("witness[+OWNER_ADDRESS_NOWITNESS+] not exists"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Witness[" + OWNER_ADDRESS_SECOND + "] not exists", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// } -// -// /** -// * use invalid parameter, result is failed, exception is "Bad chain parameter id". -// */ -// @Test -// public void invalidPara() { -// HashMap paras = new HashMap<>(); -// paras.put(17L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("Bad chain parameter id"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Bad chain parameter id", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// -// paras = new HashMap<>(); -// paras.put(3L, 1 + 100_000_000_000_000_000L); -// actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// -// paras = new HashMap<>(); -// paras.put(10L, -1L); -// actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(-1); -// try { -// actuator.validate(); -// fail("This exchange has been executed before and is only allowed to be executed once"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals( -// "This exchange has been executed before and is only allowed to be executed once", -// e.getMessage()); -// } -// -// paras.put(10L, -1L); -// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); -// actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); -// try { -// actuator.validate(); -// fail("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1", -// e.getMessage()); -// } -// } + /** + * second inject Exchange,result is success. + */ + @Test + public void successExchangeInject2() { + long exchangeId = 2; + String firstTokenId = "_"; + long firstTokenQuant = 100_000_000000L; + String secondTokenId = "def"; + long secondTokenQuant = 4_000_000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(firstTokenQuant); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeInjectActuator actuator = new ExchangeInjectActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore() + .get(ByteArray.fromLong(exchangeId)); + Assert.assertNotNull(exchangeCapsule); + + Assert.assertEquals(ByteString.copyFrom(ownerAddress), exchangeCapsule.getCreatorAddress()); + Assert.assertEquals(exchangeId, exchangeCapsule.getID()); + Assert.assertEquals(1000000, exchangeCapsule.getCreateTime()); + Assert.assertTrue(Arrays.equals(firstTokenId.getBytes(), exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(firstTokenId, ByteArray.toStr(exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(1_100_000_000000L, exchangeCapsule.getFirstTokenBalance()); + Assert.assertEquals(secondTokenId, ByteArray.toStr(exchangeCapsule.getSecondTokenId())); + Assert.assertEquals(11_000_000L, exchangeCapsule.getSecondTokenBalance()); + + accountCapsule = dbManager.getAccountStore().get(ownerAddress); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(0L, accountCapsule.getBalance()); + Assert.assertEquals(3_000_000L, assetMap.get(secondTokenId).longValue()); + + } catch (ContractValidateException e) { + logger.info(e.getMessage()); + Assert.assertFalse(e instanceof ContractValidateException); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } catch (ItemNotFoundException e) { + Assert.assertFalse(e instanceof ItemNotFoundException); + } + } + + /** + * use Invalid Address, result is failed, exception is "Invalid address". + */ + @Test + public void invalidAddress() { + long exchangeId = 1; + String firstTokenId = "abc"; + long firstTokenQuant = 200000000L; + + ExchangeInjectActuator actuator = new ExchangeInjectActuator(getContract( + OWNER_ADDRESS_INVALID, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail("Invalid address"); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("Invalid address", e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * use AccountStore not exists, result is failed, exception is "account not exists". + */ + @Test + public void noAccount() { + long exchangeId = 1; + String firstTokenId = "abc"; + long firstTokenQuant = 200000000L; + + ExchangeInjectActuator actuator = new ExchangeInjectActuator(getContract( + OWNER_ADDRESS_NOACCOUNT, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail("account[+OWNER_ADDRESS_NOACCOUNT+] not exists"); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("account[" + OWNER_ADDRESS_NOACCOUNT + "] not exists", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * Exchange not exists + */ + @Test + public void exchangeNotExist() { + long exchangeId = 3; + String firstTokenId = "abc"; + long firstTokenQuant = 200000000L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenQuant); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeInjectActuator actuator = new ExchangeInjectActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail("Exchange not exists"); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("Exchange[3] not exists", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * account[" + readableOwnerAddress + "] is not creator + */ + @Test + public void accountIsNotCreator() { + long exchangeId = 1; + String firstTokenId = "abc"; + long firstTokenQuant = 200000000L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_SECOND); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenQuant); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeInjectActuator actuator = new ExchangeInjectActuator(getContract( + OWNER_ADDRESS_SECOND, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("account[a0548794500882809695a8a687866e76d4271a1abc]" + + " is not creator", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * token is not in exchange + */ + @Test + public void tokenIsNotInExchange() { + long exchangeId = 1; + String firstTokenId = "_"; + long firstTokenQuant = 200000000L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(firstTokenQuant); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeInjectActuator actuator = new ExchangeInjectActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("token is not in exchange", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * Token balance in exchange is equal with 0, the exchange has been closed" + */ + @Test + public void tokenBalanceZero() { + long exchangeId = 1; + String firstTokenId = "abc"; + long firstTokenQuant = 200000000L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenQuant); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeInjectActuator actuator = new ExchangeInjectActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore() + .get(ByteArray.fromLong(exchangeId)); + exchangeCapsule.setBalance(0, 0); + dbManager.getExchangeStore().put(exchangeCapsule.createDbKey(), exchangeCapsule); + + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("Token balance in exchange is equal with 0," + + "the exchange has been closed", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } catch (ItemNotFoundException e) { + Assert.assertFalse(e instanceof ItemNotFoundException); + } + } + + /** + * injected token quant must greater than zero + */ + @Test + public void tokenQuantLessThanZero() { + long exchangeId = 1; + String firstTokenId = "abc"; + long firstTokenQuant = -1L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), 1000L); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeInjectActuator actuator = new ExchangeInjectActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("injected token quant must greater than zero", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * "the calculated token quant must be greater than 0" + */ + @Test + public void calculatedTokenQuantLessThanZero() { + long exchangeId = 2; + String firstTokenId = "_"; + long firstTokenQuant = 100L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(firstTokenQuant); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeInjectActuator actuator = new ExchangeInjectActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("the calculated token quant must be greater than 0", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * token balance must less than balanceLimit + */ + @Test + public void tokenBalanceGreaterThanBalanceLimit() { + long exchangeId = 2; + String firstTokenId = "_"; + long firstTokenQuant = 1_000_000_000_000_001L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(firstTokenQuant); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeInjectActuator actuator = new ExchangeInjectActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("token balance must less than 1000000000000000", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * balance is not enough + */ + @Test + public void balanceNotEnough() { + long exchangeId = 2; + String firstTokenId = "_"; + long firstTokenQuant = 100_000000L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(firstTokenQuant - 1); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeInjectActuator actuator = new ExchangeInjectActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("balance is not enough", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * first token balance is not enough + */ + @Test + public void tokenBalanceNotEnough() { + long exchangeId = 1; + String firstTokenId = "abc"; + long firstTokenQuant = 200000000L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenQuant - 1); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeInjectActuator actuator = new ExchangeInjectActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("token balance is not enough", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * balance is not enough + */ + @Test + public void balanceNotEnough2() { + long exchangeId = 2; + String secondTokenId = "def"; + long secondTokenQuant = 4000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(399_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeInjectActuator actuator = new ExchangeInjectActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, secondTokenId, secondTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("balance is not enough", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * first token balance is not enough + */ + @Test + public void anotherTokenBalanceNotEnough() { + long exchangeId = 1; + String firstTokenId = "abc"; + long firstTokenQuant = 200000000L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenQuant - 1); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeInjectActuator actuator = new ExchangeInjectActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, secondTokenId, secondTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("another token balance is not enough", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } } \ No newline at end of file diff --git a/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java b/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java index c9839b8dc1a..6d8522b6a59 100644 --- a/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java +++ b/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java @@ -131,5 +131,41 @@ public void testSellAndBuy2() { } + @Test + public void testInject() { + long sellBalance = 1_000_000_000000L; + long buyBalance = 10_000_000L; + long sellQuant = 10_000_000L; // 10 trx + + long result = processor.exchange(sellBalance, buyBalance, sellQuant); + Assert.assertEquals(99L, result); + + // inject + sellBalance += 100_000_000000L; + buyBalance += 1_000_000L; + + long result2 = processor.exchange(sellBalance, buyBalance, sellQuant); + Assert.assertEquals(99L, result2); + + } + + @Test + public void testWithdraw() { + long sellBalance = 1_000_000_000000L; + long buyBalance = 10_000_000L; + long sellQuant = 10_000_000L; // 10 trx + + long result = processor.exchange(sellBalance, buyBalance, sellQuant); + Assert.assertEquals(99L, result); + + // inject + sellBalance -= 800_000_000000L; + buyBalance -= 8_000_000L; + + long result2 = processor.exchange(sellBalance, buyBalance, sellQuant); + Assert.assertEquals(99L, result2); + + } + } From ff6db872096a139f89d0862c79ea6f1d1711eca3 Mon Sep 17 00:00:00 2001 From: nanfengpo Date: Thu, 23 Aug 2018 20:43:46 +0800 Subject: [PATCH 08/10] fix: use BigInteger in exchange inject and withdraw; test: exchangewithdrawactuator test --- .../actuator/ExchangeWithdrawActuator.java | 20 +- .../ExchangeWithdrawActuatorTest.java | 529 +++++++++++++----- 2 files changed, 408 insertions(+), 141 deletions(-) diff --git a/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java b/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java index 0e61ecbd33d..98682a69476 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java @@ -165,22 +165,30 @@ public boolean validate() throws ContractValidateException { } if (tokenQuant <= 0) { - throw new ContractValidateException("withdraw token balance must greater than zero"); + throw new ContractValidateException("withdraw token quant must greater than zero"); } if (firstTokenBalance == 0 || secondTokenBalance == 0) { - throw new ContractValidateException("Token balance in exchange is equal with 0,the exchange has been closed"); + throw new ContractValidateException("Token balance in exchange is equal with 0," + + "the exchange has been closed"); } + BigInteger bigFirstTokenBalance = new BigInteger(String.valueOf(firstTokenBalance)); + BigInteger bigSecondTokenBalance = new BigInteger(String.valueOf(secondTokenBalance)); + BigInteger bigTokenQuant = new BigInteger(String.valueOf(tokenQuant)); if (Arrays.equals(tokenID, firstTokenID)) { - anotherTokenQuant = Math - .floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance); +// anotherTokenQuant = Math +// .floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance); + anotherTokenQuant = bigSecondTokenBalance.multiply(bigTokenQuant) + .divide(bigFirstTokenBalance).longValue(); if (firstTokenBalance < tokenQuant || secondTokenBalance < anotherTokenQuant) { throw new ContractValidateException("exchange balance is not enough"); } } else { - anotherTokenQuant = Math - .floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance); +// anotherTokenQuant = Math +// .floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance); + anotherTokenQuant = bigFirstTokenBalance.multiply(bigTokenQuant) + .divide(bigSecondTokenBalance).longValue(); if (secondTokenBalance < tokenQuant || firstTokenBalance < anotherTokenQuant) { throw new ContractValidateException("exchange balance is not enough"); } diff --git a/src/test/java/org/tron/core/actuator/ExchangeWithdrawActuatorTest.java b/src/test/java/org/tron/core/actuator/ExchangeWithdrawActuatorTest.java index 1b5a46fe35b..3a0bcfea2ba 100644 --- a/src/test/java/org/tron/core/actuator/ExchangeWithdrawActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/ExchangeWithdrawActuatorTest.java @@ -1,5 +1,7 @@ package org.tron.core.actuator; +import static org.testng.Assert.fail; + import com.google.protobuf.Any; import com.google.protobuf.ByteString; import java.io.File; @@ -105,6 +107,14 @@ public void initTest() { "abc".getBytes(), "def".getBytes()); exchangeCapsule.setBalance(100000000L, 200000000L); + ExchangeCapsule exchangeCapsule2 = + new ExchangeCapsule( + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_FIRST)), + 2, + 1000000, + "_".getBytes(), + "def".getBytes()); + exchangeCapsule2.setBalance(1_000_000_000000L, 10_000_000L); dbManager.getAccountStore() .put(ownerAccountFirstCapsule.getAddress().toByteArray(), ownerAccountFirstCapsule); @@ -112,6 +122,8 @@ public void initTest() { .put(ownerAccountSecondCapsule.getAddress().toByteArray(), ownerAccountSecondCapsule); dbManager.getExchangeStore() .put(exchangeCapsule.createDbKey(), exchangeCapsule); + dbManager.getExchangeStore() + .put(exchangeCapsule2.createDbKey(), exchangeCapsule2); dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(1000000); dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(10); @@ -184,140 +196,387 @@ public void successExchangeWithdraw() { } } -// /** -// * use Invalid Address, result is failed, exception is "Invalid address". -// */ -// @Test -// public void invalidAddress() { -// HashMap paras = new HashMap<>(); -// paras.put(0L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_INVALID, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("Invalid address"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Invalid address", e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// } -// -// /** -// * use AccountStore not exists, result is failed, exception is "account not exists". -// */ -// @Test -// public void noAccount() { -// HashMap paras = new HashMap<>(); -// paras.put(0L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_NOACCOUNT, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("account[+OWNER_ADDRESS_NOACCOUNT+] not exists"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("account[" + OWNER_ADDRESS_NOACCOUNT + "] not exists", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// } -// -// /** -// * use WitnessStore not exists Address,result is failed,exception is "witness not exists". -// */ -// @Test -// public void noWitness() { -// HashMap paras = new HashMap<>(); -// paras.put(0L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_SECOND, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("witness[+OWNER_ADDRESS_NOWITNESS+] not exists"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Witness[" + OWNER_ADDRESS_SECOND + "] not exists", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// } -// -// /** -// * use invalid parameter, result is failed, exception is "Bad chain parameter id". -// */ -// @Test -// public void invalidPara() { -// HashMap paras = new HashMap<>(); -// paras.put(17L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("Bad chain parameter id"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Bad chain parameter id", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// -// paras = new HashMap<>(); -// paras.put(3L, 1 + 100_000_000_000_000_000L); -// actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// -// paras = new HashMap<>(); -// paras.put(10L, -1L); -// actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(-1); -// try { -// actuator.validate(); -// fail("This exchange has been executed before and is only allowed to be executed once"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals( -// "This exchange has been executed before and is only allowed to be executed once", -// e.getMessage()); -// } -// -// paras.put(10L, -1L); -// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); -// actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); -// try { -// actuator.validate(); -// fail("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1", -// e.getMessage()); -// } -// } + /** + * second withdraw Exchange,result is success. + */ + @Test + public void successExchangeWithdraw2() { + long exchangeId = 2; + String firstTokenId = "_"; + long firstTokenQuant = 1_000_000_000000L; + String secondTokenId = "def"; + long secondTokenQuant = 4_000_000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(10000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(secondTokenId)); + + ExchangeWithdrawActuator actuator = new ExchangeWithdrawActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore() + .get(ByteArray.fromLong(exchangeId)); + Assert.assertNotNull(exchangeCapsule); + + Assert.assertEquals(ByteString.copyFrom(ownerAddress), exchangeCapsule.getCreatorAddress()); + Assert.assertEquals(exchangeId, exchangeCapsule.getID()); + Assert.assertEquals(1000000, exchangeCapsule.getCreateTime()); + Assert.assertTrue(Arrays.equals(firstTokenId.getBytes(), exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(firstTokenId, ByteArray.toStr(exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(0L, exchangeCapsule.getFirstTokenBalance()); + Assert.assertEquals(secondTokenId, ByteArray.toStr(exchangeCapsule.getSecondTokenId())); + Assert.assertEquals(0L, exchangeCapsule.getSecondTokenBalance()); + + accountCapsule = dbManager.getAccountStore().get(ownerAddress); + assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(firstTokenQuant + 10000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(10_000_000L, assetMap.get(secondTokenId).longValue()); + + } catch (ContractValidateException e) { + logger.info(e.getMessage()); + Assert.assertFalse(e instanceof ContractValidateException); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } catch (ItemNotFoundException e) { + Assert.assertFalse(e instanceof ItemNotFoundException); + } + } + + /** + * use Invalid Address, result is failed, exception is "Invalid address". + */ + @Test + public void invalidAddress() { + long exchangeId = 1; + String firstTokenId = "abc"; + long firstTokenQuant = 100000000L; + String secondTokenId = "def"; + long secondTokenQuant = 200000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(10000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(firstTokenId)); + Assert.assertEquals(null, assetMap.get(secondTokenId)); + + ExchangeWithdrawActuator actuator = new ExchangeWithdrawActuator(getContract( + OWNER_ADDRESS_INVALID, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail("Invalid address"); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("Invalid address", e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * use AccountStore not exists, result is failed, exception is "account not exists". + */ + @Test + public void noAccount() { + long exchangeId = 1; + String firstTokenId = "abc"; + long firstTokenQuant = 100000000L; + String secondTokenId = "def"; + long secondTokenQuant = 200000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(10000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(firstTokenId)); + Assert.assertEquals(null, assetMap.get(secondTokenId)); + + ExchangeWithdrawActuator actuator = new ExchangeWithdrawActuator(getContract( + OWNER_ADDRESS_NOACCOUNT, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail("account[+OWNER_ADDRESS_NOACCOUNT+] not exists"); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("account[" + OWNER_ADDRESS_NOACCOUNT + "] not exists", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * Exchange not exists + */ + @Test + public void exchangeNotExist() { + long exchangeId = 3; + String firstTokenId = "abc"; + long firstTokenQuant = 100000000L; + String secondTokenId = "def"; + long secondTokenQuant = 200000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(10000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(firstTokenId)); + Assert.assertEquals(null, assetMap.get(secondTokenId)); + + ExchangeWithdrawActuator actuator = new ExchangeWithdrawActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail("Exchange not exists"); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("Exchange[3] not exists", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * account is not creator + */ + @Test + public void accountIsNotCreator() { + long exchangeId = 1; + String firstTokenId = "abc"; + long firstTokenQuant = 200000000L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_SECOND); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenQuant); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeWithdrawActuator actuator = new ExchangeWithdrawActuator(getContract( + OWNER_ADDRESS_SECOND, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("account[a0548794500882809695a8a687866e76d4271a1abc]" + + " is not creator", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * token is not in exchange + */ + @Test + public void tokenIsNotInExchange() { + long exchangeId = 1; + String firstTokenId = "_"; + long firstTokenQuant = 200000000L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(firstTokenQuant); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeWithdrawActuator actuator = new ExchangeWithdrawActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("token is not in exchange", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * Token balance in exchange is equal with 0, the exchange has been closed" + */ + @Test + public void tokenBalanceZero() { + long exchangeId = 1; + String firstTokenId = "abc"; + long firstTokenQuant = 200000000L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), firstTokenQuant); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeWithdrawActuator actuator = new ExchangeWithdrawActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore() + .get(ByteArray.fromLong(exchangeId)); + exchangeCapsule.setBalance(0, 0); + dbManager.getExchangeStore().put(exchangeCapsule.createDbKey(), exchangeCapsule); + + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("Token balance in exchange is equal with 0," + + "the exchange has been closed", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } catch (ItemNotFoundException e) { + Assert.assertFalse(e instanceof ItemNotFoundException); + } + } + + /** + * withdraw token quant must greater than zero + */ + @Test + public void tokenQuantLessThanZero() { + long exchangeId = 1; + String firstTokenId = "abc"; + long firstTokenQuant = -1L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(firstTokenId.getBytes(), 1000L); + accountCapsule.addAssetAmount(secondTokenId.getBytes(), secondTokenQuant); + accountCapsule.setBalance(10000_000000L); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeWithdrawActuator actuator = new ExchangeWithdrawActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("withdraw token quant must greater than zero", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * exchange balance is not enough + */ + @Test + public void exchangeBalanceIsNotEnough() { + long exchangeId = 1; + String firstTokenId = "abc"; + long firstTokenQuant = 100_000_001L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(10000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(firstTokenId)); + Assert.assertEquals(null, assetMap.get(secondTokenId)); + + ExchangeWithdrawActuator actuator = new ExchangeWithdrawActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("exchange balance is not enough", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * exchange balance is not enough + */ + @Test + public void exchangeBalanceIsNotEnough2() { + long exchangeId = 2; + String firstTokenId = "_"; + long firstTokenQuant = 1000_000_000001L; + String secondTokenId = "def"; + long secondTokenQuant = 400000000L; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_FIRST); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(10000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(secondTokenId)); + + ExchangeWithdrawActuator actuator = new ExchangeWithdrawActuator(getContract( + OWNER_ADDRESS_FIRST, exchangeId, firstTokenId, firstTokenQuant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("exchange balance is not enough", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } } \ No newline at end of file From 64c236ac5c54591c103cefc51c74838e33a75e9b Mon Sep 17 00:00:00 2001 From: nanfengpo Date: Thu, 23 Aug 2018 21:30:11 +0800 Subject: [PATCH 09/10] test: exchangetransactionactuator test --- .../actuator/ExchangeTransactionActuator.java | 5 + .../actuator/ExchangeInjectActuatorTest.java | 2 +- .../ExchangeTransactionActuatorTest.java | 542 +++++++++++++----- 3 files changed, 412 insertions(+), 137 deletions(-) diff --git a/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java b/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java index d2e61827a55..481fae4dc0d 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java @@ -144,6 +144,11 @@ public boolean validate() throws ContractValidateException { throw new ContractValidateException("transaction token balance must greater than zero"); } + if (firstTokenBalance == 0 || secondTokenBalance == 0) { + throw new ContractValidateException("Token balance in exchange is equal with 0," + + "the exchange has been closed"); + } + long balanceLimit = dbManager.getDynamicPropertiesStore().getExchangeBalanceLimit(); long tokenBalance = (Arrays.equals(tokenID, firstTokenID) ? firstTokenBalance : secondTokenBalance); diff --git a/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java b/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java index c2751feb1b7..5f852cb8d04 100644 --- a/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java @@ -633,7 +633,7 @@ public void tokenBalanceNotEnough() { } /** - * balance is not enough + * balance is not enough2 */ @Test public void balanceNotEnough2() { diff --git a/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java b/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java index 693edc026db..edea2de6f39 100644 --- a/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java @@ -1,5 +1,7 @@ package org.tron.core.actuator; +import static org.testng.Assert.fail; + import com.google.protobuf.Any; import com.google.protobuf.ByteString; import java.io.File; @@ -105,6 +107,14 @@ public void initTest() { "_".getBytes(), "abc".getBytes()); exchangeCapsule.setBalance(1_000_000_000_000L, 10_000_000L); // 1M TRX == 10M abc + ExchangeCapsule exchangeCapsule2 = + new ExchangeCapsule( + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS_FIRST)), + 2, + 1000000, + "abc".getBytes(), + "def".getBytes()); + exchangeCapsule2.setBalance(100000000L, 200000000L); dbManager.getAccountStore() .put(ownerAccountFirstCapsule.getAddress().toByteArray(), ownerAccountFirstCapsule); @@ -112,6 +122,8 @@ public void initTest() { .put(ownerAccountSecondCapsule.getAddress().toByteArray(), ownerAccountSecondCapsule); dbManager.getExchangeStore() .put(exchangeCapsule.createDbKey(), exchangeCapsule); + dbManager.getExchangeStore() + .put(exchangeCapsule2.createDbKey(), exchangeCapsule2); dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(1000000); dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(10); @@ -141,7 +153,7 @@ public void successExchangeTransaction() { AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); Map assetMap = accountCapsule.getAssetMap(); Assert.assertEquals(20000_000000L, accountCapsule.getBalance()); - Assert.assertEquals(null, assetMap.get(tokenId)); + Assert.assertEquals(null, assetMap.get("def")); ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), @@ -190,140 +202,398 @@ public void successExchangeTransaction() { } } -// /** -// * use Invalid Address, result is failed, exception is "Invalid address". -// */ -// @Test -// public void invalidAddress() { -// HashMap paras = new HashMap<>(); -// paras.put(0L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_INVALID, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("Invalid address"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Invalid address", e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// } -// -// /** -// * use AccountStore not exists, result is failed, exception is "account not exists". -// */ -// @Test -// public void noAccount() { -// HashMap paras = new HashMap<>(); -// paras.put(0L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_NOACCOUNT, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("account[+OWNER_ADDRESS_NOACCOUNT+] not exists"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("account[" + OWNER_ADDRESS_NOACCOUNT + "] not exists", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// } -// -// /** -// * use WitnessStore not exists Address,result is failed,exception is "witness not exists". -// */ -// @Test -// public void noWitness() { -// HashMap paras = new HashMap<>(); -// paras.put(0L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_SECOND, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("witness[+OWNER_ADDRESS_NOWITNESS+] not exists"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Witness[" + OWNER_ADDRESS_SECOND + "] not exists", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// } -// -// /** -// * use invalid parameter, result is failed, exception is "Bad chain parameter id". -// */ -// @Test -// public void invalidPara() { -// HashMap paras = new HashMap<>(); -// paras.put(17L, 10000L); -// ExchangeCreateActuator actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// TransactionResultCapsule ret = new TransactionResultCapsule(); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("Bad chain parameter id"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Bad chain parameter id", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// -// paras = new HashMap<>(); -// paras.put(3L, 1 + 100_000_000_000_000_000L); -// actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// try { -// actuator.validate(); -// actuator.execute(ret); -// fail("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("Bad chain parameter value,valid range is [0,100_000_000_000_000_000L]", -// e.getMessage()); -// } catch (ContractExeException e) { -// Assert.assertFalse(e instanceof ContractExeException); -// } -// -// paras = new HashMap<>(); -// paras.put(10L, -1L); -// actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(-1); -// try { -// actuator.validate(); -// fail("This exchange has been executed before and is only allowed to be executed once"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals( -// "This exchange has been executed before and is only allowed to be executed once", -// e.getMessage()); -// } -// -// paras.put(10L, -1L); -// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); -// actuator = -// new ExchangeCreateActuator(getContract(OWNER_ADDRESS_FIRST, paras), dbManager); -// dbManager.getDynamicPropertiesStore().saveRemoveThePowerOfTheGr(0); -// try { -// actuator.validate(); -// fail("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1"); -// } catch (ContractValidateException e) { -// Assert.assertTrue(e instanceof ContractValidateException); -// Assert.assertEquals("This value[REMOVE_THE_POWER_OF_THE_GR] is only allowed to be 1", -// e.getMessage()); -// } -// } + /** + * second transaction Exchange,result is success. + */ + @Test + public void successExchangeTransaction2() { + long exchangeId = 2; + String tokenId = "abc"; + long quant = 1_000L; + String buyTokenId = "def"; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_SECOND); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(tokenId.getBytes(), 10000); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(20000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(buyTokenId)); + dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + + ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore() + .get(ByteArray.fromLong(exchangeId)); + Assert.assertNotNull(exchangeCapsule); + long firstTokenBalance = exchangeCapsule.getFirstTokenBalance(); + long secondTokenBalance = exchangeCapsule.getSecondTokenBalance(); + + Assert.assertEquals(exchangeId, exchangeCapsule.getID()); + Assert.assertEquals(tokenId, ByteArray.toStr(exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(100000000L, firstTokenBalance); + Assert.assertEquals("def", ByteArray.toStr(exchangeCapsule.getSecondTokenId())); + Assert.assertEquals(200000000L, secondTokenBalance); + + actuator.validate(); + actuator.execute(ret); + Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + exchangeCapsule = dbManager.getExchangeStore().get(ByteArray.fromLong(exchangeId)); + Assert.assertNotNull(exchangeCapsule); + + Assert.assertEquals(exchangeId, exchangeCapsule.getID()); + Assert.assertEquals(1000000, exchangeCapsule.getCreateTime()); + Assert.assertTrue(Arrays.equals(tokenId.getBytes(), exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(tokenId, ByteArray.toStr(exchangeCapsule.getFirstTokenId())); + Assert.assertEquals(firstTokenBalance + quant, exchangeCapsule.getFirstTokenBalance()); + Assert.assertEquals("def", ByteArray.toStr(exchangeCapsule.getSecondTokenId())); + Assert.assertEquals(199998001L, exchangeCapsule.getSecondTokenBalance()); + + accountCapsule = dbManager.getAccountStore().get(ownerAddress); + assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(9000L, assetMap.get("abc").longValue()); + Assert.assertEquals(1999L, assetMap.get("def").longValue()); + + } catch (ContractValidateException e) { + logger.info(e.getMessage()); + Assert.assertFalse(e instanceof ContractValidateException); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } catch (ItemNotFoundException e) { + Assert.assertFalse(e instanceof ItemNotFoundException); + } + } + + /** + * use Invalid Address, result is failed, exception is "Invalid address". + */ + @Test + public void invalidAddress() { + long exchangeId = 2; + String tokenId = "abc"; + long quant = 1_000L; + String buyTokenId = "def"; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_SECOND); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(tokenId.getBytes(), 10000); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(20000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(buyTokenId)); + dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + + ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( + OWNER_ADDRESS_INVALID, exchangeId, tokenId, quant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail("Invalid address"); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("Invalid address", e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * use AccountStore not exists, result is failed, exception is "account not exists". + */ + @Test + public void noAccount() { + long exchangeId = 2; + String tokenId = "abc"; + long quant = 1_000L; + String buyTokenId = "def"; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_SECOND); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(tokenId.getBytes(), 10000); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(20000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(buyTokenId)); + dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + + ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( + OWNER_ADDRESS_NOACCOUNT, exchangeId, tokenId, quant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail("account[+OWNER_ADDRESS_NOACCOUNT+] not exists"); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("account[" + OWNER_ADDRESS_NOACCOUNT + "] not exists", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * Exchange not exists + */ + @Test + public void exchangeNotExist() { + long exchangeId = 3; + String tokenId = "abc"; + long quant = 1_000L; + String buyTokenId = "def"; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_SECOND); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(tokenId.getBytes(), 10000); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(20000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(buyTokenId)); + dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + + ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail("Exchange not exists"); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("Exchange[3] not exists", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * token is not in exchange + */ + @Test + public void tokenIsNotInExchange() { + long exchangeId = 1; + String tokenId = "ddd"; + long quant = 1_000L; + String buyTokenId = "def"; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_SECOND); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(tokenId.getBytes(), 10000); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(20000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(buyTokenId)); + dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + + ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("token is not in exchange", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * Token balance in exchange is equal with 0, the exchange has been closed" + */ + @Test + public void tokenBalanceZero() { + long exchangeId = 2; + String tokenId = "abc"; + long quant = 1_000L; + String buyTokenId = "def"; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_SECOND); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(tokenId.getBytes(), 10000); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(20000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(buyTokenId)); + dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + + ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore() + .get(ByteArray.fromLong(exchangeId)); + exchangeCapsule.setBalance(0, 0); + dbManager.getExchangeStore().put(exchangeCapsule.createDbKey(), exchangeCapsule); + + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("Token balance in exchange is equal with 0," + + "the exchange has been closed", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } catch (ItemNotFoundException e) { + Assert.assertFalse(e instanceof ItemNotFoundException); + } + } + + /** + * withdraw token quant must greater than zero + */ + @Test + public void tokenQuantLessThanZero() { + long exchangeId = 2; + String tokenId = "abc"; + long quant = -1_000L; + String buyTokenId = "def"; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_SECOND); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(tokenId.getBytes(), 10000); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(20000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(buyTokenId)); + dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + + ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("transaction token balance must greater than zero", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * token balance must less than balanceLimit + */ + @Test + public void tokenBalanceGreaterThanBalanceLimit() { + long exchangeId = 2; + String tokenId = "abc"; + long quant = 1_000_000_000_000_001L; + String buyTokenId = "def"; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_SECOND); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(tokenId.getBytes(), 10000); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(20000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(buyTokenId)); + dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + + ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("token balance must less than 1000000000000000", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * balance is not enough + */ + @Test + public void balanceNotEnough() { + long exchangeId = 1; + String tokenId = "_"; + long quant = 100_000000L; + String buyTokenId = "abc"; + + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_SECOND); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + Map assetMap = accountCapsule.getAssetMap(); + accountCapsule.setBalance(quant - 1); + Assert.assertEquals(null, assetMap.get(buyTokenId)); + dbManager.getAccountStore().put(ownerAddress, accountCapsule); + + ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("balance is not enough", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } + + /** + * first token balance is not enough + */ + @Test + public void tokenBalanceNotEnough() { + long exchangeId = 2; + String tokenId = "abc"; + long quant = 1_000L; + String buyTokenId = "def"; + byte[] ownerAddress = ByteArray.fromHexString(OWNER_ADDRESS_SECOND); + AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddress); + accountCapsule.addAssetAmount(tokenId.getBytes(), quant - 1); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(20000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(buyTokenId)); + dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + + ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail(); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("token balance is not enough", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } } \ No newline at end of file From bdbb88359fb1e7b10241a5b55196aa411c9d6198 Mon Sep 17 00:00:00 2001 From: nanfengpo Date: Fri, 24 Aug 2018 11:32:05 +0800 Subject: [PATCH 10/10] fix: use BigInteger longValueExact --- .../org/tron/core/actuator/ExchangeInjectActuator.java | 4 ++-- .../org/tron/core/actuator/ExchangeWithdrawActuator.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java b/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java index e1fa57ee0e7..50fe7459b17 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeInjectActuator.java @@ -176,7 +176,7 @@ public boolean validate() throws ContractValidateException { // anotherTokenQuant = Math // .floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance); anotherTokenQuant = bigSecondTokenBalance.multiply(bigTokenQuant) - .divide(bigFirstTokenBalance).longValue(); + .divide(bigFirstTokenBalance).longValueExact(); newTokenBalance = firstTokenBalance + tokenQuant; newAnotherTokenBalance = secondTokenBalance + anotherTokenQuant; } else { @@ -184,7 +184,7 @@ public boolean validate() throws ContractValidateException { // anotherTokenQuant = Math // .floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance); anotherTokenQuant = bigFirstTokenBalance.multiply(bigTokenQuant) - .divide(bigSecondTokenBalance).longValue(); + .divide(bigSecondTokenBalance).longValueExact(); newTokenBalance = secondTokenBalance + tokenQuant; newAnotherTokenBalance = firstTokenBalance + anotherTokenQuant; } diff --git a/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java b/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java index 98682a69476..dfdf42cdb55 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeWithdrawActuator.java @@ -57,7 +57,7 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException // anotherTokenQuant = Math // .floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance); anotherTokenQuant = bigSecondTokenBalance.multiply(bigTokenQuant) - .divide(bigFirstTokenBalance).longValue(); + .divide(bigFirstTokenBalance).longValueExact(); exchangeCapsule.setBalance(firstTokenBalance - tokenQuant, secondTokenBalance - anotherTokenQuant); } else { @@ -65,7 +65,7 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException // anotherTokenQuant = Math // .floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance); anotherTokenQuant = bigFirstTokenBalance.multiply(bigTokenQuant) - .divide(bigSecondTokenBalance).longValue(); + .divide(bigSecondTokenBalance).longValueExact(); exchangeCapsule.setBalance(firstTokenBalance - anotherTokenQuant, secondTokenBalance - tokenQuant); } @@ -180,7 +180,7 @@ public boolean validate() throws ContractValidateException { // anotherTokenQuant = Math // .floorDiv(Math.multiplyExact(secondTokenBalance, tokenQuant), firstTokenBalance); anotherTokenQuant = bigSecondTokenBalance.multiply(bigTokenQuant) - .divide(bigFirstTokenBalance).longValue(); + .divide(bigFirstTokenBalance).longValueExact(); if (firstTokenBalance < tokenQuant || secondTokenBalance < anotherTokenQuant) { throw new ContractValidateException("exchange balance is not enough"); } @@ -188,7 +188,7 @@ public boolean validate() throws ContractValidateException { // anotherTokenQuant = Math // .floorDiv(Math.multiplyExact(firstTokenBalance, tokenQuant), secondTokenBalance); anotherTokenQuant = bigFirstTokenBalance.multiply(bigTokenQuant) - .divide(bigSecondTokenBalance).longValue(); + .divide(bigSecondTokenBalance).longValueExact(); if (secondTokenBalance < tokenQuant || firstTokenBalance < anotherTokenQuant) { throw new ContractValidateException("exchange balance is not enough"); }