Contract creation revert now bills sender correctly
revision:
@@ -195,6 +195,7 @@ public class DAppCreator {
boolean enableBlockchainPrintln) {
// Expose the DApp outside the try so we can detach from it, when we exit.
LoadedDApp dapp = null;
+ IInstrumentation threadInstrumentation = null;
AvmWrappedTransactionResult result = internalResult;
try {
// read dapp module
@@ -252,7 +253,7 @@ public class DAppCreator {
// We have just created this dApp, there should be no previous runtime associated with it.
RuntimeAssertionError.assertTrue(previousRuntime == null);
- IInstrumentation threadInstrumentation = IInstrumentation.attachedThreadInstrumentation.get();
+ threadInstrumentation = IInstrumentation.attachedThreadInstrumentation.get();
threadInstrumentation.chargeEnergy(BillingRules.getDeploymentFee(rawDapp.numberOfClasses, rawDapp.bytecodeSize));
// Create the immortal version of the transformed DApp code by stripping the <clinit>.
@@ -318,7 +319,9 @@ public class DAppCreator {
System.err.println("DApp deployment to REVERT due to uncaught EXCEPTION: \"" + e.getMessage() + "\"");
e.printStackTrace(System.err);
}
- result = TransactionResultUtil.setRevertedFailureAndEnergyUsed(result, tx.energyLimit);
+ // We can never be a situation where a revert is triggered but the threadInstrumentation is null - if we are here we know we executed code.
+ RuntimeAssertionError.assertTrue(threadInstrumentation != null);
+ result = TransactionResultUtil.setRevertedFailureAndEnergyUsed(result, tx.energyLimit - threadInstrumentation.energyLeft());
} catch (InvalidException e) {
if (verboseErrors) {
