Fix OOG while A calls B makes A call unsuccesful
This commit is contained in:
parent
6e32c4a958
commit
4f10a0bec2
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue