Apply blockReward after txs and for uncles

This commit is contained in:
nicksavers 2014-07-11 13:53:43 +02:00
parent 2d7bcf64b5
commit da87d80846
7 changed files with 231 additions and 264 deletions

View File

@ -117,8 +117,7 @@ public class Blockchain {
String worldStateRootHash = Hex.toHexString(WorldManager.getInstance().getRepository().getWorldState().getRootHash());
if(!blockStateRootHash.equals(worldStateRootHash))
logger.warn("WARNING: STATE CONFLICT! worldstate {} mismatch", worldStateRootHash);
}
}
}
// Remove all wallet transactions as they already approved by the net
for (Block block : blocks) {

View File

@ -35,9 +35,7 @@ public class ProgramPlayDialog extends JPanel implements ActionListener,
VM vm = new VM();
ProgramInvoke pi = new ProgramInvokeMockImpl();
Program program = new Program(code ,
pi);
Program program = new Program(code, pi);
program.addListener(this);
program.fullTrace();

View File

@ -77,9 +77,6 @@ public class WorldManager {
if (blockchain != null)
blockchain.addWalletTransaction(tx);
// TODO: what is going on with simple wallet transfer ?
// 1. VALIDATE THE NONCE
byte[] senderAddress = tx.getSender();
AccountState senderAccount = repository.getAccountState(senderAddress);
@ -90,6 +87,7 @@ public class WorldManager {
return;
}
// 1. VALIDATE THE NONCE
BigInteger nonce = senderAccount.getNonce();
BigInteger txNonce = new BigInteger(tx.getNonce());
if (nonce.compareTo(txNonce) != 0) {
@ -105,18 +103,15 @@ public class WorldManager {
// first of all debit the gas from the issuer
BigInteger gasDebit = tx.getTotalGasValueDebit();
byte[] receiverAddress;
// Contract creation or existing Contract call
if (tx.isContractCreation()) {
receiverAddress = tx.getContractAddress();
repository.createAccount(receiverAddress);
stateLogger.info("New contract created address={}",
Hex.toHexString(receiverAddress));
} else {
receiverAddress = tx.getReceiveAddress();
AccountState receiverState = repository.getAccountState(receiverAddress);
@ -130,22 +125,19 @@ public class WorldManager {
// 2.2 UPDATE THE NONCE
// (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION)
BigInteger balance = senderAccount.getBalance();
if (balance.compareTo(BigInteger.ZERO) == 1) {
repository.increaseNonce(senderAddress);
}
repository.increaseNonce(senderAddress);
// actual gas value debit from the sender
// the purchase gas will be available for the
// contract in the execution state, and
// can be validate using GAS op
if (gasDebit.signum() == 1) {
BigInteger balance = senderAccount.getBalance();
if (balance.compareTo(gasDebit) == -1) {
logger.info("No gas to start the execution: sender={}",
Hex.toHexString(senderAddress));
return;
}
repository.addBalance(senderAddress, gasDebit.negate());
// The coinbase get the gas cost
@ -172,7 +164,6 @@ public class WorldManager {
BigInteger senderBalance = senderAccount.getBalance();
if (senderBalance.compareTo(new BigInteger(1, tx.getValue())) >= 0) {
repository.addBalance(receiverAddress,
new BigInteger(1, tx.getValue()));
repository.addBalance(senderAddress,
@ -242,7 +233,6 @@ public class WorldManager {
&& result.getException() instanceof Program.OutOfGasException) {
logger.info("contract run halted by OutOfGas: contract={}",
Hex.toHexString(contractAddress));
throw result.getException();
}
@ -262,40 +252,33 @@ public class WorldManager {
repository.addBalance(coinbase, refund.negate());
}
if (initResults){
if (initResults) {
// Save the code created by init
byte[] bodyCode = null;
if (result.getHReturn() != null) {
bodyCode = result.getHReturn().array();
}
if (bodyCode != null) {
repository.saveCode(contractAddress, bodyCode);
if (stateLogger.isInfoEnabled())
stateLogger
.info("saving code of the contract to the db:\n contract={} code={}",
Hex.toHexString(contractAddress),
Hex.toHexString(bodyCode));
}
if (bodyCode != null) {
repository.saveCode(contractAddress, bodyCode);
if (stateLogger.isInfoEnabled())
stateLogger
.info("saving code of the contract to the db:\n contract={} code={}",
Hex.toHexString(contractAddress),
Hex.toHexString(bodyCode));
}
}
// delete the marked to die accounts
if (result.getDeleteAccounts() == null) return;
for (DataWord address : result.getDeleteAccounts()){
repository.delete(address.getNoLeadZeroesData());
}
}
private static BigInteger UNCLE_RATIO = BigInteger.valueOf(7).divide(BigInteger.valueOf(8));
public void applyBlock(Block block) {
// miner reward
if (repository.getAccountState(block.getCoinbase()) == null)
repository.createAccount(block.getCoinbase());
repository.addBalance(block.getCoinbase(), Block.BLOCK_REWARD);
int i = 0;
List<Transaction> txList = block.getTransactionsList();
for (Transaction tx : txList) {
@ -304,12 +287,14 @@ public class WorldManager {
Hex.toHexString(tx.getHash()));
++i;
}
}
public void applyBlockList(List<Block> blocks) {
for (int i = blocks.size() - 1; i >= 0; --i) {
applyBlock(blocks.get(i));
}
// miner reward
if (repository.getAccountState(block.getCoinbase()) == null)
repository.createAccount(block.getCoinbase());
repository.addBalance(block.getCoinbase(), Block.BLOCK_REWARD);
for (Block uncle : block.getUncleList()) {
repository.addBalance(uncle.getCoinbase(), Block.BLOCK_REWARD.multiply(UNCLE_RATIO));
}
}
public Repository getRepository() {

View File

@ -208,14 +208,14 @@ public class Program {
}
}
public void suicide(DataWord obtainer){
public void suicide(DataWord obtainer) {
// 1) pass full endowment to the obtainer
if (logger.isInfoEnabled())
logger.info("Transfer to: [ {} ] heritage: [ {} ]", Hex.toHexString(obtainer.getNoLeadZeroesData())
, getBalance().longValue());
this.result.repository.addBalance(obtainer.getNoLeadZeroesData(),
this.result.getRepository().addBalance(obtainer.getNoLeadZeroesData(),
getBalance().value());
// 2) mark the account as for delete
@ -224,8 +224,7 @@ public class Program {
public void createContract(DataWord gas, DataWord memStart, DataWord memSize) {
if (invokeData.byTestingSuite()){
if (invokeData.byTestingSuite()) {
logger.info("[testing suite] - omit real create");
return;
}
@ -291,7 +290,7 @@ public class Program {
// 5. REFUND THE REMAIN GAS
BigInteger refundGas = gas.value().subtract(BigInteger.valueOf(result.getGasUsed()));
if (refundGas.compareTo(BigInteger.ZERO) == 1){
if (refundGas.compareTo(BigInteger.ZERO) == 1) {
this.refundGas(refundGas.intValue(), "remain gas from the internal call");
logger.info("The remain gas refunded, account: [ {} ], gas: [ {} ] ",
@ -341,7 +340,7 @@ public class Program {
BigInteger endowment = endowmentValue.value();
BigInteger senderBalance = result.getRepository().getBalance(senderAddress);
if (senderBalance.compareTo(endowment) < 0){
if (senderBalance.compareTo(endowment) < 0) {
stackPushZero();
return;
}
@ -449,7 +448,7 @@ public class Program {
public void storageSave(byte[] key, byte[] val) {
DataWord keyWord = new DataWord(key);
DataWord valWord = new DataWord(val);
result.repository.addStorageRow(this.programAddress, keyWord, valWord);
result.getRepository().addStorageRow(this.programAddress, keyWord, valWord);
}
public DataWord getOwnerAddress() {
@ -504,7 +503,7 @@ public class Program {
}
public DataWord storageLoad(DataWord key) {
return result.repository.getStorageValue(this.programAddress, key);
return result.getRepository().getStorageValue(this.programAddress, key);
}
public DataWord getPrevHash() {

View File

@ -13,23 +13,14 @@ import java.util.Map;
public class ProgramInvokeImpl implements ProgramInvoke {
/*** TRANSACTION env ***/
DataWord address;
DataWord origin;
DataWord caller;
DataWord balance;
DataWord gas;
DataWord gasPrice;
DataWord callValue;
private DataWord address, origin, caller,
balance, gas, gasPrice, callValue;
byte[] msgData;
/*** BLOCK env ***/
DataWord prevHash;
DataWord coinbase;
DataWord timestamp;
DataWord number;
DataWord difficulty;
DataWord gaslimit;
private DataWord prevHash, coinbase, timestamp,
number, difficulty, gaslimit;
Map<DataWord, DataWord> storage;
@ -104,7 +95,6 @@ public class ProgramInvokeImpl implements ProgramInvoke {
/* ADDRESS op */
public DataWord getOwnerAddress() {
return address;
}

View File

@ -18,14 +18,14 @@ public class ProgramResult {
private RuntimeException exception;
private List<DataWord> deleteAccounts;
Repository repository = null;
private Repository repository = null;
/*
* for testing runs ,
* call/create is not executed
* but dummy recorded
*/
List<CallCreate> callCreateList;
private List<CallCreate> callCreateList;
public void spendGas(int gas) {
gasUsed += gas;
@ -92,11 +92,9 @@ public class ProgramResult {
return callCreateList;
}
public void addCallCreate(byte[] data, byte[] destination, byte[] gasLimit, byte[] value){
if (callCreateList == null)
callCreateList = new ArrayList<>();
callCreateList.add(new CallCreate(data, destination, gasLimit, value));
}
public void addCallCreate(byte[] data, byte[] destination, byte[] gasLimit, byte[] value) {
if (callCreateList == null)
callCreateList = new ArrayList<>();
callCreateList.add(new CallCreate(data, destination, gasLimit, value));
}
}

File diff suppressed because it is too large Load Diff