Fix OOG while A calls B makes A call unsuccesful

This commit is contained in:
nicksavers 2014-10-18 20:28:24 +02:00
parent 6e32c4a958
commit 4f10a0bec2
1 changed files with 21 additions and 29 deletions

View File

@ -269,7 +269,7 @@ public class Program {
logger.info("creating a new contract inside contract run: [{}]", Hex.toHexString(senderAddress)); logger.info("creating a new contract inside contract run: [{}]", Hex.toHexString(senderAddress));
// actual gas subtract // actual gas subtract
int gas = this.getGas().intValue(); long gas = this.getGas().longValue();
this.spendGas(gas, "internal call"); this.spendGas(gas, "internal call");
// [2] CREATE THE CONTRACT ADDRESS // [2] CREATE THE CONTRACT ADDRESS
@ -365,8 +365,7 @@ public class Program {
logger.info("No gas for the internal call, \n" + logger.info("No gas for the internal call, \n" +
"fromAddress={}, codeAddress={}", "fromAddress={}, codeAddress={}",
Hex.toHexString(senderAddress), Hex.toHexString(codeAddress)); Hex.toHexString(senderAddress), Hex.toHexString(codeAddress));
this.stackPushZero(); throw new OutOfGasException();
return;
} }
BigInteger endowment = msg.getEndowment().value(); BigInteger endowment = msg.getEndowment().value();
@ -376,32 +375,26 @@ public class Program {
return; return;
} }
result.getRepository().addBalance(senderAddress, endowment.negate()); result.getRepository().addBalance(senderAddress, endowment.negate());
BigInteger contextBalance = result.getRepository().addBalance(contextAddress, endowment);
if (invokeData.byTestingSuite()) { if (invokeData.byTestingSuite()) {
logger.info("[testing suite] - omit real call"); // This keeps track of the calls created for a test
stackPushOne();
this.getResult().addCallCreate(data.array(), this.getResult().addCallCreate(data.array(),
msg.getCodeAddress().getLast20Bytes(), msg.getCodeAddress().getLast20Bytes(),
msg.getGas().getNoLeadZeroesData(), msg.getGas().getNoLeadZeroesData(),
msg.getEndowment().getNoLeadZeroesData()); msg.getEndowment().getNoLeadZeroesData());
return;
} }
// actual gas subtract // actual gas subtract
this.spendGas(msg.getGas().intValue(), "internal call"); this.spendGas(msg.getGas().longValue(), "internal call");
Repository trackRepository = result.getRepository().getTrack(); Repository trackRepository = result.getRepository().getTrack();
trackRepository.startTracking(); trackRepository.startTracking();
trackRepository.addBalance(contextAddress, msg.getEndowment().value());
ProgramInvoke programInvoke = ProgramInvoke programInvoke = ProgramInvokeFactory.createProgramInvoke(
ProgramInvokeFactory.createProgramInvoke(this, msg.getCodeAddress(), this, msg.getCodeAddress(), msg.getEndowment(), msg.getGas(),
msg.getEndowment(), msg.getGas(), result.getRepository().getBalance(contextAddress), contextBalance, data.array(), trackRepository,
data.array(), this.invokeData.getCallDeep() + 1);
trackRepository, this.invokeData.getCallDeep() + 1);
ProgramResult result = null; ProgramResult result = null;
@ -412,15 +405,15 @@ public class Program {
result = program.getResult(); result = program.getResult();
this.result.addDeleteAccounts(result.getDeleteAccounts()); this.result.addDeleteAccounts(result.getDeleteAccounts());
} }
if (result != null && if (result != null &&
result.getException() != null && result.getException() != null &&
result.getException() instanceof Program.OutOfGasException) { result.getException() instanceof Program.OutOfGasException) {
logger.info("contract run halted by OutOfGas: contract={}" , Hex.toHexString(contextAddress)); logger.info("contract run halted by OutOfGas: contract={}" , Hex.toHexString(contextAddress));
trackRepository.rollback(); trackRepository.rollback();
stackPushZero(); stackPushZero();
return; return;
} }
// 3. APPLY RESULTS: result.getHReturn() into out_memory allocated // 3. APPLY RESULTS: result.getHReturn() into out_memory allocated
@ -436,22 +429,21 @@ public class Program {
this.memorySave(offset, allocSize, buffer.array()); this.memorySave(offset, allocSize, buffer.array());
} }
} }
// 4. THE FLAG OF SUCCESS IS ONE PUSHED INTO THE STACK // 4. THE FLAG OF SUCCESS IS ONE PUSHED INTO THE STACK
trackRepository.commit(); trackRepository.commit();
stackPushOne(); stackPushOne();
// 5. REFUND THE REMAIN GAS // 5. REFUND THE REMAIN GAS
if (result != null) { if (result != null) {
BigInteger refundGas = msg.getGas().value().subtract(BigInteger.valueOf(result.getGasUsed())); BigInteger refundGas = msg.getGas().value().subtract(BigInteger.valueOf(result.getGasUsed()));
if (refundGas.compareTo(BigInteger.ZERO) == 1) { if (refundGas.compareTo(BigInteger.ZERO) == 1) {
this.refundGas(refundGas.longValue(), "remaining gas from the internal call");
this.refundGas(refundGas.intValue(), "remaining gas from the internal call");
logger.info("The remaining gas refunded, account: [{}], gas: [{}] ", logger.info("The remaining gas refunded, account: [{}], gas: [{}] ",
Hex.toHexString(senderAddress), refundGas.toString()); Hex.toHexString(senderAddress), refundGas.toString());
} }
} else { } else {
this.refundGas(msg.getGas().intValue(), "remaining gas from the internal call"); this.refundGas(msg.getGas().longValue(), "remaining gas from the internal call");
} }
} }