Merge pull request #60 from nicksavers/master
Clean and speed up applyTransaction
This commit is contained in:
commit
0bcf41be5b
|
@ -85,7 +85,6 @@ public class WorldManager {
|
||||||
|
|
||||||
// 1. VALIDATE THE NONCE
|
// 1. VALIDATE THE NONCE
|
||||||
byte[] senderAddress = tx.getSender();
|
byte[] senderAddress = tx.getSender();
|
||||||
|
|
||||||
AccountState senderAccount = repository.getAccountState(senderAddress);
|
AccountState senderAccount = repository.getAccountState(senderAddress);
|
||||||
|
|
||||||
if (senderAccount == null) {
|
if (senderAccount == null) {
|
||||||
|
@ -95,11 +94,12 @@ public class WorldManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BigInteger nonce = repository.getNonce(senderAddress);
|
BigInteger nonce = senderAccount.getNonce();
|
||||||
if (nonce.compareTo(new BigInteger(tx.getNonce())) != 0) {
|
BigInteger txNonce = new BigInteger(tx.getNonce());
|
||||||
|
if (nonce.compareTo(txNonce) != 0) {
|
||||||
if (stateLogger.isWarnEnabled())
|
if (stateLogger.isWarnEnabled())
|
||||||
stateLogger.warn("Invalid nonce account.nonce={} tx.nonce={}",
|
stateLogger.warn("Invalid nonce account.nonce={} tx.nonce={}",
|
||||||
nonce.longValue(), new BigInteger(tx.getNonce()));
|
nonce, txNonce);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,41 +113,33 @@ public class WorldManager {
|
||||||
if (coinbase != null)
|
if (coinbase != null)
|
||||||
repository.addBalance(coinbase, gasDebit);
|
repository.addBalance(coinbase, gasDebit);
|
||||||
|
|
||||||
byte[] contractAddress;
|
byte[] receiverAddress;
|
||||||
|
|
||||||
// Contract creation or existing Contract call
|
// Contract creation or existing Contract call
|
||||||
if (tx.isContractCreation()) {
|
if (tx.isContractCreation()) {
|
||||||
|
|
||||||
// credit the receiver
|
receiverAddress = tx.getContractAddress();
|
||||||
contractAddress = tx.getContractAddress();
|
repository.createAccount(receiverAddress);
|
||||||
repository.createAccount(contractAddress);
|
|
||||||
stateLogger.info("New contract created address={}",
|
stateLogger.info("New contract created address={}",
|
||||||
Hex.toHexString(contractAddress));
|
Hex.toHexString(receiverAddress));
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
contractAddress = tx.getReceiveAddress();
|
receiverAddress = tx.getReceiveAddress();
|
||||||
AccountState receiverState = repository.getAccountState(tx
|
AccountState receiverState = repository.getAccountState(receiverAddress);
|
||||||
.getReceiveAddress());
|
|
||||||
|
|
||||||
if (receiverState == null) {
|
if (receiverState == null) {
|
||||||
repository.createAccount(tx.getReceiveAddress());
|
repository.createAccount(receiverAddress);
|
||||||
if (stateLogger.isInfoEnabled())
|
if (stateLogger.isInfoEnabled())
|
||||||
stateLogger.info("New account created address={}",
|
stateLogger.info("New receiver account created address={}",
|
||||||
Hex.toHexString(tx.getReceiveAddress()));
|
Hex.toHexString(receiverAddress));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.2 UPDATE THE NONCE
|
// 2.2 UPDATE THE NONCE
|
||||||
// (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION)
|
// (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION)
|
||||||
BigInteger balance = repository.getBalance(senderAddress);
|
BigInteger balance = senderAccount.getBalance();
|
||||||
if (balance.compareTo(BigInteger.ZERO) == 1) {
|
if (balance.compareTo(BigInteger.ZERO) == 1) {
|
||||||
repository.increaseNonce(senderAddress);
|
repository.increaseNonce(senderAddress);
|
||||||
|
|
||||||
if (stateLogger.isInfoEnabled())
|
|
||||||
stateLogger.info(
|
|
||||||
"Before contract execution the sender address debit with gas total cost, "
|
|
||||||
+ "\n sender={} \n gas_debit= {}",
|
|
||||||
Hex.toHexString(tx.getSender()), gasDebit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// actual gas value debit from the sender
|
// actual gas value debit from the sender
|
||||||
|
@ -157,10 +149,15 @@ public class WorldManager {
|
||||||
if (gasDebit.signum() == 1) {
|
if (gasDebit.signum() == 1) {
|
||||||
if (balance.compareTo(gasDebit) == -1) {
|
if (balance.compareTo(gasDebit) == -1) {
|
||||||
logger.info("No gas to start the execution: sender={}",
|
logger.info("No gas to start the execution: sender={}",
|
||||||
Hex.toHexString(tx.getSender()));
|
Hex.toHexString(senderAddress));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
repository.addBalance(senderAddress, gasDebit.negate());
|
repository.addBalance(senderAddress, gasDebit.negate());
|
||||||
|
if (stateLogger.isInfoEnabled())
|
||||||
|
stateLogger.info(
|
||||||
|
"Before contract execution debit the sender address with gas total cost, "
|
||||||
|
+ "\n sender={} \n gas_debit= {}",
|
||||||
|
Hex.toHexString(senderAddress), gasDebit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. START TRACKING FOR REVERT CHANGES OPTION !!!
|
// 3. START TRACKING FOR REVERT CHANGES OPTION !!!
|
||||||
|
@ -172,11 +169,11 @@ public class WorldManager {
|
||||||
// 4. THE SIMPLE VALUE/BALANCE CHANGE
|
// 4. THE SIMPLE VALUE/BALANCE CHANGE
|
||||||
if (tx.getValue() != null) {
|
if (tx.getValue() != null) {
|
||||||
|
|
||||||
BigInteger senderBalance = repository.getBalance(senderAddress);
|
BigInteger senderBalance = senderAccount.getBalance();
|
||||||
|
|
||||||
if (senderBalance.compareTo(new BigInteger(1, tx.getValue())) >= 0) {
|
if (senderBalance.compareTo(new BigInteger(1, tx.getValue())) >= 0) {
|
||||||
|
|
||||||
repository.addBalance(contractAddress,
|
repository.addBalance(receiverAddress,
|
||||||
new BigInteger(1, tx.getValue()));
|
new BigInteger(1, tx.getValue()));
|
||||||
repository.addBalance(senderAddress,
|
repository.addBalance(senderAddress,
|
||||||
new BigInteger(1, tx.getValue()).negate());
|
new BigInteger(1, tx.getValue()).negate());
|
||||||
|
@ -185,53 +182,40 @@ public class WorldManager {
|
||||||
stateLogger.info("Update value balance \n "
|
stateLogger.info("Update value balance \n "
|
||||||
+ "sender={}, receiver={}, value={}",
|
+ "sender={}, receiver={}, value={}",
|
||||||
Hex.toHexString(senderAddress),
|
Hex.toHexString(senderAddress),
|
||||||
Hex.toHexString(contractAddress),
|
Hex.toHexString(receiverAddress),
|
||||||
new BigInteger(tx.getValue()));
|
new BigInteger(tx.getValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. FIND OUT WHAT IS THE TRANSACTION TYPE
|
byte[] code;
|
||||||
if (tx.isContractCreation()) {
|
boolean isContractCreation = tx.isContractCreation();
|
||||||
|
// 3. FIND OUT THE TRANSACTION TYPE
|
||||||
byte[] initCode = tx.getData();
|
if (isContractCreation) {
|
||||||
|
code = tx.getData(); // init code
|
||||||
if (logger.isInfoEnabled())
|
if (logger.isInfoEnabled())
|
||||||
logger.info("running the init for contract: address={}",
|
logger.info("running the init for contract: address={}",
|
||||||
Hex.toHexString(tx.getContractAddress()));
|
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) {
|
||||||
Block lastBlock = blockchain.getLastBlock();
|
Block lastBlock = blockchain.getLastBlock();
|
||||||
|
|
||||||
ProgramInvoke programInvoke = ProgramInvokeFactory
|
ProgramInvoke programInvoke = ProgramInvokeFactory
|
||||||
.createProgramInvoke(tx, lastBlock, trackRepository);
|
.createProgramInvoke(tx, lastBlock, trackRepository);
|
||||||
|
|
||||||
VM vm = new VM();
|
VM vm = new VM();
|
||||||
Program program = new Program(initCode, programInvoke);
|
Program program = new Program(code, programInvoke);
|
||||||
vm.play(program);
|
vm.play(program);
|
||||||
ProgramResult result = program.getResult();
|
ProgramResult result = program.getResult();
|
||||||
applyProgramResult(result, gasDebit, trackRepository,
|
applyProgramResult(result, gasDebit, trackRepository,
|
||||||
senderAddress, tx.getContractAddress(), coinbase, true);
|
senderAddress, receiverAddress, coinbase, isContractCreation);
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
byte[] programCode = trackRepository.getCode(tx.getReceiveAddress());
|
|
||||||
if (programCode != null) {
|
|
||||||
|
|
||||||
if (logger.isInfoEnabled())
|
|
||||||
logger.info("calling for existing contract: address={}",
|
|
||||||
Hex.toHexString(tx.getReceiveAddress()));
|
|
||||||
|
|
||||||
Block lastBlock = blockchain.getLastBlock();
|
|
||||||
|
|
||||||
ProgramInvoke programInvoke = ProgramInvokeFactory
|
|
||||||
.createProgramInvoke(tx, lastBlock, trackRepository);
|
|
||||||
|
|
||||||
VM vm = new VM();
|
|
||||||
Program program = new Program(programCode, programInvoke);
|
|
||||||
vm.play(program);
|
|
||||||
ProgramResult result = program.getResult();
|
|
||||||
applyProgramResult(result, gasDebit, trackRepository,
|
|
||||||
senderAddress, tx.getReceiveAddress(), coinbase,false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
trackRepository.rollback();
|
trackRepository.rollback();
|
||||||
|
|
Loading…
Reference in New Issue