-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Improve EthereumListener #1152
base: develop
Are you sure you want to change the base?
Improve EthereumListener #1152
Changes from 32 commits
27c10b1
8165a2c
53e0173
d2fd027
80fe9f8
7a27d8d
350c5d1
c216d32
9627991
86e7ca4
c54d4b9
acb5e89
06c7022
f643b3c
5fcd91f
7fc9119
e1f739c
2e07934
7bf20ff
e41e31b
ab4754d
b214302
003ae12
7288636
442046b
a06646a
698b59a
feeff0c
d463bd1
0d61180
00d4609
3bd0f73
67e9c6a
d576607
f0bf19a
7ee5811
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,7 @@ logs | |
test_db* | ||
testnetSampleDb | ||
sampleDB* | ||
*sample*db* | ||
|
||
# Mac | ||
.DS_Store | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,24 +17,36 @@ | |
*/ | ||
package org.ethereum.config; | ||
|
||
import org.ethereum.core.EventDispatchThread; | ||
import org.ethereum.core.Repository; | ||
import org.ethereum.crypto.HashUtil; | ||
import org.ethereum.datasource.*; | ||
import org.ethereum.datasource.inmem.HashMapDB; | ||
import org.ethereum.datasource.leveldb.LevelDbDataSource; | ||
import org.ethereum.datasource.rocksdb.RocksDbDataSource; | ||
import org.ethereum.db.*; | ||
import org.ethereum.db.DbFlushManager; | ||
import org.ethereum.db.HeaderStore; | ||
import org.ethereum.db.PeerSource; | ||
import org.ethereum.db.RepositoryRoot; | ||
import org.ethereum.db.RepositoryWrapper; | ||
import org.ethereum.db.StateSource; | ||
import org.ethereum.listener.CompositeEthereumListener; | ||
import org.ethereum.listener.EthereumListener; | ||
import org.ethereum.net.eth.handler.Eth63; | ||
import org.ethereum.publish.Publisher; | ||
import org.ethereum.sync.FastSyncManager; | ||
import org.ethereum.validator.*; | ||
import org.ethereum.vm.DataWord; | ||
import org.ethereum.vm.program.ProgramPrecompile; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.config.BeanPostProcessor; | ||
import org.springframework.context.annotation.*; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.ComponentScan; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.context.annotation.Lazy; | ||
import org.springframework.context.annotation.Primary; | ||
import org.springframework.context.annotation.Scope; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashSet; | ||
|
@@ -76,7 +88,8 @@ BeanPostProcessor initializer() { | |
} | ||
|
||
|
||
@Bean @Primary | ||
@Bean | ||
@Primary | ||
public Repository repository() { | ||
return new RepositoryWrapper(); | ||
} | ||
|
@@ -86,15 +99,16 @@ public Repository defaultRepository() { | |
return new RepositoryRoot(stateSource(), null); | ||
} | ||
|
||
@Bean @Scope("prototype") | ||
@Bean | ||
@Scope("prototype") | ||
public Repository repository(byte[] stateRoot) { | ||
return new RepositoryRoot(stateSource(), stateRoot); | ||
} | ||
|
||
/** | ||
* A source of nodes for state trie and all contract storage tries. <br/> | ||
* This source provides contract code too. <br/><br/> | ||
* | ||
* <p> | ||
* Picks node by 16-bytes prefix of its key. <br/> | ||
* Within {@link NodeKeyCompositor} this source is a part of ref counting workaround<br/><br/> | ||
* | ||
|
@@ -126,7 +140,7 @@ public StateSource stateSource() { | |
@Bean | ||
@Scope("prototype") | ||
public Source<byte[], byte[]> cachedDbSource(String name) { | ||
AbstractCachedSource<byte[], byte[]> writeCache = new AsyncWriteCache<byte[], byte[]>(blockchainSource(name)) { | ||
AbstractCachedSource<byte[], byte[]> writeCache = new AsyncWriteCache<byte[], byte[]>(blockchainSource(name)) { | ||
@Override | ||
protected WriteCache<byte[], byte[]> createCache(Source<byte[], byte[]> source) { | ||
WriteCache.BytesKey<byte[]> ret = new WriteCache.BytesKey<>(source, WriteCache.CacheType.SIMPLE); | ||
|
@@ -166,7 +180,7 @@ public DbSource<byte[]> keyValueDataSource(String name, DbSettings settings) { | |
DbSource<byte[]> dbSource; | ||
if ("inmem".equals(dataSource)) { | ||
dbSource = new HashMapDB<>(); | ||
} else if ("leveldb".equals(dataSource)){ | ||
} else if ("leveldb".equals(dataSource)) { | ||
dbSource = levelDbDataSource(); | ||
} else { | ||
dataSource = "rocksdb"; | ||
|
@@ -221,9 +235,14 @@ private void resetDataSource(Source source) { | |
} | ||
} | ||
|
||
@Bean(name = "EthereumListener") | ||
public CompositeEthereumListener ethereumListener() { | ||
return new CompositeEthereumListener(); | ||
@Bean | ||
public Publisher publisher(EventDispatchThread eventDispatchThread) { | ||
return new Publisher(eventDispatchThread); | ||
} | ||
|
||
@Bean | ||
public CompositeEthereumListener compositeEthereumListener(EventDispatchThread eventDispatchThread) { | ||
return new CompositeEthereumListener(eventDispatchThread); | ||
} | ||
|
||
@Bean | ||
|
@@ -261,16 +280,18 @@ public byte[] serialize(byte[] object) { | |
DataWord addResult = ret.add(DataWord.ONE); | ||
return addResult.getLast20Bytes(); | ||
} | ||
|
||
public byte[] deserialize(byte[] stream) { | ||
throw new RuntimeException("Shouldn't be called"); | ||
} | ||
}, new Serializer<ProgramPrecompile, byte[]>() { | ||
public byte[] serialize(ProgramPrecompile object) { | ||
return object == null ? null : object.serialize(); | ||
} | ||
public ProgramPrecompile deserialize(byte[] stream) { | ||
return stream == null ? null : ProgramPrecompile.deserialize(stream); | ||
} | ||
public byte[] serialize(ProgramPrecompile object) { | ||
return object == null ? null : object.serialize(); | ||
} | ||
|
||
public ProgramPrecompile deserialize(byte[] stream) { | ||
return stream == null ? null : ProgramPrecompile.deserialize(stream); | ||
} | ||
}); | ||
} | ||
|
||
|
@@ -289,14 +310,14 @@ public DbFlushManager dbFlushManager() { | |
} | ||
|
||
@Bean | ||
public BlockHeaderValidator headerValidator() { | ||
public BlockHeaderValidator headerValidator(SystemProperties systemProperties, Publisher publisher) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think it'll be handy in all cases. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @eugene-shevchenko any thoughts on that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The method uses only in java config, and as I mentioned earlier such bean definition hides component dependencies. With no arguments option I should invoke three factory methods in method's body to get necessary dependencies. But if you think that no-args option is better I can revert method's signature. PS: It's sad that java config which should configure There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's not a bad thing if we want to get rid of Spring one day. |
||
|
||
List<BlockHeaderRule> rules = new ArrayList<>(asList( | ||
new GasValueRule(), | ||
new ExtraDataRule(systemProperties()), | ||
EthashRule.createRegular(systemProperties(), ethereumListener()), | ||
new GasLimitRule(systemProperties()), | ||
new BlockHashRule(systemProperties()) | ||
new ExtraDataRule(systemProperties), | ||
EthashRule.createRegular(systemProperties, publisher), | ||
new GasLimitRule(systemProperties), | ||
new BlockHashRule(systemProperties) | ||
)); | ||
|
||
return new BlockHeaderValidator(rules); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,14 +23,23 @@ | |
import org.ethereum.config.SystemProperties; | ||
import org.ethereum.crypto.HashUtil; | ||
import org.ethereum.datasource.inmem.HashMapDB; | ||
import org.ethereum.db.*; | ||
import org.ethereum.trie.Trie; | ||
import org.ethereum.trie.TrieImpl; | ||
import org.ethereum.db.BlockStore; | ||
import org.ethereum.db.ByteArrayWrapper; | ||
import org.ethereum.db.DbFlushManager; | ||
import org.ethereum.db.HeaderStore; | ||
import org.ethereum.db.IndexedBlockStore; | ||
import org.ethereum.db.PruneManager; | ||
import org.ethereum.db.StateSource; | ||
import org.ethereum.db.TransactionStore; | ||
import org.ethereum.listener.EthereumListener; | ||
import org.ethereum.listener.EthereumListenerAdapter; | ||
import org.ethereum.manager.AdminInfo; | ||
import org.ethereum.sync.SyncManager; | ||
import org.ethereum.util.*; | ||
import org.ethereum.trie.Trie; | ||
import org.ethereum.trie.TrieImpl; | ||
import org.ethereum.util.AdvancedDeviceUtils; | ||
import org.ethereum.util.ByteUtil; | ||
import org.ethereum.util.FastByteComparisons; | ||
import org.ethereum.util.RLP; | ||
import org.ethereum.validator.DependentBlockHeaderRule; | ||
import org.ethereum.validator.ParentBlockHeaderValidator; | ||
import org.ethereum.vm.hook.VMHook; | ||
|
@@ -66,7 +75,11 @@ | |
import static java.math.BigInteger.ZERO; | ||
import static java.util.Collections.emptyList; | ||
import static org.ethereum.core.Denomination.SZABO; | ||
import static org.ethereum.core.ImportResult.*; | ||
import static org.ethereum.core.ImportResult.EXIST; | ||
import static org.ethereum.core.ImportResult.IMPORTED_BEST; | ||
import static org.ethereum.core.ImportResult.IMPORTED_NOT_BEST; | ||
import static org.ethereum.core.ImportResult.INVALID_BLOCK; | ||
import static org.ethereum.core.ImportResult.NO_PARENT; | ||
import static org.ethereum.crypto.HashUtil.sha3; | ||
import static org.ethereum.util.ByteUtil.toHexString; | ||
|
||
|
@@ -111,7 +124,8 @@ public class BlockchainImpl implements Blockchain, org.ethereum.facade.Blockchai | |
private static final int MAGIC_REWARD_OFFSET = 8; | ||
public static final byte[] EMPTY_LIST_HASH = sha3(RLP.encodeList(new byte[0])); | ||
|
||
@Autowired @Qualifier("defaultRepository") | ||
@Autowired | ||
@Qualifier("defaultRepository") | ||
private Repository repository; | ||
|
||
@Autowired | ||
|
@@ -192,11 +206,11 @@ public BlockchainImpl(final SystemProperties config) { | |
} | ||
|
||
//todo: autowire over constructor | ||
public BlockchainImpl(final BlockStore blockStore, final Repository repository) { | ||
public BlockchainImpl(final BlockStore blockStore, final Repository repository, EthereumListener listener) { | ||
this.blockStore = blockStore; | ||
this.repository = repository; | ||
this.adminInfo = new AdminInfo(); | ||
this.listener = new EthereumListenerAdapter(); | ||
this.listener = listener; | ||
this.parentHeaderValidator = null; | ||
this.transactionStore = new TransactionStore(new HashMapDB()); | ||
this.eventDispatchThread = EventDispatchThread.getDefault(); | ||
|
@@ -214,11 +228,6 @@ public BlockchainImpl withAdminInfo(AdminInfo adminInfo) { | |
return this; | ||
} | ||
|
||
public BlockchainImpl withEthereumListener(EthereumListener listener) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Listener doesn't look the thing which is required for running |
||
this.listener = listener; | ||
return this; | ||
} | ||
|
||
public BlockchainImpl withSyncManager(SyncManager syncManager) { | ||
this.syncManager = syncManager; | ||
return this; | ||
|
@@ -503,7 +512,7 @@ public synchronized Block createNewBlock(Block parent, List<Transaction> txs, Li | |
new byte[0], // nonce (to mine) | ||
new byte[0], // receiptsRoot - computed after running all transactions | ||
calcTxTrie(txs), // TransactionsRoot - computed after running all transactions | ||
new byte[] {0}, // stateRoot - computed after running all transactions | ||
new byte[]{0}, // stateRoot - computed after running all transactions | ||
txs, | ||
null); // uncle list | ||
|
||
|
@@ -835,7 +844,7 @@ public static Set<ByteArrayWrapper> getAncestors(BlockStore blockStore, Block te | |
if (!isParentBlock) { | ||
it = blockStore.getBlockByHash(it.getParentHash()); | ||
} | ||
while(it != null && it.getNumber() >= limitNum) { | ||
while (it != null && it.getNumber() >= limitNum) { | ||
ret.add(new ByteArrayWrapper(it.getHash())); | ||
it = blockStore.getBlockByHash(it.getParentHash()); | ||
} | ||
|
@@ -849,7 +858,7 @@ public Set<ByteArrayWrapper> getUsedUncles(BlockStore blockStore, Block testedBl | |
if (!isParentBlock) { | ||
it = blockStore.getBlockByHash(it.getParentHash()); | ||
} | ||
while(it.getNumber() > limitNum) { | ||
while (it.getNumber() > limitNum) { | ||
for (BlockHeader uncle : it.getUncleList()) { | ||
ret.add(new ByteArrayWrapper(uncle.getHash())); | ||
} | ||
|
@@ -964,7 +973,7 @@ private Map<byte[], BigInteger> addReward(Repository track, Block block, List<Tr | |
.multiply(BigInteger.valueOf(MAGIC_REWARD_OFFSET + uncle.getNumber() - block.getNumber())) | ||
.divide(BigInteger.valueOf(MAGIC_REWARD_OFFSET)); | ||
|
||
track.addBalance(uncle.getCoinbase(),uncleReward); | ||
track.addBalance(uncle.getCoinbase(), uncleReward); | ||
BigInteger existingUncleReward = rewards.get(uncle.getCoinbase()); | ||
if (existingUncleReward == null) { | ||
rewards.put(uncle.getCoinbase(), uncleReward); | ||
|
@@ -1107,7 +1116,7 @@ private void recordBlock(Block block) { | |
|
||
public void updateBlockTotDifficulties(long startFrom) { | ||
// no synchronization here not to lock instance for long period | ||
while(true) { | ||
while (true) { | ||
synchronized (this) { | ||
((IndexedBlockStore) blockStore).updateTotDifficulties(startFrom); | ||
|
||
|
@@ -1131,7 +1140,7 @@ public void updateBlockTotDifficulties(long startFrom) { | |
} | ||
} | ||
|
||
if (totalDifficulty.compareTo(maxTD) < 0) { | ||
if (totalDifficulty.compareTo(maxTD) < 0) { | ||
blockStore.reBranch(bestStoredBlock); | ||
bestBlock = bestStoredBlock; | ||
totalDifficulty = maxTD; | ||
|
@@ -1228,7 +1237,7 @@ public Iterator<BlockHeader> getIteratorOfHeadersStartFrom(BlockIdentifier ident | |
* Searches block in blockStore, if it's not found there | ||
* and headerStore is defined, searches blockHeader in it. | ||
* @param number block number | ||
* @return Block header | ||
* @return Block header | ||
*/ | ||
private BlockHeader findHeaderByNumber(long number) { | ||
Block block = blockStore.getChainBlockByNumber(number); | ||
|
@@ -1392,7 +1401,7 @@ public byte[] next() { | |
} | ||
|
||
private class State { | ||
// Repository savedRepo = repository; | ||
// Repository savedRepo = repository; | ||
byte[] root = repository.getRoot(); | ||
Block savedBest = bestBlock; | ||
BigInteger savedTD = totalDifficulty; | ||
|
Uh oh!
There was an error while loading. Please reload this page.