Fix TXFEE/TXDATAFEE for normal tx

This commit is contained in:
nicksavers 2014-07-13 13:12:51 +02:00
parent a5961dd13a
commit b0a564e51e
2 changed files with 40 additions and 36 deletions

View File

@ -157,7 +157,7 @@ public class Transaction {
// TODO: performance improve multiply without BigInteger // TODO: performance improve multiply without BigInteger
public BigInteger getTotalGasValueDebit() { public BigInteger getTotalGasValueDebit() {
return new BigInteger(1, gasLimit).multiply(new BigInteger(1,gasPrice)); return new BigInteger(1, gasLimit).multiply(new BigInteger(1, gasPrice));
} }
public byte[] getData() { public byte[] getData() {

View File

@ -96,40 +96,48 @@ public class WorldManager {
return; return;
} }
// 2.1 PERFORM THE GAS VALUE TX // 3. FIND OUT THE TRANSACTION TYPE
// (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION) byte[] receiverAddress, code = null;
boolean isContractCreation = tx.isContractCreation();
// first of all debit the gas from the issuer if (isContractCreation) {
BigInteger gasDebit = tx.getTotalGasValueDebit();
byte[] receiverAddress;
// Contract creation or existing Contract call
if (tx.isContractCreation()) {
receiverAddress = tx.getContractAddress(); receiverAddress = tx.getContractAddress();
repository.createAccount(receiverAddress); repository.createAccount(receiverAddress);
stateLogger.info("New contract created address={}", stateLogger.info("New contract created address={}",
Hex.toHexString(receiverAddress)); Hex.toHexString(receiverAddress));
code = tx.getData(); // init code
if (logger.isInfoEnabled())
logger.info("running the init for contract: address={}",
Hex.toHexString(receiverAddress));
} else { } else {
receiverAddress = tx.getReceiveAddress(); receiverAddress = tx.getReceiveAddress();
AccountState receiverState = repository.getAccountState(receiverAddress); AccountState receiverState = repository.getAccountState(receiverAddress);
if (receiverState == null) { if (receiverState == null) {
repository.createAccount(receiverAddress); repository.createAccount(receiverAddress);
if (stateLogger.isInfoEnabled()) if (stateLogger.isInfoEnabled())
stateLogger.info("New receiver account created address={}", stateLogger.info("New receiver account created address={}",
Hex.toHexString(receiverAddress)); Hex.toHexString(receiverAddress));
} else {
code = repository.getCode(receiverAddress);
if (code != null) {
if (logger.isInfoEnabled())
logger.info("calling for existing contract: address={}",
Hex.toHexString(receiverAddress));
}
} }
} }
// 2.2 UPDATE THE NONCE // 2.1 UPDATE THE NONCE
// (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION) // (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION)
repository.increaseNonce(senderAddress); repository.increaseNonce(senderAddress);
// actual gas value debit from the sender // 2.2 PERFORM THE GAS VALUE TX
// the purchase gas will be available for the // (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION)
// contract in the execution state, and BigInteger gasDebit = tx.getTotalGasValueDebit();
// can be validate using GAS op
// Debit the actual total gas value from the sender
// the purchased gas will be available for
// the contract in the execution state,
// it can be retrieved using GAS op
if (gasDebit.signum() == 1) { if (gasDebit.signum() == 1) {
BigInteger balance = senderAccount.getBalance(); BigInteger balance = senderAccount.getBalance();
if (balance.compareTo(gasDebit) == -1) { if (balance.compareTo(gasDebit) == -1) {
@ -177,23 +185,7 @@ public class WorldManager {
} }
} }
byte[] code; // 5. CREATE OR EXECUTE PROGRAM
boolean isContractCreation = tx.isContractCreation();
// 3. FIND OUT THE TRANSACTION TYPE
if (isContractCreation) {
code = tx.getData(); // init code
if (logger.isInfoEnabled())
logger.info("running the init for contract: address={}",
Hex.toHexString(receiverAddress));
} else {
code = trackRepository.getCode(receiverAddress);
if (code != null) {
if (logger.isInfoEnabled())
logger.info("calling for existing contract: address={}",
Hex.toHexString(receiverAddress));
}
}
if (isContractCreation || code != null) { if (isContractCreation || code != null) {
Block lastBlock = blockchain.getLastBlock(); Block lastBlock = blockchain.getLastBlock();
@ -206,6 +198,18 @@ public class WorldManager {
ProgramResult result = program.getResult(); ProgramResult result = program.getResult();
applyProgramResult(result, gasDebit, trackRepository, applyProgramResult(result, gasDebit, trackRepository,
senderAddress, receiverAddress, coinbase, isContractCreation); senderAddress, receiverAddress, coinbase, isContractCreation);
} else {
// refund everything except fee (500 + 5*txdata)
BigInteger gasPrice = new BigInteger(1, tx.getGasPrice());
long dataFee = tx.getData() == null ? 0: tx.getData().length * GasCost.TXDATA;
long minTxFee = GasCost.TRANSACTION + dataFee;
BigInteger refund = gasDebit.subtract(BigInteger.valueOf(
minTxFee).multiply(gasPrice));
if (refund.signum() > 0) {
// gas refund
repository.addBalance(senderAddress, refund);
repository.addBalance(coinbase, refund.negate());
}
} }
} catch (RuntimeException e) { } catch (RuntimeException e) {
trackRepository.rollback(); trackRepository.rollback();
@ -276,7 +280,7 @@ public class WorldManager {
} }
public void applyBlock(Block block) { public void applyBlock(Block block) {
int i = 0; int i = 0;
for (Transaction tx : block.getTransactionsList()) { for (Transaction tx : block.getTransactionsList()) {
applyTransaction(tx, block.getCoinbase()); applyTransaction(tx, block.getCoinbase());