diff --git a/src/main/java/org/tron/core/capsule/ReceiptCapsule.java b/src/main/java/org/tron/core/capsule/ReceiptCapsule.java index dc9c19dc68e..d48a5365f48 100644 --- a/src/main/java/org/tron/core/capsule/ReceiptCapsule.java +++ b/src/main/java/org/tron/core/capsule/ReceiptCapsule.java @@ -1,9 +1,11 @@ package org.tron.core.capsule; import org.tron.common.utils.Sha256Hash; +import org.tron.common.utils.StringUtil; import org.tron.core.Constant; import org.tron.core.db.EnergyProcessor; import org.tron.core.db.Manager; +import org.tron.core.exception.BalanceInsufficientException; import org.tron.protos.Protocol.ResourceReceipt; import org.tron.protos.Protocol.Transaction.Result.contractResult; @@ -87,7 +89,7 @@ public long getNetFee() { * payEnergyBill pay receipt energy bill by energy processor. */ public void payEnergyBill(Manager manager, AccountCapsule origin, AccountCapsule caller, - long percent, EnergyProcessor energyProcessor, long now) { + long percent, EnergyProcessor energyProcessor, long now) throws BalanceInsufficientException { if (0 == receipt.getEnergyUsageTotal()) { return; } @@ -110,7 +112,7 @@ private void payEnergyBill( AccountCapsule account, long usage, EnergyProcessor energyProcessor, - long now) { + long now) throws BalanceInsufficientException { long accountEnergyLeft = energyProcessor.getAccountLeftEnergyFromFreeze(account); if (accountEnergyLeft >= usage) { energyProcessor.useEnergy(account, usage, now); @@ -124,7 +126,12 @@ private void payEnergyBill( (usage - accountEnergyLeft) * SUN_PER_ENERGY; this.setEnergyUsage(accountEnergyLeft); this.setEnergyFee(energyFee); - account.setBalance(account.getBalance() - energyFee); + long balance = account.getBalance(); + if (balance < energyFee) { + throw new BalanceInsufficientException( + StringUtil.createReadableString(account.createDbKey()) + " insufficient balance"); + } + account.setBalance(balance - energyFee); } manager.getAccountStore().put(account.getAddress().toByteArray(), account); diff --git a/src/main/java/org/tron/core/db/TransactionTrace.java b/src/main/java/org/tron/core/db/TransactionTrace.java index c0ff2c1ab11..be7e8018fb9 100644 --- a/src/main/java/org/tron/core/db/TransactionTrace.java +++ b/src/main/java/org/tron/core/db/TransactionTrace.java @@ -22,6 +22,7 @@ import org.tron.core.capsule.ContractCapsule; import org.tron.core.capsule.ReceiptCapsule; import org.tron.core.capsule.TransactionCapsule; +import org.tron.core.exception.BalanceInsufficientException; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; import org.tron.core.exception.ReceiptCheckErrException; @@ -106,15 +107,19 @@ public void exec(Runtime runtime) runtime.go(); } - public void finalization(Runtime runtime) { - pay(); + public void finalization(Runtime runtime) throws ContractExeException { + try { + pay(); + } catch (BalanceInsufficientException e) { + throw new ContractExeException(e.getMessage()); + } runtime.finalization(); } /** * pay actually bill(include ENERGY and storage). */ - public void pay() { + public void pay() throws BalanceInsufficientException { byte[] originAccount; byte[] callerAccount; long percent = 0; diff --git a/src/test/java/org/tron/core/db/TransactionTraceTest.java b/src/test/java/org/tron/core/db/TransactionTraceTest.java index b151cfb1b21..1e5cc8a47c9 100644 --- a/src/test/java/org/tron/core/db/TransactionTraceTest.java +++ b/src/test/java/org/tron/core/db/TransactionTraceTest.java @@ -40,6 +40,7 @@ import org.tron.core.capsule.TransactionCapsule; import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; +import org.tron.core.exception.BalanceInsufficientException; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; import org.tron.protos.Contract.CreateSmartContract; @@ -194,6 +195,8 @@ public void testUseUsage() throws InvalidProtocolBufferException { e.printStackTrace(); } catch (ContractValidateException e) { e.printStackTrace(); + } catch (BalanceInsufficientException e) { + e.printStackTrace(); } } @@ -250,8 +253,12 @@ public void testPay() { TransactionCapsule transactionCapsule = new TransactionCapsule(transaction); TransactionTrace transactionTrace = new TransactionTrace(transactionCapsule, dbManager); // transactionTrace.setBill(this.energyUsage, this.storageUsage); - transactionTrace.pay(); - AccountCapsule accountCapsule1 = dbManager.getAccountStore().get(ownerAddress.toByteArray()); + try { + transactionTrace.pay(); + AccountCapsule accountCapsule1 = dbManager.getAccountStore().get(ownerAddress.toByteArray()); + } catch (BalanceInsufficientException e) { + e.printStackTrace(); + } } /**