From 5c628a8b94d59816484dca20db3e2b31babaf6e8 Mon Sep 17 00:00:00 2001 From: huzhenyuan Date: Thu, 30 Aug 2018 13:41:49 +0800 Subject: [PATCH 1/4] update proto --- core/Tron.proto | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/core/Tron.proto b/core/Tron.proto index 5a01c609eff..ed9526c1a78 100644 --- a/core/Tron.proto +++ b/core/Tron.proto @@ -183,16 +183,13 @@ message TXOutputs { } message ResourceReceipt { - enum code { - SUCCESS = 0; - FAILED = 1; - } int64 energy_usage = 1; int64 energy_fee = 2; int64 origin_energy_usage = 3; int64 energy_usage_total = 4; int64 net_usage = 5; int64 net_fee = 6; + Transaction.Result.contractResult result = 7; } message Transaction { @@ -234,7 +231,6 @@ message Transaction { google.protobuf.Any parameter = 2; bytes provider = 3; bytes ContractName = 4; - } message Result { @@ -242,8 +238,25 @@ message Transaction { SUCESS = 0; FAILED = 1; } + enum contractResult { + DEFAULT = 0; + SUCCESS = 1; + REVERT = 2; + BAD_JUMP_DESTINATION = 3; + OUT_OF_MEMORY = 4; + PRECOMPILED_CONTRACT = 5; + STACK_TOO_SMALL = 6; + STACK_TOO_LARGE = 7; + ILLEGAL_OPERATION = 8; + STACK_OVERFLOW = 9; + OUT_OF_ENERGY = 10; + OUT_OF_TIME = 11; + JVM_STACK_OVER_FLOW = 12; + UNKNOWN = 13; + } int64 fee = 1; code ret = 2; + contractResult contractRet = 3; int64 withdraw_amount = 15; int64 unfreeze_amount = 16; @@ -315,6 +328,7 @@ message BlockHeader { int64 number = 7; int64 witness_id = 8; bytes witness_address = 9; + int32 version = 10; } raw raw_data = 1; bytes witness_signature = 2; @@ -424,17 +438,6 @@ message HelloMessage { BlockId headBlockId = 6; } -message StorageItem { - bytes contract_address = 1; - map items = 2; -} - -message StorageRow { - bytes key = 1; // composition of contract_address and storage_key - bytes value = 2; -} - - message SmartContract { message ABI { message Entry { From dba3ca75d92c008f66b720a26fd71c7a7364338c Mon Sep 17 00:00:00 2001 From: nanfengpo Date: Wed, 5 Sep 2018 12:42:21 +0800 Subject: [PATCH 2/4] add expected in ExchangeTransactionContract --- core/Contract.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/core/Contract.proto b/core/Contract.proto index 5d5c1421f9a..18eafded8f8 100644 --- a/core/Contract.proto +++ b/core/Contract.proto @@ -225,4 +225,5 @@ message ExchangeTransactionContract { int64 exchange_id = 2; bytes token_id = 3; int64 quant = 4; + int64 expected = 5; } \ No newline at end of file From 9b8370602c21641d75e7e15b6a17ad3642b563a9 Mon Sep 17 00:00:00 2001 From: nanfengpo Date: Wed, 5 Sep 2018 12:57:36 +0800 Subject: [PATCH 3/4] add Expected validation in ExchangeTransactionActuator --- .../core/actuator/ExchangeTransactionActuator.java | 11 ++++++++--- .../actuator/ExchangeTransactionActuatorTest.java | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java b/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java index 481fae4dc0d..0b8288abab2 100755 --- a/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java +++ b/src/main/java/org/tron/core/actuator/ExchangeTransactionActuator.java @@ -135,13 +135,18 @@ public boolean validate() throws ContractValidateException { byte[] tokenID = contract.getTokenId().toByteArray(); long tokenQuant = contract.getQuant(); + long tokenExpected = contract.getExpected(); if (!Arrays.equals(tokenID, firstTokenID) && !Arrays.equals(tokenID, secondTokenID)) { throw new ContractValidateException("token is not in exchange"); } if (tokenQuant <= 0) { - throw new ContractValidateException("transaction token balance must greater than zero"); + throw new ContractValidateException("token quant must greater than zero"); + } + + if (tokenExpected <= 0) { + throw new ContractValidateException("token expected must greater than zero"); } if (firstTokenBalance == 0 || secondTokenBalance == 0) { @@ -168,8 +173,8 @@ public boolean validate() throws ContractValidateException { } long anotherTokenQuant = exchangeCapsule.transaction(tokenID, tokenQuant); - if (anotherTokenQuant < 1) { - throw new ContractValidateException("token quant is not enough to buy 1 another token"); + if (anotherTokenQuant < tokenExpected) { + throw new ContractValidateException("token required must greater than expected"); } return true; diff --git a/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java b/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java index edea2de6f39..6a51d4039b4 100644 --- a/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java @@ -455,7 +455,7 @@ public void tokenBalanceZero() { } /** - * withdraw token quant must greater than zero + * token quant must greater than zero */ @Test public void tokenQuantLessThanZero() { @@ -562,7 +562,7 @@ public void balanceNotEnough() { } /** - * first token balance is not enough + * token balance is not enough */ @Test public void tokenBalanceNotEnough() { From 21c94cdba357c08e84d747ba19ed4aeaba043380 Mon Sep 17 00:00:00 2001 From: nanfengpo Date: Wed, 5 Sep 2018 13:11:49 +0800 Subject: [PATCH 4/4] add Expected validation unittest --- .../ExchangeTransactionActuatorTest.java | 73 +++++++++++++++---- 1 file changed, 60 insertions(+), 13 deletions(-) diff --git a/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java b/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java index 6a51d4039b4..716619a6895 100644 --- a/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java @@ -130,13 +130,15 @@ public void initTest() { dbManager.getDynamicPropertiesStore().saveNextMaintenanceTime(2000000); } - private Any getContract(String address, long exchangeId, String tokenId, long quant) { + private Any getContract(String address, long exchangeId, String tokenId, + long quant, long expected) { return Any.pack( Contract.ExchangeTransactionContract.newBuilder() .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(address))) .setExchangeId(exchangeId) .setTokenId(ByteString.copyFrom(tokenId.getBytes())) .setQuant(quant) + .setExpected(expected) .build()); } @@ -156,7 +158,7 @@ public void successExchangeTransaction() { Assert.assertEquals(null, assetMap.get("def")); ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( - OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant, 1), dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); @@ -221,7 +223,7 @@ public void successExchangeTransaction2() { dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( - OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant, 1), dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); @@ -286,7 +288,7 @@ public void invalidAddress() { dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( - OWNER_ADDRESS_INVALID, exchangeId, tokenId, quant), + OWNER_ADDRESS_INVALID, exchangeId, tokenId, quant, 1), dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); @@ -321,7 +323,7 @@ public void noAccount() { dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( - OWNER_ADDRESS_NOACCOUNT, exchangeId, tokenId, quant), + OWNER_ADDRESS_NOACCOUNT, exchangeId, tokenId, quant, 1), dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); @@ -357,7 +359,7 @@ public void exchangeNotExist() { dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( - OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant, 1), dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); @@ -393,7 +395,7 @@ public void tokenIsNotInExchange() { dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( - OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant, 1), dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); @@ -429,7 +431,7 @@ public void tokenBalanceZero() { dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( - OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant, 1), dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); @@ -473,7 +475,7 @@ public void tokenQuantLessThanZero() { dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( - OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant, 1), dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); @@ -483,7 +485,7 @@ public void tokenQuantLessThanZero() { fail(); } catch (ContractValidateException e) { Assert.assertTrue(e instanceof ContractValidateException); - Assert.assertEquals("transaction token balance must greater than zero", + Assert.assertEquals("token quant must greater than zero", e.getMessage()); } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); @@ -509,7 +511,7 @@ public void tokenBalanceGreaterThanBalanceLimit() { dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( - OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant, 1), dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); @@ -544,7 +546,7 @@ public void balanceNotEnough() { dbManager.getAccountStore().put(ownerAddress, accountCapsule); ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( - OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant, 1), dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); @@ -580,7 +582,7 @@ public void tokenBalanceNotEnough() { dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( - OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant), + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant, 1), dbManager); TransactionResultCapsule ret = new TransactionResultCapsule(); @@ -596,4 +598,49 @@ public void tokenBalanceNotEnough() { Assert.assertFalse(e instanceof ContractExeException); } } + + /** + * token required must greater than expected + */ + @Test + public void tokenRequiredNotEnough() { + 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); + Map assetMap = accountCapsule.getAssetMap(); + Assert.assertEquals(20000_000000L, accountCapsule.getBalance()); + Assert.assertEquals(null, assetMap.get(buyTokenId)); + dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + + long expected = 0; + try { + ExchangeCapsule exchangeCapsule = dbManager.getExchangeStore() + .get(ByteArray.fromLong(exchangeId)); + expected = exchangeCapsule.transaction(tokenId.getBytes(), quant); + } catch (ItemNotFoundException e) { + fail(); + } + + ExchangeTransactionActuator actuator = new ExchangeTransactionActuator(getContract( + OWNER_ADDRESS_SECOND, exchangeId, tokenId, quant, expected + 1), + dbManager); + TransactionResultCapsule ret = new TransactionResultCapsule(); + + try { + actuator.validate(); + actuator.execute(ret); + fail("should not run here"); + } catch (ContractValidateException e) { + Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("token required must greater than expected", + e.getMessage()); + } catch (ContractExeException e) { + Assert.assertFalse(e instanceof ContractExeException); + } + } } \ No newline at end of file