Apply blockReward after txs and for uncles
This commit is contained in:
parent
2d7bcf64b5
commit
da87d80846
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue