Merge pull request #62 from nicksavers/master
Refactoring uncle reward and wallet processing
This commit is contained in:
commit
eb382199cc
|
@ -37,6 +37,8 @@ public class Block {
|
|||
/* A scalar value equal to the mininum limit of gas expenditure per block */
|
||||
private static long MIN_GAS_LIMIT = 125000L;
|
||||
public static BigInteger BLOCK_REWARD = BigInteger.valueOf(1500000000000000000L);
|
||||
public static BigInteger UNCLE_REWARD = BLOCK_REWARD.multiply(
|
||||
BigInteger.valueOf(7)).divide(BigInteger.valueOf(8));
|
||||
|
||||
private BlockHeader header;
|
||||
|
||||
|
@ -91,7 +93,7 @@ public class Block {
|
|||
|
||||
// Parse Transactions
|
||||
RLPList txReceipts = (RLPList) block.get(1);
|
||||
this.processTxs(txReceipts);
|
||||
this.parseTxs(txReceipts);
|
||||
|
||||
// Parse Uncles
|
||||
RLPList uncleBlocks = (RLPList) block.get(2);
|
||||
|
@ -259,7 +261,7 @@ public class Block {
|
|||
return toStringBuff.toString();
|
||||
}
|
||||
|
||||
private void processTxs(RLPList txReceipts) {
|
||||
private void parseTxs(RLPList txReceipts) {
|
||||
|
||||
this.txsState = new Trie(null);
|
||||
for (int i = 0; i < txReceipts.size(); i++) {
|
||||
|
|
|
@ -2,7 +2,6 @@ package org.ethereum.core;
|
|||
|
||||
import org.ethereum.db.DatabaseImpl;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
import org.ethereum.net.submit.WalletTransaction;
|
||||
import org.ethereum.util.ByteUtil;
|
||||
import org.iq80.leveldb.DBIterator;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -54,7 +53,6 @@ public class Blockchain {
|
|||
private static long INITIAL_MIN_GAS_PRICE = 10 * SZABO.longValue();
|
||||
|
||||
private DatabaseImpl chainDb;
|
||||
private Wallet wallet;
|
||||
|
||||
private long gasPrice = 1000;
|
||||
private Block lastBlock;
|
||||
|
@ -63,11 +61,6 @@ public class Blockchain {
|
|||
// convenient usage, <block_number, block_hash>
|
||||
private Map<Long, byte[]> index = new HashMap<>();
|
||||
|
||||
// This map of transaction designed
|
||||
// to approve the tx by external trusted peer
|
||||
private Map<String, WalletTransaction> walletTransactions =
|
||||
Collections.synchronizedMap(new HashMap<String, WalletTransaction>());
|
||||
|
||||
public Blockchain() {
|
||||
this.chainDb = new DatabaseImpl("blockchain");
|
||||
}
|
||||
|
@ -108,7 +101,7 @@ public class Blockchain {
|
|||
String blockParentHash = Hex.toHexString(firstBlockToAdd.getParentHash());
|
||||
if (!hashLast.equals(blockParentHash)) return;
|
||||
}
|
||||
for (int i = blocks.size() - 1; i >= 0 ; --i) {
|
||||
for (int i = blocks.size() - 1; i >= 0 ; --i) {
|
||||
this.addBlock(blocks.get(i));
|
||||
|
||||
/* Debug check to see if the state is still as expected */
|
||||
|
@ -124,7 +117,7 @@ public class Blockchain {
|
|||
for (Transaction tx : block.getTransactionsList()) {
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("pending cleanup: tx.hash: [{}]", Hex.toHexString( tx.getHash()));
|
||||
this.removeWalletTransaction(tx);
|
||||
WorldManager.getInstance().removeWalletTransaction(tx);
|
||||
}
|
||||
}
|
||||
logger.info("*** Block chain size: [ {} ]", this.getSize());
|
||||
|
@ -133,13 +126,17 @@ public class Blockchain {
|
|||
public void addBlock(Block block) {
|
||||
if(block.isValid()) {
|
||||
|
||||
if (!block.isGenesis())
|
||||
if (!block.isGenesis()) {
|
||||
for (Transaction tx : block.getTransactionsList())
|
||||
// TODO: refactor the wallet pending transactions to the world manager
|
||||
WorldManager.getInstance().addWalletTransaction(tx);
|
||||
WorldManager.getInstance().applyBlock(block);
|
||||
}
|
||||
|
||||
this.chainDb.put(ByteUtil.longToBytes(block.getNumber()), block.getEncoded());
|
||||
this.index.put(block.getNumber(), block.getEncoded());
|
||||
|
||||
this.wallet.processBlock(block);
|
||||
WorldManager.getInstance().getWallet().processBlock(block);
|
||||
this.updateGasPrice(block);
|
||||
this.setLastBlock(block);
|
||||
if (logger.isDebugEnabled())
|
||||
|
@ -158,37 +155,6 @@ public class Blockchain {
|
|||
return gasPrice;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* 1) the dialog put a pending transaction on the list
|
||||
* 2) the dialog send the transaction to a net
|
||||
* 3) wherever the transaction got in from the wire it will change to approve state
|
||||
* 4) only after the approve a) Wallet state changes
|
||||
* 5) After the block is received with that tx the pending been clean up
|
||||
*/
|
||||
public WalletTransaction addWalletTransaction(Transaction transaction) {
|
||||
String hash = Hex.toHexString(transaction.getHash());
|
||||
logger.info("pending transaction placed hash: {}", hash );
|
||||
|
||||
WalletTransaction walletTransaction = this.walletTransactions.get(hash);
|
||||
if (walletTransaction != null)
|
||||
walletTransaction.incApproved();
|
||||
else {
|
||||
walletTransaction = new WalletTransaction(transaction);
|
||||
this.walletTransactions.put(hash, walletTransaction);
|
||||
}
|
||||
return walletTransaction;
|
||||
}
|
||||
|
||||
public void removeWalletTransaction(Transaction transaction) {
|
||||
String hash = Hex.toHexString(transaction.getHash());
|
||||
logger.info("pending transaction removed with hash: {} ", hash);
|
||||
walletTransactions.remove(hash);
|
||||
}
|
||||
|
||||
public void setWallet(Wallet wallet) {
|
||||
this.wallet = wallet;
|
||||
}
|
||||
|
||||
public byte[] getLatestBlockHash() {
|
||||
if (index.isEmpty())
|
||||
return Genesis.getInstance().getHash();
|
||||
|
|
|
@ -5,7 +5,6 @@ import static org.ethereum.config.SystemProperties.CONFIG;
|
|||
import java.math.BigInteger;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.ethereum.core.AccountState;
|
||||
|
@ -16,6 +15,7 @@ import org.ethereum.core.Wallet;
|
|||
import org.ethereum.crypto.ECKey;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.net.submit.WalletTransaction;
|
||||
import org.ethereum.vm.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -40,6 +40,11 @@ public class WorldManager {
|
|||
|
||||
private Map<String, Transaction> pendingTransactions = Collections
|
||||
.synchronizedMap(new HashMap<String, Transaction>());
|
||||
|
||||
// This map of transaction designed
|
||||
// to approve the tx by external trusted peer
|
||||
private Map<String, WalletTransaction> walletTransactions =
|
||||
Collections.synchronizedMap(new HashMap<String, WalletTransaction>());
|
||||
|
||||
private static WorldManager instance;
|
||||
|
||||
|
@ -59,8 +64,6 @@ public class WorldManager {
|
|||
String secret = CONFIG.coinbaseSecret();
|
||||
byte[] cbAddr = HashUtil.sha3(secret.getBytes());
|
||||
wallet.importKey(cbAddr);
|
||||
|
||||
blockchain.setWallet(wallet);
|
||||
}
|
||||
|
||||
public static WorldManager getInstance() {
|
||||
|
@ -73,10 +76,6 @@ public class WorldManager {
|
|||
|
||||
public void applyTransaction(Transaction tx, byte[] coinbase) {
|
||||
|
||||
// TODO: refactor the wallet pending transactions to the world manager
|
||||
if (blockchain != null)
|
||||
blockchain.addWalletTransaction(tx);
|
||||
|
||||
byte[] senderAddress = tx.getSender();
|
||||
AccountState senderAccount = repository.getAccountState(senderAddress);
|
||||
|
||||
|
@ -276,12 +275,10 @@ public class WorldManager {
|
|||
}
|
||||
}
|
||||
|
||||
private static BigInteger UNCLE_RATIO = BigInteger.valueOf(7).divide(BigInteger.valueOf(8));
|
||||
public void applyBlock(Block block) {
|
||||
|
||||
int i = 0;
|
||||
List<Transaction> txList = block.getTransactionsList();
|
||||
for (Transaction tx : txList) {
|
||||
for (Transaction tx : block.getTransactionsList()) {
|
||||
applyTransaction(tx, block.getCoinbase());
|
||||
repository.dumpState(block.getNumber(), i,
|
||||
Hex.toHexString(tx.getHash()));
|
||||
|
@ -293,9 +290,40 @@ public class WorldManager {
|
|||
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));
|
||||
repository.addBalance(uncle.getCoinbase(), Block.UNCLE_REWARD);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* 1) the dialog put a pending transaction on the list
|
||||
* 2) the dialog send the transaction to a net
|
||||
* 3) wherever the transaction got in from the wire it will change to approve state
|
||||
* 4) only after the approve a) Wallet state changes
|
||||
* 5) After the block is received with that tx the pending been clean up
|
||||
*/
|
||||
public WalletTransaction addWalletTransaction(Transaction transaction) {
|
||||
String hash = Hex.toHexString(transaction.getHash());
|
||||
logger.info("pending transaction placed hash: {}", hash );
|
||||
|
||||
WalletTransaction walletTransaction = this.walletTransactions.get(hash);
|
||||
if (walletTransaction != null)
|
||||
walletTransaction.incApproved();
|
||||
else {
|
||||
walletTransaction = new WalletTransaction(transaction);
|
||||
this.walletTransactions.put(hash, walletTransaction);
|
||||
}
|
||||
return walletTransaction;
|
||||
}
|
||||
|
||||
public void removeWalletTransaction(Transaction transaction) {
|
||||
String hash = Hex.toHexString(transaction.getHash());
|
||||
logger.info("pending transaction removed with hash: {} ", hash);
|
||||
walletTransactions.remove(hash);
|
||||
}
|
||||
|
||||
public void setWallet(Wallet wallet) {
|
||||
this.wallet = wallet;
|
||||
}
|
||||
|
||||
public Repository getRepository() {
|
||||
return repository;
|
||||
|
|
|
@ -35,7 +35,7 @@ public class TransactionTask implements Callable<Transaction> {
|
|||
ClientPeer peer = MainData.instance.getActivePeer();
|
||||
|
||||
WalletTransaction walletTransaction = WorldManager.getInstance()
|
||||
.getBlockChain().addWalletTransaction(tx);
|
||||
.addWalletTransaction(tx);
|
||||
peer.sendTransaction(tx);
|
||||
|
||||
while(walletTransaction.getApproved() < 1 ) {
|
||||
|
@ -44,7 +44,7 @@ public class TransactionTask implements Callable<Transaction> {
|
|||
logger.info("return approved: {}", walletTransaction.getApproved());
|
||||
} catch (Throwable th) {
|
||||
logger.info("exception caugh: {}", th);
|
||||
WorldManager.getInstance().getBlockChain().removeWalletTransaction(tx);
|
||||
WorldManager.getInstance().removeWalletTransaction(tx);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue