From 057894f3b6db50b192c3ba6cd9198ba3619206c1 Mon Sep 17 00:00:00 2001 From: zergweak Date: Thu, 29 Mar 2018 15:42:01 +0800 Subject: [PATCH 1/2] 1.No exchange tokens for yourself 2.Check balance of token befor exchange 3.Must exchange tokens from issuer 4.Allow to exchange any number of trx. --- .../ParticipateAssetIssueActuator.java | 39 +++++++++++++------ .../org/tron/core/capsule/AccountCapsule.java | 15 +++++++ 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/tron/core/actuator/ParticipateAssetIssueActuator.java b/src/main/java/org/tron/core/actuator/ParticipateAssetIssueActuator.java index d8cbcda185d..cb6af49305f 100644 --- a/src/main/java/org/tron/core/actuator/ParticipateAssetIssueActuator.java +++ b/src/main/java/org/tron/core/actuator/ParticipateAssetIssueActuator.java @@ -20,6 +20,7 @@ import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import org.joda.time.DateTime; +import org.tron.common.utils.ByteArray; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.AssetIssueCapsule; import org.tron.core.capsule.TransactionResultCapsule; @@ -54,13 +55,16 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException AssetIssueCapsule assetIssueCapsule = this.dbManager.getAssetIssueStore() .get(participateAssetIssueContract.getAssetName().toByteArray()); - long exchangeAmount = cost / assetIssueCapsule.getTrxNum() * assetIssueCapsule.getNum(); + long exchangeAmount = cost * assetIssueCapsule.getNum() / assetIssueCapsule.getTrxNum(); ownerAccount.addAssetAmount(assetIssueCapsule.getName(), exchangeAmount); //add to to_address byte[] toAddressBytes = participateAssetIssueContract.getToAddress().toByteArray(); AccountCapsule toAccount = this.dbManager.getAccountStore().get(toAddressBytes); toAccount.setBalance(toAccount.getBalance() + cost); - toAccount.reduceAssetAmount(assetIssueCapsule.getName(), exchangeAmount); + if (!toAccount.reduceAssetAmount(assetIssueCapsule.getName(), exchangeAmount)) { + throw new ContractExeException("reduceAssetAmount failed !"); + } + //write to db dbManager.getAccountStore().put(ownerAddressBytes, ownerAccount); dbManager.getAccountStore().put(toAddressBytes, toAccount); @@ -93,6 +97,10 @@ public boolean validate() throws ContractValidateException { throw new ContractValidateException("Trx Num must be positive!"); } + if ( participateAssetIssueContract.getOwnerAddress().equals(participateAssetIssueContract.getToAddress())){ + throw new ContractValidateException("Cannot participate asset Issue yourself !"); + } + byte[] addressBytes = participateAssetIssueContract.getOwnerAddress().toByteArray(); //Whether the account exist if (!this.dbManager.getAccountStore().has(addressBytes)) { @@ -103,20 +111,26 @@ public boolean validate() throws ContractValidateException { long fee = calcFee(); //Whether the balance is enough if (ac.getBalance() < participateAssetIssueContract.getAmount() + fee) { - throw new ContractValidateException(); + throw new ContractValidateException("No enough balance !"); } //Whether have the mapping if (!this.dbManager.getAssetIssueStore() .has(participateAssetIssueContract.getAssetName().toByteArray())) { - throw new ContractValidateException(); + throw new ContractValidateException("No asset named " + ByteArray + .toStr(participateAssetIssueContract.getAssetName().toByteArray())); } - - //Whether the exchange can be processed: to see if the exchange can be the exact int - long cost = participateAssetIssueContract.getAmount(); AssetIssueCapsule assetIssueCapsule = this.dbManager.getAssetIssueStore() .get(participateAssetIssueContract.getAssetName().toByteArray()); + if (!participateAssetIssueContract.getToAddress() + .equals(assetIssueCapsule.getOwnerAddress())) { + throw new ContractValidateException("The asset is not issued by " + ByteArray + .toHexString(participateAssetIssueContract.getToAddress().toByteArray())); + } + //Whether the exchange can be processed: to see if the exchange can be the exact int + long cost = participateAssetIssueContract.getAmount(); + DateTime now = DateTime.now(); if (now.getMillis() >= assetIssueCapsule.getEndTime() || now.getMillis() < assetIssueCapsule .getStartTime()) { @@ -124,12 +138,15 @@ public boolean validate() throws ContractValidateException { } int trxNum = assetIssueCapsule.getTrxNum(); int num = assetIssueCapsule.getNum(); - long exchangeAmount = cost / trxNum * num; - float preciseExchangeAmount = (float) cost / (float) trxNum * (float) num; - if (preciseExchangeAmount - exchangeAmount >= 0.000001f - || preciseExchangeAmount - exchangeAmount <= -0.000001f) { + long exchangeAmount = cost * num / trxNum; + if (exchangeAmount == 0) { throw new ContractValidateException("Can not process the exchange!"); } + AccountCapsule toAccount = this.dbManager.getAccountStore().get(participateAssetIssueContract.getToAddress().toByteArray()); + if (!toAccount.assetBalanceEnough(assetIssueCapsule.getName(), exchangeAmount)) { + throw new ContractValidateException("Asset balance is not enough !"); + } + } catch (InvalidProtocolBufferException e) { throw new ContractValidateException(); } diff --git a/src/main/java/org/tron/core/capsule/AccountCapsule.java b/src/main/java/org/tron/core/capsule/AccountCapsule.java index 0e84bd38eb3..dcaedd43d68 100644 --- a/src/main/java/org/tron/core/capsule/AccountCapsule.java +++ b/src/main/java/org/tron/core/capsule/AccountCapsule.java @@ -175,6 +175,21 @@ public long getShare() { return this.account.getBalance(); } + /** + * asset balance enough + */ + public boolean assetBalanceEnough(ByteString name, long amount) { + Map assetMap = this.account.getAssetMap(); + String nameKey = ByteArray.toStr(name.toByteArray()); + Long currentAmount = assetMap.get(nameKey); + + if (amount > 0 && null != currentAmount && amount <= currentAmount) { + return true; + } + return false; + } + + /** * reduce asset amount. */ From ad871b63a539c4bf2c7193e6ca9e5c3b3d496aa0 Mon Sep 17 00:00:00 2001 From: zergweak Date: Thu, 29 Mar 2018 16:39:47 +0800 Subject: [PATCH 2/2] No transfer asset or trx to yourself --- .../ParticipateAssetIssueActuator.java | 6 +++-- .../tron/core/actuator/TransferActuator.java | 24 +++++++++---------- .../core/actuator/TransferAssetActuator.java | 12 +++++++++- .../ParticipateAssetIssueActuatorTest.java | 2 +- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/tron/core/actuator/ParticipateAssetIssueActuator.java b/src/main/java/org/tron/core/actuator/ParticipateAssetIssueActuator.java index cb6af49305f..009d8acb221 100644 --- a/src/main/java/org/tron/core/actuator/ParticipateAssetIssueActuator.java +++ b/src/main/java/org/tron/core/actuator/ParticipateAssetIssueActuator.java @@ -97,7 +97,8 @@ public boolean validate() throws ContractValidateException { throw new ContractValidateException("Trx Num must be positive!"); } - if ( participateAssetIssueContract.getOwnerAddress().equals(participateAssetIssueContract.getToAddress())){ + if (participateAssetIssueContract.getOwnerAddress() + .equals(participateAssetIssueContract.getToAddress())) { throw new ContractValidateException("Cannot participate asset Issue yourself !"); } @@ -142,7 +143,8 @@ public boolean validate() throws ContractValidateException { if (exchangeAmount == 0) { throw new ContractValidateException("Can not process the exchange!"); } - AccountCapsule toAccount = this.dbManager.getAccountStore().get(participateAssetIssueContract.getToAddress().toByteArray()); + AccountCapsule toAccount = this.dbManager.getAccountStore() + .get(participateAssetIssueContract.getToAddress().toByteArray()); if (!toAccount.assetBalanceEnough(assetIssueCapsule.getName(), exchangeAmount)) { throw new ContractValidateException("Asset balance is not enough !"); } diff --git a/src/main/java/org/tron/core/actuator/TransferActuator.java b/src/main/java/org/tron/core/actuator/TransferActuator.java index eca0f28988e..e40fb2ae352 100755 --- a/src/main/java/org/tron/core/actuator/TransferActuator.java +++ b/src/main/java/org/tron/core/actuator/TransferActuator.java @@ -59,31 +59,29 @@ public boolean validate() throws ContractValidateException { "contract type error,expected type [TransferContract],real type[" + contract .getClass() + "]"); } - TransferContract transferContract = this.contract.unpack(TransferContract.class); - AccountCapsule ownerAccount = dbManager.getAccountStore() - .get(transferContract.getOwnerAddress().toByteArray()); Preconditions.checkNotNull(transferContract.getOwnerAddress(), "OwnerAddress is null"); Preconditions.checkNotNull(transferContract.getToAddress(), "ToAddress is null"); Preconditions.checkNotNull(transferContract.getAmount(), "Amount is null"); - AccountCapsule accountCapsule = dbManager.getAccountStore() + if (transferContract.getOwnerAddress().equals(transferContract.getToAddress())) { + throw new ContractValidateException("Cannot transfer trx to yourself."); + } + if (!dbManager.getAccountStore().has(transferContract.getOwnerAddress().toByteArray())) { + throw new ContractValidateException("Validate TransferContract error, no OwnerAccount."); + } + + AccountCapsule ownerAccount = dbManager.getAccountStore() .get(transferContract.getOwnerAddress().toByteArray()); - long balance = accountCapsule.getBalance(); - long laststOperationTime = accountCapsule.getLatestOperationTime(); + long balance = ownerAccount.getBalance(); + long laststOperationTime = ownerAccount.getLatestOperationTime(); long now = System.currentTimeMillis(); - + //TODO: //if (now - laststOperationTime < balance) { //throw new ContractValidateException(); //} - { - if (!dbManager.getAccountStore().has(transferContract.getOwnerAddress().toByteArray())) { - throw new ContractValidateException("Validate TransferContract error, no OwnerAccount."); - } - } - // if account with to_address is not existed, create it. ByteString toAddress = transferContract.getToAddress(); if (!dbManager.getAccountStore().has(toAddress.toByteArray())) { diff --git a/src/main/java/org/tron/core/actuator/TransferAssetActuator.java b/src/main/java/org/tron/core/actuator/TransferAssetActuator.java index 7b40e33f06d..bd158773a6b 100644 --- a/src/main/java/org/tron/core/actuator/TransferAssetActuator.java +++ b/src/main/java/org/tron/core/actuator/TransferAssetActuator.java @@ -15,6 +15,7 @@ package org.tron.core.actuator; +import com.google.common.base.Preconditions; import com.google.protobuf.Any; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; @@ -57,7 +58,9 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException long amount = transferAssetContract.getAmount(); AccountCapsule ownerAccountCapsule = accountStore.get(ownerKey); - ownerAccountCapsule.reduceAssetAmount(assertName, amount); + if (!ownerAccountCapsule.reduceAssetAmount(assertName, amount)) { + throw new ContractExeException("reduceAssetAmount failed !"); + } accountStore.put(ownerKey, ownerAccountCapsule); AccountCapsule toAccountCapsule = accountStore.get(toKey); @@ -78,6 +81,13 @@ public boolean validate() throws ContractValidateException { TransferAssetContract transferAssetContract = this.contract .unpack(TransferAssetContract.class); + Preconditions.checkNotNull(transferAssetContract.getOwnerAddress(), "OwnerAddress is null"); + Preconditions.checkNotNull(transferAssetContract.getToAddress(), "ToAddress is null"); + Preconditions.checkNotNull(transferAssetContract.getAssetName(), "AssetName is null"); + Preconditions.checkNotNull(transferAssetContract.getAmount(), "Amount is null"); + if (transferAssetContract.getOwnerAddress().equals(transferAssetContract.getToAddress())) { + throw new ContractValidateException("Cannot transfer asset to yourself."); + } byte[] ownerKey = transferAssetContract.getOwnerAddress().toByteArray(); if (!this.dbManager.getAccountStore().has(ownerKey)) { throw new ContractValidateException(); diff --git a/src/test/java/org/tron/core/actuator/ParticipateAssetIssueActuatorTest.java b/src/test/java/org/tron/core/actuator/ParticipateAssetIssueActuatorTest.java index f371e469ead..0ff0b24ec7f 100644 --- a/src/test/java/org/tron/core/actuator/ParticipateAssetIssueActuatorTest.java +++ b/src/test/java/org/tron/core/actuator/ParticipateAssetIssueActuatorTest.java @@ -106,7 +106,7 @@ private Any getContract(long count) { private void initAssetIssue(long startTimestmp, long endTimestmp) { AssetIssueContract assetIssueContract = AssetIssueContract.newBuilder() - .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(TO_ADDRESS))) .setName(ByteString.copyFrom(ByteArray.fromString(ASSET_NAME))) .setTotalSupply(TOTAL_SUPPLY) .setTrxNum(TRX_NUM)