VM results apply:

+ Gas debit/refund addeded
+ GUI validation impl started
This commit is contained in:
romanman 2014-06-09 13:09:06 +01:00
parent 899767affb
commit 2156177970
4 changed files with 56 additions and 2 deletions

View File

@ -12,6 +12,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.spongycastle.util.BigIntegers; import org.spongycastle.util.BigIntegers;
import java.math.BigInteger;
import java.security.SignatureException; import java.security.SignatureException;
import java.util.Arrays; import java.util.Arrays;
@ -154,6 +155,11 @@ public class Transaction {
return gasLimit; return gasLimit;
} }
// TODO: performance improve multiply without BigInteger
public BigInteger getTotalGasDebit(){
return new BigInteger(1, gasLimit).multiply(new BigInteger(1,gasPrice));
}
public byte[] getData() { public byte[] getData() {
if (!parsed) rlpParse(); if (!parsed) rlpParse();
return data; return data;

View File

@ -260,6 +260,9 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog {
public void submitContract(){ public void submitContract(){
if (!validInput())
return;
Transaction tx = null; Transaction tx = null;
try { try {
tx = createTransaction(); tx = createTransaction();
@ -304,6 +307,24 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog {
return tx; return tx;
} }
private boolean validInput() {
Account account = ((AccountWrapper)creatorAddressCombo.getSelectedItem()).getAccount();
BigInteger currentBalance = account.getState().getBalance();
BigInteger gasPrice = BigInteger.valueOf( MainData.instance.getBlockchain().getGasPrice());
BigInteger gasInput = new BigInteger( this.gasInput.getText());
boolean canAfford = currentBalance.compareTo(gasPrice.multiply(gasInput)) >= 0;
if (!canAfford){
alertStatusMsg("The address can't afford this transaction");
return false;
}
return true;
}
public static void main(String args[]) { public static void main(String args[]) {
AccountState as = new AccountState(); AccountState as = new AccountState();

View File

@ -115,6 +115,20 @@ public class WorldManager {
logger.info("running the init for contract: addres={}" , logger.info("running the init for contract: addres={}" ,
Hex.toHexString(tx.getContractAddress())); Hex.toHexString(tx.getContractAddress()));
// first of all debit the gas from the issuer
BigInteger gasDebit = tx.getTotalGasDebit();
senderState.addToBalance(gasDebit.negate());
if (senderState.getBalance().signum() == -1){
// todo: the sender can't afford this contract do Out-Of-Gas
}
if(stateLogger.isInfoEnabled())
stateLogger.info("Before contract execution the sender address debit with gas total cost, \n sender={} \n contract={} \n gas_debit= {}",
Hex.toHexString( tx.getSender() ), Hex.toHexString(tx.getContractAddress()), gasDebit);
worldState.update(senderAddress, senderState.getEncoded());
VM vm = new VM(); VM vm = new VM();
Program program = new Program(initCode, programInvoke); Program program = new Program(initCode, programInvoke);
vm.play(program); vm.play(program);
@ -129,8 +143,19 @@ public class WorldManager {
// TODO: (!!!!!) ALL THE CHECKS FOR THE PROGRAM RESULT // TODO: (!!!!!) ALL THE CHECKS FOR THE PROGRAM RESULT
if (bodyCode != null){ BigInteger gasPrice = BigInteger.valueOf( MainData.instance.getBlockchain().getGasPrice());
BigInteger refund =
gasDebit.subtract(BigInteger.valueOf( result.getGasUsed()).multiply(gasPrice));
if (refund.signum() > 0){
if(stateLogger.isInfoEnabled())
stateLogger.info("After contract execution the sender address refunded with gas leftover , \n sender={} \n contract={} \n gas_refund= {}",
Hex.toHexString(tx.getSender()) ,Hex.toHexString(tx.getContractAddress()), refund);
senderState.addToBalance(refund);
worldState.update(senderAddress, senderState.getEncoded());
}
if (bodyCode != null){
byte[] codeKey = HashUtil.sha3(bodyCode); byte[] codeKey = HashUtil.sha3(bodyCode);
chainDB.put(codeKey, bodyCode); chainDB.put(codeKey, bodyCode);
receiverState.setCodeHash(codeKey); receiverState.setCodeHash(codeKey);
@ -148,7 +173,7 @@ public class WorldManager {
if (receiverState.getCodeHash() != HashUtil.EMPTY_DATA_HASH){ if (receiverState.getCodeHash() != HashUtil.EMPTY_DATA_HASH){
byte[] programCode = chainDB.get(receiverState.getCodeHash()); byte[] programCode = chainDB.get(receiverState.getCodeHash());
if (programCode.length != 0){ if (programCode != null && programCode.length != 0){
Block lastBlock = Block lastBlock =
MainData.instance.getBlockchain().getLastBlock(); MainData.instance.getBlockchain().getLastBlock();

View File

@ -368,6 +368,8 @@ public class Program {
logger.debug(" -- MEMORY -- {}", memoryData); logger.debug(" -- MEMORY -- {}", memoryData);
logger.debug(" -- STORAGE -- {}\n", storageData); logger.debug(" -- STORAGE -- {}\n", storageData);
logger.debug("\n\n Spent Gas: {}", result.getGasUsed());
StringBuilder globalOutput = new StringBuilder("\n"); StringBuilder globalOutput = new StringBuilder("\n");
if (stackData.length() > 0) stackData.append("\n"); if (stackData.length() > 0) stackData.append("\n");