From 27c10b12a9efc2408fa1fa197d892b69f5c176f7 Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Thu, 9 Aug 2018 01:58:13 +0300 Subject: [PATCH 01/28] Replaces CompositeEthereumListener with new pub/sub model implementation. --- .../org/ethereum/config/CommonConfig.java | 52 +-- .../org/ethereum/core/BlockchainImpl.java | 74 ++--- .../org/ethereum/core/PendingStateImpl.java | 48 ++- .../ethereum/core/TransactionExecutor.java | 22 +- .../java/org/ethereum/db/DbFlushManager.java | 31 +- .../org/ethereum/facade/EthereumImpl.java | 39 ++- .../listener/CompositeEthereumListener.java | 269 ---------------- .../ethereum/listener/GasPriceTracker.java | 15 +- .../org/ethereum/manager/WorldManager.java | 47 ++- .../java/org/ethereum/mine/BlockMiner.java | 58 ++-- .../org/ethereum/net/eth/handler/Eth62.java | 18 +- .../org/ethereum/net/eth/handler/Eth63.java | 13 +- .../ethereum/net/eth/handler/EthHandler.java | 54 ++-- .../java/org/ethereum/publish/Publisher.java | 300 ++++++++++++++++++ .../org/ethereum/publish/Subscription.java | 86 +++++ .../publish/event/BestBlockAddedEvent.java | 28 ++ .../publish/event/BlockAddedEvent.java | 10 + .../org/ethereum/publish/event/Event.java | 36 +++ .../publish/event/NoConnectionsEvent.java | 4 + .../publish/event/NodeDiscoveredEvent.java | 9 + .../event/PeerAddedToSyncPoolEvent.java | 10 + .../publish/event/PeerDisconnectedEvent.java | 26 ++ .../event/PendingStateChangedEvent.java | 17 + .../event/PendingTransactionUpdatedEvent.java | 50 +++ .../PendingTransactionsReceivedEvent.java | 17 + .../ethereum/publish/event/SignalEvent.java | 13 + .../org/ethereum/publish/event/Single.java | 9 + .../ethereum/publish/event/SyncDoneEvent.java | 10 + .../publish/event/TraceCreatedEvent.java | 8 + .../event/TransactionExecutedEvent.java | 9 + .../publish/event/VmTraceCreatedEvent.java | 26 ++ .../event/message/AbstractMessageEvent.java | 35 ++ .../event/message/EthStatusUpdatedEvent.java | 19 ++ .../event/message/PeerHandshakedEvent.java | 19 ++ .../event/message/ReceivedMessageEvent.java | 11 + .../event/message/SentMessageEvent.java | 11 + .../publish/exprimental/EventBus.java | 55 ++++ .../publish/exprimental/EventPublisher.java | 115 +++++++ .../org/ethereum/sync/FastSyncManager.java | 47 +-- .../java/org/ethereum/sync/SyncManager.java | 31 +- .../util/blockchain/StandaloneBlockchain.java | 181 ++++++----- .../org/ethereum/validator/EthashRule.java | 62 ++-- .../org/ethereum/core/ImportLightTest.java | 218 ++++++------- .../core/PendingStateLongRunTest.java | 11 +- .../jsontestsuite/suite/TestRunner.java | 31 +- .../ethereum/longrun/SyncWithLoadTest.java | 29 +- .../org/ethereum/mine/ExternalMinerTest.java | 22 +- .../net/eth/handler/LockBlockchainTest.java | 64 ++-- .../org/ethereum/publish/PublisherTest.java | 142 +++++++++ .../ethereum/validator/EthashRuleTest.java | 61 ++-- 50 files changed, 1688 insertions(+), 884 deletions(-) delete mode 100644 ethereumj-core/src/main/java/org/ethereum/listener/CompositeEthereumListener.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/BestBlockAddedEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAddedEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/Event.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnectionsEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/NodeDiscoveredEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPoolEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/PeerDisconnectedEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/PendingStateChangedEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdatedEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceivedEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/SignalEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/Single.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDoneEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/TraceCreatedEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecutedEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/VmTraceCreatedEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/message/AbstractMessageEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/message/EthStatusUpdatedEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/message/PeerHandshakedEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/message/ReceivedMessageEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/message/SentMessageEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventBus.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventPublisher.java create mode 100644 ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java diff --git a/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java b/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java index 0621cc35ab..51ca72697f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java +++ b/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java @@ -17,16 +17,17 @@ */ package org.ethereum.config; -import org.ethereum.core.*; +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.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; @@ -78,7 +79,8 @@ BeanPostProcessor initializer() { } - @Bean @Primary + @Bean + @Primary public Repository repository() { return new RepositoryWrapper(); } @@ -88,7 +90,8 @@ public Repository defaultRepository() { return new RepositoryRoot(stateSource(), null); } - @Bean @Scope("prototype") + @Bean + @Scope("prototype") public Repository repository(byte[] stateRoot) { return new RepositoryRoot(stateSource(), stateRoot); } @@ -96,7 +99,7 @@ public Repository repository(byte[] stateRoot) { /** * A source of nodes for state trie and all contract storage tries.
* This source provides contract code too.

- * + *

* Picks node by 16-bytes prefix of its key.
* Within {@link NodeKeyCompositor} this source is a part of ref counting workaround

* @@ -128,7 +131,7 @@ public StateSource stateSource() { @Bean @Scope("prototype") public Source cachedDbSource(String name) { - AbstractCachedSource writeCache = new AsyncWriteCache(blockchainSource(name)) { + AbstractCachedSource writeCache = new AsyncWriteCache(blockchainSource(name)) { @Override protected WriteCache createCache(Source source) { WriteCache.BytesKey ret = new WriteCache.BytesKey<>(source, WriteCache.CacheType.SIMPLE); @@ -168,7 +171,7 @@ public DbSource keyValueDataSource(String name, DbSettings settings) { DbSource dbSource; if ("inmem".equals(dataSource)) { dbSource = new HashMapDB<>(); - } else if ("leveldb".equals(dataSource)){ + } else if ("leveldb".equals(dataSource)) { dbSource = levelDbDataSource(); } else { dataSource = "rocksdb"; @@ -222,9 +225,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 EthereumListener ethereumListener(Publisher publisher) { + return publisher.asListener(); } @Bean @@ -262,16 +270,18 @@ public byte[] serialize(byte[] object) { ret.add(new DataWord(1)); return ret.getLast20Bytes(); } + public byte[] deserialize(byte[] stream) { throw new RuntimeException("Shouldn't be called"); } }, new Serializer() { - 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); + } }); } @@ -290,14 +300,14 @@ public DbFlushManager dbFlushManager() { } @Bean - public BlockHeaderValidator headerValidator() { + public BlockHeaderValidator headerValidator(SystemProperties systemProperties, Publisher publisher) { List 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); diff --git a/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java b/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java index 23f62aff5b..54d2c30ae5 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java @@ -24,13 +24,18 @@ 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.listener.EthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.manager.AdminInfo; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.BestBlockAddedEvent; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.TraceCreatedEvent; 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.program.invoke.ProgramInvokeFactory; @@ -47,20 +52,11 @@ import java.io.FileWriter; import java.io.IOException; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collections; -import java.util.ConcurrentModificationException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.Stack; +import java.util.*; import static java.lang.Math.max; import static java.lang.Runtime.getRuntime; +import static java.lang.String.format; import static java.math.BigInteger.ONE; import static java.math.BigInteger.ZERO; import static java.util.Collections.emptyList; @@ -110,7 +106,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 @@ -126,7 +123,7 @@ public class BlockchainImpl implements Blockchain, org.ethereum.facade.Blockchai private BigInteger totalDifficulty = ZERO; @Autowired - private EthereumListener listener; + private Publisher publisher; @Autowired ProgramInvokeFactory programInvokeFactory; @@ -176,7 +173,9 @@ public class BlockchainImpl implements Blockchain, org.ethereum.facade.Blockchai private Stack stateStack = new Stack<>(); - /** Tests only **/ + /** + * Tests only + **/ public BlockchainImpl() { } @@ -187,11 +186,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, Publisher publisher) { this.blockStore = blockStore; this.repository = repository; this.adminInfo = new AdminInfo(); - this.listener = new EthereumListenerAdapter(); + this.publisher = publisher; this.parentHeaderValidator = null; this.transactionStore = new TransactionStore(new HashMapDB()); this.eventDispatchThread = EventDispatchThread.getDefault(); @@ -209,8 +208,8 @@ public BlockchainImpl withAdminInfo(AdminInfo adminInfo) { return this; } - public BlockchainImpl withEthereumListener(EthereumListener listener) { - this.listener = listener; + public BlockchainImpl withPublisher(Publisher publisher) { + this.publisher = publisher; return this; } @@ -455,8 +454,10 @@ public synchronized ImportResult tryToConnect(final Block block) { } if (ret.isSuccessful()) { - listener.onBlock(summary, ret == IMPORTED_BEST); - listener.trace(String.format("Block chain size: [ %d ]", this.getSize())); + publisher + .publish(new BlockAddedEvent(summary)) + .publish(new BestBlockAddedEvent(summary, ret == IMPORTED_BEST)) + .publish(new TraceCreatedEvent(format("Block chain size: [ %d ]", this.getSize()))); if (ret == IMPORTED_BEST) { eventDispatchThread.invokeLater(() -> pendingState.processBest(block, summary.getReceipts())); @@ -493,7 +494,7 @@ public synchronized Block createNewBlock(Block parent, List 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 @@ -825,7 +826,7 @@ public static Set 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()); } @@ -839,7 +840,7 @@ public Set 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())); } @@ -852,8 +853,7 @@ private BlockSummary processBlock(Repository track, Block block) { if (!block.isGenesis() && !config.blockChainOnly()) { return applyBlock(track, block); - } - else { + } else { return new BlockSummary(block, new HashMap(), new ArrayList(), new ArrayList()); } } @@ -876,7 +876,7 @@ private BlockSummary applyBlock(Repository track, Block block) { Repository txTrack = track.startTracking(); TransactionExecutor executor = new TransactionExecutor(tx, block.getCoinbase(), - txTrack, blockStore, programInvokeFactory, block, listener, totalGasUsed) + txTrack, blockStore, programInvokeFactory, block, publisher, totalGasUsed) .withCommonConfig(commonConfig); executor.init(); @@ -951,7 +951,7 @@ private Map addReward(Repository track, Block block, List 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); @@ -1233,6 +1234,7 @@ private BlockHeader findHeaderByNumber(long number) { /** * Searches block in blockStore, if it's not found there * and headerStore is defined, searches blockHeader in it. + * * @param hash block hash * @return Block header */ @@ -1379,7 +1381,7 @@ public byte[] next() { } private class State { -// Repository savedRepo = repository; + // Repository savedRepo = repository; byte[] root = repository.getRoot(); Block savedBest = bestBlock; BigInteger savedTD = totalDifficulty; diff --git a/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java b/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java index 4b5717af74..6a84974b1b 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java @@ -17,27 +17,17 @@ */ package org.ethereum.core; -import static org.ethereum.listener.EthereumListener.PendingTransactionState.DROPPED; -import static org.ethereum.listener.EthereumListener.PendingTransactionState.INCLUDED; -import static org.ethereum.listener.EthereumListener.PendingTransactionState.NEW_PENDING; -import static org.ethereum.listener.EthereumListener.PendingTransactionState.PENDING; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.TreeSet; - import org.apache.commons.collections4.map.LRUMap; import org.ethereum.config.CommonConfig; import org.ethereum.config.SystemProperties; import org.ethereum.db.BlockStore; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.db.TransactionStore; -import org.ethereum.listener.EthereumListener; import org.ethereum.listener.EthereumListener.PendingTransactionState; -import org.ethereum.listener.EthereumListenerAdapter; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.PendingStateChangedEvent; +import org.ethereum.publish.event.PendingTransactionUpdatedEvent; +import org.ethereum.publish.event.PendingTransactionsReceivedEvent; import org.ethereum.util.ByteUtil; import org.ethereum.util.FastByteComparisons; import org.ethereum.vm.program.invoke.ProgramInvokeFactory; @@ -46,6 +36,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.*; + +import static org.ethereum.listener.EthereumListener.PendingTransactionState.*; import static org.ethereum.util.ByteUtil.toHexString; /** @@ -78,8 +71,7 @@ public TransactionSortedSet() { @Autowired CommonConfig commonConfig = CommonConfig.getDefault(); - @Autowired - private EthereumListener listener; + private Publisher publisher; @Autowired private BlockchainImpl blockchain; @@ -107,8 +99,8 @@ public TransactionSortedSet() { private Block best = null; @Autowired - public PendingStateImpl(final EthereumListener listener) { - this.listener = listener; + public PendingStateImpl(final Publisher publisher) { + this.publisher = publisher; // this.repository = blockchain.getRepository(); } @@ -173,8 +165,9 @@ public synchronized List addPendingTransactions(List t transactions.size(), unknownTx, newPending, receivedTxs.size()); if (!newPending.isEmpty()) { - listener.onPendingTransactionsReceived(newPending); - listener.onPendingStateChanged(PendingStateImpl.this); + this.publisher + .publish(new PendingTransactionsReceivedEvent(newPending)) + .publish(new PendingStateChangedEvent(PendingStateImpl.this)); } return newPending; @@ -204,13 +197,14 @@ state, toHexString(txReceipt.getTransaction().getSender()).substring(0, 8), ByteUtil.byteArrayToLong(txReceipt.getTransaction().getNonce()), block.getShortDescr(), txReceipt.getError())); } - listener.onPendingTransactionUpdate(txReceipt, state, block); + publisher.publish(new PendingTransactionUpdatedEvent(block, txReceipt, state)); } /** * Executes pending tx on the latest best block * Fires pending state update - * @param tx Transaction + * + * @param tx Transaction * @return True if transaction gets NEW_PENDING state, False if DROPPED */ private boolean addPendingTransactionImpl(final Transaction tx) { @@ -258,7 +252,7 @@ private String validate(Transaction tx) { } private Block findCommonAncestor(Block b1, Block b2) { - while(!b1.isEqual(b2)) { + while (!b1.isEqual(b2)) { if (b1.getNumber() >= b2.getNumber()) { b1 = blockchain.getBlockByHash(b1.getParentHash()); } @@ -288,7 +282,7 @@ public synchronized void processBest(Block newBlock, List re // first return back the transactions from forked blocks Block rollback = getBestBlock(); - while(!rollback.isEqual(commonAncestor)) { + while (!rollback.isEqual(commonAncestor)) { List blockTxs = new ArrayList<>(); for (Transaction tx : rollback.getTransactionsList()) { logger.trace("Returning transaction back to pending: " + tx); @@ -304,7 +298,7 @@ public synchronized void processBest(Block newBlock, List re // next process blocks from new fork Block main = newBlock; List mainFork = new ArrayList<>(); - while(!main.isEqual(commonAncestor)) { + while (!main.isEqual(commonAncestor)) { mainFork.add(main); main = blockchain.getBlockByHash(main.getParentHash()); } @@ -322,7 +316,7 @@ public synchronized void processBest(Block newBlock, List re updateState(newBlock); - listener.onPendingStateChanged(PendingStateImpl.this); + publisher.publish(new PendingStateChangedEvent(PendingStateImpl.this)); } private void processBestInternal(Block block, List receipts) { @@ -411,7 +405,7 @@ private TransactionReceipt executeTx(Transaction tx) { TransactionExecutor executor = new TransactionExecutor( tx, best.getCoinbase(), getRepository(), - blockStore, programInvokeFactory, createFakePendingBlock(), new EthereumListenerAdapter(), 0) + blockStore, programInvokeFactory, createFakePendingBlock(), new Publisher(EventDispatchThread.getDefault()), 0) .withCommonConfig(commonConfig); executor.init(); diff --git a/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java b/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java index df7539377b..7bfb3185f6 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java @@ -23,10 +23,14 @@ import org.ethereum.config.SystemProperties; import org.ethereum.db.BlockStore; import org.ethereum.db.ContractDetails; -import org.ethereum.listener.EthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.TransactionExecutedEvent; +import org.ethereum.publish.event.VmTraceCreatedEvent; import org.ethereum.util.ByteArraySet; -import org.ethereum.vm.*; +import org.ethereum.vm.DataWord; +import org.ethereum.vm.LogInfo; +import org.ethereum.vm.PrecompiledContracts; +import org.ethereum.vm.VM; import org.ethereum.vm.program.Program; import org.ethereum.vm.program.ProgramResult; import org.ethereum.vm.program.invoke.ProgramInvoke; @@ -73,7 +77,7 @@ public class TransactionExecutor { private ProgramResult result = new ProgramResult(); private Block currentBlock; - private final EthereumListener listener; + private final Publisher publisher; private VM vm; private Program program; @@ -91,12 +95,12 @@ public class TransactionExecutor { public TransactionExecutor(Transaction tx, byte[] coinbase, Repository track, BlockStore blockStore, ProgramInvokeFactory programInvokeFactory, Block currentBlock) { - this(tx, coinbase, track, blockStore, programInvokeFactory, currentBlock, new EthereumListenerAdapter(), 0); + this(tx, coinbase, track, blockStore, programInvokeFactory, currentBlock, new Publisher(EventDispatchThread.getDefault()), 0); } public TransactionExecutor(Transaction tx, byte[] coinbase, Repository track, BlockStore blockStore, ProgramInvokeFactory programInvokeFactory, Block currentBlock, - EthereumListener listener, long gasUsedInTheBlock) { + Publisher publisher, long gasUsedInTheBlock) { this.tx = tx; this.coinbase = coinbase; @@ -105,7 +109,7 @@ public TransactionExecutor(Transaction tx, byte[] coinbase, Repository track, Bl this.blockStore = blockStore; this.programInvokeFactory = programInvokeFactory; this.currentBlock = currentBlock; - this.listener = listener; + this.publisher = publisher; this.gasUsedInTheBlock = gasUsedInTheBlock; this.m_endGas = toBI(tx.getGasLimit()); withCommonConfig(CommonConfig.getDefault()); @@ -450,7 +454,7 @@ public TransactionExecutionSummary finalization() { } - listener.onTransactionExecuted(summary); + publisher.publish(new TransactionExecutedEvent(summary)); if (config.vmTrace() && program != null && result != null) { String trace = program.getTrace() @@ -465,7 +469,7 @@ public TransactionExecutionSummary finalization() { String txHash = toHexString(tx.getHash()); saveProgramTraceFile(config, txHash, trace); - listener.onVMTraceCreated(txHash, trace); + publisher.publish(new VmTraceCreatedEvent(txHash, trace)); } return summary; } diff --git a/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java b/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java index ba3dfc2697..3848ed0470 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java @@ -18,20 +18,19 @@ package org.ethereum.db; import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.JdkFutureAdapters; -import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ThreadFactoryBuilder; -import org.ethereum.config.CommonConfig; import org.ethereum.config.SystemProperties; -import org.ethereum.datasource.*; -import org.ethereum.listener.CompositeEthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; +import org.ethereum.datasource.AbstractCachedSource; +import org.ethereum.datasource.AsyncFlushable; +import org.ethereum.datasource.DbSource; +import org.ethereum.datasource.Source; +import org.ethereum.listener.EthereumListener; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.SyncDoneEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.*; @@ -44,7 +43,7 @@ public class DbFlushManager { List> writeCaches = new CopyOnWriteArrayList<>(); List> sources = new CopyOnWriteArrayList<>(); - Set dbSources = new HashSet<>(); + Set dbSources ; AbstractCachedSource stateDbCache; long sizeThreshold; @@ -71,15 +70,13 @@ public DbFlushManager(SystemProperties config, Set dbSources, Abstract } @Autowired - public void setEthereumListener(CompositeEthereumListener listener) { + public void setPublisher(Publisher publisher) { if (!flushAfterSyncDone) return; - listener.addListener(new EthereumListenerAdapter() { - @Override - public void onSyncDone(SyncState state) { - if (state == SyncState.COMPLETE) { - logger.info("DbFlushManager: long sync done, flushing each block now"); - syncDone = true; - } + + publisher.subscribe(SyncDoneEvent.class, state -> { + if (state == EthereumListener.SyncState.COMPLETE) { + logger.info("DbFlushManager: long sync done, flushing each block now"); + syncDone = true; } }); } diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index 7938310c7a..2fb01e10d2 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -17,7 +17,6 @@ */ package org.ethereum.facade; -import org.apache.commons.lang3.ArrayUtils; import org.ethereum.config.BlockchainConfig; import org.ethereum.config.CommonConfig; import org.ethereum.config.SystemProperties; @@ -25,9 +24,7 @@ import org.ethereum.core.PendingState; import org.ethereum.core.Repository; import org.ethereum.crypto.ECKey; -import org.ethereum.listener.CompositeEthereumListener; import org.ethereum.listener.EthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.listener.GasPriceTracker; import org.ethereum.manager.AdminInfo; import org.ethereum.manager.BlockLoader; @@ -39,6 +36,8 @@ import org.ethereum.net.shh.Whisper; import org.ethereum.net.submit.TransactionExecutor; import org.ethereum.net.submit.TransactionTask; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.BlockAddedEvent; import org.ethereum.sync.SyncManager; import org.ethereum.util.ByteUtil; import org.ethereum.vm.program.ProgramResult; @@ -53,9 +52,12 @@ import org.springframework.stereotype.Component; import org.springframework.util.concurrent.FutureAdapter; +import javax.annotation.PostConstruct; import java.math.BigInteger; import java.net.InetAddress; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -104,20 +106,25 @@ public class EthereumImpl implements Ethereum, SmartLifecycle { private SystemProperties config; - private CompositeEthereumListener compositeEthereumListener; - - private GasPriceTracker gasPriceTracker = new GasPriceTracker(); @Autowired - public EthereumImpl(final SystemProperties config, final CompositeEthereumListener compositeEthereumListener) { - this.compositeEthereumListener = compositeEthereumListener; + private Publisher publisher; + + @Autowired + public EthereumImpl(final SystemProperties config) { this.config = config; System.out.println(); - this.compositeEthereumListener.addListener(gasPriceTracker); gLogger.info("EthereumJ node started: enode://" + toHexString(config.nodeId()) + "@" + config.externalIp() + ":" + config.listenPort()); } + @PostConstruct + public void init() { + publisher.subscribe(BlockAddedEvent.class, blockSummary -> { + blockSummary.getBlock().getTransactionsList().forEach(gasPriceTracker::onTransaction); + }); + } + @Override public void startPeerDiscovery() { worldManager.startPeerDiscovery(); @@ -164,7 +171,7 @@ public BlockMiner getBlockMiner() { @Override public void addListener(EthereumListener listener) { - worldManager.addListener(listener); + worldManager.getPublisher().subscribeListener(listener); } @Override @@ -252,7 +259,7 @@ public BlockSummary replayBlock(Block block) { Repository txTrack = track.startTracking(); org.ethereum.core.TransactionExecutor executor = new org.ethereum.core.TransactionExecutor( tx, block.getCoinbase(), txTrack, worldManager.getBlockStore(), - programInvokeFactory, block, worldManager.getListener(), 0) + programInvokeFactory, block, worldManager.getPublisher(), 0) .withCommonConfig(commonConfig); executor.init(); @@ -284,7 +291,7 @@ private org.ethereum.core.TransactionExecutor callConstantImpl(Transaction tx, B try { org.ethereum.core.TransactionExecutor executor = new org.ethereum.core.TransactionExecutor (tx, block.getCoinbase(), repository, worldManager.getBlockStore(), - programInvokeFactory, block, new EthereumListenerAdapter(), 0) + programInvokeFactory, block, new Publisher(EventDispatchThread.getDefault()), 0) .withCommonConfig(commonConfig) .setLocalCall(true); @@ -421,10 +428,12 @@ public void stop(Runnable callback) { } @Override - public void start() {} + public void start() { + } @Override - public void stop() {} + public void stop() { + } @Override public boolean isRunning() { diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/CompositeEthereumListener.java b/ethereumj-core/src/main/java/org/ethereum/listener/CompositeEthereumListener.java deleted file mode 100644 index 5f3d5998b5..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/listener/CompositeEthereumListener.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (c) [2016] [ ] - * This file is part of the ethereumJ library. - * - * The ethereumJ library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The ethereumJ library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the ethereumJ library. If not, see . - */ -package org.ethereum.listener; - -import org.ethereum.core.*; -import org.ethereum.net.eth.message.StatusMessage; -import org.ethereum.net.message.Message; -import org.ethereum.net.p2p.HelloMessage; -import org.ethereum.net.rlpx.Node; -import org.ethereum.net.server.Channel; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -/** - * @author Roman Mandeleil - * @since 12.11.2014 - */ -public class CompositeEthereumListener implements EthereumListener { - - private static abstract class RunnableInfo implements Runnable { - private EthereumListener listener; - private String info; - - public RunnableInfo(EthereumListener listener, String info) { - this.listener = listener; - this.info = info; - } - - @Override - public String toString() { - return "RunnableInfo: " + info + " [listener: " + listener.getClass() + "]"; - } - } - - @Autowired - EventDispatchThread eventDispatchThread = EventDispatchThread.getDefault(); - - protected List listeners = new CopyOnWriteArrayList<>(); - - public void addListener(EthereumListener listener) { - listeners.add(listener); - } - public void removeListener(EthereumListener listener) { - listeners.remove(listener); - } - - @Override - public void trace(final String output) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "trace") { - @Override - public void run() { - listener.trace(output); - } - }); - } - } - - @Override - public void onBlock(final BlockSummary blockSummary) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onBlock") { - @Override - public void run() { - listener.onBlock(blockSummary); - } - }); - } - } - - @Override - public void onBlock(final BlockSummary blockSummary, final boolean best) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onBlock") { - @Override - public void run() { - listener.onBlock(blockSummary, best); - } - }); - } - } - - @Override - public void onRecvMessage(final Channel channel, final Message message) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onRecvMessage") { - @Override - public void run() { - listener.onRecvMessage(channel, message); - } - }); - } - } - - @Override - public void onSendMessage(final Channel channel, final Message message) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onSendMessage") { - @Override - public void run() { - listener.onSendMessage(channel, message); - } - }); - } - } - - @Override - public void onPeerDisconnect(final String host, final long port) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onPeerDisconnect") { - @Override - public void run() { - listener.onPeerDisconnect(host, port); - } - }); - } - } - - @Override - public void onPendingTransactionsReceived(final List transactions) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onPendingTransactionsReceived") { - @Override - public void run() { - listener.onPendingTransactionsReceived(transactions); - } - }); - } - } - - @Override - public void onPendingStateChanged(final PendingState pendingState) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onPendingStateChanged") { - @Override - public void run() { - listener.onPendingStateChanged(pendingState); - } - }); - } - } - - @Override - public void onSyncDone(final SyncState state) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onSyncDone") { - @Override - public void run() { - listener.onSyncDone(state); - } - }); - } - } - - @Override - public void onNoConnections() { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onNoConnections") { - @Override - public void run() { - listener.onNoConnections(); - } - }); - } - } - - @Override - public void onHandShakePeer(final Channel channel, final HelloMessage helloMessage) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onHandShakePeer") { - @Override - public void run() { - listener.onHandShakePeer(channel, helloMessage); - } - }); - } - } - - @Override - public void onVMTraceCreated(final String transactionHash, final String trace) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onVMTraceCreated") { - @Override - public void run() { - listener.onVMTraceCreated(transactionHash, trace); - } - }); - } - } - - @Override - public void onNodeDiscovered(final Node node) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onNodeDiscovered") { - @Override - public void run() { - listener.onNodeDiscovered(node); - } - }); - } - } - - @Override - public void onEthStatusUpdated(final Channel channel, final StatusMessage status) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onEthStatusUpdated") { - @Override - public void run() { - listener.onEthStatusUpdated(channel, status); - } - }); - } - } - - @Override - public void onTransactionExecuted(final TransactionExecutionSummary summary) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onTransactionExecuted") { - @Override - public void run() { - listener.onTransactionExecuted(summary); - } - }); - } - } - - @Override - public void onPeerAddedToSyncPool(final Channel peer) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onPeerAddedToSyncPool") { - @Override - public void run() { - listener.onPeerAddedToSyncPool(peer); - } - }); - } - } - - @Override - public void onPendingTransactionUpdate(final TransactionReceipt txReceipt, final PendingTransactionState state, - final Block block) { - for (final EthereumListener listener : listeners) { - eventDispatchThread.invokeLater(new RunnableInfo(listener, "onPendingTransactionUpdate") { - @Override - public void run() { - listener.onPendingTransactionUpdate(txReceipt, state, block); - } - }); - } - } -} diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java b/ethereumj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java index beac0910f5..56693bcfc1 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java @@ -17,22 +17,20 @@ */ package org.ethereum.listener; -import org.ethereum.core.BlockSummary; import org.ethereum.core.Transaction; -import org.ethereum.core.TransactionExecutionSummary; import org.ethereum.util.ByteUtil; import java.util.Arrays; /** * Calculates a 'reasonable' Gas price based on statistics of the latest transaction's Gas prices - * + *

* Normally the price returned should be sufficient to execute a transaction since ~25% of the latest * transactions were executed at this or lower price. - * + *

* Created by Anton Nashatyrev on 22.09.2015. */ -public class GasPriceTracker extends EthereumListenerAdapter { +public class GasPriceTracker { private static final long defaultPrice = 70_000_000_000L; @@ -42,13 +40,6 @@ public class GasPriceTracker extends EthereumListenerAdapter { private long lastVal; - @Override - public void onBlock(BlockSummary blockSummary) { - for (Transaction tx : blockSummary.getBlock().getTransactionsList()) { - onTransaction(tx); - } - } - public void onTransaction(Transaction tx) { if (idx == -1) { idx = window.length - 1; diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java index 988d169bc5..a791a05a60 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java @@ -23,14 +23,16 @@ import org.ethereum.db.DbFlushManager; import org.ethereum.db.HeaderStore; import org.ethereum.db.migrate.MigrateHeaderSourceTotalDiff; -import org.ethereum.listener.CompositeEthereumListener; import org.ethereum.listener.EthereumListener; import org.ethereum.net.client.PeerClient; +import org.ethereum.net.rlpx.discover.NodeManager; import org.ethereum.net.rlpx.discover.UDPListener; +import org.ethereum.net.server.ChannelManager; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.BestBlockAddedEvent; +import org.ethereum.publish.event.Event; import org.ethereum.sync.FastSyncManager; import org.ethereum.sync.SyncManager; -import org.ethereum.net.rlpx.discover.NodeManager; -import org.ethereum.net.server.ChannelManager; import org.ethereum.sync.SyncPool; import org.ethereum.util.Utils; import org.slf4j.Logger; @@ -42,11 +44,13 @@ import javax.annotation.PostConstruct; import java.math.BigInteger; -import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; +import java.util.function.Consumer; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static org.ethereum.crypto.HashUtil.EMPTY_TRIE_HASH; +import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.ByteUtil.toHexString; /** @@ -95,7 +99,7 @@ public class WorldManager { private SystemProperties config; - private EthereumListener listener; + private Publisher publisher; private Blockchain blockchain; @@ -105,9 +109,9 @@ public class WorldManager { @Autowired public WorldManager(final SystemProperties config, final Repository repository, - final EthereumListener listener, final Blockchain blockchain, + final Publisher publisher, final Blockchain blockchain, final BlockStore blockStore) { - this.listener = listener; + this.publisher = publisher; this.blockchain = blockchain; this.repository = repository; this.blockStore = blockStore; @@ -121,9 +125,18 @@ private void init() { syncManager.init(channelManager, pool); } + /** + * @param listener + * @deprecated use {@link #subscribe(Class, Consumer)} instead. + */ + @Deprecated public void addListener(EthereumListener listener) { logger.info("Ethereum listener added"); - ((CompositeEthereumListener) this.listener).addListener(listener); + publisher.subscribeListener(listener); + } + + public , P> Publisher subscribe(Class eventType, Consumer

handler) { + return this.publisher.subscribe(to(eventType, handler)); } public void startPeerDiscovery() { @@ -143,12 +156,21 @@ public ChannelManager getChannelManager() { return channelManager; } + /** + * @return + * @deprecated use {@link #getPublisher()} instead. + */ + @Deprecated public EthereumListener getListener() { - return listener; + return publisher.asListener(); + } + + public Publisher getPublisher() { + return publisher; } public org.ethereum.facade.Repository getRepository() { - return (org.ethereum.facade.Repository)repository; + return repository; } public Blockchain getBlockchain() { @@ -186,7 +208,8 @@ public void loadBlockchain() { blockchain.setBestBlock(Genesis.getInstance(config)); blockchain.setTotalDifficulty(Genesis.getInstance(config).getDifficultyBI()); - listener.onBlock(new BlockSummary(Genesis.getInstance(config), new HashMap(), new ArrayList(), new ArrayList()), true); + BlockSummary blockSummary = new BlockSummary(Genesis.getInstance(config), emptyMap(), emptyList(), emptyList()); + publisher.publish(new BestBlockAddedEvent(blockSummary, true)); // repository.dumpState(Genesis.getInstance(config), 0, 0, null); logger.info("Genesis block loaded"); diff --git a/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java b/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java index 7d5685f13b..265086a210 100644 --- a/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java +++ b/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java @@ -27,9 +27,10 @@ import org.ethereum.db.IndexedBlockStore; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumImpl; -import org.ethereum.listener.CompositeEthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.mine.MinerIfc.MiningResult; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.PendingStateChangedEvent; +import org.ethereum.publish.event.SyncDoneEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -40,10 +41,11 @@ import java.util.concurrent.*; import static java.lang.Math.max; +import static org.ethereum.publish.Subscription.to; /** * Manages embedded CPU mining and allows to use external miners. - * + *

* Created by Anton Nashatyrev on 10.12.2015. */ @Component @@ -61,8 +63,6 @@ public class BlockMiner { protected PendingState pendingState; - private CompositeEthereumListener listener; - private SystemProperties config; private List listeners = new CopyOnWriteArrayList<>(); @@ -81,35 +81,31 @@ public class BlockMiner { private int UNCLE_LIST_LIMIT; private int UNCLE_GENERATION_LIMIT; + private final Publisher publisher; + @Autowired - public BlockMiner(final SystemProperties config, final CompositeEthereumListener listener, + public BlockMiner(final SystemProperties config, Publisher publisher, final Blockchain blockchain, final BlockStore blockStore, final PendingState pendingState) { - this.listener = listener; this.config = config; this.blockchain = blockchain; this.blockStore = blockStore; this.pendingState = pendingState; - UNCLE_LIST_LIMIT = config.getBlockchainConfig().getCommonConstants().getUNCLE_LIST_LIMIT(); - UNCLE_GENERATION_LIMIT = config.getBlockchainConfig().getCommonConstants().getUNCLE_GENERATION_LIMIT(); - minGasPrice = config.getMineMinGasPrice(); - minBlockTimeout = config.getMineMinBlockTimeoutMsec(); - cpuThreads = config.getMineCpuThreads(); - fullMining = config.isMineFullDataset(); - listener.addListener(new EthereumListenerAdapter() { - @Override - public void onPendingStateChanged(PendingState pendingState) { - BlockMiner.this.onPendingStateChanged(); - } + this.UNCLE_LIST_LIMIT = config.getBlockchainConfig().getCommonConstants().getUNCLE_LIST_LIMIT(); + this.UNCLE_GENERATION_LIMIT = config.getBlockchainConfig().getCommonConstants().getUNCLE_GENERATION_LIMIT(); + this.minGasPrice = config.getMineMinGasPrice(); + this.minBlockTimeout = config.getMineMinBlockTimeoutMsec(); + this.cpuThreads = config.getMineCpuThreads(); + this.fullMining = config.isMineFullDataset(); + this.publisher = publisher + .subscribe(to(PendingStateChangedEvent.class, ps -> onPendingStateChanged())) + .subscribe(to(SyncDoneEvent.class, s -> { + if (config.minerStart() && config.isSyncEnabled()) { + logger.info("Sync complete, start mining..."); + startMining(); + } + })); - @Override - public void onSyncDone(SyncState state) { - if (config.minerStart() && config.isSyncEnabled()) { - logger.info("Sync complete, start mining..."); - startMining(); - } - } - }); if (config.minerStart() && !config.isSyncEnabled()) { logger.info("Sync disabled, start mining now..."); @@ -152,7 +148,7 @@ protected List getAllPendingTransactions() { PendingStateImpl.TransactionSortedSet ret = new PendingStateImpl.TransactionSortedSet(); ret.addAll(pendingState.getPendingTransactions()); Iterator it = ret.iterator(); - while(it.hasNext()) { + while (it.hasNext()) { Transaction tx = it.next(); if (!isAcceptableTx(tx)) { logger.debug("Miner excluded the transaction: {}", tx); @@ -211,7 +207,7 @@ protected List getUncles(Block mineBest) { long limitNum = max(0, miningNum - UNCLE_GENERATION_LIMIT); Set ancestors = BlockchainImpl.getAncestors(blockStore, mineBest, UNCLE_GENERATION_LIMIT + 1, true); - Set knownUncles = ((BlockchainImpl)blockchain).getUsedUncles(blockStore, mineBest, true); + Set knownUncles = ((BlockchainImpl) blockchain).getUsedUncles(blockStore, mineBest, true); knownUncles.addAll(ancestors); knownUncles.add(new ByteArrayWrapper(mineBest.getHash())); @@ -254,7 +250,7 @@ protected Block getNewBlockForMining() { protected void restartMining() { Block newMiningBlock = getNewBlockForMining(); - synchronized(this) { + synchronized (this) { cancelCurrentBlock(); miningBlock = newMiningBlock; @@ -338,21 +334,25 @@ protected void fireMinerStarted() { l.miningStarted(); } } + protected void fireMinerStopped() { for (MinerListener l : listeners) { l.miningStopped(); } } + protected void fireBlockStarted(Block b) { for (MinerListener l : listeners) { l.blockMiningStarted(b); } } + protected void fireBlockCancelled(Block b) { for (MinerListener l : listeners) { l.blockMiningCanceled(b); } } + protected void fireBlockMined(Block b) { for (MinerListener l : listeners) { l.blockMined(b); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java index d0deb570cb..80f240b59d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java @@ -24,15 +24,16 @@ import org.ethereum.config.SystemProperties; import org.ethereum.core.*; import org.ethereum.db.BlockStore; -import org.ethereum.listener.CompositeEthereumListener; import org.ethereum.net.eth.EthVersion; import org.ethereum.net.eth.message.*; import org.ethereum.net.message.ReasonCode; import org.ethereum.net.rlpx.discover.NodeManager; import org.ethereum.net.submit.TransactionExecutor; import org.ethereum.net.submit.TransactionTask; -import org.ethereum.sync.SyncManager; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.message.EthStatusUpdatedEvent; import org.ethereum.sync.PeerState; +import org.ethereum.sync.SyncManager; import org.ethereum.sync.SyncStatistics; import org.ethereum.util.ByteUtil; import org.ethereum.validator.BlockHeaderRule; @@ -53,9 +54,8 @@ import static org.ethereum.net.eth.EthVersion.V62; import static org.ethereum.net.message.ReasonCode.USELESS_PEER; import static org.ethereum.sync.PeerState.*; -import static org.ethereum.sync.PeerState.BLOCK_RETRIEVING; -import static org.ethereum.util.Utils.longToTimePeriod; import static org.ethereum.util.ByteUtil.toHexString; +import static org.ethereum.util.Utils.longToTimePeriod; /** * Eth 62 @@ -127,14 +127,14 @@ public Eth62() { @Autowired public Eth62(final SystemProperties config, final Blockchain blockchain, - final BlockStore blockStore, final CompositeEthereumListener ethereumListener) { - this(version, config, blockchain, blockStore, ethereumListener); + final BlockStore blockStore, Publisher publisher) { + this(version, config, blockchain, blockStore, publisher); } Eth62(final EthVersion version, final SystemProperties config, final Blockchain blockchain, final BlockStore blockStore, - final CompositeEthereumListener ethereumListener) { - super(version, config, blockchain, blockStore, ethereumListener); + final Publisher publisher) { + super(version, config, blockchain, blockStore, publisher); } @Override @@ -340,7 +340,7 @@ protected synchronized void processStatus(StatusMessage msg, ChannelHandlerConte // basic checks passed, update statistics channel.getNodeStatistics().ethHandshake(msg); - ethereumListener.onEthStatusUpdated(channel, msg); + getPublisher().publish(new EthStatusUpdatedEvent(channel, msg)); if (peerDiscoveryMode) { loggerNet.trace("Peer discovery mode: STATUS received, disconnecting..."); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java index acde14d363..550e7bd75b 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java @@ -25,15 +25,10 @@ import org.ethereum.core.*; import org.ethereum.datasource.Source; import org.ethereum.db.BlockStore; -import org.ethereum.listener.CompositeEthereumListener; import org.ethereum.net.eth.EthVersion; -import org.ethereum.net.eth.message.EthMessage; -import org.ethereum.net.eth.message.GetNodeDataMessage; -import org.ethereum.net.eth.message.GetReceiptsMessage; -import org.ethereum.net.eth.message.NodeDataMessage; -import org.ethereum.net.eth.message.ReceiptsMessage; - +import org.ethereum.net.eth.message.*; import org.ethereum.net.message.ReasonCode; +import org.ethereum.publish.Publisher; import org.ethereum.sync.PeerState; import org.ethereum.util.ByteArraySet; import org.ethereum.util.Value; @@ -73,8 +68,8 @@ public Eth63() { @Autowired public Eth63(final SystemProperties config, final Blockchain blockchain, BlockStore blockStore, - final CompositeEthereumListener ethereumListener) { - super(version, config, blockchain, blockStore, ethereumListener); + final Publisher publisher) { + super(version, config, blockchain, blockStore, publisher); } @Override diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java index a520d3f402..9aa2a25134 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java @@ -19,27 +19,31 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; -import org.ethereum.db.BlockStore; -import org.ethereum.listener.EthereumListener; import org.ethereum.config.SystemProperties; -import org.ethereum.core.*; -import org.ethereum.listener.CompositeEthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; +import org.ethereum.core.Block; +import org.ethereum.core.BlockSummary; +import org.ethereum.core.Blockchain; +import org.ethereum.db.BlockStore; import org.ethereum.net.MessageQueue; import org.ethereum.net.eth.EthVersion; -import org.ethereum.net.eth.message.*; +import org.ethereum.net.eth.message.EthMessage; +import org.ethereum.net.eth.message.EthMessageCodes; +import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.message.ReasonCode; import org.ethereum.net.server.Channel; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.Subscription; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.TraceCreatedEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; +import static java.lang.String.format; /** * Process the messages between peers with 'eth' capability on the network
* Contains common logic to all supported versions * delegating version specific stuff to its descendants - * */ public abstract class EthHandler extends SimpleChannelInboundHandler implements Eth { @@ -49,7 +53,7 @@ public abstract class EthHandler extends SimpleChannelInboundHandler protected SystemProperties config; - protected CompositeEthereumListener ethereumListener; + private Publisher publisher; protected Channel channel; @@ -60,14 +64,9 @@ public abstract class EthHandler extends SimpleChannelInboundHandler protected boolean peerDiscoveryMode = false; protected Block bestBlock; - protected EthereumListener listener = new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - bestBlock = block; - } - }; protected boolean processTransactions = false; + private Subscription bestBlockSub; protected EthHandler(EthVersion version) { this.version = version; @@ -75,15 +74,20 @@ protected EthHandler(EthVersion version) { protected EthHandler(final EthVersion version, final SystemProperties config, final Blockchain blockchain, final BlockStore blockStore, - final CompositeEthereumListener ethereumListener) { + final Publisher publisher) { this.version = version; this.config = config; - this.ethereumListener = ethereumListener; this.blockchain = blockchain; - bestBlock = blockStore.getBestBlock(); - this.ethereumListener.addListener(listener); + this.bestBlock = blockStore.getBestBlock(); + this.publisher = publisher; + this.bestBlockSub = publisher.subscribe(BlockAddedEvent.class, this::setBestBlock); + // when sync enabled we delay transactions processing until sync is complete - processTransactions = !config.isSyncEnabled(); + this.processTransactions = !config.isSyncEnabled(); + } + + private void setBestBlock(BlockSummary blockSummary) { + this.bestBlock = blockSummary.getBlock(); } @Override @@ -92,13 +96,17 @@ public void channelRead0(final ChannelHandlerContext ctx, EthMessage msg) throws if (EthMessageCodes.inRange(msg.getCommand().asByte(), version)) logger.trace("EthHandler invoke: [{}]", msg.getCommand()); - ethereumListener.trace(String.format("EthHandler invoke: [%s]", msg.getCommand())); + publisher.publish(new TraceCreatedEvent(format("EthHandler invoke: [%s]", msg.getCommand()))); channel.getNodeStatistics().ethInbound.add(); msgQueue.receivedMessage(msg); } + public Publisher getPublisher() { + return publisher; + } + @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { logger.warn("Eth handling failed", cause); @@ -108,13 +116,13 @@ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws E @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { logger.debug("handlerRemoved: kill timers in EthHandler"); - ethereumListener.removeListener(listener); + publisher.unsubscribe(bestBlockSub); onShutdown(); } public void activate() { logger.debug("ETH protocol activated"); - ethereumListener.trace("ETH protocol activated"); + publisher.publish(new TraceCreatedEvent("ETH protocol activated")); sendStatus(); } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java new file mode 100644 index 0000000000..c85b3e4c17 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java @@ -0,0 +1,300 @@ +package org.ethereum.publish; + +import org.ethereum.core.*; +import org.ethereum.listener.EthereumListener; +import org.ethereum.net.eth.message.StatusMessage; +import org.ethereum.net.message.Message; +import org.ethereum.net.p2p.HelloMessage; +import org.ethereum.net.rlpx.Node; +import org.ethereum.net.server.Channel; +import org.ethereum.publish.event.*; +import org.ethereum.publish.event.message.EthStatusUpdatedEvent; +import org.ethereum.publish.event.message.PeerHandshakedEvent; +import org.ethereum.publish.event.message.ReceivedMessageEvent; +import org.ethereum.publish.event.message.SentMessageEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; + +import static java.util.Collections.emptyList; +import static java.util.Objects.nonNull; +import static java.util.stream.Collectors.toList; +import static org.ethereum.publish.Subscription.to; + +/** + * Event publisher that uses pub/sub model to deliver event messages.
+ * Uses {@link EventDispatchThread} as task executor, and subscribers notifying in parallel thread depends on + * {@link EventDispatchThread} implementation passed via constructor.
+ *

+ * Usage examples: + *

+ * {@code
+ *
+ *     // Publisher creating and subscribing
+ *     EventDispatchThread edt = new EventDispatchThread();
+ *     Publisher publisher = new Publisher(edt)
+ *             .subscribe(to(SingleEvent.class, singleEventPayload -> handleOnce(singleEventPayload)))
+ *             .subscribe(to(SomeEvent.class, someEventPayload -> doSmthWith(someEventPayload)))
+ *             .subscribe(to(SomeEvent.class, someEventPayload -> doSmthWithElse(someEventPayload);}))
+ *             .subscribe(to(AnotherEvent.class, SubscriberClass::handleAnotherEventPayload))
+ *             .subscribe(to(OneMoreEvent.class, subscriberInstance::processOneMoreEventPayload)
+ *                     .conditionally(oneMoreEventPayload -> shouldHandleOrNot(oneMoreEventPayload)));
+ *
+ *     // Publishing events
+ *     publisher
+ *             .publish(new OneMoreEvent())    // will fire processOneMoreEventPayload if shouldHandleOrNot return true
+ *             .publish(new SomeEvent())       // will fire doSmthWith and doSmthWithElse with the same payload argument
+ *             .publish(new UnknownEvent())    // do nothing, because there is no subscription for this event type
+ *             .publish(new SingleEvent())     // will fire handleOnce and unsubscribe all subscribers of this event type
+ *             .publish(new SingleEvent());    // do nothing, because there is no subscription for this event type
+ * }
+ * 

+ * + * @see EventDispatchThread + * @see Subscription + * @see Event + * @see SignalEvent + * @see Single + * + * @author Eugene Shevchenko + */ +public class Publisher { + + private static final Logger log = LoggerFactory.getLogger("events"); + + private final EventDispatchThread dispatchThread; + private final Map, List> subscriptionsByEvent = new ConcurrentHashMap<>(); + + public Publisher(EventDispatchThread dispatchThread) { + this.dispatchThread = dispatchThread; + } + + /** + * Publishes specified event for all its subscribers.
+ * Concurrent execution depends on implementation of nested {@link EventDispatchThread}. + * + * @param event event to publish; + * @return current {@link Publisher} instance to support fluent API. + */ + public Publisher publish(Event event) { + List subscriptions = subscriptionsByEvent.getOrDefault(event.getClass(), emptyList()).stream() + .filter(subscription -> subscription.matches(event)) + .collect(toList()); + + if (!subscriptions.isEmpty()) { + dispatchThread.invokeLater(() -> subscriptions.forEach(subscription -> { + subscription.handle(event); + if (event instanceof Single) { + subscriptionsByEvent.remove(event.getClass()); + } + })); + } + + return this; + } + + /** + * Adds specified {@link Subscription} to publisher.
+ * Do nothing if specified subscription already added. + * + * @param subscription + * @param {@link Event} subclass which describes specific event type; + * @param

payload type of specified event type; + * @return current {@link Publisher} instance to support fluent API. + */ + public , P> Publisher subscribe(Subscription subscription) { + List subscriptions = subscriptionsByEvent.computeIfAbsent(subscription.getEventType(), t -> new ArrayList<>()); + if (subscriptions.contains(subscription)) { + log.warn("Specified subscription already exists {}.", subscription.getEventType().getSimpleName()); + } else { + subscriptions.add(subscription); + } + return this; + } + + /** + * Creates {@link Subscription} from specified parameters and adds it to current publisher. + * + * @param eventType even's type to subscribe; + * @param handler callback that will be invoked after event will be published; + * @param event's type; + * @param

payload of specified event; + * @return created {@link Subscription} instance. + */ + public , P> Subscription subscribe(Class eventType, Consumer

handler) { + Subscription subscription = new Subscription<>(eventType, handler); + subscribe(subscription); + return subscription; + } + + /** + * Removes specified {@link Subscription} from publisher. + * + * @param subscription subscription to remove; + * @return current {@link Publisher} instance to support fluent API. + */ + public Publisher unsubscribe(Subscription subscription) { + List subscriptions = subscriptionsByEvent.get(subscription.getEventType()); + if (nonNull(subscriptions)) { + subscriptions.remove(subscription); + if (subscriptions.isEmpty()) { + subscriptionsByEvent.remove(subscription.getEventType()); + } + } + + return this; + } + + /** + * Calculates specific event type {@link Subscription}s amount added to current {@link Publisher}. + * + * @param eventType event type to filter {@link Subscription}s; + * @return specified event type {@link Subscription}s count. + */ + public int subscribersCount(Class eventType) { + return subscriptionsByEvent.getOrDefault(eventType, emptyList()).size(); + } + + /** + * Calculates total amount {@link Subscription}s added to current {@link Publisher}. + * + * @return all subscribers total count. + */ + public int subscribersCount() { + return subscriptionsByEvent.values().stream() + .mapToInt(List::size) + .sum(); + } + + public void shutdown() { + dispatchThread.shutdown(); + } + + /** + * Method that subscribes all {@link EthereumListener} callbacks to corresponding events. + * Avoid using this method directly, because it creates unnecessary stub {@link Subscription}s. + * Uses for backward compatibility only and will be removed in future releases. + * + * @param listener highly likely {@link org.ethereum.listener.EthereumListenerAdapter} subclass. + */ + public void subscribeListener(EthereumListener listener) { + this + .subscribe(to(TraceCreatedEvent.class, listener::trace)) + .subscribe(to(NodeDiscoveredEvent.class, listener::onNodeDiscovered)) + .subscribe(to(PeerHandshakedEvent.class, data -> listener.onHandShakePeer(data.getChannel(), data.getMessage()))) + .subscribe(to(EthStatusUpdatedEvent.class, data -> listener.onEthStatusUpdated(data.getChannel(), data.getMessage()))) + .subscribe(to(ReceivedMessageEvent.class, data -> listener.onRecvMessage(data.getChannel(), data.getMessage()))) + .subscribe(to(SentMessageEvent.class, data -> listener.onSendMessage(data.getChannel(), data.getMessage()))) + .subscribe(to(BlockAddedEvent.class, listener::onBlock)) + .subscribe(to(BestBlockAddedEvent.class, data -> listener.onBlock(data.getBlockSummary(), data.isBest()))) + .subscribe(to(PeerDisconnectedEvent.class, data -> listener.onPeerDisconnect(data.getHost(), data.getPort()))) + .subscribe(to(PendingTransactionsReceivedEvent.class, listener::onPendingTransactionsReceived)) + .subscribe(to(PendingStateChangedEvent.class, listener::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdatedEvent.class, data -> listener.onPendingTransactionUpdate(data.getReceipt(), data.getState(), data.getBlock()))) + .subscribe(to(SyncDoneEvent.class, listener::onSyncDone)) + .subscribe(to(NoConnectionsEvent.class, data -> listener.onNoConnections())) + .subscribe(to(VmTraceCreatedEvent.class, data -> listener.onVMTraceCreated(data.getTxHash(), data.getTrace()))) + .subscribe(to(TransactionExecutedEvent.class, listener::onTransactionExecuted)) + .subscribe(to(PeerAddedToSyncPoolEvent.class, listener::onPeerAddedToSyncPool)); + } + + /** + * Creates backward compatibility adaptor for {@link EthereumListener}. + * Uses for backward compatibility only and will be removed in future releases. + * + * @return instance of EthereumListener that proxies all method invokes to publishing corresponding events. + */ + public EthereumListener asListener() { + return new EthereumListener() { + @Override + public void trace(String output) { + publish(new TraceCreatedEvent(output)); + } + + @Override + public void onNodeDiscovered(Node node) { + publish(new NodeDiscoveredEvent(node)); + } + + @Override + public void onHandShakePeer(Channel channel, HelloMessage helloMessage) { + publish(new PeerHandshakedEvent(channel, helloMessage)); + } + + @Override + public void onEthStatusUpdated(Channel channel, StatusMessage status) { + publish(new EthStatusUpdatedEvent(channel, status)); + } + + @Override + public void onRecvMessage(Channel channel, Message message) { + publish(new ReceivedMessageEvent(channel, message)); + } + + @Override + public void onSendMessage(Channel channel, Message message) { + publish(new SentMessageEvent(channel, message)); + } + + @Override + public void onBlock(BlockSummary blockSummary) { + publish(new BlockAddedEvent(blockSummary)); + } + + @Override + public void onBlock(BlockSummary blockSummary, boolean best) { + publish(new BestBlockAddedEvent(blockSummary, best)); + } + + @Override + public void onPeerDisconnect(String host, long port) { + publish(new PeerDisconnectedEvent(host, port)); + } + + @Override + public void onPendingTransactionsReceived(List transactions) { + publish(new PendingTransactionsReceivedEvent(transactions)); + } + + @Override + public void onPendingStateChanged(PendingState pendingState) { + publish(new PendingStateChangedEvent(pendingState)); + } + + @Override + public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionState state, Block block) { + publish(new PendingTransactionUpdatedEvent(block, txReceipt, state)); + } + + @Override + public void onSyncDone(SyncState state) { + publish(new SyncDoneEvent(state)); + } + + @Override + public void onNoConnections() { + publish(new NoConnectionsEvent()); + } + + @Override + public void onVMTraceCreated(String transactionHash, String trace) { + publish(new VmTraceCreatedEvent(transactionHash, trace)); + } + + @Override + public void onTransactionExecuted(TransactionExecutionSummary summary) { + publish(new TransactionExecutedEvent(summary)); + } + + @Override + public void onPeerAddedToSyncPool(Channel peer) { + publish(new PeerAddedToSyncPoolEvent(peer)); + } + }; + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java new file mode 100644 index 0000000000..79c9ba4508 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java @@ -0,0 +1,86 @@ +package org.ethereum.publish; + +import org.ethereum.publish.event.Event; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.function.Consumer; +import java.util.function.Function; + +import static java.util.Objects.isNull; + +/** + * Abstraction that holds together event type, event processor (a.k.a consumer) and optional condition that resolves + * event processing. + * + * @author Eugene Shevchenko + */ +public class Subscription, D> { + + private final static Logger log = LoggerFactory.getLogger("event"); + + private final Class eventType; + private final Consumer consumer; + private Function condition; + + public Subscription(Class eventType, Consumer consumer) { + this.eventType = eventType; + this.consumer = consumer; + } + + /** + * Gets event type that current {@link Subscription} processes. + * + * @return type of event. + */ + public Class getEventType() { + return eventType; + } + + /** + * Optionally adds conditional clause that indicates should consumes tested event or not. + * + * @param condition function that resolves sequential event consumption. + * @return current {@link Subscription} instance to support fluent API. + */ + public Subscription conditionally(Function condition) { + this.condition = condition; + return this; + } + + /** + * Tests specified event whether it should be consumed. + * + * @param event event to test; + * @return true if event should be consumed, false otherwise. + */ + boolean matches(E event) { + return isNull(condition) || condition.apply(event.getPayload()); + } + + /** + * Safely (catches all exceptions with logging only) consumes specified event. + * + * @param event event to consume. + */ + void handle(E event) { + try { + consumer.accept(event.getPayload()); + } catch (Throwable e) { + log.error(eventType.getSimpleName() + " handling error: ", e); + } + } + + /** + * Short static alias for {@link Subscription} constructor. + * + * @param eventType event type to process; + * @param consumer callback that consumes event's payload; + * @param event type that should be process; + * @param payload's type of specified event type; + * @return new {@link Subscription} instance. + */ + public static , D> Subscription to(Class eventType, Consumer consumer) { + return new Subscription<>(eventType, consumer); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/BestBlockAddedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/BestBlockAddedEvent.java new file mode 100644 index 0000000000..cc6f558843 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/BestBlockAddedEvent.java @@ -0,0 +1,28 @@ +package org.ethereum.publish.event; + +import org.ethereum.core.BlockSummary; + +public class BestBlockAddedEvent extends Event { + + public static class Data { + private final BlockSummary blockSummary; + private final boolean best; + + public Data(BlockSummary blockSummary, boolean best) { + this.blockSummary = blockSummary; + this.best = best; + } + + public BlockSummary getBlockSummary() { + return blockSummary; + } + + public boolean isBest() { + return best; + } + } + + public BestBlockAddedEvent(BlockSummary blockSummary, boolean best) { + super(new Data(blockSummary, best)); + } +} \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAddedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAddedEvent.java new file mode 100644 index 0000000000..5a5e761614 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAddedEvent.java @@ -0,0 +1,10 @@ +package org.ethereum.publish.event; + +import org.ethereum.core.BlockSummary; + +public class BlockAddedEvent extends Event { + + public BlockAddedEvent(BlockSummary data) { + super(data); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/Event.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/Event.java new file mode 100644 index 0000000000..0e914c3640 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/Event.java @@ -0,0 +1,36 @@ +package org.ethereum.publish.event; + +/** + * Base class for all event types which can be used with {@link org.ethereum.publish.Publisher}. + * + * @author Eugene Shevchenko + */ +public abstract class Event { + + private final T payload; + private final long timestamp; + + public Event(T payload) { + this.payload = payload; + this.timestamp = System.currentTimeMillis(); + } + + /** + * @return event's payload object. + */ + public T getPayload() { + return payload; + } + + /** + * @return timestamp of event creation. + */ + public long getTimestamp() { + return timestamp; + } + + @Override + public String toString() { + return getClass().getSimpleName() + " emitted at " + getTimestamp(); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnectionsEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnectionsEvent.java new file mode 100644 index 0000000000..5a4c405793 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnectionsEvent.java @@ -0,0 +1,4 @@ +package org.ethereum.publish.event; + +public class NoConnectionsEvent extends SignalEvent { +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/NodeDiscoveredEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/NodeDiscoveredEvent.java new file mode 100644 index 0000000000..0f9b343265 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/NodeDiscoveredEvent.java @@ -0,0 +1,9 @@ +package org.ethereum.publish.event; + +import org.ethereum.net.rlpx.Node; + +public class NodeDiscoveredEvent extends Event { + public NodeDiscoveredEvent(Node payload) { + super(payload); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPoolEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPoolEvent.java new file mode 100644 index 0000000000..7433ffe300 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPoolEvent.java @@ -0,0 +1,10 @@ +package org.ethereum.publish.event; + +import org.ethereum.net.server.Channel; + +public class PeerAddedToSyncPoolEvent extends Event { + + public PeerAddedToSyncPoolEvent(Channel channel) { + super(channel); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerDisconnectedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerDisconnectedEvent.java new file mode 100644 index 0000000000..6ae4ea433b --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerDisconnectedEvent.java @@ -0,0 +1,26 @@ +package org.ethereum.publish.event; + +public class PeerDisconnectedEvent extends Event { + + public static class Data { + private final String host; + private final long port; + + public Data(String host, long port) { + this.host = host; + this.port = port; + } + + public String getHost() { + return host; + } + + public long getPort() { + return port; + } + } + + public PeerDisconnectedEvent(String host, long port) { + super(new Data(host, port)); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingStateChangedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingStateChangedEvent.java new file mode 100644 index 0000000000..8e188d44e5 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingStateChangedEvent.java @@ -0,0 +1,17 @@ +package org.ethereum.publish.event; + +import org.ethereum.core.PendingState; + +/** + * PendingState changes on either new pending transaction or new best block receive + * When a new transaction arrives it is executed on top of the current pending state + * When a new best block arrives the PendingState is adjusted to the new Repository state + * and all transactions which remain pending are executed on top of the new PendingState + * + * @author Eugene Shevchenko + */ +public class PendingStateChangedEvent extends Event { + public PendingStateChangedEvent(PendingState state) { + super(state); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdatedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdatedEvent.java new file mode 100644 index 0000000000..1b3cb428ac --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdatedEvent.java @@ -0,0 +1,50 @@ +package org.ethereum.publish.event; + +import org.ethereum.core.Block; +import org.ethereum.core.TransactionReceipt; +import org.ethereum.listener.EthereumListener; + +/** + * Emits when PendingTransaction arrives, executed or dropped and included to a block. + * + * @author Eugene Shevchenko + */ +public class PendingTransactionUpdatedEvent extends Event { + + /** + * Event DTO + */ + public static class Data { + private final TransactionReceipt receipt; + private final EthereumListener.PendingTransactionState state; + private final Block block; + + /** + * @param receipt Receipt of the tx execution on the current PendingState + * @param state Current state of pending tx + * @param block The block which the current pending state is based on (for PENDING tx state) + * or the block which tx was included to (for INCLUDED state) + */ + public Data(Block block, TransactionReceipt receipt, EthereumListener.PendingTransactionState state) { + this.receipt = receipt; + this.state = state; + this.block = block; + } + + public TransactionReceipt getReceipt() { + return receipt; + } + + public EthereumListener.PendingTransactionState getState() { + return state; + } + + public Block getBlock() { + return block; + } + } + + public PendingTransactionUpdatedEvent(Block block, TransactionReceipt receipt, EthereumListener.PendingTransactionState state) { + super(new Data(block, receipt, state)); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceivedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceivedEvent.java new file mode 100644 index 0000000000..37c64cb0f1 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceivedEvent.java @@ -0,0 +1,17 @@ +package org.ethereum.publish.event; + +import org.ethereum.core.Transaction; + +import java.util.List; + +/** + * @author Eugene Shevchenko + * @deprecated use PendingTransactionUpdatedEvent filtering state NEW_PENDING + * Will be removed in the next release + */ +public class PendingTransactionsReceivedEvent extends Event> { + + public PendingTransactionsReceivedEvent(List transactions) { + super(transactions); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/SignalEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/SignalEvent.java new file mode 100644 index 0000000000..d38f62a9a3 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/SignalEvent.java @@ -0,0 +1,13 @@ +package org.ethereum.publish.event; + +/** + * Base class for signal events (without any payload). + * + * @author Eugene Shevchenko + */ +public abstract class SignalEvent extends Event { + + public SignalEvent() { + super(null); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/Single.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/Single.java new file mode 100644 index 0000000000..71fa1429c9 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/Single.java @@ -0,0 +1,9 @@ +package org.ethereum.publish.event; + +/** + * Marker interface for one time emitted events. + * + * @author Eugene Shevchenko + */ +public interface Single { +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDoneEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDoneEvent.java new file mode 100644 index 0000000000..c49cf19c2c --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDoneEvent.java @@ -0,0 +1,10 @@ +package org.ethereum.publish.event; + +import org.ethereum.listener.EthereumListener; + +public class SyncDoneEvent extends Event implements Single { + + public SyncDoneEvent(EthereumListener.SyncState payload) { + super(payload); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/TraceCreatedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/TraceCreatedEvent.java new file mode 100644 index 0000000000..da83ebea35 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/TraceCreatedEvent.java @@ -0,0 +1,8 @@ +package org.ethereum.publish.event; + +public class TraceCreatedEvent extends Event { + + public TraceCreatedEvent(String trace) { + super(trace); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecutedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecutedEvent.java new file mode 100644 index 0000000000..675e14410d --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecutedEvent.java @@ -0,0 +1,9 @@ +package org.ethereum.publish.event; + +import org.ethereum.core.TransactionExecutionSummary; + +public class TransactionExecutedEvent extends Event { + public TransactionExecutedEvent(TransactionExecutionSummary executionSummary) { + super(executionSummary); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/VmTraceCreatedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/VmTraceCreatedEvent.java new file mode 100644 index 0000000000..ca83a06fb9 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/VmTraceCreatedEvent.java @@ -0,0 +1,26 @@ +package org.ethereum.publish.event; + +public class VmTraceCreatedEvent extends Event { + + public static class Data { + private final String txHash; + private final String trace; + + public Data(String txHash, String trace) { + this.txHash = txHash; + this.trace = trace; + } + + public String getTxHash() { + return txHash; + } + + public String getTrace() { + return trace; + } + } + + public VmTraceCreatedEvent(String txHash, String trace) { + super(new Data(txHash, trace)); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/AbstractMessageEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/AbstractMessageEvent.java new file mode 100644 index 0000000000..64869851ba --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/AbstractMessageEvent.java @@ -0,0 +1,35 @@ +package org.ethereum.publish.event.message; + +import org.ethereum.net.message.Message; +import org.ethereum.net.server.Channel; +import org.ethereum.publish.event.Event; + +/** + * Base class for any message events (received, sent, etc.) + * + * @author Eugene Shevchenko + */ +public abstract class AbstractMessageEvent

extends Event

{ + + public static class Data { + public final Channel channel; + public final M message; + + public Data(Channel channel, M message) { + this.channel = channel; + this.message = message; + } + + public Channel getChannel() { + return channel; + } + + public M getMessage() { + return message; + } + } + + public AbstractMessageEvent(P payload) { + super(payload); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/EthStatusUpdatedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/EthStatusUpdatedEvent.java new file mode 100644 index 0000000000..476b3988ca --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/EthStatusUpdatedEvent.java @@ -0,0 +1,19 @@ +package org.ethereum.publish.event.message; + +import org.ethereum.net.eth.message.StatusMessage; +import org.ethereum.net.server.Channel; + +public class EthStatusUpdatedEvent extends AbstractMessageEvent { + + public static class Data extends AbstractMessageEvent.Data { + + public Data(Channel channel, StatusMessage message) { + super(channel, message); + } + + } + + public EthStatusUpdatedEvent(Channel channel, StatusMessage message) { + super(new Data(channel, message)); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/PeerHandshakedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/PeerHandshakedEvent.java new file mode 100644 index 0000000000..a1802986e4 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/PeerHandshakedEvent.java @@ -0,0 +1,19 @@ +package org.ethereum.publish.event.message; + +import org.ethereum.net.p2p.HelloMessage; +import org.ethereum.net.server.Channel; + +public class PeerHandshakedEvent extends AbstractMessageEvent { + + public static class Data extends AbstractMessageEvent.Data { + + public Data(Channel channel, HelloMessage message) { + super(channel, message); + } + } + + + public PeerHandshakedEvent(Channel channel, HelloMessage message) { + super(new Data(channel, message)); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/ReceivedMessageEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/ReceivedMessageEvent.java new file mode 100644 index 0000000000..1734ff8d42 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/ReceivedMessageEvent.java @@ -0,0 +1,11 @@ +package org.ethereum.publish.event.message; + +import org.ethereum.net.message.Message; +import org.ethereum.net.server.Channel; + +public class ReceivedMessageEvent extends AbstractMessageEvent> { + + public ReceivedMessageEvent(Channel channel, Message message) { + super(new Data(channel, message)); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/SentMessageEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/SentMessageEvent.java new file mode 100644 index 0000000000..88b2591d58 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/SentMessageEvent.java @@ -0,0 +1,11 @@ +package org.ethereum.publish.event.message; + +import org.ethereum.net.message.Message; +import org.ethereum.net.server.Channel; + +public class SentMessageEvent extends AbstractMessageEvent> { + + public SentMessageEvent(Channel channel, Message message) { + super(new Data(channel, message)); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventBus.java b/ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventBus.java new file mode 100644 index 0000000000..218753ad84 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventBus.java @@ -0,0 +1,55 @@ +package org.ethereum.publish.exprimental; + +import org.ethereum.publish.event.Event; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.function.Consumer; + +import static java.util.Objects.isNull; + +public class EventBus { + + private static final Logger log = LoggerFactory.getLogger("events"); + + private final Map, EventPublisher> publisherByEvent = new HashMap<>(); + private final ExecutorService executor = Executors.newCachedThreadPool(Thread::new); + + + public , P> void subscribe(Class eventType, Consumer

handler) { + publisherByEvent + .computeIfAbsent(eventType, t -> new EventPublisher<>(eventType, executor).onCompleted(this::removePublisher)) + .subscribe(handler); + } + + private void removePublisher(EventPublisher publisher) { + publisherByEvent.remove(publisher.getEventType()); + } + + public , P> void unsubscribe(Class eventType, Consumer

handler) { + + } + + public boolean publish(Event event) { + if (executor.isShutdown()) { + log.warn("Cannot publish event: event bus is stopped."); + return false; + } + + EventPublisher eventPublisher = publisherByEvent.get(event.getClass()); + if (isNull(eventPublisher)) { + return false; + } + + return eventPublisher.publish(event); + } + + public void shutdown() { + executor.shutdown(); + } + +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventPublisher.java b/ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventPublisher.java new file mode 100644 index 0000000000..033b45b03a --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventPublisher.java @@ -0,0 +1,115 @@ +package org.ethereum.publish.exprimental; + +import org.ethereum.publish.event.Event; +import org.ethereum.publish.event.Single; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.List; +import java.util.concurrent.*; +import java.util.function.Consumer; + +import static java.time.LocalDateTime.now; +import static java.util.Objects.nonNull; + +public class EventPublisher, P> { + + public static final Logger log = LoggerFactory.getLogger("event"); + + private final Class eventType; + private final BlockingQueue eventsQueue = new LinkedBlockingQueue<>(); + private final List> consumers = new CopyOnWriteArrayList<>(); + private final ExecutorService executor; + + private final Thread listener; + private Consumer> completedCallback; + + public EventPublisher(Class eventType, ExecutorService executor) { + this.eventType = eventType; + this.executor = executor; + this.listener = new Thread(this::listenEvents, "publisher-" + eventType.getSimpleName()); + } + + public EventPublisher onCompleted(Consumer> callback) { + this.completedCallback = callback; + return this; + } + + public Class getEventType() { + return eventType; + } + + public boolean publish(E event) { + return eventsQueue.offer(event); + } + + public void subscribe(Consumer

consumer) { + boolean isFirstConsumer = consumers.isEmpty(); + consumers.add(consumer); + if (isFirstConsumer && !listener.isAlive()) { + listener.start(); + } + } + + public void unsubscribe(Consumer

consumer) { + consumers.remove(consumer); + if (consumers.isEmpty() && eventsQueue.isEmpty()) { + listener.interrupt(); + } + } + + private void listenEvents() { + while (!(consumers.isEmpty() || executor.isShutdown())) { + + try { + E event = eventsQueue.take(); + + + notify(event); + + if (event instanceof Single) { + consumers.clear(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + } + + if (nonNull(completedCallback)) { + completedCallback.accept(this); + } + } + + private void notify(Consumer

consumer, E event) { + try { + consumer.accept(event.getPayload()); + } catch (Throwable err) { + log.error("Event handling error: ", err); + } + } + + private void notifyParallel(List> consumers, E event) throws InterruptedException, ExecutionException { + CompletableFuture[] futures = consumers.stream() + .map(consumer -> CompletableFuture.runAsync(() -> notify(consumer, event), executor)) + .toArray(CompletableFuture[]::new); + + CompletableFuture.allOf(futures).get(); + } + + private void notify(E event) throws InterruptedException, ExecutionException { + LocalDateTime start = now(); + try { + if (consumers.size() == 1) { + notify(consumers.get(0), event); + } else { + notifyParallel(consumers, event); + } + } finally { + log.debug("{} subscriber(s) processing took {} ms.", consumers.size(), Duration.between(start, now()).toMillis()); + } + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java b/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java index c26bd53847..ea207ff728 100644 --- a/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java @@ -32,13 +32,13 @@ import org.ethereum.db.IndexedBlockStore; import org.ethereum.db.StateSource; import org.ethereum.facade.SyncStatus; -import org.ethereum.listener.CompositeEthereumListener; import org.ethereum.listener.EthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.net.client.Capability; import org.ethereum.net.eth.handler.Eth63; import org.ethereum.net.message.ReasonCode; import org.ethereum.net.server.Channel; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.SyncDoneEvent; import org.ethereum.trie.TrieKey; import org.ethereum.util.*; import org.slf4j.Logger; @@ -56,12 +56,10 @@ import java.util.concurrent.*; import java.util.stream.Collectors; -import static org.ethereum.listener.EthereumListener.SyncState.COMPLETE; -import static org.ethereum.listener.EthereumListener.SyncState.SECURE; -import static org.ethereum.listener.EthereumListener.SyncState.UNSECURE; +import static org.ethereum.listener.EthereumListener.SyncState.*; import static org.ethereum.trie.TrieKey.fromPacked; -import static org.ethereum.util.CompactEncoder.hasTerminator; import static org.ethereum.util.ByteUtil.toHexString; +import static org.ethereum.util.CompactEncoder.hasTerminator; /** * Created by Anton Nashatyrev on 24.10.2016. @@ -109,7 +107,7 @@ public class FastSyncManager { DbFlushManager dbFlushManager; @Autowired - CompositeEthereumListener listener; + private Publisher publisher; @Autowired ApplicationContext applicationContext; @@ -194,7 +192,7 @@ public SyncStatus getSyncState() { case SECURE: if (headersDownloader != null) { return new SyncStatus(SyncStatus.SyncStage.Headers, headersDownloader.getHeadersLoaded(), - pivot.getNumber()); + pivot.getNumber()); } else { return new SyncStatus(SyncStatus.SyncStage.Headers, pivot.getNumber(), pivot.getNumber()); } @@ -236,9 +234,15 @@ private class TrieNodeRequest { this.nodeHash = nodeHash; switch (type) { - case STATE: stateNodesCnt++; break; - case CODE: codeNodesCnt++; break; - case STORAGE: storageNodesCnt++; break; + case STATE: + stateNodesCnt++; + break; + case CODE: + codeNodesCnt++; + break; + case STORAGE: + storageNodesCnt++; + break; } } @@ -540,7 +544,7 @@ private void syncUnsecure(BlockHeader pivot) { retrieveLoop(); - logger.info("FastSync: state trie download complete! (Nodes count: state: " + stateNodesCnt + ", storage: " +storageNodesCnt + ", code: " +codeNodesCnt + ")"); + logger.info("FastSync: state trie download complete! (Nodes count: state: " + stateNodesCnt + ", storage: " + storageNodesCnt + ", code: " + codeNodesCnt + ")"); last = 0; logStat(); @@ -556,12 +560,7 @@ private void syncUnsecure(BlockHeader pivot) { logger.info("FastSync: proceeding to regular sync..."); final CountDownLatch syncDoneLatch = new CountDownLatch(1); - listener.addListener(new EthereumListenerAdapter() { - @Override - public void onSyncDone(SyncState state) { - syncDoneLatch.countDown(); - } - }); + publisher.subscribe(SyncDoneEvent.class, syncState -> syncDoneLatch.countDown()); syncManager.initRegularSync(UNSECURE); logger.info("FastSync: waiting for regular sync to reach the blockchain head..."); @@ -755,7 +754,8 @@ private void fireSyncDone(EthereumListener.SyncState state) { // prevent early state notification when sync is not yet done syncManager.setSyncDoneType(state); if (syncManager.isSyncDone()) { - listener.onSyncDone(state); +// listener.onSyncDone(state); + publisher.publish(new SyncDoneEvent(state)); } } @@ -880,10 +880,11 @@ private BlockHeader getPivotHeaderByHash(byte[] pivotBlockHash) throws Exception * 1. Get pivotBlockNumber blocks from all peers * 2. Ensure that pivot block available from 50% + 1 peer * 3. Otherwise proposes new pivotBlockNumber (stepped back) - * @param pivotBlockNumber Pivot block number - * @return null - if no peers available - * null, newPivotBlockNumber - if it's better to try other pivot block number - * BlockHeader, null - if pivot successfully fetched and verified by majority of peers + * + * @param pivotBlockNumber Pivot block number + * @return null - if no peers available + * null, newPivotBlockNumber - if it's better to try other pivot block number + * BlockHeader, null - if pivot successfully fetched and verified by majority of peers */ private Pair getPivotHeaderByNumber(long pivotBlockNumber) throws Exception { List allIdle = pool.getAllIdle(); diff --git a/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java b/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java index d5d19ab49d..3305fa97fb 100644 --- a/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java @@ -19,12 +19,12 @@ import org.ethereum.config.SystemProperties; import org.ethereum.core.*; -import org.ethereum.core.Blockchain; import org.ethereum.facade.SyncStatus; -import org.ethereum.listener.CompositeEthereumListener; import org.ethereum.listener.EthereumListener; import org.ethereum.net.server.Channel; import org.ethereum.net.server.ChannelManager; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.SyncDoneEvent; import org.ethereum.util.ExecutorPipeline; import org.ethereum.validator.BlockHeaderValidator; import org.slf4j.Logger; @@ -47,8 +47,8 @@ import static java.lang.Math.max; import static java.util.Collections.singletonList; import static org.ethereum.core.ImportResult.*; -import static org.ethereum.util.Utils.longToTimePeriod; import static org.ethereum.util.ByteUtil.toHexString; +import static org.ethereum.util.Utils.longToTimePeriod; /** * @author Mikhail Kalinin @@ -61,7 +61,7 @@ public class SyncManager extends BlockDownloader { // Transaction.getSender() is quite heavy operation so we are prefetching this value on several threads // to unload the main block importing cycle - private ExecutorPipeline exec1 = new ExecutorPipeline<> + private ExecutorPipeline exec1 = new ExecutorPipeline<> (4, 1000, true, blockWrapper -> { for (Transaction tx : blockWrapper.getBlock().getTransactionsList()) { tx.getSender(); @@ -86,7 +86,7 @@ public void accept(BlockWrapper blockWrapper) { private Blockchain blockchain; @Autowired - private CompositeEthereumListener compositeEthereumListener; + private Publisher publisher; @Autowired private FastSyncManager fastSyncManager; @@ -132,7 +132,7 @@ public void init(final ChannelManager channelManager, final SyncPool pool) { try { logger.info("Sync state: " + getSyncStatus() + (isSyncDone() || importStart == 0 ? "" : "; Import idle time " + - longToTimePeriod(importIdleTime.get()) + " of total " + longToTimePeriod(System.currentTimeMillis() - importStart))); + longToTimePeriod(importIdleTime.get()) + " of total " + longToTimePeriod(System.currentTimeMillis() - importStart))); } catch (Exception e) { logger.error("Unexpected", e); } @@ -166,7 +166,7 @@ void initRegularSync(EthereumListener.SyncState syncDoneType) { Runnable queueProducer = this::produceQueue; - syncQueueThread = new Thread (queueProducer, "SyncQueueThread"); + syncQueueThread = new Thread(queueProducer, "SyncQueueThread"); syncQueueThread.start(); if (config.makeDoneByTimeout() >= 0) { @@ -225,7 +225,8 @@ protected void pushBlocks(List blockWrappers) { } @Override - protected void pushHeaders(List headers) {} + protected void pushHeaders(List headers) { + } @Override protected int getBlockQueueFreeSize() { @@ -310,7 +311,8 @@ private void produceQueue() { wrapper.getBlock().getTransactionsList().size(), ts); if (syncDone && (importResult == IMPORTED_BEST || importResult == IMPORTED_NOT_BEST)) { - if (logger.isDebugEnabled()) logger.debug("Block dump: " + toHexString(wrapper.getBlock().getEncoded())); + if (logger.isDebugEnabled()) + logger.debug("Block dump: " + toHexString(wrapper.getBlock().getEncoded())); // Propagate block to the net after successful import asynchronously if (wrapper.isNewBlock()) channelManager.onNewForeignBlock(wrapper); } @@ -339,14 +341,14 @@ private synchronized void makeSyncDone() { if (syncDone) return; syncDone = true; channelManager.onSyncDone(true); - compositeEthereumListener.onSyncDone(syncDoneType); + publisher.publish(new SyncDoneEvent(syncDoneType)); } public CompletableFuture switchToShortSync() { final CompletableFuture syncDoneF = new CompletableFuture<>(); - if(!syncDone && config.isSyncEnabled()) { + if (!syncDone && config.isSyncEnabled()) { new Thread(() -> { - while(!blockQueue.isEmpty() && !syncDone) { + while (!blockQueue.isEmpty() && !syncDone) { try { Thread.sleep(100); } catch (InterruptedException e) { @@ -366,11 +368,10 @@ public CompletableFuture switchToShortSync() { /** * Adds NEW block to the queue * - * @param block new block + * @param block new block * @param nodeId nodeId of the remote peer which this block is received from - * * @return true if block passed validations and was added to the queue, - * otherwise it returns false + * otherwise it returns false */ public boolean validateAndAddNewBlock(Block block, byte[] nodeId) { diff --git a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java index 6fc3411b2b..fea748a494 100644 --- a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java @@ -23,16 +23,18 @@ import org.ethereum.core.*; import org.ethereum.core.genesis.GenesisLoader; import org.ethereum.crypto.ECKey; -import org.ethereum.datasource.*; +import org.ethereum.datasource.JournalSource; +import org.ethereum.datasource.Source; import org.ethereum.datasource.inmem.HashMapDB; -import org.ethereum.db.PruneManager; -import org.ethereum.db.RepositoryRoot; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.db.IndexedBlockStore; -import org.ethereum.listener.CompositeEthereumListener; +import org.ethereum.db.PruneManager; +import org.ethereum.db.RepositoryRoot; import org.ethereum.listener.EthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.mine.Ethash; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.Event; import org.ethereum.solidity.compiler.CompilationResult; import org.ethereum.solidity.compiler.CompilationResult.ContractMetadata; import org.ethereum.solidity.compiler.SolidityCompiler; @@ -51,6 +53,7 @@ import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutionException; +import java.util.function.Consumer; import static org.ethereum.util.ByteUtil.wrap; @@ -59,27 +62,27 @@ */ public class StandaloneBlockchain implements LocalBlockchain { - Genesis genesis; - byte[] coinbase; - BlockchainImpl blockchain; - PendingStateImpl pendingState; - CompositeEthereumListener listener; - ECKey txSender; - long gasPrice; - long gasLimit; - boolean autoBlock; - long dbDelay = 0; - long totalDbHits = 0; - BlockchainNetConfig netConfig; + private Genesis genesis; + private byte[] coinbase; + private BlockchainImpl blockchain; + private PendingStateImpl pendingState; + private Publisher publisher; + private ECKey txSender; + private long gasPrice; + private long gasLimit; + private boolean autoBlock; + private long dbDelay = 0; + private long totalDbHits = 0; + private BlockchainNetConfig netConfig; - int blockGasIncreasePercent = 0; + private int blockGasIncreasePercent = 0; - long time = 0; - long timeIncrement = 13; + private long time = 0; + private long timeIncrement = 13; private HashMapDB stateDS; - JournalSource pruningStateDS; - PruneManager pruneManager; + private JournalSource pruningStateDS; + private PruneManager pruneManager; private BlockSummary lastSummary; @@ -266,7 +269,7 @@ public Block createForkBlock(Block parent) { submittedTxes.clear(); return b; - } catch (InterruptedException|ExecutionException e) { + } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } } @@ -284,6 +287,7 @@ private TransactionExecutionSummary getTxSummary(BlockSummary bs, int idx) { public Transaction createTransaction(long nonce, byte[] toAddress, long value, byte[] data) { return createTransaction(getSender(), nonce, toAddress, BigInteger.valueOf(value), data); } + public Transaction createTransaction(ECKey sender, long nonce, byte[] toAddress, BigInteger value, byte[] data) { Transaction transaction = new Transaction(ByteUtil.longToBytesNoLeadZeroes(nonce), ByteUtil.longToBytesNoLeadZeroes(gasPrice), @@ -341,71 +345,71 @@ public SolidityContract submitNewContractFromJson(String json, Object... constru @Override public SolidityContract submitNewContractFromJson(String json, String contractName, Object... constructorArgs) { - SolidityContractImpl contract; - try { - contract = createContractFromJson(contractName, json); - return submitNewContract(contract, constructorArgs); - } catch (IOException e) { - throw new RuntimeException(e); - } + SolidityContractImpl contract; + try { + contract = createContractFromJson(contractName, json); + return submitNewContract(contract, constructorArgs); + } catch (IOException e) { + throw new RuntimeException(e); + } } @Override - public SolidityContract submitNewContract(ContractMetadata contractMetaData, Object... constructorArgs) { - SolidityContractImpl contract = new SolidityContractImpl(contractMetaData); - return submitNewContract(contract, constructorArgs); - } - - private SolidityContract submitNewContract(SolidityContractImpl contract, Object... constructorArgs) { - CallTransaction.Function constructor = contract.contract.getConstructor(); - if (constructor == null && constructorArgs.length > 0) { - throw new RuntimeException("No constructor with params found"); - } - byte[] argsEncoded = constructor == null ? new byte[0] : constructor.encodeArguments(constructorArgs); - submitNewTx(new PendingTx(new byte[0], BigInteger.ZERO, - ByteUtil.merge(Hex.decode(contract.getBinary()), argsEncoded), contract, null, - new TransactionResult())); - return contract; - } + public SolidityContract submitNewContract(ContractMetadata contractMetaData, Object... constructorArgs) { + SolidityContractImpl contract = new SolidityContractImpl(contractMetaData); + return submitNewContract(contract, constructorArgs); + } + + private SolidityContract submitNewContract(SolidityContractImpl contract, Object... constructorArgs) { + CallTransaction.Function constructor = contract.contract.getConstructor(); + if (constructor == null && constructorArgs.length > 0) { + throw new RuntimeException("No constructor with params found"); + } + byte[] argsEncoded = constructor == null ? new byte[0] : constructor.encodeArguments(constructorArgs); + submitNewTx(new PendingTx(new byte[0], BigInteger.ZERO, + ByteUtil.merge(Hex.decode(contract.getBinary()), argsEncoded), contract, null, + new TransactionResult())); + return contract; + } private SolidityContractImpl createContract(String soliditySrc, String contractName) { try { SolidityCompiler.Result compileRes = SolidityCompiler.compile(soliditySrc.getBytes(), true, SolidityCompiler.Options.ABI, SolidityCompiler.Options.BIN); if (compileRes.isFailed()) throw new RuntimeException("Compile result: " + compileRes.errors); - return createContractFromJson(contractName, compileRes.output); + return createContractFromJson(contractName, compileRes.output); } catch (IOException e) { throw new RuntimeException(e); } } - private SolidityContractImpl createContractFromJson(String contractName, String json) throws IOException { - CompilationResult result = CompilationResult.parse(json); - if (contractName == null) { + private SolidityContractImpl createContractFromJson(String contractName, String json) throws IOException { + CompilationResult result = CompilationResult.parse(json); + if (contractName == null) { contractName = result.getContractName(); - } - - return createContract(contractName, result); - } - - /** - * @param contractName - * @param result - * @return - */ - private SolidityContractImpl createContract(String contractName, CompilationResult result) { - ContractMetadata cMetaData = result.getContract(contractName); - SolidityContractImpl contract = createContract(cMetaData); - - for (CompilationResult.ContractMetadata metadata : result.getContracts()) { - contract.addRelatedContract(metadata.abi); - } - return contract; - } - - private SolidityContractImpl createContract(ContractMetadata contractData) { - SolidityContractImpl contract = new SolidityContractImpl(contractData); - return contract; - } + } + + return createContract(contractName, result); + } + + /** + * @param contractName + * @param result + * @return + */ + private SolidityContractImpl createContract(String contractName, CompilationResult result) { + ContractMetadata cMetaData = result.getContract(contractName); + SolidityContractImpl contract = createContract(cMetaData); + + for (CompilationResult.ContractMetadata metadata : result.getContracts()) { + contract.addRelatedContract(metadata.abi); + } + return contract; + } + + private SolidityContractImpl createContract(ContractMetadata contractData) { + SolidityContractImpl contract = new SolidityContractImpl(contractData); + return contract; + } @Override public SolidityContract createExistingContractFromSrc(String soliditySrc, String contractName, byte[] contractAddress) { @@ -431,19 +435,24 @@ public BlockchainImpl getBlockchain() { if (blockchain == null) { blockchain = createBlockchain(genesis); blockchain.setMinerCoinbase(coinbase); - addEthereumListener(new EthereumListenerAdapter() { - @Override - public void onBlock(BlockSummary blockSummary) { - lastSummary = blockSummary; - } - }); + subscribe(BlockAddedEvent.class, blockSummary -> lastSummary = blockSummary); } return blockchain; } + /** + * @param listener + * @deprecated use {@link #subscribe(Class, Consumer)} instead. + */ + @Deprecated public void addEthereumListener(EthereumListener listener) { getBlockchain(); - this.listener.addListener(listener); + publisher.subscribeListener(listener); + } + + public , P> StandaloneBlockchain subscribe(Class eventType, Consumer

handler) { + publisher.subscribe(eventType, handler); + return this; } private void submitNewTx(PendingTx tx) { @@ -480,10 +489,9 @@ private BlockchainImpl createBlockchain(Genesis genesis) { final RepositoryRoot repository = new RepositoryRoot(pruningStateDS); ProgramInvokeFactoryImpl programInvokeFactory = new ProgramInvokeFactoryImpl(); - listener = new CompositeEthereumListener(); + publisher = new Publisher(EventDispatchThread.getDefault()); - BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository) - .withEthereumListener(listener) + BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository, publisher) .withSyncManager(new SyncManager()); blockchain.setParentHeaderValidator(new DependentBlockHeaderRuleAdapter()); blockchain.setProgramInvokeFactory(programInvokeFactory); @@ -491,7 +499,7 @@ private BlockchainImpl createBlockchain(Genesis genesis) { blockchain.byTest = true; - pendingState = new PendingStateImpl(listener); + pendingState = new PendingStateImpl(publisher); pendingState.setBlockchain(blockchain); blockchain.setPendingState(pendingState); @@ -539,6 +547,7 @@ public class SolidityContractImpl implements SolidityContract { public SolidityContractImpl(String abi) { contract = new CallTransaction.Contract(abi); } + public SolidityContractImpl(CompilationResult.ContractMetadata result) { this(result.abi); compiled = result; @@ -711,7 +720,7 @@ public byte[] getStorageSlot(byte[] slot) { } } - class SlowHashMapDB extends HashMapDB { + class SlowHashMapDB extends HashMapDB { private void sleep(int cnt) { totalDbHits += cnt; if (dbDelay == 0) return; diff --git a/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java b/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java index 467abc2e8d..a77e80c891 100644 --- a/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java +++ b/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java @@ -20,16 +20,17 @@ import org.apache.commons.lang3.tuple.Pair; import org.ethereum.config.SystemProperties; import org.ethereum.core.BlockHeader; -import org.ethereum.core.BlockSummary; -import org.ethereum.listener.CompositeEthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.mine.EthashValidationHelper; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.BestBlockAddedEvent; +import org.ethereum.publish.event.SyncDoneEvent; import org.ethereum.util.FastByteComparisons; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Random; +import static org.ethereum.publish.Subscription.to; import static org.ethereum.validator.EthashRule.ChainType.main; import static org.ethereum.validator.EthashRule.ChainType.reverse; import static org.ethereum.validator.EthashRule.Mode.fake; @@ -39,14 +40,13 @@ * Runs block header validation against Ethash dataset. * *

- * Configurable to work in several modes: - *

    - *
  • fake - partial checks without verification against Ethash dataset - *
  • strict - full check for each block - *
  • mixed - run full check for each block if main import flow during short sync, - * run full check in random fashion (1/{@link #MIX_DENOMINATOR} blocks are checked) - * during long sync, fast sync headers and blocks downloading - * + * Configurable to work in several modes: + *
      + *
    • fake - partial checks without verification against Ethash dataset + *
    • strict - full check for each block + *
    • mixed - run full check for each block if main import flow during short sync, + * run full check in random fashion (1/{@link #MIX_DENOMINATOR} blocks are checked) + * during long sync, fast sync headers and blocks downloading * * @author Mikhail Kalinin * @since 19.06.2018 @@ -73,9 +73,17 @@ static Mode parse(String name, Mode defaultMode) { } public enum ChainType { - main, /** main chain, cache updates are stick to best block events, requires listener */ - direct, /** side chain, cache is triggered each validation attempt, no listener required */ - reverse; /** side chain with reverted validation order */ + main, /** + * main chain, cache updates are stick to best block events, requires listener + */ + direct, /** + * side chain, cache is triggered each validation attempt, no listener required + */ + reverse; + + /** + * side chain with reverted validation order + */ public boolean isSide() { return this == reverse || this == direct; @@ -89,15 +97,15 @@ public boolean isSide() { private Random rnd = new Random(); // two most common settings - public static EthashRule createRegular(SystemProperties systemProperties, CompositeEthereumListener listener) { - return new EthashRule(Mode.parse(systemProperties.getEthashMode(), mixed), main, listener); + public static EthashRule createRegular(SystemProperties systemProperties, Publisher publisher) { + return new EthashRule(Mode.parse(systemProperties.getEthashMode(), mixed), main, publisher); } public static EthashRule createReverse(SystemProperties systemProperties) { return new EthashRule(Mode.parse(systemProperties.getEthashMode(), mixed), reverse, null); } - public EthashRule(Mode mode, ChainType chain, CompositeEthereumListener listener) { + public EthashRule(Mode mode, ChainType chain, Publisher publisher) { this.mode = mode; this.chain = chain; @@ -105,18 +113,14 @@ public EthashRule(Mode mode, ChainType chain, CompositeEthereumListener listener this.ethashHelper = new EthashValidationHelper( chain == reverse ? EthashValidationHelper.CacheOrder.reverse : EthashValidationHelper.CacheOrder.direct); - if (this.chain == main && listener != null) { - listener.addListener(new EthereumListenerAdapter() { - @Override - public void onSyncDone(SyncState state) { - EthashRule.this.syncDone = true; - } - - @Override - public void onBlock(BlockSummary blockSummary, boolean best) { - if (best) ethashHelper.preCache(blockSummary.getBlock().getNumber()); - } - }); + if (this.chain == main && publisher != null) { + publisher + .subscribe(to(SyncDoneEvent.class, ss -> EthashRule.this.syncDone = true)) + .subscribe(to(BestBlockAddedEvent.class, data -> { + if (data.isBest()) { + ethashHelper.preCache(data.getBlockSummary().getBlock().getNumber()); + } + })); } } } diff --git a/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java b/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java index ee644ad15d..1b9b26a324 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java @@ -22,12 +22,13 @@ import org.ethereum.core.genesis.GenesisLoader; import org.ethereum.crypto.ECKey; import org.ethereum.crypto.HashUtil; -import org.ethereum.datasource.inmem.HashMapDB; import org.ethereum.datasource.NoDeleteSource; +import org.ethereum.datasource.inmem.HashMapDB; import org.ethereum.db.IndexedBlockStore; import org.ethereum.db.RepositoryRoot; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.mine.Ethash; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.TransactionExecutedEvent; import org.ethereum.util.ByteUtil; import org.ethereum.util.blockchain.SolidityContract; import org.ethereum.util.blockchain.StandaloneBlockchain; @@ -350,24 +351,24 @@ public void createContractFork() throws Exception { String contractSrc = "contract Child {" + - " int a;" + - " int b;" + - " int public c;" + - " function Child(int i) {" + - " a = 333 + i;" + - " b = 444 + i;" + - " }" + - " function sum() {" + - " c = a + b;" + - " }" + - "}" + - "contract Parent {" + - " address public child;" + - " function createChild(int a) returns (address) {" + - " child = new Child(a);" + - " return child;" + - " }" + - "}"; + " int a;" + + " int b;" + + " int public c;" + + " function Child(int i) {" + + " a = 333 + i;" + + " b = 444 + i;" + + " }" + + " function sum() {" + + " c = a + b;" + + " }" + + "}" + + "contract Parent {" + + " address public child;" + + " function createChild(int a) returns (address) {" + + " child = new Child(a);" + + " return child;" + + " }" + + "}"; StandaloneBlockchain bc = new StandaloneBlockchain(); SolidityContract parent = bc.submitNewContract(contractSrc, "Parent"); @@ -389,17 +390,17 @@ public void createContractFork1() throws Exception { // Test creation of the contract on forked branch with different storage String contractSrc = "contract A {" + - " int public a;" + - " function A() {" + - " a = 333;" + - " }" + - "}" + - "contract B {" + - " int public a;" + - " function B() {" + - " a = 111;" + - " }" + - "}"; + " int public a;" + + " function A() {" + + " a = 333;" + + " }" + + "}" + + "contract B {" + + " int public a;" + + " function B() {" + + " a = 111;" + + " }" + + "}"; { StandaloneBlockchain bc = new StandaloneBlockchain(); @@ -424,20 +425,20 @@ public void createValueTest() throws IOException, InterruptedException { // checks that correct msg.value is passed when contract internally created with value String contract = "pragma solidity ^0.4.3;\n" + - "contract B {\n" + - " uint public valReceived;\n" + - " \n" + - " function B() payable {\n" + - " valReceived = msg.value;\n" + - " }\n" + - "}\n" + - "contract A {\n" + - " function () payable { }\n" + - " address public child;\n" + - " function create() payable {\n" + - " child = (new B).value(20)();\n" + - " }\n" + - "}"; + "contract B {\n" + + " uint public valReceived;\n" + + " \n" + + " function B() payable {\n" + + " valReceived = msg.value;\n" + + " }\n" + + "}\n" + + "contract A {\n" + + " function () payable { }\n" + + " address public child;\n" + + " function create() payable {\n" + + " child = (new B).value(20)();\n" + + " }\n" + + "}"; StandaloneBlockchain bc = new StandaloneBlockchain().withAutoblock(true); SolidityContract a = bc.submitNewContract(contract, "A"); bc.sendEther(a.getAddress(), BigInteger.valueOf(10_000)); @@ -452,17 +453,17 @@ public void createValueTest() throws IOException, InterruptedException { public void contractCodeForkTest() throws IOException, InterruptedException { String contractA = "contract A {" + - " function call() returns (uint) {" + - " return 111;" + - " }" + - "}"; + " function call() returns (uint) {" + + " return 111;" + + " }" + + "}"; String contractB = "contract B {" + - " function call() returns (uint) {" + - " return 222222;" + - " }" + - "}"; + " function call() returns (uint) {" + + " return 222222;" + + " }" + + "}"; StandaloneBlockchain bc = new StandaloneBlockchain(); Block b1 = bc.createBlock(); @@ -484,18 +485,18 @@ public void operateNotExistingContractTest() throws IOException, InterruptedExce byte[] addr = Hex.decode("0101010101010101010101010101010101010101"); String contractA = "pragma solidity ^0.4.3;" + - "contract B { function dummy() {}}" + - "contract A {" + - " function callBalance() returns (uint) {" + - " address addr = 0x" + Hex.toHexString(addr) + ";" + - " uint bal = addr.balance;" + - " }" + - " function callMethod() returns (uint) {" + - " address addr = 0x" + Hex.toHexString(addr) + ";" + - " B b = B(addr);" + - " b.dummy();" + - " }" + - "}"; + "contract B { function dummy() {}}" + + "contract A {" + + " function callBalance() returns (uint) {" + + " address addr = 0x" + Hex.toHexString(addr) + ";" + + " uint bal = addr.balance;" + + " }" + + " function callMethod() returns (uint) {" + + " address addr = 0x" + Hex.toHexString(addr) + ";" + + " B b = B(addr);" + + " b.dummy();" + + " }" + + "}"; StandaloneBlockchain bc = new StandaloneBlockchain() .withGasPrice(1) @@ -551,10 +552,10 @@ public void spendGasSimpleTest() throws IOException, InterruptedException { public void deepRecursionTest() throws Exception { String contractA = "contract A {" + - " function recursive(){" + - " this.recursive();" + - " }" + - "}"; + " function recursive(){" + + " this.recursive();" + + " }" + + "}"; StandaloneBlockchain bc = new StandaloneBlockchain().withGasLimit(5_000_000); SolidityContract a = bc.submitNewContract(contractA, "A"); @@ -569,10 +570,10 @@ public void deepRecursionTest() throws Exception { public void prevBlockHashOnFork() throws Exception { String contractA = "contract A {" + - " bytes32 public blockHash;" + - " function a(){" + - " blockHash = block.blockhash(block.number - 1);" + - " }" + + " bytes32 public blockHash;" + + " function a(){" + + " blockHash = block.blockhash(block.number - 1);" + + " }" + "}"; StandaloneBlockchain bc = new StandaloneBlockchain(); @@ -597,19 +598,19 @@ public void prevBlockHashOnFork() throws Exception { public void rollbackInternalTx() throws Exception { String contractA = "contract A {" + - " uint public a;" + - " uint public b;" + - " function f() {" + - " b = 1;" + - " this.call(bytes4(sha3('exception()')));" + - " a = 2;" + - " }" + + " uint public a;" + + " uint public b;" + + " function f() {" + + " b = 1;" + + " this.call(bytes4(sha3('exception()')));" + + " a = 2;" + + " }" + - " function exception() {" + - " b = 2;" + - " throw;" + - " }" + - "}"; + " function exception() {" + + " b = 2;" + + " throw;" + + " }" + + "}"; StandaloneBlockchain bc = new StandaloneBlockchain(); SolidityContract a = bc.submitNewContract(contractA); @@ -662,15 +663,15 @@ public void selfdestructAttack() throws Exception { public void threadRacePendingTest() throws Exception { String contractA = "contract A {" + - " uint[32] public somedata1;" + - " uint[32] public somedata2;" + - " function set1(uint idx, uint val){" + - " somedata1[idx] = val;" + - " }" + - " function set2(uint idx, uint val){" + - " somedata2[idx] = val;" + - " }" + - "}"; + " uint[32] public somedata1;" + + " uint[32] public somedata2;" + + " function set1(uint idx, uint val){" + + " somedata1[idx] = val;" + + " }" + + " function set2(uint idx, uint val){" + + " somedata2[idx] = val;" + + " }" + + "}"; final StandaloneBlockchain bc = new StandaloneBlockchain(); final StandaloneBlockchain.SolidityContractImpl a = (StandaloneBlockchain.SolidityContractImpl) bc.submitNewContract(contractA); @@ -698,7 +699,7 @@ public void threadRacePendingTest() throws Exception { }).start(); Block b_1 = null; - while(cnt++ > 0) { + while (cnt++ > 0) { long s = System.nanoTime(); a.callFunction("set1", cnt % 32, cnt); @@ -745,14 +746,12 @@ public void threadRacePendingTest() throws Exception { } - - @Test public void suicideInFailedCall() throws Exception { // check that if a contract is suicide in call which is failed (thus suicide is reverted) // the refund for this suicide is not added String contractA = - "contract B {" + + "contract B {" + " function f(){" + " suicide(msg.sender);" + " }" + @@ -772,12 +771,7 @@ public void suicideInFailedCall() throws Exception { SolidityContract a = bc.submitNewContract(contractA, "A"); bc.createBlock(); final BigInteger[] refund = new BigInteger[1]; - bc.addEthereumListener(new EthereumListenerAdapter() { - @Override - public void onTransactionExecuted(TransactionExecutionSummary summary) { - refund[0] = summary.getGasRefund(); - } - }); + bc.subscribe(TransactionExecutedEvent.class, tes -> refund[0] = tes.getGasRefund()); a.callFunction("f"); bc.createBlock(); @@ -791,7 +785,7 @@ public void logInFailedCall() throws Exception { // check that if a contract is suicide in call which is failed (thus suicide is reverted) // the refund for this suicide is not added String contractA = - "contract A {" + + "contract A {" + " function f(){" + " this.call(bytes4(sha3('bad()')));" + " }" + @@ -805,12 +799,7 @@ public void logInFailedCall() throws Exception { SolidityContract a = bc.submitNewContract(contractA, "A"); bc.createBlock(); final List logs = new ArrayList<>(); - bc.addEthereumListener(new EthereumListenerAdapter() { - @Override - public void onTransactionExecuted(TransactionExecutionSummary summary) { - logs.addAll(summary.getLogs()); - } - }); + bc.subscribe(TransactionExecutedEvent.class, tes -> logs.addAll(tes.getLogs())); a.callFunction("f"); bc.createBlock(); @@ -852,7 +841,7 @@ public void ecRecoverTest() throws Exception { Assert.assertArrayEquals(key.getAddress(), (byte[]) ret[0]); ret = a.callConstFunction("f", hash, - ByteUtil.merge(new byte[] {1}, new byte[30], new byte[]{signature.v}), + ByteUtil.merge(new byte[]{1}, new byte[30], new byte[]{signature.v}), ByteUtil.bigIntegerToBytes(signature.r, 32), ByteUtil.bigIntegerToBytes(signature.s, 32)); @@ -894,16 +883,15 @@ public static BlockchainImpl createBlockchain(Genesis genesis) { RepositoryRoot repository = new RepositoryRoot(new NoDeleteSource<>(new HashMapDB())); ProgramInvokeFactoryImpl programInvokeFactory = new ProgramInvokeFactoryImpl(); - EthereumListenerAdapter listener = new EthereumListenerAdapter(); - BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository) + BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository, new Publisher(EventDispatchThread.getDefault())) .withParentBlockHeaderValidator(new CommonConfig().parentHeaderValidator()); blockchain.setParentHeaderValidator(new DependentBlockHeaderRuleAdapter()); blockchain.setProgramInvokeFactory(programInvokeFactory); blockchain.byTest = true; - PendingStateImpl pendingState = new PendingStateImpl(listener); + PendingStateImpl pendingState = new PendingStateImpl(new Publisher(EventDispatchThread.getDefault())); pendingState.setBlockchain(blockchain); blockchain.setPendingState(pendingState); diff --git a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateLongRunTest.java b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateLongRunTest.java index 398dbec5c5..884de68842 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateLongRunTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateLongRunTest.java @@ -19,10 +19,9 @@ import org.ethereum.config.CommonConfig; import org.ethereum.datasource.inmem.HashMapDB; -import org.ethereum.db.RepositoryRoot; -import org.ethereum.db.ByteArrayWrapper; import org.ethereum.db.IndexedBlockStore; -import org.ethereum.listener.EthereumListenerAdapter; +import org.ethereum.db.RepositoryRoot; +import org.ethereum.publish.Publisher; import org.ethereum.validator.DependentBlockHeaderRuleAdapter; import org.ethereum.vm.program.invoke.ProgramInvokeFactoryImpl; import org.junit.Before; @@ -40,7 +39,7 @@ import java.util.List; import static org.ethereum.util.BIUtil.toBI; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; /** * @author Mikhail Kalinin @@ -125,14 +124,14 @@ private Blockchain createBlockchain(Genesis genesis) { ProgramInvokeFactoryImpl programInvokeFactory = new ProgramInvokeFactoryImpl(); - BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository) + BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository, new Publisher(EventDispatchThread.getDefault())) .withParentBlockHeaderValidator(new CommonConfig().parentHeaderValidator()); blockchain.setParentHeaderValidator(new DependentBlockHeaderRuleAdapter()); blockchain.setProgramInvokeFactory(programInvokeFactory); blockchain.byTest = true; - PendingStateImpl pendingState = new PendingStateImpl(new EthereumListenerAdapter()); + PendingStateImpl pendingState = new PendingStateImpl(new Publisher(EventDispatchThread.getDefault())); pendingState.setBlockchain(blockchain); blockchain.setPendingState(pendingState); diff --git a/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/suite/TestRunner.java b/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/suite/TestRunner.java index c374bf463a..cb2c6f3f82 100644 --- a/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/suite/TestRunner.java +++ b/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/suite/TestRunner.java @@ -19,11 +19,7 @@ import org.ethereum.config.CommonConfig; import org.ethereum.config.SystemProperties; -import org.ethereum.core.Block; -import org.ethereum.core.BlockchainImpl; -import org.ethereum.core.ImportResult; -import org.ethereum.core.PendingStateImpl; -import org.ethereum.core.Repository; +import org.ethereum.core.*; import org.ethereum.datasource.inmem.HashMapDB; import org.ethereum.db.*; import org.ethereum.jsontestsuite.suite.builder.BlockBuilder; @@ -31,9 +27,8 @@ import org.ethereum.jsontestsuite.suite.model.BlockTck; import org.ethereum.jsontestsuite.suite.validators.BlockHeaderValidator; import org.ethereum.jsontestsuite.suite.validators.RepositoryValidator; -import org.ethereum.listener.EthereumListenerAdapter; +import org.ethereum.publish.Publisher; import org.ethereum.util.ByteUtil; -import org.ethereum.validator.DependentBlockHeaderRuleAdapter; import org.ethereum.vm.DataWord; import org.ethereum.vm.LogInfo; import org.ethereum.vm.VM; @@ -47,11 +42,7 @@ import org.spongycastle.util.encoders.Hex; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; import static org.ethereum.crypto.HashUtil.shortHash; import static org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY; @@ -99,11 +90,11 @@ public List runTestCase(BlockTestCase testCase) { ProgramInvokeFactoryImpl programInvokeFactory = new ProgramInvokeFactoryImpl(); - BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository) + BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository, new Publisher(EventDispatchThread.getDefault())) .withParentBlockHeaderValidator(CommonConfig.getDefault().parentHeaderValidator()); blockchain.byTest = true; - PendingStateImpl pendingState = new PendingStateImpl(new EthereumListenerAdapter()); + PendingStateImpl pendingState = new PendingStateImpl(new Publisher(EventDispatchThread.getDefault())); blockchain.setBestBlock(genesis); blockchain.setTotalDifficulty(genesis.getDifficultyBI()); @@ -121,8 +112,8 @@ public List runTestCase(BlockTestCase testCase) { blockTck.getUncleHeaders()); setNewStateRoot = !((blockTck.getTransactions() == null) - && (blockTck.getUncleHeaders() == null) - && (blockTck.getBlockHeader() == null)); + && (blockTck.getUncleHeaders() == null) + && (blockTck.getBlockHeader() == null)); Block tBlock = null; try { @@ -132,7 +123,7 @@ public List runTestCase(BlockTestCase testCase) { ArrayList outputSummary = BlockHeaderValidator.valid(tBlock.getHeader(), block.getHeader()); - if (!outputSummary.isEmpty()){ + if (!outputSummary.isEmpty()) { for (String output : outputSummary) logger.error("{}", output); } @@ -161,7 +152,7 @@ public List runTestCase(BlockTestCase testCase) { testCase.getLastblockhash().substring(2) : testCase.getLastblockhash()); String finalRoot = Hex.toHexString(blockStore.getBlockByHash(bestHash).getStateRoot()); - if (!finalRoot.equals(currRoot)){ + if (!finalRoot.equals(currRoot)) { String formattedString = String.format("Root hash doesn't match best: expected: %s current: %s", finalRoot, currRoot); results.add(formattedString); @@ -350,7 +341,7 @@ public List runTestCase(TestCase testCase) { } } - /* asset logs */ + /* asset logs */ List logResult = program.getResult().getLogInfoList(); List logResults = logs.compareToReal(logResult); @@ -500,7 +491,7 @@ public org.ethereum.core.Transaction createTransaction(Transaction tx) { public Repository loadRepository(Repository track, Map pre) { - /* 1. Store pre-exist accounts - Pre */ + /* 1. Store pre-exist accounts - Pre */ for (ByteArrayWrapper key : pre.keySet()) { AccountState accountState = pre.get(key); diff --git a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java index f37a607b48..79836d294b 100644 --- a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java @@ -21,19 +21,13 @@ import org.apache.commons.lang3.mutable.MutableObject; import org.ethereum.config.CommonConfig; import org.ethereum.config.SystemProperties; -import org.ethereum.core.AccountState; -import org.ethereum.core.Block; -import org.ethereum.core.BlockSummary; -import org.ethereum.core.Repository; -import org.ethereum.core.Transaction; -import org.ethereum.core.TransactionExecutor; -import org.ethereum.core.TransactionReceipt; +import org.ethereum.core.*; import org.ethereum.db.ContractDetails; -import org.ethereum.db.RepositoryImpl; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; import org.ethereum.listener.EthereumListener; import org.ethereum.listener.EthereumListenerAdapter; +import org.ethereum.publish.Publisher; import org.ethereum.sync.SyncManager; import org.ethereum.util.FastByteComparisons; import org.ethereum.vm.program.invoke.ProgramInvokeFactory; @@ -49,7 +43,6 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -60,18 +53,18 @@ /** * Regular sync with load * Loads ethereumJ during sync with various onBlock/repo track/callback usages - * + *

      * Runs sync with defined config for 1-30 minutes * - checks State Trie is not broken * - checks whether all blocks are in blockstore, validates parent connection and bodies * - checks and validate transaction receipts * Stopped, than restarts in 1 minute, syncs and pass all checks again. * Repeats forever or until first error occurs - * + *

      * Run with '-Dlogback.configurationFile=longrun/logback.xml' for proper logging * Also following flags are available: - * -Dreset.db.onFirstRun=true - * -Doverride.config.res=longrun/conf/live.conf + * -Dreset.db.onFirstRun=true + * -Doverride.config.res=longrun/conf/live.conf */ @Ignore public class SyncWithLoadTest { @@ -88,7 +81,7 @@ public class SyncWithLoadTest { private static final MutableObject resetDBOnFirstRun = new MutableObject<>(null); // Timer stops while not syncing - private static final AtomicLong lastImport = new AtomicLong(); + private static final AtomicLong lastImport = new AtomicLong(); private static final int LAST_IMPORT_TIMEOUT = 10 * 60 * 1000; public SyncWithLoadTest() throws Exception { @@ -209,7 +202,7 @@ public void onPendingTransactionsReceived(List transactions) { try { TransactionExecutor executor = new TransactionExecutor (tx, block.getCoinbase(), repository, ethereum.getBlockchain().getBlockStore(), - programInvokeFactory, block, new EthereumListenerAdapter(), 0) + programInvokeFactory, block, new Publisher(EventDispatchThread.getDefault()), 0) .withCommonConfig(commonConfig) .setLocalCall(true); @@ -285,13 +278,13 @@ public void testDelayedCheck() throws Exception { new Thread(() -> { try { - while(firstRun.get()) { + while (firstRun.get()) { sleep(1000); } testLogger.info("Stopping first run"); - while(true) { - while(isRunning.get()) { + while (true) { + while (isRunning.get()) { sleep(1000); } regularNode.close(); diff --git a/ethereumj-core/src/test/java/org/ethereum/mine/ExternalMinerTest.java b/ethereumj-core/src/test/java/org/ethereum/mine/ExternalMinerTest.java index 3808cc4427..f09702edfa 100644 --- a/ethereumj-core/src/test/java/org/ethereum/mine/ExternalMinerTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/mine/ExternalMinerTest.java @@ -23,14 +23,11 @@ import org.ethereum.config.blockchain.FrontierConfig; import org.ethereum.core.Block; import org.ethereum.core.BlockHeader; -import org.ethereum.core.BlockchainImpl; +import org.ethereum.core.EventDispatchThread; import org.ethereum.core.ImportResult; -import org.ethereum.db.PruneManager; -import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumImpl; -import org.ethereum.listener.CompositeEthereumListener; +import org.ethereum.publish.Publisher; import org.ethereum.util.ByteUtil; -import org.ethereum.util.blockchain.LocalBlockchain; import org.ethereum.util.blockchain.StandaloneBlockchain; import org.junit.Before; import org.junit.Test; @@ -39,14 +36,13 @@ import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -import org.springframework.beans.factory.annotation.Autowired; import javax.annotation.Resource; import java.math.BigInteger; import java.util.Collection; -import static java.util.Collections.*; -import static org.hamcrest.CoreMatchers.*; +import static java.util.Collections.EMPTY_LIST; +import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Mockito.when; @@ -59,15 +55,14 @@ public class ExternalMinerTest { private StandaloneBlockchain bc = new StandaloneBlockchain().withAutoblock(false); - private CompositeEthereumListener listener = new CompositeEthereumListener(); - @Mock private EthereumImpl ethereum; @InjectMocks @Resource - private BlockMiner blockMiner = new BlockMiner(SystemProperties.getDefault(), listener, bc.getBlockchain(), - bc.getBlockchain().getBlockStore(), bc.getPendingState());; + private BlockMiner blockMiner = new BlockMiner(SystemProperties.getDefault(), new Publisher(EventDispatchThread.getDefault()), bc.getBlockchain(), + bc.getBlockchain().getBlockStore(), bc.getPendingState()); + ; @Before public void setup() { @@ -110,7 +105,8 @@ public boolean validate(BlockHeader blockHeader) { } @Override - public void setListeners(Collection listeners) {} + public void setListeners(Collection listeners) { + } }); Block b = bc.getBlockchain().createNewBlock(startBestBlock, EMPTY_LIST, EMPTY_LIST); Ethash.getForBlock(SystemProperties.getDefault(), b.getNumber()).mineLight(b).get(); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java b/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java index 3b0c03011e..ba8821826a 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java @@ -17,22 +17,17 @@ */ package org.ethereum.net.eth.handler; -import org.ethereum.config.CommonConfig; import org.ethereum.config.NoAutoscan; import org.ethereum.config.SystemProperties; -import org.ethereum.core.Block; -import org.ethereum.core.BlockHeader; -import org.ethereum.core.Blockchain; -import org.ethereum.core.BlockchainImpl; +import org.ethereum.core.*; import org.ethereum.db.BlockStore; import org.ethereum.db.BlockStoreDummy; -import org.ethereum.listener.CompositeEthereumListener; import org.ethereum.net.eth.message.EthMessage; import org.ethereum.net.eth.message.GetBlockBodiesMessage; import org.ethereum.net.eth.message.GetBlockHeadersMessage; +import org.ethereum.publish.Publisher; import org.ethereum.sync.SyncManager; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.mockito.Mockito; import org.spongycastle.util.encoders.Hex; @@ -98,11 +93,12 @@ public synchronized boolean isBlockExist(byte[] hash) { }; SysPropConfig1.testHandler = new Eth62(SysPropConfig1.props, blockchain, blockStoreDummy, - new CompositeEthereumListener()) { + new Publisher(EventDispatchThread.getDefault())) { { this.blockstore = blockStoreDummy; this.syncManager = Mockito.mock(SyncManager.class); } + @Override public synchronized void sendStatus() { super.sendStatus(); @@ -144,15 +140,15 @@ public SystemProperties systemProperties() { public synchronized void testHeadersWithoutSkip() throws FileNotFoundException, InterruptedException { ExecutorService executor1 = Executors.newSingleThreadExecutor(); executor1.submit(() -> { - blockchain.isBlockExist(null); - } + blockchain.isBlockExist(null); + } ); this.wait(DELAY); ExecutorService executor2 = Executors.newSingleThreadExecutor(); executor2.submit(() -> { - GetBlockHeadersMessage msg = new GetBlockHeadersMessage(1L, new byte[0], 10, 0, false); - SysPropConfig1.testHandler.processGetBlockHeaders(msg); - } + GetBlockHeadersMessage msg = new GetBlockHeadersMessage(1L, new byte[0], 10, 0, false); + SysPropConfig1.testHandler.processGetBlockHeaders(msg); + } ); this.wait(DELAY); assert result.get(); @@ -162,15 +158,15 @@ public synchronized void testHeadersWithoutSkip() throws FileNotFoundException, public synchronized void testHeadersWithSkip() throws FileNotFoundException, InterruptedException { ExecutorService executor1 = Executors.newSingleThreadExecutor(); executor1.submit(() -> { - blockchain.isBlockExist(null); - } + blockchain.isBlockExist(null); + } ); this.wait(DELAY); ExecutorService executor2 = Executors.newSingleThreadExecutor(); executor2.submit(() -> { - GetBlockHeadersMessage msg = new GetBlockHeadersMessage(1L, new byte[0], 10, 5, false); - SysPropConfig1.testHandler.processGetBlockHeaders(msg); - } + GetBlockHeadersMessage msg = new GetBlockHeadersMessage(1L, new byte[0], 10, 5, false); + SysPropConfig1.testHandler.processGetBlockHeaders(msg); + } ); this.wait(DELAY); assert result.get(); @@ -180,18 +176,18 @@ public synchronized void testHeadersWithSkip() throws FileNotFoundException, Int public synchronized void testBodies() throws FileNotFoundException, InterruptedException { ExecutorService executor1 = Executors.newSingleThreadExecutor(); executor1.submit(() -> { - blockchain.isBlockExist(null); - } + blockchain.isBlockExist(null); + } ); this.wait(DELAY); ExecutorService executor2 = Executors.newSingleThreadExecutor(); executor2.submit(() -> { - List hashes = new ArrayList<>(); - hashes.add(new byte[] {1, 2, 3}); - hashes.add(new byte[] {4, 5, 6}); - GetBlockBodiesMessage msg = new GetBlockBodiesMessage(hashes); - SysPropConfig1.testHandler.processGetBlockBodies(msg); - } + List hashes = new ArrayList<>(); + hashes.add(new byte[]{1, 2, 3}); + hashes.add(new byte[]{4, 5, 6}); + GetBlockBodiesMessage msg = new GetBlockBodiesMessage(hashes); + SysPropConfig1.testHandler.processGetBlockBodies(msg); + } ); this.wait(DELAY); assert result.get(); @@ -201,18 +197,18 @@ public synchronized void testBodies() throws FileNotFoundException, InterruptedE public synchronized void testStatus() throws FileNotFoundException, InterruptedException { ExecutorService executor1 = Executors.newSingleThreadExecutor(); executor1.submit(() -> { - blockchain.isBlockExist(null); - } + blockchain.isBlockExist(null); + } ); this.wait(DELAY); ExecutorService executor2 = Executors.newSingleThreadExecutor(); executor2.submit(() -> { - try { - SysPropConfig1.testHandler.sendStatus(); - } catch (Exception e) { - e.printStackTrace(); - } - } + try { + SysPropConfig1.testHandler.sendStatus(); + } catch (Exception e) { + e.printStackTrace(); + } + } ); this.wait(DELAY); assert result.get(); diff --git a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java new file mode 100644 index 0000000000..05125c8a1b --- /dev/null +++ b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java @@ -0,0 +1,142 @@ +package org.ethereum.publish; + +import org.ethereum.core.EventDispatchThread; +import org.ethereum.publish.event.Event; +import org.ethereum.publish.event.Single; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.stream.IntStream; + +import static org.ethereum.publish.Subscription.to; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class PublisherTest { + + private class IntEvent extends Event { + IntEvent(Integer payload) { + super(payload); + } + } + + private class LongEvent extends Event { + LongEvent(long payload) { + super(payload); + } + } + + private class StringEvent extends Event { + StringEvent(String payload) { + super(payload); + } + } + + private class SingleStringEvent extends StringEvent implements Single { + SingleStringEvent(String payload) { + super(payload); + } + } + + + @Test + public void testDuplicateSubscription() { + Subscription subscription = Subscription.to(IntEvent.class, System.out::print); + + int subscribersCount = createPublisher() + .subscribe(subscription) + .subscribe(subscription) + .subscribersCount(subscription.getEventType()); + + assertEquals(1, subscribersCount); + } + + + @Test + public void testSingleEvent() { + final String payload = "desired event"; + final List strings = new ArrayList<>(); + + int subscribersCount = createPublisher() + .subscribe(to(SingleStringEvent.class, strings::add)) + .publish(new SingleStringEvent(payload)) + .subscribersCount(SingleStringEvent.class); + + assertEquals(0, subscribersCount); + assertTrue(strings.contains(payload)); + } + + @Test + public void testConditionallySubscription() { + + AtomicLong expectedSum = new AtomicLong(); + AtomicInteger expectedEvenSum = new AtomicInteger(); + + int[] numbers = IntStream.rangeClosed(1, 10).toArray(); + int sum = IntStream.of(numbers).sum(); + int evenSum = IntStream.of(numbers).filter(num -> isEven(num)).sum(); + + Publisher publisher = createPublisher() + .subscribe(to(LongEvent.class, expectedSum::getAndAdd)) + .subscribe(to(IntEvent.class, expectedEvenSum::getAndAdd) + .conditionally(PublisherTest::isEven)); + + IntStream.of(numbers) + .forEach(num -> publisher + .publish(new LongEvent(num)) + .publish(new IntEvent(num))); + + assertEquals(sum, expectedSum.get()); + assertEquals(evenSum, expectedEvenSum.get()); + } + + @Test + public void testPublishing() { + + AtomicLong longEvenSum = new AtomicLong(); + AtomicInteger firstIntSum = new AtomicInteger(); + AtomicInteger secondIntSum = new AtomicInteger(); + List expectedStrings = new ArrayList<>(); + + List strings = Arrays.asList("some event", "another event", "incredible event"); + int[] numbers = IntStream.rangeClosed(1, 10).toArray(); + int sum = IntStream.of(numbers).sum(); + int evenSum = IntStream.of(numbers).filter(num -> isEven(num)).sum(); + + + Publisher publisher = createPublisher() + .subscribe(to(IntEvent.class, firstIntSum::getAndAdd)) + .subscribe(to(IntEvent.class, secondIntSum::getAndAdd)) + .subscribe(to(StringEvent.class, expectedStrings::add)) + .subscribe(to(LongEvent.class, longEvenSum::getAndAdd) + .conditionally(PublisherTest::isEven)); + + IntStream.of(numbers) + .forEach(num -> publisher + .publish(new IntEvent(num)) + .publish(new LongEvent(num))); + + strings.stream() + .forEach(str -> publisher + .publish(new StringEvent(str))); + + assertEquals(sum, firstIntSum.get()); + assertEquals(sum, secondIntSum.get()); + assertEquals(evenSum, longEvenSum.intValue()); + assertEquals(strings.size(), expectedStrings.stream() + .filter(strings::contains) + .count()); + } + + private static Publisher createPublisher() { + return new Publisher(EventDispatchThread.getDefault()); + } + + private static boolean isEven(long number) { + return number % 2 == 0; + } +} \ No newline at end of file diff --git a/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java b/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java index 6c0d09b269..09580e8d30 100644 --- a/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java @@ -3,18 +3,19 @@ import org.ethereum.core.Block; import org.ethereum.core.BlockHeader; import org.ethereum.core.BlockSummary; -import org.ethereum.listener.CompositeEthereumListener; +import org.ethereum.core.EventDispatchThread; import org.ethereum.listener.EthereumListener; import org.ethereum.mine.EthashValidationHelper; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.BestBlockAddedEvent; +import org.ethereum.publish.event.SyncDoneEvent; import org.junit.Test; import org.spongycastle.util.encoders.Hex; import java.util.Collections; import static org.ethereum.validator.BlockHeaderRule.Success; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; /** * @author Mikhail Kalinin @@ -22,22 +23,6 @@ */ public class EthashRuleTest { - static class CompositeEthereumListenerMock extends CompositeEthereumListener { - @Override - public void onBlock(final BlockSummary blockSummary, final boolean best) { - for (final EthereumListener listener : listeners) { - listener.onBlock(blockSummary, best); - } - } - - @Override - public void onSyncDone(final SyncState state) { - for (final EthereumListener listener : listeners) { - listener.onSyncDone(state); - } - } - } - static class EthashValidationHelperMock extends EthashValidationHelper { long preCacheCounter = 0; @@ -66,8 +51,8 @@ public void fake() { @Test public void testFake() { - CompositeEthereumListener listener = new CompositeEthereumListenerMock(); - EthashRule rule = new EthashRule(EthashRule.Mode.fake, EthashRule.ChainType.main, listener); + Publisher publisher = new Publisher(EventDispatchThread.getDefault()); + EthashRule rule = new EthashRule(EthashRule.Mode.fake, EthashRule.ChainType.main, publisher); assertEquals(Success, rule.validate(validHeader)); assertEquals(Success, rule.validate(partlyValidHeader)); @@ -76,14 +61,14 @@ public void testFake() { @Test public void testStrict() { - CompositeEthereumListener listener = new CompositeEthereumListenerMock(); - EthashRule rule = new EthashRule(EthashRule.Mode.strict, EthashRule.ChainType.main, listener); + Publisher publisher = new Publisher(EventDispatchThread.getDefault()); + EthashRule rule = new EthashRule(EthashRule.Mode.strict, EthashRule.ChainType.main, publisher); // cache is empty, fallback into fake rule assertEquals(Success, rule.validate(partlyValidHeader)); // trigger ethash cache - listener.onBlock(dummySummaryNum_1, true); + publisher.publish(new BestBlockAddedEvent(dummySummaryNum_1, true)); assertEquals(Success, rule.validate(validHeader)); assertNotEquals(Success, rule.validate(partlyValidHeader)); @@ -97,11 +82,11 @@ public void testStrict() { @Test public void testMixed() { - CompositeEthereumListener listener = new CompositeEthereumListenerMock(); - EthashRule rule = new EthashRule(EthashRule.Mode.mixed, EthashRule.ChainType.main, listener); + Publisher publisher = new Publisher(EventDispatchThread.getDefault()); + EthashRule rule = new EthashRule(EthashRule.Mode.mixed, EthashRule.ChainType.main, publisher); // trigger ethash cache - listener.onBlock(dummySummaryNum_1, true); + publisher.publish(new BestBlockAddedEvent(dummySummaryNum_1, true)); // check mixed mode randomness boolean fullCheckTriggered = false; @@ -119,7 +104,7 @@ public void testMixed() { assertTrue(partialCheckTriggered); // trigger onSyncDone - listener.onSyncDone(EthereumListener.SyncState.COMPLETE); + publisher.publish(new SyncDoneEvent(EthereumListener.SyncState.COMPLETE)); // check that full verification is done on each run in strict mode for (int i = 0; i < 100; i++) { @@ -130,14 +115,15 @@ public void testMixed() { @Test public void testCacheMain() { EthashValidationHelperMock helper = new EthashValidationHelperMock(EthashValidationHelper.CacheOrder.direct); - CompositeEthereumListener listener = new CompositeEthereumListenerMock(); - EthashRule rule = new EthashRule(EthashRule.Mode.mixed, EthashRule.ChainType.main, listener); + Publisher publisher = new Publisher(EventDispatchThread.getDefault()); + EthashRule rule = new EthashRule(EthashRule.Mode.mixed, EthashRule.ChainType.main, publisher); rule.ethashHelper = helper; // trigger cache for (int i = 0; i < 100; i++) { - listener.onBlock(dummySummaryNum_1, false); - listener.onBlock(dummySummaryNum_1, true); + publisher + .publish(new BestBlockAddedEvent(dummySummaryNum_1, false)) + .publish(new BestBlockAddedEvent(dummySummaryNum_1, true)); } // must be triggered on best block only @@ -147,8 +133,8 @@ public void testCacheMain() { @Test public void testCacheDirect() { EthashValidationHelperMock helper = new EthashValidationHelperMock(EthashValidationHelper.CacheOrder.direct); - CompositeEthereumListener listener = new CompositeEthereumListenerMock(); - EthashRule rule = new EthashRule(EthashRule.Mode.mixed, EthashRule.ChainType.direct, listener); + Publisher publisher = new Publisher(EventDispatchThread.getDefault()); + EthashRule rule = new EthashRule(EthashRule.Mode.mixed, EthashRule.ChainType.direct, publisher); rule.ethashHelper = helper; // trigger cache @@ -159,11 +145,12 @@ public void testCacheDirect() { // must be triggered each verification attempt, in spite of mixed mode assertEquals(100, helper.preCacheCounter); } + @Test public void testCacheReverse() { EthashValidationHelperMock helper = new EthashValidationHelperMock(EthashValidationHelper.CacheOrder.direct); - CompositeEthereumListener listener = new CompositeEthereumListenerMock(); - EthashRule rule = new EthashRule(EthashRule.Mode.mixed, EthashRule.ChainType.reverse, listener); + Publisher publisher = new Publisher(EventDispatchThread.getDefault()); + EthashRule rule = new EthashRule(EthashRule.Mode.mixed, EthashRule.ChainType.reverse, publisher); rule.ethashHelper = helper; // trigger cache From 8165a2ce5ec166604a570916555686b63c8ebd0d Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Fri, 10 Aug 2018 13:46:28 +0300 Subject: [PATCH 02/28] Removes (almost) EthereumListenerAdaptor using --- .../org/ethereum/core/BlockchainImpl.java | 4 +- .../java/org/ethereum/facade/Ethereum.java | 5 + .../org/ethereum/facade/EthereumImpl.java | 7 + .../org/ethereum/listener/EventListener.java | 2 +- .../listener/RecommendedGasPriceTracker.java | 3 +- .../java/org/ethereum/net/MessageQueue.java | 11 +- .../org/ethereum/net/client/PeerClient.java | 6 +- .../ethereum/net/eth/handler/EthHandler.java | 6 +- .../java/org/ethereum/publish/Publisher.java | 4 +- .../publish/event/TraceCreatedEvent.java | 8 - .../ethereum/publish/event/TraceEvent.java | 8 + .../org/ethereum/samples/BasicSample.java | 141 +++----- .../samples/CreateContractSample.java | 52 ++- .../ethereum/samples/EventListenerSample.java | 43 +-- .../org/ethereum/samples/FollowAccount.java | 43 +-- .../ethereum/samples/PendingStateSample.java | 49 ++- .../org/ethereum/samples/SendTransaction.java | 36 +- .../org/ethereum/samples/TransactionBomb.java | 27 +- .../main/java/org/ethereum/sync/SyncPool.java | 6 +- .../util/blockchain/StandaloneBlockchain.java | 9 +- .../java/org/ethereum/core/CloseTest.java | 19 +- .../org/ethereum/core/PendingStateTest.java | 132 ++++--- .../java/org/ethereum/longrun/BasicNode.java | 53 +-- .../ethereum/longrun/SyncWithLoadTest.java | 112 +++--- .../java/org/ethereum/mine/MinerTest.java | 61 ++-- .../java/org/ethereum/mine/SyncDoneTest.java | 178 ++++------ .../java/org/ethereum/net/TwoPeerTest.java | 34 +- .../org/ethereum/net/rlpx/FramingTest.java | 33 +- .../ethereum/net/rlpx/SanityLongRunTest.java | 53 ++- .../net/rlpx/SnappyConnectionTest.java | 28 +- .../java/org/ethereum/net/shh/ShhLongRun.java | 19 +- .../org/ethereum/sync/BlockTxForwardTest.java | 332 ++++++++---------- .../java/org/ethereum/sync/LongSyncTest.java | 124 +++---- .../java/org/ethereum/sync/ShortSyncTest.java | 317 +++++++---------- 34 files changed, 866 insertions(+), 1099 deletions(-) delete mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/TraceCreatedEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/TraceEvent.java diff --git a/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java b/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java index 54d2c30ae5..f8ba3befd6 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java @@ -28,7 +28,7 @@ import org.ethereum.publish.Publisher; import org.ethereum.publish.event.BestBlockAddedEvent; import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.TraceCreatedEvent; +import org.ethereum.publish.event.TraceEvent; import org.ethereum.sync.SyncManager; import org.ethereum.trie.Trie; import org.ethereum.trie.TrieImpl; @@ -457,7 +457,7 @@ public synchronized ImportResult tryToConnect(final Block block) { publisher .publish(new BlockAddedEvent(summary)) .publish(new BestBlockAddedEvent(summary, ret == IMPORTED_BEST)) - .publish(new TraceCreatedEvent(format("Block chain size: [ %d ]", this.getSize()))); + .publish(new TraceEvent(format("Block chain size: [ %d ]", this.getSize()))); if (ret == IMPORTED_BEST) { eventDispatchThread.invokeLater(() -> pendingState.processBest(block, summary.getReceipts())); diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java index 0fcd872280..010e492b23 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java @@ -27,6 +27,9 @@ import org.ethereum.net.rlpx.Node; import org.ethereum.net.server.ChannelManager; import org.ethereum.net.shh.Whisper; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.Subscription; +import org.ethereum.publish.event.Event; import org.ethereum.vm.program.ProgramResult; import java.math.BigInteger; @@ -59,6 +62,8 @@ public interface Ethereum { boolean isConnected(); + , P> Publisher subscribe(Subscription subscription); + void close(); /** diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index 2fb01e10d2..0d62d3fbdf 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -37,7 +37,9 @@ import org.ethereum.net.submit.TransactionExecutor; import org.ethereum.net.submit.TransactionTask; import org.ethereum.publish.Publisher; +import org.ethereum.publish.Subscription; import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.Event; import org.ethereum.sync.SyncManager; import org.ethereum.util.ByteUtil; import org.ethereum.vm.program.ProgramResult; @@ -174,6 +176,11 @@ public void addListener(EthereumListener listener) { worldManager.getPublisher().subscribeListener(listener); } + @Override + public , P> Publisher subscribe(Subscription subscription) { + return worldManager.getPublisher().subscribe(subscription); + } + @Override public void close() { logger.info("### Shutdown initiated ### "); diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/EventListener.java b/ethereumj-core/src/main/java/org/ethereum/listener/EventListener.java index f00fe5e3b5..c07a3beb4e 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/EventListener.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/EventListener.java @@ -118,7 +118,7 @@ public String toString() { private boolean initialized = false; // txHash => PendingEvent - protected ByteArrayMap pendings = new ByteArrayMap<>(new LinkedHashMap()); + protected ByteArrayMap pendings = new ByteArrayMap<>(new LinkedHashMap<>()); protected Block bestBlock; BigInteger lastTotDiff = BigInteger.ZERO; // executing EthereumListener callbacks on a separate thread to avoid long running diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/RecommendedGasPriceTracker.java b/ethereumj-core/src/main/java/org/ethereum/listener/RecommendedGasPriceTracker.java index 9f61f5ae3a..5fee184429 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/RecommendedGasPriceTracker.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/RecommendedGasPriceTracker.java @@ -38,7 +38,7 @@ * (if {@link #getPercentileShare()} is not overridden) of the latest transactions were * executed at this or lower price. */ -public class RecommendedGasPriceTracker extends EthereumListenerAdapter { +public class RecommendedGasPriceTracker { private static final Long DEFAULT_PRICE = null; private static final int MIN_BLOCKS = 128; @@ -51,7 +51,6 @@ public class RecommendedGasPriceTracker extends EthereumListenerAdapter { private int idx = 0; private Long recommendedGasPrice = getDefaultPrice(); - @Override public void onBlock(BlockSummary blockSummary) { onBlock(blockSummary.getBlock()); } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java b/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java index cd1e86b325..f088fd2cff 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java @@ -19,14 +19,15 @@ import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; -import org.ethereum.listener.EthereumListener; import org.ethereum.net.eth.message.EthMessage; import org.ethereum.net.message.Message; import org.ethereum.net.message.ReasonCode; import org.ethereum.net.p2p.DisconnectMessage; import org.ethereum.net.p2p.PingMessage; -import org.ethereum.net.p2p.PongMessage; import org.ethereum.net.server.Channel; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.TraceEvent; +import org.ethereum.publish.event.message.SentMessageEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -73,7 +74,7 @@ public Thread newThread(Runnable r) { private ChannelHandlerContext ctx = null; @Autowired - EthereumListener ethereumListener; + private Publisher publisher; boolean hasPing = false; private ScheduledFuture timerTask; private Channel channel; @@ -128,7 +129,7 @@ private void disconnect(DisconnectMessage msg) { public void receivedMessage(Message msg) throws InterruptedException { - ethereumListener.trace("[Recv: " + msg + "]"); + publisher.publish(new TraceEvent("[Recv: " + msg + "]")); if (requestQueue.peek() != null) { MessageRoundtrip messageRoundtrip = requestQueue.peek(); @@ -167,7 +168,7 @@ private void sendToWire(MessageRoundtrip messageRoundtrip) { Message msg = messageRoundtrip.getMsg(); - ethereumListener.onSendMessage(channel, msg); + publisher.publish(new SentMessageEvent(channel, msg)); ctx.writeAndFlush(msg).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java b/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java index 10b71361a7..ed5fb872d4 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java @@ -29,6 +29,8 @@ import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.TraceEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,7 +60,7 @@ public class PeerClient { private ApplicationContext ctx; @Autowired - EthereumListener ethereumListener; + private Publisher publisher; private EventLoopGroup workerGroup; @@ -105,7 +107,7 @@ public void connect(String host, int port, String remoteId, boolean discoveryMod } public ChannelFuture connectAsync(String host, int port, String remoteId, boolean discoveryMode) { - ethereumListener.trace("Connecting to: " + host + ":" + port); + publisher.publish(new TraceEvent("Connecting to: " + host + ":" + port)); EthereumChannelInitializer ethereumChannelInitializer = ctx.getBean(EthereumChannelInitializer.class, remoteId); ethereumChannelInitializer.setPeerDiscoveryMode(discoveryMode); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java index 9aa2a25134..853246ab87 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java @@ -34,7 +34,7 @@ import org.ethereum.publish.Publisher; import org.ethereum.publish.Subscription; import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.TraceCreatedEvent; +import org.ethereum.publish.event.TraceEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -96,7 +96,7 @@ public void channelRead0(final ChannelHandlerContext ctx, EthMessage msg) throws if (EthMessageCodes.inRange(msg.getCommand().asByte(), version)) logger.trace("EthHandler invoke: [{}]", msg.getCommand()); - publisher.publish(new TraceCreatedEvent(format("EthHandler invoke: [%s]", msg.getCommand()))); + publisher.publish(new TraceEvent(format("EthHandler invoke: [%s]", msg.getCommand()))); channel.getNodeStatistics().ethInbound.add(); @@ -122,7 +122,7 @@ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { public void activate() { logger.debug("ETH protocol activated"); - publisher.publish(new TraceCreatedEvent("ETH protocol activated")); + publisher.publish(new TraceEvent("ETH protocol activated")); sendStatus(); } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java index c85b3e4c17..4b74118d13 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java @@ -184,7 +184,7 @@ public void shutdown() { */ public void subscribeListener(EthereumListener listener) { this - .subscribe(to(TraceCreatedEvent.class, listener::trace)) + .subscribe(to(TraceEvent.class, listener::trace)) .subscribe(to(NodeDiscoveredEvent.class, listener::onNodeDiscovered)) .subscribe(to(PeerHandshakedEvent.class, data -> listener.onHandShakePeer(data.getChannel(), data.getMessage()))) .subscribe(to(EthStatusUpdatedEvent.class, data -> listener.onEthStatusUpdated(data.getChannel(), data.getMessage()))) @@ -213,7 +213,7 @@ public EthereumListener asListener() { return new EthereumListener() { @Override public void trace(String output) { - publish(new TraceCreatedEvent(output)); + publish(new TraceEvent(output)); } @Override diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/TraceCreatedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/TraceCreatedEvent.java deleted file mode 100644 index da83ebea35..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/TraceCreatedEvent.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.ethereum.publish.event; - -public class TraceCreatedEvent extends Event { - - public TraceCreatedEvent(String trace) { - super(trace); - } -} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/TraceEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/TraceEvent.java new file mode 100644 index 0000000000..0320189b46 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/TraceEvent.java @@ -0,0 +1,8 @@ +package org.ethereum.publish.event; + +public class TraceEvent extends Event { + + public TraceEvent(String trace) { + super(trace); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java index e1c8f219ea..4eb4e1b443 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java @@ -24,16 +24,17 @@ import ch.qos.logback.core.filter.Filter; import ch.qos.logback.core.spi.FilterReply; import org.ethereum.config.SystemProperties; -import org.ethereum.core.*; +import org.ethereum.core.Block; +import org.ethereum.core.TransactionReceipt; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.net.eth.message.StatusMessage; -import org.ethereum.net.message.Message; -import org.ethereum.net.p2p.HelloMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.net.server.Channel; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.NodeDiscoveredEvent; +import org.ethereum.publish.event.PeerAddedToSyncPoolEvent; +import org.ethereum.publish.event.SyncDoneEvent; +import org.ethereum.publish.event.message.EthStatusUpdatedEvent; import org.ethereum.util.ByteUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,18 +44,20 @@ import javax.annotation.PostConstruct; import java.util.*; +import static org.ethereum.publish.Subscription.to; + /** - * The base sample class which creates EthereumJ instance, tracks and report all the stages - * of starting up like discovering nodes, connecting, syncing - * - * The class can be started as a standalone sample it should just run until full blockchain - * sync and then just hanging, listening for new blocks and importing them into a DB - * - * This class is a Spring Component which makes it convenient to easily get access (autowire) to - * all components created within EthereumJ. However almost all this could be done without dealing - * with the Spring machinery from within a simple main method - * - * Created by Anton Nashatyrev on 05.02.2016. + * The base sample class which creates EthereumJ instance, tracks and report all the stages + * of starting up like discovering nodes, connecting, syncing + *

      + * The class can be started as a standalone sample it should just run until full blockchain + * sync and then just hanging, listening for new blocks and importing them into a DB + *

      + * This class is a Spring Component which makes it convenient to easily get access (autowire) to + * all components created within EthereumJ. However almost all this could be done without dealing + * with the Spring machinery from within a simple main method + *

      + * Created by Anton Nashatyrev on 05.02.2016. */ public class BasicSample implements Runnable { @@ -131,7 +134,25 @@ private void springInit() { setupLogging(); // adding the main EthereumJ callback to be notified on different kind of events - ethereum.addListener(listener); + this.ethereum + .subscribe(to(SyncDoneEvent.class, syncState -> synced = true)) + .subscribe(to(NodeDiscoveredEvent.class, nodesDiscovered::add) + .conditionally(node -> nodesDiscovered.size() < 1000)) + .subscribe(to(EthStatusUpdatedEvent.class, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage()))) + .subscribe(to(PeerAddedToSyncPoolEvent.class, peer -> syncPeers.add(peer.getNode()))) + .subscribe(to(BlockAddedEvent.class, bs -> { + Block block = bs.getBlock(); + List receipts = bs.getReceipts(); + + bestBlock = block; + txCount += receipts.size(); + for (TransactionReceipt receipt : receipts) { + gasSpent += ByteUtil.byteArrayToLong(receipt.getGasUsed()); + } + if (syncComplete) { + logger.info("New block: " + block.getShortDescr()); + } + })); logger.info("Sample component created. Listening for ethereum events..."); @@ -186,7 +207,7 @@ protected void waitForDiscovery() throws Exception { int bootNodes = config.peerDiscoveryIPList().size(); int cnt = 0; - while(true) { + while (true) { Thread.sleep(cnt < 30 ? 300 : 5000); if (nodesDiscovered.size() > bootNodes) { @@ -215,7 +236,7 @@ protected void waitForDiscovery() throws Exception { protected void waitForAvailablePeers() throws Exception { logger.info("Waiting for available Eth capable nodes..."); int cnt = 0; - while(true) { + while (true) { Thread.sleep(cnt < 30 ? 1000 : 5000); if (ethNodes.size() > 0) { @@ -241,7 +262,7 @@ protected void waitForAvailablePeers() throws Exception { protected void waitForSyncPeers() throws Exception { logger.info("Searching for peers to sync with..."); int cnt = 0; - while(true) { + while (true) { Thread.sleep(cnt < 30 ? 1000 : 5000); if (syncPeers.size() > 0) { @@ -268,7 +289,7 @@ protected void waitForFirstBlock() throws Exception { logger.info("Current BEST block: " + currentBest.getShortDescr()); logger.info("Waiting for blocks start importing (may take a while)..."); int cnt = 0; - while(true) { + while (true) { Thread.sleep(cnt < 300 ? 1000 : 60000); if (bestBlock != null && bestBlock.getNumber() > currentBest.getNumber()) { @@ -293,7 +314,7 @@ protected void waitForFirstBlock() throws Exception { */ private void waitForSync() throws Exception { logger.info("Waiting for the whole blockchain sync (will take up to several hours for the whole chain)..."); - while(true) { + while (true) { Thread.sleep(10000); if (synced) { @@ -309,81 +330,9 @@ private void waitForSync() throws Exception { } } - /** - * The main EthereumJ callback. - */ - EthereumListener listener = new EthereumListenerAdapter() { - @Override - public void onSyncDone(SyncState state) { - synced = true; - } - - @Override - public void onNodeDiscovered(Node node) { - if (nodesDiscovered.size() < 1000) { - nodesDiscovered.add(node); - } - } - - @Override - public void onEthStatusUpdated(Channel channel, StatusMessage statusMessage) { - ethNodes.put(channel.getNode(), statusMessage); - } - - @Override - public void onPeerAddedToSyncPool(Channel peer) { - syncPeers.add(peer.getNode()); - } - - @Override - public void onBlock(Block block, List receipts) { - bestBlock = block; - txCount += receipts.size(); - for (TransactionReceipt receipt : receipts) { - gasSpent += ByteUtil.byteArrayToLong(receipt.getGasUsed()); - } - if (syncComplete) { - logger.info("New block: " + block.getShortDescr()); - } - } - @Override - public void onRecvMessage(Channel channel, Message message) { - } - - @Override - public void onSendMessage(Channel channel, Message message) { - } - - @Override - public void onPeerDisconnect(String host, long port) { - } - - @Override - public void onPendingTransactionsReceived(List transactions) { - } - - @Override - public void onPendingStateChanged(PendingState pendingState) { - } - @Override - public void onHandShakePeer(Channel channel, HelloMessage helloMessage) { - } - - @Override - public void onNoConnections() { - } - - @Override - public void onVMTraceCreated(String transactionHash, String trace) { - } - - @Override - public void onTransactionExecuted(TransactionExecutionSummary summary) { - } - }; - private static class CustomFilter extends Filter { private Set visibleLoggers = new HashSet<>(); + @Override public synchronized FilterReply decide(ILoggingEvent event) { return visibleLoggers.contains(event.getLoggerName()) && event.getLevel().isGreaterOrEqual(Level.INFO) || diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java index 947461e5fa..acdf7356b4 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java @@ -17,14 +17,14 @@ */ package org.ethereum.samples; -import org.ethereum.core.Block; +import org.ethereum.core.BlockSummary; import org.ethereum.core.CallTransaction; import org.ethereum.core.Transaction; import org.ethereum.core.TransactionReceipt; import org.ethereum.crypto.ECKey; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListenerAdapter; +import org.ethereum.publish.event.BlockAddedEvent; import org.ethereum.solidity.compiler.CompilationResult; import org.ethereum.solidity.compiler.SolidityCompiler; import org.ethereum.util.ByteUtil; @@ -34,8 +34,11 @@ import org.springframework.context.annotation.Bean; import java.math.BigInteger; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.ByteUtil.toHexString; /** @@ -48,27 +51,21 @@ public class CreateContractSample extends TestNetSample { String contract = "contract Sample {" + - " int i;" + - " function inc(int n) {" + - " i = i + n;" + - " }" + - " function get() returns (int) {" + - " return i;" + - " }" + - "}"; - - private Map txWaiters = - Collections.synchronizedMap(new HashMap()); + " int i;" + + " function inc(int n) {" + + " i = i + n;" + + " }" + + " function get() returns (int) {" + + " return i;" + + " }" + + "}"; + + private Map txWaiters = Collections.synchronizedMap(new HashMap<>()); @Override public void onSyncDone() throws Exception { - ethereum.addListener(new EthereumListenerAdapter() { - // when block arrives look for our included transactions - @Override - public void onBlock(Block block, List receipts) { - CreateContractSample.this.onBlock(block, receipts); - } - }); + // when block arrives look for our included transactions + ethereum.subscribe(to(BlockAddedEvent.class, this::onBlock)); logger.info("Compiling contract..."); SolidityCompiler.Result result = compiler.compileSrc(contract.getBytes(), true, true, @@ -130,8 +127,9 @@ protected TransactionReceipt sendTxAndWait(byte[] receiveAddress, byte[] data) t return waitForTx(tx.getHash()); } - private void onBlock(Block block, List receipts) { - for (TransactionReceipt receipt : receipts) { + private void onBlock(BlockSummary blockSummary) { + for (TransactionReceipt receipt : blockSummary.getReceipts()) { + ByteArrayWrapper txHashW = new ByteArrayWrapper(receipt.getTransaction().getHash()); if (txWaiters.containsKey(txHashW)) { txWaiters.put(txHashW, receipt); @@ -146,16 +144,16 @@ protected TransactionReceipt waitForTx(byte[] txHash) throws InterruptedExceptio ByteArrayWrapper txHashW = new ByteArrayWrapper(txHash); txWaiters.put(txHashW, null); long startBlock = ethereum.getBlockchain().getBestBlock().getNumber(); - while(true) { + while (true) { TransactionReceipt receipt = txWaiters.get(txHashW); if (receipt != null) { return receipt; } else { long curBlock = ethereum.getBlockchain().getBestBlock().getNumber(); if (curBlock > startBlock + 16) { - throw new RuntimeException("The transaction was not included during last 16 blocks: " + txHashW.toString().substring(0,8)); + throw new RuntimeException("The transaction was not included during last 16 blocks: " + txHashW.toString().substring(0, 8)); } else { - logger.info("Waiting for block with transaction 0x" + txHashW.toString().substring(0,8) + + logger.info("Waiting for block with transaction 0x" + txHashW.toString().substring(0, 8) + " included (" + (curBlock - startBlock) + " blocks received so far) ..."); } } @@ -168,7 +166,7 @@ protected TransactionReceipt waitForTx(byte[] txHash) throws InterruptedExceptio public static void main(String[] args) throws Exception { sLogger.info("Starting EthereumJ!"); - class Config extends TestNetConfig{ + class Config extends TestNetConfig { @Override @Bean public TestNetSample sampleBean() { diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java index 5bef418226..b0aa19cc7d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java @@ -17,11 +17,7 @@ */ package org.ethereum.samples; -import org.ethereum.core.Block; -import org.ethereum.core.CallTransaction; -import org.ethereum.core.PendingStateImpl; -import org.ethereum.core.Transaction; -import org.ethereum.core.TransactionReceipt; +import org.ethereum.core.*; import org.ethereum.crypto.ECKey; import org.ethereum.db.BlockStore; import org.ethereum.db.ByteArrayWrapper; @@ -29,9 +25,10 @@ import org.ethereum.facade.EthereumFactory; import org.ethereum.listener.BlockReplay; import org.ethereum.listener.EthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.listener.EventListener; import org.ethereum.listener.TxStatus; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.PendingTransactionUpdatedEvent; import org.ethereum.solidity.compiler.CompilationResult; import org.ethereum.solidity.compiler.SolidityCompiler; import org.ethereum.util.ByteUtil; @@ -49,11 +46,11 @@ import java.net.URL; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Scanner; import static org.ethereum.crypto.HashUtil.sha3; +import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.ByteUtil.toHexString; /** @@ -110,7 +107,7 @@ public class EventListenerSample extends TestNetSample { "} "; private Map txWaiters = - Collections.synchronizedMap(new HashMap()); + Collections.synchronizedMap(new HashMap<>()); class IncEvent { IncEvent(String address, Long inc, Long total) { @@ -205,16 +202,15 @@ protected boolean pendingTransactionUpdated(PendingEvent evt) { */ @Override public void onSyncDone() throws Exception { - ethereum.addListener(new EthereumListenerAdapter() { - @Override - public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionState state, Block block) { - ByteArrayWrapper txHashW = new ByteArrayWrapper(txReceipt.getTransaction().getHash()); - // Catching transaction errors - if (txWaiters.containsKey(txHashW) && !txReceipt.isSuccessful()) { - txWaiters.put(txHashW, txReceipt); - } + ethereum.subscribe(to(PendingTransactionUpdatedEvent.class, data -> { + TransactionReceipt txReceipt = data.getReceipt(); + ByteArrayWrapper txHashW = new ByteArrayWrapper(txReceipt.getTransaction().getHash()); + // Catching transaction errors + if (txWaiters.containsKey(txHashW) && !txReceipt.isSuccessful()) { + txWaiters.put(txHashW, txReceipt); } - }); + })); + requestFreeEther(ECKey.fromPrivate(senderPrivateKey).getAddress()); requestFreeEther(ECKey.fromPrivate(sender2PrivateKey).getAddress()); if (contractAddress == null) { @@ -287,13 +283,8 @@ private void waitForEther(byte[] address, BigInteger requiredBalance) throws Int * - Calls contract from 2 different addresses */ private void deployContractAndTest() throws Exception { - ethereum.addListener(new EthereumListenerAdapter() { - // when block arrives look for our included transactions - @Override - public void onBlock(Block block, List receipts) { - EventListenerSample.this.onBlock(block, receipts); - } - }); + // when block arrives look for our included transactions + ethereum.subscribe(to(BlockAddedEvent.class, this::onBlock)); CompilationResult.ContractMetadata metadata = compileContract(); @@ -390,8 +381,8 @@ protected TransactionReceipt sendTxAndWait(byte[] receiveAddress, return waitForTx(txHashW); } - private void onBlock(Block block, List receipts) { - for (TransactionReceipt receipt : receipts) { + private void onBlock(BlockSummary blockSummary) { + for (TransactionReceipt receipt : blockSummary.getReceipts()) { ByteArrayWrapper txHashW = new ByteArrayWrapper(receipt.getTransaction().getHash()); if (txWaiters.containsKey(txHashW)) { txWaiters.put(txHashW, receipt); diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java b/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java index 08c3ff9925..c24bc3396c 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java @@ -18,48 +18,37 @@ package org.ethereum.samples; import org.ethereum.core.Block; -import org.ethereum.core.TransactionReceipt; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; import org.ethereum.facade.Repository; -import org.ethereum.listener.EthereumListenerAdapter; +import org.ethereum.publish.event.BlockAddedEvent; import org.spongycastle.util.encoders.Hex; import java.math.BigInteger; -import java.util.List; -public class FollowAccount extends EthereumListenerAdapter { +import static org.ethereum.publish.Subscription.to; - - Ethereum ethereum = null; - - public FollowAccount(Ethereum ethereum) { - this.ethereum = ethereum; - } +public class FollowAccount { public static void main(String[] args) { - Ethereum ethereum = EthereumFactory.createEthereum(); - ethereum.addListener(new FollowAccount(ethereum)); - } - - @Override - public void onBlock(Block block, List receipts) { - - byte[] cow = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826"); + ethereum.subscribe(to(BlockAddedEvent.class, blockSummary -> { + byte[] cow = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826"); - // Get snapshot some time ago - 10% blocks ago - long bestNumber = ethereum.getBlockchain().getBestBlock().getNumber(); - long oldNumber = (long) (bestNumber * 0.9); + // Get snapshot some time ago - 10% blocks ago + long bestNumber = ethereum.getBlockchain().getBestBlock().getNumber(); + long oldNumber = (long) (bestNumber * 0.9); - Block oldBlock = ethereum.getBlockchain().getBlockByNumber(oldNumber); + Block oldBlock = ethereum.getBlockchain().getBlockByNumber(oldNumber); - Repository repository = ethereum.getRepository(); - Repository snapshot = ethereum.getSnapshotTo(oldBlock.getStateRoot()); + Repository repository = ethereum.getRepository(); + Repository snapshot = ethereum.getSnapshotTo(oldBlock.getStateRoot()); - BigInteger nonce_ = snapshot.getNonce(cow); - BigInteger nonce = repository.getNonce(cow); + BigInteger nonce_ = snapshot.getNonce(cow); + BigInteger nonce = repository.getNonce(cow); - System.err.println(" #" + block.getNumber() + " [cd2a3d9] => snapshot_nonce:" + nonce_ + " latest_nonce:" + nonce); + System.err.printf(" #%d [cd2a3d9] => snapshot_nonce:%d latest_nonce:%d\n", + blockSummary.getBlock().getNumber(), nonce_, nonce); + })); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java index 7ff7f6b3b2..18647abb3c 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java @@ -17,14 +17,12 @@ */ package org.ethereum.samples; -import org.ethereum.core.Block; -import org.ethereum.core.PendingState; -import org.ethereum.core.Transaction; -import org.ethereum.core.TransactionReceipt; +import org.ethereum.core.*; import org.ethereum.crypto.ECKey; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListenerAdapter; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.PendingTransactionsReceivedEvent; import org.ethereum.util.ByteUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -32,21 +30,22 @@ import java.math.BigInteger; import java.util.*; +import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.ByteUtil.toHexString; /** * PendingState is the ability to track the changes made by transaction immediately and not wait for * the block containing that transaction. - * + *

      * This sample connects to the test network (it has a lot of free Ethers) and starts periodically * transferring funds to a random address. The pending state is monitored and you may see that * while the actual receiver balance remains the same right after transaction sent the pending * state reflects balance change immediately. - * + *

      * While new blocks are arrived the sample monitors which of our transactions are included ot those blocks. * After each 5 transactions the sample stops sending transactions and waits for all transactions * are cleared (included to blocks) so the actual and pending receiver balances become equal. - * + *

      * Created by Anton Nashatyrev on 05.02.2016. */ public class PendingStateSample extends TestNetSample { @@ -64,21 +63,11 @@ public class PendingStateSample extends TestNetSample { @Override public void onSyncDone() { - ethereum.addListener(new EthereumListenerAdapter() { - // listening here when the PendingState is updated with new transactions - @Override - public void onPendingTransactionsReceived(List transactions) { - for (Transaction tx : transactions) { - PendingStateSample.this.onPendingTransactionReceived(tx); - } - } - - // when block arrives look for our included transactions - @Override - public void onBlock(Block block, List receipts) { - PendingStateSample.this.onBlock(block, receipts); - } - }); + this.ethereum + // listening here when the PendingState is updated with new transactions + .subscribe(to(PendingTransactionsReceivedEvent.class, txs -> txs.forEach(this::onPendingTransactionReceived))) + // when block arrives look for our included transactions + .subscribe(to(BlockAddedEvent.class, this::onBlock)); new Thread(() -> { try { @@ -100,7 +89,7 @@ void sendTransactions() throws InterruptedException { int weisToSend = 100; int count = 0; - while(true) { + while (true) { if (count < 5) { Transaction tx = new Transaction( ByteUtil.bigIntegerToBytes(nonce), @@ -129,9 +118,9 @@ void sendTransactions() throws InterruptedException { } /** - * The PendingState is updated with a new pending transactions. - * Prints the current receiver balance (based on blocks) and the pending balance - * which should immediately reflect receiver balance change + * The PendingState is updated with a new pending transactions. + * Prints the current receiver balance (based on blocks) and the pending balance + * which should immediately reflect receiver balance change */ void onPendingTransactionReceived(Transaction tx) { logger.info("onPendingTransactionReceived: " + tx); @@ -151,6 +140,10 @@ void onPendingTransactionReceived(Transaction tx) { * For each block we are looking for our transactions and clearing them * The actual receiver balance is confirmed upon block arrival */ + public void onBlock(BlockSummary blockSummary) { + onBlock(blockSummary.getBlock(), blockSummary.getReceipts()); + } + public void onBlock(Block block, List receipts) { int cleared = 0; for (Transaction tx : block.getTransactionsList()) { @@ -175,7 +168,7 @@ public void onBlock(Block block, List receipts) { public static void main(String[] args) throws Exception { sLogger.info("Starting EthereumJ!"); - class Config extends TestNetConfig{ + class Config extends TestNetConfig { @Override @Bean public TestNetSample sampleBean() { diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java b/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java index 0fd3d36258..fc30d53e42 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java @@ -17,12 +17,14 @@ */ package org.ethereum.samples; -import org.ethereum.core.*; +import org.ethereum.core.BlockSummary; +import org.ethereum.core.Transaction; +import org.ethereum.core.TransactionReceipt; import org.ethereum.crypto.ECKey; import org.ethereum.crypto.HashUtil; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListenerAdapter; +import org.ethereum.publish.event.BlockAddedEvent; import org.ethereum.util.ByteUtil; import org.ethereum.util.blockchain.EtherUtil; import org.spongycastle.util.encoders.Hex; @@ -31,13 +33,14 @@ import java.math.BigInteger; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; +import static org.ethereum.publish.Subscription.to; + /** * With this simple example you can send transaction from address to address in live public network * To make it work you just need to set sender's private key and receiver's address - * + *

      * Created by Alexander Samtsov on 12.08.16. */ public class SendTransaction extends BasicSample { @@ -47,23 +50,17 @@ public class SendTransaction extends BasicSample { @Override public void onSyncDone() throws Exception { - ethereum.addListener(new EthereumListenerAdapter() { - // when block arrives look for our included transactions - @Override - public void onBlock(Block block, List receipts) { - SendTransaction.this.onBlock(block, receipts); - } - }); - + // when block arrives look for our included transactions + this.ethereum.subscribe(to(BlockAddedEvent.class, this::onBlock)); String toAddress = ""; logger.info("Sending transaction to net and waiting for inclusion"); sendTxAndWait(Hex.decode(toAddress), new byte[0]); - logger.info("Transaction included!");} - + logger.info("Transaction included!"); + } - private void onBlock(Block block, List receipts) { - for (TransactionReceipt receipt : receipts) { + private void onBlock(BlockSummary blockSummary) { + for (TransactionReceipt receipt : blockSummary.getReceipts()) { ByteArrayWrapper txHashW = new ByteArrayWrapper(receipt.getTransaction().getHash()); if (txWaiters.containsKey(txHashW)) { txWaiters.put(txHashW, receipt); @@ -74,7 +71,6 @@ private void onBlock(Block block, List receipts) { } } - private TransactionReceipt sendTxAndWait(byte[] receiveAddress, byte[] data) throws InterruptedException { byte[] senderPrivateKey = HashUtil.sha3("cow".getBytes()); @@ -102,16 +98,16 @@ private TransactionReceipt waitForTx(byte[] txHash) throws InterruptedException txWaiters.put(txHashW, null); long startBlock = ethereum.getBlockchain().getBestBlock().getNumber(); - while(true) { + while (true) { TransactionReceipt receipt = txWaiters.get(txHashW); if (receipt != null) { return receipt; } else { long curBlock = ethereum.getBlockchain().getBestBlock().getNumber(); if (curBlock > startBlock + 16) { - throw new RuntimeException("The transaction was not included during last 16 blocks: " + txHashW.toString().substring(0,8)); + throw new RuntimeException("The transaction was not included during last 16 blocks: " + txHashW.toString().substring(0, 8)); } else { - logger.info("Waiting for block with transaction 0x" + txHashW.toString().substring(0,8) + + logger.info("Waiting for block with transaction 0x" + txHashW.toString().substring(0, 8) + " included (" + (curBlock - startBlock) + " blocks received so far) ..."); } diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java b/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java index 3a464a5ee2..406fd72c12 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java @@ -17,22 +17,23 @@ */ package org.ethereum.samples; -import org.ethereum.core.Block; +import org.ethereum.core.BlockSummary; import org.ethereum.core.Transaction; -import org.ethereum.core.TransactionReceipt; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListenerAdapter; +import org.ethereum.listener.EthereumListener; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.SyncDoneEvent; import org.spongycastle.util.encoders.Hex; import java.util.Collections; -import java.util.List; import static org.ethereum.crypto.HashUtil.sha3; +import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.ByteUtil.longToBytesNoLeadZeroes; import static org.ethereum.util.ByteUtil.toHexString; -public class TransactionBomb extends EthereumListenerAdapter { +public class TransactionBomb { Ethereum ethereum = null; @@ -40,18 +41,17 @@ public class TransactionBomb extends EthereumListenerAdapter { public TransactionBomb(Ethereum ethereum) { this.ethereum = ethereum; + this.ethereum + .subscribe(to(SyncDoneEvent.class, this::onSyncDone)) + .subscribe(to(BlockAddedEvent.class, this::onBlock)); } public static void main(String[] args) { - - Ethereum ethereum = EthereumFactory.createEthereum(); - ethereum.addListener(new TransactionBomb(ethereum)); + new TransactionBomb(EthereumFactory.createEthereum()); } - @Override - public void onSyncDone(SyncState state) { - + public void onSyncDone(EthereumListener.SyncState state) { // We will send transactions only // after we have the full chain syncs // - in order to prevent old nonce usage @@ -59,12 +59,11 @@ public void onSyncDone(SyncState state) { System.err.println(" ~~~ SYNC DONE ~~~ "); } - @Override - public void onBlock(Block block, List receipts) { + public void onBlock(BlockSummary blockSummary) { if (startedTxBomb){ byte[] sender = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826"); - long nonce = ethereum.getRepository().getNonce(sender).longValue();; + long nonce = ethereum.getRepository().getNonce(sender).longValue(); for (int i=0; i < 20; ++i){ sendTx(nonce); diff --git a/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java b/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java index ebed0b490d..9f9f0ce722 100644 --- a/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java +++ b/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java @@ -26,6 +26,8 @@ import org.ethereum.net.rlpx.discover.NodeManager; import org.ethereum.net.server.Channel; import org.ethereum.net.server.ChannelManager; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.PeerAddedToSyncPoolEvent; import org.ethereum.util.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -70,7 +72,7 @@ public class SyncPool { private BigInteger lowerUsefulDifficulty = BigInteger.ZERO; @Autowired - private EthereumListener ethereumListener; + private Publisher publisher; @Autowired private NodeManager nodeManager; @@ -339,7 +341,7 @@ private synchronized void prepareActive() { for (Channel channel : filtered) { if (!activePeers.contains(channel)) { - ethereumListener.onPeerAddedToSyncPool(channel); + publisher.publish(new PeerAddedToSyncPoolEvent(channel)); } } if (logger.isTraceEnabled()) diff --git a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java index fea748a494..8c09aaa691 100644 --- a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java @@ -33,6 +33,7 @@ import org.ethereum.listener.EthereumListener; import org.ethereum.mine.Ethash; import org.ethereum.publish.Publisher; +import org.ethereum.publish.Subscription; import org.ethereum.publish.event.BlockAddedEvent; import org.ethereum.publish.event.Event; import org.ethereum.solidity.compiler.CompilationResult; @@ -134,6 +135,8 @@ public StandaloneBlockchain() { withMinerCoinbase(Hex.decode("ffffffffffffffffffffffffffffffffffffffff")); setSender(ECKey.fromPrivate(Hex.decode("3ec771c31cac8c0dba77a69e503765701d3c2bb62435888d4ffa38fed60c445c"))); // withAccountBalance(txSender.getAddress(), new BigInteger("100000000000000000000000000")); + + publisher = new Publisher(EventDispatchThread.getDefault()); } public StandaloneBlockchain withGenesis(Genesis genesis) { @@ -450,6 +453,11 @@ public void addEthereumListener(EthereumListener listener) { publisher.subscribeListener(listener); } + public , P> StandaloneBlockchain subscribe(Subscription subscription) { + publisher.subscribe(subscription); + return this; + } + public , P> StandaloneBlockchain subscribe(Class eventType, Consumer

      handler) { publisher.subscribe(eventType, handler); return this; @@ -489,7 +497,6 @@ private BlockchainImpl createBlockchain(Genesis genesis) { final RepositoryRoot repository = new RepositoryRoot(pruningStateDS); ProgramInvokeFactoryImpl programInvokeFactory = new ProgramInvokeFactoryImpl(); - publisher = new Publisher(EventDispatchThread.getDefault()); BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository, publisher) .withSyncManager(new SyncManager()); diff --git a/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java b/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java index 911be149aa..94be8ffd5a 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java @@ -19,13 +19,15 @@ import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListenerAdapter; +import org.ethereum.publish.event.BlockAddedEvent; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; -import java.util.List; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.ethereum.publish.Subscription.to; /** * Created by Anton Nashatyrev on 24.06.2016. @@ -41,14 +43,13 @@ public void relaunchTest() throws InterruptedException { Block bestBlock = ethereum.getBlockchain().getBestBlock(); Assert.assertNotNull(bestBlock); final CountDownLatch latch = new CountDownLatch(1); - ethereum.addListener(new EthereumListenerAdapter() { - int counter = 0; - @Override - public void onBlock(Block block, List receipts) { - counter++; - if (counter > 1100) latch.countDown(); + AtomicInteger counter = new AtomicInteger(); + ethereum.subscribe(to(BlockAddedEvent.class, blockSummary -> { + if (counter.addAndGet(1) > 1100) { + latch.countDown(); } - }); + })); + System.out.println("### Waiting for some blocks to be imported..."); latch.await(); System.out.println("### Closing Ethereum instance"); diff --git a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java index 858a7eac5c..e785862194 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java @@ -20,15 +20,18 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Triple; import org.ethereum.config.SystemProperties; -import org.ethereum.config.blockchain.FrontierConfig; -import org.ethereum.config.net.MainNetConfig; import org.ethereum.crypto.ECKey; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.listener.EthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.PendingStateChangedEvent; +import org.ethereum.publish.event.PendingTransactionUpdatedEvent; import org.ethereum.util.blockchain.SolidityContract; import org.ethereum.util.blockchain.StandaloneBlockchain; -import org.junit.*; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; import java.math.BigInteger; import java.util.HashMap; @@ -42,6 +45,7 @@ import static java.util.concurrent.TimeUnit.SECONDS; import static org.ethereum.listener.EthereumListener.PendingTransactionState.*; +import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.blockchain.EtherUtil.Unit.ETHER; import static org.ethereum.util.blockchain.EtherUtil.convert; @@ -61,35 +65,38 @@ public static void cleanup() { SystemProperties.resetToDefault(); } - static class PendingListener extends EthereumListenerAdapter { + static class PendingListener { public BlockingQueue>> onBlock = new LinkedBlockingQueue<>(); public BlockingQueue onPendingStateChanged = new LinkedBlockingQueue<>(); // public BlockingQueue> onPendingTransactionUpdate = new LinkedBlockingQueue<>(); - Map>> + Map>> onPendingTransactionUpdate = new HashMap<>(); - @Override - public void onBlock(Block block, List receipts) { + public void onBlock(BlockSummary blockSummary) { + Block block = blockSummary.getBlock(); System.out.println("PendingStateTest.onBlock:" + "block = [" + block.getShortDescr() + "]"); - onBlock.add(Pair.of(block, receipts)); + onBlock.add(Pair.of(block, blockSummary.getReceipts())); } - @Override public void onPendingStateChanged(PendingState pendingState) { System.out.println("PendingStateTest.onPendingStateChanged."); onPendingStateChanged.add(new Object()); } - @Override - public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionState state, Block block) { + public void onPendingTransactionUpdate(PendingTransactionUpdatedEvent.Data data) { + onPendingTransactionUpdate(data.getReceipt(), data.getState(), data.getBlock()); + } + + + public void onPendingTransactionUpdate(TransactionReceipt txReceipt, EthereumListener.PendingTransactionState state, Block block) { System.out.println("PendingStateTest.onPendingTransactionUpdate:" + "txReceipt.err = [" + txReceipt.getError() + "], state = [" + state + "], block: " + block.getShortDescr()); getQueueFor(txReceipt.getTransaction()).add(Triple.of(txReceipt, state, block)); } - public synchronized BlockingQueue> getQueueFor(Transaction tx) { + public synchronized BlockingQueue> getQueueFor(Transaction tx) { ByteArrayWrapper hashW = new ByteArrayWrapper(tx.getHash()); - BlockingQueue> queue = onPendingTransactionUpdate.get(hashW); + BlockingQueue> queue = onPendingTransactionUpdate.get(hashW); if (queue == null) { queue = new LinkedBlockingQueue<>(); onPendingTransactionUpdate.put(hashW, queue); @@ -97,19 +104,23 @@ public synchronized BlockingQueue pollTxUpdate(Transaction tx) throws InterruptedException { + + public Triple pollTxUpdate(Transaction tx) throws InterruptedException { return getQueueFor(tx).poll(5, SECONDS); } } @Test public void testSimple() throws InterruptedException { - StandaloneBlockchain bc = new StandaloneBlockchain(); PendingListener l = new PendingListener(); - bc.addEthereumListener(l); + StandaloneBlockchain bc = new StandaloneBlockchain() + .subscribe(to(BlockAddedEvent.class, l::onBlock)) + .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + Triple txUpd; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -179,9 +190,12 @@ public void testSimple() throws InterruptedException { @Test public void testRebranch1() throws InterruptedException { - StandaloneBlockchain bc = new StandaloneBlockchain(); PendingListener l = new PendingListener(); - bc.addEthereumListener(l); + StandaloneBlockchain bc = new StandaloneBlockchain() + .subscribe(to(BlockAddedEvent.class, l::onBlock)) + .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -196,7 +210,8 @@ public void testRebranch1() throws InterruptedException { Transaction tx1 = bc.createTransaction(bob, 0, alice.getAddress(), BigInteger.valueOf(1000000), new byte[0]); pendingState.addPendingTransaction(tx1); - Transaction tx2 = bc.createTransaction(charlie, 0, alice.getAddress(), BigInteger.valueOf(1000000), new byte[0]);; + Transaction tx2 = bc.createTransaction(charlie, 0, alice.getAddress(), BigInteger.valueOf(1000000), new byte[0]); + ; pendingState.addPendingTransaction(tx2); Assert.assertEquals(l.pollTxUpdateState(tx1), NEW_PENDING); @@ -244,9 +259,12 @@ public void testRebranch1() throws InterruptedException { @Test public void testRebranch2() throws InterruptedException { - StandaloneBlockchain bc = new StandaloneBlockchain(); PendingListener l = new PendingListener(); - bc.addEthereumListener(l); + StandaloneBlockchain bc = new StandaloneBlockchain() + .subscribe(to(BlockAddedEvent.class, l::onBlock)) + .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -261,7 +279,8 @@ public void testRebranch2() throws InterruptedException { Transaction tx1 = bc.createTransaction(bob, 0, alice.getAddress(), BigInteger.valueOf(1000000), new byte[0]); pendingState.addPendingTransaction(tx1); - Transaction tx2 = bc.createTransaction(charlie, 0, alice.getAddress(), BigInteger.valueOf(1000000), new byte[0]);; + Transaction tx2 = bc.createTransaction(charlie, 0, alice.getAddress(), BigInteger.valueOf(1000000), new byte[0]); + ; pendingState.addPendingTransaction(tx2); Assert.assertEquals(l.pollTxUpdateState(tx1), NEW_PENDING); @@ -330,9 +349,12 @@ public void testRebranch2() throws InterruptedException { @Test public void testRebranch3() throws InterruptedException { - StandaloneBlockchain bc = new StandaloneBlockchain(); PendingListener l = new PendingListener(); - bc.addEthereumListener(l); + StandaloneBlockchain bc = new StandaloneBlockchain() + .subscribe(to(BlockAddedEvent.class, l::onBlock)) + .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -379,9 +401,12 @@ public void testRebranch3() throws InterruptedException { @Test public void testOldBlockIncluded() throws InterruptedException { - StandaloneBlockchain bc = new StandaloneBlockchain(); PendingListener l = new PendingListener(); - bc.addEthereumListener(l); + StandaloneBlockchain bc = new StandaloneBlockchain() + .subscribe(to(BlockAddedEvent.class, l::onBlock)) + .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -414,9 +439,12 @@ public void testOldBlockIncluded() throws InterruptedException { @Test public void testBlockOnlyIncluded() throws InterruptedException { - StandaloneBlockchain bc = new StandaloneBlockchain(); PendingListener l = new PendingListener(); - bc.addEthereumListener(l); + StandaloneBlockchain bc = new StandaloneBlockchain() + .subscribe(to(BlockAddedEvent.class, l::onBlock)) + .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -440,9 +468,12 @@ public void testBlockOnlyIncluded() throws InterruptedException { @Test public void testTrackTx1() throws InterruptedException { - StandaloneBlockchain bc = new StandaloneBlockchain(); PendingListener l = new PendingListener(); - bc.addEthereumListener(l); + StandaloneBlockchain bc = new StandaloneBlockchain() + .subscribe(to(BlockAddedEvent.class, l::onBlock)) + .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -492,7 +523,11 @@ public void testPrevBlock() throws InterruptedException { Block b3 = bc.createBlock(); PendingListener l = new PendingListener(); - bc.addEthereumListener(l); + bc + .subscribe(to(BlockAddedEvent.class, l::onBlock)) + .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + Triple txUpd; contract.callFunction("getPrevBlockHash"); @@ -504,9 +539,12 @@ public void testPrevBlock() throws InterruptedException { @Test public void testTrackTx2() throws InterruptedException { - StandaloneBlockchain bc = new StandaloneBlockchain(); PendingListener l = new PendingListener(); - bc.addEthereumListener(l); + StandaloneBlockchain bc = new StandaloneBlockchain() + .subscribe(to(BlockAddedEvent.class, l::onBlock)) + .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -534,9 +572,12 @@ public void testTrackTx2() throws InterruptedException { @Test public void testRejected1() throws InterruptedException { - StandaloneBlockchain bc = new StandaloneBlockchain(); PendingListener l = new PendingListener(); - bc.addEthereumListener(l); + StandaloneBlockchain bc = new StandaloneBlockchain() + .subscribe(to(BlockAddedEvent.class, l::onBlock)) + .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -580,9 +621,12 @@ public void testRejected1() throws InterruptedException { public void testIncludedRejected() throws InterruptedException { // check INCLUDED => DROPPED state transition when a new (long) fork without // the transaction becomes the main chain - StandaloneBlockchain bc = new StandaloneBlockchain(); PendingListener l = new PendingListener(); - bc.addEthereumListener(l); + StandaloneBlockchain bc = new StandaloneBlockchain() + .subscribe(to(BlockAddedEvent.class, l::onBlock)) + .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -621,18 +665,22 @@ public void testIncludedRejected() throws InterruptedException { @Test public void testInvalidTransaction() throws InterruptedException { - StandaloneBlockchain bc = new StandaloneBlockchain(); final CountDownLatch txHandle = new CountDownLatch(1); PendingListener l = new PendingListener() { @Override - public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionState state, Block block) { + public void onPendingTransactionUpdate(TransactionReceipt txReceipt, EthereumListener.PendingTransactionState state, Block block) { assert !txReceipt.isSuccessful(); assert txReceipt.getError().toLowerCase().contains("invalid"); assert txReceipt.getError().toLowerCase().contains("receive address"); txHandle.countDown(); } }; - bc.addEthereumListener(l); + + StandaloneBlockchain bc = new StandaloneBlockchain() + .subscribe(to(BlockAddedEvent.class, l::onBlock)) + .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); diff --git a/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java b/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java index f0939da845..5c65f937c6 100644 --- a/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java +++ b/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java @@ -20,15 +20,18 @@ import org.ethereum.config.CommonConfig; import org.ethereum.config.SystemProperties; import org.ethereum.core.Block; -import org.ethereum.core.TransactionReceipt; +import org.ethereum.core.BlockSummary; import org.ethereum.db.DbFlushManager; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; import org.ethereum.listener.EthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.rlpx.Node; import org.ethereum.net.server.Channel; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.PeerAddedToSyncPoolEvent; +import org.ethereum.publish.event.SyncDoneEvent; +import org.ethereum.publish.event.message.EthStatusUpdatedEvent; import org.ethereum.sync.SyncPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,6 +45,7 @@ import java.util.Vector; import static java.lang.Thread.sleep; +import static org.ethereum.publish.Subscription.to; /** * BasicNode of ethereum instance @@ -103,7 +107,11 @@ public BasicNode(String loggerName) { private void springInit() { logger = LoggerFactory.getLogger(loggerName); // adding the main EthereumJ callback to be notified on different kind of events - ethereum.addListener(listener); + this.ethereum + .subscribe(to(SyncDoneEvent.class, this::onSyncDone)) + .subscribe(to(BlockAddedEvent.class, this::onBlock)) + .subscribe(to(EthStatusUpdatedEvent.class, this::onEthStatusUpdated)) + .subscribe(to(PeerAddedToSyncPoolEvent.class, this::onPeerAddedToSyncPool)); logger.info("Sample component created. Listening for ethereum events..."); @@ -170,31 +178,26 @@ public void onSyncDoneImpl(EthereumListener.SyncState state) { /** * The main EthereumJ callback. */ - EthereumListener listener = new EthereumListenerAdapter() { - @Override - public void onSyncDone(SyncState state) { - syncState = state; - if (state.equals(SyncState.COMPLETE)) syncComplete = true; - onSyncDoneImpl(state); - } + public void onSyncDone(EthereumListener.SyncState state) { + syncState = state; + if (state.equals(EthereumListener.SyncState.COMPLETE)) syncComplete = true; + onSyncDoneImpl(state); + } - @Override - public void onEthStatusUpdated(Channel channel, StatusMessage statusMessage) { - ethNodes.put(channel.getNode(), statusMessage); - } + public void onEthStatusUpdated(EthStatusUpdatedEvent.Data data) { + ethNodes.put(data.getChannel().getNode(), data.getMessage()); + } - @Override - public void onPeerAddedToSyncPool(Channel peer) { - syncPeers.add(peer.getNode()); - } + public void onPeerAddedToSyncPool(Channel peer) { + syncPeers.add(peer.getNode()); + } - @Override - public void onBlock(Block block, List receipts) { - bestBlock = block; + public void onBlock(BlockSummary blockSummary) { + Block block = blockSummary.getBlock(); + bestBlock = block; - if (syncComplete) { - logger.info("New block: " + block.getShortDescr()); - } + if (syncComplete) { + logger.info("New block: " + block.getShortDescr()); } - }; + } } diff --git a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java index 79836d294b..74e349d391 100644 --- a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java @@ -25,9 +25,9 @@ import org.ethereum.db.ContractDetails; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.PendingTransactionsReceivedEvent; import org.ethereum.sync.SyncManager; import org.ethereum.util.FastByteComparisons; import org.ethereum.vm.program.invoke.ProgramInvokeFactory; @@ -49,6 +49,7 @@ import java.util.concurrent.atomic.AtomicLong; import static java.lang.Thread.sleep; +import static org.ethereum.publish.Subscription.to; /** * Regular sync with load @@ -157,67 +158,60 @@ static class RegularNode extends BasicNode { /** * The main EthereumJ callback. */ - EthereumListener blockListener = new EthereumListenerAdapter() { - @Override - public void onBlock(BlockSummary blockSummary) { - lastImport.set(System.currentTimeMillis()); - } - - @Override - public void onBlock(Block block, List receipts) { - for (TransactionReceipt receipt : receipts) { - // Getting contract details - byte[] contractAddress = receipt.getTransaction().getContractAddress(); - if (contractAddress != null) { - ContractDetails details = ((Repository) ethereum.getRepository()).getContractDetails(contractAddress); - assert FastByteComparisons.equal(details.getAddress(), contractAddress); - } - - // Getting AccountState for sender in the past - Random rnd = new Random(); - Block bestBlock = ethereum.getBlockchain().getBestBlock(); - Block randomBlock = ethereum.getBlockchain().getBlockByNumber(rnd.nextInt((int) bestBlock.getNumber())); - byte[] sender = receipt.getTransaction().getSender(); - AccountState senderState = ((Repository) ethereum.getRepository()).getSnapshotTo(randomBlock.getStateRoot()).getAccountState(sender); - if (senderState != null) senderState.getBalance(); - - // Getting receiver's nonce somewhere in the past - Block anotherRandomBlock = ethereum.getBlockchain().getBlockByNumber(rnd.nextInt((int) bestBlock.getNumber())); - byte[] receiver = receipt.getTransaction().getReceiveAddress(); - if (receiver != null) { - ((Repository) ethereum.getRepository()).getSnapshotTo(anotherRandomBlock.getStateRoot()).getNonce(receiver); - } + public void onBlock(BlockSummary blockSummary) { + lastImport.set(System.currentTimeMillis()); + + for (TransactionReceipt receipt : blockSummary.getReceipts()) { + // Getting contract details + byte[] contractAddress = receipt.getTransaction().getContractAddress(); + if (contractAddress != null) { + ContractDetails details = ((Repository) ethereum.getRepository()).getContractDetails(contractAddress); + assert FastByteComparisons.equal(details.getAddress(), contractAddress); } - } - @Override - public void onPendingTransactionsReceived(List transactions) { + // Getting AccountState for sender in the past Random rnd = new Random(); Block bestBlock = ethereum.getBlockchain().getBestBlock(); - for (Transaction tx : transactions) { - Block block = ethereum.getBlockchain().getBlockByNumber(rnd.nextInt((int) bestBlock.getNumber())); - Repository repository = ((Repository) ethereum.getRepository()) - .getSnapshotTo(block.getStateRoot()) - .startTracking(); - try { - TransactionExecutor executor = new TransactionExecutor - (tx, block.getCoinbase(), repository, ethereum.getBlockchain().getBlockStore(), - programInvokeFactory, block, new Publisher(EventDispatchThread.getDefault()), 0) - .withCommonConfig(commonConfig) - .setLocalCall(true); - - executor.init(); - executor.execute(); - executor.go(); - executor.finalization(); - - executor.getReceipt(); - } finally { - repository.rollback(); - } + Block randomBlock = ethereum.getBlockchain().getBlockByNumber(rnd.nextInt((int) bestBlock.getNumber())); + byte[] sender = receipt.getTransaction().getSender(); + AccountState senderState = ((Repository) ethereum.getRepository()).getSnapshotTo(randomBlock.getStateRoot()).getAccountState(sender); + if (senderState != null) senderState.getBalance(); + + // Getting receiver's nonce somewhere in the past + Block anotherRandomBlock = ethereum.getBlockchain().getBlockByNumber(rnd.nextInt((int) bestBlock.getNumber())); + byte[] receiver = receipt.getTransaction().getReceiveAddress(); + if (receiver != null) { + ((Repository) ethereum.getRepository()).getSnapshotTo(anotherRandomBlock.getStateRoot()).getNonce(receiver); + } + } + } + + public void onPendingTransactionsReceived(List transactions) { + Random rnd = new Random(); + Block bestBlock = ethereum.getBlockchain().getBestBlock(); + for (Transaction tx : transactions) { + Block block = ethereum.getBlockchain().getBlockByNumber(rnd.nextInt((int) bestBlock.getNumber())); + Repository repository = ((Repository) ethereum.getRepository()) + .getSnapshotTo(block.getStateRoot()) + .startTracking(); + try { + TransactionExecutor executor = new TransactionExecutor + (tx, block.getCoinbase(), repository, ethereum.getBlockchain().getBlockStore(), + programInvokeFactory, block, new Publisher(EventDispatchThread.getDefault()), 0) + .withCommonConfig(commonConfig) + .setLocalCall(true); + + executor.init(); + executor.execute(); + executor.go(); + executor.finalization(); + + executor.getReceipt(); + } finally { + repository.rollback(); } } - }; + } public RegularNode() { super("sampleNode"); @@ -226,7 +220,9 @@ public RegularNode() { @Override public void run() { try { - ethereum.addListener(blockListener); + this.ethereum + .subscribe(to(BlockAddedEvent.class, this::onBlock)) + .subscribe(to(PendingTransactionsReceivedEvent.class, this::onPendingTransactionsReceived)); // Run 1-30 minutes Random generator = new Random(); diff --git a/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java b/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java index f3f9b1a85d..2ea492d938 100644 --- a/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java @@ -21,14 +21,18 @@ import org.apache.commons.lang3.tuple.Pair; import org.ethereum.config.NoAutoscan; import org.ethereum.config.SystemProperties; -import org.ethereum.core.*; +import org.ethereum.core.Block; +import org.ethereum.core.BlockHeader; +import org.ethereum.core.Transaction; import org.ethereum.crypto.ECKey; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.net.eth.handler.Eth62; -import org.ethereum.net.eth.message.*; +import org.ethereum.net.eth.message.NewBlockMessage; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.PendingTransactionsReceivedEvent; +import org.ethereum.publish.event.SyncDoneEvent; import org.ethereum.util.ByteUtil; import org.junit.BeforeClass; import org.junit.Ignore; @@ -38,10 +42,14 @@ import org.springframework.context.annotation.Configuration; import java.io.FileNotFoundException; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import static org.ethereum.publish.Subscription.to; + /** * Long running test * @@ -99,13 +107,12 @@ public void startMiningConsumer() throws Exception { Ethereum ethereum2 = EthereumFactory.createEthereum(SysPropConfig2.props, SysPropConfig2.class); final CountDownLatch semaphore = new CountDownLatch(1); - ethereum2.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - System.err.println("=== New block: " + blockInfo(block)); - System.err.println(block); + ethereum2.subscribe(to(BlockAddedEvent.class, blockSummary -> { + Block block = blockSummary.getBlock(); + System.err.println("=== New block: " + blockInfo(block)); + System.err.println(block); - for (Transaction tx : block.getTransactionsList()) { + for (Transaction tx : block.getTransactionsList()) { // Pair remove = submittedTxs.remove(new ByteArrayWrapper(tx.getHash())); // if (remove == null) { // System.err.println("===== !!! Unknown Tx: " + tx); @@ -114,7 +121,7 @@ public void onBlock(Block block, List receipts) { // + " sec: " + tx); // } - } + } // for (Pair pair : submittedTxs.values()) { // if (System.currentTimeMillis() - pair.getRight() > 60 * 1000) { @@ -122,19 +129,13 @@ public void onBlock(Block block, List receipts) { // + " sec: " + pair.getLeft()); // } // } - } - @Override - public void onPendingTransactionsReceived(List transactions) { - System.err.println("=== Tx: " + transactions); - } - - @Override - public void onSyncDone(SyncState state) { - semaphore.countDown(); - System.err.println("=== Sync Done!"); - } - }); + })) + .subscribe(to(PendingTransactionsReceivedEvent.class, transactions -> System.err.println("=== Tx: " + transactions))) + .subscribe(to(SyncDoneEvent.class, syncState -> { + semaphore.countDown(); + System.err.println("=== Sync Done!"); + })); System.out.println("Waiting for sync..."); semaphore.await(); @@ -203,17 +204,9 @@ public void startMiningTest() throws FileNotFoundException, InterruptedException // Ethereum ethereum2 = EthereumFactory.createEthereum(SysPropConfig2.props, SysPropConfig2.class); final CountDownLatch semaphore = new CountDownLatch(1); - ethereum1.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - System.out.println("=== New block: " + blockInfo(block)); - } - - @Override - public void onSyncDone(SyncState state) { - semaphore.countDown(); - } - }); + ethereum1 + .subscribe(to(BlockAddedEvent.class, blockSummary -> System.out.println("=== New block: " + blockInfo(blockSummary.getBlock())))) + .subscribe(to(SyncDoneEvent.class, syncState -> semaphore.countDown())); // ethereum2.addListener(new EthereumListenerAdapter() { // @Override diff --git a/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java b/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java index d473cb12f9..b323eafc9d 100644 --- a/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java @@ -20,43 +20,32 @@ import org.ethereum.config.NoAutoscan; import org.ethereum.config.SystemProperties; import org.ethereum.config.net.MainNetConfig; -import org.ethereum.core.Block; -import org.ethereum.core.BlockSummary; -import org.ethereum.core.Blockchain; -import org.ethereum.core.ImportResult; -import org.ethereum.core.Transaction; +import org.ethereum.core.*; import org.ethereum.crypto.ECKey; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; import org.ethereum.facade.EthereumImpl; import org.ethereum.facade.SyncStatus; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.net.eth.handler.Eth62; import org.ethereum.net.rlpx.Node; -import org.ethereum.net.server.Channel; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.PeerAddedToSyncPoolEvent; import org.ethereum.util.FastByteComparisons; import org.ethereum.util.blockchain.EtherUtil; import org.ethereum.util.blockchain.StandaloneBlockchain; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.*; import org.spongycastle.util.encoders.Hex; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; -import java.io.File; import java.io.IOException; import java.math.BigInteger; import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.util.ArrayList; +import java.nio.file.Paths; import java.util.List; import java.util.Random; import java.util.concurrent.CountDownLatch; @@ -65,13 +54,11 @@ import java.util.concurrent.TimeoutException; import static java.util.concurrent.TimeUnit.SECONDS; +import static java.util.stream.Collectors.toList; import static org.ethereum.crypto.HashUtil.sha3; +import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.FileUtil.recursiveDelete; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.spongycastle.util.encoders.Hex.decode; +import static org.junit.Assert.*; /** @@ -81,7 +68,7 @@ * While automatic detection of long sync works correctly in any live network * with big number of peers, automatic detection of Short Sync condition in * detached or small private networks looks not doable. - * + *

      * To resolve this and any other similar issues manual switch to Short Sync mode * was added: {@link EthereumImpl#switchToShortSync()} * This test verifies that manual switching to Short Sync works correctly @@ -124,17 +111,11 @@ public static void setup() throws IOException, URISyntaxException { } private static List loadBlocks(String path) throws URISyntaxException, IOException { - URL url = ClassLoader.getSystemResource(path); - File file = new File(url.toURI()); - List strData = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8); - - List blocks = new ArrayList<>(strData.size()); - for (String rlp : strData) { - blocks.add(new Block(decode(rlp))); - } - - return blocks; + return Files.lines(Paths.get(url.toURI()), StandardCharsets.UTF_8) + .map(Hex::decode) + .map(Block::new) + .collect(toList()); } @AfterClass @@ -143,7 +124,7 @@ public static void cleanup() { } @Before - public void setupTest() throws InterruptedException { + public void setupTest() { testDbA = "test_db_" + new BigInteger(32, new Random()); testDbB = "test_db_" + new BigInteger(32, new Random()); @@ -179,38 +160,27 @@ public void test1() throws InterruptedException { // Check that we are synced and on the same block assertTrue(loadedBlocks > 0); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(BlockSummary blockSummary) { - if (blockSummary.getBlock().getNumber() == loadedBlocks) { - semaphore.countDown(); - } - } - }); + + ethereumB.subscribe(to(BlockAddedEvent.class, bs -> semaphore.countDown()) + .conditionally(bs -> isBlockNumber(bs, loadedBlocks))); + semaphore.await(MAX_SECONDS_WAIT, SECONDS); - Assert.assertEquals(0, semaphore.getCount()); + assertEquals(0, semaphore.getCount()); assertEquals(loadedBlocks, ethereumB.getBlockchain().getBestBlock().getNumber()); ethereumA.getBlockMiner().startMining(); final CountDownLatch semaphore2 = new CountDownLatch(2); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(BlockSummary blockSummary) { - if (blockSummary.getBlock().getNumber() == loadedBlocks + 2) { - semaphore2.countDown(); - ethereumA.getBlockMiner().stopMining(); - } - } - }); - ethereumA.addListener(new EthereumListenerAdapter(){ - @Override - public void onBlock(BlockSummary blockSummary) { - if (blockSummary.getBlock().getNumber() == loadedBlocks + 2) { - semaphore2.countDown(); - } + ethereumB.subscribe(to(BlockAddedEvent.class, bs -> { + if (isBlockNumber(bs, loadedBlocks + 2)) { + semaphore2.countDown(); + ethereumA.getBlockMiner().stopMining(); } - }); + })); + + ethereumA.subscribe(to(BlockAddedEvent.class, bs -> semaphore2.countDown()) + .conditionally(bs -> isBlockNumber(bs, loadedBlocks + 2))); + semaphore2.await(MAX_SECONDS_WAIT, SECONDS); Assert.assertEquals(0, semaphore2.getCount()); @@ -230,36 +200,27 @@ public void onBlock(BlockSummary blockSummary) { ); tx.sign(sender); final CountDownLatch txSemaphore = new CountDownLatch(1); - ethereumA.addListener(new EthereumListenerAdapter(){ - @Override - public void onBlock(BlockSummary blockSummary) { - if (!blockSummary.getBlock().getTransactionsList().isEmpty() && - FastByteComparisons.equal(blockSummary.getBlock().getTransactionsList().get(0).getSender(), sender.getAddress()) && - blockSummary.getReceipts().get(0).isSuccessful()) { - txSemaphore.countDown(); - } + ethereumA.subscribe(to(BlockAddedEvent.class, blockSummary -> { + + if (!blockSummary.getBlock().getTransactionsList().isEmpty() && + FastByteComparisons.equal(blockSummary.getBlock().getTransactionsList().get(0).getSender(), sender.getAddress()) && + blockSummary.getReceipts().get(0).isSuccessful()) { + txSemaphore.countDown(); } - }); + })); + ethereumB.submitTransaction(tx); final CountDownLatch semaphore3 = new CountDownLatch(2); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(BlockSummary blockSummary) { - if (blockSummary.getBlock().getNumber() == loadedBlocks + 5) { - semaphore3.countDown(); - } - } - }); - ethereumA.addListener(new EthereumListenerAdapter(){ - @Override - public void onBlock(BlockSummary blockSummary) { - if (blockSummary.getBlock().getNumber() == loadedBlocks + 5) { - semaphore3.countDown(); - ethereumA.getBlockMiner().stopMining(); - } + ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> semaphore3.countDown()) + .conditionally(bs -> isBlockNumber(bs, loadedBlocks + 5))); + + ethereumA.subscribe(to(BlockAddedEvent.class, blockSummary -> { + if (isBlockNumber(blockSummary, loadedBlocks + 5)) { + semaphore3.countDown(); + ethereumA.getBlockMiner().stopMining(); } - }); + })); ethereumA.getBlockMiner().startMining(); semaphore3.await(MAX_SECONDS_WAIT, SECONDS); @@ -290,30 +251,24 @@ public void onBlock(BlockSummary blockSummary) { ethereumB.submitTransaction(tx2); final CountDownLatch semaphore4 = new CountDownLatch(2); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(BlockSummary blockSummary) { - if (blockSummary.getBlock().getNumber() == loadedBlocks + 9) { - semaphore4.countDown(); - ethereumA.getBlockMiner().stopMining(); - } - } - }); - ethereumA.addListener(new EthereumListenerAdapter(){ - @Override - public void onBlock(BlockSummary blockSummary) { - if (blockSummary.getBlock().getNumber() == loadedBlocks + 9) { - semaphore4.countDown(); - } + + ethereumB.subscribe(to(BlockAddedEvent.class, bs -> { + if (isBlockNumber(bs, loadedBlocks + 9)) { + semaphore4.countDown(); + ethereumA.getBlockMiner().stopMining(); } - }); + })); + + ethereumA.subscribe(to(BlockAddedEvent.class, blockSummary -> semaphore4.countDown()) + .conditionally(bs -> isBlockNumber(bs, loadedBlocks + 9))); semaphore4.await(MAX_SECONDS_WAIT, SECONDS); - Assert.assertEquals(0, semaphore4.getCount()); - Assert.assertEquals(loadedBlocks + 9, ethereumA.getBlockchain().getBestBlock().getNumber()); - Assert.assertEquals(loadedBlocks + 9, ethereumB.getBlockchain().getBestBlock().getNumber()); - assertTrue(ethereumA.getSyncStatus().getStage().equals(SyncStatus.SyncStage.Complete)); - assertTrue(ethereumB.getSyncStatus().getStage().equals(SyncStatus.SyncStage.Complete)); + + assertEquals(0, semaphore4.getCount()); + assertEquals(loadedBlocks + 9, ethereumA.getBlockchain().getBestBlock().getNumber()); + assertEquals(loadedBlocks + 9, ethereumB.getBlockchain().getBestBlock().getNumber()); + assertEquals(SyncStatus.SyncStage.Complete, ethereumA.getSyncStatus().getStage()); + assertEquals(SyncStatus.SyncStage.Complete, ethereumB.getSyncStatus().getStage()); // Tx is included! assertTrue(txSemaphore.getCount() == 0); } @@ -325,21 +280,20 @@ private void setupPeers() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onPeerAddedToSyncPool(Channel peer) { - semaphore.countDown(); - } - }); + ethereumB.subscribe(to(PeerAddedToSyncPoolEvent.class, channel -> semaphore.countDown())); ethereumB.connect(nodeA); semaphore.await(10, SECONDS); - if(semaphore.getCount() > 0) { + if (semaphore.getCount() > 0) { fail("Failed to set up peers"); } } + private static boolean isBlockNumber(BlockSummary blockSummary, long number) { + return blockSummary.getBlock().getNumber() == number; + } + @Configuration @NoAutoscan public static class SysPropConfigA { @@ -354,7 +308,7 @@ public SystemProperties systemProperties() { @Bean @Scope("prototype") - public Eth62 eth62() throws IllegalAccessException, InstantiationException { + public Eth62 eth62() { if (eth62 != null) return eth62; return new Eth62(); } diff --git a/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java b/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java index 5ebc95ec98..93373c4474 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java @@ -24,11 +24,15 @@ import org.ethereum.crypto.ECKey; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.mine.Ethash; import org.ethereum.net.eth.handler.Eth62; -import org.ethereum.net.eth.message.*; +import org.ethereum.net.eth.message.BlockBodiesMessage; +import org.ethereum.net.eth.message.BlockHeadersMessage; +import org.ethereum.net.eth.message.GetBlockBodiesMessage; +import org.ethereum.net.eth.message.GetBlockHeadersMessage; import org.ethereum.net.server.Channel; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.message.EthStatusUpdatedEvent; import org.ethereum.util.RLP; import org.junit.Ignore; import org.junit.Test; @@ -48,6 +52,7 @@ import static java.lang.Math.max; import static java.lang.Math.min; import static org.ethereum.crypto.HashUtil.sha3; +import static org.ethereum.publish.Subscription.to; /** * Created by Anton Nashatyrev on 13.10.2015. @@ -221,22 +226,17 @@ protected void processGetBlockBodies(GetBlockBodiesMessage msg) { final CountDownLatch semaphore = new CountDownLatch(1); final Channel[] channel1 = new Channel[1]; - ethereum1.addListener(new EthereumListenerAdapter() { - @Override - public void onEthStatusUpdated(Channel channel, StatusMessage statusMessage) { - channel1[0] = channel; - System.out.println("==== Got the Channel: " + channel); + ethereum1.subscribe(to(EthStatusUpdatedEvent.class, data -> { + channel1[0] = data.getChannel(); + System.out.println("==== Got the Channel: " + data.getChannel()); + })); + + ethereum2.subscribe(to(BlockAddedEvent.class, blockSummary -> { + Block block = blockSummary.getBlock(); + if (block.getNumber() == 4) { + semaphore.countDown(); } - }); - ethereum2.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - if (block.getNumber() == 4) { - semaphore.countDown(); - } - } - - }); + })); System.out.println("======= Waiting for block #4"); semaphore.await(60, TimeUnit.SECONDS); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/FramingTest.java b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/FramingTest.java index a67d78d3d3..9eaf76278a 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/FramingTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/FramingTest.java @@ -21,10 +21,9 @@ import org.ethereum.config.SystemProperties; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.message.Message; -import org.ethereum.net.server.Channel; +import org.ethereum.publish.event.message.ReceivedMessageEvent; import org.junit.Ignore; import org.junit.Test; import org.springframework.context.annotation.Bean; @@ -35,6 +34,8 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import static org.ethereum.publish.Subscription.to; + /** * Created by Anton Nashatyrev on 13.10.2015. */ @@ -98,25 +99,19 @@ public void testTest() throws FileNotFoundException, InterruptedException { final CountDownLatch semaphore = new CountDownLatch(2); - ethereum1.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof StatusMessage) { - System.out.println("1: -> " + message); - semaphore.countDown(); - } + ethereum1.subscribe(to(ReceivedMessageEvent.class, messageData -> { + if (messageData.getMessage() instanceof StatusMessage) { + System.out.println("1: -> " + messageData.getMessage()); + semaphore.countDown(); } - }); - ethereum2.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof StatusMessage) { - System.out.println("2: -> " + message); - semaphore.countDown(); - } + })); + ethereum2.subscribe(to(ReceivedMessageEvent.class, messageData -> { + Message message = messageData.getMessage(); + if (message instanceof StatusMessage) { + System.out.println("2: -> " + message); + semaphore.countDown(); } - - }); + })); ethereum2.connect(new Node("enode://a560c55a0a5b5d137c638eb6973812f431974e4398c6644fa0c19181954fab530bb2a1e2c4eec7cc855f6bab9193ea41d6cf0bf2b8b41ed6b8b9e09c072a1e5a" + "@localhost:30334")); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java index c4874f8c1e..b61c3b7a30 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java @@ -20,17 +20,15 @@ import com.typesafe.config.ConfigFactory; import org.ethereum.config.NoAutoscan; import org.ethereum.config.SystemProperties; -import org.ethereum.core.Block; -import org.ethereum.core.TransactionReceipt; import org.ethereum.crypto.ECKey; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.message.Message; -import org.ethereum.net.server.Channel; import org.ethereum.net.shh.MessageWatcher; import org.ethereum.net.shh.WhisperMessage; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.message.ReceivedMessageEvent; import org.junit.Ignore; import org.junit.Test; import org.spongycastle.util.encoders.Hex; @@ -38,9 +36,11 @@ import org.springframework.context.annotation.Configuration; import java.io.FileNotFoundException; -import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.ethereum.publish.Subscription.to; /** * Created by Anton Nashatyrev on 13.10.2015. @@ -112,16 +112,13 @@ public void testTest() throws FileNotFoundException, InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); - ethereum2.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof StatusMessage) { - System.out.println("=== Status received: " + message); - semaphore.countDown(); - } + ethereum2.subscribe(to(ReceivedMessageEvent.class, messageData -> { + Message message = messageData.getMessage(); + if (message instanceof StatusMessage) { + System.out.println("=== Status received: " + message); + semaphore.countDown(); } - - }); + })); semaphore.await(60, TimeUnit.SECONDS); if(semaphore.getCount() > 0) { @@ -131,24 +128,20 @@ public void onRecvMessage(Channel channel, Message message) { final CountDownLatch semaphoreBlocks = new CountDownLatch(1); final CountDownLatch semaphoreFirstBlock = new CountDownLatch(1); - ethereum2.addListener(new EthereumListenerAdapter() { - int blocksCnt = 0; - - @Override - public void onBlock(Block block, List receipts) { - blocksCnt++; - if (blocksCnt % 1000 == 0 || blocksCnt == 1) { - System.out.println("=== Blocks imported: " + blocksCnt); - if (blocksCnt == 1) { - semaphoreFirstBlock.countDown(); - } - } - if (blocksCnt >= 10_000) { - semaphoreBlocks.countDown(); - System.out.println("=== Blocks task done."); + AtomicInteger blocksCnt = new AtomicInteger(); + ethereum2.subscribe(to(BlockAddedEvent.class, blockSummary -> { + blocksCnt.addAndGet(1); + if (blocksCnt.get() % 1000 == 0 || blocksCnt.get() == 1) { + System.out.println("=== Blocks imported: " + blocksCnt); + if (blocksCnt.get() == 1) { + semaphoreFirstBlock.countDown(); } } - }); + if (blocksCnt.get() >= 10_000) { + semaphoreBlocks.countDown(); + System.out.println("=== Blocks task done."); + } + })); semaphoreFirstBlock.await(180, TimeUnit.SECONDS); if(semaphoreFirstBlock.getCount() > 0) { diff --git a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SnappyConnectionTest.java b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SnappyConnectionTest.java index 082ff6dbc3..0168401509 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SnappyConnectionTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SnappyConnectionTest.java @@ -21,9 +21,7 @@ import org.ethereum.config.SystemProperties; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListenerAdapter; -import org.ethereum.net.eth.message.StatusMessage; -import org.ethereum.net.server.Channel; +import org.ethereum.publish.event.message.EthStatusUpdatedEvent; import org.junit.Ignore; import org.junit.Test; import org.springframework.context.annotation.Bean; @@ -33,6 +31,8 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import static org.ethereum.publish.Subscription.to; + /** * @author Mikhail Kalinin * @since 02.11.2017 @@ -99,20 +99,14 @@ private void runScenario(int vOutbound, int vInbound) throws FileNotFoundExcepti final CountDownLatch semaphore = new CountDownLatch(2); - ethereum1.addListener(new EthereumListenerAdapter() { - @Override - public void onEthStatusUpdated(Channel channel, StatusMessage statusMessage) { - System.out.println("1: -> " + statusMessage); - semaphore.countDown(); - } - }); - ethereum2.addListener(new EthereumListenerAdapter() { - @Override - public void onEthStatusUpdated(Channel channel, StatusMessage statusMessage) { - System.out.println("2: -> " + statusMessage); - semaphore.countDown(); - } - }); + ethereum1.subscribe(to(EthStatusUpdatedEvent.class, data -> { + System.out.println("1: -> " + data.getMessage()); + semaphore.countDown(); + })); + ethereum2.subscribe(to(EthStatusUpdatedEvent.class, data -> { + System.out.println("2: -> " + data.getMessage()); + semaphore.countDown(); + })); ethereum2.connect(new Node("enode://a560c55a0a5b5d137c638eb6973812f431974e4398c6644fa0c19181954fab530bb2a1e2c4eec7cc855f6bab9193ea41d6cf0bf2b8b41ed6b8b9e09c072a1e5a" + "@localhost:30334")); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/shh/ShhLongRun.java b/ethereumj-core/src/test/java/org/ethereum/net/shh/ShhLongRun.java index ced3831f01..de06c9dc15 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/shh/ShhLongRun.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/shh/ShhLongRun.java @@ -21,11 +21,9 @@ import org.ethereum.config.NoAutoscan; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.manager.WorldManager; -import org.ethereum.net.p2p.HelloMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.net.server.Channel; +import org.ethereum.publish.event.message.PeerHandshakedEvent; import org.junit.Ignore; import org.junit.Test; import org.spongycastle.util.encoders.Hex; @@ -41,6 +39,8 @@ import java.util.Date; import java.util.List; +import static org.ethereum.publish.Subscription.to; + /** * This is not a JUnit test but rather a long running standalone test for messages exchange with another peer. * To start it another peer with JSON PRC API should be started. @@ -110,15 +110,12 @@ public TestComponent() { @PostConstruct void init() { System.out.println("========= init"); - worldManager.addListener(new EthereumListenerAdapter() { - @Override - public void onHandShakePeer(Channel channel, HelloMessage helloMessage) { - System.out.println("========= onHandShakePeer"); - if (!isAlive()) { - start(); - } + worldManager.getPublisher().subscribe(to(PeerHandshakedEvent.class, data -> { + System.out.println("========= onHandShakePeer"); + if (!isAlive()) { + start(); } - }); + })); } static class MessageMatcher extends MessageWatcher { diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java index 0161794770..1e15f1d452 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java @@ -22,25 +22,21 @@ import org.ethereum.config.SystemProperties; import org.ethereum.core.Block; import org.ethereum.core.BlockIdentifier; -import org.ethereum.core.BlockSummary; import org.ethereum.core.Transaction; -import org.ethereum.core.TransactionReceipt; import org.ethereum.crypto.ECKey; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.mine.Ethash; import org.ethereum.mine.MinerListener; -import org.ethereum.net.eth.message.EthMessage; -import org.ethereum.net.eth.message.EthMessageCodes; -import org.ethereum.net.eth.message.NewBlockHashesMessage; -import org.ethereum.net.eth.message.NewBlockMessage; -import org.ethereum.net.eth.message.StatusMessage; -import org.ethereum.net.eth.message.TransactionsMessage; +import org.ethereum.net.eth.message.*; import org.ethereum.net.message.Message; import org.ethereum.net.rlpx.Node; -import org.ethereum.net.server.Channel; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.PeerAddedToSyncPoolEvent; +import org.ethereum.publish.event.SyncDoneEvent; +import org.ethereum.publish.event.message.EthStatusUpdatedEvent; +import org.ethereum.publish.event.message.ReceivedMessageEvent; +import org.ethereum.publish.event.message.SentMessageEvent; import org.ethereum.util.ByteUtil; import org.junit.Ignore; import org.junit.Test; @@ -51,22 +47,18 @@ import org.springframework.context.annotation.Bean; import javax.annotation.PostConstruct; -import java.util.Collections; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; -import java.util.Vector; +import java.util.*; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import static org.ethereum.publish.Subscription.to; + /** * Long running test - * + *

      * 3 peers: A <-> B <-> C where A is miner, C is issuing txs, and B should forward Txs/Blocks */ @Ignore @@ -128,7 +120,16 @@ public BasicSample(String loggerName) { private void springInit() { logger = LoggerFactory.getLogger(loggerName); // adding the main EthereumJ callback to be notified on different kind of events - ethereum.addListener(listener); + this.ethereum + .subscribe(to(SyncDoneEvent.class, syncState -> synced = true)) + .subscribe(to(EthStatusUpdatedEvent.class, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage()))) + .subscribe(to(PeerAddedToSyncPoolEvent.class, peer -> syncPeers.add(peer.getNode()))) + .subscribe(to(BlockAddedEvent.class, blockSummary -> { + bestBlock = blockSummary.getBlock(); + if (syncComplete) { + logger.info("New block: " + bestBlock.getShortDescr()); + } + })); logger.info("Sample component created. Listening for ethereum events..."); @@ -164,7 +165,7 @@ public void run() { */ private void waitForSync() throws Exception { logger.info("Waiting for the whole blockchain sync (will take up to several hours for the whole chain)..."); - while(true) { + while (true) { Thread.sleep(10000); if (synced) { @@ -189,35 +190,6 @@ public void onSyncDone() throws Exception { boolean synced = false; boolean syncComplete = false; - - /** - * The main EthereumJ callback. - */ - EthereumListener listener = new EthereumListenerAdapter() { - @Override - public void onSyncDone(SyncState state) { - synced = true; - } - - @Override - public void onEthStatusUpdated(Channel channel, StatusMessage statusMessage) { - ethNodes.put(channel.getNode(), statusMessage); - } - - @Override - public void onPeerAddedToSyncPool(Channel peer) { - syncPeers.add(peer.getNode()); - } - - @Override - public void onBlock(Block block, List receipts) { - bestBlock = block; - - if (syncComplete) { - logger.info("New block: " + block.getShortDescr()); - } - } - }; } /** @@ -228,22 +200,22 @@ private static class MinerConfig { private final String config = // no need for discovery in that small network "peer.discovery.enabled = false \n" + - "peer.listen.port = 30335 \n" + - // need to have different nodeId's for the peers - "peer.privateKey = 6ef8da380c27cea8fdf7448340ea99e8e2268fc2950d79ed47cbf6f85dc977ec \n" + - // our private net ID - "peer.networkId = 555 \n" + - // we have no peers to sync with - "sync.enabled = false \n" + - // genesis with a lower initial difficulty and some predefined known funded accounts - "genesis = sample-genesis.json \n" + - // two peers need to have separate database dirs - "database.dir = sampleDB-1 \n" + - "keyvalue.datasource = leveldb \n" + - // when more than 1 miner exist on the network extraData helps to identify the block creator - "mine.extraDataHex = cccccccccccccccccccc \n" + - "mine.cpuMineThreads = 2 \n" + - "cache.flush.blocks = 1"; + "peer.listen.port = 30335 \n" + + // need to have different nodeId's for the peers + "peer.privateKey = 6ef8da380c27cea8fdf7448340ea99e8e2268fc2950d79ed47cbf6f85dc977ec \n" + + // our private net ID + "peer.networkId = 555 \n" + + // we have no peers to sync with + "sync.enabled = false \n" + + // genesis with a lower initial difficulty and some predefined known funded accounts + "genesis = sample-genesis.json \n" + + // two peers need to have separate database dirs + "database.dir = sampleDB-1 \n" + + "keyvalue.datasource = rocksdb \n" + + // when more than 1 miner exist on the network extraData helps to identify the block creator + "mine.extraDataHex = cccccccccccccccccccc \n" + + "mine.cpuMineThreads = 2 \n" + + "cache.flush.blocks = 1"; @Bean public MinerNode node() { @@ -266,7 +238,7 @@ public SystemProperties systemProperties() { /** * Miner bean, which just start a miner upon creation and prints miner events */ - static class MinerNode extends BasicSample implements MinerListener{ + static class MinerNode extends BasicSample implements MinerListener { public MinerNode() { // peers need different loggers super("sampleMiner"); @@ -323,22 +295,22 @@ private static class RegularConfig { private final String config = // no discovery: we are connecting directly to the generator and miner peers "peer.discovery.enabled = false \n" + - "peer.listen.port = 30339 \n" + - "peer.privateKey = 1f0bbd4ffd61128a7d150c07d3f5b7dcd078359cd708ada8b60e4b9ffd90b3f5 \n" + - "peer.networkId = 555 \n" + - // actively connecting to the miner and tx generator - "peer.active = [" + - // miner - " { url = 'enode://26ba1aadaf59d7607ad7f437146927d79e80312f026cfa635c6b2ccf2c5d3521f5812ca2beb3b295b14f97110e6448c1c7ff68f14c5328d43a3c62b44143e9b1@localhost:30335' }, \n" + - // tx generator - " { url = 'enode://3973cb86d7bef9c96e5d589601d788370f9e24670dcba0480c0b3b1b0647d13d0f0fffed115dd2d4b5ca1929287839dcd4e77bdc724302b44ae48622a8766ee6@localhost:30336' } \n" + - "] \n" + - "sync.enabled = true \n" + - // all peers in the same network need to use the same genesis block - "genesis = sample-genesis.json \n" + - // two peers need to have separate database dirs - "database.dir = sampleDB-2 \n" + - "keyvalue.datasource = leveldb \n"; + "peer.listen.port = 30339 \n" + + "peer.privateKey = 1f0bbd4ffd61128a7d150c07d3f5b7dcd078359cd708ada8b60e4b9ffd90b3f5 \n" + + "peer.networkId = 555 \n" + + // actively connecting to the miner and tx generator + "peer.active = [" + + // miner + " { url = 'enode://26ba1aadaf59d7607ad7f437146927d79e80312f026cfa635c6b2ccf2c5d3521f5812ca2beb3b295b14f97110e6448c1c7ff68f14c5328d43a3c62b44143e9b1@localhost:30335' }, \n" + + // tx generator + " { url = 'enode://3973cb86d7bef9c96e5d589601d788370f9e24670dcba0480c0b3b1b0647d13d0f0fffed115dd2d4b5ca1929287839dcd4e77bdc724302b44ae48622a8766ee6@localhost:30336' } \n" + + "] \n" + + "sync.enabled = true \n" + + // all peers in the same network need to use the same genesis block + "genesis = sample-genesis.json \n" + + // two peers need to have separate database dirs + "database.dir = sampleDB-2 \n" + + "keyvalue.datasource = rocksdb \n"; @Bean public RegularNode node() { @@ -375,15 +347,15 @@ private static class GeneratorConfig { private final String config = // no discovery: forwarder will connect to us "peer.discovery.enabled = false \n" + - "peer.listen.port = 30336 \n" + - "peer.privateKey = 3ec771c31cac8c0dba77a69e503765701d3c2bb62435888d4ffa38fed60c445c \n" + - "peer.networkId = 555 \n" + - "sync.enabled = true \n" + - // all peers in the same network need to use the same genesis block - "genesis = sample-genesis.json \n" + - // two peers need to have separate database dirs - "database.dir = sampleDB-3 \n" + - "keyvalue.datasource = leveldb \n"; + "peer.listen.port = 30336 \n" + + "peer.privateKey = 3ec771c31cac8c0dba77a69e503765701d3c2bb62435888d4ffa38fed60c445c \n" + + "peer.networkId = 555 \n" + + "sync.enabled = true \n" + + // all peers in the same network need to use the same genesis block + "genesis = sample-genesis.json \n" + + // two peers need to have separate database dirs + "database.dir = sampleDB-3 \n" + + "keyvalue.datasource = rocksdb \n"; @Bean public GeneratorNode node() { @@ -427,12 +399,11 @@ public void onSyncDone() { } - /** * Generate one simple value transfer transaction each 7 seconds. * Thus blocks will include one, several and none transactions */ - private void generateTransactions() throws Exception{ + private void generateTransactions() throws Exception { logger.info("Start generating transactions..."); // the sender which some coins from the genesis @@ -455,7 +426,7 @@ private void generateTransactions() throws Exception{ } private final static Map blocks = Collections.synchronizedMap(new HashMap()); - private final static Map txs = Collections.synchronizedMap(new HashMap()); + private final static Map txs = Collections.synchronizedMap(new HashMap()); private final static AtomicInteger fatalErrors = new AtomicInteger(0); private final static AtomicBoolean stopTxGeneration = new AtomicBoolean(false); @@ -485,12 +456,12 @@ private boolean logStats() { } /** - * Creating 3 EthereumJ instances with different config classes - * 1st - Miner node, no sync - * 2nd - Regular node, synced with both Miner and Generator - * 3rd - Generator node, sync is on, but can see only 2nd node - * We want to check that blocks mined on Miner will reach Generator and - * txs from Generator will reach Miner node + * Creating 3 EthereumJ instances with different config classes + * 1st - Miner node, no sync + * 2nd - Regular node, synced with both Miner and Generator + * 3rd - Generator node, sync is on, but can see only 2nd node + * We want to check that blocks mined on Miner will reach Generator and + * txs from Generator will reach Miner node */ @Test public void testTest() throws Exception { @@ -509,98 +480,91 @@ public void testTest() throws Exception { testLogger.info("Starting EthereumJ miner instance!"); Ethereum miner = EthereumFactory.createEthereum(MinerConfig.class); - miner.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(BlockSummary blockSummary) { - if (blockSummary.getBlock().getNumber() != 0L) { - blocks.put(Hex.toHexString(blockSummary.getBlock().getHash()), Boolean.FALSE); - } - } - - @Override - public void onRecvMessage(Channel channel, Message message) { - super.onRecvMessage(channel, message); - if (!(message instanceof EthMessage)) return; - switch (((EthMessage) message).getCommand()) { - case NEW_BLOCK_HASHES: - testLogger.error("Received new block hash message at miner: {}", message.toString()); - fatalErrors.incrementAndGet(); - break; - case NEW_BLOCK: - testLogger.error("Received new block message at miner: {}", message.toString()); - fatalErrors.incrementAndGet(); - break; - case TRANSACTIONS: - TransactionsMessage msgCopy = new TransactionsMessage(message.getEncoded()); - for (Transaction transaction : msgCopy.getTransactions()) { - if (txs.put(Hex.toHexString(transaction.getHash()), Boolean.TRUE) == null) { - testLogger.error("Received strange transaction at miner: {}", transaction); - fatalErrors.incrementAndGet(); - }; - } - default: - break; - } - } - }); + miner + .subscribe(to(BlockAddedEvent.class, blockSummary -> { + if (blockSummary.getBlock().getNumber() != 0L) { + blocks.put(Hex.toHexString(blockSummary.getBlock().getHash()), Boolean.FALSE); + } + })) + .subscribe(to(ReceivedMessageEvent.class, messageData -> { + Message message = messageData.getMessage(); + if (!(message instanceof EthMessage)) return; + switch (((EthMessage) message).getCommand()) { + case NEW_BLOCK_HASHES: + testLogger.error("Received new block hash message at miner: {}", message.toString()); + fatalErrors.incrementAndGet(); + break; + case NEW_BLOCK: + testLogger.error("Received new block message at miner: {}", message.toString()); + fatalErrors.incrementAndGet(); + break; + case TRANSACTIONS: + TransactionsMessage msgCopy = new TransactionsMessage(message.getEncoded()); + for (Transaction transaction : msgCopy.getTransactions()) { + if (txs.put(Hex.toHexString(transaction.getHash()), Boolean.TRUE) == null) { + testLogger.error("Received strange transaction at miner: {}", transaction); + fatalErrors.incrementAndGet(); + } + } + default: + break; + } + })); testLogger.info("Starting EthereumJ regular instance!"); EthereumFactory.createEthereum(RegularConfig.class); testLogger.info("Starting EthereumJ txSender instance!"); Ethereum txGenerator = EthereumFactory.createEthereum(GeneratorConfig.class); - txGenerator.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - super.onRecvMessage(channel, message); - if (!(message instanceof EthMessage)) return; - switch (((EthMessage) message).getCommand()) { - case NEW_BLOCK_HASHES: - testLogger.info("Received new block hash message at generator: {}", message.toString()); - NewBlockHashesMessage msgCopy = new NewBlockHashesMessage(message.getEncoded()); - for (BlockIdentifier identifier : msgCopy.getBlockIdentifiers()) { - if (blocks.put(Hex.toHexString(identifier.getHash()), Boolean.TRUE) == null) { - testLogger.error("Received strange block: {}", identifier); + txGenerator + .subscribe(to(ReceivedMessageEvent.class, messageData -> { + Message message = messageData.getMessage(); + if (!(message instanceof EthMessage)) return; + switch (((EthMessage) message).getCommand()) { + case NEW_BLOCK_HASHES: + testLogger.info("Received new block hash message at generator: {}", message.toString()); + NewBlockHashesMessage msgCopy = new NewBlockHashesMessage(message.getEncoded()); + for (BlockIdentifier identifier : msgCopy.getBlockIdentifiers()) { + if (blocks.put(Hex.toHexString(identifier.getHash()), Boolean.TRUE) == null) { + testLogger.error("Received strange block: {}", identifier); + fatalErrors.incrementAndGet(); + } + } + break; + case NEW_BLOCK: + testLogger.info("Received new block message at generator: {}", message.toString()); + NewBlockMessage msgCopy2 = new NewBlockMessage(message.getEncoded()); + Block block = msgCopy2.getBlock(); + if (blocks.put(Hex.toHexString(block.getHash()), Boolean.TRUE) == null) { + testLogger.error("Received strange block: {}", block); fatalErrors.incrementAndGet(); - }; + } + break; + case BLOCK_BODIES: + testLogger.info("Received block bodies message at generator: {}", message.toString()); + break; + case TRANSACTIONS: + testLogger.warn("Received new transaction message at generator: {}, " + + "allowed only after disconnect.", message.toString()); + break; + default: + break; + } + + })) + .subscribe(to(SentMessageEvent.class, messageData -> { + Message message = messageData.getMessage(); + if (!(message instanceof EthMessage)) return; + if (((EthMessage) message).getCommand().equals(EthMessageCodes.TRANSACTIONS)) { + TransactionsMessage msgCopy = new TransactionsMessage(message.getEncoded()); + for (Transaction transaction : msgCopy.getTransactions()) { + Transaction copyTransaction = new Transaction(transaction.getEncoded()); + txs.put(Hex.toHexString(copyTransaction.getHash()), Boolean.FALSE); } - break; - case NEW_BLOCK: - testLogger.info("Received new block message at generator: {}", message.toString()); - NewBlockMessage msgCopy2 = new NewBlockMessage(message.getEncoded()); - Block block = msgCopy2.getBlock(); - if (blocks.put(Hex.toHexString(block.getHash()), Boolean.TRUE) == null) { - testLogger.error("Received strange block: {}", block); - fatalErrors.incrementAndGet(); - }; - break; - case BLOCK_BODIES: - testLogger.info("Received block bodies message at generator: {}", message.toString()); - break; - case TRANSACTIONS: - testLogger.warn("Received new transaction message at generator: {}, " + - "allowed only after disconnect.", message.toString()); - break; - default: - break; - } - } - - @Override - public void onSendMessage(Channel channel, Message message) { - super.onSendMessage(channel, message); - if (!(message instanceof EthMessage)) return; - if (((EthMessage) message).getCommand().equals(EthMessageCodes.TRANSACTIONS)) { - TransactionsMessage msgCopy = new TransactionsMessage(message.getEncoded()); - for (Transaction transaction : msgCopy.getTransactions()) { - Transaction copyTransaction = new Transaction(transaction.getEncoded()); - txs.put(Hex.toHexString(copyTransaction.getHash()), Boolean.FALSE); - }; - } - } - }); + } + })); - if(statTimer.awaitTermination(MAX_RUN_MINUTES, TimeUnit.MINUTES)) { + if (statTimer.awaitTermination(MAX_RUN_MINUTES, TimeUnit.MINUTES)) { logStats(); // Stop generating new txs stopTxGeneration.set(true); diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java index 856cf7ae01..80b4f334fa 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java @@ -19,19 +19,24 @@ import org.ethereum.config.NoAutoscan; import org.ethereum.config.SystemProperties; -import org.ethereum.config.blockchain.FrontierConfig; -import org.ethereum.config.net.MainNetConfig; -import org.ethereum.core.*; +import org.ethereum.core.Block; +import org.ethereum.core.BlockHeader; +import org.ethereum.core.Blockchain; +import org.ethereum.core.ImportResult; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.net.eth.handler.Eth62; import org.ethereum.net.eth.handler.EthHandler; -import org.ethereum.net.eth.message.*; -import org.ethereum.net.message.Message; +import org.ethereum.net.eth.message.BlockBodiesMessage; +import org.ethereum.net.eth.message.BlockHeadersMessage; +import org.ethereum.net.eth.message.GetBlockBodiesMessage; +import org.ethereum.net.eth.message.GetBlockHeadersMessage; import org.ethereum.net.p2p.DisconnectMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.net.server.Channel; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.PeerAddedToSyncPoolEvent; +import org.ethereum.publish.event.message.EthStatusUpdatedEvent; +import org.ethereum.publish.event.message.ReceivedMessageEvent; import org.ethereum.util.blockchain.StandaloneBlockchain; import org.junit.*; import org.springframework.context.annotation.Bean; @@ -49,6 +54,7 @@ import java.util.concurrent.CountDownLatch; import static java.util.concurrent.TimeUnit.SECONDS; +import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.FileUtil.recursiveDelete; import static org.junit.Assert.fail; import static org.spongycastle.util.encoders.Hex.decode; @@ -155,14 +161,11 @@ public void test1() throws InterruptedException { // A == b10, B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - if (block.isEqual(b10)) { - semaphore.countDown(); - } + ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + if (blockSummary.getBlock().isEqual(b10)) { + semaphore.countDown(); } - }); + })); semaphore.await(40, SECONDS); @@ -195,14 +198,11 @@ protected void processGetBlockBodies(GetBlockBodiesMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof DisconnectMessage) { - semaphoreDisconnect.countDown(); - } + ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + if (messageData.getMessage() instanceof DisconnectMessage) { + semaphoreDisconnect.countDown(); } - }); + })); semaphoreDisconnect.await(10, SECONDS); @@ -245,14 +245,11 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof DisconnectMessage) { - semaphoreDisconnect.countDown(); - } + ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + if (messageData.getMessage() instanceof DisconnectMessage) { + semaphoreDisconnect.countDown(); } - }); + })); semaphoreDisconnect.await(10, SECONDS); @@ -290,14 +287,11 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof DisconnectMessage) { - semaphoreDisconnect.countDown(); - } + ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + if (messageData.getMessage() instanceof DisconnectMessage) { + semaphoreDisconnect.countDown(); } - }); + })); semaphoreDisconnect.await(10, SECONDS); @@ -339,14 +333,11 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof DisconnectMessage) { - semaphoreDisconnect.countDown(); - } + ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + if (messageData.getMessage() instanceof DisconnectMessage) { + semaphoreDisconnect.countDown(); } - }); + })); semaphoreDisconnect.await(10, SECONDS); @@ -392,14 +383,11 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof DisconnectMessage) { - semaphoreDisconnect.countDown(); - } + ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + if (messageData.getMessage() instanceof DisconnectMessage) { + semaphoreDisconnect.countDown(); } - }); + })); semaphoreDisconnect.await(10, SECONDS); @@ -441,14 +429,11 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof DisconnectMessage) { - semaphoreDisconnect.countDown(); - } + ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + if (messageData.getMessage() instanceof DisconnectMessage) { + semaphoreDisconnect.countDown(); } - }); + })); semaphoreDisconnect.await(10, SECONDS); @@ -491,14 +476,11 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof DisconnectMessage) { - semaphoreDisconnect.countDown(); - } + ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + if (messageData.getMessage() instanceof DisconnectMessage) { + semaphoreDisconnect.countDown(); } - }); + })); semaphoreDisconnect.await(10, SECONDS); @@ -526,23 +508,11 @@ private void setupPeers(Block best) throws InterruptedException { // A == best ethereumB = EthereumFactory.createEthereum(SysPropConfigB.props, SysPropConfigB.class); - - ethereumA.addListener(new EthereumListenerAdapter() { - @Override - public void onEthStatusUpdated(Channel channel, StatusMessage statusMessage) { - ethA = (EthHandler) channel.getEthHandler(); - } - }); + ethereumA.subscribe(to(EthStatusUpdatedEvent.class, data -> ethA = (EthHandler) data.getChannel().getEthHandler())); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onPeerAddedToSyncPool(Channel peer) { - semaphore.countDown(); - } - }); - + ethereumB.subscribe(to(PeerAddedToSyncPoolEvent.class, channel -> semaphore.countDown())); ethereumB.connect(nodeA); semaphore.await(10, SECONDS); diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java index 21cd330fe0..bded3f9e57 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java @@ -19,22 +19,21 @@ import org.ethereum.config.NoAutoscan; import org.ethereum.config.SystemProperties; -import org.ethereum.config.blockchain.FrontierConfig; import org.ethereum.config.net.MainNetConfig; import org.ethereum.core.Block; import org.ethereum.core.BlockHeader; import org.ethereum.core.Blockchain; -import org.ethereum.core.TransactionReceipt; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.net.eth.handler.Eth62; import org.ethereum.net.eth.handler.EthHandler; import org.ethereum.net.eth.message.*; -import org.ethereum.net.message.Message; import org.ethereum.net.p2p.DisconnectMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.net.server.Channel; +import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.PeerAddedToSyncPoolEvent; +import org.ethereum.publish.event.message.EthStatusUpdatedEvent; +import org.ethereum.publish.event.message.ReceivedMessageEvent; import org.ethereum.util.blockchain.StandaloneBlockchain; import org.junit.*; import org.springframework.context.annotation.Bean; @@ -55,6 +54,7 @@ import java.util.concurrent.CountDownLatch; import static java.util.concurrent.TimeUnit.SECONDS; +import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.FileUtil.recursiveDelete; import static org.junit.Assert.fail; import static org.spongycastle.util.encoders.Hex.decode; @@ -160,21 +160,15 @@ public void test1() throws InterruptedException { // A == b10, B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - if (block.isEqual(b10)) { - semaphore.countDown(); - } - } - }); + ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> semaphore.countDown()) + .conditionally(blockSummary -> blockSummary.getBlock().isEqual(b10))); ethA.sendNewBlock(b10); semaphore.await(10, SECONDS); // check if B == b10 - if(semaphore.getCount() > 0) { + if (semaphore.getCount() > 0) { fail("PeerB bestBlock is incorrect"); } } @@ -198,21 +192,15 @@ public void test2() throws InterruptedException { // A == b8', B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - if (block.isEqual(b8_)) { - semaphore.countDown(); - } - } - }); + ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> semaphore.countDown()) + .conditionally(blockSummary -> blockSummary.getBlock().isEqual(b8_))); ethA.sendNewBlock(b8_); semaphore.await(10, SECONDS); // check if B == b8' - if(semaphore.getCount() > 0) { + if (semaphore.getCount() > 0) { fail("PeerB bestBlock is incorrect"); } } @@ -240,21 +228,19 @@ public void test3() throws InterruptedException { // A == b10, B == b8' final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - if (block.isEqual(b10)) { - semaphore.countDown(); - } + ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + Block block = blockSummary.getBlock(); + if (block.isEqual(b10)) { + semaphore.countDown(); } - }); + })); ethA.sendNewBlock(b10); semaphore.await(10, SECONDS); // check if B == b10 - if(semaphore.getCount() > 0) { + if (semaphore.getCount() > 0) { fail("PeerB bestBlock is incorrect"); } } @@ -287,14 +273,8 @@ public void test4() throws InterruptedException { // A == b5, B == b9 final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - if (block.isEqual(b10)) { - semaphore.countDown(); - } - } - }); + ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> semaphore.countDown()) + .conditionally(blockSummary -> blockSummary.getBlock().equals(b10))); ethA.sendNewBlockHashes(b5); @@ -309,7 +289,7 @@ public void onBlock(Block block, List receipts) { semaphore.await(10, SECONDS); // check if B == b10 - if(semaphore.getCount() > 0) { + if (semaphore.getCount() > 0) { fail("PeerB bestBlock is incorrect"); } } @@ -342,22 +322,20 @@ public void test5() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB8_ = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - if (block.isEqual(b10)) { - semaphore.countDown(); - } - if (block.isEqual(b8_)) { - semaphoreB8_.countDown(); - } + ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + Block block = blockSummary.getBlock(); + if (block.isEqual(b10)) { + semaphore.countDown(); + } + if (block.isEqual(b8_)) { + semaphoreB8_.countDown(); } - }); + })); ethA.sendNewBlockHashes(b8_); semaphoreB8_.await(10, SECONDS); - if(semaphoreB8_.getCount() > 0) { + if (semaphoreB8_.getCount() > 0) { fail("PeerB didn't import b8'"); } @@ -372,7 +350,7 @@ public void onBlock(Block block, List receipts) { semaphore.await(10, SECONDS); // check if B == b10 - if(semaphore.getCount() > 0) { + if (semaphore.getCount() > 0) { fail("PeerB bestBlock is incorrect"); } } @@ -404,24 +382,22 @@ public void test6() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB7 = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - if (block.isEqual(b7)) { - semaphoreB7.countDown(); - } - if (block.isEqual(b10)) { - semaphore.countDown(); - } + ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + Block block = blockSummary.getBlock(); + if (block.isEqual(b7)) { + semaphoreB7.countDown(); + } + if (block.isEqual(b10)) { + semaphore.countDown(); } - }); + })); ethA.sendNewBlockHashes(b7); semaphoreB7.await(10, SECONDS); // check if B == b7 - if(semaphoreB7.getCount() > 0) { + if (semaphoreB7.getCount() > 0) { fail("PeerB didn't recover a gap"); } @@ -435,7 +411,7 @@ public void onBlock(Block block, List receipts) { semaphore.await(10, SECONDS); // check if B == b10 - if(semaphore.getCount() > 0) { + if (semaphore.getCount() > 0) { fail("PeerB bestBlock is incorrect"); } } @@ -466,27 +442,23 @@ public void test7() throws InterruptedException { // A == b8', B == b4 - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof NewBlockMessage) { - // it's time to do a re-branch - for (Block b : mainB1B10) { - blockchainA.tryToConnect(b); - } + ethereumB.subscribe(to(ReceivedMessageEvent.class, data -> { + if (data.getMessage() instanceof NewBlockMessage) { + // it's time to do a re-branch + for (Block b : mainB1B10) { + blockchainA.tryToConnect(b); } } - }); + + })); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - if (block.isEqual(b10)) { - semaphore.countDown(); - } + ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + Block block = blockSummary.getBlock(); + if (block.isEqual(b10)) { + semaphore.countDown(); } - }); + })); ethA.sendNewBlock(b8_); ethA.sendNewBlock(b10); @@ -494,7 +466,7 @@ public void onBlock(Block block, List receipts) { semaphore.await(10, SECONDS); // check if B == b10 - if(semaphore.getCount() > 0) { + if (semaphore.getCount() > 0) { fail("PeerB bestBlock is incorrect"); } } @@ -529,27 +501,25 @@ public void test8() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB7_ = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - if (block.isEqual(b7_)) { - // it's time to do a re-branch - for (Block b : mainB1B10) { - blockchainA.tryToConnect(b); - } - - semaphoreB7_.countDown(); - } - if (block.isEqual(b10)) { - semaphore.countDown(); + ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + Block block = blockSummary.getBlock(); + if (block.isEqual(b7_)) { + // it's time to do a re-branch + for (Block b : mainB1B10) { + blockchainA.tryToConnect(b); } + + semaphoreB7_.countDown(); + } + if (block.isEqual(b10)) { + semaphore.countDown(); } - }); + })); ethA.sendNewBlockHashes(b7_); semaphoreB7_.await(10, SECONDS); - if(semaphoreB7_.getCount() > 0) { + if (semaphoreB7_.getCount() > 0) { fail("PeerB didn't import b7'"); } @@ -558,7 +528,7 @@ public void onBlock(Block block, List receipts) { semaphore.await(10, SECONDS); // check if B == b10 - if(semaphore.getCount() > 0) { + if (semaphore.getCount() > 0) { fail("PeerB bestBlock is incorrect"); } } @@ -613,19 +583,16 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { ethA.sendNewBlock(b8_); final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof DisconnectMessage) { - semaphoreDisconnect.countDown(); - } + ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + if (messageData.getMessage() instanceof DisconnectMessage) { + semaphoreDisconnect.countDown(); } - }); + })); semaphoreDisconnect.await(10, SECONDS); // check if peer was dropped - if(semaphoreDisconnect.getCount() > 0) { + if (semaphoreDisconnect.getCount() > 0) { fail("PeerA is not dropped"); } @@ -637,27 +604,21 @@ public void onRecvMessage(Channel channel, Message message) { } final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - if (block.isEqual(b10)) { - semaphore.countDown(); - } + ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + Block block = blockSummary.getBlock(); + if (block.isEqual(b10)) { + semaphore.countDown(); } - }); + })); + final CountDownLatch semaphoreConnect = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onPeerAddedToSyncPool(Channel peer) { - semaphoreConnect.countDown(); - } - }); + ethereumB.subscribe(to(PeerAddedToSyncPoolEvent.class, channel -> semaphoreConnect.countDown())); ethereumB.connect(nodeA); // await connection semaphoreConnect.await(10, SECONDS); - if(semaphoreConnect.getCount() > 0) { + if (semaphoreConnect.getCount() > 0) { fail("PeerB is not able to connect to PeerA"); } @@ -666,7 +627,7 @@ public void onPeerAddedToSyncPool(Channel peer) { semaphore.await(10, SECONDS); // check if B == b10 - if(semaphore.getCount() > 0) { + if (semaphore.getCount() > 0) { fail("PeerB bestBlock is incorrect"); } } @@ -720,47 +681,38 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { ethA.sendNewBlockHashes(b8_); final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof DisconnectMessage) { - semaphoreDisconnect.countDown(); - } + ethereumA.subscribe(to(ReceivedMessageEvent.class, data -> { + if (data.getMessage() instanceof DisconnectMessage) { + semaphoreDisconnect.countDown(); } - }); + })); + semaphoreDisconnect.await(10, SECONDS); // check if peer was dropped - if(semaphoreDisconnect.getCount() > 0) { + if (semaphoreDisconnect.getCount() > 0) { fail("PeerA is not dropped"); } // back to usual handler - SysPropConfigA.eth62 = null; + LongSyncTest.SysPropConfigA.eth62 = null; final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - if (block.isEqual(b10)) { - semaphore.countDown(); - } + ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + Block block = blockSummary.getBlock(); + if (block.isEqual(b10)) { + semaphore.countDown(); } - }); + })); final CountDownLatch semaphoreConnect = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onPeerAddedToSyncPool(Channel peer) { - semaphoreConnect.countDown(); - } - }); + ethereumB.subscribe(to(PeerAddedToSyncPoolEvent.class, channel -> semaphoreConnect.countDown())); ethereumB.connect(nodeA); // await connection semaphoreConnect.await(10, SECONDS); - if(semaphoreConnect.getCount() > 0) { + if (semaphoreConnect.getCount() > 0) { fail("PeerB is not able to connect to PeerA"); } @@ -775,7 +727,7 @@ public void onPeerAddedToSyncPool(Channel peer) { semaphore.await(10, SECONDS); // check if B == b10 - if(semaphore.getCount() > 0) { + if (semaphore.getCount() > 0) { fail("PeerB bestBlock is incorrect"); } } @@ -808,23 +760,20 @@ public void test11() throws InterruptedException { final CountDownLatch semaphore1 = new CountDownLatch(1); final CountDownLatch semaphore2 = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onBlock(Block block, List receipts) { - if (block.isEqual(b6_)) { - if (semaphore1.getCount() > 0) { - semaphore1.countDown(); - } else { - semaphore2.countDown(); - } + ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + if (blockSummary.getBlock().isEqual(b6_)) { + if (semaphore1.getCount() > 0) { + semaphore1.countDown(); + } else { + semaphore2.countDown(); } } - }); + })); ethA.sendNewBlock(b6_); semaphore1.await(10, SECONDS); - if(semaphore1.getCount() > 0) { + if (semaphore1.getCount() > 0) { fail("PeerB doesn't accept block with higher TD"); } @@ -839,7 +788,7 @@ public void onBlock(Block block, List receipts) { semaphore2.await(5, SECONDS); // check if B skips b6' - if(semaphore2.getCount() == 0) { + if (semaphore2.getCount() == 0) { fail("PeerB doesn't skip block with lower TD"); } } @@ -873,21 +822,16 @@ protected void processGetBlockBodies(GetBlockBodiesMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof DisconnectMessage) { - semaphoreDisconnect.countDown(); - } - } - }); + this.ethereumA + .subscribe(to(ReceivedMessageEvent.class, data -> semaphoreDisconnect.countDown()) + .conditionally(data -> data.getMessage() instanceof DisconnectMessage)); ethA.sendNewBlock(b10); semaphoreDisconnect.await(10, SECONDS); // check if peer was dropped - if(semaphoreDisconnect.getCount() > 0) { + if (semaphoreDisconnect.getCount() > 0) { fail("PeerA is not dropped"); } } @@ -938,21 +882,15 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b8', B == b10 final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof DisconnectMessage) { - semaphoreDisconnect.countDown(); - } - } - }); + ethereumA.subscribe(to(ReceivedMessageEvent.class, data -> semaphoreDisconnect.countDown()) + .conditionally(data -> data.getMessage() instanceof DisconnectMessage)); ethA.sendNewBlockHashes(b8_); semaphoreDisconnect.await(10, SECONDS); // check if peer was dropped - if(semaphoreDisconnect.getCount() > 0) { + if (semaphoreDisconnect.getCount() > 0) { fail("PeerA is not dropped"); } } @@ -978,7 +916,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { forkB1B5B8_.get(7).getHeader(), forkB1B5B8_.get(6).getHeader(), new BlockHeader(new byte[32], new byte[32], new byte[32], new byte[32], new byte[32], - 6, new byte[] {0}, 0, 0, new byte[0], new byte[0], new byte[0]), + 6, new byte[]{0}, 0, 0, new byte[0], new byte[0], new byte[0]), forkB1B5B8_.get(4).getHeader() ); @@ -1004,21 +942,15 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b8', B == b10 final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.addListener(new EthereumListenerAdapter() { - @Override - public void onRecvMessage(Channel channel, Message message) { - if (message instanceof DisconnectMessage) { - semaphoreDisconnect.countDown(); - } - } - }); + ethereumA.subscribe(to(ReceivedMessageEvent.class, data -> semaphoreDisconnect.countDown()) + .conditionally(data -> data.getMessage() instanceof DisconnectMessage)); ethA.sendNewBlockHashes(b8_); semaphoreDisconnect.await(10, SECONDS); // check if peer was dropped - if(semaphoreDisconnect.getCount() > 0) { + if (semaphoreDisconnect.getCount() > 0) { fail("PeerA is not dropped"); } } @@ -1028,26 +960,15 @@ private void setupPeers() throws InterruptedException { ethereumA = EthereumFactory.createEthereum(SysPropConfigA.props, SysPropConfigA.class); ethereumB = EthereumFactory.createEthereum(SysPropConfigB.props, SysPropConfigB.class); - ethereumA.addListener(new EthereumListenerAdapter() { - @Override - public void onEthStatusUpdated(Channel channel, StatusMessage statusMessage) { - ethA = (EthHandler) channel.getEthHandler(); - } - }); + ethereumA.subscribe(to(EthStatusUpdatedEvent.class, data -> ethA = (EthHandler) data.getChannel().getEthHandler())); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.addListener(new EthereumListenerAdapter() { - @Override - public void onPeerAddedToSyncPool(Channel peer) { - semaphore.countDown(); - } - }); - + ethereumB.subscribe(to(PeerAddedToSyncPoolEvent.class, channel -> semaphore.countDown())); ethereumB.connect(nodeA); semaphore.await(10, SECONDS); - if(semaphore.getCount() > 0) { + if (semaphore.getCount() > 0) { fail("Failed to set up peers"); } } From 53e0173661e1a66e2d11206e966bc54e5821ac9c Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Fri, 10 Aug 2018 14:22:45 +0300 Subject: [PATCH 03/28] Adds unsubscribeAfter(event) logic --- .../java/org/ethereum/publish/Publisher.java | 17 ++++++--- .../org/ethereum/publish/Subscription.java | 35 +++++++++++++++---- .../org/ethereum/publish/PublisherTest.java | 31 ++++++++++++---- 3 files changed, 66 insertions(+), 17 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java index 4b74118d13..e4ce7ca8e3 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java @@ -15,10 +15,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Consumer; import static java.util.Collections.emptyList; @@ -82,13 +82,20 @@ public Publisher(EventDispatchThread dispatchThread) { * @return current {@link Publisher} instance to support fluent API. */ public Publisher publish(Event event) { - List subscriptions = subscriptionsByEvent.getOrDefault(event.getClass(), emptyList()).stream() + List subscriptions = subscriptionsByEvent.getOrDefault(event.getClass(), emptyList()); + List toHandle = subscriptions.stream() .filter(subscription -> subscription.matches(event)) .collect(toList()); - if (!subscriptions.isEmpty()) { - dispatchThread.invokeLater(() -> subscriptions.forEach(subscription -> { + subscriptions.stream() + .filter(subscription -> subscription.needUnsubscribeAfter(event)) + .forEach(this::unsubscribe); + + + if (!toHandle.isEmpty()) { + dispatchThread.invokeLater(() -> toHandle.forEach(subscription -> { subscription.handle(event); + if (event instanceof Single) { subscriptionsByEvent.remove(event.getClass()); } @@ -108,7 +115,7 @@ public Publisher publish(Event event) { * @return current {@link Publisher} instance to support fluent API. */ public , P> Publisher subscribe(Subscription subscription) { - List subscriptions = subscriptionsByEvent.computeIfAbsent(subscription.getEventType(), t -> new ArrayList<>()); + List subscriptions = subscriptionsByEvent.computeIfAbsent(subscription.getEventType(), t -> new CopyOnWriteArrayList<>()); if (subscriptions.contains(subscription)) { log.warn("Specified subscription already exists {}.", subscription.getEventType().getSimpleName()); } else { diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java index 79c9ba4508..b838bba84e 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java @@ -8,6 +8,7 @@ import java.util.function.Function; import static java.util.Objects.isNull; +import static java.util.Objects.nonNull; /** * Abstraction that holds together event type, event processor (a.k.a consumer) and optional condition that resolves @@ -21,7 +22,8 @@ public class Subscription, D> { private final Class eventType; private final Consumer consumer; - private Function condition; + private Function handleCondition; + private Function unsubscribeCondition; public Subscription(Class eventType, Consumer consumer) { this.eventType = eventType; @@ -44,7 +46,18 @@ public Class getEventType() { * @return current {@link Subscription} instance to support fluent API. */ public Subscription conditionally(Function condition) { - this.condition = condition; + this.handleCondition = condition; + return this; + } + + /** + * Optionally adds unsubscribe condition after event consuming. + * + * @param condition function that resolves unsubscribing after event consumption. + * @return current {@link Subscription} instance to support fluent API. + */ + public Subscription unsubscribeAfter(Function condition) { + this.unsubscribeCondition = condition; return this; } @@ -55,7 +68,7 @@ public Subscription conditionally(Function condition) { * @return true if event should be consumed, false otherwise. */ boolean matches(E event) { - return isNull(condition) || condition.apply(event.getPayload()); + return isNull(handleCondition) || handleCondition.apply(event.getPayload()); } /** @@ -71,13 +84,23 @@ void handle(E event) { } } + /** + * Tests whether publisher should remove current {@link Subscription} after specified event handling. + * + * @param event event to test; + * @return true if after event consumption {@link Subscription} should be unsubscribed, false otherwise. + */ + boolean needUnsubscribeAfter(E event) { + return nonNull(unsubscribeCondition) && unsubscribeCondition.apply(event.getPayload()); + } + /** * Short static alias for {@link Subscription} constructor. * * @param eventType event type to process; - * @param consumer callback that consumes event's payload; - * @param event type that should be process; - * @param payload's type of specified event type; + * @param consumer callback that consumes event's payload; + * @param event type that should be process; + * @param payload's type of specified event type; * @return new {@link Subscription} instance. */ public static , D> Subscription to(Class eventType, Consumer consumer) { diff --git a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java index 05125c8a1b..7ea8250afb 100644 --- a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java @@ -73,16 +73,16 @@ public void testSingleEvent() { @Test public void testConditionallySubscription() { - AtomicLong expectedSum = new AtomicLong(); - AtomicInteger expectedEvenSum = new AtomicInteger(); + AtomicLong actualSum = new AtomicLong(); + AtomicInteger actualEvenSum = new AtomicInteger(); int[] numbers = IntStream.rangeClosed(1, 10).toArray(); int sum = IntStream.of(numbers).sum(); int evenSum = IntStream.of(numbers).filter(num -> isEven(num)).sum(); Publisher publisher = createPublisher() - .subscribe(to(LongEvent.class, expectedSum::getAndAdd)) - .subscribe(to(IntEvent.class, expectedEvenSum::getAndAdd) + .subscribe(to(LongEvent.class, actualSum::getAndAdd)) + .subscribe(to(IntEvent.class, actualEvenSum::getAndAdd) .conditionally(PublisherTest::isEven)); IntStream.of(numbers) @@ -90,8 +90,27 @@ public void testConditionallySubscription() { .publish(new LongEvent(num)) .publish(new IntEvent(num))); - assertEquals(sum, expectedSum.get()); - assertEquals(evenSum, expectedEvenSum.get()); + assertEquals(sum, actualSum.get()); + assertEquals(evenSum, actualEvenSum.get()); + } + + @Test + public void testUnsubscribeAfter() { + AtomicInteger actualSum = new AtomicInteger(); + + int limit = 10; + int[] numbers = IntStream.rangeClosed(1, limit).toArray(); + int sum = IntStream.of(numbers).sum(); + + Publisher publisher = createPublisher() + .subscribe(to(IntEvent.class, actualSum::addAndGet) + .unsubscribeAfter(num -> num == limit)); + + IntStream.rangeClosed(1, limit * 2) + .mapToObj(IntEvent::new) + .forEach(publisher::publish); + + assertEquals(sum, actualSum.get()); } @Test From d2fd02795ca618686b89901847a2d2998806bb25 Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Fri, 10 Aug 2018 15:03:09 +0300 Subject: [PATCH 04/28] Makes Publisher dependant from abstract executor. Adds additional logging. --- .../ethereum/core/EventDispatchThread.java | 7 +- .../java/org/ethereum/facade/Ethereum.java | 86 ++++++++++++------- .../ethereum/listener/EthereumListener.java | 16 ++-- .../listener/EthereumListenerAdapter.java | 6 ++ .../java/org/ethereum/publish/Publisher.java | 59 ++++++++----- .../org/ethereum/publish/Subscription.java | 4 +- 6 files changed, 117 insertions(+), 61 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/core/EventDispatchThread.java b/ethereumj-core/src/main/java/org/ethereum/core/EventDispatchThread.java index 8f1fa4a5a9..e1d07a80b5 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/EventDispatchThread.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/EventDispatchThread.java @@ -35,7 +35,7 @@ * Created by Anton Nashatyrev on 29.12.2015. */ @Component -public class EventDispatchThread { +public class EventDispatchThread implements Executor { private static final Logger logger = LoggerFactory.getLogger("blockchain"); private static EventDispatchThread eventDispatchThread; @@ -67,6 +67,11 @@ public void invokeLater(Runnable r) { return eventDispatchThread; } + @Override + public void execute(Runnable command) { + invokeLater(command); + } + public void invokeLater(final Runnable r) { if (executor.isShutdown()) return; if (counter++ % 1000 == 0) logStatus(); diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java index 010e492b23..afde481a78 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java @@ -56,14 +56,33 @@ public interface Ethereum { Blockchain getBlockchain(); + /** + * Uses expensive enough logic for delivery events to client.
      + * Will be removed in future releases. + * + * @param listener + * @deprecated use {@link #subscribe(Subscription)} instead. + */ + @Deprecated void addListener(EthereumListener listener); + /** + * Adds subscription for specific event. + * + * @param subscription + * @param event type to listen; + * @param

      {@link Event} payload type, which will be passed to subscription handler; + * @return publisher instance to support fluent API. + * @see Subscription + * @see Publisher + * @see Event + */ + , P> Publisher subscribe(Subscription subscription); + PeerClient getDefaultPeer(); boolean isConnected(); - , P> Publisher subscribe(Subscription subscription); - void close(); /** @@ -74,24 +93,23 @@ public interface Ethereum { /** * Factory for general transaction * - * - * @param nonce - account nonce, based on number of transaction submited by - * this account - * @param gasPrice - gas price bid by miner , the user ask can be based on - * lastr submited block - * @param gas - the quantity of gas requested for the transaction + * @param nonce - account nonce, based on number of transaction submited by + * this account + * @param gasPrice - gas price bid by miner , the user ask can be based on + * lastr submited block + * @param gas - the quantity of gas requested for the transaction * @param receiveAddress - the target address of the transaction - * @param value - the ether value of the transaction - * @param data - can be init procedure for creational transaction, - * also msg data for invoke transaction for only value - * transactions this one is empty. + * @param value - the ether value of the transaction + * @param data - can be init procedure for creational transaction, + * also msg data for invoke transaction for only value + * transactions this one is empty. * @return newly created transaction */ Transaction createTransaction(BigInteger nonce, - BigInteger gasPrice, - BigInteger gas, - byte[] receiveAddress, - BigInteger value, byte[] data); + BigInteger gasPrice, + BigInteger gas, + byte[] receiveAddress, + BigInteger value, byte[] data); /** @@ -104,11 +122,12 @@ Transaction createTransaction(BigInteger nonce, /** * Executes the transaction based on the specified block but doesn't change the blockchain state * and doesn't send the transaction to the network - * @param tx The transaction to execute. No need to sign the transaction and specify the correct nonce - * @param block Transaction is executed the same way as if it was executed after all transactions existing - * in that block. I.e. the root state is the same as this block's root state and this block - * is assumed to be the current block - * @return receipt of the executed transaction + * + * @param tx The transaction to execute. No need to sign the transaction and specify the correct nonce + * @param block Transaction is executed the same way as if it was executed after all transactions existing + * in that block. I.e. the root state is the same as this block's root state and this block + * is assumed to be the current block + * @return receipt of the executed transaction */ TransactionReceipt callConstant(Transaction tx, Block block); @@ -121,16 +140,17 @@ Transaction createTransaction(BigInteger nonce, * * @param block block to be replayed * @return block summary with receipts and execution summaries - * Note: it doesn't include block rewards info + * Note: it doesn't include block rewards info */ BlockSummary replayBlock(Block block); /** * Call a contract function locally without sending transaction to the network * and without changing contract storage. + * * @param receiveAddress hex encoded contract address - * @param function contract function - * @param funcArgs function arguments + * @param function contract function + * @param funcArgs function arguments * @return function result. The return value can be fetched via {@link ProgramResult#getHReturn()} * and decoded with {@link org.ethereum.core.CallTransaction.Function#decodeResult(byte[])}. */ @@ -141,11 +161,12 @@ ProgramResult callConstantFunction(String receiveAddress, CallTransaction.Functi /** * Call a contract function locally without sending transaction to the network * and without changing contract storage. - * @param receiveAddress hex encoded contract address - * @param senderPrivateKey Normally the constant call doesn't require a sender though - * in some cases it may affect the result (e.g. if function refers to msg.sender) - * @param function contract function - * @param funcArgs function arguments + * + * @param receiveAddress hex encoded contract address + * @param senderPrivateKey Normally the constant call doesn't require a sender though + * in some cases it may affect the result (e.g. if function refers to msg.sender) + * @param function contract function + * @param funcArgs function arguments * @return function result. The return value can be fetched via {@link ProgramResult#getHReturn()} * and decoded with {@link org.ethereum.core.CallTransaction.Function#decodeResult(byte[])}. */ @@ -197,7 +218,7 @@ ProgramResult callConstantFunction(String receiveAddress, ECKey senderPrivateKey Whisper getWhisper(); /** - * Gets the Miner component + * Gets the Miner component */ BlockMiner getBlockMiner(); @@ -207,8 +228,7 @@ ProgramResult callConstantFunction(String receiveAddress, ECKey senderPrivateKey void initSyncing(); /** - * @deprecated - * Calculates a 'reasonable' Gas price based on statistics of the latest transaction's Gas prices + * @deprecated Calculates a 'reasonable' Gas price based on statistics of the latest transaction's Gas prices * Normally the price returned should be sufficient to execute a transaction since ~25% of the latest * transactions were executed at this or lower price. * If the transaction is wanted to be executed promptly with higher chances the returned price might @@ -227,6 +247,7 @@ ProgramResult callConstantFunction(String receiveAddress, ECKey senderPrivateKey /** * Chain id for next block. * Introduced in EIP-155 + * * @return chain id or null */ Integer getChainIdForNextBlock(); @@ -234,6 +255,7 @@ ProgramResult callConstantFunction(String receiveAddress, ECKey senderPrivateKey /** * Manual switch to Short Sync mode * Maybe useful in small private and detached networks when automatic detection fails + * * @return Future, which completes when syncDone is turned to True in {@link org.ethereum.sync.SyncManager} */ CompletableFuture switchToShortSync(); diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java b/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java index 4ece1f0682..bba95322ef 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java @@ -27,8 +27,12 @@ import java.util.List; /** + * Uses expensive enough logic for delivery events to client.
      + * Will be removed in future releases. + * * @author Roman Mandeleil * @since 27.07.2014 + * @deprecated use {@link org.ethereum.publish.Publisher} instead. */ public interface EthereumListener { @@ -36,9 +40,9 @@ enum PendingTransactionState { /** * Transaction may be dropped due to: * - Invalid transaction (invalid nonce, low gas price, insufficient account funds, - * invalid signature) + * invalid signature) * - Timeout (when pending transaction is not included to any block for - * last [transaction.outdated.threshold] blocks + * last [transaction.outdated.threshold] blocks * This is the final state */ DROPPED, @@ -62,7 +66,7 @@ enum PendingTransactionState { * This could be the final state, however next state could also be * PENDING: when a fork became the main chain but doesn't include this tx * INCLUDED: when a fork became the main chain and tx is included into another - * block from the new main chain + * block from the new main chain * DROPPED: If switched to a new (long enough) main chain without this Tx */ INCLUDED; @@ -135,9 +139,9 @@ default void onBlock(BlockSummary blockSummary, boolean best) { * Is called when PendingTransaction arrives, executed or dropped and included to a block * * @param txReceipt Receipt of the tx execution on the current PendingState - * @param state Current state of pending tx - * @param block The block which the current pending state is based on (for PENDING tx state) - * or the block which tx was included to (for INCLUDED state) + * @param state Current state of pending tx + * @param block The block which the current pending state is based on (for PENDING tx state) + * or the block which tx was included to (for INCLUDED state) */ void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionState state, Block block); diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListenerAdapter.java b/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListenerAdapter.java index e2f7d29930..67b4969868 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListenerAdapter.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListenerAdapter.java @@ -27,9 +27,15 @@ import java.util.List; /** + * Default implementation of {@link EthereumListener}.
      + * Uses expensive enough logic for delivery events to client.
      + * Will be removed in future releases. + * * @author Roman Mandeleil * @since 08.08.2014 + * @deprecated use {@link org.ethereum.publish.Publisher} instead. */ +@Deprecated public class EthereumListenerAdapter implements EthereumListener { @Override diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java index e4ce7ca8e3..9ab89541ea 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java @@ -19,8 +19,10 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Executor; import java.util.function.Consumer; +import static java.lang.String.format; import static java.util.Collections.emptyList; import static java.util.Objects.nonNull; import static java.util.stream.Collectors.toList; @@ -67,11 +69,31 @@ public class Publisher { private static final Logger log = LoggerFactory.getLogger("events"); - private final EventDispatchThread dispatchThread; + private class Command implements Runnable { + private final List subscriptions; + private final Event event; + + private Command(List subscriptions, Event event) { + this.subscriptions = subscriptions; + this.event = event; + } + + @Override + public void run() { + subscriptions.forEach(subscription -> subscription.handle(event)); + } + + @Override + public String toString() { + return format("%s: consumed by %d subscriber(s).", event, subscriptions.size()); + } + } + + private final Executor executor; private final Map, List> subscriptionsByEvent = new ConcurrentHashMap<>(); - public Publisher(EventDispatchThread dispatchThread) { - this.dispatchThread = dispatchThread; + public Publisher(Executor executor) { + this.executor = executor; } /** @@ -83,23 +105,24 @@ public Publisher(EventDispatchThread dispatchThread) { */ public Publisher publish(Event event) { List subscriptions = subscriptionsByEvent.getOrDefault(event.getClass(), emptyList()); - List toHandle = subscriptions.stream() - .filter(subscription -> subscription.matches(event)) - .collect(toList()); + if (!subscriptions.isEmpty()) { + + List toHandle = subscriptions.stream() + .filter(subscription -> subscription.matches(event)) + .collect(toList()); - subscriptions.stream() - .filter(subscription -> subscription.needUnsubscribeAfter(event)) - .forEach(this::unsubscribe); + subscriptions.stream() + .filter(subscription -> subscription.needUnsubscribeAfter(event)) + .forEach(this::unsubscribe); + if (event instanceof Single) { + subscriptionsByEvent.remove(event.getClass()); + } - if (!toHandle.isEmpty()) { - dispatchThread.invokeLater(() -> toHandle.forEach(subscription -> { - subscription.handle(event); - if (event instanceof Single) { - subscriptionsByEvent.remove(event.getClass()); - } - })); + if (!toHandle.isEmpty()) { + executor.execute(new Command(toHandle, event)); + } } return this; @@ -178,10 +201,6 @@ public int subscribersCount() { .sum(); } - public void shutdown() { - dispatchThread.shutdown(); - } - /** * Method that subscribes all {@link EthereumListener} callbacks to corresponding events. * Avoid using this method directly, because it creates unnecessary stub {@link Subscription}s. diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java index b838bba84e..ab4beeca8a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java @@ -11,8 +11,8 @@ import static java.util.Objects.nonNull; /** - * Abstraction that holds together event type, event processor (a.k.a consumer) and optional condition that resolves - * event processing. + * Abstraction that holds together event type, event processor (a.k.a consumer) and optional conditions that resolves + * event processing and auto-unsubscribe. * * @author Eugene Shevchenko */ From 7a27d8d6560340ac92063e431f86cdacb82e2277 Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Fri, 10 Aug 2018 16:35:12 +0300 Subject: [PATCH 05/28] Replace EthereumListener to Publisher usage --- .../org/ethereum/net/client/PeerClient.java | 8 ++--- .../java/org/ethereum/net/p2p/P2pHandler.java | 36 +++++++++---------- .../org/ethereum/net/rlpx/MessageCodec.java | 10 +++--- .../net/rlpx/discover/NodeManager.java | 15 ++++---- .../org/ethereum/net/server/PeerServer.java | 16 ++++----- .../java/org/ethereum/net/shh/ShhHandler.java | 18 +++++----- .../ethereum/net/swarm/bzz/BzzHandler.java | 11 +++--- 7 files changed, 55 insertions(+), 59 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java b/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java index ed5fb872d4..72560f9d1c 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java @@ -17,10 +17,6 @@ */ package org.ethereum.net.client; -import org.ethereum.config.SystemProperties; -import org.ethereum.listener.EthereumListener; -import org.ethereum.net.server.EthereumChannelInitializer; - import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; @@ -28,12 +24,12 @@ import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; - +import org.ethereum.config.SystemProperties; +import org.ethereum.net.server.EthereumChannelInitializer; import org.ethereum.publish.Publisher; import org.ethereum.publish.event.TraceEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; diff --git a/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java index 37fefab397..366bd36236 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java @@ -17,11 +17,11 @@ */ package org.ethereum.net.p2p; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; import org.ethereum.config.SystemProperties; import org.ethereum.core.Block; import org.ethereum.core.Transaction; -import org.ethereum.listener.EthereumListener; -import org.ethereum.manager.WorldManager; import org.ethereum.net.MessageQueue; import org.ethereum.net.client.Capability; import org.ethereum.net.client.ConfigCapabilities; @@ -31,30 +31,28 @@ import org.ethereum.net.message.StaticMessages; import org.ethereum.net.server.Channel; import org.ethereum.net.shh.ShhHandler; - -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; - import org.ethereum.net.swarm.Util; import org.ethereum.net.swarm.bzz.BzzHandler; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.TraceEvent; +import org.ethereum.publish.event.message.PeerHandshakedEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; -import java.net.InetAddress; -import java.net.InetSocketAddress; - import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.concurrent.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; -import static org.ethereum.net.eth.EthVersion.*; -import static org.ethereum.net.message.StaticMessages.*; +import static java.lang.String.format; +import static org.ethereum.net.eth.EthVersion.fromCode; +import static org.ethereum.net.message.StaticMessages.PING_MESSAGE; +import static org.ethereum.net.message.StaticMessages.PONG_MESSAGE; /** * Process the basic protocol messages between every peer on the network. @@ -90,7 +88,7 @@ public class P2pHandler extends SimpleChannelInboundHandler { private int ethOutbound; @Autowired - EthereumListener ethereumListener; + private Publisher publisher; @Autowired ConfigCapabilities configCapabilities; @@ -122,7 +120,7 @@ public void setPeerDiscoveryMode(boolean peerDiscoveryMode) { public void handlerAdded(ChannelHandlerContext ctx) throws Exception { logger.debug("P2P protocol activated"); msgQueue.activate(ctx); - ethereumListener.trace("P2P protocol activated"); + publisher.publish(new TraceEvent("P2P protocol activated")); startTimers(); } @@ -133,7 +131,7 @@ public void channelRead0(final ChannelHandlerContext ctx, P2pMessage msg) throws if (P2pMessageCodes.inRange(msg.getCommand().asByte())) logger.trace("P2PHandler invoke: [{}]", msg.getCommand()); - ethereumListener.trace(String.format("P2PHandler invoke: [%s]", msg.getCommand())); + publisher.publish(new TraceEvent(format("P2PHandler invoke: [%s]", msg.getCommand()))); switch (msg.getCommand()) { case HELLO: @@ -245,7 +243,7 @@ public void setHandshake(HelloMessage msg, ChannelHandlerContext ctx) { } //todo calculate the Offsets - ethereumListener.onHandShakePeer(channel, msg); + publisher.publish(new PeerHandshakedEvent(channel, msg)); } /** diff --git a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java index 536357b52a..70adc14d95 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java @@ -23,7 +23,6 @@ import org.apache.commons.collections4.map.LRUMap; import org.apache.commons.lang3.tuple.Pair; import org.ethereum.config.SystemProperties; -import org.ethereum.listener.EthereumListener; import org.ethereum.net.client.Capability; import org.ethereum.net.eth.EthVersion; import org.ethereum.net.eth.message.EthMessageCodes; @@ -34,6 +33,9 @@ import org.ethereum.net.server.Channel; import org.ethereum.net.shh.ShhMessageCodes; import org.ethereum.net.swarm.bzz.BzzMessageCodes; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.TraceEvent; +import org.ethereum.publish.event.message.ReceivedMessageEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -72,7 +74,7 @@ public class MessageCodec extends MessageToMessageCodec { private EthVersion ethVersion; @Autowired - EthereumListener ethereumListener; + private Publisher publisher; private SystemProperties config; @@ -166,7 +168,7 @@ private Message decodeMessage(ChannelHandlerContext ctx, List frames) thr return null; } - ethereumListener.onRecvMessage(channel, msg); + publisher.publish(new ReceivedMessageEvent(channel, msg)); channel.getNodeStatistics().rlpxInMessages.add(); return msg; @@ -175,7 +177,7 @@ private Message decodeMessage(ChannelHandlerContext ctx, List frames) thr @Override protected void encode(ChannelHandlerContext ctx, Message msg, List out) throws Exception { String output = String.format("To: \t%s \tSend: \t%s", ctx.channel().remoteAddress(), msg); - ethereumListener.trace(output); + publisher.publish(new TraceEvent(output)); if (loggerNet.isDebugEnabled()) loggerNet.debug("To: {} Send: {}", channel, msg); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java index 58dee3a7b1..a99d910cea 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java @@ -21,9 +21,10 @@ import org.ethereum.config.SystemProperties; import org.ethereum.crypto.ECKey; import org.ethereum.db.PeerSource; -import org.ethereum.listener.EthereumListener; import org.ethereum.net.rlpx.*; import org.ethereum.net.rlpx.discover.table.NodeTable; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.NodeDiscoveredEvent; import org.ethereum.util.CollectionUtils; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -38,8 +39,6 @@ import java.util.function.Consumer; import java.util.function.Predicate; -import static java.lang.Math.min; - /** * The central class for Peer Discovery machinery. * @@ -62,7 +61,7 @@ public class NodeManager implements Consumer{ PeerConnectionTester peerConnectionManager; PeerSource peerSource; - EthereumListener ethereumListener; + Publisher publisher; SystemProperties config = SystemProperties.getDefault(); Consumer messageSender; @@ -86,10 +85,10 @@ public class NodeManager implements Consumer{ private ScheduledExecutorService pongTimer; @Autowired - public NodeManager(SystemProperties config, EthereumListener ethereumListener, + public NodeManager(SystemProperties config, Publisher publisher, ApplicationContext ctx, PeerConnectionTester peerConnectionManager) { this.config = config; - this.ethereumListener = ethereumListener; + this.publisher = publisher; this.peerConnectionManager = peerConnectionManager; PERSIST = config.peerDiscoveryPersist(); @@ -198,14 +197,14 @@ public synchronized NodeHandler getNodeHandler(Node n) { nodeHandlerMap.put(key, ret); logger.debug(" +++ New node: " + ret + " " + n); if (!n.isDiscoveryNode() && !n.getHexId().equals(homeNode.getHexId())) { - ethereumListener.onNodeDiscovered(ret.getNode()); + publisher.publish(new NodeDiscoveredEvent(ret.getNode())); } } else if (ret.getNode().isDiscoveryNode() && !n.isDiscoveryNode()) { // we found discovery node with same host:port, // replace node with correct nodeId ret.node = n; if (!n.getHexId().equals(homeNode.getHexId())) { - ethereumListener.onNodeDiscovered(ret.getNode()); + publisher.publish(new NodeDiscoveredEvent(ret.getNode())); } logger.debug(" +++ Found real nodeId for discovery endpoint {}", n); } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java b/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java index f4ae5ac1c7..489f4da57f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java @@ -17,9 +17,6 @@ */ package org.ethereum.net.server; -import org.ethereum.config.SystemProperties; -import org.ethereum.listener.EthereumListener; - import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; @@ -28,10 +25,11 @@ import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LoggingHandler; - +import org.ethereum.config.SystemProperties; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.TraceEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; @@ -54,7 +52,7 @@ public class PeerServer { private ApplicationContext ctx; - private EthereumListener ethereumListener; + private Publisher publisher; public EthereumChannelInitializer ethereumChannelInitializer; @@ -66,10 +64,10 @@ public class PeerServer { @Autowired public PeerServer(final SystemProperties config, final ApplicationContext ctx, - final EthereumListener ethereumListener) { + final Publisher publisher) { this.ctx = ctx; this.config = config; - this.ethereumListener = ethereumListener; + this.publisher = publisher; } public void start(int port) { @@ -79,7 +77,7 @@ public void start(int port) { ethereumChannelInitializer = ctx.getBean(EthereumChannelInitializer.class, ""); - ethereumListener.trace("Listening on port " + port); + publisher.publish(new TraceEvent("Listening on port " + port)); try { diff --git a/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java index 5e6a90717f..277b8349fa 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java @@ -17,19 +17,19 @@ */ package org.ethereum.net.shh; -import org.ethereum.listener.EthereumListener; -import org.ethereum.net.MessageQueue; - import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; - +import org.ethereum.net.MessageQueue; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.TraceEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import static java.lang.String.format; + /** * Process the messages between peers with 'shh' capability on the network. * @@ -46,7 +46,7 @@ public class ShhHandler extends SimpleChannelInboundHandler { private BloomFilter peerBloomFilter = BloomFilter.createAll(); @Autowired - private EthereumListener ethereumListener; + private Publisher publisher; @Autowired private WhisperImpl whisper; @@ -66,11 +66,11 @@ public void channelRead0(final ChannelHandlerContext ctx, ShhMessage msg) throws if (ShhMessageCodes.inRange(msg.getCommand().asByte())) logger.info("ShhHandler invoke: [{}]", msg.getCommand()); - ethereumListener.trace(String.format("ShhHandler invoke: [%s]", msg.getCommand())); + publisher.publish(new TraceEvent(format("ShhHandler invoke: [%s]", msg.getCommand()))); switch (msg.getCommand()) { case STATUS: - ethereumListener.trace("[Recv: " + msg + "]"); + publisher.publish(new TraceEvent("[Recv: " + msg + "]")); break; case MESSAGE: whisper.processEnvelope((ShhEnvelopeMessage) msg, this); @@ -104,7 +104,7 @@ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { public void activate() { logger.info("SHH protocol activated"); - ethereumListener.trace("SHH protocol activated"); + publisher.publish(new TraceEvent("SHH protocol activated")); whisper.addPeer(this); sendStatus(); sendHostBloom(); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java index 0dfc40426d..63d9d30ab6 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java @@ -19,9 +19,10 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; -import org.ethereum.listener.EthereumListener; import org.ethereum.net.MessageQueue; import org.ethereum.net.swarm.NetStore; +import org.ethereum.publish.Publisher; +import org.ethereum.publish.event.TraceEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -30,6 +31,8 @@ import java.util.function.Consumer; +import static java.lang.String.format; + /** * Process the messages between peers with 'bzz' capability on the network. */ @@ -48,7 +51,7 @@ public class BzzHandler extends SimpleChannelInboundHandler BzzProtocol bzzProtocol; @Autowired - EthereumListener ethereumListener; + private Publisher publisher; @Autowired NetStore netStore; @@ -68,7 +71,7 @@ public void channelRead0(final ChannelHandlerContext ctx, BzzMessage msg) throws if (BzzMessageCodes.inRange(msg.getCommand().asByte())) logger.debug("BzzHandler invoke: [{}]", msg.getCommand()); - ethereumListener.trace(String.format("BzzHandler invoke: [%s]", msg.getCommand())); + publisher.publish(new TraceEvent(format("BzzHandler invoke: [%s]", msg.getCommand()))); if (bzzProtocol != null) { bzzProtocol.accept(msg); @@ -95,7 +98,7 @@ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { public void activate() { logger.info("BZZ protocol activated"); - ethereumListener.trace("BZZ protocol activated"); + publisher.publish(new TraceEvent("BZZ protocol activated")); createBzzProtocol(); this.active = true; } From c216d329cc7796777523087f51d4592bc05e202f Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Tue, 14 Aug 2018 13:53:50 +0300 Subject: [PATCH 06/28] Renames all events by removing 'Event' suffix. --- .../org/ethereum/core/BlockchainImpl.java | 12 +-- .../org/ethereum/core/PendingStateImpl.java | 14 ++-- .../ethereum/core/TransactionExecutor.java | 8 +- .../java/org/ethereum/db/DbFlushManager.java | 4 +- .../org/ethereum/facade/EthereumImpl.java | 4 +- .../org/ethereum/manager/WorldManager.java | 4 +- .../java/org/ethereum/mine/BlockMiner.java | 8 +- .../java/org/ethereum/net/MessageQueue.java | 8 +- .../org/ethereum/net/client/PeerClient.java | 4 +- .../org/ethereum/net/eth/handler/Eth62.java | 4 +- .../ethereum/net/eth/handler/EthHandler.java | 12 +-- .../java/org/ethereum/net/p2p/P2pHandler.java | 10 +-- .../org/ethereum/net/rlpx/MessageCodec.java | 8 +- .../net/rlpx/discover/NodeManager.java | 6 +- .../org/ethereum/net/server/PeerServer.java | 4 +- .../java/org/ethereum/net/shh/ShhHandler.java | 8 +- .../ethereum/net/swarm/bzz/BzzHandler.java | 6 +- .../java/org/ethereum/publish/Publisher.java | 76 +++++++++--------- ...ockAddedEvent.java => BestBlockAdded.java} | 4 +- .../{BlockAddedEvent.java => BlockAdded.java} | 4 +- .../ethereum/publish/event/NoConnections.java | 4 + .../publish/event/NoConnectionsEvent.java | 4 - ...scoveredEvent.java => NodeDiscovered.java} | 4 +- .../publish/event/PeerAddedToSyncPool.java | 10 +++ .../event/PeerAddedToSyncPoolEvent.java | 10 --- ...nectedEvent.java => PeerDisconnected.java} | 4 +- ...gedEvent.java => PendingStateChanged.java} | 4 +- ...nt.java => PendingTransactionUpdated.java} | 4 +- .../event/PendingTransactionsReceived.java | 17 ++++ .../PendingTransactionsReceivedEvent.java | 17 ---- .../org/ethereum/publish/event/SyncDone.java | 10 +++ .../ethereum/publish/event/SyncDoneEvent.java | 10 --- .../org/ethereum/publish/event/Trace.java | 8 ++ .../ethereum/publish/event/TraceEvent.java | 8 -- .../publish/event/TransactionExecuted.java | 9 +++ .../event/TransactionExecutedEvent.java | 9 --- ...eCreatedEvent.java => VmTraceCreated.java} | 4 +- ...pdatedEvent.java => EthStatusUpdated.java} | 4 +- ...MessageEvent.java => MessageReceived.java} | 4 +- ...ivedMessageEvent.java => MessageSent.java} | 4 +- ...ndshakedEvent.java => PeerHandshaked.java} | 4 +- .../org/ethereum/samples/BasicSample.java | 20 ++--- .../samples/CreateContractSample.java | 4 +- .../ethereum/samples/EventListenerSample.java | 8 +- .../org/ethereum/samples/FollowAccount.java | 4 +- .../ethereum/samples/PendingStateSample.java | 8 +- .../org/ethereum/samples/SendTransaction.java | 4 +- .../org/ethereum/samples/TransactionBomb.java | 8 +- .../org/ethereum/sync/FastSyncManager.java | 6 +- .../java/org/ethereum/sync/SyncManager.java | 4 +- .../main/java/org/ethereum/sync/SyncPool.java | 5 +- .../util/blockchain/StandaloneBlockchain.java | 4 +- .../org/ethereum/validator/EthashRule.java | 8 +- .../java/org/ethereum/core/CloseTest.java | 4 +- .../org/ethereum/core/ImportLightTest.java | 6 +- .../org/ethereum/core/PendingStateTest.java | 80 +++++++++---------- .../java/org/ethereum/longrun/BasicNode.java | 18 ++--- .../ethereum/longrun/SyncWithLoadTest.java | 8 +- .../java/org/ethereum/mine/MinerTest.java | 16 ++-- .../java/org/ethereum/mine/SyncDoneTest.java | 22 ++--- .../java/org/ethereum/net/TwoPeerTest.java | 8 +- .../org/ethereum/net/rlpx/FramingTest.java | 6 +- .../ethereum/net/rlpx/SanityLongRunTest.java | 8 +- .../net/rlpx/SnappyConnectionTest.java | 6 +- .../java/org/ethereum/net/shh/ShhLongRun.java | 4 +- .../org/ethereum/sync/BlockTxForwardTest.java | 28 +++---- .../java/org/ethereum/sync/LongSyncTest.java | 28 +++---- .../java/org/ethereum/sync/ShortSyncTest.java | 50 ++++++------ .../ethereum/validator/EthashRuleTest.java | 14 ++-- 69 files changed, 374 insertions(+), 375 deletions(-) rename ethereumj-core/src/main/java/org/ethereum/publish/event/{BestBlockAddedEvent.java => BestBlockAdded.java} (79%) rename ethereumj-core/src/main/java/org/ethereum/publish/event/{BlockAddedEvent.java => BlockAdded.java} (50%) create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnections.java delete mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnectionsEvent.java rename ethereumj-core/src/main/java/org/ethereum/publish/event/{NodeDiscoveredEvent.java => NodeDiscovered.java} (50%) create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPool.java delete mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPoolEvent.java rename ethereumj-core/src/main/java/org/ethereum/publish/event/{PeerDisconnectedEvent.java => PeerDisconnected.java} (76%) rename ethereumj-core/src/main/java/org/ethereum/publish/event/{PendingStateChangedEvent.java => PendingStateChanged.java} (79%) rename ethereumj-core/src/main/java/org/ethereum/publish/event/{PendingTransactionUpdatedEvent.java => PendingTransactionUpdated.java} (85%) create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceived.java delete mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceivedEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java delete mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDoneEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/Trace.java delete mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/TraceEvent.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecuted.java delete mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecutedEvent.java rename ethereumj-core/src/main/java/org/ethereum/publish/event/{VmTraceCreatedEvent.java => VmTraceCreated.java} (77%) rename ethereumj-core/src/main/java/org/ethereum/publish/event/message/{EthStatusUpdatedEvent.java => EthStatusUpdated.java} (69%) rename ethereumj-core/src/main/java/org/ethereum/publish/event/message/{SentMessageEvent.java => MessageReceived.java} (52%) rename ethereumj-core/src/main/java/org/ethereum/publish/event/message/{ReceivedMessageEvent.java => MessageSent.java} (51%) rename ethereumj-core/src/main/java/org/ethereum/publish/event/message/{PeerHandshakedEvent.java => PeerHandshaked.java} (69%) diff --git a/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java b/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java index fb343ed2e1..e4421298ed 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java @@ -26,9 +26,9 @@ import org.ethereum.db.*; import org.ethereum.manager.AdminInfo; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.BestBlockAddedEvent; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.TraceEvent; +import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.Trace; import org.ethereum.sync.SyncManager; import org.ethereum.trie.Trie; import org.ethereum.trie.TrieImpl; @@ -455,9 +455,9 @@ public synchronized ImportResult tryToConnect(final Block block) { if (ret.isSuccessful()) { publisher - .publish(new BlockAddedEvent(summary)) - .publish(new BestBlockAddedEvent(summary, ret == IMPORTED_BEST)) - .publish(new TraceEvent(format("Block chain size: [ %d ]", this.getSize()))); + .publish(new BlockAdded(summary)) + .publish(new BestBlockAdded(summary, ret == IMPORTED_BEST)) + .publish(new Trace(format("Block chain size: [ %d ]", this.getSize()))); if (ret == IMPORTED_BEST) { eventDispatchThread.invokeLater(() -> pendingState.processBest(block, summary.getReceipts())); diff --git a/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java b/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java index 6a84974b1b..9bfa807235 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java @@ -25,9 +25,9 @@ import org.ethereum.db.TransactionStore; import org.ethereum.listener.EthereumListener.PendingTransactionState; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.PendingStateChangedEvent; -import org.ethereum.publish.event.PendingTransactionUpdatedEvent; -import org.ethereum.publish.event.PendingTransactionsReceivedEvent; +import org.ethereum.publish.event.PendingStateChanged; +import org.ethereum.publish.event.PendingTransactionUpdated; +import org.ethereum.publish.event.PendingTransactionsReceived; import org.ethereum.util.ByteUtil; import org.ethereum.util.FastByteComparisons; import org.ethereum.vm.program.invoke.ProgramInvokeFactory; @@ -166,8 +166,8 @@ public synchronized List addPendingTransactions(List t if (!newPending.isEmpty()) { this.publisher - .publish(new PendingTransactionsReceivedEvent(newPending)) - .publish(new PendingStateChangedEvent(PendingStateImpl.this)); + .publish(new PendingTransactionsReceived(newPending)) + .publish(new PendingStateChanged(PendingStateImpl.this)); } return newPending; @@ -197,7 +197,7 @@ state, toHexString(txReceipt.getTransaction().getSender()).substring(0, 8), ByteUtil.byteArrayToLong(txReceipt.getTransaction().getNonce()), block.getShortDescr(), txReceipt.getError())); } - publisher.publish(new PendingTransactionUpdatedEvent(block, txReceipt, state)); + publisher.publish(new PendingTransactionUpdated(block, txReceipt, state)); } /** @@ -316,7 +316,7 @@ public synchronized void processBest(Block newBlock, List re updateState(newBlock); - publisher.publish(new PendingStateChangedEvent(PendingStateImpl.this)); + publisher.publish(new PendingStateChanged(PendingStateImpl.this)); } private void processBestInternal(Block block, List receipts) { diff --git a/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java b/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java index 7bfb3185f6..4c1838b516 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java @@ -24,8 +24,8 @@ import org.ethereum.db.BlockStore; import org.ethereum.db.ContractDetails; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.TransactionExecutedEvent; -import org.ethereum.publish.event.VmTraceCreatedEvent; +import org.ethereum.publish.event.TransactionExecuted; +import org.ethereum.publish.event.VmTraceCreated; import org.ethereum.util.ByteArraySet; import org.ethereum.vm.DataWord; import org.ethereum.vm.LogInfo; @@ -454,7 +454,7 @@ public TransactionExecutionSummary finalization() { } - publisher.publish(new TransactionExecutedEvent(summary)); + publisher.publish(new TransactionExecuted(summary)); if (config.vmTrace() && program != null && result != null) { String trace = program.getTrace() @@ -469,7 +469,7 @@ public TransactionExecutionSummary finalization() { String txHash = toHexString(tx.getHash()); saveProgramTraceFile(config, txHash, trace); - publisher.publish(new VmTraceCreatedEvent(txHash, trace)); + publisher.publish(new VmTraceCreated(txHash, trace)); } return summary; } diff --git a/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java b/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java index 3848ed0470..d4c17f6754 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java @@ -26,7 +26,7 @@ import org.ethereum.datasource.Source; import org.ethereum.listener.EthereumListener; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.SyncDoneEvent; +import org.ethereum.publish.event.SyncDone; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -73,7 +73,7 @@ public DbFlushManager(SystemProperties config, Set dbSources, Abstract public void setPublisher(Publisher publisher) { if (!flushAfterSyncDone) return; - publisher.subscribe(SyncDoneEvent.class, state -> { + publisher.subscribe(SyncDone.class, state -> { if (state == EthereumListener.SyncState.COMPLETE) { logger.info("DbFlushManager: long sync done, flushing each block now"); syncDone = true; diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index 0d62d3fbdf..087d978f3d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -38,7 +38,7 @@ import org.ethereum.net.submit.TransactionTask; import org.ethereum.publish.Publisher; import org.ethereum.publish.Subscription; -import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.Event; import org.ethereum.sync.SyncManager; import org.ethereum.util.ByteUtil; @@ -122,7 +122,7 @@ public EthereumImpl(final SystemProperties config) { @PostConstruct public void init() { - publisher.subscribe(BlockAddedEvent.class, blockSummary -> { + publisher.subscribe(BlockAdded.class, blockSummary -> { blockSummary.getBlock().getTransactionsList().forEach(gasPriceTracker::onTransaction); }); } diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java index a791a05a60..f637c3f711 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java @@ -29,7 +29,7 @@ import org.ethereum.net.rlpx.discover.UDPListener; import org.ethereum.net.server.ChannelManager; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.BestBlockAddedEvent; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.Event; import org.ethereum.sync.FastSyncManager; import org.ethereum.sync.SyncManager; @@ -209,7 +209,7 @@ public void loadBlockchain() { blockchain.setTotalDifficulty(Genesis.getInstance(config).getDifficultyBI()); BlockSummary blockSummary = new BlockSummary(Genesis.getInstance(config), emptyMap(), emptyList(), emptyList()); - publisher.publish(new BestBlockAddedEvent(blockSummary, true)); + publisher.publish(new BestBlockAdded(blockSummary, true)); // repository.dumpState(Genesis.getInstance(config), 0, 0, null); logger.info("Genesis block loaded"); diff --git a/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java b/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java index 265086a210..ab011d93d5 100644 --- a/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java +++ b/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java @@ -29,8 +29,8 @@ import org.ethereum.facade.EthereumImpl; import org.ethereum.mine.MinerIfc.MiningResult; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.PendingStateChangedEvent; -import org.ethereum.publish.event.SyncDoneEvent; +import org.ethereum.publish.event.PendingStateChanged; +import org.ethereum.publish.event.SyncDone; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -98,8 +98,8 @@ public BlockMiner(final SystemProperties config, Publisher publisher, this.cpuThreads = config.getMineCpuThreads(); this.fullMining = config.isMineFullDataset(); this.publisher = publisher - .subscribe(to(PendingStateChangedEvent.class, ps -> onPendingStateChanged())) - .subscribe(to(SyncDoneEvent.class, s -> { + .subscribe(to(PendingStateChanged.class, ps -> onPendingStateChanged())) + .subscribe(to(SyncDone.class, s -> { if (config.minerStart() && config.isSyncEnabled()) { logger.info("Sync complete, start mining..."); startMining(); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java b/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java index f088fd2cff..aeae550582 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java @@ -26,8 +26,8 @@ import org.ethereum.net.p2p.PingMessage; import org.ethereum.net.server.Channel; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.TraceEvent; -import org.ethereum.publish.event.message.SentMessageEvent; +import org.ethereum.publish.event.Trace; +import org.ethereum.publish.event.message.MessageSent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -129,7 +129,7 @@ private void disconnect(DisconnectMessage msg) { public void receivedMessage(Message msg) throws InterruptedException { - publisher.publish(new TraceEvent("[Recv: " + msg + "]")); + publisher.publish(new Trace("[Recv: " + msg + "]")); if (requestQueue.peek() != null) { MessageRoundtrip messageRoundtrip = requestQueue.peek(); @@ -168,7 +168,7 @@ private void sendToWire(MessageRoundtrip messageRoundtrip) { Message msg = messageRoundtrip.getMsg(); - publisher.publish(new SentMessageEvent(channel, msg)); + publisher.publish(new MessageSent(channel, msg)); ctx.writeAndFlush(msg).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java b/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java index 72560f9d1c..fd3042d13a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java @@ -27,7 +27,7 @@ import org.ethereum.config.SystemProperties; import org.ethereum.net.server.EthereumChannelInitializer; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.TraceEvent; +import org.ethereum.publish.event.Trace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -103,7 +103,7 @@ public void connect(String host, int port, String remoteId, boolean discoveryMod } public ChannelFuture connectAsync(String host, int port, String remoteId, boolean discoveryMode) { - publisher.publish(new TraceEvent("Connecting to: " + host + ":" + port)); + publisher.publish(new Trace("Connecting to: " + host + ":" + port)); EthereumChannelInitializer ethereumChannelInitializer = ctx.getBean(EthereumChannelInitializer.class, remoteId); ethereumChannelInitializer.setPeerDiscoveryMode(discoveryMode); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java index 80f240b59d..38be67e886 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java @@ -31,7 +31,7 @@ import org.ethereum.net.submit.TransactionExecutor; import org.ethereum.net.submit.TransactionTask; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.message.EthStatusUpdatedEvent; +import org.ethereum.publish.event.message.EthStatusUpdated; import org.ethereum.sync.PeerState; import org.ethereum.sync.SyncManager; import org.ethereum.sync.SyncStatistics; @@ -340,7 +340,7 @@ protected synchronized void processStatus(StatusMessage msg, ChannelHandlerConte // basic checks passed, update statistics channel.getNodeStatistics().ethHandshake(msg); - getPublisher().publish(new EthStatusUpdatedEvent(channel, msg)); + getPublisher().publish(new EthStatusUpdated(channel, msg)); if (peerDiscoveryMode) { loggerNet.trace("Peer discovery mode: STATUS received, disconnecting..."); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java index 853246ab87..8d8aa25864 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java @@ -33,8 +33,8 @@ import org.ethereum.net.server.Channel; import org.ethereum.publish.Publisher; import org.ethereum.publish.Subscription; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.TraceEvent; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.Trace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,7 +66,7 @@ public abstract class EthHandler extends SimpleChannelInboundHandler protected Block bestBlock; protected boolean processTransactions = false; - private Subscription bestBlockSub; + private Subscription bestBlockSub; protected EthHandler(EthVersion version) { this.version = version; @@ -80,7 +80,7 @@ protected EthHandler(final EthVersion version, final SystemProperties config, this.blockchain = blockchain; this.bestBlock = blockStore.getBestBlock(); this.publisher = publisher; - this.bestBlockSub = publisher.subscribe(BlockAddedEvent.class, this::setBestBlock); + this.bestBlockSub = publisher.subscribe(BlockAdded.class, this::setBestBlock); // when sync enabled we delay transactions processing until sync is complete this.processTransactions = !config.isSyncEnabled(); @@ -96,7 +96,7 @@ public void channelRead0(final ChannelHandlerContext ctx, EthMessage msg) throws if (EthMessageCodes.inRange(msg.getCommand().asByte(), version)) logger.trace("EthHandler invoke: [{}]", msg.getCommand()); - publisher.publish(new TraceEvent(format("EthHandler invoke: [%s]", msg.getCommand()))); + publisher.publish(new Trace(format("EthHandler invoke: [%s]", msg.getCommand()))); channel.getNodeStatistics().ethInbound.add(); @@ -122,7 +122,7 @@ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { public void activate() { logger.debug("ETH protocol activated"); - publisher.publish(new TraceEvent("ETH protocol activated")); + publisher.publish(new Trace("ETH protocol activated")); sendStatus(); } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java index 366bd36236..0239d2d145 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java @@ -34,8 +34,8 @@ import org.ethereum.net.swarm.Util; import org.ethereum.net.swarm.bzz.BzzHandler; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.TraceEvent; -import org.ethereum.publish.event.message.PeerHandshakedEvent; +import org.ethereum.publish.event.Trace; +import org.ethereum.publish.event.message.PeerHandshaked; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -120,7 +120,7 @@ public void setPeerDiscoveryMode(boolean peerDiscoveryMode) { public void handlerAdded(ChannelHandlerContext ctx) throws Exception { logger.debug("P2P protocol activated"); msgQueue.activate(ctx); - publisher.publish(new TraceEvent("P2P protocol activated")); + publisher.publish(new Trace("P2P protocol activated")); startTimers(); } @@ -131,7 +131,7 @@ public void channelRead0(final ChannelHandlerContext ctx, P2pMessage msg) throws if (P2pMessageCodes.inRange(msg.getCommand().asByte())) logger.trace("P2PHandler invoke: [{}]", msg.getCommand()); - publisher.publish(new TraceEvent(format("P2PHandler invoke: [%s]", msg.getCommand()))); + publisher.publish(new Trace(format("P2PHandler invoke: [%s]", msg.getCommand()))); switch (msg.getCommand()) { case HELLO: @@ -243,7 +243,7 @@ public void setHandshake(HelloMessage msg, ChannelHandlerContext ctx) { } //todo calculate the Offsets - publisher.publish(new PeerHandshakedEvent(channel, msg)); + publisher.publish(new PeerHandshaked(channel, msg)); } /** diff --git a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java index 70adc14d95..82a61560d4 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java @@ -34,8 +34,8 @@ import org.ethereum.net.shh.ShhMessageCodes; import org.ethereum.net.swarm.bzz.BzzMessageCodes; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.TraceEvent; -import org.ethereum.publish.event.message.ReceivedMessageEvent; +import org.ethereum.publish.event.Trace; +import org.ethereum.publish.event.message.MessageReceived; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -168,7 +168,7 @@ private Message decodeMessage(ChannelHandlerContext ctx, List frames) thr return null; } - publisher.publish(new ReceivedMessageEvent(channel, msg)); + publisher.publish(new MessageReceived(channel, msg)); channel.getNodeStatistics().rlpxInMessages.add(); return msg; @@ -177,7 +177,7 @@ private Message decodeMessage(ChannelHandlerContext ctx, List frames) thr @Override protected void encode(ChannelHandlerContext ctx, Message msg, List out) throws Exception { String output = String.format("To: \t%s \tSend: \t%s", ctx.channel().remoteAddress(), msg); - publisher.publish(new TraceEvent(output)); + publisher.publish(new Trace(output)); if (loggerNet.isDebugEnabled()) loggerNet.debug("To: {} Send: {}", channel, msg); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java index a99d910cea..5a2a9d3524 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java @@ -24,7 +24,7 @@ import org.ethereum.net.rlpx.*; import org.ethereum.net.rlpx.discover.table.NodeTable; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.NodeDiscoveredEvent; +import org.ethereum.publish.event.NodeDiscovered; import org.ethereum.util.CollectionUtils; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -197,14 +197,14 @@ public synchronized NodeHandler getNodeHandler(Node n) { nodeHandlerMap.put(key, ret); logger.debug(" +++ New node: " + ret + " " + n); if (!n.isDiscoveryNode() && !n.getHexId().equals(homeNode.getHexId())) { - publisher.publish(new NodeDiscoveredEvent(ret.getNode())); + publisher.publish(new NodeDiscovered(ret.getNode())); } } else if (ret.getNode().isDiscoveryNode() && !n.isDiscoveryNode()) { // we found discovery node with same host:port, // replace node with correct nodeId ret.node = n; if (!n.getHexId().equals(homeNode.getHexId())) { - publisher.publish(new NodeDiscoveredEvent(ret.getNode())); + publisher.publish(new NodeDiscovered(ret.getNode())); } logger.debug(" +++ Found real nodeId for discovery endpoint {}", n); } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java b/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java index 489f4da57f..0ee707d0e9 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java @@ -27,7 +27,7 @@ import io.netty.handler.logging.LoggingHandler; import org.ethereum.config.SystemProperties; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.TraceEvent; +import org.ethereum.publish.event.Trace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -77,7 +77,7 @@ public void start(int port) { ethereumChannelInitializer = ctx.getBean(EthereumChannelInitializer.class, ""); - publisher.publish(new TraceEvent("Listening on port " + port)); + publisher.publish(new Trace("Listening on port " + port)); try { diff --git a/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java index 277b8349fa..3ad2dd88f0 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java @@ -21,7 +21,7 @@ import io.netty.channel.SimpleChannelInboundHandler; import org.ethereum.net.MessageQueue; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.TraceEvent; +import org.ethereum.publish.event.Trace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -66,11 +66,11 @@ public void channelRead0(final ChannelHandlerContext ctx, ShhMessage msg) throws if (ShhMessageCodes.inRange(msg.getCommand().asByte())) logger.info("ShhHandler invoke: [{}]", msg.getCommand()); - publisher.publish(new TraceEvent(format("ShhHandler invoke: [%s]", msg.getCommand()))); + publisher.publish(new Trace(format("ShhHandler invoke: [%s]", msg.getCommand()))); switch (msg.getCommand()) { case STATUS: - publisher.publish(new TraceEvent("[Recv: " + msg + "]")); + publisher.publish(new Trace("[Recv: " + msg + "]")); break; case MESSAGE: whisper.processEnvelope((ShhEnvelopeMessage) msg, this); @@ -104,7 +104,7 @@ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { public void activate() { logger.info("SHH protocol activated"); - publisher.publish(new TraceEvent("SHH protocol activated")); + publisher.publish(new Trace("SHH protocol activated")); whisper.addPeer(this); sendStatus(); sendHostBloom(); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java index 63d9d30ab6..6255be34f6 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java @@ -22,7 +22,7 @@ import org.ethereum.net.MessageQueue; import org.ethereum.net.swarm.NetStore; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.TraceEvent; +import org.ethereum.publish.event.Trace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -71,7 +71,7 @@ public void channelRead0(final ChannelHandlerContext ctx, BzzMessage msg) throws if (BzzMessageCodes.inRange(msg.getCommand().asByte())) logger.debug("BzzHandler invoke: [{}]", msg.getCommand()); - publisher.publish(new TraceEvent(format("BzzHandler invoke: [%s]", msg.getCommand()))); + publisher.publish(new Trace(format("BzzHandler invoke: [%s]", msg.getCommand()))); if (bzzProtocol != null) { bzzProtocol.accept(msg); @@ -98,7 +98,7 @@ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { public void activate() { logger.info("BZZ protocol activated"); - publisher.publish(new TraceEvent("BZZ protocol activated")); + publisher.publish(new Trace("BZZ protocol activated")); createBzzProtocol(); this.active = true; } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java index 9ab89541ea..8e3815db63 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java @@ -8,10 +8,10 @@ import org.ethereum.net.rlpx.Node; import org.ethereum.net.server.Channel; import org.ethereum.publish.event.*; -import org.ethereum.publish.event.message.EthStatusUpdatedEvent; -import org.ethereum.publish.event.message.PeerHandshakedEvent; -import org.ethereum.publish.event.message.ReceivedMessageEvent; -import org.ethereum.publish.event.message.SentMessageEvent; +import org.ethereum.publish.event.message.EthStatusUpdated; +import org.ethereum.publish.event.message.PeerHandshaked; +import org.ethereum.publish.event.message.MessageReceived; +import org.ethereum.publish.event.message.MessageSent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -210,23 +210,23 @@ public int subscribersCount() { */ public void subscribeListener(EthereumListener listener) { this - .subscribe(to(TraceEvent.class, listener::trace)) - .subscribe(to(NodeDiscoveredEvent.class, listener::onNodeDiscovered)) - .subscribe(to(PeerHandshakedEvent.class, data -> listener.onHandShakePeer(data.getChannel(), data.getMessage()))) - .subscribe(to(EthStatusUpdatedEvent.class, data -> listener.onEthStatusUpdated(data.getChannel(), data.getMessage()))) - .subscribe(to(ReceivedMessageEvent.class, data -> listener.onRecvMessage(data.getChannel(), data.getMessage()))) - .subscribe(to(SentMessageEvent.class, data -> listener.onSendMessage(data.getChannel(), data.getMessage()))) - .subscribe(to(BlockAddedEvent.class, listener::onBlock)) - .subscribe(to(BestBlockAddedEvent.class, data -> listener.onBlock(data.getBlockSummary(), data.isBest()))) - .subscribe(to(PeerDisconnectedEvent.class, data -> listener.onPeerDisconnect(data.getHost(), data.getPort()))) - .subscribe(to(PendingTransactionsReceivedEvent.class, listener::onPendingTransactionsReceived)) - .subscribe(to(PendingStateChangedEvent.class, listener::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdatedEvent.class, data -> listener.onPendingTransactionUpdate(data.getReceipt(), data.getState(), data.getBlock()))) - .subscribe(to(SyncDoneEvent.class, listener::onSyncDone)) - .subscribe(to(NoConnectionsEvent.class, data -> listener.onNoConnections())) - .subscribe(to(VmTraceCreatedEvent.class, data -> listener.onVMTraceCreated(data.getTxHash(), data.getTrace()))) - .subscribe(to(TransactionExecutedEvent.class, listener::onTransactionExecuted)) - .subscribe(to(PeerAddedToSyncPoolEvent.class, listener::onPeerAddedToSyncPool)); + .subscribe(to(Trace.class, listener::trace)) + .subscribe(to(NodeDiscovered.class, listener::onNodeDiscovered)) + .subscribe(to(PeerHandshaked.class, data -> listener.onHandShakePeer(data.getChannel(), data.getMessage()))) + .subscribe(to(EthStatusUpdated.class, data -> listener.onEthStatusUpdated(data.getChannel(), data.getMessage()))) + .subscribe(to(MessageReceived.class, data -> listener.onRecvMessage(data.getChannel(), data.getMessage()))) + .subscribe(to(MessageSent.class, data -> listener.onSendMessage(data.getChannel(), data.getMessage()))) + .subscribe(to(BlockAdded.class, listener::onBlock)) + .subscribe(to(BestBlockAdded.class, data -> listener.onBlock(data.getBlockSummary(), data.isBest()))) + .subscribe(to(PeerDisconnected.class, data -> listener.onPeerDisconnect(data.getHost(), data.getPort()))) + .subscribe(to(PendingTransactionsReceived.class, listener::onPendingTransactionsReceived)) + .subscribe(to(PendingStateChanged.class, listener::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdated.class, data -> listener.onPendingTransactionUpdate(data.getReceipt(), data.getState(), data.getBlock()))) + .subscribe(to(SyncDone.class, listener::onSyncDone)) + .subscribe(to(NoConnections.class, data -> listener.onNoConnections())) + .subscribe(to(VmTraceCreated.class, data -> listener.onVMTraceCreated(data.getTxHash(), data.getTrace()))) + .subscribe(to(TransactionExecuted.class, listener::onTransactionExecuted)) + .subscribe(to(PeerAddedToSyncPool.class, listener::onPeerAddedToSyncPool)); } /** @@ -239,87 +239,87 @@ public EthereumListener asListener() { return new EthereumListener() { @Override public void trace(String output) { - publish(new TraceEvent(output)); + publish(new Trace(output)); } @Override public void onNodeDiscovered(Node node) { - publish(new NodeDiscoveredEvent(node)); + publish(new NodeDiscovered(node)); } @Override public void onHandShakePeer(Channel channel, HelloMessage helloMessage) { - publish(new PeerHandshakedEvent(channel, helloMessage)); + publish(new PeerHandshaked(channel, helloMessage)); } @Override public void onEthStatusUpdated(Channel channel, StatusMessage status) { - publish(new EthStatusUpdatedEvent(channel, status)); + publish(new EthStatusUpdated(channel, status)); } @Override public void onRecvMessage(Channel channel, Message message) { - publish(new ReceivedMessageEvent(channel, message)); + publish(new MessageReceived(channel, message)); } @Override public void onSendMessage(Channel channel, Message message) { - publish(new SentMessageEvent(channel, message)); + publish(new MessageSent(channel, message)); } @Override public void onBlock(BlockSummary blockSummary) { - publish(new BlockAddedEvent(blockSummary)); + publish(new BlockAdded(blockSummary)); } @Override public void onBlock(BlockSummary blockSummary, boolean best) { - publish(new BestBlockAddedEvent(blockSummary, best)); + publish(new BestBlockAdded(blockSummary, best)); } @Override public void onPeerDisconnect(String host, long port) { - publish(new PeerDisconnectedEvent(host, port)); + publish(new PeerDisconnected(host, port)); } @Override public void onPendingTransactionsReceived(List transactions) { - publish(new PendingTransactionsReceivedEvent(transactions)); + publish(new PendingTransactionsReceived(transactions)); } @Override public void onPendingStateChanged(PendingState pendingState) { - publish(new PendingStateChangedEvent(pendingState)); + publish(new PendingStateChanged(pendingState)); } @Override public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionState state, Block block) { - publish(new PendingTransactionUpdatedEvent(block, txReceipt, state)); + publish(new PendingTransactionUpdated(block, txReceipt, state)); } @Override public void onSyncDone(SyncState state) { - publish(new SyncDoneEvent(state)); + publish(new SyncDone(state)); } @Override public void onNoConnections() { - publish(new NoConnectionsEvent()); + publish(new NoConnections()); } @Override public void onVMTraceCreated(String transactionHash, String trace) { - publish(new VmTraceCreatedEvent(transactionHash, trace)); + publish(new VmTraceCreated(transactionHash, trace)); } @Override public void onTransactionExecuted(TransactionExecutionSummary summary) { - publish(new TransactionExecutedEvent(summary)); + publish(new TransactionExecuted(summary)); } @Override public void onPeerAddedToSyncPool(Channel peer) { - publish(new PeerAddedToSyncPoolEvent(peer)); + publish(new PeerAddedToSyncPool(peer)); } }; } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/BestBlockAddedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/BestBlockAdded.java similarity index 79% rename from ethereumj-core/src/main/java/org/ethereum/publish/event/BestBlockAddedEvent.java rename to ethereumj-core/src/main/java/org/ethereum/publish/event/BestBlockAdded.java index cc6f558843..56818c181d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/BestBlockAddedEvent.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/BestBlockAdded.java @@ -2,7 +2,7 @@ import org.ethereum.core.BlockSummary; -public class BestBlockAddedEvent extends Event { +public class BestBlockAdded extends Event { public static class Data { private final BlockSummary blockSummary; @@ -22,7 +22,7 @@ public boolean isBest() { } } - public BestBlockAddedEvent(BlockSummary blockSummary, boolean best) { + public BestBlockAdded(BlockSummary blockSummary, boolean best) { super(new Data(blockSummary, best)); } } \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAddedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAdded.java similarity index 50% rename from ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAddedEvent.java rename to ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAdded.java index 5a5e761614..de4359009a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAddedEvent.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAdded.java @@ -2,9 +2,9 @@ import org.ethereum.core.BlockSummary; -public class BlockAddedEvent extends Event { +public class BlockAdded extends Event { - public BlockAddedEvent(BlockSummary data) { + public BlockAdded(BlockSummary data) { super(data); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnections.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnections.java new file mode 100644 index 0000000000..8ff9ca23e0 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnections.java @@ -0,0 +1,4 @@ +package org.ethereum.publish.event; + +public class NoConnections extends SignalEvent { +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnectionsEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnectionsEvent.java deleted file mode 100644 index 5a4c405793..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnectionsEvent.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.ethereum.publish.event; - -public class NoConnectionsEvent extends SignalEvent { -} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/NodeDiscoveredEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/NodeDiscovered.java similarity index 50% rename from ethereumj-core/src/main/java/org/ethereum/publish/event/NodeDiscoveredEvent.java rename to ethereumj-core/src/main/java/org/ethereum/publish/event/NodeDiscovered.java index 0f9b343265..9897904580 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/NodeDiscoveredEvent.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/NodeDiscovered.java @@ -2,8 +2,8 @@ import org.ethereum.net.rlpx.Node; -public class NodeDiscoveredEvent extends Event { - public NodeDiscoveredEvent(Node payload) { +public class NodeDiscovered extends Event { + public NodeDiscovered(Node payload) { super(payload); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPool.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPool.java new file mode 100644 index 0000000000..b0ba280e6c --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPool.java @@ -0,0 +1,10 @@ +package org.ethereum.publish.event; + +import org.ethereum.net.server.Channel; + +public class PeerAddedToSyncPool extends Event { + + public PeerAddedToSyncPool(Channel channel) { + super(channel); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPoolEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPoolEvent.java deleted file mode 100644 index 7433ffe300..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPoolEvent.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.ethereum.publish.event; - -import org.ethereum.net.server.Channel; - -public class PeerAddedToSyncPoolEvent extends Event { - - public PeerAddedToSyncPoolEvent(Channel channel) { - super(channel); - } -} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerDisconnectedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerDisconnected.java similarity index 76% rename from ethereumj-core/src/main/java/org/ethereum/publish/event/PeerDisconnectedEvent.java rename to ethereumj-core/src/main/java/org/ethereum/publish/event/PeerDisconnected.java index 6ae4ea433b..36436785e4 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerDisconnectedEvent.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerDisconnected.java @@ -1,6 +1,6 @@ package org.ethereum.publish.event; -public class PeerDisconnectedEvent extends Event { +public class PeerDisconnected extends Event { public static class Data { private final String host; @@ -20,7 +20,7 @@ public long getPort() { } } - public PeerDisconnectedEvent(String host, long port) { + public PeerDisconnected(String host, long port) { super(new Data(host, port)); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingStateChangedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingStateChanged.java similarity index 79% rename from ethereumj-core/src/main/java/org/ethereum/publish/event/PendingStateChangedEvent.java rename to ethereumj-core/src/main/java/org/ethereum/publish/event/PendingStateChanged.java index 8e188d44e5..c8e713305e 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingStateChangedEvent.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingStateChanged.java @@ -10,8 +10,8 @@ * * @author Eugene Shevchenko */ -public class PendingStateChangedEvent extends Event { - public PendingStateChangedEvent(PendingState state) { +public class PendingStateChanged extends Event { + public PendingStateChanged(PendingState state) { super(state); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdatedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdated.java similarity index 85% rename from ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdatedEvent.java rename to ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdated.java index 1b3cb428ac..6bb799a18b 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdatedEvent.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdated.java @@ -9,7 +9,7 @@ * * @author Eugene Shevchenko */ -public class PendingTransactionUpdatedEvent extends Event { +public class PendingTransactionUpdated extends Event { /** * Event DTO @@ -44,7 +44,7 @@ public Block getBlock() { } } - public PendingTransactionUpdatedEvent(Block block, TransactionReceipt receipt, EthereumListener.PendingTransactionState state) { + public PendingTransactionUpdated(Block block, TransactionReceipt receipt, EthereumListener.PendingTransactionState state) { super(new Data(block, receipt, state)); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceived.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceived.java new file mode 100644 index 0000000000..112048cc82 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceived.java @@ -0,0 +1,17 @@ +package org.ethereum.publish.event; + +import org.ethereum.core.Transaction; + +import java.util.List; + +/** + * @author Eugene Shevchenko + * @deprecated use PendingTransactionUpdated filtering state NEW_PENDING + * Will be removed in the next release + */ +public class PendingTransactionsReceived extends Event> { + + public PendingTransactionsReceived(List transactions) { + super(transactions); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceivedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceivedEvent.java deleted file mode 100644 index 37c64cb0f1..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceivedEvent.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.ethereum.publish.event; - -import org.ethereum.core.Transaction; - -import java.util.List; - -/** - * @author Eugene Shevchenko - * @deprecated use PendingTransactionUpdatedEvent filtering state NEW_PENDING - * Will be removed in the next release - */ -public class PendingTransactionsReceivedEvent extends Event> { - - public PendingTransactionsReceivedEvent(List transactions) { - super(transactions); - } -} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java new file mode 100644 index 0000000000..2016edd6ac --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java @@ -0,0 +1,10 @@ +package org.ethereum.publish.event; + +import org.ethereum.listener.EthereumListener; + +public class SyncDone extends Event implements Single { + + public SyncDone(EthereumListener.SyncState payload) { + super(payload); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDoneEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDoneEvent.java deleted file mode 100644 index c49cf19c2c..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDoneEvent.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.ethereum.publish.event; - -import org.ethereum.listener.EthereumListener; - -public class SyncDoneEvent extends Event implements Single { - - public SyncDoneEvent(EthereumListener.SyncState payload) { - super(payload); - } -} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/Trace.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/Trace.java new file mode 100644 index 0000000000..0860d5c14b --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/Trace.java @@ -0,0 +1,8 @@ +package org.ethereum.publish.event; + +public class Trace extends Event { + + public Trace(String trace) { + super(trace); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/TraceEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/TraceEvent.java deleted file mode 100644 index 0320189b46..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/TraceEvent.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.ethereum.publish.event; - -public class TraceEvent extends Event { - - public TraceEvent(String trace) { - super(trace); - } -} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecuted.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecuted.java new file mode 100644 index 0000000000..d9f2e13494 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecuted.java @@ -0,0 +1,9 @@ +package org.ethereum.publish.event; + +import org.ethereum.core.TransactionExecutionSummary; + +public class TransactionExecuted extends Event { + public TransactionExecuted(TransactionExecutionSummary executionSummary) { + super(executionSummary); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecutedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecutedEvent.java deleted file mode 100644 index 675e14410d..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecutedEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.ethereum.publish.event; - -import org.ethereum.core.TransactionExecutionSummary; - -public class TransactionExecutedEvent extends Event { - public TransactionExecutedEvent(TransactionExecutionSummary executionSummary) { - super(executionSummary); - } -} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/VmTraceCreatedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/VmTraceCreated.java similarity index 77% rename from ethereumj-core/src/main/java/org/ethereum/publish/event/VmTraceCreatedEvent.java rename to ethereumj-core/src/main/java/org/ethereum/publish/event/VmTraceCreated.java index ca83a06fb9..e8b7094321 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/VmTraceCreatedEvent.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/VmTraceCreated.java @@ -1,6 +1,6 @@ package org.ethereum.publish.event; -public class VmTraceCreatedEvent extends Event { +public class VmTraceCreated extends Event { public static class Data { private final String txHash; @@ -20,7 +20,7 @@ public String getTrace() { } } - public VmTraceCreatedEvent(String txHash, String trace) { + public VmTraceCreated(String txHash, String trace) { super(new Data(txHash, trace)); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/EthStatusUpdatedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/EthStatusUpdated.java similarity index 69% rename from ethereumj-core/src/main/java/org/ethereum/publish/event/message/EthStatusUpdatedEvent.java rename to ethereumj-core/src/main/java/org/ethereum/publish/event/message/EthStatusUpdated.java index 476b3988ca..04964fa3e9 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/EthStatusUpdatedEvent.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/EthStatusUpdated.java @@ -3,7 +3,7 @@ import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.server.Channel; -public class EthStatusUpdatedEvent extends AbstractMessageEvent { +public class EthStatusUpdated extends AbstractMessageEvent { public static class Data extends AbstractMessageEvent.Data { @@ -13,7 +13,7 @@ public Data(Channel channel, StatusMessage message) { } - public EthStatusUpdatedEvent(Channel channel, StatusMessage message) { + public EthStatusUpdated(Channel channel, StatusMessage message) { super(new Data(channel, message)); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/SentMessageEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/MessageReceived.java similarity index 52% rename from ethereumj-core/src/main/java/org/ethereum/publish/event/message/SentMessageEvent.java rename to ethereumj-core/src/main/java/org/ethereum/publish/event/message/MessageReceived.java index 88b2591d58..e0fab5eb51 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/SentMessageEvent.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/MessageReceived.java @@ -3,9 +3,9 @@ import org.ethereum.net.message.Message; import org.ethereum.net.server.Channel; -public class SentMessageEvent extends AbstractMessageEvent> { +public class MessageReceived extends AbstractMessageEvent> { - public SentMessageEvent(Channel channel, Message message) { + public MessageReceived(Channel channel, Message message) { super(new Data(channel, message)); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/ReceivedMessageEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/MessageSent.java similarity index 51% rename from ethereumj-core/src/main/java/org/ethereum/publish/event/message/ReceivedMessageEvent.java rename to ethereumj-core/src/main/java/org/ethereum/publish/event/message/MessageSent.java index 1734ff8d42..3c7ec54d15 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/ReceivedMessageEvent.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/MessageSent.java @@ -3,9 +3,9 @@ import org.ethereum.net.message.Message; import org.ethereum.net.server.Channel; -public class ReceivedMessageEvent extends AbstractMessageEvent> { +public class MessageSent extends AbstractMessageEvent> { - public ReceivedMessageEvent(Channel channel, Message message) { + public MessageSent(Channel channel, Message message) { super(new Data(channel, message)); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/PeerHandshakedEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/PeerHandshaked.java similarity index 69% rename from ethereumj-core/src/main/java/org/ethereum/publish/event/message/PeerHandshakedEvent.java rename to ethereumj-core/src/main/java/org/ethereum/publish/event/message/PeerHandshaked.java index a1802986e4..308d967a55 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/PeerHandshakedEvent.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/PeerHandshaked.java @@ -3,7 +3,7 @@ import org.ethereum.net.p2p.HelloMessage; import org.ethereum.net.server.Channel; -public class PeerHandshakedEvent extends AbstractMessageEvent { +public class PeerHandshaked extends AbstractMessageEvent { public static class Data extends AbstractMessageEvent.Data { @@ -13,7 +13,7 @@ public Data(Channel channel, HelloMessage message) { } - public PeerHandshakedEvent(Channel channel, HelloMessage message) { + public PeerHandshaked(Channel channel, HelloMessage message) { super(new Data(channel, message)); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java index 4eb4e1b443..7f06bf8b97 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java @@ -30,11 +30,11 @@ import org.ethereum.facade.EthereumFactory; import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.NodeDiscoveredEvent; -import org.ethereum.publish.event.PeerAddedToSyncPoolEvent; -import org.ethereum.publish.event.SyncDoneEvent; -import org.ethereum.publish.event.message.EthStatusUpdatedEvent; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.NodeDiscovered; +import org.ethereum.publish.event.PeerAddedToSyncPool; +import org.ethereum.publish.event.SyncDone; +import org.ethereum.publish.event.message.EthStatusUpdated; import org.ethereum.util.ByteUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -135,12 +135,12 @@ private void springInit() { // adding the main EthereumJ callback to be notified on different kind of events this.ethereum - .subscribe(to(SyncDoneEvent.class, syncState -> synced = true)) - .subscribe(to(NodeDiscoveredEvent.class, nodesDiscovered::add) + .subscribe(to(SyncDone.class, syncState -> synced = true)) + .subscribe(to(NodeDiscovered.class, nodesDiscovered::add) .conditionally(node -> nodesDiscovered.size() < 1000)) - .subscribe(to(EthStatusUpdatedEvent.class, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage()))) - .subscribe(to(PeerAddedToSyncPoolEvent.class, peer -> syncPeers.add(peer.getNode()))) - .subscribe(to(BlockAddedEvent.class, bs -> { + .subscribe(to(EthStatusUpdated.class, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage()))) + .subscribe(to(PeerAddedToSyncPool.class, peer -> syncPeers.add(peer.getNode()))) + .subscribe(to(BlockAdded.class, bs -> { Block block = bs.getBlock(); List receipts = bs.getReceipts(); diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java index acdf7356b4..582fbf2097 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java @@ -24,7 +24,7 @@ import org.ethereum.crypto.ECKey; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.solidity.compiler.CompilationResult; import org.ethereum.solidity.compiler.SolidityCompiler; import org.ethereum.util.ByteUtil; @@ -65,7 +65,7 @@ public class CreateContractSample extends TestNetSample { @Override public void onSyncDone() throws Exception { // when block arrives look for our included transactions - ethereum.subscribe(to(BlockAddedEvent.class, this::onBlock)); + ethereum.subscribe(to(BlockAdded.class, this::onBlock)); logger.info("Compiling contract..."); SolidityCompiler.Result result = compiler.compileSrc(contract.getBytes(), true, true, diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java index b0aa19cc7d..22cecd4fba 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java @@ -27,8 +27,8 @@ import org.ethereum.listener.EthereumListener; import org.ethereum.listener.EventListener; import org.ethereum.listener.TxStatus; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.PendingTransactionUpdatedEvent; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.PendingTransactionUpdated; import org.ethereum.solidity.compiler.CompilationResult; import org.ethereum.solidity.compiler.SolidityCompiler; import org.ethereum.util.ByteUtil; @@ -202,7 +202,7 @@ protected boolean pendingTransactionUpdated(PendingEvent evt) { */ @Override public void onSyncDone() throws Exception { - ethereum.subscribe(to(PendingTransactionUpdatedEvent.class, data -> { + ethereum.subscribe(to(PendingTransactionUpdated.class, data -> { TransactionReceipt txReceipt = data.getReceipt(); ByteArrayWrapper txHashW = new ByteArrayWrapper(txReceipt.getTransaction().getHash()); // Catching transaction errors @@ -284,7 +284,7 @@ private void waitForEther(byte[] address, BigInteger requiredBalance) throws Int */ private void deployContractAndTest() throws Exception { // when block arrives look for our included transactions - ethereum.subscribe(to(BlockAddedEvent.class, this::onBlock)); + ethereum.subscribe(to(BlockAdded.class, this::onBlock)); CompilationResult.ContractMetadata metadata = compileContract(); diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java b/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java index c24bc3396c..8bb30bcf40 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java @@ -21,7 +21,7 @@ import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; import org.ethereum.facade.Repository; -import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.BlockAdded; import org.spongycastle.util.encoders.Hex; import java.math.BigInteger; @@ -32,7 +32,7 @@ public class FollowAccount { public static void main(String[] args) { Ethereum ethereum = EthereumFactory.createEthereum(); - ethereum.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereum.subscribe(to(BlockAdded.class, blockSummary -> { byte[] cow = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826"); // Get snapshot some time ago - 10% blocks ago diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java index 18647abb3c..e85b65d0e1 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java @@ -21,8 +21,8 @@ import org.ethereum.crypto.ECKey; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.PendingTransactionsReceivedEvent; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.PendingTransactionsReceived; import org.ethereum.util.ByteUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -65,9 +65,9 @@ public class PendingStateSample extends TestNetSample { public void onSyncDone() { this.ethereum // listening here when the PendingState is updated with new transactions - .subscribe(to(PendingTransactionsReceivedEvent.class, txs -> txs.forEach(this::onPendingTransactionReceived))) + .subscribe(to(PendingTransactionsReceived.class, txs -> txs.forEach(this::onPendingTransactionReceived))) // when block arrives look for our included transactions - .subscribe(to(BlockAddedEvent.class, this::onBlock)); + .subscribe(to(BlockAdded.class, this::onBlock)); new Thread(() -> { try { diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java b/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java index fc30d53e42..356f10b135 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java @@ -24,7 +24,7 @@ import org.ethereum.crypto.HashUtil; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.util.ByteUtil; import org.ethereum.util.blockchain.EtherUtil; import org.spongycastle.util.encoders.Hex; @@ -51,7 +51,7 @@ public class SendTransaction extends BasicSample { @Override public void onSyncDone() throws Exception { // when block arrives look for our included transactions - this.ethereum.subscribe(to(BlockAddedEvent.class, this::onBlock)); + this.ethereum.subscribe(to(BlockAdded.class, this::onBlock)); String toAddress = ""; logger.info("Sending transaction to net and waiting for inclusion"); diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java b/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java index 406fd72c12..04b0de45ec 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java @@ -22,8 +22,8 @@ import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; import org.ethereum.listener.EthereumListener; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.SyncDoneEvent; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.SyncDone; import org.spongycastle.util.encoders.Hex; import java.util.Collections; @@ -42,8 +42,8 @@ public class TransactionBomb { public TransactionBomb(Ethereum ethereum) { this.ethereum = ethereum; this.ethereum - .subscribe(to(SyncDoneEvent.class, this::onSyncDone)) - .subscribe(to(BlockAddedEvent.class, this::onBlock)); + .subscribe(to(SyncDone.class, this::onSyncDone)) + .subscribe(to(BlockAdded.class, this::onBlock)); } public static void main(String[] args) { diff --git a/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java b/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java index ea207ff728..dc669786bb 100644 --- a/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java @@ -38,7 +38,7 @@ import org.ethereum.net.message.ReasonCode; import org.ethereum.net.server.Channel; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.SyncDoneEvent; +import org.ethereum.publish.event.SyncDone; import org.ethereum.trie.TrieKey; import org.ethereum.util.*; import org.slf4j.Logger; @@ -560,7 +560,7 @@ private void syncUnsecure(BlockHeader pivot) { logger.info("FastSync: proceeding to regular sync..."); final CountDownLatch syncDoneLatch = new CountDownLatch(1); - publisher.subscribe(SyncDoneEvent.class, syncState -> syncDoneLatch.countDown()); + publisher.subscribe(SyncDone.class, syncState -> syncDoneLatch.countDown()); syncManager.initRegularSync(UNSECURE); logger.info("FastSync: waiting for regular sync to reach the blockchain head..."); @@ -755,7 +755,7 @@ private void fireSyncDone(EthereumListener.SyncState state) { syncManager.setSyncDoneType(state); if (syncManager.isSyncDone()) { // listener.onSyncDone(state); - publisher.publish(new SyncDoneEvent(state)); + publisher.publish(new SyncDone(state)); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java b/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java index 3305fa97fb..6f1201a9a0 100644 --- a/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java @@ -24,7 +24,7 @@ import org.ethereum.net.server.Channel; import org.ethereum.net.server.ChannelManager; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.SyncDoneEvent; +import org.ethereum.publish.event.SyncDone; import org.ethereum.util.ExecutorPipeline; import org.ethereum.validator.BlockHeaderValidator; import org.slf4j.Logger; @@ -341,7 +341,7 @@ private synchronized void makeSyncDone() { if (syncDone) return; syncDone = true; channelManager.onSyncDone(true); - publisher.publish(new SyncDoneEvent(syncDoneType)); + publisher.publish(new SyncDone(syncDoneType)); } public CompletableFuture switchToShortSync() { diff --git a/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java b/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java index 9f9f0ce722..22d91a021c 100644 --- a/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java +++ b/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java @@ -19,7 +19,6 @@ import org.ethereum.config.SystemProperties; import org.ethereum.core.Blockchain; -import org.ethereum.listener.EthereumListener; import org.ethereum.net.message.ReasonCode; import org.ethereum.net.rlpx.Node; import org.ethereum.net.rlpx.discover.NodeHandler; @@ -27,7 +26,7 @@ import org.ethereum.net.server.Channel; import org.ethereum.net.server.ChannelManager; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.PeerAddedToSyncPoolEvent; +import org.ethereum.publish.event.PeerAddedToSyncPool; import org.ethereum.util.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -341,7 +340,7 @@ private synchronized void prepareActive() { for (Channel channel : filtered) { if (!activePeers.contains(channel)) { - publisher.publish(new PeerAddedToSyncPoolEvent(channel)); + publisher.publish(new PeerAddedToSyncPool(channel)); } } if (logger.isTraceEnabled()) diff --git a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java index 8c09aaa691..7e4039e969 100644 --- a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java @@ -34,7 +34,7 @@ import org.ethereum.mine.Ethash; import org.ethereum.publish.Publisher; import org.ethereum.publish.Subscription; -import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.Event; import org.ethereum.solidity.compiler.CompilationResult; import org.ethereum.solidity.compiler.CompilationResult.ContractMetadata; @@ -438,7 +438,7 @@ public BlockchainImpl getBlockchain() { if (blockchain == null) { blockchain = createBlockchain(genesis); blockchain.setMinerCoinbase(coinbase); - subscribe(BlockAddedEvent.class, blockSummary -> lastSummary = blockSummary); + subscribe(BlockAdded.class, blockSummary -> lastSummary = blockSummary); } return blockchain; } diff --git a/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java b/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java index a77e80c891..824342004a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java +++ b/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java @@ -22,8 +22,8 @@ import org.ethereum.core.BlockHeader; import org.ethereum.mine.EthashValidationHelper; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.BestBlockAddedEvent; -import org.ethereum.publish.event.SyncDoneEvent; +import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.SyncDone; import org.ethereum.util.FastByteComparisons; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -115,8 +115,8 @@ public EthashRule(Mode mode, ChainType chain, Publisher publisher) { if (this.chain == main && publisher != null) { publisher - .subscribe(to(SyncDoneEvent.class, ss -> EthashRule.this.syncDone = true)) - .subscribe(to(BestBlockAddedEvent.class, data -> { + .subscribe(to(SyncDone.class, ss -> EthashRule.this.syncDone = true)) + .subscribe(to(BestBlockAdded.class, data -> { if (data.isBest()) { ethashHelper.preCache(data.getBlockSummary().getBlock().getNumber()); } diff --git a/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java b/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java index 94be8ffd5a..5034482271 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java @@ -19,7 +19,7 @@ import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.BlockAddedEvent; +import org.ethereum.publish.event.BlockAdded; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; @@ -44,7 +44,7 @@ public void relaunchTest() throws InterruptedException { Assert.assertNotNull(bestBlock); final CountDownLatch latch = new CountDownLatch(1); AtomicInteger counter = new AtomicInteger(); - ethereum.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereum.subscribe(to(BlockAdded.class, blockSummary -> { if (counter.addAndGet(1) > 1100) { latch.countDown(); } diff --git a/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java b/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java index 24131652b8..1e798386a2 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java @@ -28,7 +28,7 @@ import org.ethereum.db.RepositoryRoot; import org.ethereum.mine.Ethash; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.TransactionExecutedEvent; +import org.ethereum.publish.event.TransactionExecuted; import org.ethereum.util.ByteUtil; import org.ethereum.util.blockchain.SolidityContract; import org.ethereum.util.blockchain.StandaloneBlockchain; @@ -772,7 +772,7 @@ public void suicideInFailedCall() throws Exception { SolidityContract a = bc.submitNewContract(contractA, "A"); bc.createBlock(); final BigInteger[] refund = new BigInteger[1]; - bc.subscribe(TransactionExecutedEvent.class, tes -> refund[0] = tes.getGasRefund()); + bc.subscribe(TransactionExecuted.class, tes -> refund[0] = tes.getGasRefund()); a.callFunction("f"); bc.createBlock(); @@ -800,7 +800,7 @@ public void logInFailedCall() throws Exception { SolidityContract a = bc.submitNewContract(contractA, "A"); bc.createBlock(); final List logs = new ArrayList<>(); - bc.subscribe(TransactionExecutedEvent.class, tes -> logs.addAll(tes.getLogs())); + bc.subscribe(TransactionExecuted.class, tes -> logs.addAll(tes.getLogs())); a.callFunction("f"); bc.createBlock(); diff --git a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java index e785862194..3667cc1a67 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java @@ -23,9 +23,9 @@ import org.ethereum.crypto.ECKey; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.listener.EthereumListener; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.PendingStateChangedEvent; -import org.ethereum.publish.event.PendingTransactionUpdatedEvent; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.PendingStateChanged; +import org.ethereum.publish.event.PendingTransactionUpdated; import org.ethereum.util.blockchain.SolidityContract; import org.ethereum.util.blockchain.StandaloneBlockchain; import org.junit.AfterClass; @@ -84,7 +84,7 @@ public void onPendingStateChanged(PendingState pendingState) { onPendingStateChanged.add(new Object()); } - public void onPendingTransactionUpdate(PendingTransactionUpdatedEvent.Data data) { + public void onPendingTransactionUpdate(PendingTransactionUpdated.Data data) { onPendingTransactionUpdate(data.getReceipt(), data.getState(), data.getBlock()); } @@ -117,9 +117,9 @@ public Triple txUpd; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -192,9 +192,9 @@ public void testSimple() throws InterruptedException { public void testRebranch1() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAddedEvent.class, l::onBlock)) - .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + .subscribe(to(BlockAdded.class, l::onBlock)) + .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -261,9 +261,9 @@ public void testRebranch1() throws InterruptedException { public void testRebranch2() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAddedEvent.class, l::onBlock)) - .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + .subscribe(to(BlockAdded.class, l::onBlock)) + .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -351,9 +351,9 @@ public void testRebranch2() throws InterruptedException { public void testRebranch3() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAddedEvent.class, l::onBlock)) - .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + .subscribe(to(BlockAdded.class, l::onBlock)) + .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -403,9 +403,9 @@ public void testRebranch3() throws InterruptedException { public void testOldBlockIncluded() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAddedEvent.class, l::onBlock)) - .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + .subscribe(to(BlockAdded.class, l::onBlock)) + .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -441,9 +441,9 @@ public void testOldBlockIncluded() throws InterruptedException { public void testBlockOnlyIncluded() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAddedEvent.class, l::onBlock)) - .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + .subscribe(to(BlockAdded.class, l::onBlock)) + .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -470,9 +470,9 @@ public void testBlockOnlyIncluded() throws InterruptedException { public void testTrackTx1() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAddedEvent.class, l::onBlock)) - .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + .subscribe(to(BlockAdded.class, l::onBlock)) + .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -524,9 +524,9 @@ public void testPrevBlock() throws InterruptedException { PendingListener l = new PendingListener(); bc - .subscribe(to(BlockAddedEvent.class, l::onBlock)) - .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + .subscribe(to(BlockAdded.class, l::onBlock)) + .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); Triple txUpd; @@ -541,9 +541,9 @@ public void testPrevBlock() throws InterruptedException { public void testTrackTx2() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAddedEvent.class, l::onBlock)) - .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + .subscribe(to(BlockAdded.class, l::onBlock)) + .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -574,9 +574,9 @@ public void testTrackTx2() throws InterruptedException { public void testRejected1() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAddedEvent.class, l::onBlock)) - .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + .subscribe(to(BlockAdded.class, l::onBlock)) + .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -623,9 +623,9 @@ public void testIncludedRejected() throws InterruptedException { // the transaction becomes the main chain PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAddedEvent.class, l::onBlock)) - .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + .subscribe(to(BlockAdded.class, l::onBlock)) + .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); @@ -677,9 +677,9 @@ public void onPendingTransactionUpdate(TransactionReceipt txReceipt, EthereumLis }; StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAddedEvent.class, l::onBlock)) - .subscribe(to(PendingStateChangedEvent.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdatedEvent.class, l::onPendingTransactionUpdate)); + .subscribe(to(BlockAdded.class, l::onBlock)) + .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) + .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); diff --git a/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java b/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java index 5c65f937c6..3329f330ca 100644 --- a/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java +++ b/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java @@ -28,10 +28,10 @@ import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.rlpx.Node; import org.ethereum.net.server.Channel; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.PeerAddedToSyncPoolEvent; -import org.ethereum.publish.event.SyncDoneEvent; -import org.ethereum.publish.event.message.EthStatusUpdatedEvent; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.PeerAddedToSyncPool; +import org.ethereum.publish.event.SyncDone; +import org.ethereum.publish.event.message.EthStatusUpdated; import org.ethereum.sync.SyncPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -108,10 +108,10 @@ private void springInit() { logger = LoggerFactory.getLogger(loggerName); // adding the main EthereumJ callback to be notified on different kind of events this.ethereum - .subscribe(to(SyncDoneEvent.class, this::onSyncDone)) - .subscribe(to(BlockAddedEvent.class, this::onBlock)) - .subscribe(to(EthStatusUpdatedEvent.class, this::onEthStatusUpdated)) - .subscribe(to(PeerAddedToSyncPoolEvent.class, this::onPeerAddedToSyncPool)); + .subscribe(to(SyncDone.class, this::onSyncDone)) + .subscribe(to(BlockAdded.class, this::onBlock)) + .subscribe(to(EthStatusUpdated.class, this::onEthStatusUpdated)) + .subscribe(to(PeerAddedToSyncPool.class, this::onPeerAddedToSyncPool)); logger.info("Sample component created. Listening for ethereum events..."); @@ -184,7 +184,7 @@ public void onSyncDone(EthereumListener.SyncState state) { onSyncDoneImpl(state); } - public void onEthStatusUpdated(EthStatusUpdatedEvent.Data data) { + public void onEthStatusUpdated(EthStatusUpdated.Data data) { ethNodes.put(data.getChannel().getNode(), data.getMessage()); } diff --git a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java index 74e349d391..53beb794ca 100644 --- a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java @@ -26,8 +26,8 @@ import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.PendingTransactionsReceivedEvent; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.PendingTransactionsReceived; import org.ethereum.sync.SyncManager; import org.ethereum.util.FastByteComparisons; import org.ethereum.vm.program.invoke.ProgramInvokeFactory; @@ -221,8 +221,8 @@ public RegularNode() { public void run() { try { this.ethereum - .subscribe(to(BlockAddedEvent.class, this::onBlock)) - .subscribe(to(PendingTransactionsReceivedEvent.class, this::onPendingTransactionsReceived)); + .subscribe(to(BlockAdded.class, this::onBlock)) + .subscribe(to(PendingTransactionsReceived.class, this::onPendingTransactionsReceived)); // Run 1-30 minutes Random generator = new Random(); diff --git a/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java b/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java index 2ea492d938..f1340685bb 100644 --- a/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java @@ -30,9 +30,9 @@ import org.ethereum.facade.EthereumFactory; import org.ethereum.net.eth.handler.Eth62; import org.ethereum.net.eth.message.NewBlockMessage; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.PendingTransactionsReceivedEvent; -import org.ethereum.publish.event.SyncDoneEvent; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.PendingTransactionsReceived; +import org.ethereum.publish.event.SyncDone; import org.ethereum.util.ByteUtil; import org.junit.BeforeClass; import org.junit.Ignore; @@ -107,7 +107,7 @@ public void startMiningConsumer() throws Exception { Ethereum ethereum2 = EthereumFactory.createEthereum(SysPropConfig2.props, SysPropConfig2.class); final CountDownLatch semaphore = new CountDownLatch(1); - ethereum2.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereum2.subscribe(to(BlockAdded.class, blockSummary -> { Block block = blockSummary.getBlock(); System.err.println("=== New block: " + blockInfo(block)); System.err.println(block); @@ -131,8 +131,8 @@ public void startMiningConsumer() throws Exception { // } })) - .subscribe(to(PendingTransactionsReceivedEvent.class, transactions -> System.err.println("=== Tx: " + transactions))) - .subscribe(to(SyncDoneEvent.class, syncState -> { + .subscribe(to(PendingTransactionsReceived.class, transactions -> System.err.println("=== Tx: " + transactions))) + .subscribe(to(SyncDone.class, syncState -> { semaphore.countDown(); System.err.println("=== Sync Done!"); })); @@ -205,8 +205,8 @@ public void startMiningTest() throws FileNotFoundException, InterruptedException final CountDownLatch semaphore = new CountDownLatch(1); ethereum1 - .subscribe(to(BlockAddedEvent.class, blockSummary -> System.out.println("=== New block: " + blockInfo(blockSummary.getBlock())))) - .subscribe(to(SyncDoneEvent.class, syncState -> semaphore.countDown())); + .subscribe(to(BlockAdded.class, blockSummary -> System.out.println("=== New block: " + blockInfo(blockSummary.getBlock())))) + .subscribe(to(SyncDone.class, syncState -> semaphore.countDown())); // ethereum2.addListener(new EthereumListenerAdapter() { // @Override diff --git a/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java b/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java index b323eafc9d..1ef39e0d63 100644 --- a/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java @@ -28,8 +28,8 @@ import org.ethereum.facade.SyncStatus; import org.ethereum.net.eth.handler.Eth62; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.PeerAddedToSyncPoolEvent; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.PeerAddedToSyncPool; import org.ethereum.util.FastByteComparisons; import org.ethereum.util.blockchain.EtherUtil; import org.ethereum.util.blockchain.StandaloneBlockchain; @@ -161,7 +161,7 @@ public void test1() throws InterruptedException { assertTrue(loadedBlocks > 0); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAddedEvent.class, bs -> semaphore.countDown()) + ethereumB.subscribe(to(BlockAdded.class, bs -> semaphore.countDown()) .conditionally(bs -> isBlockNumber(bs, loadedBlocks))); semaphore.await(MAX_SECONDS_WAIT, SECONDS); @@ -171,14 +171,14 @@ public void test1() throws InterruptedException { ethereumA.getBlockMiner().startMining(); final CountDownLatch semaphore2 = new CountDownLatch(2); - ethereumB.subscribe(to(BlockAddedEvent.class, bs -> { + ethereumB.subscribe(to(BlockAdded.class, bs -> { if (isBlockNumber(bs, loadedBlocks + 2)) { semaphore2.countDown(); ethereumA.getBlockMiner().stopMining(); } })); - ethereumA.subscribe(to(BlockAddedEvent.class, bs -> semaphore2.countDown()) + ethereumA.subscribe(to(BlockAdded.class, bs -> semaphore2.countDown()) .conditionally(bs -> isBlockNumber(bs, loadedBlocks + 2))); semaphore2.await(MAX_SECONDS_WAIT, SECONDS); @@ -200,7 +200,7 @@ public void test1() throws InterruptedException { ); tx.sign(sender); final CountDownLatch txSemaphore = new CountDownLatch(1); - ethereumA.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereumA.subscribe(to(BlockAdded.class, blockSummary -> { if (!blockSummary.getBlock().getTransactionsList().isEmpty() && FastByteComparisons.equal(blockSummary.getBlock().getTransactionsList().get(0).getSender(), sender.getAddress()) && @@ -212,10 +212,10 @@ public void test1() throws InterruptedException { ethereumB.submitTransaction(tx); final CountDownLatch semaphore3 = new CountDownLatch(2); - ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> semaphore3.countDown()) + ethereumB.subscribe(to(BlockAdded.class, blockSummary -> semaphore3.countDown()) .conditionally(bs -> isBlockNumber(bs, loadedBlocks + 5))); - ethereumA.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereumA.subscribe(to(BlockAdded.class, blockSummary -> { if (isBlockNumber(blockSummary, loadedBlocks + 5)) { semaphore3.countDown(); ethereumA.getBlockMiner().stopMining(); @@ -252,14 +252,14 @@ public void test1() throws InterruptedException { final CountDownLatch semaphore4 = new CountDownLatch(2); - ethereumB.subscribe(to(BlockAddedEvent.class, bs -> { + ethereumB.subscribe(to(BlockAdded.class, bs -> { if (isBlockNumber(bs, loadedBlocks + 9)) { semaphore4.countDown(); ethereumA.getBlockMiner().stopMining(); } })); - ethereumA.subscribe(to(BlockAddedEvent.class, blockSummary -> semaphore4.countDown()) + ethereumA.subscribe(to(BlockAdded.class, blockSummary -> semaphore4.countDown()) .conditionally(bs -> isBlockNumber(bs, loadedBlocks + 9))); semaphore4.await(MAX_SECONDS_WAIT, SECONDS); @@ -280,7 +280,7 @@ private void setupPeers() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(PeerAddedToSyncPoolEvent.class, channel -> semaphore.countDown())); + ethereumB.subscribe(to(PeerAddedToSyncPool.class, channel -> semaphore.countDown())); ethereumB.connect(nodeA); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java b/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java index 93373c4474..8c26d3efe2 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java @@ -31,8 +31,8 @@ import org.ethereum.net.eth.message.GetBlockBodiesMessage; import org.ethereum.net.eth.message.GetBlockHeadersMessage; import org.ethereum.net.server.Channel; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.message.EthStatusUpdatedEvent; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.message.EthStatusUpdated; import org.ethereum.util.RLP; import org.junit.Ignore; import org.junit.Test; @@ -226,12 +226,12 @@ protected void processGetBlockBodies(GetBlockBodiesMessage msg) { final CountDownLatch semaphore = new CountDownLatch(1); final Channel[] channel1 = new Channel[1]; - ethereum1.subscribe(to(EthStatusUpdatedEvent.class, data -> { + ethereum1.subscribe(to(EthStatusUpdated.class, data -> { channel1[0] = data.getChannel(); System.out.println("==== Got the Channel: " + data.getChannel()); })); - ethereum2.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereum2.subscribe(to(BlockAdded.class, blockSummary -> { Block block = blockSummary.getBlock(); if (block.getNumber() == 4) { semaphore.countDown(); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/FramingTest.java b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/FramingTest.java index 9eaf76278a..5867971f5d 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/FramingTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/FramingTest.java @@ -23,7 +23,7 @@ import org.ethereum.facade.EthereumFactory; import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.message.Message; -import org.ethereum.publish.event.message.ReceivedMessageEvent; +import org.ethereum.publish.event.message.MessageReceived; import org.junit.Ignore; import org.junit.Test; import org.springframework.context.annotation.Bean; @@ -99,13 +99,13 @@ public void testTest() throws FileNotFoundException, InterruptedException { final CountDownLatch semaphore = new CountDownLatch(2); - ethereum1.subscribe(to(ReceivedMessageEvent.class, messageData -> { + ethereum1.subscribe(to(MessageReceived.class, messageData -> { if (messageData.getMessage() instanceof StatusMessage) { System.out.println("1: -> " + messageData.getMessage()); semaphore.countDown(); } })); - ethereum2.subscribe(to(ReceivedMessageEvent.class, messageData -> { + ethereum2.subscribe(to(MessageReceived.class, messageData -> { Message message = messageData.getMessage(); if (message instanceof StatusMessage) { System.out.println("2: -> " + message); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java index b61c3b7a30..61d9ad8e96 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java @@ -27,8 +27,8 @@ import org.ethereum.net.message.Message; import org.ethereum.net.shh.MessageWatcher; import org.ethereum.net.shh.WhisperMessage; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.message.ReceivedMessageEvent; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.message.MessageReceived; import org.junit.Ignore; import org.junit.Test; import org.spongycastle.util.encoders.Hex; @@ -112,7 +112,7 @@ public void testTest() throws FileNotFoundException, InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); - ethereum2.subscribe(to(ReceivedMessageEvent.class, messageData -> { + ethereum2.subscribe(to(MessageReceived.class, messageData -> { Message message = messageData.getMessage(); if (message instanceof StatusMessage) { System.out.println("=== Status received: " + message); @@ -129,7 +129,7 @@ public void testTest() throws FileNotFoundException, InterruptedException { final CountDownLatch semaphoreFirstBlock = new CountDownLatch(1); AtomicInteger blocksCnt = new AtomicInteger(); - ethereum2.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereum2.subscribe(to(BlockAdded.class, blockSummary -> { blocksCnt.addAndGet(1); if (blocksCnt.get() % 1000 == 0 || blocksCnt.get() == 1) { System.out.println("=== Blocks imported: " + blocksCnt); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SnappyConnectionTest.java b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SnappyConnectionTest.java index 0168401509..ead4868115 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SnappyConnectionTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SnappyConnectionTest.java @@ -21,7 +21,7 @@ import org.ethereum.config.SystemProperties; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.message.EthStatusUpdatedEvent; +import org.ethereum.publish.event.message.EthStatusUpdated; import org.junit.Ignore; import org.junit.Test; import org.springframework.context.annotation.Bean; @@ -99,11 +99,11 @@ private void runScenario(int vOutbound, int vInbound) throws FileNotFoundExcepti final CountDownLatch semaphore = new CountDownLatch(2); - ethereum1.subscribe(to(EthStatusUpdatedEvent.class, data -> { + ethereum1.subscribe(to(EthStatusUpdated.class, data -> { System.out.println("1: -> " + data.getMessage()); semaphore.countDown(); })); - ethereum2.subscribe(to(EthStatusUpdatedEvent.class, data -> { + ethereum2.subscribe(to(EthStatusUpdated.class, data -> { System.out.println("2: -> " + data.getMessage()); semaphore.countDown(); })); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/shh/ShhLongRun.java b/ethereumj-core/src/test/java/org/ethereum/net/shh/ShhLongRun.java index de06c9dc15..91a487fff2 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/shh/ShhLongRun.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/shh/ShhLongRun.java @@ -23,7 +23,7 @@ import org.ethereum.facade.EthereumFactory; import org.ethereum.manager.WorldManager; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.message.PeerHandshakedEvent; +import org.ethereum.publish.event.message.PeerHandshaked; import org.junit.Ignore; import org.junit.Test; import org.spongycastle.util.encoders.Hex; @@ -110,7 +110,7 @@ public TestComponent() { @PostConstruct void init() { System.out.println("========= init"); - worldManager.getPublisher().subscribe(to(PeerHandshakedEvent.class, data -> { + worldManager.getPublisher().subscribe(to(PeerHandshaked.class, data -> { System.out.println("========= onHandShakePeer"); if (!isAlive()) { start(); diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java index 1c99219fa9..d6a1ea22ef 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java @@ -31,12 +31,12 @@ import org.ethereum.net.eth.message.*; import org.ethereum.net.message.Message; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.PeerAddedToSyncPoolEvent; -import org.ethereum.publish.event.SyncDoneEvent; -import org.ethereum.publish.event.message.EthStatusUpdatedEvent; -import org.ethereum.publish.event.message.ReceivedMessageEvent; -import org.ethereum.publish.event.message.SentMessageEvent; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.PeerAddedToSyncPool; +import org.ethereum.publish.event.SyncDone; +import org.ethereum.publish.event.message.EthStatusUpdated; +import org.ethereum.publish.event.message.MessageReceived; +import org.ethereum.publish.event.message.MessageSent; import org.ethereum.util.ByteUtil; import org.junit.Ignore; import org.junit.Test; @@ -121,10 +121,10 @@ private void springInit() { logger = LoggerFactory.getLogger(loggerName); // adding the main EthereumJ callback to be notified on different kind of events this.ethereum - .subscribe(to(SyncDoneEvent.class, syncState -> synced = true)) - .subscribe(to(EthStatusUpdatedEvent.class, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage()))) - .subscribe(to(PeerAddedToSyncPoolEvent.class, peer -> syncPeers.add(peer.getNode()))) - .subscribe(to(BlockAddedEvent.class, blockSummary -> { + .subscribe(to(SyncDone.class, syncState -> synced = true)) + .subscribe(to(EthStatusUpdated.class, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage()))) + .subscribe(to(PeerAddedToSyncPool.class, peer -> syncPeers.add(peer.getNode()))) + .subscribe(to(BlockAdded.class, blockSummary -> { bestBlock = blockSummary.getBlock(); if (syncComplete) { logger.info("New block: " + bestBlock.getShortDescr()); @@ -482,12 +482,12 @@ public void testTest() throws Exception { Ethereum miner = EthereumFactory.createEthereum(MinerConfig.class); miner - .subscribe(to(BlockAddedEvent.class, blockSummary -> { + .subscribe(to(BlockAdded.class, blockSummary -> { if (blockSummary.getBlock().getNumber() != 0L) { blocks.put(Hex.toHexString(blockSummary.getBlock().getHash()), Boolean.FALSE); } })) - .subscribe(to(ReceivedMessageEvent.class, messageData -> { + .subscribe(to(MessageReceived.class, messageData -> { Message message = messageData.getMessage(); if (!(message instanceof EthMessage)) return; switch (((EthMessage) message).getCommand()) { @@ -519,7 +519,7 @@ public void testTest() throws Exception { testLogger.info("Starting EthereumJ txSender instance!"); Ethereum txGenerator = EthereumFactory.createEthereum(GeneratorConfig.class); txGenerator - .subscribe(to(ReceivedMessageEvent.class, messageData -> { + .subscribe(to(MessageReceived.class, messageData -> { Message message = messageData.getMessage(); if (!(message instanceof EthMessage)) return; switch (((EthMessage) message).getCommand()) { @@ -554,7 +554,7 @@ public void testTest() throws Exception { } })) - .subscribe(to(SentMessageEvent.class, messageData -> { + .subscribe(to(MessageSent.class, messageData -> { Message message = messageData.getMessage(); if (!(message instanceof EthMessage)) return; if (((EthMessage) message).getCommand().equals(EthMessageCodes.TRANSACTIONS)) { diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java index 80b4f334fa..cd68e1d958 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java @@ -33,10 +33,10 @@ import org.ethereum.net.eth.message.GetBlockHeadersMessage; import org.ethereum.net.p2p.DisconnectMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.PeerAddedToSyncPoolEvent; -import org.ethereum.publish.event.message.EthStatusUpdatedEvent; -import org.ethereum.publish.event.message.ReceivedMessageEvent; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.PeerAddedToSyncPool; +import org.ethereum.publish.event.message.EthStatusUpdated; +import org.ethereum.publish.event.message.MessageReceived; import org.ethereum.util.blockchain.StandaloneBlockchain; import org.junit.*; import org.springframework.context.annotation.Bean; @@ -161,7 +161,7 @@ public void test1() throws InterruptedException { // A == b10, B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { if (blockSummary.getBlock().isEqual(b10)) { semaphore.countDown(); } @@ -198,7 +198,7 @@ protected void processGetBlockBodies(GetBlockBodiesMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + ethereumA.subscribe(to(MessageReceived.class, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } @@ -245,7 +245,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + ethereumA.subscribe(to(MessageReceived.class, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } @@ -287,7 +287,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + ethereumA.subscribe(to(MessageReceived.class, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } @@ -333,7 +333,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + ethereumA.subscribe(to(MessageReceived.class, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } @@ -383,7 +383,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + ethereumA.subscribe(to(MessageReceived.class, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } @@ -429,7 +429,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + ethereumA.subscribe(to(MessageReceived.class, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } @@ -476,7 +476,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + ethereumA.subscribe(to(MessageReceived.class, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } @@ -508,11 +508,11 @@ private void setupPeers(Block best) throws InterruptedException { // A == best ethereumB = EthereumFactory.createEthereum(SysPropConfigB.props, SysPropConfigB.class); - ethereumA.subscribe(to(EthStatusUpdatedEvent.class, data -> ethA = (EthHandler) data.getChannel().getEthHandler())); + ethereumA.subscribe(to(EthStatusUpdated.class, data -> ethA = (EthHandler) data.getChannel().getEthHandler())); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(PeerAddedToSyncPoolEvent.class, channel -> semaphore.countDown())); + ethereumB.subscribe(to(PeerAddedToSyncPool.class, channel -> semaphore.countDown())); ethereumB.connect(nodeA); semaphore.await(10, SECONDS); diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java index bded3f9e57..6c714a06c2 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java @@ -30,10 +30,10 @@ import org.ethereum.net.eth.message.*; import org.ethereum.net.p2p.DisconnectMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BlockAddedEvent; -import org.ethereum.publish.event.PeerAddedToSyncPoolEvent; -import org.ethereum.publish.event.message.EthStatusUpdatedEvent; -import org.ethereum.publish.event.message.ReceivedMessageEvent; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.PeerAddedToSyncPool; +import org.ethereum.publish.event.message.EthStatusUpdated; +import org.ethereum.publish.event.message.MessageReceived; import org.ethereum.util.blockchain.StandaloneBlockchain; import org.junit.*; import org.springframework.context.annotation.Bean; @@ -160,7 +160,7 @@ public void test1() throws InterruptedException { // A == b10, B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> semaphore.countDown()) + ethereumB.subscribe(to(BlockAdded.class, blockSummary -> semaphore.countDown()) .conditionally(blockSummary -> blockSummary.getBlock().isEqual(b10))); ethA.sendNewBlock(b10); @@ -192,7 +192,7 @@ public void test2() throws InterruptedException { // A == b8', B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> semaphore.countDown()) + ethereumB.subscribe(to(BlockAdded.class, blockSummary -> semaphore.countDown()) .conditionally(blockSummary -> blockSummary.getBlock().isEqual(b8_))); ethA.sendNewBlock(b8_); @@ -228,7 +228,7 @@ public void test3() throws InterruptedException { // A == b10, B == b8' final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { Block block = blockSummary.getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -273,7 +273,7 @@ public void test4() throws InterruptedException { // A == b5, B == b9 final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> semaphore.countDown()) + ethereumB.subscribe(to(BlockAdded.class, blockSummary -> semaphore.countDown()) .conditionally(blockSummary -> blockSummary.getBlock().equals(b10))); ethA.sendNewBlockHashes(b5); @@ -322,7 +322,7 @@ public void test5() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB8_ = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { Block block = blockSummary.getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -382,7 +382,7 @@ public void test6() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB7 = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { Block block = blockSummary.getBlock(); if (block.isEqual(b7)) { semaphoreB7.countDown(); @@ -442,7 +442,7 @@ public void test7() throws InterruptedException { // A == b8', B == b4 - ethereumB.subscribe(to(ReceivedMessageEvent.class, data -> { + ethereumB.subscribe(to(MessageReceived.class, data -> { if (data.getMessage() instanceof NewBlockMessage) { // it's time to do a re-branch for (Block b : mainB1B10) { @@ -453,7 +453,7 @@ public void test7() throws InterruptedException { })); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { Block block = blockSummary.getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -501,7 +501,7 @@ public void test8() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB7_ = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { Block block = blockSummary.getBlock(); if (block.isEqual(b7_)) { // it's time to do a re-branch @@ -583,7 +583,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { ethA.sendNewBlock(b8_); final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(ReceivedMessageEvent.class, messageData -> { + ethereumA.subscribe(to(MessageReceived.class, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } @@ -604,7 +604,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { } final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { Block block = blockSummary.getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -613,7 +613,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { final CountDownLatch semaphoreConnect = new CountDownLatch(1); - ethereumB.subscribe(to(PeerAddedToSyncPoolEvent.class, channel -> semaphoreConnect.countDown())); + ethereumB.subscribe(to(PeerAddedToSyncPool.class, channel -> semaphoreConnect.countDown())); ethereumB.connect(nodeA); // await connection @@ -681,7 +681,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { ethA.sendNewBlockHashes(b8_); final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(ReceivedMessageEvent.class, data -> { + ethereumA.subscribe(to(MessageReceived.class, data -> { if (data.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } @@ -699,7 +699,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { LongSyncTest.SysPropConfigA.eth62 = null; final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { Block block = blockSummary.getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -707,7 +707,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { })); final CountDownLatch semaphoreConnect = new CountDownLatch(1); - ethereumB.subscribe(to(PeerAddedToSyncPoolEvent.class, channel -> semaphoreConnect.countDown())); + ethereumB.subscribe(to(PeerAddedToSyncPool.class, channel -> semaphoreConnect.countDown())); ethereumB.connect(nodeA); // await connection @@ -760,7 +760,7 @@ public void test11() throws InterruptedException { final CountDownLatch semaphore1 = new CountDownLatch(1); final CountDownLatch semaphore2 = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAddedEvent.class, blockSummary -> { + ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { if (blockSummary.getBlock().isEqual(b6_)) { if (semaphore1.getCount() > 0) { semaphore1.countDown(); @@ -823,7 +823,7 @@ protected void processGetBlockBodies(GetBlockBodiesMessage msg) { final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); this.ethereumA - .subscribe(to(ReceivedMessageEvent.class, data -> semaphoreDisconnect.countDown()) + .subscribe(to(MessageReceived.class, data -> semaphoreDisconnect.countDown()) .conditionally(data -> data.getMessage() instanceof DisconnectMessage)); ethA.sendNewBlock(b10); @@ -882,7 +882,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b8', B == b10 final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(ReceivedMessageEvent.class, data -> semaphoreDisconnect.countDown()) + ethereumA.subscribe(to(MessageReceived.class, data -> semaphoreDisconnect.countDown()) .conditionally(data -> data.getMessage() instanceof DisconnectMessage)); ethA.sendNewBlockHashes(b8_); @@ -942,7 +942,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b8', B == b10 final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(ReceivedMessageEvent.class, data -> semaphoreDisconnect.countDown()) + ethereumA.subscribe(to(MessageReceived.class, data -> semaphoreDisconnect.countDown()) .conditionally(data -> data.getMessage() instanceof DisconnectMessage)); ethA.sendNewBlockHashes(b8_); @@ -960,11 +960,11 @@ private void setupPeers() throws InterruptedException { ethereumA = EthereumFactory.createEthereum(SysPropConfigA.props, SysPropConfigA.class); ethereumB = EthereumFactory.createEthereum(SysPropConfigB.props, SysPropConfigB.class); - ethereumA.subscribe(to(EthStatusUpdatedEvent.class, data -> ethA = (EthHandler) data.getChannel().getEthHandler())); + ethereumA.subscribe(to(EthStatusUpdated.class, data -> ethA = (EthHandler) data.getChannel().getEthHandler())); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(PeerAddedToSyncPoolEvent.class, channel -> semaphore.countDown())); + ethereumB.subscribe(to(PeerAddedToSyncPool.class, channel -> semaphore.countDown())); ethereumB.connect(nodeA); semaphore.await(10, SECONDS); diff --git a/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java b/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java index 09580e8d30..6c557f7571 100644 --- a/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java @@ -7,8 +7,8 @@ import org.ethereum.listener.EthereumListener; import org.ethereum.mine.EthashValidationHelper; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.BestBlockAddedEvent; -import org.ethereum.publish.event.SyncDoneEvent; +import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.SyncDone; import org.junit.Test; import org.spongycastle.util.encoders.Hex; @@ -68,7 +68,7 @@ public void testStrict() { assertEquals(Success, rule.validate(partlyValidHeader)); // trigger ethash cache - publisher.publish(new BestBlockAddedEvent(dummySummaryNum_1, true)); + publisher.publish(new BestBlockAdded(dummySummaryNum_1, true)); assertEquals(Success, rule.validate(validHeader)); assertNotEquals(Success, rule.validate(partlyValidHeader)); @@ -86,7 +86,7 @@ public void testMixed() { EthashRule rule = new EthashRule(EthashRule.Mode.mixed, EthashRule.ChainType.main, publisher); // trigger ethash cache - publisher.publish(new BestBlockAddedEvent(dummySummaryNum_1, true)); + publisher.publish(new BestBlockAdded(dummySummaryNum_1, true)); // check mixed mode randomness boolean fullCheckTriggered = false; @@ -104,7 +104,7 @@ public void testMixed() { assertTrue(partialCheckTriggered); // trigger onSyncDone - publisher.publish(new SyncDoneEvent(EthereumListener.SyncState.COMPLETE)); + publisher.publish(new SyncDone(EthereumListener.SyncState.COMPLETE)); // check that full verification is done on each run in strict mode for (int i = 0; i < 100; i++) { @@ -122,8 +122,8 @@ public void testCacheMain() { // trigger cache for (int i = 0; i < 100; i++) { publisher - .publish(new BestBlockAddedEvent(dummySummaryNum_1, false)) - .publish(new BestBlockAddedEvent(dummySummaryNum_1, true)); + .publish(new BestBlockAdded(dummySummaryNum_1, false)) + .publish(new BestBlockAdded(dummySummaryNum_1, true)); } // must be triggered on best block only From 9627991165de205d93c0d5583018b440eda62b0b Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Tue, 14 Aug 2018 14:09:17 +0300 Subject: [PATCH 07/28] Removes experimental publisher --- .../publish/exprimental/EventBus.java | 55 --------- .../publish/exprimental/EventPublisher.java | 115 ------------------ 2 files changed, 170 deletions(-) delete mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventBus.java delete mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventPublisher.java diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventBus.java b/ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventBus.java deleted file mode 100644 index 218753ad84..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventBus.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.ethereum.publish.exprimental; - -import org.ethereum.publish.event.Event; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Consumer; - -import static java.util.Objects.isNull; - -public class EventBus { - - private static final Logger log = LoggerFactory.getLogger("events"); - - private final Map, EventPublisher> publisherByEvent = new HashMap<>(); - private final ExecutorService executor = Executors.newCachedThreadPool(Thread::new); - - - public , P> void subscribe(Class eventType, Consumer

      handler) { - publisherByEvent - .computeIfAbsent(eventType, t -> new EventPublisher<>(eventType, executor).onCompleted(this::removePublisher)) - .subscribe(handler); - } - - private void removePublisher(EventPublisher publisher) { - publisherByEvent.remove(publisher.getEventType()); - } - - public , P> void unsubscribe(Class eventType, Consumer

      handler) { - - } - - public boolean publish(Event event) { - if (executor.isShutdown()) { - log.warn("Cannot publish event: event bus is stopped."); - return false; - } - - EventPublisher eventPublisher = publisherByEvent.get(event.getClass()); - if (isNull(eventPublisher)) { - return false; - } - - return eventPublisher.publish(event); - } - - public void shutdown() { - executor.shutdown(); - } - -} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventPublisher.java b/ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventPublisher.java deleted file mode 100644 index 033b45b03a..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/publish/exprimental/EventPublisher.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.ethereum.publish.exprimental; - -import org.ethereum.publish.event.Event; -import org.ethereum.publish.event.Single; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.time.Duration; -import java.time.LocalDateTime; -import java.util.List; -import java.util.concurrent.*; -import java.util.function.Consumer; - -import static java.time.LocalDateTime.now; -import static java.util.Objects.nonNull; - -public class EventPublisher, P> { - - public static final Logger log = LoggerFactory.getLogger("event"); - - private final Class eventType; - private final BlockingQueue eventsQueue = new LinkedBlockingQueue<>(); - private final List> consumers = new CopyOnWriteArrayList<>(); - private final ExecutorService executor; - - private final Thread listener; - private Consumer> completedCallback; - - public EventPublisher(Class eventType, ExecutorService executor) { - this.eventType = eventType; - this.executor = executor; - this.listener = new Thread(this::listenEvents, "publisher-" + eventType.getSimpleName()); - } - - public EventPublisher onCompleted(Consumer> callback) { - this.completedCallback = callback; - return this; - } - - public Class getEventType() { - return eventType; - } - - public boolean publish(E event) { - return eventsQueue.offer(event); - } - - public void subscribe(Consumer

      consumer) { - boolean isFirstConsumer = consumers.isEmpty(); - consumers.add(consumer); - if (isFirstConsumer && !listener.isAlive()) { - listener.start(); - } - } - - public void unsubscribe(Consumer

      consumer) { - consumers.remove(consumer); - if (consumers.isEmpty() && eventsQueue.isEmpty()) { - listener.interrupt(); - } - } - - private void listenEvents() { - while (!(consumers.isEmpty() || executor.isShutdown())) { - - try { - E event = eventsQueue.take(); - - - notify(event); - - if (event instanceof Single) { - consumers.clear(); - } - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (ExecutionException e) { - e.printStackTrace(); - } - } - - if (nonNull(completedCallback)) { - completedCallback.accept(this); - } - } - - private void notify(Consumer

      consumer, E event) { - try { - consumer.accept(event.getPayload()); - } catch (Throwable err) { - log.error("Event handling error: ", err); - } - } - - private void notifyParallel(List> consumers, E event) throws InterruptedException, ExecutionException { - CompletableFuture[] futures = consumers.stream() - .map(consumer -> CompletableFuture.runAsync(() -> notify(consumer, event), executor)) - .toArray(CompletableFuture[]::new); - - CompletableFuture.allOf(futures).get(); - } - - private void notify(E event) throws InterruptedException, ExecutionException { - LocalDateTime start = now(); - try { - if (consumers.size() == 1) { - notify(consumers.get(0), event); - } else { - notifyParallel(consumers, event); - } - } finally { - log.debug("{} subscriber(s) processing took {} ms.", consumers.size(), Duration.between(start, now()).toMillis()); - } - } -} From 86e7ca4535620afc7d2e11075dab7d6c14a00c3f Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Tue, 14 Aug 2018 15:11:30 +0300 Subject: [PATCH 08/28] Adds backward compatibility EthereumListener proxy component. --- .../org/ethereum/config/CommonConfig.java | 12 +- .../listener/CompositeEthereumListener.java | 272 ++++++++++++++++++ ...ardCompatibilityEthereumListenerProxy.java | 127 ++++++++ .../org/ethereum/publish/event/Events.java | 75 +++++ 4 files changed, 484 insertions(+), 2 deletions(-) create mode 100644 ethereumj-core/src/main/java/org/ethereum/listener/CompositeEthereumListener.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/BackwardCompatibilityEthereumListenerProxy.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java diff --git a/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java b/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java index 115524874f..2fec848c9e 100644 --- a/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java +++ b/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java @@ -25,8 +25,10 @@ import org.ethereum.datasource.leveldb.LevelDbDataSource; import org.ethereum.datasource.rocksdb.RocksDbDataSource; import org.ethereum.db.*; +import org.ethereum.listener.CompositeEthereumListener; import org.ethereum.listener.EthereumListener; import org.ethereum.net.eth.handler.Eth63; +import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.Publisher; import org.ethereum.sync.FastSyncManager; import org.ethereum.validator.*; @@ -229,8 +231,14 @@ public Publisher publisher(EventDispatchThread eventDispatchThread) { } @Bean - public EthereumListener ethereumListener(Publisher publisher) { - return publisher.asListener(); + public CompositeEthereumListener compositeEthereumListener(EventDispatchThread eventDispatchThread) { + return new CompositeEthereumListener(eventDispatchThread); + } + + @Bean + @Primary + public EthereumListener ethereumListener(CompositeEthereumListener compositeListener, Publisher publisher) { + return new BackwardCompatibilityEthereumListenerProxy(compositeListener, publisher); } @Bean diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/CompositeEthereumListener.java b/ethereumj-core/src/main/java/org/ethereum/listener/CompositeEthereumListener.java new file mode 100644 index 0000000000..ef1cf12dbb --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/listener/CompositeEthereumListener.java @@ -0,0 +1,272 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ +package org.ethereum.listener; + +import org.ethereum.core.*; +import org.ethereum.net.eth.message.StatusMessage; +import org.ethereum.net.message.Message; +import org.ethereum.net.p2p.HelloMessage; +import org.ethereum.net.rlpx.Node; +import org.ethereum.net.server.Channel; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Executor; + +/** + * @author Roman Mandeleil + * @since 12.11.2014 + */ +public class CompositeEthereumListener implements EthereumListener { + + private static abstract class RunnableInfo implements Runnable { + private EthereumListener listener; + private String info; + + public RunnableInfo(EthereumListener listener, String info) { + this.listener = listener; + this.info = info; + } + + @Override + public String toString() { + return "RunnableInfo: " + info + " [listener: " + listener.getClass() + "]"; + } + } + + private final Executor executor; + private final List listeners; + + + public CompositeEthereumListener(Executor executor) { + this.executor = executor; + this.listeners = new CopyOnWriteArrayList<>(); + } + + public void addListener(EthereumListener listener) { + listeners.add(listener); + } + public void removeListener(EthereumListener listener) { + listeners.remove(listener); + } + + @Override + public void trace(final String output) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "trace") { + @Override + public void run() { + listener.trace(output); + } + }); + } + } + + @Override + public void onBlock(final BlockSummary blockSummary) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onBlock") { + @Override + public void run() { + listener.onBlock(blockSummary); + } + }); + } + } + + @Override + public void onBlock(final BlockSummary blockSummary, final boolean best) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onBlock") { + @Override + public void run() { + listener.onBlock(blockSummary, best); + } + }); + } + } + + @Override + public void onRecvMessage(final Channel channel, final Message message) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onRecvMessage") { + @Override + public void run() { + listener.onRecvMessage(channel, message); + } + }); + } + } + + @Override + public void onSendMessage(final Channel channel, final Message message) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onSendMessage") { + @Override + public void run() { + listener.onSendMessage(channel, message); + } + }); + } + } + + @Override + public void onPeerDisconnect(final String host, final long port) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onPeerDisconnect") { + @Override + public void run() { + listener.onPeerDisconnect(host, port); + } + }); + } + } + + @Override + public void onPendingTransactionsReceived(final List transactions) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onPendingTransactionsReceived") { + @Override + public void run() { + listener.onPendingTransactionsReceived(transactions); + } + }); + } + } + + @Override + public void onPendingStateChanged(final PendingState pendingState) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onPendingStateChanged") { + @Override + public void run() { + listener.onPendingStateChanged(pendingState); + } + }); + } + } + + @Override + public void onSyncDone(final SyncState state) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onSyncDone") { + @Override + public void run() { + listener.onSyncDone(state); + } + }); + } + } + + @Override + public void onNoConnections() { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onNoConnections") { + @Override + public void run() { + listener.onNoConnections(); + } + }); + } + } + + @Override + public void onHandShakePeer(final Channel channel, final HelloMessage helloMessage) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onHandShakePeer") { + @Override + public void run() { + listener.onHandShakePeer(channel, helloMessage); + } + }); + } + } + + @Override + public void onVMTraceCreated(final String transactionHash, final String trace) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onVMTraceCreated") { + @Override + public void run() { + listener.onVMTraceCreated(transactionHash, trace); + } + }); + } + } + + @Override + public void onNodeDiscovered(final Node node) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onNodeDiscovered") { + @Override + public void run() { + listener.onNodeDiscovered(node); + } + }); + } + } + + @Override + public void onEthStatusUpdated(final Channel channel, final StatusMessage status) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onEthStatusUpdated") { + @Override + public void run() { + listener.onEthStatusUpdated(channel, status); + } + }); + } + } + + @Override + public void onTransactionExecuted(final TransactionExecutionSummary summary) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onTransactionExecuted") { + @Override + public void run() { + listener.onTransactionExecuted(summary); + } + }); + } + } + + @Override + public void onPeerAddedToSyncPool(final Channel peer) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onPeerAddedToSyncPool") { + @Override + public void run() { + listener.onPeerAddedToSyncPool(peer); + } + }); + } + } + + @Override + public void onPendingTransactionUpdate(final TransactionReceipt txReceipt, final PendingTransactionState state, + final Block block) { + for (final EthereumListener listener : listeners) { + executor.execute(new RunnableInfo(listener, "onPendingTransactionUpdate") { + @Override + public void run() { + listener.onPendingTransactionUpdate(txReceipt, state, block); + } + }); + } + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/BackwardCompatibilityEthereumListenerProxy.java b/ethereumj-core/src/main/java/org/ethereum/publish/BackwardCompatibilityEthereumListenerProxy.java new file mode 100644 index 0000000000..6a53fb4b8c --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/BackwardCompatibilityEthereumListenerProxy.java @@ -0,0 +1,127 @@ +package org.ethereum.publish; + +import org.ethereum.core.*; +import org.ethereum.listener.CompositeEthereumListener; +import org.ethereum.listener.EthereumListener; +import org.ethereum.net.eth.message.StatusMessage; +import org.ethereum.net.message.Message; +import org.ethereum.net.p2p.HelloMessage; +import org.ethereum.net.rlpx.Node; +import org.ethereum.net.server.Channel; +import org.ethereum.publish.event.Events; + +import java.util.List; + +public class BackwardCompatibilityEthereumListenerProxy implements EthereumListener { + + private final CompositeEthereumListener compositeListener; + private final Publisher publisher; + + public BackwardCompatibilityEthereumListenerProxy(CompositeEthereumListener listener, Publisher publisher) { + this.compositeListener = listener; + this.publisher = publisher; + } + + public void addListener(EthereumListener listener) { + this.compositeListener.addListener(listener); + } + + @Override + public void trace(String output) { + compositeListener.trace(output); + } + + @Override + public void onNodeDiscovered(Node node) { + compositeListener.onNodeDiscovered(node); + publisher.publish(Events.onNodeDiscovered(node)); + } + + @Override + public void onHandShakePeer(Channel channel, HelloMessage message) { + compositeListener.onHandShakePeer(channel, message); + publisher.publish(Events.onPeerHanshaked(channel, message)); + } + + @Override + public void onEthStatusUpdated(Channel channel, StatusMessage message) { + compositeListener.onEthStatusUpdated(channel, message); + publisher.publish(Events.onEthStatusUpdated(channel, message)); + } + + @Override + public void onRecvMessage(Channel channel, Message message) { + compositeListener.onRecvMessage(channel, message); + publisher.publish(Events.onMessageReceived(channel, message)); + } + + @Override + public void onSendMessage(Channel channel, Message message) { + compositeListener.onSendMessage(channel, message); + publisher.publish(Events.onMessageSent(channel, message)); + } + + @Override + public void onBlock(BlockSummary blockSummary) { + compositeListener.onBlock(blockSummary); + publisher.publish(Events.onBlockAdded(blockSummary)); + } + + @Override + public void onBlock(BlockSummary blockSummary, boolean best) { + compositeListener.onBlock(blockSummary, best); + publisher.publish(Events.onBlockAdded(blockSummary, best)); + } + + @Override + public void onPeerDisconnect(String host, long port) { + compositeListener.onPeerDisconnect(host, port); + publisher.publish(Events.onPeerDisconnected(host, port)); + } + + @Override + public void onPendingTransactionsReceived(List transactions) { + compositeListener.onPendingTransactionsReceived(transactions); + } + + @Override + public void onPendingStateChanged(PendingState pendingState) { + compositeListener.onPendingStateChanged(pendingState); + publisher.publish(Events.onPendingStateChanged(pendingState)); + } + + @Override + public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionState state, Block block) { + compositeListener.onPendingTransactionUpdate(txReceipt, state, block); + publisher.publish(Events.onPendingTransactionUpdated(block, txReceipt, state)); + } + + @Override + public void onSyncDone(SyncState state) { + compositeListener.onSyncDone(state); + publisher.publish(Events.onSyncDone(state)); + } + + @Override + public void onNoConnections() { + compositeListener.onNoConnections(); + } + + @Override + public void onVMTraceCreated(String transactionHash, String trace) { + compositeListener.onVMTraceCreated(transactionHash, trace); + publisher.publish(Events.onVmTraceCreated(transactionHash, trace)); + } + + @Override + public void onTransactionExecuted(TransactionExecutionSummary summary) { + compositeListener.onTransactionExecuted(summary); + publisher.publish(Events.onTransactionExecuted(summary)); + } + + @Override + public void onPeerAddedToSyncPool(Channel peer) { + compositeListener.onPeerAddedToSyncPool(peer); + publisher.publish(Events.onPeerAddedToSyncPool(peer)); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java new file mode 100644 index 0000000000..e050e489fc --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java @@ -0,0 +1,75 @@ +package org.ethereum.publish.event; + +import org.ethereum.core.*; +import org.ethereum.listener.EthereumListener; +import org.ethereum.net.eth.message.StatusMessage; +import org.ethereum.net.message.Message; +import org.ethereum.net.p2p.HelloMessage; +import org.ethereum.net.rlpx.Node; +import org.ethereum.net.server.Channel; +import org.ethereum.publish.event.message.EthStatusUpdated; +import org.ethereum.publish.event.message.MessageReceived; +import org.ethereum.publish.event.message.MessageSent; +import org.ethereum.publish.event.message.PeerHandshaked; + +public final class Events { + + private Events() { + } + + public static Event onEthStatusUpdated(Channel channel, StatusMessage message) { + return new EthStatusUpdated(channel, message); + } + + public static Event onMessageReceived(Channel channel, Message message) { + return new MessageReceived(channel, message); + } + + public static Event onMessageSent(Channel channel, Message message) { + return new MessageSent(channel, message); + } + + public static Event onPeerHanshaked(Channel channel, HelloMessage message) { + return new PeerHandshaked(channel, message); + } + + public static Event onBlockAdded(BlockSummary summary, boolean isBest) { + return new BestBlockAdded(summary, isBest); + } + + public static Event onBlockAdded(BlockSummary summary) { + return onBlockAdded(summary, false); + } + + public static Event onNodeDiscovered(Node node) { + return new NodeDiscovered(node); + } + + public static Event onPeerAddedToSyncPool(Channel channel) { + return new PeerAddedToSyncPool(channel); + } + + public static Event onPeerDisconnected(String host, long port) { + return new PeerDisconnected(host, port); + } + + public static Event onPendingStateChanged(PendingState state) { + return new PendingStateChanged(state); + } + + public static Event onPendingTransactionUpdated(Block block, TransactionReceipt receipt, EthereumListener.PendingTransactionState state) { + return new PendingTransactionUpdated(block, receipt, state); + } + + public static Event onSyncDone(EthereumListener.SyncState state) { + return new SyncDone(state); + } + + public static Event onTransactionExecuted(TransactionExecutionSummary summary) { + return new TransactionExecuted(summary); + } + + public static Event onVmTraceCreated(String txHash, String trace) { + return new VmTraceCreated(txHash, trace); + } +} From c54d4b9246eb825f674f997e30c02b3362157122 Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Wed, 15 Aug 2018 00:25:59 +0300 Subject: [PATCH 09/28] Migrate to backeard compatibility EthereumListener using. --- .../org/ethereum/core/BlockchainImpl.java | 24 +-- .../org/ethereum/core/PendingStateImpl.java | 22 ++- .../ethereum/core/TransactionExecutor.java | 16 +- .../java/org/ethereum/db/DbFlushManager.java | 6 +- .../org/ethereum/facade/EthereumImpl.java | 15 +- .../ethereum/listener/EthereumListener.java | 82 ++++++++++ .../org/ethereum/manager/WorldManager.java | 22 +-- .../java/org/ethereum/mine/BlockMiner.java | 11 +- .../java/org/ethereum/net/MessageQueue.java | 27 ++-- .../org/ethereum/net/client/PeerClient.java | 7 +- .../org/ethereum/net/eth/handler/Eth62.java | 13 +- .../org/ethereum/net/eth/handler/Eth63.java | 6 +- .../ethereum/net/eth/handler/EthHandler.java | 28 ++-- .../java/org/ethereum/net/p2p/P2pHandler.java | 12 +- .../org/ethereum/net/rlpx/MessageCodec.java | 11 +- .../net/rlpx/discover/NodeManager.java | 13 +- .../org/ethereum/net/server/PeerServer.java | 12 +- .../java/org/ethereum/net/shh/ShhHandler.java | 11 +- .../ethereum/net/swarm/bzz/BzzHandler.java | 9 +- ...ardCompatibilityEthereumListenerProxy.java | 17 +++ .../java/org/ethereum/publish/Publisher.java | 140 +----------------- .../org/ethereum/samples/BasicSample.java | 10 +- .../samples/CreateContractSample.java | 9 +- .../ethereum/samples/EventListenerSample.java | 8 +- .../org/ethereum/samples/FollowAccount.java | 6 +- .../ethereum/samples/PendingStateSample.java | 7 +- .../org/ethereum/samples/SendTransaction.java | 9 +- .../org/ethereum/samples/TransactionBomb.java | 8 +- .../org/ethereum/sync/FastSyncManager.java | 6 +- .../java/org/ethereum/sync/SyncManager.java | 6 +- .../main/java/org/ethereum/sync/SyncPool.java | 7 +- .../util/blockchain/StandaloneBlockchain.java | 27 ++-- .../java/org/ethereum/core/CloseTest.java | 4 +- .../org/ethereum/core/ImportLightTest.java | 13 +- .../core/PendingStateLongRunTest.java | 7 +- .../org/ethereum/core/PendingStateTest.java | 29 ++-- .../jsontestsuite/suite/TestRunner.java | 7 +- .../java/org/ethereum/longrun/BasicNode.java | 9 +- .../ethereum/longrun/SyncWithLoadTest.java | 8 +- .../java/org/ethereum/mine/MinerTest.java | 8 +- .../java/org/ethereum/mine/SyncDoneTest.java | 34 ++--- .../java/org/ethereum/net/TwoPeerTest.java | 6 +- .../net/eth/handler/LockBlockchainTest.java | 9 +- .../ethereum/net/rlpx/SanityLongRunTest.java | 4 +- .../org/ethereum/sync/BlockTxForwardTest.java | 13 +- .../java/org/ethereum/sync/LongSyncTest.java | 6 +- .../java/org/ethereum/sync/ShortSyncTest.java | 46 +++--- 47 files changed, 376 insertions(+), 434 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java b/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java index e4421298ed..21ee22d646 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java @@ -24,11 +24,8 @@ import org.ethereum.crypto.HashUtil; import org.ethereum.datasource.inmem.HashMapDB; import org.ethereum.db.*; +import org.ethereum.listener.EthereumListener; import org.ethereum.manager.AdminInfo; -import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.BestBlockAdded; -import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.Trace; import org.ethereum.sync.SyncManager; import org.ethereum.trie.Trie; import org.ethereum.trie.TrieImpl; @@ -123,7 +120,7 @@ public class BlockchainImpl implements Blockchain, org.ethereum.facade.Blockchai private BigInteger totalDifficulty = ZERO; @Autowired - private Publisher publisher; + private EthereumListener listenerProxy; @Autowired ProgramInvokeFactory programInvokeFactory; @@ -186,11 +183,11 @@ public BlockchainImpl(final SystemProperties config) { } //todo: autowire over constructor - public BlockchainImpl(final BlockStore blockStore, final Repository repository, Publisher publisher) { + public BlockchainImpl(final BlockStore blockStore, final Repository repository, EthereumListener listener) { this.blockStore = blockStore; this.repository = repository; this.adminInfo = new AdminInfo(); - this.publisher = publisher; + this.listenerProxy = listener; this.parentHeaderValidator = null; this.transactionStore = new TransactionStore(new HashMapDB()); this.eventDispatchThread = EventDispatchThread.getDefault(); @@ -208,11 +205,6 @@ public BlockchainImpl withAdminInfo(AdminInfo adminInfo) { return this; } - public BlockchainImpl withPublisher(Publisher publisher) { - this.publisher = publisher; - return this; - } - public BlockchainImpl withSyncManager(SyncManager syncManager) { this.syncManager = syncManager; return this; @@ -454,10 +446,8 @@ public synchronized ImportResult tryToConnect(final Block block) { } if (ret.isSuccessful()) { - publisher - .publish(new BlockAdded(summary)) - .publish(new BestBlockAdded(summary, ret == IMPORTED_BEST)) - .publish(new Trace(format("Block chain size: [ %d ]", this.getSize()))); + listenerProxy.onBlock(summary, ret == IMPORTED_BEST); + listenerProxy.trace(format("Block chain size: [ %d ]", this.getSize())); if (ret == IMPORTED_BEST) { eventDispatchThread.invokeLater(() -> pendingState.processBest(block, summary.getReceipts())); @@ -876,7 +866,7 @@ private BlockSummary applyBlock(Repository track, Block block) { Repository txTrack = track.startTracking(); TransactionExecutor executor = new TransactionExecutor(tx, block.getCoinbase(), - txTrack, blockStore, programInvokeFactory, block, publisher, totalGasUsed) + txTrack, blockStore, programInvokeFactory, block, listenerProxy, totalGasUsed) .withCommonConfig(commonConfig); executor.init(); diff --git a/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java b/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java index 9bfa807235..ebfcd115fc 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java @@ -23,11 +23,8 @@ import org.ethereum.db.BlockStore; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.db.TransactionStore; +import org.ethereum.listener.EthereumListener; import org.ethereum.listener.EthereumListener.PendingTransactionState; -import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.PendingStateChanged; -import org.ethereum.publish.event.PendingTransactionUpdated; -import org.ethereum.publish.event.PendingTransactionsReceived; import org.ethereum.util.ByteUtil; import org.ethereum.util.FastByteComparisons; import org.ethereum.vm.program.invoke.ProgramInvokeFactory; @@ -71,7 +68,7 @@ public TransactionSortedSet() { @Autowired CommonConfig commonConfig = CommonConfig.getDefault(); - private Publisher publisher; + private EthereumListener listener; @Autowired private BlockchainImpl blockchain; @@ -99,8 +96,8 @@ public TransactionSortedSet() { private Block best = null; @Autowired - public PendingStateImpl(final Publisher publisher) { - this.publisher = publisher; + public PendingStateImpl(final EthereumListener listener) { + this.listener = listener; // this.repository = blockchain.getRepository(); } @@ -165,9 +162,8 @@ public synchronized List addPendingTransactions(List t transactions.size(), unknownTx, newPending, receivedTxs.size()); if (!newPending.isEmpty()) { - this.publisher - .publish(new PendingTransactionsReceived(newPending)) - .publish(new PendingStateChanged(PendingStateImpl.this)); + listener.onPendingTransactionsReceived(newPending); + listener.onPendingStateChanged(PendingStateImpl.this); } return newPending; @@ -197,7 +193,7 @@ state, toHexString(txReceipt.getTransaction().getSender()).substring(0, 8), ByteUtil.byteArrayToLong(txReceipt.getTransaction().getNonce()), block.getShortDescr(), txReceipt.getError())); } - publisher.publish(new PendingTransactionUpdated(block, txReceipt, state)); + listener.onPendingTransactionUpdate(txReceipt, state, block); } /** @@ -316,7 +312,7 @@ public synchronized void processBest(Block newBlock, List re updateState(newBlock); - publisher.publish(new PendingStateChanged(PendingStateImpl.this)); + listener.onPendingStateChanged(PendingStateImpl.this); } private void processBestInternal(Block block, List receipts) { @@ -405,7 +401,7 @@ private TransactionReceipt executeTx(Transaction tx) { TransactionExecutor executor = new TransactionExecutor( tx, best.getCoinbase(), getRepository(), - blockStore, programInvokeFactory, createFakePendingBlock(), new Publisher(EventDispatchThread.getDefault()), 0) + blockStore, programInvokeFactory, createFakePendingBlock(), EthereumListener.STUB, 0) .withCommonConfig(commonConfig); executor.init(); diff --git a/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java b/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java index 4c1838b516..fc805eb8ce 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java @@ -23,9 +23,7 @@ import org.ethereum.config.SystemProperties; import org.ethereum.db.BlockStore; import org.ethereum.db.ContractDetails; -import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.TransactionExecuted; -import org.ethereum.publish.event.VmTraceCreated; +import org.ethereum.listener.EthereumListener; import org.ethereum.util.ByteArraySet; import org.ethereum.vm.DataWord; import org.ethereum.vm.LogInfo; @@ -77,7 +75,7 @@ public class TransactionExecutor { private ProgramResult result = new ProgramResult(); private Block currentBlock; - private final Publisher publisher; + private final EthereumListener listener; private VM vm; private Program program; @@ -95,12 +93,12 @@ public class TransactionExecutor { public TransactionExecutor(Transaction tx, byte[] coinbase, Repository track, BlockStore blockStore, ProgramInvokeFactory programInvokeFactory, Block currentBlock) { - this(tx, coinbase, track, blockStore, programInvokeFactory, currentBlock, new Publisher(EventDispatchThread.getDefault()), 0); + this(tx, coinbase, track, blockStore, programInvokeFactory, currentBlock, EthereumListener.STUB, 0); } public TransactionExecutor(Transaction tx, byte[] coinbase, Repository track, BlockStore blockStore, ProgramInvokeFactory programInvokeFactory, Block currentBlock, - Publisher publisher, long gasUsedInTheBlock) { + EthereumListener listener, long gasUsedInTheBlock) { this.tx = tx; this.coinbase = coinbase; @@ -109,7 +107,7 @@ public TransactionExecutor(Transaction tx, byte[] coinbase, Repository track, Bl this.blockStore = blockStore; this.programInvokeFactory = programInvokeFactory; this.currentBlock = currentBlock; - this.publisher = publisher; + this.listener = listener; this.gasUsedInTheBlock = gasUsedInTheBlock; this.m_endGas = toBI(tx.getGasLimit()); withCommonConfig(CommonConfig.getDefault()); @@ -454,7 +452,7 @@ public TransactionExecutionSummary finalization() { } - publisher.publish(new TransactionExecuted(summary)); + listener.onTransactionExecuted(summary); if (config.vmTrace() && program != null && result != null) { String trace = program.getTrace() @@ -469,7 +467,7 @@ public TransactionExecutionSummary finalization() { String txHash = toHexString(tx.getHash()); saveProgramTraceFile(config, txHash, trace); - publisher.publish(new VmTraceCreated(txHash, trace)); + listener.onVMTraceCreated(txHash, trace); } return summary; } diff --git a/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java b/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java index d4c17f6754..18d622e9ef 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java @@ -35,6 +35,8 @@ import java.util.Set; import java.util.concurrent.*; +import static org.ethereum.publish.Subscription.to; + /** * Created by Anton Nashatyrev on 01.12.2016. */ @@ -73,12 +75,12 @@ public DbFlushManager(SystemProperties config, Set dbSources, Abstract public void setPublisher(Publisher publisher) { if (!flushAfterSyncDone) return; - publisher.subscribe(SyncDone.class, state -> { + publisher.subscribe(to(SyncDone.class, state -> { if (state == EthereumListener.SyncState.COMPLETE) { logger.info("DbFlushManager: long sync done, flushing each block now"); syncDone = true; } - }); + })); } public void setSizeThreshold(long sizeThreshold) { diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index 087d978f3d..ab363cbf40 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -38,7 +38,7 @@ import org.ethereum.net.submit.TransactionTask; import org.ethereum.publish.Publisher; import org.ethereum.publish.Subscription; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.Event; import org.ethereum.sync.SyncManager; import org.ethereum.util.ByteUtil; @@ -64,6 +64,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.ByteUtil.toHexString; /** @@ -122,9 +123,9 @@ public EthereumImpl(final SystemProperties config) { @PostConstruct public void init() { - publisher.subscribe(BlockAdded.class, blockSummary -> { - blockSummary.getBlock().getTransactionsList().forEach(gasPriceTracker::onTransaction); - }); + publisher.subscribe(to(BestBlockAdded.class, data -> { + data.getBlockSummary().getBlock().getTransactionsList().forEach(gasPriceTracker::onTransaction); + })); } @Override @@ -173,7 +174,7 @@ public BlockMiner getBlockMiner() { @Override public void addListener(EthereumListener listener) { - worldManager.getPublisher().subscribeListener(listener); + worldManager.addListener(listener); } @Override @@ -266,7 +267,7 @@ public BlockSummary replayBlock(Block block) { Repository txTrack = track.startTracking(); org.ethereum.core.TransactionExecutor executor = new org.ethereum.core.TransactionExecutor( tx, block.getCoinbase(), txTrack, worldManager.getBlockStore(), - programInvokeFactory, block, worldManager.getPublisher(), 0) + programInvokeFactory, block, worldManager.getListener(), 0) .withCommonConfig(commonConfig); executor.init(); @@ -298,7 +299,7 @@ private org.ethereum.core.TransactionExecutor callConstantImpl(Transaction tx, B try { org.ethereum.core.TransactionExecutor executor = new org.ethereum.core.TransactionExecutor (tx, block.getCoinbase(), repository, worldManager.getBlockStore(), - programInvokeFactory, block, new Publisher(EventDispatchThread.getDefault()), 0) + programInvokeFactory, block, EthereumListener.STUB, 0) .withCommonConfig(commonConfig) .setLocalCall(true); diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java b/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java index bba95322ef..98265ffb4e 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java @@ -154,4 +154,86 @@ default void onBlock(BlockSummary blockSummary, boolean best) { void onTransactionExecuted(TransactionExecutionSummary summary); void onPeerAddedToSyncPool(Channel peer); + + EthereumListener STUB = new EthereumListener() { + @Override + public void trace(String output) { + + } + + @Override + public void onNodeDiscovered(Node node) { + + } + + @Override + public void onHandShakePeer(Channel channel, HelloMessage helloMessage) { + + } + + @Override + public void onEthStatusUpdated(Channel channel, StatusMessage status) { + + } + + @Override + public void onRecvMessage(Channel channel, Message message) { + + } + + @Override + public void onSendMessage(Channel channel, Message message) { + + } + + @Override + public void onBlock(BlockSummary blockSummary) { + + } + + @Override + public void onPeerDisconnect(String host, long port) { + + } + + @Override + public void onPendingTransactionsReceived(List transactions) { + + } + + @Override + public void onPendingStateChanged(PendingState pendingState) { + + } + + @Override + public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionState state, Block block) { + + } + + @Override + public void onSyncDone(SyncState state) { + + } + + @Override + public void onNoConnections() { + + } + + @Override + public void onVMTraceCreated(String transactionHash, String trace) { + + } + + @Override + public void onTransactionExecuted(TransactionExecutionSummary summary) { + + } + + @Override + public void onPeerAddedToSyncPool(Channel peer) { + + } + }; } diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java index f637c3f711..282b598748 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java @@ -28,8 +28,8 @@ import org.ethereum.net.rlpx.discover.NodeManager; import org.ethereum.net.rlpx.discover.UDPListener; import org.ethereum.net.server.ChannelManager; +import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.Event; import org.ethereum.sync.FastSyncManager; import org.ethereum.sync.SyncManager; @@ -99,7 +99,7 @@ public class WorldManager { private SystemProperties config; - private Publisher publisher; + private EthereumListener listener; private Blockchain blockchain; @@ -108,10 +108,10 @@ public class WorldManager { private BlockStore blockStore; @Autowired - public WorldManager(final SystemProperties config, final Repository repository, - final Publisher publisher, final Blockchain blockchain, - final BlockStore blockStore) { - this.publisher = publisher; + public WorldManager(SystemProperties config, Repository repository, EthereumListener listener, + Blockchain blockchain, BlockStore blockStore) { + + this.listener = listener; this.blockchain = blockchain; this.repository = repository; this.blockStore = blockStore; @@ -132,11 +132,11 @@ private void init() { @Deprecated public void addListener(EthereumListener listener) { logger.info("Ethereum listener added"); - publisher.subscribeListener(listener); + ((BackwardCompatibilityEthereumListenerProxy) listener).addListener(listener); } public , P> Publisher subscribe(Class eventType, Consumer

      handler) { - return this.publisher.subscribe(to(eventType, handler)); + return getPublisher().subscribe(to(eventType, handler)); } public void startPeerDiscovery() { @@ -162,11 +162,11 @@ public ChannelManager getChannelManager() { */ @Deprecated public EthereumListener getListener() { - return publisher.asListener(); + return listener; } public Publisher getPublisher() { - return publisher; + return ((BackwardCompatibilityEthereumListenerProxy) listener).getPublisher(); } public org.ethereum.facade.Repository getRepository() { @@ -209,7 +209,7 @@ public void loadBlockchain() { blockchain.setTotalDifficulty(Genesis.getInstance(config).getDifficultyBI()); BlockSummary blockSummary = new BlockSummary(Genesis.getInstance(config), emptyMap(), emptyList(), emptyList()); - publisher.publish(new BestBlockAdded(blockSummary, true)); + listener.onBlock(blockSummary, true); // repository.dumpState(Genesis.getInstance(config), 0, 0, null); logger.info("Genesis block loaded"); diff --git a/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java b/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java index ab011d93d5..06e433a021 100644 --- a/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java +++ b/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java @@ -38,7 +38,9 @@ import java.math.BigInteger; import java.util.*; -import java.util.concurrent.*; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.CopyOnWriteArrayList; import static java.lang.Math.max; import static org.ethereum.publish.Subscription.to; @@ -52,8 +54,6 @@ public class BlockMiner { private static final Logger logger = LoggerFactory.getLogger("mine"); - private static ExecutorService executor = Executors.newSingleThreadExecutor(); - private Blockchain blockchain; private BlockStore blockStore; @@ -81,8 +81,6 @@ public class BlockMiner { private int UNCLE_LIST_LIMIT; private int UNCLE_GENERATION_LIMIT; - private final Publisher publisher; - @Autowired public BlockMiner(final SystemProperties config, Publisher publisher, final Blockchain blockchain, final BlockStore blockStore, @@ -97,7 +95,8 @@ public BlockMiner(final SystemProperties config, Publisher publisher, this.minBlockTimeout = config.getMineMinBlockTimeoutMsec(); this.cpuThreads = config.getMineCpuThreads(); this.fullMining = config.isMineFullDataset(); - this.publisher = publisher + + publisher .subscribe(to(PendingStateChanged.class, ps -> onPendingStateChanged())) .subscribe(to(SyncDone.class, s -> { if (config.minerStart() && config.isSyncEnabled()) { diff --git a/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java b/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java index aeae550582..82e65182d6 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java @@ -19,15 +19,13 @@ import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; +import org.ethereum.listener.EthereumListener; import org.ethereum.net.eth.message.EthMessage; import org.ethereum.net.message.Message; import org.ethereum.net.message.ReasonCode; import org.ethereum.net.p2p.DisconnectMessage; import org.ethereum.net.p2p.PingMessage; import org.ethereum.net.server.Channel; -import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.Trace; -import org.ethereum.publish.event.message.MessageSent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -42,16 +40,16 @@ /** * This class contains the logic for sending messages in a queue - * + *

      * Messages open by send and answered by receive of appropriate message - * PING by PONG - * GET_PEERS by PEERS - * GET_TRANSACTIONS by TRANSACTIONS - * GET_BLOCK_HASHES by BLOCK_HASHES - * GET_BLOCKS by BLOCKS - * + * PING by PONG + * GET_PEERS by PEERS + * GET_TRANSACTIONS by TRANSACTIONS + * GET_BLOCK_HASHES by BLOCK_HASHES + * GET_BLOCKS by BLOCKS + *

      * The following messages will not be answered: - * PONG, PEERS, HELLO, STATUS, TRANSACTIONS, BLOCKS + * PONG, PEERS, HELLO, STATUS, TRANSACTIONS, BLOCKS * * @author Roman Mandeleil */ @@ -74,7 +72,7 @@ public Thread newThread(Runnable r) { private ChannelHandlerContext ctx = null; @Autowired - private Publisher publisher; + private EthereumListener listener; boolean hasPing = false; private ScheduledFuture timerTask; private Channel channel; @@ -128,8 +126,7 @@ private void disconnect(DisconnectMessage msg) { } public void receivedMessage(Message msg) throws InterruptedException { - - publisher.publish(new Trace("[Recv: " + msg + "]")); + listener.trace("[Recv: " + msg + "]"); if (requestQueue.peek() != null) { MessageRoundtrip messageRoundtrip = requestQueue.peek(); @@ -168,7 +165,7 @@ private void sendToWire(MessageRoundtrip messageRoundtrip) { Message msg = messageRoundtrip.getMsg(); - publisher.publish(new MessageSent(channel, msg)); + listener.onSendMessage(channel, msg); ctx.writeAndFlush(msg).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java b/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java index fd3042d13a..219cdca197 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java @@ -25,9 +25,8 @@ import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import org.ethereum.config.SystemProperties; +import org.ethereum.listener.EthereumListener; import org.ethereum.net.server.EthereumChannelInitializer; -import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.Trace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -56,7 +55,7 @@ public class PeerClient { private ApplicationContext ctx; @Autowired - private Publisher publisher; + private EthereumListener listener; private EventLoopGroup workerGroup; @@ -103,7 +102,7 @@ public void connect(String host, int port, String remoteId, boolean discoveryMod } public ChannelFuture connectAsync(String host, int port, String remoteId, boolean discoveryMode) { - publisher.publish(new Trace("Connecting to: " + host + ":" + port)); + listener.trace("Connecting to: " + host + ":" + port); EthereumChannelInitializer ethereumChannelInitializer = ctx.getBean(EthereumChannelInitializer.class, remoteId); ethereumChannelInitializer.setPeerDiscoveryMode(discoveryMode); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java index 38be67e886..0c5f9e73b8 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java @@ -24,14 +24,13 @@ import org.ethereum.config.SystemProperties; import org.ethereum.core.*; import org.ethereum.db.BlockStore; +import org.ethereum.listener.EthereumListener; import org.ethereum.net.eth.EthVersion; import org.ethereum.net.eth.message.*; import org.ethereum.net.message.ReasonCode; import org.ethereum.net.rlpx.discover.NodeManager; import org.ethereum.net.submit.TransactionExecutor; import org.ethereum.net.submit.TransactionTask; -import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.message.EthStatusUpdated; import org.ethereum.sync.PeerState; import org.ethereum.sync.SyncManager; import org.ethereum.sync.SyncStatistics; @@ -127,14 +126,14 @@ public Eth62() { @Autowired public Eth62(final SystemProperties config, final Blockchain blockchain, - final BlockStore blockStore, Publisher publisher) { - this(version, config, blockchain, blockStore, publisher); + final BlockStore blockStore, EthereumListener listener) { + this(version, config, blockchain, blockStore, listener); } Eth62(final EthVersion version, final SystemProperties config, final Blockchain blockchain, final BlockStore blockStore, - final Publisher publisher) { - super(version, config, blockchain, blockStore, publisher); + final EthereumListener listener) { + super(version, config, blockchain, blockStore, listener); } @Override @@ -340,7 +339,7 @@ protected synchronized void processStatus(StatusMessage msg, ChannelHandlerConte // basic checks passed, update statistics channel.getNodeStatistics().ethHandshake(msg); - getPublisher().publish(new EthStatusUpdated(channel, msg)); + listener.onEthStatusUpdated(channel, msg); if (peerDiscoveryMode) { loggerNet.trace("Peer discovery mode: STATUS received, disconnecting..."); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java index 550e7bd75b..2e64473f7f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java @@ -25,10 +25,10 @@ import org.ethereum.core.*; import org.ethereum.datasource.Source; import org.ethereum.db.BlockStore; +import org.ethereum.listener.EthereumListener; import org.ethereum.net.eth.EthVersion; import org.ethereum.net.eth.message.*; import org.ethereum.net.message.ReasonCode; -import org.ethereum.publish.Publisher; import org.ethereum.sync.PeerState; import org.ethereum.util.ByteArraySet; import org.ethereum.util.Value; @@ -68,8 +68,8 @@ public Eth63() { @Autowired public Eth63(final SystemProperties config, final Blockchain blockchain, BlockStore blockStore, - final Publisher publisher) { - super(version, config, blockchain, blockStore, publisher); + final EthereumListener listener) { + super(version, config, blockchain, blockStore, listener); } @Override diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java index 8d8aa25864..f96ecfb70b 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java @@ -21,9 +21,9 @@ import io.netty.channel.SimpleChannelInboundHandler; import org.ethereum.config.SystemProperties; import org.ethereum.core.Block; -import org.ethereum.core.BlockSummary; import org.ethereum.core.Blockchain; import org.ethereum.db.BlockStore; +import org.ethereum.listener.EthereumListener; import org.ethereum.net.MessageQueue; import org.ethereum.net.eth.EthVersion; import org.ethereum.net.eth.message.EthMessage; @@ -31,10 +31,10 @@ import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.message.ReasonCode; import org.ethereum.net.server.Channel; +import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.Publisher; import org.ethereum.publish.Subscription; -import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.Trace; +import org.ethereum.publish.event.BestBlockAdded; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,7 +53,7 @@ public abstract class EthHandler extends SimpleChannelInboundHandler protected SystemProperties config; - private Publisher publisher; + protected EthereumListener listener; protected Channel channel; @@ -66,7 +66,7 @@ public abstract class EthHandler extends SimpleChannelInboundHandler protected Block bestBlock; protected boolean processTransactions = false; - private Subscription bestBlockSub; + private Subscription bestBlockSub; protected EthHandler(EthVersion version) { this.version = version; @@ -74,20 +74,20 @@ protected EthHandler(EthVersion version) { protected EthHandler(final EthVersion version, final SystemProperties config, final Blockchain blockchain, final BlockStore blockStore, - final Publisher publisher) { + final EthereumListener listener) { this.version = version; this.config = config; this.blockchain = blockchain; this.bestBlock = blockStore.getBestBlock(); - this.publisher = publisher; - this.bestBlockSub = publisher.subscribe(BlockAdded.class, this::setBestBlock); + this.listener = listener; + this.bestBlockSub = getPublisher().subscribe(BestBlockAdded.class, this::setBestBlock); // when sync enabled we delay transactions processing until sync is complete this.processTransactions = !config.isSyncEnabled(); } - private void setBestBlock(BlockSummary blockSummary) { - this.bestBlock = blockSummary.getBlock(); + private void setBestBlock(BestBlockAdded.Data data) { + this.bestBlock = data.getBlockSummary().getBlock(); } @Override @@ -96,7 +96,7 @@ public void channelRead0(final ChannelHandlerContext ctx, EthMessage msg) throws if (EthMessageCodes.inRange(msg.getCommand().asByte(), version)) logger.trace("EthHandler invoke: [{}]", msg.getCommand()); - publisher.publish(new Trace(format("EthHandler invoke: [%s]", msg.getCommand()))); + listener.trace(format("EthHandler invoke: [%s]", msg.getCommand())); channel.getNodeStatistics().ethInbound.add(); @@ -104,7 +104,7 @@ public void channelRead0(final ChannelHandlerContext ctx, EthMessage msg) throws } public Publisher getPublisher() { - return publisher; + return ((BackwardCompatibilityEthereumListenerProxy) listener).getPublisher(); } @Override @@ -116,13 +116,13 @@ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws E @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { logger.debug("handlerRemoved: kill timers in EthHandler"); - publisher.unsubscribe(bestBlockSub); + getPublisher().unsubscribe(bestBlockSub); onShutdown(); } public void activate() { logger.debug("ETH protocol activated"); - publisher.publish(new Trace("ETH protocol activated")); + listener.trace("ETH protocol activated"); sendStatus(); } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java index 0239d2d145..d1144fd48d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java @@ -22,6 +22,7 @@ import org.ethereum.config.SystemProperties; import org.ethereum.core.Block; import org.ethereum.core.Transaction; +import org.ethereum.listener.EthereumListener; import org.ethereum.net.MessageQueue; import org.ethereum.net.client.Capability; import org.ethereum.net.client.ConfigCapabilities; @@ -33,9 +34,6 @@ import org.ethereum.net.shh.ShhHandler; import org.ethereum.net.swarm.Util; import org.ethereum.net.swarm.bzz.BzzHandler; -import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.Trace; -import org.ethereum.publish.event.message.PeerHandshaked; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -88,7 +86,7 @@ public class P2pHandler extends SimpleChannelInboundHandler { private int ethOutbound; @Autowired - private Publisher publisher; + private EthereumListener listener; @Autowired ConfigCapabilities configCapabilities; @@ -120,7 +118,7 @@ public void setPeerDiscoveryMode(boolean peerDiscoveryMode) { public void handlerAdded(ChannelHandlerContext ctx) throws Exception { logger.debug("P2P protocol activated"); msgQueue.activate(ctx); - publisher.publish(new Trace("P2P protocol activated")); + listener.trace("P2P protocol activated"); startTimers(); } @@ -131,7 +129,7 @@ public void channelRead0(final ChannelHandlerContext ctx, P2pMessage msg) throws if (P2pMessageCodes.inRange(msg.getCommand().asByte())) logger.trace("P2PHandler invoke: [{}]", msg.getCommand()); - publisher.publish(new Trace(format("P2PHandler invoke: [%s]", msg.getCommand()))); + listener.trace(format("P2PHandler invoke: [%s]", msg.getCommand())); switch (msg.getCommand()) { case HELLO: @@ -243,7 +241,7 @@ public void setHandshake(HelloMessage msg, ChannelHandlerContext ctx) { } //todo calculate the Offsets - publisher.publish(new PeerHandshaked(channel, msg)); + listener.onHandShakePeer(channel, msg); } /** diff --git a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java index 82a61560d4..2dfc3a744e 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java @@ -23,6 +23,7 @@ import org.apache.commons.collections4.map.LRUMap; import org.apache.commons.lang3.tuple.Pair; import org.ethereum.config.SystemProperties; +import org.ethereum.listener.EthereumListener; import org.ethereum.net.client.Capability; import org.ethereum.net.eth.EthVersion; import org.ethereum.net.eth.message.EthMessageCodes; @@ -33,9 +34,6 @@ import org.ethereum.net.server.Channel; import org.ethereum.net.shh.ShhMessageCodes; import org.ethereum.net.swarm.bzz.BzzMessageCodes; -import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.Trace; -import org.ethereum.publish.event.message.MessageReceived; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -74,7 +72,7 @@ public class MessageCodec extends MessageToMessageCodec { private EthVersion ethVersion; @Autowired - private Publisher publisher; + private EthereumListener listener; private SystemProperties config; @@ -168,7 +166,7 @@ private Message decodeMessage(ChannelHandlerContext ctx, List frames) thr return null; } - publisher.publish(new MessageReceived(channel, msg)); + listener.onRecvMessage(channel, msg); channel.getNodeStatistics().rlpxInMessages.add(); return msg; @@ -177,7 +175,8 @@ private Message decodeMessage(ChannelHandlerContext ctx, List frames) thr @Override protected void encode(ChannelHandlerContext ctx, Message msg, List out) throws Exception { String output = String.format("To: \t%s \tSend: \t%s", ctx.channel().remoteAddress(), msg); - publisher.publish(new Trace(output)); + + listener.trace(output); if (loggerNet.isDebugEnabled()) loggerNet.debug("To: {} Send: {}", channel, msg); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java index 5a2a9d3524..ca295e26e8 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java @@ -21,10 +21,9 @@ import org.ethereum.config.SystemProperties; import org.ethereum.crypto.ECKey; import org.ethereum.db.PeerSource; +import org.ethereum.listener.EthereumListener; import org.ethereum.net.rlpx.*; import org.ethereum.net.rlpx.discover.table.NodeTable; -import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.NodeDiscovered; import org.ethereum.util.CollectionUtils; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -61,7 +60,7 @@ public class NodeManager implements Consumer{ PeerConnectionTester peerConnectionManager; PeerSource peerSource; - Publisher publisher; + EthereumListener listener; SystemProperties config = SystemProperties.getDefault(); Consumer messageSender; @@ -85,10 +84,10 @@ public class NodeManager implements Consumer{ private ScheduledExecutorService pongTimer; @Autowired - public NodeManager(SystemProperties config, Publisher publisher, + public NodeManager(SystemProperties config, EthereumListener listener, ApplicationContext ctx, PeerConnectionTester peerConnectionManager) { this.config = config; - this.publisher = publisher; + this.listener = listener; this.peerConnectionManager = peerConnectionManager; PERSIST = config.peerDiscoveryPersist(); @@ -197,14 +196,14 @@ public synchronized NodeHandler getNodeHandler(Node n) { nodeHandlerMap.put(key, ret); logger.debug(" +++ New node: " + ret + " " + n); if (!n.isDiscoveryNode() && !n.getHexId().equals(homeNode.getHexId())) { - publisher.publish(new NodeDiscovered(ret.getNode())); + listener.onNodeDiscovered(ret.getNode()); } } else if (ret.getNode().isDiscoveryNode() && !n.isDiscoveryNode()) { // we found discovery node with same host:port, // replace node with correct nodeId ret.node = n; if (!n.getHexId().equals(homeNode.getHexId())) { - publisher.publish(new NodeDiscovered(ret.getNode())); + listener.onNodeDiscovered(ret.getNode()); } logger.debug(" +++ Found real nodeId for discovery endpoint {}", n); } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java b/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java index 0ee707d0e9..99cd8396e2 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java @@ -26,8 +26,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LoggingHandler; import org.ethereum.config.SystemProperties; -import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.Trace; +import org.ethereum.listener.EthereumListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -52,7 +51,7 @@ public class PeerServer { private ApplicationContext ctx; - private Publisher publisher; + private EthereumListener listener; public EthereumChannelInitializer ethereumChannelInitializer; @@ -64,10 +63,10 @@ public class PeerServer { @Autowired public PeerServer(final SystemProperties config, final ApplicationContext ctx, - final Publisher publisher) { + final EthereumListener listener) { this.ctx = ctx; this.config = config; - this.publisher = publisher; + this.listener = listener; } public void start(int port) { @@ -77,8 +76,7 @@ public void start(int port) { ethereumChannelInitializer = ctx.getBean(EthereumChannelInitializer.class, ""); - publisher.publish(new Trace("Listening on port " + port)); - + listener.trace("Listening on port " + port); try { ServerBootstrap b = new ServerBootstrap(); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java index 3ad2dd88f0..6a6bad2ca2 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java @@ -19,9 +19,8 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; +import org.ethereum.listener.EthereumListener; import org.ethereum.net.MessageQueue; -import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.Trace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -46,7 +45,7 @@ public class ShhHandler extends SimpleChannelInboundHandler { private BloomFilter peerBloomFilter = BloomFilter.createAll(); @Autowired - private Publisher publisher; + private EthereumListener listener; @Autowired private WhisperImpl whisper; @@ -66,11 +65,11 @@ public void channelRead0(final ChannelHandlerContext ctx, ShhMessage msg) throws if (ShhMessageCodes.inRange(msg.getCommand().asByte())) logger.info("ShhHandler invoke: [{}]", msg.getCommand()); - publisher.publish(new Trace(format("ShhHandler invoke: [%s]", msg.getCommand()))); + listener.trace(format("ShhHandler invoke: [%s]", msg.getCommand())); switch (msg.getCommand()) { case STATUS: - publisher.publish(new Trace("[Recv: " + msg + "]")); + listener.trace("[Recv: " + msg + "]"); break; case MESSAGE: whisper.processEnvelope((ShhEnvelopeMessage) msg, this); @@ -104,7 +103,7 @@ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { public void activate() { logger.info("SHH protocol activated"); - publisher.publish(new Trace("SHH protocol activated")); + listener.trace("SHH protocol activated"); whisper.addPeer(this); sendStatus(); sendHostBloom(); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java index 6255be34f6..991673ab50 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java @@ -19,10 +19,9 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; +import org.ethereum.listener.EthereumListener; import org.ethereum.net.MessageQueue; import org.ethereum.net.swarm.NetStore; -import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.Trace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -51,7 +50,7 @@ public class BzzHandler extends SimpleChannelInboundHandler BzzProtocol bzzProtocol; @Autowired - private Publisher publisher; + private EthereumListener listener; @Autowired NetStore netStore; @@ -71,7 +70,7 @@ public void channelRead0(final ChannelHandlerContext ctx, BzzMessage msg) throws if (BzzMessageCodes.inRange(msg.getCommand().asByte())) logger.debug("BzzHandler invoke: [{}]", msg.getCommand()); - publisher.publish(new Trace(format("BzzHandler invoke: [%s]", msg.getCommand()))); + listener.trace(format("BzzHandler invoke: [%s]", msg.getCommand())); if (bzzProtocol != null) { bzzProtocol.accept(msg); @@ -98,7 +97,7 @@ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { public void activate() { logger.info("BZZ protocol activated"); - publisher.publish(new Trace("BZZ protocol activated")); + listener.trace("BZZ protocol activated"); createBzzProtocol(); this.active = true; } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/BackwardCompatibilityEthereumListenerProxy.java b/ethereumj-core/src/main/java/org/ethereum/publish/BackwardCompatibilityEthereumListenerProxy.java index 6a53fb4b8c..3284589aca 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/BackwardCompatibilityEthereumListenerProxy.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/BackwardCompatibilityEthereumListenerProxy.java @@ -22,6 +22,14 @@ public BackwardCompatibilityEthereumListenerProxy(CompositeEthereumListener list this.publisher = publisher; } + public CompositeEthereumListener getCompositeListener() { + return compositeListener; + } + + public Publisher getPublisher() { + return publisher; + } + public void addListener(EthereumListener listener) { this.compositeListener.addListener(listener); } @@ -70,6 +78,7 @@ public void onBlock(BlockSummary blockSummary) { @Override public void onBlock(BlockSummary blockSummary, boolean best) { compositeListener.onBlock(blockSummary, best); + compositeListener.onBlock(blockSummary); publisher.publish(Events.onBlockAdded(blockSummary, best)); } @@ -124,4 +133,12 @@ public void onPeerAddedToSyncPool(Channel peer) { compositeListener.onPeerAddedToSyncPool(peer); publisher.publish(Events.onPeerAddedToSyncPool(peer)); } + + public static BackwardCompatibilityEthereumListenerProxy createDefault() { + EventDispatchThread eventDispatchThread = EventDispatchThread.getDefault(); + CompositeEthereumListener compositeEthereumListener = new CompositeEthereumListener(eventDispatchThread); + Publisher publisher = new Publisher(eventDispatchThread); + + return new BackwardCompatibilityEthereumListenerProxy(compositeEthereumListener, publisher); + } } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java index 8e3815db63..58703c3afd 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java @@ -1,17 +1,9 @@ package org.ethereum.publish; -import org.ethereum.core.*; -import org.ethereum.listener.EthereumListener; -import org.ethereum.net.eth.message.StatusMessage; -import org.ethereum.net.message.Message; -import org.ethereum.net.p2p.HelloMessage; -import org.ethereum.net.rlpx.Node; -import org.ethereum.net.server.Channel; -import org.ethereum.publish.event.*; -import org.ethereum.publish.event.message.EthStatusUpdated; -import org.ethereum.publish.event.message.PeerHandshaked; -import org.ethereum.publish.event.message.MessageReceived; -import org.ethereum.publish.event.message.MessageSent; +import org.ethereum.core.EventDispatchThread; +import org.ethereum.publish.event.Event; +import org.ethereum.publish.event.SignalEvent; +import org.ethereum.publish.event.Single; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,7 +18,6 @@ import static java.util.Collections.emptyList; import static java.util.Objects.nonNull; import static java.util.stream.Collectors.toList; -import static org.ethereum.publish.Subscription.to; /** * Event publisher that uses pub/sub model to deliver event messages.
      @@ -200,127 +191,4 @@ public int subscribersCount() { .mapToInt(List::size) .sum(); } - - /** - * Method that subscribes all {@link EthereumListener} callbacks to corresponding events. - * Avoid using this method directly, because it creates unnecessary stub {@link Subscription}s. - * Uses for backward compatibility only and will be removed in future releases. - * - * @param listener highly likely {@link org.ethereum.listener.EthereumListenerAdapter} subclass. - */ - public void subscribeListener(EthereumListener listener) { - this - .subscribe(to(Trace.class, listener::trace)) - .subscribe(to(NodeDiscovered.class, listener::onNodeDiscovered)) - .subscribe(to(PeerHandshaked.class, data -> listener.onHandShakePeer(data.getChannel(), data.getMessage()))) - .subscribe(to(EthStatusUpdated.class, data -> listener.onEthStatusUpdated(data.getChannel(), data.getMessage()))) - .subscribe(to(MessageReceived.class, data -> listener.onRecvMessage(data.getChannel(), data.getMessage()))) - .subscribe(to(MessageSent.class, data -> listener.onSendMessage(data.getChannel(), data.getMessage()))) - .subscribe(to(BlockAdded.class, listener::onBlock)) - .subscribe(to(BestBlockAdded.class, data -> listener.onBlock(data.getBlockSummary(), data.isBest()))) - .subscribe(to(PeerDisconnected.class, data -> listener.onPeerDisconnect(data.getHost(), data.getPort()))) - .subscribe(to(PendingTransactionsReceived.class, listener::onPendingTransactionsReceived)) - .subscribe(to(PendingStateChanged.class, listener::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdated.class, data -> listener.onPendingTransactionUpdate(data.getReceipt(), data.getState(), data.getBlock()))) - .subscribe(to(SyncDone.class, listener::onSyncDone)) - .subscribe(to(NoConnections.class, data -> listener.onNoConnections())) - .subscribe(to(VmTraceCreated.class, data -> listener.onVMTraceCreated(data.getTxHash(), data.getTrace()))) - .subscribe(to(TransactionExecuted.class, listener::onTransactionExecuted)) - .subscribe(to(PeerAddedToSyncPool.class, listener::onPeerAddedToSyncPool)); - } - - /** - * Creates backward compatibility adaptor for {@link EthereumListener}. - * Uses for backward compatibility only and will be removed in future releases. - * - * @return instance of EthereumListener that proxies all method invokes to publishing corresponding events. - */ - public EthereumListener asListener() { - return new EthereumListener() { - @Override - public void trace(String output) { - publish(new Trace(output)); - } - - @Override - public void onNodeDiscovered(Node node) { - publish(new NodeDiscovered(node)); - } - - @Override - public void onHandShakePeer(Channel channel, HelloMessage helloMessage) { - publish(new PeerHandshaked(channel, helloMessage)); - } - - @Override - public void onEthStatusUpdated(Channel channel, StatusMessage status) { - publish(new EthStatusUpdated(channel, status)); - } - - @Override - public void onRecvMessage(Channel channel, Message message) { - publish(new MessageReceived(channel, message)); - } - - @Override - public void onSendMessage(Channel channel, Message message) { - publish(new MessageSent(channel, message)); - } - - @Override - public void onBlock(BlockSummary blockSummary) { - publish(new BlockAdded(blockSummary)); - } - - @Override - public void onBlock(BlockSummary blockSummary, boolean best) { - publish(new BestBlockAdded(blockSummary, best)); - } - - @Override - public void onPeerDisconnect(String host, long port) { - publish(new PeerDisconnected(host, port)); - } - - @Override - public void onPendingTransactionsReceived(List transactions) { - publish(new PendingTransactionsReceived(transactions)); - } - - @Override - public void onPendingStateChanged(PendingState pendingState) { - publish(new PendingStateChanged(pendingState)); - } - - @Override - public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionState state, Block block) { - publish(new PendingTransactionUpdated(block, txReceipt, state)); - } - - @Override - public void onSyncDone(SyncState state) { - publish(new SyncDone(state)); - } - - @Override - public void onNoConnections() { - publish(new NoConnections()); - } - - @Override - public void onVMTraceCreated(String transactionHash, String trace) { - publish(new VmTraceCreated(transactionHash, trace)); - } - - @Override - public void onTransactionExecuted(TransactionExecutionSummary summary) { - publish(new TransactionExecuted(summary)); - } - - @Override - public void onPeerAddedToSyncPool(Channel peer) { - publish(new PeerAddedToSyncPool(peer)); - } - }; - } } diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java index 7f06bf8b97..d662477bb3 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java @@ -25,12 +25,13 @@ import ch.qos.logback.core.spi.FilterReply; import org.ethereum.config.SystemProperties; import org.ethereum.core.Block; +import org.ethereum.core.BlockSummary; import org.ethereum.core.TransactionReceipt; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.NodeDiscovered; import org.ethereum.publish.event.PeerAddedToSyncPool; import org.ethereum.publish.event.SyncDone; @@ -140,9 +141,10 @@ private void springInit() { .conditionally(node -> nodesDiscovered.size() < 1000)) .subscribe(to(EthStatusUpdated.class, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage()))) .subscribe(to(PeerAddedToSyncPool.class, peer -> syncPeers.add(peer.getNode()))) - .subscribe(to(BlockAdded.class, bs -> { - Block block = bs.getBlock(); - List receipts = bs.getReceipts(); + .subscribe(to(BestBlockAdded.class, data -> { + BlockSummary blockSummary = data.getBlockSummary(); + Block block = blockSummary.getBlock(); + List receipts = blockSummary.getReceipts(); bestBlock = block; txCount += receipts.size(); diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java index 582fbf2097..4f9d87196f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java @@ -17,14 +17,13 @@ */ package org.ethereum.samples; -import org.ethereum.core.BlockSummary; import org.ethereum.core.CallTransaction; import org.ethereum.core.Transaction; import org.ethereum.core.TransactionReceipt; import org.ethereum.crypto.ECKey; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.solidity.compiler.CompilationResult; import org.ethereum.solidity.compiler.SolidityCompiler; import org.ethereum.util.ByteUtil; @@ -65,7 +64,7 @@ public class CreateContractSample extends TestNetSample { @Override public void onSyncDone() throws Exception { // when block arrives look for our included transactions - ethereum.subscribe(to(BlockAdded.class, this::onBlock)); + ethereum.subscribe(to(BestBlockAdded.class, this::onBlock)); logger.info("Compiling contract..."); SolidityCompiler.Result result = compiler.compileSrc(contract.getBytes(), true, true, @@ -127,8 +126,8 @@ protected TransactionReceipt sendTxAndWait(byte[] receiveAddress, byte[] data) t return waitForTx(tx.getHash()); } - private void onBlock(BlockSummary blockSummary) { - for (TransactionReceipt receipt : blockSummary.getReceipts()) { + private void onBlock(BestBlockAdded.Data data) { + for (TransactionReceipt receipt : data.getBlockSummary().getReceipts()) { ByteArrayWrapper txHashW = new ByteArrayWrapper(receipt.getTransaction().getHash()); if (txWaiters.containsKey(txHashW)) { diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java index 22cecd4fba..72f463d438 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java @@ -27,7 +27,7 @@ import org.ethereum.listener.EthereumListener; import org.ethereum.listener.EventListener; import org.ethereum.listener.TxStatus; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.PendingTransactionUpdated; import org.ethereum.solidity.compiler.CompilationResult; import org.ethereum.solidity.compiler.SolidityCompiler; @@ -284,7 +284,7 @@ private void waitForEther(byte[] address, BigInteger requiredBalance) throws Int */ private void deployContractAndTest() throws Exception { // when block arrives look for our included transactions - ethereum.subscribe(to(BlockAdded.class, this::onBlock)); + ethereum.subscribe(to(BestBlockAdded.class, this::onBlock)); CompilationResult.ContractMetadata metadata = compileContract(); @@ -381,8 +381,8 @@ protected TransactionReceipt sendTxAndWait(byte[] receiveAddress, return waitForTx(txHashW); } - private void onBlock(BlockSummary blockSummary) { - for (TransactionReceipt receipt : blockSummary.getReceipts()) { + private void onBlock(BestBlockAdded.Data data) { + for (TransactionReceipt receipt : data.getBlockSummary().getReceipts()) { ByteArrayWrapper txHashW = new ByteArrayWrapper(receipt.getTransaction().getHash()); if (txWaiters.containsKey(txHashW)) { txWaiters.put(txHashW, receipt); diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java b/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java index 8bb30bcf40..eafefffbbd 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java @@ -21,7 +21,7 @@ import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; import org.ethereum.facade.Repository; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.spongycastle.util.encoders.Hex; import java.math.BigInteger; @@ -32,7 +32,7 @@ public class FollowAccount { public static void main(String[] args) { Ethereum ethereum = EthereumFactory.createEthereum(); - ethereum.subscribe(to(BlockAdded.class, blockSummary -> { + ethereum.subscribe(to(BestBlockAdded.class, data -> { byte[] cow = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826"); // Get snapshot some time ago - 10% blocks ago @@ -48,7 +48,7 @@ public static void main(String[] args) { BigInteger nonce = repository.getNonce(cow); System.err.printf(" #%d [cd2a3d9] => snapshot_nonce:%d latest_nonce:%d\n", - blockSummary.getBlock().getNumber(), nonce_, nonce); + data.getBlockSummary().getBlock().getNumber(), nonce_, nonce); })); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java index e85b65d0e1..dd37bc296c 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java @@ -21,7 +21,7 @@ import org.ethereum.crypto.ECKey; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.PendingTransactionsReceived; import org.ethereum.util.ByteUtil; import org.springframework.beans.factory.annotation.Autowired; @@ -67,7 +67,7 @@ public void onSyncDone() { // listening here when the PendingState is updated with new transactions .subscribe(to(PendingTransactionsReceived.class, txs -> txs.forEach(this::onPendingTransactionReceived))) // when block arrives look for our included transactions - .subscribe(to(BlockAdded.class, this::onBlock)); + .subscribe(to(BestBlockAdded.class, this::onBlock)); new Thread(() -> { try { @@ -140,7 +140,8 @@ void onPendingTransactionReceived(Transaction tx) { * For each block we are looking for our transactions and clearing them * The actual receiver balance is confirmed upon block arrival */ - public void onBlock(BlockSummary blockSummary) { + public void onBlock(BestBlockAdded.Data data) { + BlockSummary blockSummary = data.getBlockSummary(); onBlock(blockSummary.getBlock(), blockSummary.getReceipts()); } diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java b/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java index 356f10b135..69e59a70c0 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java @@ -17,14 +17,13 @@ */ package org.ethereum.samples; -import org.ethereum.core.BlockSummary; import org.ethereum.core.Transaction; import org.ethereum.core.TransactionReceipt; import org.ethereum.crypto.ECKey; import org.ethereum.crypto.HashUtil; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.util.ByteUtil; import org.ethereum.util.blockchain.EtherUtil; import org.spongycastle.util.encoders.Hex; @@ -51,7 +50,7 @@ public class SendTransaction extends BasicSample { @Override public void onSyncDone() throws Exception { // when block arrives look for our included transactions - this.ethereum.subscribe(to(BlockAdded.class, this::onBlock)); + this.ethereum.subscribe(to(BestBlockAdded.class, this::onBlock)); String toAddress = ""; logger.info("Sending transaction to net and waiting for inclusion"); @@ -59,8 +58,8 @@ public void onSyncDone() throws Exception { logger.info("Transaction included!"); } - private void onBlock(BlockSummary blockSummary) { - for (TransactionReceipt receipt : blockSummary.getReceipts()) { + private void onBlock(BestBlockAdded.Data data) { + for (TransactionReceipt receipt : data.getBlockSummary().getReceipts()) { ByteArrayWrapper txHashW = new ByteArrayWrapper(receipt.getTransaction().getHash()); if (txWaiters.containsKey(txHashW)) { txWaiters.put(txHashW, receipt); diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java b/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java index 04b0de45ec..e3b2539511 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java @@ -17,12 +17,11 @@ */ package org.ethereum.samples; -import org.ethereum.core.BlockSummary; import org.ethereum.core.Transaction; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; import org.ethereum.listener.EthereumListener; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.SyncDone; import org.spongycastle.util.encoders.Hex; @@ -43,7 +42,7 @@ public TransactionBomb(Ethereum ethereum) { this.ethereum = ethereum; this.ethereum .subscribe(to(SyncDone.class, this::onSyncDone)) - .subscribe(to(BlockAdded.class, this::onBlock)); + .subscribe(to(BestBlockAdded.class, this::onBlock)); } public static void main(String[] args) { @@ -59,8 +58,7 @@ public void onSyncDone(EthereumListener.SyncState state) { System.err.println(" ~~~ SYNC DONE ~~~ "); } - public void onBlock(BlockSummary blockSummary) { - + public void onBlock(BestBlockAdded.Data data) { if (startedTxBomb){ byte[] sender = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826"); long nonce = ethereum.getRepository().getNonce(sender).longValue(); diff --git a/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java b/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java index dc669786bb..c63e45148c 100644 --- a/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java @@ -106,9 +106,12 @@ public class FastSyncManager { @Autowired DbFlushManager dbFlushManager; + @Autowired + private EthereumListener listener; @Autowired private Publisher publisher; + @Autowired ApplicationContext applicationContext; @@ -754,8 +757,7 @@ private void fireSyncDone(EthereumListener.SyncState state) { // prevent early state notification when sync is not yet done syncManager.setSyncDoneType(state); if (syncManager.isSyncDone()) { -// listener.onSyncDone(state); - publisher.publish(new SyncDone(state)); + listener.onSyncDone(state); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java b/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java index 6f1201a9a0..1e7ec58e91 100644 --- a/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java @@ -23,8 +23,6 @@ import org.ethereum.listener.EthereumListener; import org.ethereum.net.server.Channel; import org.ethereum.net.server.ChannelManager; -import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.SyncDone; import org.ethereum.util.ExecutorPipeline; import org.ethereum.validator.BlockHeaderValidator; import org.slf4j.Logger; @@ -86,7 +84,7 @@ public void accept(BlockWrapper blockWrapper) { private Blockchain blockchain; @Autowired - private Publisher publisher; + private EthereumListener listener; @Autowired private FastSyncManager fastSyncManager; @@ -341,7 +339,7 @@ private synchronized void makeSyncDone() { if (syncDone) return; syncDone = true; channelManager.onSyncDone(true); - publisher.publish(new SyncDone(syncDoneType)); + listener.onSyncDone(syncDoneType); } public CompletableFuture switchToShortSync() { diff --git a/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java b/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java index 22d91a021c..7c1b379a3a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java +++ b/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java @@ -19,14 +19,13 @@ import org.ethereum.config.SystemProperties; import org.ethereum.core.Blockchain; +import org.ethereum.listener.EthereumListener; import org.ethereum.net.message.ReasonCode; import org.ethereum.net.rlpx.Node; import org.ethereum.net.rlpx.discover.NodeHandler; import org.ethereum.net.rlpx.discover.NodeManager; import org.ethereum.net.server.Channel; import org.ethereum.net.server.ChannelManager; -import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.PeerAddedToSyncPool; import org.ethereum.util.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -71,7 +70,7 @@ public class SyncPool { private BigInteger lowerUsefulDifficulty = BigInteger.ZERO; @Autowired - private Publisher publisher; + private EthereumListener listener; @Autowired private NodeManager nodeManager; @@ -340,7 +339,7 @@ private synchronized void prepareActive() { for (Channel channel : filtered) { if (!activePeers.contains(channel)) { - publisher.publish(new PeerAddedToSyncPool(channel)); + listener.onPeerAddedToSyncPool(channel); } } if (logger.isTraceEnabled()) diff --git a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java index 7e4039e969..ec60c961fc 100644 --- a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java @@ -32,9 +32,9 @@ import org.ethereum.db.RepositoryRoot; import org.ethereum.listener.EthereumListener; import org.ethereum.mine.Ethash; -import org.ethereum.publish.Publisher; +import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.Subscription; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.Event; import org.ethereum.solidity.compiler.CompilationResult; import org.ethereum.solidity.compiler.CompilationResult.ContractMetadata; @@ -54,8 +54,8 @@ import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutionException; -import java.util.function.Consumer; +import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.ByteUtil.wrap; /** @@ -67,7 +67,6 @@ public class StandaloneBlockchain implements LocalBlockchain { private byte[] coinbase; private BlockchainImpl blockchain; private PendingStateImpl pendingState; - private Publisher publisher; private ECKey txSender; private long gasPrice; private long gasLimit; @@ -86,6 +85,7 @@ public class StandaloneBlockchain implements LocalBlockchain { private PruneManager pruneManager; private BlockSummary lastSummary; + private final BackwardCompatibilityEthereumListenerProxy listenerProxy; class PendingTx { ECKey sender; @@ -136,7 +136,7 @@ public StandaloneBlockchain() { setSender(ECKey.fromPrivate(Hex.decode("3ec771c31cac8c0dba77a69e503765701d3c2bb62435888d4ffa38fed60c445c"))); // withAccountBalance(txSender.getAddress(), new BigInteger("100000000000000000000000000")); - publisher = new Publisher(EventDispatchThread.getDefault()); + listenerProxy = BackwardCompatibilityEthereumListenerProxy.createDefault(); } public StandaloneBlockchain withGenesis(Genesis genesis) { @@ -438,28 +438,23 @@ public BlockchainImpl getBlockchain() { if (blockchain == null) { blockchain = createBlockchain(genesis); blockchain.setMinerCoinbase(coinbase); - subscribe(BlockAdded.class, blockSummary -> lastSummary = blockSummary); + subscribe(to(BestBlockAdded.class, data -> lastSummary = data.getBlockSummary())); } return blockchain; } /** * @param listener - * @deprecated use {@link #subscribe(Class, Consumer)} instead. + * @deprecated use {@link #subscribe(Subscription)} instead. */ @Deprecated public void addEthereumListener(EthereumListener listener) { getBlockchain(); - publisher.subscribeListener(listener); + listenerProxy.addListener(listener); } public , P> StandaloneBlockchain subscribe(Subscription subscription) { - publisher.subscribe(subscription); - return this; - } - - public , P> StandaloneBlockchain subscribe(Class eventType, Consumer

      handler) { - publisher.subscribe(eventType, handler); + listenerProxy.getPublisher().subscribe(subscription); return this; } @@ -498,7 +493,7 @@ private BlockchainImpl createBlockchain(Genesis genesis) { ProgramInvokeFactoryImpl programInvokeFactory = new ProgramInvokeFactoryImpl(); - BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository, publisher) + BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository, listenerProxy) .withSyncManager(new SyncManager()); blockchain.setParentHeaderValidator(new DependentBlockHeaderRuleAdapter()); blockchain.setProgramInvokeFactory(programInvokeFactory); @@ -506,7 +501,7 @@ private BlockchainImpl createBlockchain(Genesis genesis) { blockchain.byTest = true; - pendingState = new PendingStateImpl(publisher); + pendingState = new PendingStateImpl(listenerProxy); pendingState.setBlockchain(blockchain); blockchain.setPendingState(pendingState); diff --git a/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java b/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java index 5034482271..98807594a1 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java @@ -19,7 +19,7 @@ import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; @@ -44,7 +44,7 @@ public void relaunchTest() throws InterruptedException { Assert.assertNotNull(bestBlock); final CountDownLatch latch = new CountDownLatch(1); AtomicInteger counter = new AtomicInteger(); - ethereum.subscribe(to(BlockAdded.class, blockSummary -> { + ethereum.subscribe(to(BestBlockAdded.class, data -> { if (counter.addAndGet(1) > 1100) { latch.countDown(); } diff --git a/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java b/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java index 1e798386a2..901e65afaa 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java @@ -27,7 +27,7 @@ import org.ethereum.db.IndexedBlockStore; import org.ethereum.db.RepositoryRoot; import org.ethereum.mine.Ethash; -import org.ethereum.publish.Publisher; +import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.event.TransactionExecuted; import org.ethereum.util.ByteUtil; import org.ethereum.util.blockchain.SolidityContract; @@ -45,6 +45,8 @@ import java.math.BigInteger; import java.util.*; +import static org.ethereum.publish.Subscription.to; + /** * Created by Anton Nashatyrev on 29.12.2015. */ @@ -772,7 +774,7 @@ public void suicideInFailedCall() throws Exception { SolidityContract a = bc.submitNewContract(contractA, "A"); bc.createBlock(); final BigInteger[] refund = new BigInteger[1]; - bc.subscribe(TransactionExecuted.class, tes -> refund[0] = tes.getGasRefund()); + bc.subscribe(to(TransactionExecuted.class, tes -> refund[0] = tes.getGasRefund())); a.callFunction("f"); bc.createBlock(); @@ -800,7 +802,7 @@ public void logInFailedCall() throws Exception { SolidityContract a = bc.submitNewContract(contractA, "A"); bc.createBlock(); final List logs = new ArrayList<>(); - bc.subscribe(TransactionExecuted.class, tes -> logs.addAll(tes.getLogs())); + bc.subscribe(to(TransactionExecuted.class, tes -> logs.addAll(tes.getLogs()))); a.callFunction("f"); bc.createBlock(); @@ -885,14 +887,15 @@ public static BlockchainImpl createBlockchain(Genesis genesis) { ProgramInvokeFactoryImpl programInvokeFactory = new ProgramInvokeFactoryImpl(); - BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository, new Publisher(EventDispatchThread.getDefault())) + BackwardCompatibilityEthereumListenerProxy listenerProxy = BackwardCompatibilityEthereumListenerProxy.createDefault(); + BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository, listenerProxy) .withParentBlockHeaderValidator(new CommonConfig().parentHeaderValidator()); blockchain.setParentHeaderValidator(new DependentBlockHeaderRuleAdapter()); blockchain.setProgramInvokeFactory(programInvokeFactory); blockchain.byTest = true; - PendingStateImpl pendingState = new PendingStateImpl(new Publisher(EventDispatchThread.getDefault())); + PendingStateImpl pendingState = new PendingStateImpl(listenerProxy); pendingState.setBlockchain(blockchain); blockchain.setPendingState(pendingState); diff --git a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateLongRunTest.java b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateLongRunTest.java index 884de68842..926e5317f0 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateLongRunTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateLongRunTest.java @@ -21,7 +21,7 @@ import org.ethereum.datasource.inmem.HashMapDB; import org.ethereum.db.IndexedBlockStore; import org.ethereum.db.RepositoryRoot; -import org.ethereum.publish.Publisher; +import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.validator.DependentBlockHeaderRuleAdapter; import org.ethereum.vm.program.invoke.ProgramInvokeFactoryImpl; import org.junit.Before; @@ -124,14 +124,15 @@ private Blockchain createBlockchain(Genesis genesis) { ProgramInvokeFactoryImpl programInvokeFactory = new ProgramInvokeFactoryImpl(); - BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository, new Publisher(EventDispatchThread.getDefault())) + BackwardCompatibilityEthereumListenerProxy listenerProxy = BackwardCompatibilityEthereumListenerProxy.createDefault(); + BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository, listenerProxy) .withParentBlockHeaderValidator(new CommonConfig().parentHeaderValidator()); blockchain.setParentHeaderValidator(new DependentBlockHeaderRuleAdapter()); blockchain.setProgramInvokeFactory(programInvokeFactory); blockchain.byTest = true; - PendingStateImpl pendingState = new PendingStateImpl(new Publisher(EventDispatchThread.getDefault())); + PendingStateImpl pendingState = new PendingStateImpl(listenerProxy); pendingState.setBlockchain(blockchain); blockchain.setPendingState(pendingState); diff --git a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java index 3667cc1a67..9922d7128e 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java @@ -23,7 +23,7 @@ import org.ethereum.crypto.ECKey; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.listener.EthereumListener; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.PendingStateChanged; import org.ethereum.publish.event.PendingTransactionUpdated; import org.ethereum.util.blockchain.SolidityContract; @@ -73,7 +73,8 @@ static class PendingListener { Map>> onPendingTransactionUpdate = new HashMap<>(); - public void onBlock(BlockSummary blockSummary) { + public void onBlock(BestBlockAdded.Data data) { + BlockSummary blockSummary = data.getBlockSummary(); Block block = blockSummary.getBlock(); System.out.println("PendingStateTest.onBlock:" + "block = [" + block.getShortDescr() + "]"); onBlock.add(Pair.of(block, blockSummary.getReceipts())); @@ -117,7 +118,7 @@ public Triple runTestCase(BlockTestCase testCase) { ProgramInvokeFactoryImpl programInvokeFactory = new ProgramInvokeFactoryImpl(); - BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository, new Publisher(EventDispatchThread.getDefault())) + BackwardCompatibilityEthereumListenerProxy listenerProxy = BackwardCompatibilityEthereumListenerProxy.createDefault(); + BlockchainImpl blockchain = new BlockchainImpl(blockStore, repository, listenerProxy) .withParentBlockHeaderValidator(CommonConfig.getDefault().parentHeaderValidator()); blockchain.byTest = true; - PendingStateImpl pendingState = new PendingStateImpl(new Publisher(EventDispatchThread.getDefault())); + PendingStateImpl pendingState = new PendingStateImpl(listenerProxy); blockchain.setBestBlock(genesis); blockchain.setTotalDifficulty(genesis.getDifficultyBI()); diff --git a/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java b/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java index 3329f330ca..f253afcf9b 100644 --- a/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java +++ b/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java @@ -20,7 +20,6 @@ import org.ethereum.config.CommonConfig; import org.ethereum.config.SystemProperties; import org.ethereum.core.Block; -import org.ethereum.core.BlockSummary; import org.ethereum.db.DbFlushManager; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; @@ -28,7 +27,7 @@ import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.rlpx.Node; import org.ethereum.net.server.Channel; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.PeerAddedToSyncPool; import org.ethereum.publish.event.SyncDone; import org.ethereum.publish.event.message.EthStatusUpdated; @@ -109,7 +108,7 @@ private void springInit() { // adding the main EthereumJ callback to be notified on different kind of events this.ethereum .subscribe(to(SyncDone.class, this::onSyncDone)) - .subscribe(to(BlockAdded.class, this::onBlock)) + .subscribe(to(BestBlockAdded.class, this::onBlock)) .subscribe(to(EthStatusUpdated.class, this::onEthStatusUpdated)) .subscribe(to(PeerAddedToSyncPool.class, this::onPeerAddedToSyncPool)); @@ -192,8 +191,8 @@ public void onPeerAddedToSyncPool(Channel peer) { syncPeers.add(peer.getNode()); } - public void onBlock(BlockSummary blockSummary) { - Block block = blockSummary.getBlock(); + public void onBlock(BestBlockAdded.Data data) { + Block block = data.getBlockSummary().getBlock(); bestBlock = block; if (syncComplete) { diff --git a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java index 53beb794ca..7d8e70f681 100644 --- a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java @@ -25,8 +25,8 @@ import org.ethereum.db.ContractDetails; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.listener.EthereumListener; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.PendingTransactionsReceived; import org.ethereum.sync.SyncManager; import org.ethereum.util.FastByteComparisons; @@ -197,7 +197,7 @@ public void onPendingTransactionsReceived(List transactions) { try { TransactionExecutor executor = new TransactionExecutor (tx, block.getCoinbase(), repository, ethereum.getBlockchain().getBlockStore(), - programInvokeFactory, block, new Publisher(EventDispatchThread.getDefault()), 0) + programInvokeFactory, block, EthereumListener.STUB, 0) .withCommonConfig(commonConfig) .setLocalCall(true); @@ -221,7 +221,7 @@ public RegularNode() { public void run() { try { this.ethereum - .subscribe(to(BlockAdded.class, this::onBlock)) + .subscribe(to(BestBlockAdded.class, this::onBlock)) .subscribe(to(PendingTransactionsReceived.class, this::onPendingTransactionsReceived)); // Run 1-30 minutes diff --git a/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java b/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java index f1340685bb..af6ab46d70 100644 --- a/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java @@ -30,7 +30,7 @@ import org.ethereum.facade.EthereumFactory; import org.ethereum.net.eth.handler.Eth62; import org.ethereum.net.eth.message.NewBlockMessage; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.PendingTransactionsReceived; import org.ethereum.publish.event.SyncDone; import org.ethereum.util.ByteUtil; @@ -107,8 +107,8 @@ public void startMiningConsumer() throws Exception { Ethereum ethereum2 = EthereumFactory.createEthereum(SysPropConfig2.props, SysPropConfig2.class); final CountDownLatch semaphore = new CountDownLatch(1); - ethereum2.subscribe(to(BlockAdded.class, blockSummary -> { - Block block = blockSummary.getBlock(); + ethereum2.subscribe(to(BestBlockAdded.class, data -> { + Block block = data.getBlockSummary().getBlock(); System.err.println("=== New block: " + blockInfo(block)); System.err.println(block); @@ -205,7 +205,7 @@ public void startMiningTest() throws FileNotFoundException, InterruptedException final CountDownLatch semaphore = new CountDownLatch(1); ethereum1 - .subscribe(to(BlockAdded.class, blockSummary -> System.out.println("=== New block: " + blockInfo(blockSummary.getBlock())))) + .subscribe(to(BestBlockAdded.class, data -> System.out.println("=== New block: " + blockInfo(data.getBlockSummary().getBlock())))) .subscribe(to(SyncDone.class, syncState -> semaphore.countDown())); // ethereum2.addListener(new EthereumListenerAdapter() { diff --git a/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java b/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java index 1ef39e0d63..31d86ae64b 100644 --- a/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java @@ -28,7 +28,7 @@ import org.ethereum.facade.SyncStatus; import org.ethereum.net.eth.handler.Eth62; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.PeerAddedToSyncPool; import org.ethereum.util.FastByteComparisons; import org.ethereum.util.blockchain.EtherUtil; @@ -161,8 +161,8 @@ public void test1() throws InterruptedException { assertTrue(loadedBlocks > 0); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, bs -> semaphore.countDown()) - .conditionally(bs -> isBlockNumber(bs, loadedBlocks))); + ethereumB.subscribe(to(BestBlockAdded.class, data -> semaphore.countDown()) + .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks))); semaphore.await(MAX_SECONDS_WAIT, SECONDS); assertEquals(0, semaphore.getCount()); @@ -171,15 +171,15 @@ public void test1() throws InterruptedException { ethereumA.getBlockMiner().startMining(); final CountDownLatch semaphore2 = new CountDownLatch(2); - ethereumB.subscribe(to(BlockAdded.class, bs -> { - if (isBlockNumber(bs, loadedBlocks + 2)) { + ethereumB.subscribe(to(BestBlockAdded.class, data -> { + if (isBlockNumber(data.getBlockSummary(), loadedBlocks + 2)) { semaphore2.countDown(); ethereumA.getBlockMiner().stopMining(); } })); - ethereumA.subscribe(to(BlockAdded.class, bs -> semaphore2.countDown()) - .conditionally(bs -> isBlockNumber(bs, loadedBlocks + 2))); + ethereumA.subscribe(to(BestBlockAdded.class, data -> semaphore2.countDown()) + .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks + 2))); semaphore2.await(MAX_SECONDS_WAIT, SECONDS); Assert.assertEquals(0, semaphore2.getCount()); @@ -200,8 +200,8 @@ public void test1() throws InterruptedException { ); tx.sign(sender); final CountDownLatch txSemaphore = new CountDownLatch(1); - ethereumA.subscribe(to(BlockAdded.class, blockSummary -> { - + ethereumA.subscribe(to(BestBlockAdded.class, data -> { + BlockSummary blockSummary = data.getBlockSummary(); if (!blockSummary.getBlock().getTransactionsList().isEmpty() && FastByteComparisons.equal(blockSummary.getBlock().getTransactionsList().get(0).getSender(), sender.getAddress()) && blockSummary.getReceipts().get(0).isSuccessful()) { @@ -212,11 +212,11 @@ public void test1() throws InterruptedException { ethereumB.submitTransaction(tx); final CountDownLatch semaphore3 = new CountDownLatch(2); - ethereumB.subscribe(to(BlockAdded.class, blockSummary -> semaphore3.countDown()) - .conditionally(bs -> isBlockNumber(bs, loadedBlocks + 5))); + ethereumB.subscribe(to(BestBlockAdded.class, data -> semaphore3.countDown()) + .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks + 5))); - ethereumA.subscribe(to(BlockAdded.class, blockSummary -> { - if (isBlockNumber(blockSummary, loadedBlocks + 5)) { + ethereumA.subscribe(to(BestBlockAdded.class, data -> { + if (isBlockNumber(data.getBlockSummary(), loadedBlocks + 5)) { semaphore3.countDown(); ethereumA.getBlockMiner().stopMining(); } @@ -252,15 +252,15 @@ public void test1() throws InterruptedException { final CountDownLatch semaphore4 = new CountDownLatch(2); - ethereumB.subscribe(to(BlockAdded.class, bs -> { - if (isBlockNumber(bs, loadedBlocks + 9)) { + ethereumB.subscribe(to(BestBlockAdded.class, data -> { + if (isBlockNumber(data.getBlockSummary(), loadedBlocks + 9)) { semaphore4.countDown(); ethereumA.getBlockMiner().stopMining(); } })); - ethereumA.subscribe(to(BlockAdded.class, blockSummary -> semaphore4.countDown()) - .conditionally(bs -> isBlockNumber(bs, loadedBlocks + 9))); + ethereumA.subscribe(to(BestBlockAdded.class, data -> semaphore4.countDown()) + .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks + 9))); semaphore4.await(MAX_SECONDS_WAIT, SECONDS); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java b/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java index 8c26d3efe2..15450764a8 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java @@ -31,7 +31,7 @@ import org.ethereum.net.eth.message.GetBlockBodiesMessage; import org.ethereum.net.eth.message.GetBlockHeadersMessage; import org.ethereum.net.server.Channel; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.message.EthStatusUpdated; import org.ethereum.util.RLP; import org.junit.Ignore; @@ -231,8 +231,8 @@ protected void processGetBlockBodies(GetBlockBodiesMessage msg) { System.out.println("==== Got the Channel: " + data.getChannel()); })); - ethereum2.subscribe(to(BlockAdded.class, blockSummary -> { - Block block = blockSummary.getBlock(); + ethereum2.subscribe(to(BestBlockAdded.class, data -> { + Block block = data.getBlockSummary().getBlock(); if (block.getNumber() == 4) { semaphore.countDown(); } diff --git a/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java b/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java index ba8821826a..c53d747d49 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java @@ -19,13 +19,16 @@ import org.ethereum.config.NoAutoscan; import org.ethereum.config.SystemProperties; -import org.ethereum.core.*; +import org.ethereum.core.Block; +import org.ethereum.core.BlockHeader; +import org.ethereum.core.Blockchain; +import org.ethereum.core.BlockchainImpl; import org.ethereum.db.BlockStore; import org.ethereum.db.BlockStoreDummy; import org.ethereum.net.eth.message.EthMessage; import org.ethereum.net.eth.message.GetBlockBodiesMessage; import org.ethereum.net.eth.message.GetBlockHeadersMessage; -import org.ethereum.publish.Publisher; +import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.sync.SyncManager; import org.junit.Before; import org.junit.Test; @@ -93,7 +96,7 @@ public synchronized boolean isBlockExist(byte[] hash) { }; SysPropConfig1.testHandler = new Eth62(SysPropConfig1.props, blockchain, blockStoreDummy, - new Publisher(EventDispatchThread.getDefault())) { + BackwardCompatibilityEthereumListenerProxy.createDefault()) { { this.blockstore = blockStoreDummy; this.syncManager = Mockito.mock(SyncManager.class); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java index 61d9ad8e96..ca7a4d818d 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java @@ -27,7 +27,7 @@ import org.ethereum.net.message.Message; import org.ethereum.net.shh.MessageWatcher; import org.ethereum.net.shh.WhisperMessage; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.message.MessageReceived; import org.junit.Ignore; import org.junit.Test; @@ -129,7 +129,7 @@ public void testTest() throws FileNotFoundException, InterruptedException { final CountDownLatch semaphoreFirstBlock = new CountDownLatch(1); AtomicInteger blocksCnt = new AtomicInteger(); - ethereum2.subscribe(to(BlockAdded.class, blockSummary -> { + ethereum2.subscribe(to(BestBlockAdded.class, data -> { blocksCnt.addAndGet(1); if (blocksCnt.get() % 1000 == 0 || blocksCnt.get() == 1) { System.out.println("=== Blocks imported: " + blocksCnt); diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java index d6a1ea22ef..010d2be652 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java @@ -31,7 +31,7 @@ import org.ethereum.net.eth.message.*; import org.ethereum.net.message.Message; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.PeerAddedToSyncPool; import org.ethereum.publish.event.SyncDone; import org.ethereum.publish.event.message.EthStatusUpdated; @@ -124,8 +124,8 @@ private void springInit() { .subscribe(to(SyncDone.class, syncState -> synced = true)) .subscribe(to(EthStatusUpdated.class, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage()))) .subscribe(to(PeerAddedToSyncPool.class, peer -> syncPeers.add(peer.getNode()))) - .subscribe(to(BlockAdded.class, blockSummary -> { - bestBlock = blockSummary.getBlock(); + .subscribe(to(BestBlockAdded.class, data -> { + bestBlock = data.getBlockSummary().getBlock(); if (syncComplete) { logger.info("New block: " + bestBlock.getShortDescr()); } @@ -482,9 +482,10 @@ public void testTest() throws Exception { Ethereum miner = EthereumFactory.createEthereum(MinerConfig.class); miner - .subscribe(to(BlockAdded.class, blockSummary -> { - if (blockSummary.getBlock().getNumber() != 0L) { - blocks.put(Hex.toHexString(blockSummary.getBlock().getHash()), Boolean.FALSE); + .subscribe(to(BestBlockAdded.class, data -> { + Block block = data.getBlockSummary().getBlock(); + if (block.getNumber() != 0L) { + blocks.put(Hex.toHexString(block.getHash()), Boolean.FALSE); } })) .subscribe(to(MessageReceived.class, messageData -> { diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java index cd68e1d958..7378eed56f 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java @@ -33,7 +33,7 @@ import org.ethereum.net.eth.message.GetBlockHeadersMessage; import org.ethereum.net.p2p.DisconnectMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.PeerAddedToSyncPool; import org.ethereum.publish.event.message.EthStatusUpdated; import org.ethereum.publish.event.message.MessageReceived; @@ -161,8 +161,8 @@ public void test1() throws InterruptedException { // A == b10, B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { - if (blockSummary.getBlock().isEqual(b10)) { + ethereumB.subscribe(to(BestBlockAdded.class, data -> { + if (data.getBlockSummary().getBlock().isEqual(b10)) { semaphore.countDown(); } })); diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java index 6c714a06c2..39fe9e7286 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java @@ -30,7 +30,7 @@ import org.ethereum.net.eth.message.*; import org.ethereum.net.p2p.DisconnectMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.BestBlockAdded; import org.ethereum.publish.event.PeerAddedToSyncPool; import org.ethereum.publish.event.message.EthStatusUpdated; import org.ethereum.publish.event.message.MessageReceived; @@ -160,8 +160,8 @@ public void test1() throws InterruptedException { // A == b10, B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, blockSummary -> semaphore.countDown()) - .conditionally(blockSummary -> blockSummary.getBlock().isEqual(b10))); + ethereumB.subscribe(to(BestBlockAdded.class, data -> semaphore.countDown()) + .conditionally(data -> data.getBlockSummary().getBlock().isEqual(b10))); ethA.sendNewBlock(b10); @@ -192,8 +192,8 @@ public void test2() throws InterruptedException { // A == b8', B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, blockSummary -> semaphore.countDown()) - .conditionally(blockSummary -> blockSummary.getBlock().isEqual(b8_))); + ethereumB.subscribe(to(BestBlockAdded.class, data -> semaphore.countDown()) + .conditionally(data -> data.getBlockSummary().getBlock().isEqual(b8_))); ethA.sendNewBlock(b8_); @@ -228,8 +228,8 @@ public void test3() throws InterruptedException { // A == b10, B == b8' final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { - Block block = blockSummary.getBlock(); + ethereumB.subscribe(to(BestBlockAdded.class, data -> { + Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); } @@ -273,8 +273,8 @@ public void test4() throws InterruptedException { // A == b5, B == b9 final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, blockSummary -> semaphore.countDown()) - .conditionally(blockSummary -> blockSummary.getBlock().equals(b10))); + ethereumB.subscribe(to(BestBlockAdded.class, blockSummary -> semaphore.countDown()) + .conditionally(data -> data.getBlockSummary().getBlock().equals(b10))); ethA.sendNewBlockHashes(b5); @@ -322,8 +322,8 @@ public void test5() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB8_ = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { - Block block = blockSummary.getBlock(); + ethereumB.subscribe(to(BestBlockAdded.class, data -> { + Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); } @@ -382,8 +382,8 @@ public void test6() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB7 = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { - Block block = blockSummary.getBlock(); + ethereumB.subscribe(to(BestBlockAdded.class, data -> { + Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b7)) { semaphoreB7.countDown(); } @@ -453,8 +453,8 @@ public void test7() throws InterruptedException { })); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { - Block block = blockSummary.getBlock(); + ethereumB.subscribe(to(BestBlockAdded.class, data -> { + Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); } @@ -501,8 +501,8 @@ public void test8() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB7_ = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { - Block block = blockSummary.getBlock(); + ethereumB.subscribe(to(BestBlockAdded.class, data -> { + Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b7_)) { // it's time to do a re-branch for (Block b : mainB1B10) { @@ -604,8 +604,8 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { } final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { - Block block = blockSummary.getBlock(); + ethereumB.subscribe(to(BestBlockAdded.class, data -> { + Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); } @@ -699,8 +699,8 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { LongSyncTest.SysPropConfigA.eth62 = null; final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { - Block block = blockSummary.getBlock(); + ethereumB.subscribe(to(BestBlockAdded.class, data -> { + Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); } @@ -760,8 +760,8 @@ public void test11() throws InterruptedException { final CountDownLatch semaphore1 = new CountDownLatch(1); final CountDownLatch semaphore2 = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, blockSummary -> { - if (blockSummary.getBlock().isEqual(b6_)) { + ethereumB.subscribe(to(BestBlockAdded.class, data -> { + if (data.getBlockSummary().getBlock().isEqual(b6_)) { if (semaphore1.getCount() > 0) { semaphore1.countDown(); } else { From acb5e899d630ed2f841ca11435efdb2e9c7b6175 Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Wed, 15 Aug 2018 00:58:48 +0300 Subject: [PATCH 10/28] Deletes unused events + some events rename. --- .../org/ethereum/core/PendingStateImpl.java | 2 +- .../org/ethereum/facade/EthereumImpl.java | 4 +- .../ethereum/net/eth/handler/EthHandler.java | 8 +-- .../java/org/ethereum/publish/Publisher.java | 6 +- .../publish/event/BestBlockAdded.java | 28 --------- .../ethereum/publish/event/BlockAdded.java | 26 +++++++-- .../org/ethereum/publish/event/Events.java | 2 +- .../ethereum/publish/event/NoConnections.java | 4 -- .../event/{Single.java => OneOffEvent.java} | 2 +- .../event/PendingTransactionsReceived.java | 17 ------ .../org/ethereum/publish/event/SyncDone.java | 2 +- .../org/ethereum/publish/event/Trace.java | 8 --- .../org/ethereum/samples/BasicSample.java | 4 +- .../samples/CreateContractSample.java | 6 +- .../ethereum/samples/EventListenerSample.java | 6 +- .../org/ethereum/samples/FollowAccount.java | 4 +- .../ethereum/samples/PendingStateSample.java | 12 ++-- .../org/ethereum/samples/SendTransaction.java | 6 +- .../org/ethereum/samples/TransactionBomb.java | 6 +- .../util/blockchain/StandaloneBlockchain.java | 4 +- .../org/ethereum/validator/EthashRule.java | 4 +- .../java/org/ethereum/core/CloseTest.java | 4 +- .../org/ethereum/core/PendingStateTest.java | 28 ++++----- .../java/org/ethereum/longrun/BasicNode.java | 6 +- .../ethereum/longrun/SyncWithLoadTest.java | 57 +++++++++---------- .../java/org/ethereum/mine/MinerTest.java | 12 ++-- .../java/org/ethereum/mine/SyncDoneTest.java | 18 +++--- .../java/org/ethereum/net/TwoPeerTest.java | 4 +- .../ethereum/net/rlpx/SanityLongRunTest.java | 4 +- .../org/ethereum/publish/PublisherTest.java | 12 ++-- .../org/ethereum/sync/BlockTxForwardTest.java | 6 +- .../java/org/ethereum/sync/LongSyncTest.java | 4 +- .../java/org/ethereum/sync/ShortSyncTest.java | 24 ++++---- .../ethereum/validator/EthashRuleTest.java | 10 ++-- 34 files changed, 157 insertions(+), 193 deletions(-) delete mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/BestBlockAdded.java delete mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnections.java rename ethereumj-core/src/main/java/org/ethereum/publish/event/{Single.java => OneOffEvent.java} (80%) delete mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceived.java delete mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/Trace.java diff --git a/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java b/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java index ebfcd115fc..3f298f4775 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java @@ -163,7 +163,7 @@ public synchronized List addPendingTransactions(List t if (!newPending.isEmpty()) { listener.onPendingTransactionsReceived(newPending); - listener.onPendingStateChanged(PendingStateImpl.this); + listener.onPendingStateChanged(this); } return newPending; diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index ab363cbf40..c71971e8fc 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -38,7 +38,7 @@ import org.ethereum.net.submit.TransactionTask; import org.ethereum.publish.Publisher; import org.ethereum.publish.Subscription; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.Event; import org.ethereum.sync.SyncManager; import org.ethereum.util.ByteUtil; @@ -123,7 +123,7 @@ public EthereumImpl(final SystemProperties config) { @PostConstruct public void init() { - publisher.subscribe(to(BestBlockAdded.class, data -> { + publisher.subscribe(to(BlockAdded.class, data -> { data.getBlockSummary().getBlock().getTransactionsList().forEach(gasPriceTracker::onTransaction); })); } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java index f96ecfb70b..5d599b2d80 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java @@ -34,7 +34,7 @@ import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.Publisher; import org.ethereum.publish.Subscription; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,7 +66,7 @@ public abstract class EthHandler extends SimpleChannelInboundHandler protected Block bestBlock; protected boolean processTransactions = false; - private Subscription bestBlockSub; + private Subscription bestBlockSub; protected EthHandler(EthVersion version) { this.version = version; @@ -80,13 +80,13 @@ protected EthHandler(final EthVersion version, final SystemProperties config, this.blockchain = blockchain; this.bestBlock = blockStore.getBestBlock(); this.listener = listener; - this.bestBlockSub = getPublisher().subscribe(BestBlockAdded.class, this::setBestBlock); + this.bestBlockSub = getPublisher().subscribe(BlockAdded.class, this::setBestBlock); // when sync enabled we delay transactions processing until sync is complete this.processTransactions = !config.isSyncEnabled(); } - private void setBestBlock(BestBlockAdded.Data data) { + private void setBestBlock(BlockAdded.Data data) { this.bestBlock = data.getBlockSummary().getBlock(); } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java index 58703c3afd..f5570ba076 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java @@ -2,8 +2,8 @@ import org.ethereum.core.EventDispatchThread; import org.ethereum.publish.event.Event; +import org.ethereum.publish.event.OneOffEvent; import org.ethereum.publish.event.SignalEvent; -import org.ethereum.publish.event.Single; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,7 +52,7 @@ * @see Subscription * @see Event * @see SignalEvent - * @see Single + * @see OneOffEvent * * @author Eugene Shevchenko */ @@ -106,7 +106,7 @@ public Publisher publish(Event event) { .filter(subscription -> subscription.needUnsubscribeAfter(event)) .forEach(this::unsubscribe); - if (event instanceof Single) { + if (event instanceof OneOffEvent) { subscriptionsByEvent.remove(event.getClass()); } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/BestBlockAdded.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/BestBlockAdded.java deleted file mode 100644 index 56818c181d..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/BestBlockAdded.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.ethereum.publish.event; - -import org.ethereum.core.BlockSummary; - -public class BestBlockAdded extends Event { - - public static class Data { - private final BlockSummary blockSummary; - private final boolean best; - - public Data(BlockSummary blockSummary, boolean best) { - this.blockSummary = blockSummary; - this.best = best; - } - - public BlockSummary getBlockSummary() { - return blockSummary; - } - - public boolean isBest() { - return best; - } - } - - public BestBlockAdded(BlockSummary blockSummary, boolean best) { - super(new Data(blockSummary, best)); - } -} \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAdded.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAdded.java index de4359009a..abb8d7d077 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAdded.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAdded.java @@ -2,9 +2,27 @@ import org.ethereum.core.BlockSummary; -public class BlockAdded extends Event { +public class BlockAdded extends Event { - public BlockAdded(BlockSummary data) { - super(data); + public static class Data { + private final BlockSummary blockSummary; + private final boolean best; + + public Data(BlockSummary blockSummary, boolean best) { + this.blockSummary = blockSummary; + this.best = best; + } + + public BlockSummary getBlockSummary() { + return blockSummary; + } + + public boolean isBest() { + return best; + } + } + + public BlockAdded(BlockSummary blockSummary, boolean best) { + super(new Data(blockSummary, best)); } -} +} \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java index e050e489fc..7fd55b34a2 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java @@ -34,7 +34,7 @@ public static Event onPeerHanshaked(Channel channel, HelloMessage message) { } public static Event onBlockAdded(BlockSummary summary, boolean isBest) { - return new BestBlockAdded(summary, isBest); + return new BlockAdded(summary, isBest); } public static Event onBlockAdded(BlockSummary summary) { diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnections.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnections.java deleted file mode 100644 index 8ff9ca23e0..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/NoConnections.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.ethereum.publish.event; - -public class NoConnections extends SignalEvent { -} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/Single.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/OneOffEvent.java similarity index 80% rename from ethereumj-core/src/main/java/org/ethereum/publish/event/Single.java rename to ethereumj-core/src/main/java/org/ethereum/publish/event/OneOffEvent.java index 71fa1429c9..250bf5f56b 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/Single.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/OneOffEvent.java @@ -5,5 +5,5 @@ * * @author Eugene Shevchenko */ -public interface Single { +public interface OneOffEvent { } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceived.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceived.java deleted file mode 100644 index 112048cc82..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionsReceived.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.ethereum.publish.event; - -import org.ethereum.core.Transaction; - -import java.util.List; - -/** - * @author Eugene Shevchenko - * @deprecated use PendingTransactionUpdated filtering state NEW_PENDING - * Will be removed in the next release - */ -public class PendingTransactionsReceived extends Event> { - - public PendingTransactionsReceived(List transactions) { - super(transactions); - } -} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java index 2016edd6ac..4d909a1513 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java @@ -2,7 +2,7 @@ import org.ethereum.listener.EthereumListener; -public class SyncDone extends Event implements Single { +public class SyncDone extends Event implements OneOffEvent { public SyncDone(EthereumListener.SyncState payload) { super(payload); diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/Trace.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/Trace.java deleted file mode 100644 index 0860d5c14b..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/Trace.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.ethereum.publish.event; - -public class Trace extends Event { - - public Trace(String trace) { - super(trace); - } -} diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java index d662477bb3..53f232c655 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java @@ -31,7 +31,7 @@ import org.ethereum.facade.EthereumFactory; import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.NodeDiscovered; import org.ethereum.publish.event.PeerAddedToSyncPool; import org.ethereum.publish.event.SyncDone; @@ -141,7 +141,7 @@ private void springInit() { .conditionally(node -> nodesDiscovered.size() < 1000)) .subscribe(to(EthStatusUpdated.class, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage()))) .subscribe(to(PeerAddedToSyncPool.class, peer -> syncPeers.add(peer.getNode()))) - .subscribe(to(BestBlockAdded.class, data -> { + .subscribe(to(BlockAdded.class, data -> { BlockSummary blockSummary = data.getBlockSummary(); Block block = blockSummary.getBlock(); List receipts = blockSummary.getReceipts(); diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java index 4f9d87196f..2b1647f9b2 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java @@ -23,7 +23,7 @@ import org.ethereum.crypto.ECKey; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.solidity.compiler.CompilationResult; import org.ethereum.solidity.compiler.SolidityCompiler; import org.ethereum.util.ByteUtil; @@ -64,7 +64,7 @@ public class CreateContractSample extends TestNetSample { @Override public void onSyncDone() throws Exception { // when block arrives look for our included transactions - ethereum.subscribe(to(BestBlockAdded.class, this::onBlock)); + ethereum.subscribe(to(BlockAdded.class, this::onBlock)); logger.info("Compiling contract..."); SolidityCompiler.Result result = compiler.compileSrc(contract.getBytes(), true, true, @@ -126,7 +126,7 @@ protected TransactionReceipt sendTxAndWait(byte[] receiveAddress, byte[] data) t return waitForTx(tx.getHash()); } - private void onBlock(BestBlockAdded.Data data) { + private void onBlock(BlockAdded.Data data) { for (TransactionReceipt receipt : data.getBlockSummary().getReceipts()) { ByteArrayWrapper txHashW = new ByteArrayWrapper(receipt.getTransaction().getHash()); diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java index 72f463d438..4e5f95012a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java @@ -27,7 +27,7 @@ import org.ethereum.listener.EthereumListener; import org.ethereum.listener.EventListener; import org.ethereum.listener.TxStatus; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.PendingTransactionUpdated; import org.ethereum.solidity.compiler.CompilationResult; import org.ethereum.solidity.compiler.SolidityCompiler; @@ -284,7 +284,7 @@ private void waitForEther(byte[] address, BigInteger requiredBalance) throws Int */ private void deployContractAndTest() throws Exception { // when block arrives look for our included transactions - ethereum.subscribe(to(BestBlockAdded.class, this::onBlock)); + ethereum.subscribe(to(BlockAdded.class, this::onBlock)); CompilationResult.ContractMetadata metadata = compileContract(); @@ -381,7 +381,7 @@ protected TransactionReceipt sendTxAndWait(byte[] receiveAddress, return waitForTx(txHashW); } - private void onBlock(BestBlockAdded.Data data) { + private void onBlock(BlockAdded.Data data) { for (TransactionReceipt receipt : data.getBlockSummary().getReceipts()) { ByteArrayWrapper txHashW = new ByteArrayWrapper(receipt.getTransaction().getHash()); if (txWaiters.containsKey(txHashW)) { diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java b/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java index eafefffbbd..fb2e588292 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java @@ -21,7 +21,7 @@ import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; import org.ethereum.facade.Repository; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.spongycastle.util.encoders.Hex; import java.math.BigInteger; @@ -32,7 +32,7 @@ public class FollowAccount { public static void main(String[] args) { Ethereum ethereum = EthereumFactory.createEthereum(); - ethereum.subscribe(to(BestBlockAdded.class, data -> { + ethereum.subscribe(to(BlockAdded.class, data -> { byte[] cow = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826"); // Get snapshot some time ago - 10% blocks ago diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java index dd37bc296c..9ca86166c8 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java @@ -21,8 +21,8 @@ import org.ethereum.crypto.ECKey; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.BestBlockAdded; -import org.ethereum.publish.event.PendingTransactionsReceived; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.PendingTransactionUpdated; import org.ethereum.util.ByteUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -30,6 +30,7 @@ import java.math.BigInteger; import java.util.*; +import static org.ethereum.listener.EthereumListener.PendingTransactionState.NEW_PENDING; import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.ByteUtil.toHexString; @@ -65,9 +66,10 @@ public class PendingStateSample extends TestNetSample { public void onSyncDone() { this.ethereum // listening here when the PendingState is updated with new transactions - .subscribe(to(PendingTransactionsReceived.class, txs -> txs.forEach(this::onPendingTransactionReceived))) + .subscribe(to(PendingTransactionUpdated.class, data -> onPendingTransactionReceived(data.getReceipt().getTransaction())) + .conditionally(data -> data.getState() == NEW_PENDING)) // when block arrives look for our included transactions - .subscribe(to(BestBlockAdded.class, this::onBlock)); + .subscribe(to(BlockAdded.class, this::onBlock)); new Thread(() -> { try { @@ -140,7 +142,7 @@ void onPendingTransactionReceived(Transaction tx) { * For each block we are looking for our transactions and clearing them * The actual receiver balance is confirmed upon block arrival */ - public void onBlock(BestBlockAdded.Data data) { + public void onBlock(BlockAdded.Data data) { BlockSummary blockSummary = data.getBlockSummary(); onBlock(blockSummary.getBlock(), blockSummary.getReceipts()); } diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java b/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java index 69e59a70c0..07c68ac858 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java @@ -23,7 +23,7 @@ import org.ethereum.crypto.HashUtil; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.util.ByteUtil; import org.ethereum.util.blockchain.EtherUtil; import org.spongycastle.util.encoders.Hex; @@ -50,7 +50,7 @@ public class SendTransaction extends BasicSample { @Override public void onSyncDone() throws Exception { // when block arrives look for our included transactions - this.ethereum.subscribe(to(BestBlockAdded.class, this::onBlock)); + this.ethereum.subscribe(to(BlockAdded.class, this::onBlock)); String toAddress = ""; logger.info("Sending transaction to net and waiting for inclusion"); @@ -58,7 +58,7 @@ public void onSyncDone() throws Exception { logger.info("Transaction included!"); } - private void onBlock(BestBlockAdded.Data data) { + private void onBlock(BlockAdded.Data data) { for (TransactionReceipt receipt : data.getBlockSummary().getReceipts()) { ByteArrayWrapper txHashW = new ByteArrayWrapper(receipt.getTransaction().getHash()); if (txWaiters.containsKey(txHashW)) { diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java b/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java index e3b2539511..0b737db645 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java @@ -21,7 +21,7 @@ import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; import org.ethereum.listener.EthereumListener; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.SyncDone; import org.spongycastle.util.encoders.Hex; @@ -42,7 +42,7 @@ public TransactionBomb(Ethereum ethereum) { this.ethereum = ethereum; this.ethereum .subscribe(to(SyncDone.class, this::onSyncDone)) - .subscribe(to(BestBlockAdded.class, this::onBlock)); + .subscribe(to(BlockAdded.class, this::onBlock)); } public static void main(String[] args) { @@ -58,7 +58,7 @@ public void onSyncDone(EthereumListener.SyncState state) { System.err.println(" ~~~ SYNC DONE ~~~ "); } - public void onBlock(BestBlockAdded.Data data) { + public void onBlock(BlockAdded.Data data) { if (startedTxBomb){ byte[] sender = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826"); long nonce = ethereum.getRepository().getNonce(sender).longValue(); diff --git a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java index ec60c961fc..54a4496425 100644 --- a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java @@ -34,7 +34,7 @@ import org.ethereum.mine.Ethash; import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.Subscription; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.Event; import org.ethereum.solidity.compiler.CompilationResult; import org.ethereum.solidity.compiler.CompilationResult.ContractMetadata; @@ -438,7 +438,7 @@ public BlockchainImpl getBlockchain() { if (blockchain == null) { blockchain = createBlockchain(genesis); blockchain.setMinerCoinbase(coinbase); - subscribe(to(BestBlockAdded.class, data -> lastSummary = data.getBlockSummary())); + subscribe(to(BlockAdded.class, data -> lastSummary = data.getBlockSummary())); } return blockchain; } diff --git a/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java b/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java index 824342004a..079ec7e897 100644 --- a/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java +++ b/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java @@ -22,7 +22,7 @@ import org.ethereum.core.BlockHeader; import org.ethereum.mine.EthashValidationHelper; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.SyncDone; import org.ethereum.util.FastByteComparisons; import org.slf4j.Logger; @@ -116,7 +116,7 @@ public EthashRule(Mode mode, ChainType chain, Publisher publisher) { if (this.chain == main && publisher != null) { publisher .subscribe(to(SyncDone.class, ss -> EthashRule.this.syncDone = true)) - .subscribe(to(BestBlockAdded.class, data -> { + .subscribe(to(BlockAdded.class, data -> { if (data.isBest()) { ethashHelper.preCache(data.getBlockSummary().getBlock().getNumber()); } diff --git a/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java b/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java index 98807594a1..705ec37dc8 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java @@ -19,7 +19,7 @@ import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; @@ -44,7 +44,7 @@ public void relaunchTest() throws InterruptedException { Assert.assertNotNull(bestBlock); final CountDownLatch latch = new CountDownLatch(1); AtomicInteger counter = new AtomicInteger(); - ethereum.subscribe(to(BestBlockAdded.class, data -> { + ethereum.subscribe(to(BlockAdded.class, data -> { if (counter.addAndGet(1) > 1100) { latch.countDown(); } diff --git a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java index 9922d7128e..9ee8eb3e24 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java @@ -23,7 +23,7 @@ import org.ethereum.crypto.ECKey; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.listener.EthereumListener; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.PendingStateChanged; import org.ethereum.publish.event.PendingTransactionUpdated; import org.ethereum.util.blockchain.SolidityContract; @@ -73,7 +73,7 @@ static class PendingListener { Map>> onPendingTransactionUpdate = new HashMap<>(); - public void onBlock(BestBlockAdded.Data data) { + public void onBlock(BlockAdded.Data data) { BlockSummary blockSummary = data.getBlockSummary(); Block block = blockSummary.getBlock(); System.out.println("PendingStateTest.onBlock:" + "block = [" + block.getShortDescr() + "]"); @@ -118,7 +118,7 @@ public Triple transactions) { - Random rnd = new Random(); - Block bestBlock = ethereum.getBlockchain().getBestBlock(); - for (Transaction tx : transactions) { - Block block = ethereum.getBlockchain().getBlockByNumber(rnd.nextInt((int) bestBlock.getNumber())); - Repository repository = ((Repository) ethereum.getRepository()) - .getSnapshotTo(block.getStateRoot()) - .startTracking(); - try { - TransactionExecutor executor = new TransactionExecutor - (tx, block.getCoinbase(), repository, ethereum.getBlockchain().getBlockStore(), - programInvokeFactory, block, EthereumListener.STUB, 0) - .withCommonConfig(commonConfig) - .setLocalCall(true); - - executor.init(); - executor.execute(); - executor.go(); - executor.finalization(); - - executor.getReceipt(); - } finally { - repository.rollback(); - } + private void onPendingTransactionUpdated(PendingTransactionUpdated.Data data) { + Transaction tx = data.getReceipt().getTransaction(); + Block block = data.getBlock(); +// Block block = ethereum.getBlockchain().getBlockByNumber(new Random().nextInt((int) bestBlock.getNumber())); + Repository repository = ((Repository) ethereum.getRepository()) + .getSnapshotTo(block.getStateRoot()) + .startTracking(); + try { + TransactionExecutor executor = new TransactionExecutor + (tx, block.getCoinbase(), repository, ethereum.getBlockchain().getBlockStore(), + programInvokeFactory, block, EthereumListener.STUB, 0) + .withCommonConfig(commonConfig) + .setLocalCall(true); + + executor.init(); + executor.execute(); + executor.go(); + executor.finalization(); + + executor.getReceipt(); + } finally { + repository.rollback(); } } @@ -221,8 +219,9 @@ public RegularNode() { public void run() { try { this.ethereum - .subscribe(to(BestBlockAdded.class, this::onBlock)) - .subscribe(to(PendingTransactionsReceived.class, this::onPendingTransactionsReceived)); + .subscribe(to(BlockAdded.class, this::onBlock)) + .subscribe(to(PendingTransactionUpdated.class, this::onPendingTransactionUpdated) + .conditionally(data -> data.getState() == NEW_PENDING)); // Run 1-30 minutes Random generator = new Random(); diff --git a/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java b/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java index af6ab46d70..76a89d1e07 100644 --- a/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java @@ -30,8 +30,8 @@ import org.ethereum.facade.EthereumFactory; import org.ethereum.net.eth.handler.Eth62; import org.ethereum.net.eth.message.NewBlockMessage; -import org.ethereum.publish.event.BestBlockAdded; -import org.ethereum.publish.event.PendingTransactionsReceived; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.PendingTransactionUpdated; import org.ethereum.publish.event.SyncDone; import org.ethereum.util.ByteUtil; import org.junit.BeforeClass; @@ -48,6 +48,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import static org.ethereum.listener.EthereumListener.PendingTransactionState.NEW_PENDING; import static org.ethereum.publish.Subscription.to; /** @@ -107,7 +108,7 @@ public void startMiningConsumer() throws Exception { Ethereum ethereum2 = EthereumFactory.createEthereum(SysPropConfig2.props, SysPropConfig2.class); final CountDownLatch semaphore = new CountDownLatch(1); - ethereum2.subscribe(to(BestBlockAdded.class, data -> { + ethereum2.subscribe(to(BlockAdded.class, data -> { Block block = data.getBlockSummary().getBlock(); System.err.println("=== New block: " + blockInfo(block)); System.err.println(block); @@ -131,7 +132,8 @@ public void startMiningConsumer() throws Exception { // } })) - .subscribe(to(PendingTransactionsReceived.class, transactions -> System.err.println("=== Tx: " + transactions))) + .subscribe(to(PendingTransactionUpdated.class, data -> System.err.println("=== Tx: " + data.getReceipt().getTransaction())) + .conditionally(data -> data.getState() == NEW_PENDING)) .subscribe(to(SyncDone.class, syncState -> { semaphore.countDown(); System.err.println("=== Sync Done!"); @@ -205,7 +207,7 @@ public void startMiningTest() throws FileNotFoundException, InterruptedException final CountDownLatch semaphore = new CountDownLatch(1); ethereum1 - .subscribe(to(BestBlockAdded.class, data -> System.out.println("=== New block: " + blockInfo(data.getBlockSummary().getBlock())))) + .subscribe(to(BlockAdded.class, data -> System.out.println("=== New block: " + blockInfo(data.getBlockSummary().getBlock())))) .subscribe(to(SyncDone.class, syncState -> semaphore.countDown())); // ethereum2.addListener(new EthereumListenerAdapter() { diff --git a/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java b/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java index 31d86ae64b..d29027b2e5 100644 --- a/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java @@ -28,7 +28,7 @@ import org.ethereum.facade.SyncStatus; import org.ethereum.net.eth.handler.Eth62; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.PeerAddedToSyncPool; import org.ethereum.util.FastByteComparisons; import org.ethereum.util.blockchain.EtherUtil; @@ -161,7 +161,7 @@ public void test1() throws InterruptedException { assertTrue(loadedBlocks > 0); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BestBlockAdded.class, data -> semaphore.countDown()) + ethereumB.subscribe(to(BlockAdded.class, data -> semaphore.countDown()) .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks))); semaphore.await(MAX_SECONDS_WAIT, SECONDS); @@ -171,14 +171,14 @@ public void test1() throws InterruptedException { ethereumA.getBlockMiner().startMining(); final CountDownLatch semaphore2 = new CountDownLatch(2); - ethereumB.subscribe(to(BestBlockAdded.class, data -> { + ethereumB.subscribe(to(BlockAdded.class, data -> { if (isBlockNumber(data.getBlockSummary(), loadedBlocks + 2)) { semaphore2.countDown(); ethereumA.getBlockMiner().stopMining(); } })); - ethereumA.subscribe(to(BestBlockAdded.class, data -> semaphore2.countDown()) + ethereumA.subscribe(to(BlockAdded.class, data -> semaphore2.countDown()) .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks + 2))); semaphore2.await(MAX_SECONDS_WAIT, SECONDS); @@ -200,7 +200,7 @@ public void test1() throws InterruptedException { ); tx.sign(sender); final CountDownLatch txSemaphore = new CountDownLatch(1); - ethereumA.subscribe(to(BestBlockAdded.class, data -> { + ethereumA.subscribe(to(BlockAdded.class, data -> { BlockSummary blockSummary = data.getBlockSummary(); if (!blockSummary.getBlock().getTransactionsList().isEmpty() && FastByteComparisons.equal(blockSummary.getBlock().getTransactionsList().get(0).getSender(), sender.getAddress()) && @@ -212,10 +212,10 @@ public void test1() throws InterruptedException { ethereumB.submitTransaction(tx); final CountDownLatch semaphore3 = new CountDownLatch(2); - ethereumB.subscribe(to(BestBlockAdded.class, data -> semaphore3.countDown()) + ethereumB.subscribe(to(BlockAdded.class, data -> semaphore3.countDown()) .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks + 5))); - ethereumA.subscribe(to(BestBlockAdded.class, data -> { + ethereumA.subscribe(to(BlockAdded.class, data -> { if (isBlockNumber(data.getBlockSummary(), loadedBlocks + 5)) { semaphore3.countDown(); ethereumA.getBlockMiner().stopMining(); @@ -252,14 +252,14 @@ public void test1() throws InterruptedException { final CountDownLatch semaphore4 = new CountDownLatch(2); - ethereumB.subscribe(to(BestBlockAdded.class, data -> { + ethereumB.subscribe(to(BlockAdded.class, data -> { if (isBlockNumber(data.getBlockSummary(), loadedBlocks + 9)) { semaphore4.countDown(); ethereumA.getBlockMiner().stopMining(); } })); - ethereumA.subscribe(to(BestBlockAdded.class, data -> semaphore4.countDown()) + ethereumA.subscribe(to(BlockAdded.class, data -> semaphore4.countDown()) .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks + 9))); semaphore4.await(MAX_SECONDS_WAIT, SECONDS); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java b/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java index 15450764a8..6441e6bd3a 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java @@ -31,7 +31,7 @@ import org.ethereum.net.eth.message.GetBlockBodiesMessage; import org.ethereum.net.eth.message.GetBlockHeadersMessage; import org.ethereum.net.server.Channel; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.message.EthStatusUpdated; import org.ethereum.util.RLP; import org.junit.Ignore; @@ -231,7 +231,7 @@ protected void processGetBlockBodies(GetBlockBodiesMessage msg) { System.out.println("==== Got the Channel: " + data.getChannel()); })); - ethereum2.subscribe(to(BestBlockAdded.class, data -> { + ethereum2.subscribe(to(BlockAdded.class, data -> { Block block = data.getBlockSummary().getBlock(); if (block.getNumber() == 4) { semaphore.countDown(); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java index ca7a4d818d..7605e97ece 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java @@ -27,7 +27,7 @@ import org.ethereum.net.message.Message; import org.ethereum.net.shh.MessageWatcher; import org.ethereum.net.shh.WhisperMessage; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.message.MessageReceived; import org.junit.Ignore; import org.junit.Test; @@ -129,7 +129,7 @@ public void testTest() throws FileNotFoundException, InterruptedException { final CountDownLatch semaphoreFirstBlock = new CountDownLatch(1); AtomicInteger blocksCnt = new AtomicInteger(); - ethereum2.subscribe(to(BestBlockAdded.class, data -> { + ethereum2.subscribe(to(BlockAdded.class, data -> { blocksCnt.addAndGet(1); if (blocksCnt.get() % 1000 == 0 || blocksCnt.get() == 1) { System.out.println("=== Blocks imported: " + blocksCnt); diff --git a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java index 7ea8250afb..d5de2b4fb2 100644 --- a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java @@ -2,7 +2,7 @@ import org.ethereum.core.EventDispatchThread; import org.ethereum.publish.event.Event; -import org.ethereum.publish.event.Single; +import org.ethereum.publish.event.OneOffEvent; import org.junit.Test; import java.util.ArrayList; @@ -36,8 +36,8 @@ private class StringEvent extends Event { } } - private class SingleStringEvent extends StringEvent implements Single { - SingleStringEvent(String payload) { + private class OneOffStringEvent extends StringEvent implements OneOffEvent { + OneOffStringEvent(String payload) { super(payload); } } @@ -62,9 +62,9 @@ public void testSingleEvent() { final List strings = new ArrayList<>(); int subscribersCount = createPublisher() - .subscribe(to(SingleStringEvent.class, strings::add)) - .publish(new SingleStringEvent(payload)) - .subscribersCount(SingleStringEvent.class); + .subscribe(to(OneOffStringEvent.class, strings::add)) + .publish(new OneOffStringEvent(payload)) + .subscribersCount(OneOffStringEvent.class); assertEquals(0, subscribersCount); assertTrue(strings.contains(payload)); diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java index 010d2be652..37deeb955d 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java @@ -31,7 +31,7 @@ import org.ethereum.net.eth.message.*; import org.ethereum.net.message.Message; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.PeerAddedToSyncPool; import org.ethereum.publish.event.SyncDone; import org.ethereum.publish.event.message.EthStatusUpdated; @@ -124,7 +124,7 @@ private void springInit() { .subscribe(to(SyncDone.class, syncState -> synced = true)) .subscribe(to(EthStatusUpdated.class, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage()))) .subscribe(to(PeerAddedToSyncPool.class, peer -> syncPeers.add(peer.getNode()))) - .subscribe(to(BestBlockAdded.class, data -> { + .subscribe(to(BlockAdded.class, data -> { bestBlock = data.getBlockSummary().getBlock(); if (syncComplete) { logger.info("New block: " + bestBlock.getShortDescr()); @@ -482,7 +482,7 @@ public void testTest() throws Exception { Ethereum miner = EthereumFactory.createEthereum(MinerConfig.class); miner - .subscribe(to(BestBlockAdded.class, data -> { + .subscribe(to(BlockAdded.class, data -> { Block block = data.getBlockSummary().getBlock(); if (block.getNumber() != 0L) { blocks.put(Hex.toHexString(block.getHash()), Boolean.FALSE); diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java index 7378eed56f..f9e519e739 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java @@ -33,7 +33,7 @@ import org.ethereum.net.eth.message.GetBlockHeadersMessage; import org.ethereum.net.p2p.DisconnectMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.PeerAddedToSyncPool; import org.ethereum.publish.event.message.EthStatusUpdated; import org.ethereum.publish.event.message.MessageReceived; @@ -161,7 +161,7 @@ public void test1() throws InterruptedException { // A == b10, B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BestBlockAdded.class, data -> { + ethereumB.subscribe(to(BlockAdded.class, data -> { if (data.getBlockSummary().getBlock().isEqual(b10)) { semaphore.countDown(); } diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java index 39fe9e7286..ae51aed0a3 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java @@ -30,7 +30,7 @@ import org.ethereum.net.eth.message.*; import org.ethereum.net.p2p.DisconnectMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.PeerAddedToSyncPool; import org.ethereum.publish.event.message.EthStatusUpdated; import org.ethereum.publish.event.message.MessageReceived; @@ -160,7 +160,7 @@ public void test1() throws InterruptedException { // A == b10, B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BestBlockAdded.class, data -> semaphore.countDown()) + ethereumB.subscribe(to(BlockAdded.class, data -> semaphore.countDown()) .conditionally(data -> data.getBlockSummary().getBlock().isEqual(b10))); ethA.sendNewBlock(b10); @@ -192,7 +192,7 @@ public void test2() throws InterruptedException { // A == b8', B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BestBlockAdded.class, data -> semaphore.countDown()) + ethereumB.subscribe(to(BlockAdded.class, data -> semaphore.countDown()) .conditionally(data -> data.getBlockSummary().getBlock().isEqual(b8_))); ethA.sendNewBlock(b8_); @@ -228,7 +228,7 @@ public void test3() throws InterruptedException { // A == b10, B == b8' final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BestBlockAdded.class, data -> { + ethereumB.subscribe(to(BlockAdded.class, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -273,7 +273,7 @@ public void test4() throws InterruptedException { // A == b5, B == b9 final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BestBlockAdded.class, blockSummary -> semaphore.countDown()) + ethereumB.subscribe(to(BlockAdded.class, blockSummary -> semaphore.countDown()) .conditionally(data -> data.getBlockSummary().getBlock().equals(b10))); ethA.sendNewBlockHashes(b5); @@ -322,7 +322,7 @@ public void test5() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB8_ = new CountDownLatch(1); - ethereumB.subscribe(to(BestBlockAdded.class, data -> { + ethereumB.subscribe(to(BlockAdded.class, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -382,7 +382,7 @@ public void test6() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB7 = new CountDownLatch(1); - ethereumB.subscribe(to(BestBlockAdded.class, data -> { + ethereumB.subscribe(to(BlockAdded.class, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b7)) { semaphoreB7.countDown(); @@ -453,7 +453,7 @@ public void test7() throws InterruptedException { })); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BestBlockAdded.class, data -> { + ethereumB.subscribe(to(BlockAdded.class, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -501,7 +501,7 @@ public void test8() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB7_ = new CountDownLatch(1); - ethereumB.subscribe(to(BestBlockAdded.class, data -> { + ethereumB.subscribe(to(BlockAdded.class, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b7_)) { // it's time to do a re-branch @@ -604,7 +604,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { } final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BestBlockAdded.class, data -> { + ethereumB.subscribe(to(BlockAdded.class, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -699,7 +699,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { LongSyncTest.SysPropConfigA.eth62 = null; final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BestBlockAdded.class, data -> { + ethereumB.subscribe(to(BlockAdded.class, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -760,7 +760,7 @@ public void test11() throws InterruptedException { final CountDownLatch semaphore1 = new CountDownLatch(1); final CountDownLatch semaphore2 = new CountDownLatch(1); - ethereumB.subscribe(to(BestBlockAdded.class, data -> { + ethereumB.subscribe(to(BlockAdded.class, data -> { if (data.getBlockSummary().getBlock().isEqual(b6_)) { if (semaphore1.getCount() > 0) { semaphore1.countDown(); diff --git a/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java b/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java index 6c557f7571..245a428217 100644 --- a/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java @@ -7,7 +7,7 @@ import org.ethereum.listener.EthereumListener; import org.ethereum.mine.EthashValidationHelper; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.BestBlockAdded; +import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.SyncDone; import org.junit.Test; import org.spongycastle.util.encoders.Hex; @@ -68,7 +68,7 @@ public void testStrict() { assertEquals(Success, rule.validate(partlyValidHeader)); // trigger ethash cache - publisher.publish(new BestBlockAdded(dummySummaryNum_1, true)); + publisher.publish(new BlockAdded(dummySummaryNum_1, true)); assertEquals(Success, rule.validate(validHeader)); assertNotEquals(Success, rule.validate(partlyValidHeader)); @@ -86,7 +86,7 @@ public void testMixed() { EthashRule rule = new EthashRule(EthashRule.Mode.mixed, EthashRule.ChainType.main, publisher); // trigger ethash cache - publisher.publish(new BestBlockAdded(dummySummaryNum_1, true)); + publisher.publish(new BlockAdded(dummySummaryNum_1, true)); // check mixed mode randomness boolean fullCheckTriggered = false; @@ -122,8 +122,8 @@ public void testCacheMain() { // trigger cache for (int i = 0; i < 100; i++) { publisher - .publish(new BestBlockAdded(dummySummaryNum_1, false)) - .publish(new BestBlockAdded(dummySummaryNum_1, true)); + .publish(new BlockAdded(dummySummaryNum_1, false)) + .publish(new BlockAdded(dummySummaryNum_1, true)); } // must be triggered on best block only From 06c702255e40af19669346978ff29789c9e0adac Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Wed, 15 Aug 2018 17:40:54 +0300 Subject: [PATCH 11/28] Removes import wilcards. --- .../org/ethereum/core/BlockchainImpl.java | 27 ++++++++++++++++--- .../org/ethereum/core/PendingStateImpl.java | 13 ++++++--- .../org/ethereum/net/eth/handler/Eth63.java | 12 +++++++-- .../ethereum/validator/EthashRuleTest.java | 13 +++++---- 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java b/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java index 21ee22d646..3590261573 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java @@ -23,7 +23,14 @@ import org.ethereum.config.SystemProperties; import org.ethereum.crypto.HashUtil; import org.ethereum.datasource.inmem.HashMapDB; -import org.ethereum.db.*; +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.manager.AdminInfo; import org.ethereum.sync.SyncManager; @@ -49,7 +56,17 @@ import java.io.FileWriter; import java.io.IOException; import java.math.BigInteger; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.Stack; import static java.lang.Math.max; import static java.lang.Runtime.getRuntime; @@ -58,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; diff --git a/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java b/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java index 3f298f4775..2ee87b20ef 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java @@ -33,9 +33,16 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.util.*; - -import static org.ethereum.listener.EthereumListener.PendingTransactionState.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.TreeSet; + +import static org.ethereum.listener.EthereumListener.PendingTransactionState.DROPPED; +import static org.ethereum.listener.EthereumListener.PendingTransactionState.INCLUDED; +import static org.ethereum.listener.EthereumListener.PendingTransactionState.NEW_PENDING; +import static org.ethereum.listener.EthereumListener.PendingTransactionState.PENDING; import static org.ethereum.util.ByteUtil.toHexString; /** diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java index 2e64473f7f..993c1afaa7 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java @@ -22,12 +22,20 @@ import io.netty.channel.ChannelHandlerContext; import org.apache.commons.lang3.tuple.Pair; import org.ethereum.config.SystemProperties; -import org.ethereum.core.*; +import org.ethereum.core.Block; +import org.ethereum.core.Blockchain; +import org.ethereum.core.Transaction; +import org.ethereum.core.TransactionInfo; +import org.ethereum.core.TransactionReceipt; import org.ethereum.datasource.Source; import org.ethereum.db.BlockStore; import org.ethereum.listener.EthereumListener; import org.ethereum.net.eth.EthVersion; -import org.ethereum.net.eth.message.*; +import org.ethereum.net.eth.message.EthMessage; +import org.ethereum.net.eth.message.GetNodeDataMessage; +import org.ethereum.net.eth.message.GetReceiptsMessage; +import org.ethereum.net.eth.message.NodeDataMessage; +import org.ethereum.net.eth.message.ReceiptsMessage; import org.ethereum.net.message.ReasonCode; import org.ethereum.sync.PeerState; import org.ethereum.util.ByteArraySet; diff --git a/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java b/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java index 245a428217..03546548e2 100644 --- a/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java @@ -8,12 +8,15 @@ import org.ethereum.mine.EthashValidationHelper; import org.ethereum.publish.Publisher; import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.Events; import org.ethereum.publish.event.SyncDone; import org.junit.Test; import org.spongycastle.util.encoders.Hex; import java.util.Collections; +import static org.ethereum.publish.event.Events.onBlockAdded; +import static org.ethereum.publish.event.Events.onSyncDone; import static org.ethereum.validator.BlockHeaderRule.Success; import static org.junit.Assert.*; @@ -68,7 +71,7 @@ public void testStrict() { assertEquals(Success, rule.validate(partlyValidHeader)); // trigger ethash cache - publisher.publish(new BlockAdded(dummySummaryNum_1, true)); + publisher.publish(onBlockAdded(dummySummaryNum_1, true)); assertEquals(Success, rule.validate(validHeader)); assertNotEquals(Success, rule.validate(partlyValidHeader)); @@ -86,7 +89,7 @@ public void testMixed() { EthashRule rule = new EthashRule(EthashRule.Mode.mixed, EthashRule.ChainType.main, publisher); // trigger ethash cache - publisher.publish(new BlockAdded(dummySummaryNum_1, true)); + publisher.publish(onBlockAdded(dummySummaryNum_1, true)); // check mixed mode randomness boolean fullCheckTriggered = false; @@ -104,7 +107,7 @@ public void testMixed() { assertTrue(partialCheckTriggered); // trigger onSyncDone - publisher.publish(new SyncDone(EthereumListener.SyncState.COMPLETE)); + publisher.publish(onSyncDone(EthereumListener.SyncState.COMPLETE)); // check that full verification is done on each run in strict mode for (int i = 0; i < 100; i++) { @@ -122,8 +125,8 @@ public void testCacheMain() { // trigger cache for (int i = 0; i < 100; i++) { publisher - .publish(new BlockAdded(dummySummaryNum_1, false)) - .publish(new BlockAdded(dummySummaryNum_1, true)); + .publish(onBlockAdded(dummySummaryNum_1, false)) + .publish(onBlockAdded(dummySummaryNum_1, true)); } // must be triggered on best block only From f643b3cdad355af2d1866cfad445a8c508f5996d Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Wed, 15 Aug 2018 18:27:13 +0300 Subject: [PATCH 12/28] Adds one-off condition to subscription. --- .../java/org/ethereum/publish/Publisher.java | 1 - .../java/org/ethereum/publish/Subscription.java | 13 +++++++++++++ .../java/org/ethereum/publish/PublisherTest.java | 16 ++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java index f5570ba076..911baebe62 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java @@ -48,7 +48,6 @@ * } *

      * - * @see EventDispatchThread * @see Subscription * @see Event * @see SignalEvent diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java index ab4beeca8a..c23231730f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java @@ -61,6 +61,19 @@ public Subscription unsubscribeAfter(Function condition) { return this; } + /** + * Optionally adds {@link #conditionally(Function)} and {@link #unsubscribeAfter(Function)} clauses with the same + * condition. It helps achieve specific behavior, when subscriber consumes and then unsubscribe from event source. + * + * @param condition + * @return current {@link Subscription} instance to support fluent API. + */ + public Subscription oneOff(Function condition) { + return this + .conditionally(condition) + .unsubscribeAfter(condition); + } + /** * Tests specified event whether it should be consumed. * diff --git a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java index d5de2b4fb2..f6271b6bc5 100644 --- a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java @@ -113,6 +113,22 @@ public void testUnsubscribeAfter() { assertEquals(sum, actualSum.get()); } + @Test + public void testOneOffSubscription() { + AtomicInteger actual = new AtomicInteger(); + final int expected = 5; + + Publisher publisher = createPublisher() + .subscribe(to(IntEvent.class, actual::set) + .oneOff(num -> num == expected)); + + IntStream.rangeClosed(1, 10) + .mapToObj(IntEvent::new) + .forEach(publisher::publish); + + assertEquals(expected, actual.get()); + } + @Test public void testPublishing() { From 5fcd91fd64d666da2046e6c35d7f3dc947e8b07e Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Wed, 15 Aug 2018 19:16:50 +0300 Subject: [PATCH 13/28] Adds subscription with life cycle abstraction. --- .../org/ethereum/config/CommonConfig.java | 2 +- ...ardCompatibilityEthereumListenerProxy.java | 5 +- .../org/ethereum/manager/WorldManager.java | 2 +- .../ethereum/net/eth/handler/EthHandler.java | 5 +- .../publish/LifeCycleSubscription.java | 53 ++++++++++++++++++ .../java/org/ethereum/publish/Publisher.java | 56 ++++++------------- .../org/ethereum/publish/Subscription.java | 9 ++- .../org/ethereum/sync/FastSyncManager.java | 36 ++++++++++-- .../util/blockchain/StandaloneBlockchain.java | 2 +- .../org/ethereum/core/ImportLightTest.java | 2 +- .../core/PendingStateLongRunTest.java | 2 +- .../jsontestsuite/suite/TestRunner.java | 2 +- .../net/eth/handler/LockBlockchainTest.java | 2 +- .../org/ethereum/publish/PublisherTest.java | 20 +++++++ 14 files changed, 139 insertions(+), 59 deletions(-) rename ethereumj-core/src/main/java/org/ethereum/{publish => listener}/BackwardCompatibilityEthereumListenerProxy.java (97%) create mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/LifeCycleSubscription.java diff --git a/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java b/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java index 2fec848c9e..385b2abee2 100644 --- a/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java +++ b/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java @@ -28,7 +28,7 @@ import org.ethereum.listener.CompositeEthereumListener; import org.ethereum.listener.EthereumListener; import org.ethereum.net.eth.handler.Eth63; -import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; +import org.ethereum.listener.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.Publisher; import org.ethereum.sync.FastSyncManager; import org.ethereum.validator.*; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/BackwardCompatibilityEthereumListenerProxy.java b/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java similarity index 97% rename from ethereumj-core/src/main/java/org/ethereum/publish/BackwardCompatibilityEthereumListenerProxy.java rename to ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java index 3284589aca..7531f41b11 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/BackwardCompatibilityEthereumListenerProxy.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java @@ -1,13 +1,12 @@ -package org.ethereum.publish; +package org.ethereum.listener; import org.ethereum.core.*; -import org.ethereum.listener.CompositeEthereumListener; -import org.ethereum.listener.EthereumListener; import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.message.Message; import org.ethereum.net.p2p.HelloMessage; import org.ethereum.net.rlpx.Node; import org.ethereum.net.server.Channel; +import org.ethereum.publish.Publisher; import org.ethereum.publish.event.Events; import java.util.List; diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java index 282b598748..7f63931271 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java @@ -28,7 +28,7 @@ import org.ethereum.net.rlpx.discover.NodeManager; import org.ethereum.net.rlpx.discover.UDPListener; import org.ethereum.net.server.ChannelManager; -import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; +import org.ethereum.listener.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.Publisher; import org.ethereum.publish.event.Event; import org.ethereum.sync.FastSyncManager; diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java index 5d599b2d80..0bc2dd4cfd 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java @@ -31,7 +31,7 @@ import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.message.ReasonCode; import org.ethereum.net.server.Channel; -import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; +import org.ethereum.listener.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.Publisher; import org.ethereum.publish.Subscription; import org.ethereum.publish.event.BlockAdded; @@ -80,7 +80,8 @@ protected EthHandler(final EthVersion version, final SystemProperties config, this.blockchain = blockchain; this.bestBlock = blockStore.getBestBlock(); this.listener = listener; - this.bestBlockSub = getPublisher().subscribe(BlockAdded.class, this::setBestBlock); + this.bestBlockSub = Subscription.to(BlockAdded.class, this::setBestBlock); + getPublisher().subscribe(this.bestBlockSub); // when sync enabled we delay transactions processing until sync is complete this.processTransactions = !config.isSyncEnabled(); diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/LifeCycleSubscription.java b/ethereumj-core/src/main/java/org/ethereum/publish/LifeCycleSubscription.java new file mode 100644 index 0000000000..cfa525f060 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/publish/LifeCycleSubscription.java @@ -0,0 +1,53 @@ +package org.ethereum.publish; + +import org.ethereum.publish.event.Event; + +import java.util.function.BiConsumer; + +/** + * Abstraction that holds together event type, event processor (a.k.a consumer) and optional conditions that resolves + * event processing and auto-unsubscribe. + * + * @author Eugene Shevchenko + */ +public class LifeCycleSubscription, D> extends Subscription { + + public static class LifeCycle { + private final LifeCycleSubscription subscription; + + private LifeCycle(LifeCycleSubscription subscription) { + this.subscription = subscription; + } + + public void unsubscribe() { + subscription.unsubscribeAfter(data -> true); + } + } + + private final BiConsumer biConsumer; + private final LifeCycle lifeCycle; + + LifeCycleSubscription(Class eventType, BiConsumer biConsumer) { + super(eventType, null); + this.biConsumer = biConsumer; + this.lifeCycle = new LifeCycle(this); + } + + @Override + protected void handlePayload(D payload) { + biConsumer.accept(payload, lifeCycle); + } + + /** + * Short static alias for {@link LifeCycleSubscription} constructor. + * + * @param eventType event type to process; + * @param biConsumer callback that consumes event's payload; + * @param event type that should be process; + * @param payload's type of specified event type; + * @return new {@link LifeCycleSubscription} instance. + */ + public static , D> LifeCycleSubscription to(Class eventType, BiConsumer biConsumer) { + return new LifeCycleSubscription<>(eventType, biConsumer); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java index 911baebe62..5e0cd0a6aa 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java @@ -14,7 +14,6 @@ import java.util.concurrent.Executor; import java.util.function.Consumer; -import static java.lang.String.format; import static java.util.Collections.emptyList; import static java.util.Objects.nonNull; import static java.util.stream.Collectors.toList; @@ -60,22 +59,28 @@ public class Publisher { private static final Logger log = LoggerFactory.getLogger("events"); private class Command implements Runnable { - private final List subscriptions; + private final Subscription subscription; private final Event event; - private Command(List subscriptions, Event event) { - this.subscriptions = subscriptions; + private Command(Subscription subscription, Event event) { + this.subscription = subscription; this.event = event; } @Override public void run() { - subscriptions.forEach(subscription -> subscription.handle(event)); + try { + subscription.handle(event); + } finally { + if (subscription.needUnsubscribeAfter(event)) { + Publisher.this.unsubscribe(subscription); + } + } } @Override public String toString() { - return format("%s: consumed by %d subscriber(s).", event, subscriptions.size()); + return event.toString(); } } @@ -94,25 +99,13 @@ public Publisher(Executor executor) { * @return current {@link Publisher} instance to support fluent API. */ public Publisher publish(Event event) { - List subscriptions = subscriptionsByEvent.getOrDefault(event.getClass(), emptyList()); - if (!subscriptions.isEmpty()) { - - List toHandle = subscriptions.stream() - .filter(subscription -> subscription.matches(event)) - .collect(toList()); - - subscriptions.stream() - .filter(subscription -> subscription.needUnsubscribeAfter(event)) - .forEach(this::unsubscribe); - - if (event instanceof OneOffEvent) { - subscriptionsByEvent.remove(event.getClass()); - } - + subscriptionsByEvent.getOrDefault(event.getClass(), emptyList()).stream() + .filter(subscription -> subscription.matches(event)) + .map(subscription -> new Command(subscription, event)) + .forEach(executor::execute); - if (!toHandle.isEmpty()) { - executor.execute(new Command(toHandle, event)); - } + if (event instanceof OneOffEvent) { + subscriptionsByEvent.remove(event.getClass()); } return this; @@ -137,21 +130,6 @@ public , P> Publisher subscribe(Subscription subscripti return this; } - /** - * Creates {@link Subscription} from specified parameters and adds it to current publisher. - * - * @param eventType even's type to subscribe; - * @param handler callback that will be invoked after event will be published; - * @param event's type; - * @param

      payload of specified event; - * @return created {@link Subscription} instance. - */ - public , P> Subscription subscribe(Class eventType, Consumer

      handler) { - Subscription subscription = new Subscription<>(eventType, handler); - subscribe(subscription); - return subscription; - } - /** * Removes specified {@link Subscription} from publisher. * diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java index c23231730f..720b7c15a8 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java @@ -4,6 +4,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; @@ -25,7 +26,7 @@ public class Subscription, D> { private Function handleCondition; private Function unsubscribeCondition; - public Subscription(Class eventType, Consumer consumer) { + Subscription(Class eventType, Consumer consumer) { this.eventType = eventType; this.consumer = consumer; } @@ -91,12 +92,16 @@ boolean matches(E event) { */ void handle(E event) { try { - consumer.accept(event.getPayload()); + handlePayload(event.getPayload()); } catch (Throwable e) { log.error(eventType.getSimpleName() + " handling error: ", e); } } + protected void handlePayload(D payload) { + consumer.accept(payload); + } + /** * Tests whether publisher should remove current {@link Subscription} after specified event handling. * diff --git a/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java b/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java index c63e45148c..9bf5a6f0ce 100644 --- a/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java @@ -22,7 +22,11 @@ import com.google.common.util.concurrent.ListenableFuture; import org.apache.commons.lang3.tuple.Pair; import org.ethereum.config.SystemProperties; -import org.ethereum.core.*; +import org.ethereum.core.AccountState; +import org.ethereum.core.Block; +import org.ethereum.core.BlockHeader; +import org.ethereum.core.BlockIdentifier; +import org.ethereum.core.BlockchainImpl; import org.ethereum.crypto.HashUtil; import org.ethereum.datasource.DbSource; import org.ethereum.datasource.NodeKeyCompositor; @@ -40,7 +44,11 @@ import org.ethereum.publish.Publisher; import org.ethereum.publish.event.SyncDone; import org.ethereum.trie.TrieKey; -import org.ethereum.util.*; +import org.ethereum.util.ByteArrayMap; +import org.ethereum.util.ByteArraySet; +import org.ethereum.util.FastByteComparisons; +import org.ethereum.util.FileUtil; +import org.ethereum.util.Value; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -52,11 +60,27 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.*; -import java.util.concurrent.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; -import static org.ethereum.listener.EthereumListener.SyncState.*; +import static org.ethereum.listener.EthereumListener.SyncState.COMPLETE; +import static org.ethereum.listener.EthereumListener.SyncState.SECURE; +import static org.ethereum.listener.EthereumListener.SyncState.UNSECURE; +import static org.ethereum.publish.Subscription.to; import static org.ethereum.trie.TrieKey.fromPacked; import static org.ethereum.util.ByteUtil.toHexString; import static org.ethereum.util.CompactEncoder.hasTerminator; @@ -563,7 +587,7 @@ private void syncUnsecure(BlockHeader pivot) { logger.info("FastSync: proceeding to regular sync..."); final CountDownLatch syncDoneLatch = new CountDownLatch(1); - publisher.subscribe(SyncDone.class, syncState -> syncDoneLatch.countDown()); + publisher.subscribe(to(SyncDone.class, syncState -> syncDoneLatch.countDown())); syncManager.initRegularSync(UNSECURE); logger.info("FastSync: waiting for regular sync to reach the blockchain head..."); diff --git a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java index 54a4496425..f1bdd62430 100644 --- a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java @@ -32,7 +32,7 @@ import org.ethereum.db.RepositoryRoot; import org.ethereum.listener.EthereumListener; import org.ethereum.mine.Ethash; -import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; +import org.ethereum.listener.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.Subscription; import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.Event; diff --git a/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java b/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java index 901e65afaa..c323b3769f 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java @@ -27,7 +27,7 @@ import org.ethereum.db.IndexedBlockStore; import org.ethereum.db.RepositoryRoot; import org.ethereum.mine.Ethash; -import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; +import org.ethereum.listener.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.event.TransactionExecuted; import org.ethereum.util.ByteUtil; import org.ethereum.util.blockchain.SolidityContract; diff --git a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateLongRunTest.java b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateLongRunTest.java index 926e5317f0..72e0620a32 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateLongRunTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateLongRunTest.java @@ -21,7 +21,7 @@ import org.ethereum.datasource.inmem.HashMapDB; import org.ethereum.db.IndexedBlockStore; import org.ethereum.db.RepositoryRoot; -import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; +import org.ethereum.listener.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.validator.DependentBlockHeaderRuleAdapter; import org.ethereum.vm.program.invoke.ProgramInvokeFactoryImpl; import org.junit.Before; diff --git a/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/suite/TestRunner.java b/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/suite/TestRunner.java index 386e07f797..e6e1c485af 100644 --- a/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/suite/TestRunner.java +++ b/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/suite/TestRunner.java @@ -27,7 +27,7 @@ import org.ethereum.jsontestsuite.suite.model.BlockTck; import org.ethereum.jsontestsuite.suite.validators.BlockHeaderValidator; import org.ethereum.jsontestsuite.suite.validators.RepositoryValidator; -import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; +import org.ethereum.listener.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.util.ByteUtil; import org.ethereum.vm.DataWord; import org.ethereum.vm.LogInfo; diff --git a/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java b/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java index c53d747d49..10e300da8a 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java @@ -28,7 +28,7 @@ import org.ethereum.net.eth.message.EthMessage; import org.ethereum.net.eth.message.GetBlockBodiesMessage; import org.ethereum.net.eth.message.GetBlockHeadersMessage; -import org.ethereum.publish.BackwardCompatibilityEthereumListenerProxy; +import org.ethereum.listener.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.sync.SyncManager; import org.junit.Before; import org.junit.Test; diff --git a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java index f6271b6bc5..25a70b1940 100644 --- a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java @@ -129,6 +129,26 @@ public void testOneOffSubscription() { assertEquals(expected, actual.get()); } + @Test + public void testLifeCycleSubscription() { + AtomicInteger actual = new AtomicInteger(); + final int expected = 5; + + Publisher publisher = createPublisher() + .subscribe(LifeCycleSubscription.to(IntEvent.class, (num, lc) -> { + if (num == expected) { + actual.set(num); + lc.unsubscribe(); + } + })); + + IntStream.rangeClosed(1, 10) + .mapToObj(IntEvent::new) + .forEach(publisher::publish); + + assertEquals(expected, actual.get()); + } + @Test public void testPublishing() { From 7fc9119682811d4684a840462137924a1fe1e38d Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Fri, 17 Aug 2018 15:26:58 +0300 Subject: [PATCH 14/28] Reverts formattings changes. --- .../org/ethereum/config/CommonConfig.java | 21 ++++--- .../org/ethereum/core/BlockchainImpl.java | 20 +++---- .../java/org/ethereum/facade/Ethereum.java | 7 +-- .../org/ethereum/facade/EthereumImpl.java | 18 +++--- ...ardCompatibilityEthereumListenerProxy.java | 13 +++++ .../listener/CompositeEthereumListener.java | 2 + .../ethereum/listener/EthereumListener.java | 6 ++ .../org/ethereum/listener/EventListener.java | 2 +- .../ethereum/listener/GasPriceTracker.java | 9 ++- .../org/ethereum/manager/WorldManager.java | 57 ++++++++++--------- .../java/org/ethereum/mine/BlockMiner.java | 4 -- .../java/org/ethereum/net/MessageQueue.java | 12 ++-- .../org/ethereum/net/client/PeerClient.java | 13 +++-- .../org/ethereum/net/eth/handler/Eth62.java | 2 +- .../ethereum/net/eth/handler/EthHandler.java | 12 ++-- .../java/org/ethereum/net/p2p/P2pHandler.java | 32 ++++++----- .../org/ethereum/net/rlpx/MessageCodec.java | 7 +-- .../net/rlpx/discover/NodeManager.java | 12 ++-- .../org/ethereum/net/server/PeerServer.java | 16 ++++-- .../java/org/ethereum/net/shh/ShhHandler.java | 17 +++--- .../ethereum/net/swarm/bzz/BzzHandler.java | 8 +-- .../main/java/org/ethereum/sync/SyncPool.java | 4 +- .../org/ethereum/validator/EthashRule.java | 14 +---- .../org/ethereum/publish/PublisherTest.java | 2 - 24 files changed, 170 insertions(+), 140 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java b/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java index 385b2abee2..483cc32ae8 100644 --- a/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java +++ b/ethereumj-core/src/main/java/org/ethereum/config/CommonConfig.java @@ -24,11 +24,15 @@ 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.listener.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.Publisher; import org.ethereum.sync.FastSyncManager; import org.ethereum.validator.*; @@ -37,7 +41,12 @@ 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; @@ -235,12 +244,6 @@ public CompositeEthereumListener compositeEthereumListener(EventDispatchThread e return new CompositeEthereumListener(eventDispatchThread); } - @Bean - @Primary - public EthereumListener ethereumListener(CompositeEthereumListener compositeListener, Publisher publisher) { - return new BackwardCompatibilityEthereumListenerProxy(compositeListener, publisher); - } - @Bean @Lazy public DbSource headerSource() { diff --git a/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java b/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java index 3590261573..f67ae366c4 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/BlockchainImpl.java @@ -70,7 +70,6 @@ import static java.lang.Math.max; import static java.lang.Runtime.getRuntime; -import static java.lang.String.format; import static java.math.BigInteger.ONE; import static java.math.BigInteger.ZERO; import static java.util.Collections.emptyList; @@ -141,7 +140,7 @@ public class BlockchainImpl implements Blockchain, org.ethereum.facade.Blockchai private BigInteger totalDifficulty = ZERO; @Autowired - private EthereumListener listenerProxy; + private EthereumListener listener; @Autowired ProgramInvokeFactory programInvokeFactory; @@ -191,9 +190,7 @@ public class BlockchainImpl implements Blockchain, org.ethereum.facade.Blockchai private Stack stateStack = new Stack<>(); - /** - * Tests only - **/ + /** Tests only **/ public BlockchainImpl() { } @@ -208,7 +205,7 @@ public BlockchainImpl(final BlockStore blockStore, final Repository repository, this.blockStore = blockStore; this.repository = repository; this.adminInfo = new AdminInfo(); - this.listenerProxy = listener; + this.listener = listener; this.parentHeaderValidator = null; this.transactionStore = new TransactionStore(new HashMapDB()); this.eventDispatchThread = EventDispatchThread.getDefault(); @@ -467,8 +464,8 @@ public synchronized ImportResult tryToConnect(final Block block) { } if (ret.isSuccessful()) { - listenerProxy.onBlock(summary, ret == IMPORTED_BEST); - listenerProxy.trace(format("Block chain size: [ %d ]", this.getSize())); + listener.onBlock(summary, ret == IMPORTED_BEST); + listener.trace(String.format("Block chain size: [ %d ]", this.getSize())); if (ret == IMPORTED_BEST) { eventDispatchThread.invokeLater(() -> pendingState.processBest(block, summary.getReceipts())); @@ -864,7 +861,8 @@ private BlockSummary processBlock(Repository track, Block block) { if (!block.isGenesis() && !config.blockChainOnly()) { return applyBlock(track, block); - } else { + } + else { return new BlockSummary(block, new HashMap(), new ArrayList(), new ArrayList()); } } @@ -887,7 +885,7 @@ private BlockSummary applyBlock(Repository track, Block block) { Repository txTrack = track.startTracking(); TransactionExecutor executor = new TransactionExecutor(tx, block.getCoinbase(), - txTrack, blockStore, programInvokeFactory, block, listenerProxy, totalGasUsed) + txTrack, blockStore, programInvokeFactory, block, listener, totalGasUsed) .withCommonConfig(commonConfig); executor.init(); @@ -1227,7 +1225,6 @@ public Iterator 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 */ @@ -1247,7 +1244,6 @@ private BlockHeader findHeaderByNumber(long number) { /** * Searches block in blockStore, if it's not found there * and headerStore is defined, searches blockHeader in it. - * * @param hash block hash * @return Block header */ diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java index afde481a78..257b9502d9 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java @@ -70,14 +70,12 @@ public interface Ethereum { * Adds subscription for specific event. * * @param subscription - * @param event type to listen; - * @param

      {@link Event} payload type, which will be passed to subscription handler; * @return publisher instance to support fluent API. * @see Subscription * @see Publisher * @see Event */ - , P> Publisher subscribe(Subscription subscription); + Publisher subscribe(Subscription subscription); PeerClient getDefaultPeer(); @@ -228,7 +226,8 @@ ProgramResult callConstantFunction(String receiveAddress, ECKey senderPrivateKey void initSyncing(); /** - * @deprecated Calculates a 'reasonable' Gas price based on statistics of the latest transaction's Gas prices + * @deprecated + * Calculates a 'reasonable' Gas price based on statistics of the latest transaction's Gas prices * Normally the price returned should be sufficient to execute a transaction since ~25% of the latest * transactions were executed at this or lower price. * If the transaction is wanted to be executed promptly with higher chances the returned price might diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index c71971e8fc..19a7794dbf 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -20,9 +20,15 @@ import org.ethereum.config.BlockchainConfig; import org.ethereum.config.CommonConfig; import org.ethereum.config.SystemProperties; -import org.ethereum.core.*; +import org.ethereum.core.Block; +import org.ethereum.core.BlockSummary; +import org.ethereum.core.CallTransaction; +import org.ethereum.core.ImportResult; import org.ethereum.core.PendingState; import org.ethereum.core.Repository; +import org.ethereum.core.Transaction; +import org.ethereum.core.TransactionExecutionSummary; +import org.ethereum.core.TransactionReceipt; import org.ethereum.crypto.ECKey; import org.ethereum.listener.EthereumListener; import org.ethereum.listener.GasPriceTracker; @@ -39,7 +45,6 @@ import org.ethereum.publish.Publisher; import org.ethereum.publish.Subscription; import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.Event; import org.ethereum.sync.SyncManager; import org.ethereum.util.ByteUtil; import org.ethereum.vm.program.ProgramResult; @@ -111,9 +116,6 @@ public class EthereumImpl implements Ethereum, SmartLifecycle { private GasPriceTracker gasPriceTracker = new GasPriceTracker(); - @Autowired - private Publisher publisher; - @Autowired public EthereumImpl(final SystemProperties config) { this.config = config; @@ -123,9 +125,7 @@ public EthereumImpl(final SystemProperties config) { @PostConstruct public void init() { - publisher.subscribe(to(BlockAdded.class, data -> { - data.getBlockSummary().getBlock().getTransactionsList().forEach(gasPriceTracker::onTransaction); - })); + worldManager.subscribe(to(BlockAdded.class, data -> gasPriceTracker.onBlock(data.getBlockSummary()))); } @Override @@ -178,7 +178,7 @@ public void addListener(EthereumListener listener) { } @Override - public , P> Publisher subscribe(Subscription subscription) { + public Publisher subscribe(Subscription subscription) { return worldManager.getPublisher().subscribe(subscription); } diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java b/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java index 7531f41b11..6096bc9a01 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java @@ -8,14 +8,27 @@ import org.ethereum.net.server.Channel; import org.ethereum.publish.Publisher; import org.ethereum.publish.event.Events; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; import java.util.List; +/** + * Backward compatibility component that holds old and new event publishing implementations.
      + * Proxies all events to both implementations. + * Will be removed after {@link EthereumListener} eviction. + * + * @author Eugene Shevchenko + */ +@Primary +@Component public class BackwardCompatibilityEthereumListenerProxy implements EthereumListener { private final CompositeEthereumListener compositeListener; private final Publisher publisher; + @Autowired public BackwardCompatibilityEthereumListenerProxy(CompositeEthereumListener listener, Publisher publisher) { this.compositeListener = listener; this.publisher = publisher; diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/CompositeEthereumListener.java b/ethereumj-core/src/main/java/org/ethereum/listener/CompositeEthereumListener.java index ef1cf12dbb..ec021f7924 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/CompositeEthereumListener.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/CompositeEthereumListener.java @@ -29,9 +29,11 @@ import java.util.concurrent.Executor; /** + * @deprecated use {@link org.ethereum.publish.Publisher} instead. * @author Roman Mandeleil * @since 12.11.2014 */ +@Deprecated public class CompositeEthereumListener implements EthereumListener { private static abstract class RunnableInfo implements Runnable { diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java b/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java index 98265ffb4e..24f4a4fec9 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java @@ -36,6 +36,9 @@ */ public interface EthereumListener { + /** + * Will be extracted to separate enum in future releases after {@link EthereumListener} eviction. + */ enum PendingTransactionState { /** * Transaction may be dropped due to: @@ -76,6 +79,9 @@ public boolean isPending() { } } + /** + * Will be extracted to separate enum in future releases after {@link EthereumListener} eviction. + */ enum SyncState { /** * When doing fast sync UNSECURE sync means that the full state is downloaded, diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/EventListener.java b/ethereumj-core/src/main/java/org/ethereum/listener/EventListener.java index c07a3beb4e..f00fe5e3b5 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/EventListener.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/EventListener.java @@ -118,7 +118,7 @@ public String toString() { private boolean initialized = false; // txHash => PendingEvent - protected ByteArrayMap pendings = new ByteArrayMap<>(new LinkedHashMap<>()); + protected ByteArrayMap pendings = new ByteArrayMap<>(new LinkedHashMap()); protected Block bestBlock; BigInteger lastTotDiff = BigInteger.ZERO; // executing EthereumListener callbacks on a separate thread to avoid long running diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java b/ethereumj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java index 56693bcfc1..ab7c53c17d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java @@ -17,6 +17,7 @@ */ package org.ethereum.listener; +import org.ethereum.core.BlockSummary; import org.ethereum.core.Transaction; import org.ethereum.util.ByteUtil; @@ -40,7 +41,13 @@ public class GasPriceTracker { private long lastVal; - public void onTransaction(Transaction tx) { + public void onBlock(BlockSummary blockSummary) { + for (Transaction tx : blockSummary.getBlock().getTransactionsList()) { + onTransaction(tx); + } + } + + private void onTransaction(Transaction tx) { if (idx == -1) { idx = window.length - 1; filled = true; diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java index 7f63931271..92b06e1d7b 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java @@ -18,19 +18,26 @@ package org.ethereum.manager; import org.ethereum.config.SystemProperties; -import org.ethereum.core.*; +import org.ethereum.core.Block; +import org.ethereum.core.BlockSummary; +import org.ethereum.core.Blockchain; +import org.ethereum.core.BlockchainImpl; +import org.ethereum.core.EventDispatchThread; +import org.ethereum.core.Genesis; +import org.ethereum.core.PendingState; +import org.ethereum.core.Repository; import org.ethereum.db.BlockStore; import org.ethereum.db.DbFlushManager; import org.ethereum.db.HeaderStore; import org.ethereum.db.migrate.MigrateHeaderSourceTotalDiff; +import org.ethereum.listener.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.listener.EthereumListener; import org.ethereum.net.client.PeerClient; import org.ethereum.net.rlpx.discover.NodeManager; import org.ethereum.net.rlpx.discover.UDPListener; import org.ethereum.net.server.ChannelManager; -import org.ethereum.listener.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.Event; +import org.ethereum.publish.Subscription; import org.ethereum.sync.FastSyncManager; import org.ethereum.sync.SyncManager; import org.ethereum.sync.SyncPool; @@ -38,19 +45,19 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; +import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.math.BigInteger; import java.util.Arrays; -import java.util.function.Consumer; import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; import static org.ethereum.crypto.HashUtil.EMPTY_TRIE_HASH; -import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.ByteUtil.toHexString; /** @@ -60,7 +67,7 @@ * @since 01.06.2014 */ @Component -public class WorldManager { +public class WorldManager implements ApplicationContextAware { private static final Logger logger = LoggerFactory.getLogger("general"); @@ -70,9 +77,6 @@ public class WorldManager { @Autowired private ChannelManager channelManager; - @Autowired - private AdminInfo adminInfo; - @Autowired private NodeManager nodeManager; @@ -94,18 +98,12 @@ public class WorldManager { @Autowired private DbFlushManager dbFlushManager; - @Autowired private ApplicationContext ctx; - - private SystemProperties config; - - private EthereumListener listener; - - private Blockchain blockchain; - - private Repository repository; - - private BlockStore blockStore; + private final SystemProperties config; + private final EthereumListener listener; + private final Blockchain blockchain; + private final Repository repository; + private final BlockStore blockStore; @Autowired public WorldManager(SystemProperties config, Repository repository, EthereumListener listener, @@ -116,6 +114,7 @@ public WorldManager(SystemProperties config, Repository repository, EthereumList this.repository = repository; this.blockStore = blockStore; this.config = config; + loadBlockchain(); } @@ -125,18 +124,25 @@ private void init() { syncManager.init(channelManager, pool); } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.ctx = applicationContext; + } + /** * @param listener - * @deprecated use {@link #subscribe(Class, Consumer)} instead. + * @deprecated use #subscription instead. */ @Deprecated public void addListener(EthereumListener listener) { logger.info("Ethereum listener added"); - ((BackwardCompatibilityEthereumListenerProxy) listener).addListener(listener); + ((BackwardCompatibilityEthereumListenerProxy) listener).getCompositeListener().addListener(listener); } - public , P> Publisher subscribe(Class eventType, Consumer

      handler) { - return getPublisher().subscribe(to(eventType, handler)); + + public Publisher subscribe(Subscription subscription) { + return getPublisher().subscribe(subscription); } public void startPeerDiscovery() { @@ -208,8 +214,7 @@ public void loadBlockchain() { blockchain.setBestBlock(Genesis.getInstance(config)); blockchain.setTotalDifficulty(Genesis.getInstance(config).getDifficultyBI()); - BlockSummary blockSummary = new BlockSummary(Genesis.getInstance(config), emptyMap(), emptyList(), emptyList()); - listener.onBlock(blockSummary, true); + listener.onBlock(new BlockSummary(Genesis.getInstance(config), emptyMap(), emptyList(), emptyList()), true); // repository.dumpState(Genesis.getInstance(config), 0, 0, null); logger.info("Genesis block loaded"); diff --git a/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java b/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java index 06e433a021..4bbf7f1d93 100644 --- a/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java +++ b/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java @@ -333,25 +333,21 @@ protected void fireMinerStarted() { l.miningStarted(); } } - protected void fireMinerStopped() { for (MinerListener l : listeners) { l.miningStopped(); } } - protected void fireBlockStarted(Block b) { for (MinerListener l : listeners) { l.blockMiningStarted(b); } } - protected void fireBlockCancelled(Block b) { for (MinerListener l : listeners) { l.blockMiningCanceled(b); } } - protected void fireBlockMined(Block b) { for (MinerListener l : listeners) { l.blockMined(b); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java b/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java index 82e65182d6..4d2296b7d1 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/MessageQueue.java @@ -25,6 +25,7 @@ import org.ethereum.net.message.ReasonCode; import org.ethereum.net.p2p.DisconnectMessage; import org.ethereum.net.p2p.PingMessage; +import org.ethereum.net.p2p.PongMessage; import org.ethereum.net.server.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,14 +41,14 @@ /** * This class contains the logic for sending messages in a queue - *

      + * * Messages open by send and answered by receive of appropriate message * PING by PONG * GET_PEERS by PEERS * GET_TRANSACTIONS by TRANSACTIONS * GET_BLOCK_HASHES by BLOCK_HASHES * GET_BLOCKS by BLOCKS - *

      + * * The following messages will not be answered: * PONG, PEERS, HELLO, STATUS, TRANSACTIONS, BLOCKS * @@ -72,7 +73,7 @@ public Thread newThread(Runnable r) { private ChannelHandlerContext ctx = null; @Autowired - private EthereumListener listener; + EthereumListener ethereumListener; boolean hasPing = false; private ScheduledFuture timerTask; private Channel channel; @@ -126,7 +127,8 @@ private void disconnect(DisconnectMessage msg) { } public void receivedMessage(Message msg) throws InterruptedException { - listener.trace("[Recv: " + msg + "]"); + + ethereumListener.trace("[Recv: " + msg + "]"); if (requestQueue.peek() != null) { MessageRoundtrip messageRoundtrip = requestQueue.peek(); @@ -165,7 +167,7 @@ private void sendToWire(MessageRoundtrip messageRoundtrip) { Message msg = messageRoundtrip.getMsg(); - listener.onSendMessage(channel, msg); + ethereumListener.onSendMessage(channel, msg); ctx.writeAndFlush(msg).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java b/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java index 219cdca197..10b71361a7 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/client/PeerClient.java @@ -17,6 +17,10 @@ */ package org.ethereum.net.client; +import org.ethereum.config.SystemProperties; +import org.ethereum.listener.EthereumListener; +import org.ethereum.net.server.EthereumChannelInitializer; + import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; @@ -24,11 +28,10 @@ import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; -import org.ethereum.config.SystemProperties; -import org.ethereum.listener.EthereumListener; -import org.ethereum.net.server.EthereumChannelInitializer; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; @@ -55,7 +58,7 @@ public class PeerClient { private ApplicationContext ctx; @Autowired - private EthereumListener listener; + EthereumListener ethereumListener; private EventLoopGroup workerGroup; @@ -102,7 +105,7 @@ public void connect(String host, int port, String remoteId, boolean discoveryMod } public ChannelFuture connectAsync(String host, int port, String remoteId, boolean discoveryMode) { - listener.trace("Connecting to: " + host + ":" + port); + ethereumListener.trace("Connecting to: " + host + ":" + port); EthereumChannelInitializer ethereumChannelInitializer = ctx.getBean(EthereumChannelInitializer.class, remoteId); ethereumChannelInitializer.setPeerDiscoveryMode(discoveryMode); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java index 0c5f9e73b8..073bcf02bb 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java @@ -339,7 +339,7 @@ protected synchronized void processStatus(StatusMessage msg, ChannelHandlerConte // basic checks passed, update statistics channel.getNodeStatistics().ethHandshake(msg); - listener.onEthStatusUpdated(channel, msg); + ethereumListener.onEthStatusUpdated(channel, msg); if (peerDiscoveryMode) { loggerNet.trace("Peer discovery mode: STATUS received, disconnecting..."); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java index 0bc2dd4cfd..c7e79efe9d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java @@ -53,7 +53,7 @@ public abstract class EthHandler extends SimpleChannelInboundHandler protected SystemProperties config; - protected EthereumListener listener; + protected EthereumListener ethereumListener; protected Channel channel; @@ -64,9 +64,9 @@ public abstract class EthHandler extends SimpleChannelInboundHandler protected boolean peerDiscoveryMode = false; protected Block bestBlock; + private Subscription bestBlockSub; protected boolean processTransactions = false; - private Subscription bestBlockSub; protected EthHandler(EthVersion version) { this.version = version; @@ -79,7 +79,7 @@ protected EthHandler(final EthVersion version, final SystemProperties config, this.config = config; this.blockchain = blockchain; this.bestBlock = blockStore.getBestBlock(); - this.listener = listener; + this.ethereumListener = listener; this.bestBlockSub = Subscription.to(BlockAdded.class, this::setBestBlock); getPublisher().subscribe(this.bestBlockSub); @@ -97,7 +97,7 @@ public void channelRead0(final ChannelHandlerContext ctx, EthMessage msg) throws if (EthMessageCodes.inRange(msg.getCommand().asByte(), version)) logger.trace("EthHandler invoke: [{}]", msg.getCommand()); - listener.trace(format("EthHandler invoke: [%s]", msg.getCommand())); + ethereumListener.trace(String.format("EthHandler invoke: [%s]", msg.getCommand())); channel.getNodeStatistics().ethInbound.add(); @@ -105,7 +105,7 @@ public void channelRead0(final ChannelHandlerContext ctx, EthMessage msg) throws } public Publisher getPublisher() { - return ((BackwardCompatibilityEthereumListenerProxy) listener).getPublisher(); + return ((BackwardCompatibilityEthereumListenerProxy) ethereumListener).getPublisher(); } @Override @@ -123,7 +123,7 @@ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { public void activate() { logger.debug("ETH protocol activated"); - listener.trace("ETH protocol activated"); + ethereumListener.trace("ETH protocol activated"); sendStatus(); } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java index d1144fd48d..37fefab397 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/p2p/P2pHandler.java @@ -17,12 +17,11 @@ */ package org.ethereum.net.p2p; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; import org.ethereum.config.SystemProperties; import org.ethereum.core.Block; import org.ethereum.core.Transaction; import org.ethereum.listener.EthereumListener; +import org.ethereum.manager.WorldManager; import org.ethereum.net.MessageQueue; import org.ethereum.net.client.Capability; import org.ethereum.net.client.ConfigCapabilities; @@ -32,25 +31,30 @@ import org.ethereum.net.message.StaticMessages; import org.ethereum.net.server.Channel; import org.ethereum.net.shh.ShhHandler; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; + import org.ethereum.net.swarm.Util; import org.ethereum.net.swarm.bzz.BzzHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import java.net.InetAddress; +import java.net.InetSocketAddress; + import java.util.ArrayList; +import java.util.HashSet; import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; +import java.util.Set; +import java.util.concurrent.*; -import static java.lang.String.format; -import static org.ethereum.net.eth.EthVersion.fromCode; -import static org.ethereum.net.message.StaticMessages.PING_MESSAGE; -import static org.ethereum.net.message.StaticMessages.PONG_MESSAGE; +import static org.ethereum.net.eth.EthVersion.*; +import static org.ethereum.net.message.StaticMessages.*; /** * Process the basic protocol messages between every peer on the network. @@ -86,7 +90,7 @@ public class P2pHandler extends SimpleChannelInboundHandler { private int ethOutbound; @Autowired - private EthereumListener listener; + EthereumListener ethereumListener; @Autowired ConfigCapabilities configCapabilities; @@ -118,7 +122,7 @@ public void setPeerDiscoveryMode(boolean peerDiscoveryMode) { public void handlerAdded(ChannelHandlerContext ctx) throws Exception { logger.debug("P2P protocol activated"); msgQueue.activate(ctx); - listener.trace("P2P protocol activated"); + ethereumListener.trace("P2P protocol activated"); startTimers(); } @@ -129,7 +133,7 @@ public void channelRead0(final ChannelHandlerContext ctx, P2pMessage msg) throws if (P2pMessageCodes.inRange(msg.getCommand().asByte())) logger.trace("P2PHandler invoke: [{}]", msg.getCommand()); - listener.trace(format("P2PHandler invoke: [%s]", msg.getCommand())); + ethereumListener.trace(String.format("P2PHandler invoke: [%s]", msg.getCommand())); switch (msg.getCommand()) { case HELLO: @@ -241,7 +245,7 @@ public void setHandshake(HelloMessage msg, ChannelHandlerContext ctx) { } //todo calculate the Offsets - listener.onHandShakePeer(channel, msg); + ethereumListener.onHandShakePeer(channel, msg); } /** diff --git a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java index 2dfc3a744e..536357b52a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/MessageCodec.java @@ -72,7 +72,7 @@ public class MessageCodec extends MessageToMessageCodec { private EthVersion ethVersion; @Autowired - private EthereumListener listener; + EthereumListener ethereumListener; private SystemProperties config; @@ -166,7 +166,7 @@ private Message decodeMessage(ChannelHandlerContext ctx, List frames) thr return null; } - listener.onRecvMessage(channel, msg); + ethereumListener.onRecvMessage(channel, msg); channel.getNodeStatistics().rlpxInMessages.add(); return msg; @@ -175,8 +175,7 @@ private Message decodeMessage(ChannelHandlerContext ctx, List frames) thr @Override protected void encode(ChannelHandlerContext ctx, Message msg, List out) throws Exception { String output = String.format("To: \t%s \tSend: \t%s", ctx.channel().remoteAddress(), msg); - - listener.trace(output); + ethereumListener.trace(output); if (loggerNet.isDebugEnabled()) loggerNet.debug("To: {} Send: {}", channel, msg); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java index ca295e26e8..58dee3a7b1 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/rlpx/discover/NodeManager.java @@ -38,6 +38,8 @@ import java.util.function.Consumer; import java.util.function.Predicate; +import static java.lang.Math.min; + /** * The central class for Peer Discovery machinery. * @@ -60,7 +62,7 @@ public class NodeManager implements Consumer{ PeerConnectionTester peerConnectionManager; PeerSource peerSource; - EthereumListener listener; + EthereumListener ethereumListener; SystemProperties config = SystemProperties.getDefault(); Consumer messageSender; @@ -84,10 +86,10 @@ public class NodeManager implements Consumer{ private ScheduledExecutorService pongTimer; @Autowired - public NodeManager(SystemProperties config, EthereumListener listener, + public NodeManager(SystemProperties config, EthereumListener ethereumListener, ApplicationContext ctx, PeerConnectionTester peerConnectionManager) { this.config = config; - this.listener = listener; + this.ethereumListener = ethereumListener; this.peerConnectionManager = peerConnectionManager; PERSIST = config.peerDiscoveryPersist(); @@ -196,14 +198,14 @@ public synchronized NodeHandler getNodeHandler(Node n) { nodeHandlerMap.put(key, ret); logger.debug(" +++ New node: " + ret + " " + n); if (!n.isDiscoveryNode() && !n.getHexId().equals(homeNode.getHexId())) { - listener.onNodeDiscovered(ret.getNode()); + ethereumListener.onNodeDiscovered(ret.getNode()); } } else if (ret.getNode().isDiscoveryNode() && !n.isDiscoveryNode()) { // we found discovery node with same host:port, // replace node with correct nodeId ret.node = n; if (!n.getHexId().equals(homeNode.getHexId())) { - listener.onNodeDiscovered(ret.getNode()); + ethereumListener.onNodeDiscovered(ret.getNode()); } logger.debug(" +++ Found real nodeId for discovery endpoint {}", n); } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java b/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java index 99cd8396e2..f4ae5ac1c7 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/server/PeerServer.java @@ -17,6 +17,9 @@ */ package org.ethereum.net.server; +import org.ethereum.config.SystemProperties; +import org.ethereum.listener.EthereumListener; + import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; @@ -25,10 +28,10 @@ import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LoggingHandler; -import org.ethereum.config.SystemProperties; -import org.ethereum.listener.EthereumListener; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; @@ -51,7 +54,7 @@ public class PeerServer { private ApplicationContext ctx; - private EthereumListener listener; + private EthereumListener ethereumListener; public EthereumChannelInitializer ethereumChannelInitializer; @@ -63,10 +66,10 @@ public class PeerServer { @Autowired public PeerServer(final SystemProperties config, final ApplicationContext ctx, - final EthereumListener listener) { + final EthereumListener ethereumListener) { this.ctx = ctx; this.config = config; - this.listener = listener; + this.ethereumListener = ethereumListener; } public void start(int port) { @@ -76,7 +79,8 @@ public void start(int port) { ethereumChannelInitializer = ctx.getBean(EthereumChannelInitializer.class, ""); - listener.trace("Listening on port " + port); + ethereumListener.trace("Listening on port " + port); + try { ServerBootstrap b = new ServerBootstrap(); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java index 6a6bad2ca2..5e6a90717f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/shh/ShhHandler.java @@ -17,18 +17,19 @@ */ package org.ethereum.net.shh; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; import org.ethereum.listener.EthereumListener; import org.ethereum.net.MessageQueue; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; -import static java.lang.String.format; - /** * Process the messages between peers with 'shh' capability on the network. * @@ -45,7 +46,7 @@ public class ShhHandler extends SimpleChannelInboundHandler { private BloomFilter peerBloomFilter = BloomFilter.createAll(); @Autowired - private EthereumListener listener; + private EthereumListener ethereumListener; @Autowired private WhisperImpl whisper; @@ -65,11 +66,11 @@ public void channelRead0(final ChannelHandlerContext ctx, ShhMessage msg) throws if (ShhMessageCodes.inRange(msg.getCommand().asByte())) logger.info("ShhHandler invoke: [{}]", msg.getCommand()); - listener.trace(format("ShhHandler invoke: [%s]", msg.getCommand())); + ethereumListener.trace(String.format("ShhHandler invoke: [%s]", msg.getCommand())); switch (msg.getCommand()) { case STATUS: - listener.trace("[Recv: " + msg + "]"); + ethereumListener.trace("[Recv: " + msg + "]"); break; case MESSAGE: whisper.processEnvelope((ShhEnvelopeMessage) msg, this); @@ -103,7 +104,7 @@ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { public void activate() { logger.info("SHH protocol activated"); - listener.trace("SHH protocol activated"); + ethereumListener.trace("SHH protocol activated"); whisper.addPeer(this); sendStatus(); sendHostBloom(); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java index 991673ab50..0dfc40426d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/swarm/bzz/BzzHandler.java @@ -30,8 +30,6 @@ import java.util.function.Consumer; -import static java.lang.String.format; - /** * Process the messages between peers with 'bzz' capability on the network. */ @@ -50,7 +48,7 @@ public class BzzHandler extends SimpleChannelInboundHandler BzzProtocol bzzProtocol; @Autowired - private EthereumListener listener; + EthereumListener ethereumListener; @Autowired NetStore netStore; @@ -70,7 +68,7 @@ public void channelRead0(final ChannelHandlerContext ctx, BzzMessage msg) throws if (BzzMessageCodes.inRange(msg.getCommand().asByte())) logger.debug("BzzHandler invoke: [{}]", msg.getCommand()); - listener.trace(format("BzzHandler invoke: [%s]", msg.getCommand())); + ethereumListener.trace(String.format("BzzHandler invoke: [%s]", msg.getCommand())); if (bzzProtocol != null) { bzzProtocol.accept(msg); @@ -97,7 +95,7 @@ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { public void activate() { logger.info("BZZ protocol activated"); - listener.trace("BZZ protocol activated"); + ethereumListener.trace("BZZ protocol activated"); createBzzProtocol(); this.active = true; } diff --git a/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java b/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java index 7c1b379a3a..ebed0b490d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java +++ b/ethereumj-core/src/main/java/org/ethereum/sync/SyncPool.java @@ -70,7 +70,7 @@ public class SyncPool { private BigInteger lowerUsefulDifficulty = BigInteger.ZERO; @Autowired - private EthereumListener listener; + private EthereumListener ethereumListener; @Autowired private NodeManager nodeManager; @@ -339,7 +339,7 @@ private synchronized void prepareActive() { for (Channel channel : filtered) { if (!activePeers.contains(channel)) { - listener.onPeerAddedToSyncPool(channel); + ethereumListener.onPeerAddedToSyncPool(channel); } } if (logger.isTraceEnabled()) diff --git a/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java b/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java index 079ec7e897..62710058c6 100644 --- a/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java +++ b/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java @@ -73,17 +73,9 @@ static Mode parse(String name, Mode defaultMode) { } public enum ChainType { - main, /** - * main chain, cache updates are stick to best block events, requires listener - */ - direct, /** - * side chain, cache is triggered each validation attempt, no listener required - */ - reverse; - - /** - * side chain with reverted validation order - */ + main, /** main chain, cache updates are stick to best block events, requires listener */ + direct, /** side chain, cache is triggered each validation attempt, no listener required */ + reverse; /** side chain with reverted validation order */ public boolean isSide() { return this == reverse || this == direct; diff --git a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java index 25a70b1940..df3a68e581 100644 --- a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java @@ -42,7 +42,6 @@ private class OneOffStringEvent extends StringEvent implements OneOffEvent { } } - @Test public void testDuplicateSubscription() { Subscription subscription = Subscription.to(IntEvent.class, System.out::print); @@ -55,7 +54,6 @@ public void testDuplicateSubscription() { assertEquals(1, subscribersCount); } - @Test public void testSingleEvent() { final String payload = "desired event"; From 2e0793486af3160825cfdebbf54917bb89acd151 Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Mon, 20 Aug 2018 18:10:15 +0300 Subject: [PATCH 15/28] Adds concurrency testing. --- .../java/org/ethereum/publish/Publisher.java | 41 +++- .../org/ethereum/publish/Subscription.java | 6 +- .../ethereum/publish/event/SignalEvent.java | 13 -- .../org/ethereum/publish/EventGenerator.java | 34 ++++ .../java/org/ethereum/publish/Events.java | 31 +++ .../org/ethereum/publish/PublisherTest.java | 182 +++++++++++++----- .../org/ethereum/util/RandomGenerator.java | 39 ++++ 7 files changed, 278 insertions(+), 68 deletions(-) delete mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/event/SignalEvent.java create mode 100644 ethereumj-core/src/test/java/org/ethereum/publish/EventGenerator.java create mode 100644 ethereumj-core/src/test/java/org/ethereum/publish/Events.java create mode 100644 ethereumj-core/src/test/java/org/ethereum/util/RandomGenerator.java diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java index 5e0cd0a6aa..edc31f2f5b 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java @@ -1,22 +1,21 @@ package org.ethereum.publish; +import org.apache.commons.lang3.text.StrBuilder; import org.ethereum.core.EventDispatchThread; import org.ethereum.publish.event.Event; import org.ethereum.publish.event.OneOffEvent; -import org.ethereum.publish.event.SignalEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; -import java.util.function.Consumer; import static java.util.Collections.emptyList; import static java.util.Objects.nonNull; -import static java.util.stream.Collectors.toList; /** * Event publisher that uses pub/sub model to deliver event messages.
      @@ -49,7 +48,6 @@ * * @see Subscription * @see Event - * @see SignalEvent * @see OneOffEvent * * @author Eugene Shevchenko @@ -99,11 +97,16 @@ public Publisher(Executor executor) { * @return current {@link Publisher} instance to support fluent API. */ public Publisher publish(Event event) { - subscriptionsByEvent.getOrDefault(event.getClass(), emptyList()).stream() + List subscriptions = subscriptionsByEvent.getOrDefault(event.getClass(), emptyList()); + subscriptions.stream() .filter(subscription -> subscription.matches(event)) .map(subscription -> new Command(subscription, event)) .forEach(executor::execute); + subscriptions.stream() + .filter(subscription -> subscription.needUnsubscribeAfter(event)) + .forEach(this::unsubscribe); + if (event instanceof OneOffEvent) { subscriptionsByEvent.remove(event.getClass()); } @@ -126,6 +129,7 @@ public , P> Publisher subscribe(Subscription subscripti log.warn("Specified subscription already exists {}.", subscription.getEventType().getSimpleName()); } else { subscriptions.add(subscription); + log.debug("{} added to publisher.", subscription); } return this; } @@ -140,6 +144,7 @@ public Publisher unsubscribe(Subscription subscription) { List subscriptions = subscriptionsByEvent.get(subscription.getEventType()); if (nonNull(subscriptions)) { subscriptions.remove(subscription); + log.debug("{} removed from publisher.", subscription); if (subscriptions.isEmpty()) { subscriptionsByEvent.remove(subscription.getEventType()); } @@ -168,4 +173,30 @@ public int subscribersCount() { .mapToInt(List::size) .sum(); } + + /** + * Gets events set subscribed via current publisher. + * + * @return all events which have subscribers. + */ + public Set> events() { + return subscriptionsByEvent.keySet(); + } + + @Override + public String toString() { + StrBuilder builder = new StrBuilder("Publisher info:\n"); + if (subscriptionsByEvent.isEmpty()) { + builder.append("\tempty.\n"); + } else { + subscriptionsByEvent.forEach((type, subscriptions) -> builder + .append("\t- ") + .append(type.getSimpleName()) + .append(": ") + .append(subscriptions.size()) + .append(" subscription(s);\n")); + } + + return builder.toString(); + } } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java index 720b7c15a8..cfbb5cd98b 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java @@ -4,7 +4,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; @@ -124,4 +123,9 @@ boolean needUnsubscribeAfter(E event) { public static , D> Subscription to(Class eventType, Consumer consumer) { return new Subscription<>(eventType, consumer); } + + @Override + public String toString() { + return eventType.getSimpleName() + " subscription"; + } } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/SignalEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/SignalEvent.java deleted file mode 100644 index d38f62a9a3..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/SignalEvent.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.ethereum.publish.event; - -/** - * Base class for signal events (without any payload). - * - * @author Eugene Shevchenko - */ -public abstract class SignalEvent extends Event { - - public SignalEvent() { - super(null); - } -} diff --git a/ethereumj-core/src/test/java/org/ethereum/publish/EventGenerator.java b/ethereumj-core/src/test/java/org/ethereum/publish/EventGenerator.java new file mode 100644 index 0000000000..0ecd6e357b --- /dev/null +++ b/ethereumj-core/src/test/java/org/ethereum/publish/EventGenerator.java @@ -0,0 +1,34 @@ +package org.ethereum.publish; + +import com.google.common.base.Function; +import org.ethereum.publish.event.Event; +import org.ethereum.util.RandomGenerator; + +import java.util.Random; + +public class EventGenerator extends RandomGenerator { + + public EventGenerator(Random random) { + super(random); + } + + private EventGenerator withGenFunction(Function function) { + return (EventGenerator) addGenFunction(function); + } + + public EventGenerator withIntEvent(int bound) { + return withGenFunction(r -> new Events.IntEvent(r.nextInt(bound))); + } + + public EventGenerator withLongEvent(int bound) { + return withGenFunction(r -> new Events.LongEvent(r.nextInt(bound))); + } + + public EventGenerator withStringEvent(String... strings) { + return withGenFunction(r -> new Events.StringEvent(randomFrom(strings))); + } + + public EventGenerator withOneOffStringEvent(String... strings) { + return withGenFunction(random -> new Events.OneOffStringEvent(randomFrom(strings))); + } +} diff --git a/ethereumj-core/src/test/java/org/ethereum/publish/Events.java b/ethereumj-core/src/test/java/org/ethereum/publish/Events.java new file mode 100644 index 0000000000..74fa482112 --- /dev/null +++ b/ethereumj-core/src/test/java/org/ethereum/publish/Events.java @@ -0,0 +1,31 @@ +package org.ethereum.publish; + +import org.ethereum.publish.event.Event; +import org.ethereum.publish.event.OneOffEvent; + +public class Events { + + static class IntEvent extends Event { + IntEvent(Integer payload) { + super(payload); + } + } + + static class LongEvent extends Event { + LongEvent(long payload) { + super(payload); + } + } + + static class StringEvent extends Event { + StringEvent(String payload) { + super(payload); + } + } + + static class OneOffStringEvent extends StringEvent implements OneOffEvent { + OneOffStringEvent(String payload) { + super(payload); + } + } +} diff --git a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java index df3a68e581..e19e356601 100644 --- a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java @@ -1,50 +1,32 @@ package org.ethereum.publish; import org.ethereum.core.EventDispatchThread; -import org.ethereum.publish.event.Event; -import org.ethereum.publish.event.OneOffEvent; +import org.ethereum.util.RandomGenerator; import org.junit.Test; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; +import java.util.Random; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.IntStream; +import static java.util.Arrays.asList; import static org.ethereum.publish.Subscription.to; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class PublisherTest { - private class IntEvent extends Event { - IntEvent(Integer payload) { - super(payload); - } - } - - private class LongEvent extends Event { - LongEvent(long payload) { - super(payload); - } - } - - private class StringEvent extends Event { - StringEvent(String payload) { - super(payload); - } - } - - private class OneOffStringEvent extends StringEvent implements OneOffEvent { - OneOffStringEvent(String payload) { - super(payload); - } - } - @Test public void testDuplicateSubscription() { - Subscription subscription = Subscription.to(IntEvent.class, System.out::print); + Subscription subscription = Subscription.to(Events.IntEvent.class, System.out::print); int subscribersCount = createPublisher() .subscribe(subscription) @@ -60,9 +42,9 @@ public void testSingleEvent() { final List strings = new ArrayList<>(); int subscribersCount = createPublisher() - .subscribe(to(OneOffStringEvent.class, strings::add)) - .publish(new OneOffStringEvent(payload)) - .subscribersCount(OneOffStringEvent.class); + .subscribe(to(Events.OneOffStringEvent.class, strings::add)) + .publish(new Events.OneOffStringEvent(payload)) + .subscribersCount(Events.OneOffStringEvent.class); assertEquals(0, subscribersCount); assertTrue(strings.contains(payload)); @@ -79,14 +61,14 @@ public void testConditionallySubscription() { int evenSum = IntStream.of(numbers).filter(num -> isEven(num)).sum(); Publisher publisher = createPublisher() - .subscribe(to(LongEvent.class, actualSum::getAndAdd)) - .subscribe(to(IntEvent.class, actualEvenSum::getAndAdd) + .subscribe(to(Events.LongEvent.class, actualSum::getAndAdd)) + .subscribe(to(Events.IntEvent.class, actualEvenSum::getAndAdd) .conditionally(PublisherTest::isEven)); IntStream.of(numbers) .forEach(num -> publisher - .publish(new LongEvent(num)) - .publish(new IntEvent(num))); + .publish(new Events.LongEvent(num)) + .publish(new Events.IntEvent(num))); assertEquals(sum, actualSum.get()); assertEquals(evenSum, actualEvenSum.get()); @@ -101,11 +83,11 @@ public void testUnsubscribeAfter() { int sum = IntStream.of(numbers).sum(); Publisher publisher = createPublisher() - .subscribe(to(IntEvent.class, actualSum::addAndGet) + .subscribe(to(Events.IntEvent.class, actualSum::addAndGet) .unsubscribeAfter(num -> num == limit)); IntStream.rangeClosed(1, limit * 2) - .mapToObj(IntEvent::new) + .mapToObj(Events.IntEvent::new) .forEach(publisher::publish); assertEquals(sum, actualSum.get()); @@ -117,11 +99,11 @@ public void testOneOffSubscription() { final int expected = 5; Publisher publisher = createPublisher() - .subscribe(to(IntEvent.class, actual::set) + .subscribe(to(Events.IntEvent.class, actual::set) .oneOff(num -> num == expected)); IntStream.rangeClosed(1, 10) - .mapToObj(IntEvent::new) + .mapToObj(Events.IntEvent::new) .forEach(publisher::publish); assertEquals(expected, actual.get()); @@ -133,7 +115,7 @@ public void testLifeCycleSubscription() { final int expected = 5; Publisher publisher = createPublisher() - .subscribe(LifeCycleSubscription.to(IntEvent.class, (num, lc) -> { + .subscribe(LifeCycleSubscription.to(Events.IntEvent.class, (num, lc) -> { if (num == expected) { actual.set(num); lc.unsubscribe(); @@ -141,7 +123,7 @@ public void testLifeCycleSubscription() { })); IntStream.rangeClosed(1, 10) - .mapToObj(IntEvent::new) + .mapToObj(Events.IntEvent::new) .forEach(publisher::publish); assertEquals(expected, actual.get()); @@ -155,27 +137,27 @@ public void testPublishing() { AtomicInteger secondIntSum = new AtomicInteger(); List expectedStrings = new ArrayList<>(); - List strings = Arrays.asList("some event", "another event", "incredible event"); + List strings = asList("some event", "another event", "incredible event"); int[] numbers = IntStream.rangeClosed(1, 10).toArray(); int sum = IntStream.of(numbers).sum(); int evenSum = IntStream.of(numbers).filter(num -> isEven(num)).sum(); Publisher publisher = createPublisher() - .subscribe(to(IntEvent.class, firstIntSum::getAndAdd)) - .subscribe(to(IntEvent.class, secondIntSum::getAndAdd)) - .subscribe(to(StringEvent.class, expectedStrings::add)) - .subscribe(to(LongEvent.class, longEvenSum::getAndAdd) + .subscribe(to(Events.IntEvent.class, firstIntSum::getAndAdd)) + .subscribe(to(Events.IntEvent.class, secondIntSum::getAndAdd)) + .subscribe(to(Events.StringEvent.class, expectedStrings::add)) + .subscribe(to(Events.LongEvent.class, longEvenSum::getAndAdd) .conditionally(PublisherTest::isEven)); IntStream.of(numbers) .forEach(num -> publisher - .publish(new IntEvent(num)) - .publish(new LongEvent(num))); + .publish(new Events.IntEvent(num)) + .publish(new Events.LongEvent(num))); strings.stream() .forEach(str -> publisher - .publish(new StringEvent(str))); + .publish(new Events.StringEvent(str))); assertEquals(sum, firstIntSum.get()); assertEquals(sum, secondIntSum.get()); @@ -185,6 +167,108 @@ public void testPublishing() { .count()); } + @Test + public void testHandlingWithException() { + AtomicInteger actual = new AtomicInteger(); + int expected = 5; + + createPublisher() + .subscribe(to(Events.IntEvent.class, num -> { + throw new RuntimeException(); + })) + .subscribe(to(Events.IntEvent.class, num -> actual.set(num))) + .publish(new Events.IntEvent(expected)); + + assertEquals(expected, actual.get()); + } + + @Test + public void testConcurrentAccess() { + BlockingQueue executorQueue = new LinkedBlockingQueue<>(); + ExecutorService executor = new ThreadPoolExecutor(10, 10, 0L, + TimeUnit.MILLISECONDS, executorQueue); + + Random random = new Random(); + final String[] strings1 = {"one", "two", "three", "thousand", "one hundred", "zero"}; + final int limit = 1000; + + EventGenerator eGen = new EventGenerator(random) + .withIntEvent(limit) + .withLongEvent(limit) + .withStringEvent(strings1) + .withOneOffStringEvent(strings1); + + + RandomGenerator sGen = new RandomGenerator(random) + .addGenFunction(r -> to(Events.OneOffStringEvent.class, s -> sleepSilent(r.nextInt(10)))) + .addGenFunction(r -> to(Events.StringEvent.class, s -> sleepSilent(r.nextInt(10))) + .conditionally(s -> s.startsWith("t")) + .unsubscribeAfter(s -> s.startsWith("z"))) + .addGenFunction(r -> to(Events.IntEvent.class, i -> sleepSilent(r.nextInt(10))) + .unsubscribeAfter(i -> i < r.nextInt(limit))) + .addGenFunction(r -> LifeCycleSubscription.to(Events.IntEvent.class, (i, lifeCycle) -> { + sleepSilent(r.nextInt(10)); + if (i < r.nextInt(limit)) { + lifeCycle.unsubscribe(); + } + })) + .addGenFunction(r -> to(Events.LongEvent.class, i -> sleepSilent(r.nextInt(10))) + .oneOff(i -> i < r.nextInt(limit))); + + + try { + Publisher publisher = new Publisher(executor); + // prints publisher state info + executor.execute(() -> { + while (true) { + System.out.println(publisher); + sleepSilent(300); + } + }); + + AtomicBoolean running = new AtomicBoolean(true); + try { + // generates events + executor.execute(() -> { + while (running.get()) { + publisher.publish(eGen.genNext()); + if (executorQueue.size() > limit) { + sleepSilent(100); + } + } + }); + // generates subscriptions + executor.execute(() -> { + while (running.get()) { + publisher.subscribe(sGen.genNext()); + if (publisher.subscribersCount() > limit) { + sleepSilent(100); + } + } + }); + + sleepSilent(5000); + } finally { + running.set(false); + } + + while (!executorQueue.isEmpty()) { + sleepSilent(100); + } + + } finally { + executor.shutdown(); + } + } + + private static void sleepSilent(int millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + private static Publisher createPublisher() { return new Publisher(EventDispatchThread.getDefault()); } diff --git a/ethereumj-core/src/test/java/org/ethereum/util/RandomGenerator.java b/ethereumj-core/src/test/java/org/ethereum/util/RandomGenerator.java new file mode 100644 index 0000000000..d30d7c62e8 --- /dev/null +++ b/ethereumj-core/src/test/java/org/ethereum/util/RandomGenerator.java @@ -0,0 +1,39 @@ +package org.ethereum.util; + +import com.google.common.base.Function; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class RandomGenerator { + + private final Random random; + private final List> genFunctions = new ArrayList<>(); + + + public RandomGenerator(Random random) { + this.random = random; + } + + public RandomGenerator addGenFunction(Function function) { + genFunctions.add(function); + return this; + } + + public E randomFrom(List list) { + return list.get(random.nextInt(list.size())); + } + + public E randomFrom(E[] array) { + return array[random.nextInt(array.length)]; + } + + public T genNext() { + if (genFunctions.isEmpty()) { + throw new IllegalStateException(); + } + + return randomFrom(genFunctions).apply(random); + } +} From e41e31bc2106f8709c4520cbe6b42da945d2d362 Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Wed, 22 Aug 2018 20:40:25 +0300 Subject: [PATCH 16/28] Moves LifeCycle to Subscription. --- .../publish/LifeCycleSubscription.java | 53 ------------------- .../org/ethereum/publish/Subscription.java | 31 +++++++++-- .../org/ethereum/samples/BasicSample.java | 2 +- .../ethereum/samples/PendingStateSample.java | 2 +- .../org/ethereum/publish/PublisherTest.java | 8 +-- 5 files changed, 32 insertions(+), 64 deletions(-) delete mode 100644 ethereumj-core/src/main/java/org/ethereum/publish/LifeCycleSubscription.java diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/LifeCycleSubscription.java b/ethereumj-core/src/main/java/org/ethereum/publish/LifeCycleSubscription.java deleted file mode 100644 index cfa525f060..0000000000 --- a/ethereumj-core/src/main/java/org/ethereum/publish/LifeCycleSubscription.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.ethereum.publish; - -import org.ethereum.publish.event.Event; - -import java.util.function.BiConsumer; - -/** - * Abstraction that holds together event type, event processor (a.k.a consumer) and optional conditions that resolves - * event processing and auto-unsubscribe. - * - * @author Eugene Shevchenko - */ -public class LifeCycleSubscription, D> extends Subscription { - - public static class LifeCycle { - private final LifeCycleSubscription subscription; - - private LifeCycle(LifeCycleSubscription subscription) { - this.subscription = subscription; - } - - public void unsubscribe() { - subscription.unsubscribeAfter(data -> true); - } - } - - private final BiConsumer biConsumer; - private final LifeCycle lifeCycle; - - LifeCycleSubscription(Class eventType, BiConsumer biConsumer) { - super(eventType, null); - this.biConsumer = biConsumer; - this.lifeCycle = new LifeCycle(this); - } - - @Override - protected void handlePayload(D payload) { - biConsumer.accept(payload, lifeCycle); - } - - /** - * Short static alias for {@link LifeCycleSubscription} constructor. - * - * @param eventType event type to process; - * @param biConsumer callback that consumes event's payload; - * @param event type that should be process; - * @param payload's type of specified event type; - * @return new {@link LifeCycleSubscription} instance. - */ - public static , D> LifeCycleSubscription to(Class eventType, BiConsumer biConsumer) { - return new LifeCycleSubscription<>(eventType, biConsumer); - } -} diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java index cfbb5cd98b..b516ef5194 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java @@ -4,6 +4,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; @@ -20,14 +21,30 @@ public class Subscription, D> { private final static Logger log = LoggerFactory.getLogger("event"); + public static class LifeCycle { + private final Subscription subscription; + + private LifeCycle(Subscription subscription) { + this.subscription = subscription; + } + + public void unsubscribe() { + subscription.unsubscribeAfter(data -> true); + } + } + + private final Class eventType; - private final Consumer consumer; + private final BiConsumer biConsumer; + private final LifeCycle lifeCycle; + private Function handleCondition; private Function unsubscribeCondition; - Subscription(Class eventType, Consumer consumer) { + Subscription(Class eventType, BiConsumer biConsumer) { this.eventType = eventType; - this.consumer = consumer; + this.lifeCycle = new LifeCycle(this); + this.biConsumer = biConsumer; } /** @@ -98,7 +115,7 @@ void handle(E event) { } protected void handlePayload(D payload) { - consumer.accept(payload); + biConsumer.accept(payload, lifeCycle); } /** @@ -111,6 +128,10 @@ boolean needUnsubscribeAfter(E event) { return nonNull(unsubscribeCondition) && unsubscribeCondition.apply(event.getPayload()); } + public static , D> Subscription to(Class eventType, BiConsumer biConsumer) { + return new Subscription<>(eventType, biConsumer); + } + /** * Short static alias for {@link Subscription} constructor. * @@ -121,7 +142,7 @@ boolean needUnsubscribeAfter(E event) { * @return new {@link Subscription} instance. */ public static , D> Subscription to(Class eventType, Consumer consumer) { - return new Subscription<>(eventType, consumer); + return new Subscription<>(eventType, (payload, lifeCycle) -> consumer.accept(payload)); } @Override diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java index 53f232c655..fac2fb158a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java @@ -137,7 +137,7 @@ private void springInit() { // adding the main EthereumJ callback to be notified on different kind of events this.ethereum .subscribe(to(SyncDone.class, syncState -> synced = true)) - .subscribe(to(NodeDiscovered.class, nodesDiscovered::add) + .subscribe(to(NodeDiscovered.class, node -> nodesDiscovered.add(node)) .conditionally(node -> nodesDiscovered.size() < 1000)) .subscribe(to(EthStatusUpdated.class, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage()))) .subscribe(to(PeerAddedToSyncPool.class, peer -> syncPeers.add(peer.getNode()))) diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java index 9ca86166c8..742e9efcff 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java @@ -69,7 +69,7 @@ public void onSyncDone() { .subscribe(to(PendingTransactionUpdated.class, data -> onPendingTransactionReceived(data.getReceipt().getTransaction())) .conditionally(data -> data.getState() == NEW_PENDING)) // when block arrives look for our included transactions - .subscribe(to(BlockAdded.class, this::onBlock)); + .subscribe(to(BlockAdded.class, d -> onBlock(d))); new Thread(() -> { try { diff --git a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java index e19e356601..971f1fbc88 100644 --- a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java @@ -42,7 +42,7 @@ public void testSingleEvent() { final List strings = new ArrayList<>(); int subscribersCount = createPublisher() - .subscribe(to(Events.OneOffStringEvent.class, strings::add)) + .subscribe(to(Events.OneOffStringEvent.class, s -> strings.add(s))) .publish(new Events.OneOffStringEvent(payload)) .subscribersCount(Events.OneOffStringEvent.class); @@ -115,7 +115,7 @@ public void testLifeCycleSubscription() { final int expected = 5; Publisher publisher = createPublisher() - .subscribe(LifeCycleSubscription.to(Events.IntEvent.class, (num, lc) -> { + .subscribe(to(Events.IntEvent.class, (num, lc) -> { if (num == expected) { actual.set(num); lc.unsubscribe(); @@ -146,7 +146,7 @@ public void testPublishing() { Publisher publisher = createPublisher() .subscribe(to(Events.IntEvent.class, firstIntSum::getAndAdd)) .subscribe(to(Events.IntEvent.class, secondIntSum::getAndAdd)) - .subscribe(to(Events.StringEvent.class, expectedStrings::add)) + .subscribe(to(Events.StringEvent.class, s -> expectedStrings.add(s))) .subscribe(to(Events.LongEvent.class, longEvenSum::getAndAdd) .conditionally(PublisherTest::isEven)); @@ -206,7 +206,7 @@ public void testConcurrentAccess() { .unsubscribeAfter(s -> s.startsWith("z"))) .addGenFunction(r -> to(Events.IntEvent.class, i -> sleepSilent(r.nextInt(10))) .unsubscribeAfter(i -> i < r.nextInt(limit))) - .addGenFunction(r -> LifeCycleSubscription.to(Events.IntEvent.class, (i, lifeCycle) -> { + .addGenFunction(r -> to(Events.IntEvent.class, (i, lifeCycle) -> { sleepSilent(r.nextInt(10)); if (i < r.nextInt(limit)) { lifeCycle.unsubscribe(); From ab4754db0bec9d56c6e69b9f75c4f164918c60be Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Wed, 22 Aug 2018 20:49:58 +0300 Subject: [PATCH 17/28] Replaces EthereumListener.STUB anonymous class with EthereumListenerAdapter instance. --- .../org/ethereum/core/PendingStateImpl.java | 2 +- .../ethereum/core/TransactionExecutor.java | 2 +- .../org/ethereum/facade/EthereumImpl.java | 2 +- .../ethereum/listener/EthereumListener.java | 82 +------------------ .../ethereum/longrun/SyncWithLoadTest.java | 2 +- 5 files changed, 5 insertions(+), 85 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java b/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java index 2ee87b20ef..78e5c9127a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/PendingStateImpl.java @@ -408,7 +408,7 @@ private TransactionReceipt executeTx(Transaction tx) { TransactionExecutor executor = new TransactionExecutor( tx, best.getCoinbase(), getRepository(), - blockStore, programInvokeFactory, createFakePendingBlock(), EthereumListener.STUB, 0) + blockStore, programInvokeFactory, createFakePendingBlock(), EthereumListener.EMPTY, 0) .withCommonConfig(commonConfig); executor.init(); diff --git a/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java b/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java index fd0ca51974..0a3ce696de 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/TransactionExecutor.java @@ -93,7 +93,7 @@ public class TransactionExecutor { public TransactionExecutor(Transaction tx, byte[] coinbase, Repository track, BlockStore blockStore, ProgramInvokeFactory programInvokeFactory, Block currentBlock) { - this(tx, coinbase, track, blockStore, programInvokeFactory, currentBlock, EthereumListener.STUB, 0); + this(tx, coinbase, track, blockStore, programInvokeFactory, currentBlock, EthereumListener.EMPTY, 0); } public TransactionExecutor(Transaction tx, byte[] coinbase, Repository track, BlockStore blockStore, diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index 19a7794dbf..d929107fbe 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -299,7 +299,7 @@ private org.ethereum.core.TransactionExecutor callConstantImpl(Transaction tx, B try { org.ethereum.core.TransactionExecutor executor = new org.ethereum.core.TransactionExecutor (tx, block.getCoinbase(), repository, worldManager.getBlockStore(), - programInvokeFactory, block, EthereumListener.STUB, 0) + programInvokeFactory, block, EthereumListener.EMPTY, 0) .withCommonConfig(commonConfig) .setLocalCall(true); diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java b/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java index 24f4a4fec9..166cc80c43 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/EthereumListener.java @@ -161,85 +161,5 @@ default void onBlock(BlockSummary blockSummary, boolean best) { void onPeerAddedToSyncPool(Channel peer); - EthereumListener STUB = new EthereumListener() { - @Override - public void trace(String output) { - - } - - @Override - public void onNodeDiscovered(Node node) { - - } - - @Override - public void onHandShakePeer(Channel channel, HelloMessage helloMessage) { - - } - - @Override - public void onEthStatusUpdated(Channel channel, StatusMessage status) { - - } - - @Override - public void onRecvMessage(Channel channel, Message message) { - - } - - @Override - public void onSendMessage(Channel channel, Message message) { - - } - - @Override - public void onBlock(BlockSummary blockSummary) { - - } - - @Override - public void onPeerDisconnect(String host, long port) { - - } - - @Override - public void onPendingTransactionsReceived(List transactions) { - - } - - @Override - public void onPendingStateChanged(PendingState pendingState) { - - } - - @Override - public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionState state, Block block) { - - } - - @Override - public void onSyncDone(SyncState state) { - - } - - @Override - public void onNoConnections() { - - } - - @Override - public void onVMTraceCreated(String transactionHash, String trace) { - - } - - @Override - public void onTransactionExecuted(TransactionExecutionSummary summary) { - - } - - @Override - public void onPeerAddedToSyncPool(Channel peer) { - - } - }; + EthereumListener EMPTY = new EthereumListenerAdapter(); } diff --git a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java index b96066506a..111d007538 100644 --- a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java @@ -196,7 +196,7 @@ private void onPendingTransactionUpdated(PendingTransactionUpdated.Data data) { try { TransactionExecutor executor = new TransactionExecutor (tx, block.getCoinbase(), repository, ethereum.getBlockchain().getBlockStore(), - programInvokeFactory, block, EthereumListener.STUB, 0) + programInvokeFactory, block, EthereumListener.EMPTY, 0) .withCommonConfig(commonConfig) .setLocalCall(true); From b2143020df6cb92933012bcc90572fc330522860 Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Wed, 22 Aug 2018 21:58:46 +0300 Subject: [PATCH 18/28] Adds more convenient subscribing methods to Ethereum interface. --- .../src/main/java/org/ethereum/facade/Ethereum.java | 12 ++++++++++++ .../main/java/org/ethereum/facade/EthereumImpl.java | 13 +++++++++++++ 2 files changed, 25 insertions(+) diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java index 257b9502d9..7d66a774b9 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java @@ -37,6 +37,8 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; +import java.util.function.BiConsumer; +import java.util.function.Consumer; /** * @author Roman Mandeleil @@ -77,6 +79,16 @@ public interface Ethereum { */ Publisher subscribe(Subscription subscription); + /** + * More convenient version of {@link #subscribe(Subscription)} + */ + Publisher subscribe(Class> type, Consumer handler); + + /** + * More convenient version of {@link #subscribe(Subscription)} + */ + Publisher subscribe(Class> type, BiConsumer handler); + PeerClient getDefaultPeer(); boolean isConnected(); diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index d929107fbe..ede7cd3e7d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -45,6 +45,7 @@ import org.ethereum.publish.Publisher; import org.ethereum.publish.Subscription; import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.Event; import org.ethereum.sync.SyncManager; import org.ethereum.util.ByteUtil; import org.ethereum.vm.program.ProgramResult; @@ -68,6 +69,8 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import java.util.function.BiConsumer; +import java.util.function.Consumer; import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.ByteUtil.toHexString; @@ -182,6 +185,16 @@ public Publisher subscribe(Subscription subscription) { return worldManager.getPublisher().subscribe(subscription); } + @Override + public Publisher subscribe(Class> type, Consumer handler) { + return subscribe(to(type, handler)); + } + + @Override + public Publisher subscribe(Class> type, BiConsumer handler) { + return subscribe(to(type, handler)); + } + @Override public void close() { logger.info("### Shutdown initiated ### "); From 003ae1260d5bad2a8386b92eb53c43da0a46aaae Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Wed, 22 Aug 2018 22:02:20 +0300 Subject: [PATCH 19/28] Reverts RecommendedGasPriceTracker --- .../java/org/ethereum/listener/RecommendedGasPriceTracker.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/RecommendedGasPriceTracker.java b/ethereumj-core/src/main/java/org/ethereum/listener/RecommendedGasPriceTracker.java index 5fee184429..9f61f5ae3a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/RecommendedGasPriceTracker.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/RecommendedGasPriceTracker.java @@ -38,7 +38,7 @@ * (if {@link #getPercentileShare()} is not overridden) of the latest transactions were * executed at this or lower price. */ -public class RecommendedGasPriceTracker { +public class RecommendedGasPriceTracker extends EthereumListenerAdapter { private static final Long DEFAULT_PRICE = null; private static final int MIN_BLOCKS = 128; @@ -51,6 +51,7 @@ public class RecommendedGasPriceTracker { private int idx = 0; private Long recommendedGasPrice = getDefaultPrice(); + @Override public void onBlock(BlockSummary blockSummary) { onBlock(blockSummary.getBlock()); } From 7288636217a5cea7849fadf2d369065a8b8bc1b9 Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Wed, 22 Aug 2018 22:05:44 +0300 Subject: [PATCH 20/28] Adds copyright headers. --- ...kwardCompatibilityEthereumListenerProxy.java | 17 +++++++++++++++++ .../java/org/ethereum/publish/Publisher.java | 17 +++++++++++++++++ .../java/org/ethereum/publish/Subscription.java | 17 +++++++++++++++++ .../org/ethereum/publish/event/BlockAdded.java | 17 +++++++++++++++++ .../java/org/ethereum/publish/event/Event.java | 17 +++++++++++++++++ .../java/org/ethereum/publish/event/Events.java | 17 +++++++++++++++++ .../ethereum/publish/event/NodeDiscovered.java | 17 +++++++++++++++++ .../org/ethereum/publish/event/OneOffEvent.java | 17 +++++++++++++++++ .../publish/event/PeerAddedToSyncPool.java | 17 +++++++++++++++++ .../publish/event/PeerDisconnected.java | 17 +++++++++++++++++ .../publish/event/PendingStateChanged.java | 17 +++++++++++++++++ .../event/PendingTransactionUpdated.java | 17 +++++++++++++++++ .../org/ethereum/publish/event/SyncDone.java | 17 +++++++++++++++++ .../publish/event/TransactionExecuted.java | 17 +++++++++++++++++ .../ethereum/publish/event/VmTraceCreated.java | 17 +++++++++++++++++ .../event/message/AbstractMessageEvent.java | 17 +++++++++++++++++ .../publish/event/message/EthStatusUpdated.java | 17 +++++++++++++++++ .../publish/event/message/MessageReceived.java | 17 +++++++++++++++++ .../publish/event/message/MessageSent.java | 17 +++++++++++++++++ .../publish/event/message/PeerHandshaked.java | 17 +++++++++++++++++ .../org/ethereum/publish/EventGenerator.java | 17 +++++++++++++++++ .../test/java/org/ethereum/publish/Events.java | 17 +++++++++++++++++ .../org/ethereum/publish/PublisherTest.java | 17 +++++++++++++++++ .../java/org/ethereum/util/RandomGenerator.java | 17 +++++++++++++++++ 24 files changed, 408 insertions(+) diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java b/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java index 6096bc9a01..0830d8777a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.listener; import org.ethereum.core.*; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java index edc31f2f5b..dad55527ea 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish; import org.apache.commons.lang3.text.StrBuilder; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java index b516ef5194..90787f7b3d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish; import org.ethereum.publish.event.Event; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAdded.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAdded.java index abb8d7d077..2a8dd98dbb 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAdded.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/BlockAdded.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event; import org.ethereum.core.BlockSummary; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/Event.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/Event.java index 0e914c3640..0b708c9f80 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/Event.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/Event.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event; /** diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java index 7fd55b34a2..9ad2666a30 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event; import org.ethereum.core.*; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/NodeDiscovered.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/NodeDiscovered.java index 9897904580..df1e32797c 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/NodeDiscovered.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/NodeDiscovered.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event; import org.ethereum.net.rlpx.Node; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/OneOffEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/OneOffEvent.java index 250bf5f56b..98e04039eb 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/OneOffEvent.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/OneOffEvent.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event; /** diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPool.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPool.java index b0ba280e6c..7aef12ce2a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPool.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerAddedToSyncPool.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event; import org.ethereum.net.server.Channel; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerDisconnected.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerDisconnected.java index 36436785e4..cfd4d73ec3 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerDisconnected.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PeerDisconnected.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event; public class PeerDisconnected extends Event { diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingStateChanged.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingStateChanged.java index c8e713305e..d70620b40e 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingStateChanged.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingStateChanged.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event; import org.ethereum.core.PendingState; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdated.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdated.java index 6bb799a18b..d4abdca7a1 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdated.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdated.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event; import org.ethereum.core.Block; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java index 4d909a1513..b0198f6c03 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event; import org.ethereum.listener.EthereumListener; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecuted.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecuted.java index d9f2e13494..ee56132907 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecuted.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/TransactionExecuted.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event; import org.ethereum.core.TransactionExecutionSummary; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/VmTraceCreated.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/VmTraceCreated.java index e8b7094321..8eaad440cf 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/VmTraceCreated.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/VmTraceCreated.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event; public class VmTraceCreated extends Event { diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/AbstractMessageEvent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/AbstractMessageEvent.java index 64869851ba..b05a71ddce 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/AbstractMessageEvent.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/AbstractMessageEvent.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event.message; import org.ethereum.net.message.Message; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/EthStatusUpdated.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/EthStatusUpdated.java index 04964fa3e9..cec1155d06 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/EthStatusUpdated.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/EthStatusUpdated.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event.message; import org.ethereum.net.eth.message.StatusMessage; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/MessageReceived.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/MessageReceived.java index e0fab5eb51..72eb6e56d3 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/MessageReceived.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/MessageReceived.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event.message; import org.ethereum.net.message.Message; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/MessageSent.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/MessageSent.java index 3c7ec54d15..137c6ba85a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/MessageSent.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/MessageSent.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event.message; import org.ethereum.net.message.Message; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/PeerHandshaked.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/PeerHandshaked.java index 308d967a55..8f01d49281 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/message/PeerHandshaked.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/message/PeerHandshaked.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish.event.message; import org.ethereum.net.p2p.HelloMessage; diff --git a/ethereumj-core/src/test/java/org/ethereum/publish/EventGenerator.java b/ethereumj-core/src/test/java/org/ethereum/publish/EventGenerator.java index 0ecd6e357b..0ca909ff5a 100644 --- a/ethereumj-core/src/test/java/org/ethereum/publish/EventGenerator.java +++ b/ethereumj-core/src/test/java/org/ethereum/publish/EventGenerator.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish; import com.google.common.base.Function; diff --git a/ethereumj-core/src/test/java/org/ethereum/publish/Events.java b/ethereumj-core/src/test/java/org/ethereum/publish/Events.java index 74fa482112..d2c684b3ab 100644 --- a/ethereumj-core/src/test/java/org/ethereum/publish/Events.java +++ b/ethereumj-core/src/test/java/org/ethereum/publish/Events.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish; import org.ethereum.publish.event.Event; diff --git a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java index 971f1fbc88..d66f64cd81 100644 --- a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.publish; import org.ethereum.core.EventDispatchThread; diff --git a/ethereumj-core/src/test/java/org/ethereum/util/RandomGenerator.java b/ethereumj-core/src/test/java/org/ethereum/util/RandomGenerator.java index d30d7c62e8..23d44527dc 100644 --- a/ethereumj-core/src/test/java/org/ethereum/util/RandomGenerator.java +++ b/ethereumj-core/src/test/java/org/ethereum/util/RandomGenerator.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.util; import com.google.common.base.Function; From 698b59a267f560a1853800239410cb67bb64c3e0 Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Thu, 6 Sep 2018 14:08:46 +0300 Subject: [PATCH 21/28] Clones deprecated EthereumListener's state enums for Publisher events. --- .../java/org/ethereum/db/DbFlushManager.java | 12 +++-- ...ardCompatibilityEthereumListenerProxy.java | 20 ++++++-- .../org/ethereum/publish/event/Events.java | 11 +++-- .../event/PendingTransactionUpdated.java | 49 +++++++++++++++++-- .../org/ethereum/publish/event/SyncDone.java | 29 +++++++++-- .../ethereum/samples/PendingStateSample.java | 2 +- .../org/ethereum/samples/TransactionBomb.java | 3 +- .../org/ethereum/core/PendingStateTest.java | 41 +++++++++------- .../java/org/ethereum/longrun/BasicNode.java | 10 ++-- .../ethereum/longrun/SyncWithLoadTest.java | 10 +++- .../java/org/ethereum/mine/MinerTest.java | 2 +- .../ethereum/validator/EthashRuleTest.java | 11 ++--- 12 files changed, 146 insertions(+), 54 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java b/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java index 18d622e9ef..542b7f79c4 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java @@ -24,7 +24,6 @@ import org.ethereum.datasource.AsyncFlushable; import org.ethereum.datasource.DbSource; import org.ethereum.datasource.Source; -import org.ethereum.listener.EthereumListener; import org.ethereum.publish.Publisher; import org.ethereum.publish.event.SyncDone; import org.slf4j.Logger; @@ -33,9 +32,16 @@ import java.util.List; import java.util.Set; -import java.util.concurrent.*; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.SyncDone.State.COMPLETE; /** * Created by Anton Nashatyrev on 01.12.2016. @@ -76,7 +82,7 @@ public void setPublisher(Publisher publisher) { if (!flushAfterSyncDone) return; publisher.subscribe(to(SyncDone.class, state -> { - if (state == EthereumListener.SyncState.COMPLETE) { + if (state == COMPLETE) { logger.info("DbFlushManager: long sync done, flushing each block now"); syncDone = true; } diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java b/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java index 0830d8777a..01079186d8 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java @@ -17,7 +17,13 @@ */ package org.ethereum.listener; -import org.ethereum.core.*; +import org.ethereum.core.Block; +import org.ethereum.core.BlockSummary; +import org.ethereum.core.EventDispatchThread; +import org.ethereum.core.PendingState; +import org.ethereum.core.Transaction; +import org.ethereum.core.TransactionExecutionSummary; +import org.ethereum.core.TransactionReceipt; import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.message.Message; import org.ethereum.net.p2p.HelloMessage; @@ -25,6 +31,8 @@ import org.ethereum.net.server.Channel; import org.ethereum.publish.Publisher; import org.ethereum.publish.event.Events; +import org.ethereum.publish.event.PendingTransactionUpdated; +import org.ethereum.publish.event.SyncDone; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; @@ -131,13 +139,19 @@ public void onPendingStateChanged(PendingState pendingState) { @Override public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionState state, Block block) { compositeListener.onPendingTransactionUpdate(txReceipt, state, block); - publisher.publish(Events.onPendingTransactionUpdated(block, txReceipt, state)); + PendingTransactionUpdated.State translatedState = translate(state, PendingTransactionUpdated.State.class); + publisher.publish(Events.onPendingTransactionUpdated(block, txReceipt, translatedState)); } @Override public void onSyncDone(SyncState state) { compositeListener.onSyncDone(state); - publisher.publish(Events.onSyncDone(state)); + SyncDone.State translatedState = translate(state, SyncDone.State.class); + publisher.publish(Events.onSyncDone(translatedState)); + } + + private static , T extends Enum> T translate(S source, Class targetType) { + return Enum.valueOf(targetType, source.name()); } @Override diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java index 9ad2666a30..d77b265dba 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java @@ -17,8 +17,11 @@ */ package org.ethereum.publish.event; -import org.ethereum.core.*; -import org.ethereum.listener.EthereumListener; +import org.ethereum.core.Block; +import org.ethereum.core.BlockSummary; +import org.ethereum.core.PendingState; +import org.ethereum.core.TransactionExecutionSummary; +import org.ethereum.core.TransactionReceipt; import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.message.Message; import org.ethereum.net.p2p.HelloMessage; @@ -74,11 +77,11 @@ public static Event onPendingStateChanged(PendingState state) { return new PendingStateChanged(state); } - public static Event onPendingTransactionUpdated(Block block, TransactionReceipt receipt, EthereumListener.PendingTransactionState state) { + public static Event onPendingTransactionUpdated(Block block, TransactionReceipt receipt, PendingTransactionUpdated.State state) { return new PendingTransactionUpdated(block, receipt, state); } - public static Event onSyncDone(EthereumListener.SyncState state) { + public static Event onSyncDone(SyncDone.State state) { return new SyncDone(state); } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdated.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdated.java index d4abdca7a1..8ab1f01221 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdated.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdated.java @@ -19,7 +19,6 @@ import org.ethereum.core.Block; import org.ethereum.core.TransactionReceipt; -import org.ethereum.listener.EthereumListener; /** * Emits when PendingTransaction arrives, executed or dropped and included to a block. @@ -28,12 +27,52 @@ */ public class PendingTransactionUpdated extends Event { + public enum State { + /** + * Transaction may be dropped due to: + * - Invalid transaction (invalid nonce, low gas price, insufficient account funds, + * invalid signature) + * - Timeout (when pending transaction is not included to any block for + * last [transaction.outdated.threshold] blocks + * This is the final state + */ + DROPPED, + + /** + * The same as PENDING when transaction is just arrived + * Next state can be either PENDING or INCLUDED + */ + NEW_PENDING, + + /** + * State when transaction is not included to any blocks (on the main chain), and + * was executed on the last best block. The repository state is reflected in the PendingState + * Next state can be either INCLUDED, DROPPED (due to timeout) + * or again PENDING when a new block (without this transaction) arrives + */ + PENDING, + + /** + * State when the transaction is included to a block. + * This could be the final state, however next state could also be + * PENDING: when a fork became the main chain but doesn't include this tx + * INCLUDED: when a fork became the main chain and tx is included into another + * block from the new main chain + * DROPPED: If switched to a new (long enough) main chain without this Tx + */ + INCLUDED; + + public boolean isPending() { + return this == NEW_PENDING || this == PENDING; + } + } + /** * Event DTO */ public static class Data { private final TransactionReceipt receipt; - private final EthereumListener.PendingTransactionState state; + private final State state; private final Block block; /** @@ -42,7 +81,7 @@ public static class Data { * @param block The block which the current pending state is based on (for PENDING tx state) * or the block which tx was included to (for INCLUDED state) */ - public Data(Block block, TransactionReceipt receipt, EthereumListener.PendingTransactionState state) { + public Data(Block block, TransactionReceipt receipt, State state) { this.receipt = receipt; this.state = state; this.block = block; @@ -52,7 +91,7 @@ public TransactionReceipt getReceipt() { return receipt; } - public EthereumListener.PendingTransactionState getState() { + public State getState() { return state; } @@ -61,7 +100,7 @@ public Block getBlock() { } } - public PendingTransactionUpdated(Block block, TransactionReceipt receipt, EthereumListener.PendingTransactionState state) { + public PendingTransactionUpdated(Block block, TransactionReceipt receipt, State state) { super(new Data(block, receipt, state)); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java index b0198f6c03..2d9bebfbac 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java @@ -17,11 +17,34 @@ */ package org.ethereum.publish.event; -import org.ethereum.listener.EthereumListener; +public class SyncDone extends Event implements OneOffEvent { -public class SyncDone extends Event implements OneOffEvent { + public enum State { + /** + * When doing fast sync UNSECURE sync means that the full state is downloaded, + * chain is on the latest block, and blockchain operations may be executed + * (such as state querying, transaction submission) + * but the state isn't yet confirmed with the whole block chain and can't be + * trusted. + * At this stage historical blocks and receipts are unavailable yet + */ + UNSECURE, + /** + * When doing fast sync SECURE sync means that the full state is downloaded, + * chain is on the latest block, and blockchain operations may be executed + * (such as state querying, transaction submission) + * The state is now confirmed by the full chain (all block headers are + * downloaded and verified) and can be trusted + * At this stage historical blocks and receipts are unavailable yet + */ + SECURE, + /** + * Sync is fully complete. All blocks and receipts are downloaded. + */ + COMPLETE + } - public SyncDone(EthereumListener.SyncState payload) { + public SyncDone(State payload) { super(payload); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java index 742e9efcff..a5e830e912 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java @@ -30,7 +30,7 @@ import java.math.BigInteger; import java.util.*; -import static org.ethereum.listener.EthereumListener.PendingTransactionState.NEW_PENDING; +import static org.ethereum.publish.event.PendingTransactionUpdated.State.NEW_PENDING; import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.ByteUtil.toHexString; diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java b/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java index 0b737db645..f8ecf5f2b9 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java @@ -20,7 +20,6 @@ import org.ethereum.core.Transaction; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListener; import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.SyncDone; import org.spongycastle.util.encoders.Hex; @@ -50,7 +49,7 @@ public static void main(String[] args) { } - public void onSyncDone(EthereumListener.SyncState state) { + public void onSyncDone(SyncDone.State state) { // We will send transactions only // after we have the full chain syncs // - in order to prevent old nonce usage diff --git a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java index 9ee8eb3e24..d55f1865bd 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java @@ -44,7 +44,10 @@ import java.util.concurrent.TimeUnit; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.ethereum.listener.EthereumListener.PendingTransactionState.*; +import static org.ethereum.publish.event.PendingTransactionUpdated.State.DROPPED; +import static org.ethereum.publish.event.PendingTransactionUpdated.State.INCLUDED; +import static org.ethereum.publish.event.PendingTransactionUpdated.State.NEW_PENDING; +import static org.ethereum.publish.event.PendingTransactionUpdated.State.PENDING; import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.blockchain.EtherUtil.Unit.ETHER; import static org.ethereum.util.blockchain.EtherUtil.convert; @@ -70,7 +73,7 @@ static class PendingListener { public BlockingQueue onPendingStateChanged = new LinkedBlockingQueue<>(); // public BlockingQueue> onPendingTransactionUpdate = new LinkedBlockingQueue<>(); - Map>> + Map>> onPendingTransactionUpdate = new HashMap<>(); public void onBlock(BlockAdded.Data data) { @@ -90,14 +93,14 @@ public void onPendingTransactionUpdate(PendingTransactionUpdated.Data data) { } - public void onPendingTransactionUpdate(TransactionReceipt txReceipt, EthereumListener.PendingTransactionState state, Block block) { + public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionUpdated.State state, Block block) { System.out.println("PendingStateTest.onPendingTransactionUpdate:" + "txReceipt.err = [" + txReceipt.getError() + "], state = [" + state + "], block: " + block.getShortDescr()); getQueueFor(txReceipt.getTransaction()).add(Triple.of(txReceipt, state, block)); } - public synchronized BlockingQueue> getQueueFor(Transaction tx) { + public synchronized BlockingQueue> getQueueFor(Transaction tx) { ByteArrayWrapper hashW = new ByteArrayWrapper(tx.getHash()); - BlockingQueue> queue = onPendingTransactionUpdate.get(hashW); + BlockingQueue> queue = onPendingTransactionUpdate.get(hashW); if (queue == null) { queue = new LinkedBlockingQueue<>(); onPendingTransactionUpdate.put(hashW, queue); @@ -105,11 +108,11 @@ public synchronized BlockingQueue pollTxUpdate(Transaction tx) throws InterruptedException { + public Triple pollTxUpdate(Transaction tx) throws InterruptedException { return getQueueFor(tx).poll(5, SECONDS); } } @@ -122,7 +125,7 @@ public void testSimple() throws InterruptedException { .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); - Triple txUpd; + Triple txUpd; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -179,7 +182,7 @@ public void testSimple() throws InterruptedException { for (int i = 0; i < SystemProperties.getDefault().txOutdatedThreshold() + 1; i++) { bc.createBlock(); txUpd = l.pollTxUpdate(tx3); - if (txUpd.getMiddle() != PENDING) break; + if (txUpd.getMiddle() != PendingTransactionUpdated.State.PENDING) break; } // tx3 dropped due to timeout @@ -266,7 +269,7 @@ public void testRebranch2() throws InterruptedException { .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); - Triple txUpd = null; + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -356,7 +359,7 @@ public void testRebranch3() throws InterruptedException { .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); - Triple txUpd = null; + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -408,7 +411,7 @@ public void testOldBlockIncluded() throws InterruptedException { .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); - Triple txUpd = null; + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -446,7 +449,7 @@ public void testBlockOnlyIncluded() throws InterruptedException { .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); - Triple txUpd = null; + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -475,7 +478,7 @@ public void testTrackTx1() throws InterruptedException { .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); - Triple txUpd = null; + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -529,7 +532,7 @@ public void testPrevBlock() throws InterruptedException { .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); - Triple txUpd; + Triple txUpd; contract.callFunction("getPrevBlockHash"); bc.generatePendingTransactions(); @@ -546,7 +549,7 @@ public void testTrackTx2() throws InterruptedException { .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); - Triple txUpd = null; + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -608,8 +611,8 @@ public void testRejected1() throws InterruptedException { for (int i = 0; i < 16; i++) { bc.createBlock(); - EthereumListener.PendingTransactionState state = l.pollTxUpdateState(tx1); - if (state == EthereumListener.PendingTransactionState.DROPPED) { + PendingTransactionUpdated.State state = l.pollTxUpdateState(tx1); + if (state == PendingTransactionUpdated.State.DROPPED) { break; } if (i == 15) { @@ -669,7 +672,7 @@ public void testInvalidTransaction() throws InterruptedException { final CountDownLatch txHandle = new CountDownLatch(1); PendingListener l = new PendingListener() { @Override - public void onPendingTransactionUpdate(TransactionReceipt txReceipt, EthereumListener.PendingTransactionState state, Block block) { + public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionUpdated.State state, Block block) { assert !txReceipt.isSuccessful(); assert txReceipt.getError().toLowerCase().contains("invalid"); assert txReceipt.getError().toLowerCase().contains("receive address"); diff --git a/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java b/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java index 6452a576cf..53da13c3dc 100644 --- a/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java +++ b/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java @@ -23,7 +23,6 @@ import org.ethereum.db.DbFlushManager; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.EthereumListener; import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.rlpx.Node; import org.ethereum.net.server.Channel; @@ -45,6 +44,7 @@ import static java.lang.Thread.sleep; import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.SyncDone.State.COMPLETE; /** * BasicNode of ethereum instance @@ -162,7 +162,7 @@ public void onSyncDone() throws Exception { logger.info("Monitoring new blocks in real-time..."); } - public void onSyncDoneImpl(EthereumListener.SyncState state) { + public void onSyncDoneImpl(SyncDone.State state) { logger.info("onSyncDone: " + state); } @@ -171,15 +171,15 @@ public void onSyncDoneImpl(EthereumListener.SyncState state) { protected Block bestBlock = null; - EthereumListener.SyncState syncState = null; + SyncDone.State syncState = null; boolean syncComplete = false; /** * The main EthereumJ callback. */ - public void onSyncDone(EthereumListener.SyncState state) { + public void onSyncDone(SyncDone.State state) { syncState = state; - if (state.equals(EthereumListener.SyncState.COMPLETE)) syncComplete = true; + if (state == COMPLETE) syncComplete = true; onSyncDoneImpl(state); } diff --git a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java index 111d007538..3664447d17 100644 --- a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java @@ -21,7 +21,13 @@ import org.apache.commons.lang3.mutable.MutableObject; import org.ethereum.config.CommonConfig; import org.ethereum.config.SystemProperties; -import org.ethereum.core.*; +import org.ethereum.core.AccountState; +import org.ethereum.core.Block; +import org.ethereum.core.BlockSummary; +import org.ethereum.core.Repository; +import org.ethereum.core.Transaction; +import org.ethereum.core.TransactionExecutor; +import org.ethereum.core.TransactionReceipt; import org.ethereum.db.ContractDetails; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; @@ -48,8 +54,8 @@ import java.util.concurrent.atomic.AtomicLong; import static java.lang.Thread.sleep; -import static org.ethereum.listener.EthereumListener.PendingTransactionState.NEW_PENDING; import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.PendingTransactionUpdated.State.NEW_PENDING; /** * Regular sync with load diff --git a/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java b/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java index 76a89d1e07..5ee8221f30 100644 --- a/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java @@ -48,8 +48,8 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import static org.ethereum.listener.EthereumListener.PendingTransactionState.NEW_PENDING; import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.PendingTransactionUpdated.State.NEW_PENDING; /** * Long running test diff --git a/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java b/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java index 03546548e2..4bb7dd3353 100644 --- a/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java @@ -4,12 +4,8 @@ import org.ethereum.core.BlockHeader; import org.ethereum.core.BlockSummary; import org.ethereum.core.EventDispatchThread; -import org.ethereum.listener.EthereumListener; import org.ethereum.mine.EthashValidationHelper; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.Events; -import org.ethereum.publish.event.SyncDone; import org.junit.Test; import org.spongycastle.util.encoders.Hex; @@ -17,8 +13,11 @@ import static org.ethereum.publish.event.Events.onBlockAdded; import static org.ethereum.publish.event.Events.onSyncDone; +import static org.ethereum.publish.event.SyncDone.State.COMPLETE; import static org.ethereum.validator.BlockHeaderRule.Success; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; /** * @author Mikhail Kalinin @@ -107,7 +106,7 @@ public void testMixed() { assertTrue(partialCheckTriggered); // trigger onSyncDone - publisher.publish(onSyncDone(EthereumListener.SyncState.COMPLETE)); + publisher.publish(onSyncDone(COMPLETE)); // check that full verification is done on each run in strict mode for (int i = 0; i < 100; i++) { From 0d611804a3b4a6a8d2e28dc812ba58b16347cc62 Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Fri, 21 Sep 2018 13:36:23 +0300 Subject: [PATCH 22/28] Fixes 'this' reference error. --- .../src/main/java/org/ethereum/manager/WorldManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java index 92b06e1d7b..cd50fe55d3 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java @@ -137,7 +137,7 @@ public void setApplicationContext(ApplicationContext applicationContext) throws @Deprecated public void addListener(EthereumListener listener) { logger.info("Ethereum listener added"); - ((BackwardCompatibilityEthereumListenerProxy) listener).getCompositeListener().addListener(listener); + ((BackwardCompatibilityEthereumListenerProxy) this.listener).getCompositeListener().addListener(listener); } From 00d46096fd50622c8df9668f865a44bd86c34843 Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Mon, 8 Oct 2018 12:06:36 +0300 Subject: [PATCH 23/28] Adds extra shortcuts to Publisher. Adds Events.Type constants. Fixes couple bugs. Refactors samples. --- .gitignore | 1 + .../src/main/java/org/ethereum/Start.java | 3 - .../org/ethereum/core/PendingTransaction.java | 40 ++ .../java/org/ethereum/db/DbFlushManager.java | 6 +- .../java/org/ethereum/facade/Ethereum.java | 62 +++- .../org/ethereum/facade/EthereumImpl.java | 20 +- ...ardCompatibilityEthereumListenerProxy.java | 8 +- .../org/ethereum/listener/BlockReplayer.java | 207 +++++++++++ .../org/ethereum/listener/EventListener.java | 78 +++- .../java/org/ethereum/mine/BlockMiner.java | 10 +- .../main/java/org/ethereum/mine/Ethash.java | 12 +- .../org/ethereum/net/eth/handler/Eth62.java | 13 +- .../org/ethereum/net/eth/handler/Eth63.java | 6 +- .../ethereum/net/eth/handler/EthHandler.java | 30 +- .../java/org/ethereum/publish/Publisher.java | 35 ++ .../org/ethereum/publish/Subscription.java | 27 +- .../org/ethereum/publish/event/Events.java | 36 +- .../event/PendingTransactionUpdated.java | 49 +-- .../org/ethereum/publish/event/SyncDone.java | 29 +- .../org/ethereum/samples/BasicSample.java | 24 +- .../ethereum/samples/BlockReplaySample.java | 59 +++ .../samples/CreateContractSample.java | 4 +- .../ethereum/samples/EventListenerSample.java | 342 +++--------------- .../org/ethereum/samples/FollowAccount.java | 7 +- .../ethereum/samples/PendingStateSample.java | 9 +- .../ethereum/samples/PrivateMinerSample.java | 1 + .../org/ethereum/samples/SendTransaction.java | 4 +- .../samples/SingleMinerNetSample.java | 285 +++++++++++++++ .../org/ethereum/samples/TransactionBomb.java | 14 +- .../org/ethereum/samples/util/Account.java | 82 +++++ .../org/ethereum/samples/util/Contract.java | 166 +++++++++ .../samples/util/TransactionSubmitter.java | 250 +++++++++++++ .../org/ethereum/sync/FastSyncManager.java | 5 +- .../java/org/ethereum/sync/SyncManager.java | 25 ++ .../util/blockchain/StandaloneBlockchain.java | 4 +- .../org/ethereum/validator/EthashRule.java | 11 +- .../genesis/sample-local-genesis.json | 27 ++ .../resources/samples/contracts/sample.sol | 19 + .../java/org/ethereum/core/CloseTest.java | 7 +- .../org/ethereum/core/ImportLightTest.java | 6 +- .../org/ethereum/core/PendingStateTest.java | 128 +++---- .../java/org/ethereum/longrun/BasicNode.java | 24 +- .../ethereum/longrun/SyncWithLoadTest.java | 9 +- .../org/ethereum/manager/BlockLoaderTest.java | 8 +- .../java/org/ethereum/mine/MinerTest.java | 20 +- .../java/org/ethereum/mine/SyncDoneTest.java | 30 +- .../java/org/ethereum/net/TwoPeerTest.java | 13 +- .../net/eth/handler/LockBlockchainTest.java | 7 +- .../org/ethereum/net/rlpx/FramingTest.java | 11 +- .../ethereum/net/rlpx/SanityLongRunTest.java | 12 +- .../net/rlpx/SnappyConnectionTest.java | 11 +- .../java/org/ethereum/net/shh/ShhLongRun.java | 6 +- .../org/ethereum/publish/PublisherTest.java | 2 +- .../org/ethereum/sync/BlockTxForwardTest.java | 34 +- .../java/org/ethereum/sync/LongSyncTest.java | 45 ++- .../java/org/ethereum/sync/ShortSyncTest.java | 72 ++-- .../ethereum/validator/EthashRuleTest.java | 2 +- 57 files changed, 1742 insertions(+), 715 deletions(-) create mode 100644 ethereumj-core/src/main/java/org/ethereum/listener/BlockReplayer.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/samples/BlockReplaySample.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/samples/SingleMinerNetSample.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/samples/util/Account.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/samples/util/Contract.java create mode 100644 ethereumj-core/src/main/java/org/ethereum/samples/util/TransactionSubmitter.java create mode 100644 ethereumj-core/src/main/resources/genesis/sample-local-genesis.json create mode 100644 ethereumj-core/src/main/resources/samples/contracts/sample.sol diff --git a/.gitignore b/.gitignore index 725e440052..4cb5c675d9 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ logs test_db* testnetSampleDb sampleDB* +*sample*db* # Mac .DS_Store diff --git a/ethereumj-core/src/main/java/org/ethereum/Start.java b/ethereumj-core/src/main/java/org/ethereum/Start.java index 312b5e3656..591eda174d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/Start.java +++ b/ethereumj-core/src/main/java/org/ethereum/Start.java @@ -19,9 +19,6 @@ import org.ethereum.cli.CLIInterface; import org.ethereum.config.SystemProperties; -import org.ethereum.facade.Ethereum; -import org.ethereum.facade.EthereumFactory; -import org.ethereum.manager.BlockLoader; import org.ethereum.mine.Ethash; import java.io.IOException; diff --git a/ethereumj-core/src/main/java/org/ethereum/core/PendingTransaction.java b/ethereumj-core/src/main/java/org/ethereum/core/PendingTransaction.java index ab2411790e..a5a2e9f671 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/PendingTransaction.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/PendingTransaction.java @@ -31,6 +31,46 @@ */ public class PendingTransaction { + public enum State { + /** + * Transaction may be dropped due to: + * - Invalid transaction (invalid nonce, low gas price, insufficient account funds, + * invalid signature) + * - Timeout (when pending transaction is not included to any block for + * last [transaction.outdated.threshold] blocks + * This is the final state + */ + DROPPED, + + /** + * The same as PENDING when transaction is just arrived + * Next state can be either PENDING or INCLUDED + */ + NEW_PENDING, + + /** + * State when transaction is not included to any blocks (on the main chain), and + * was executed on the last best block. The repository state is reflected in the PendingState + * Next state can be either INCLUDED, DROPPED (due to timeout) + * or again PENDING when a new block (without this transaction) arrives + */ + PENDING, + + /** + * State when the transaction is included to a block. + * This could be the final state, however next state could also be + * PENDING: when a fork became the main chain but doesn't include this tx + * INCLUDED: when a fork became the main chain and tx is included into another + * block from the new main chain + * DROPPED: If switched to a new (long enough) main chain without this Tx + */ + INCLUDED; + + public boolean isPending() { + return this == NEW_PENDING || this == PENDING; + } + } + /** * transaction */ diff --git a/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java b/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java index 542b7f79c4..6c9837cd40 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java @@ -25,7 +25,6 @@ import org.ethereum.datasource.DbSource; import org.ethereum.datasource.Source; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.SyncDone; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -41,7 +40,8 @@ import java.util.concurrent.TimeUnit; import static org.ethereum.publish.Subscription.to; -import static org.ethereum.publish.event.SyncDone.State.COMPLETE; +import static org.ethereum.publish.event.Events.Type.SYNC_DONE; +import static org.ethereum.sync.SyncManager.State.COMPLETE; /** * Created by Anton Nashatyrev on 01.12.2016. @@ -81,7 +81,7 @@ public DbFlushManager(SystemProperties config, Set dbSources, Abstract public void setPublisher(Publisher publisher) { if (!flushAfterSyncDone) return; - publisher.subscribe(to(SyncDone.class, state -> { + publisher.subscribe(to(SYNC_DONE, state -> { if (state == COMPLETE) { logger.info("DbFlushManager: long sync done, flushing each block now"); syncDone = true; diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java index 7d66a774b9..f7fdab2ec2 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java @@ -17,7 +17,11 @@ */ package org.ethereum.facade; -import org.ethereum.core.*; +import org.ethereum.core.Block; +import org.ethereum.core.BlockSummary; +import org.ethereum.core.CallTransaction; +import org.ethereum.core.Transaction; +import org.ethereum.core.TransactionReceipt; import org.ethereum.crypto.ECKey; import org.ethereum.listener.EthereumListener; import org.ethereum.manager.AdminInfo; @@ -63,31 +67,68 @@ public interface Ethereum { * Will be removed in future releases. * * @param listener - * @deprecated use {@link #subscribe(Subscription)} instead. + * @deprecated use {@link #subscribe(Subscription)} or other overloaded subscribe(...) methods instead. */ @Deprecated void addListener(EthereumListener listener); /** - * Adds subscription for specific event. + * Adds specified subscription to Ethereum pub/sub system.
      + * Use this method to get more control over {@link Subscription}, like adding handle condition and other supported stuff. + *

      + * Could be used in conjunction with {@link #unsubscribe(Subscription)} method to get extra control + * over subscription lifecycle. + *

      + * If you don't need any tricky subscription logic it's better to use more convenient subscription methods: + *

        + *
      • {@link #subscribe(Class, Consumer)}
      • + *
      • {@link #subscribe(Class, BiConsumer)}
      • + *
      * - * @param subscription + * @param subscription event subscription instance to add; * @return publisher instance to support fluent API. * @see Subscription * @see Publisher * @see Event */ - Publisher subscribe(Subscription subscription); + Ethereum subscribe(Subscription subscription); /** - * More convenient version of {@link #subscribe(Subscription)} + * Removes specified subscription to Ethereum pub/sub system if it was subscribed before.
      + * Usually unsubscribe client from event previously subscribed via {@link #subscribe(Subscription)} method. + * + * @param subscription event subscription instance to remove; + * @return publisher instance to support fluent API. + * @see Subscription + * @see Publisher + * @see Event */ - Publisher subscribe(Class> type, Consumer handler); + Ethereum unsubscribe(Subscription subscription); /** - * More convenient version of {@link #subscribe(Subscription)} + * Subscribes client's handler to specific Ethereum event. + *

      + * Supported events list you can find here {@link org.ethereum.publish.event.Events.Type} + * + * @param type event type to subscribe; + * @param handler event handler; + * @param event payload which will be passed to handler; + * @return {@link Ethereum} instance to support fluent API. + */ + Ethereum subscribe(Class> type, Consumer handler); + + /** + * More advanced version of {@link #subscribe(Class, Consumer)} + * where besides event's payload to client handler passes subscription's {@link org.ethereum.publish.Subscription.LifeCycle}. + *

      + * Supported events list you can find here {@link org.ethereum.publish.event.Events.Type} + * + * @param type event type to subscribe; + * @param handler extended event handler; + * @param event payload which will be passed to handler; + * @return {@link Ethereum} instance to support fluent API. */ - Publisher subscribe(Class> type, BiConsumer handler); + Ethereum subscribe(Class> type, BiConsumer handler); PeerClient getDefaultPeer(); @@ -238,8 +279,7 @@ ProgramResult callConstantFunction(String receiveAddress, ECKey senderPrivateKey void initSyncing(); /** - * @deprecated - * Calculates a 'reasonable' Gas price based on statistics of the latest transaction's Gas prices + * @deprecated Calculates a 'reasonable' Gas price based on statistics of the latest transaction's Gas prices * Normally the price returned should be sufficient to execute a transaction since ~25% of the latest * transactions were executed at this or lower price. * If the transaction is wanted to be executed promptly with higher chances the returned price might diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index 69b48788ac..65c8716f97 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -36,9 +36,7 @@ import org.ethereum.net.shh.Whisper; import org.ethereum.net.submit.TransactionExecutor; import org.ethereum.net.submit.TransactionTask; -import org.ethereum.publish.Publisher; import org.ethereum.publish.Subscription; -import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.Event; import org.ethereum.sync.SyncManager; import org.ethereum.util.ByteUtil; @@ -68,6 +66,7 @@ import java.util.function.Consumer; import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; import static org.ethereum.util.ByteUtil.toHexString; /** @@ -123,7 +122,7 @@ public EthereumImpl(final SystemProperties config) { @PostConstruct public void init() { - worldManager.subscribe(to(BlockAdded.class, data -> gasPriceTracker.onBlock(data.getBlockSummary()))); + worldManager.subscribe(to(BLOCK_ADED, data -> gasPriceTracker.onBlock(data.getBlockSummary()))); } @Override @@ -176,17 +175,24 @@ public void addListener(EthereumListener listener) { } @Override - public Publisher subscribe(Subscription subscription) { - return worldManager.getPublisher().subscribe(subscription); + public Ethereum subscribe(Subscription subscription) { + worldManager.getPublisher().subscribe(subscription); + return this; } @Override - public Publisher subscribe(Class> type, Consumer handler) { + public Ethereum unsubscribe(Subscription subscription) { + worldManager.getPublisher().unsubscribe(subscription); + return this; + } + + @Override + public Ethereum subscribe(Class> type, Consumer handler) { return subscribe(to(type, handler)); } @Override - public Publisher subscribe(Class> type, BiConsumer handler) { + public Ethereum subscribe(Class> type, BiConsumer handler) { return subscribe(to(type, handler)); } diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java b/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java index 01079186d8..380151eb00 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java @@ -21,6 +21,7 @@ import org.ethereum.core.BlockSummary; import org.ethereum.core.EventDispatchThread; import org.ethereum.core.PendingState; +import org.ethereum.core.PendingTransaction; import org.ethereum.core.Transaction; import org.ethereum.core.TransactionExecutionSummary; import org.ethereum.core.TransactionReceipt; @@ -31,8 +32,7 @@ import org.ethereum.net.server.Channel; import org.ethereum.publish.Publisher; import org.ethereum.publish.event.Events; -import org.ethereum.publish.event.PendingTransactionUpdated; -import org.ethereum.publish.event.SyncDone; +import org.ethereum.sync.SyncManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; @@ -139,14 +139,14 @@ public void onPendingStateChanged(PendingState pendingState) { @Override public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionState state, Block block) { compositeListener.onPendingTransactionUpdate(txReceipt, state, block); - PendingTransactionUpdated.State translatedState = translate(state, PendingTransactionUpdated.State.class); + PendingTransaction.State translatedState = translate(state, PendingTransaction.State.class); publisher.publish(Events.onPendingTransactionUpdated(block, txReceipt, translatedState)); } @Override public void onSyncDone(SyncState state) { compositeListener.onSyncDone(state); - SyncDone.State translatedState = translate(state, SyncDone.State.class); + SyncManager.State translatedState = translate(state, SyncManager.State.class); publisher.publish(Events.onSyncDone(translatedState)); } diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/BlockReplayer.java b/ethereumj-core/src/main/java/org/ethereum/listener/BlockReplayer.java new file mode 100644 index 0000000000..e5e3db46d7 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/listener/BlockReplayer.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ +package org.ethereum.listener; + +import org.apache.commons.collections4.queue.CircularFifoQueue; +import org.ethereum.core.Block; +import org.ethereum.core.BlockSummary; +import org.ethereum.core.TransactionInfo; +import org.ethereum.core.TransactionReceipt; +import org.ethereum.db.BlockStore; +import org.ethereum.db.TransactionStore; +import org.ethereum.facade.Ethereum; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.sync.BlockDownloader; +import org.ethereum.util.FastByteComparisons; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.List; +import java.util.function.Consumer; + +import static java.util.Objects.requireNonNull; +import static java.util.stream.Collectors.toList; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; + +/** + * Class capable of replaying stored blocks prior to 'going online' and + * notifying on newly imported blocks + *

      + * For example of usage, look at {@link org.ethereum.samples.BlockReplaySample} + *

      + * Created by Eugene Shevchenko on 07.10.2018. + */ +public class BlockReplayer { + + private static final Logger logger = LoggerFactory.getLogger("events"); + private static final int HALF_BUFFER = BlockDownloader.MAX_IN_REQUEST; + + private final BlockStore blockStore; + private final TransactionStore transactionStore; + private final long firstBlock; + private final Consumer handler; + + private final CircularFifoQueue blocksCache = new CircularFifoQueue<>(HALF_BUFFER * 2); + private boolean completed = false; + private byte[] lastReplayedBlockHash; + + public BlockReplayer(long firstBlock, BlockStore blockStore, TransactionStore transactionStore, Consumer handler) { + if (firstBlock < 0L) { + throw new IllegalArgumentException("Initial block number should be positive value or zero."); + } + requireNonNull(blockStore, "Blocks store is not defined."); + requireNonNull(transactionStore, "Transactions store is not defined."); + requireNonNull(handler, "BlockAdded event handler is not defined."); + + this.blockStore = blockStore; + this.transactionStore = transactionStore; + this.firstBlock = firstBlock; + this.handler = handler; + } + + private void replayBlock(long num) { + Block block = blockStore.getChainBlockByNumber(num); + List receipts = block.getTransactionsList().stream() + .map(tx -> { + TransactionInfo info = transactionStore.get(tx.getHash(), block.getHash()); + TransactionReceipt receipt = info.getReceipt(); + receipt.setTransaction(tx); + return receipt; + }) + .collect(toList()); + + BlockSummary blockSummary = new BlockSummary(block, null, receipts, null); + blockSummary.setTotalDifficulty(BigInteger.valueOf(num)); + + lastReplayedBlockHash = block.getHash(); + + handler.accept(new BlockAdded.Data(blockSummary, true)); + } + + /** + * Replay blocks synchronously + */ + public void replay() { + long lastBlock = blockStore.getMaxNumber(); + long currentBlock = firstBlock; + int replayedBlocksCount = 0; + + logger.info("Replaying blocks from {}, current best block: {}", firstBlock, lastBlock); + while (!completed) { + for (; currentBlock <= lastBlock; currentBlock++, replayedBlocksCount++) { + replayBlock(currentBlock); + + if (replayedBlocksCount % 1000 == 0) { + logger.info("Replayed " + replayedBlocksCount + " blocks so far. Current block: " + currentBlock); + } + } + + synchronized (this) { + if (blocksCache.size() < blocksCache.maxSize()) { + completed = true; + } else { + // So we'll have half of the buffer for new blocks until not synchronized replay finish + long newLastBlock = blockStore.getMaxNumber() - HALF_BUFFER; + if (lastBlock < newLastBlock) { + lastBlock = newLastBlock; + } else { + completed = true; + } + } + } + } + logger.info("Replay complete."); + } + + private synchronized void onBlock(BlockAdded.Data data) { + if (completed) { + if (!blocksCache.isEmpty()) { + replayCachedBlocks(); + logger.info("Cache replay complete. Switching to online mode."); + } + + handler.accept(data); + } else { + blocksCache.add(data); + } + } + + private void replayCachedBlocks() { + logger.info("Replaying cached {} blocks...", blocksCache.size()); + + boolean lastBlockFound = (lastReplayedBlockHash == null) || (blocksCache.size() < blocksCache.maxSize()); + for (BlockAdded.Data cachedBlock : blocksCache) { + if (lastBlockFound) { + handler.accept(cachedBlock); + } else { + byte[] blockHash = cachedBlock.getBlockSummary().getBlock().getHash(); + lastBlockFound = FastByteComparisons.equal(blockHash, lastReplayedBlockHash); + } + } + + blocksCache.clear(); + } + + public boolean isDone() { + return completed && blocksCache.isEmpty(); + } + + public static Builder startFrom(long blockNumber) { + return new Builder(blockNumber); + } + + public static class Builder { + + private long startBlockNumber; + private BlockStore blockStore; + private TransactionStore transactionStore; + private Consumer handler; + + public Builder(long startBlockNumber) { + this.startBlockNumber = startBlockNumber; + } + + public Builder withStores(BlockStore blockStore, TransactionStore transactionStore) { + this.blockStore = blockStore; + this.transactionStore = transactionStore; + return this; + } + + public Builder withHandler(Consumer handler) { + this.handler = handler; + return this; + } + + public BlockReplayer build() { + return new BlockReplayer(startBlockNumber, blockStore, transactionStore, handler); + } + + public BlockReplayer replayAsyncAt(Ethereum ethereum) { + if (startBlockNumber > ethereum.getBlockchain().getBestBlock().getNumber()) { + logger.info("Nothing to replay: start replay block is greater than blockchain's best block."); + } + + BlockReplayer blockReplay = build(); + ethereum.subscribe(BLOCK_ADED, blockReplay::onBlock); + new Thread(() -> blockReplay.replay()).start(); + + return blockReplay; + } + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/EventListener.java b/ethereumj-core/src/main/java/org/ethereum/listener/EventListener.java index f00fe5e3b5..b7844ff0a7 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/EventListener.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/EventListener.java @@ -22,14 +22,18 @@ import org.ethereum.core.Bloom; import org.ethereum.core.CallTransaction; import org.ethereum.core.PendingStateImpl; +import org.ethereum.core.PendingTransaction; import org.ethereum.core.TransactionReceipt; import org.ethereum.db.ByteArrayWrapper; import org.ethereum.listener.EthereumListener.PendingTransactionState; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.PendingTransactionUpdated; import org.ethereum.util.ByteArrayMap; import org.ethereum.util.Utils; import org.ethereum.vm.LogInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; import java.math.BigInteger; import java.util.ArrayList; @@ -38,6 +42,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import static org.ethereum.core.PendingTransaction.State.DROPPED; +import static org.ethereum.core.PendingTransaction.State.INCLUDED; import static org.ethereum.sync.BlockDownloader.MAX_IN_REQUEST; import static org.ethereum.util.ByteUtil.toHexString; @@ -73,7 +79,7 @@ protected class PendingEvent { public Block includedTo; // the latest block from the main branch public Block bestConfirmingBlock; - // if came from a block we take block time, it pending we take current time + // if came from a block we take block time, if pending we take current time public long created; // status of the Ethereum Tx public TxStatus txStatus; @@ -82,13 +88,20 @@ public PendingEvent(long created) { this.created = created; } + /** + * @deprecated use {@link #update(TransactionReceipt, List, PendingTransaction.State, Block)} instead of this method. + */ public void update(TransactionReceipt receipt, List txs, PendingTransactionState state, Block includedTo) { + update(receipt, txs, translate(state), includedTo); + } + + public void update(TransactionReceipt receipt, List txs, PendingTransaction.State state, Block includedTo) { this.receipt = receipt; this.eventData = txs; - this.bestConfirmingBlock = state == PendingTransactionState.INCLUDED ? includedTo : null; - this.includedTo = state == PendingTransactionState.INCLUDED ? includedTo : null; + this.bestConfirmingBlock = state == INCLUDED ? includedTo : null; + this.includedTo = state == INCLUDED ? includedTo : null; txStatus = state.isPending() ? TxStatus.PENDING : - (state == PendingTransactionState.DROPPED ? TxStatus.REJECTED : TxStatus.getConfirmed(1)); + (state == DROPPED ? TxStatus.REJECTED : TxStatus.getConfirmed(1)); } public boolean setBestConfirmingBlock(Block bestConfirmingBlock) { @@ -141,6 +154,14 @@ public EventListener(PendingStateImpl pendingState) { this.pendingState = pendingState; } + public void onBlock(BlockAdded.Data data) { + executor.submit(() -> onBlockImpl(data.getBlockSummary())); + } + + public void onPendingTransactionUpdated(PendingTransactionUpdated.Data data) { + executor.submit(() -> onPendingTransactionUpdateImpl(data.getReceipt(), data.getState(), data.getBlock())); + } + public void onBlockImpl(BlockSummary blockSummary) { if (!initialized) throw new RuntimeException("Event listener should be initialized"); try { @@ -180,9 +201,21 @@ public void onBlockImpl(BlockSummary blockSummary) { } } + private static PendingTransaction.State translate(PendingTransactionState state) { + return PendingTransaction.State.valueOf(state.name()); + } + + private static PendingTransactionState translate(PendingTransaction.State state) { + return PendingTransactionState.valueOf(state.name()); + } + public void onPendingTransactionUpdateImpl(TransactionReceipt txReceipt, PendingTransactionState state, Block block) { + onPendingTransactionUpdateImpl(txReceipt, translate(state), block); + } + + public void onPendingTransactionUpdateImpl(TransactionReceipt txReceipt, PendingTransaction.State state, Block block) { try { - if (state != PendingTransactionState.DROPPED || pendings.containsKey(txReceipt.getTransaction().getHash())) { + if (state != DROPPED || pendings.containsKey(txReceipt.getTransaction().getHash())) { logger.debug("onPendingTransactionUpdate: " + toHexString(txReceipt.getTransaction().getHash()) + ", " + state); } onReceipt(txReceipt, block, state); @@ -213,7 +246,7 @@ public synchronized void initContractTopic(String abi, byte[] topic) { // checks the Tx receipt for the contract LogEvents // initiated on [onPendingTransactionUpdateImpl] callback only - private synchronized void onReceipt(TransactionReceipt receipt, Block block, PendingTransactionState state) { + private synchronized void onReceipt(TransactionReceipt receipt, Block block, PendingTransaction.State state) { if (!initialized) throw new RuntimeException("Event listener should be initialized"); byte[] txHash = receipt.getTransaction().getHash(); if (logFilter.matchBloom(receipt.getBloomFilter())) { @@ -235,7 +268,7 @@ private synchronized void onReceipt(TransactionReceipt receipt, Block block, Pen // cool, we've got some Events from this Tx, let's track further Tx lifecycle onEventData(receipt, block, state, matchedTxs); } - } else if (state == PendingTransactionState.DROPPED && pendings.containsKey(txHash)) { + } else if (state == DROPPED && pendings.containsKey(txHash)) { PendingEvent event = pendings.get(txHash); onEventData(receipt, block, state, event.eventData); } @@ -244,7 +277,7 @@ private synchronized void onReceipt(TransactionReceipt receipt, Block block, Pen // process the list of [EventData] generated by the Tx // initiated on [onPendingTransactionUpdateImpl] callback only private void onEventData(TransactionReceipt receipt, Block block, - PendingTransactionState state, List matchedTxs) { + PendingTransaction.State state, List matchedTxs) { byte[] txHash = receipt.getTransaction().getHash(); PendingEvent event = pendings.get(txHash); boolean newEvent = false; @@ -266,7 +299,20 @@ private void onEventData(TransactionReceipt receipt, Block block, pendingTransactionsUpdated(); } + /** + * @deprecated use {@link #onLogMatch(LogInfo, Block, TransactionReceipt, int, PendingTransaction.State)} instead of this method. + * @param logInfo + * @param block + * @param receipt + * @param txCount + * @param state + * @return + */ protected EventData onLogMatch(LogInfo logInfo, Block block, TransactionReceipt receipt, int txCount, PendingTransactionState state) { + return onLogMatch(logInfo, block,receipt, txCount, translate(state)); + } + + protected EventData onLogMatch(LogInfo logInfo, Block block, TransactionReceipt receipt, int txCount, PendingTransaction.State state) { CallTransaction.Invocation event = contract.parseEvent(logInfo); if (event == null) { @@ -277,6 +323,15 @@ protected EventData onLogMatch(LogInfo logInfo, Block block, TransactionReceipt return onEvent(event, block, receipt, txCount, state); } + /** + * @deprecated override {@link #onEvent(CallTransaction.Invocation, Block, TransactionReceipt, int, PendingTransaction.State)} + * instead of this method. + */ + protected EventData onEvent(CallTransaction.Invocation event, Block block, TransactionReceipt receipt, + int txCount, PendingTransactionState state) { + throw new NotImplementedException(); + } + /** * The implementing subclass should create an EventData instance with the data extracted from * Solidity [event] @@ -289,8 +344,11 @@ protected EventData onLogMatch(LogInfo logInfo, Block block, TransactionReceipt * @param state The state of Transaction (Pending/Rejected/Included) * @return Either null if this [event] is not interesting for implementation class, or [event] representation */ - protected abstract EventData onEvent(CallTransaction.Invocation event, Block block, TransactionReceipt receipt, - int txCount, PendingTransactionState state); + protected EventData onEvent(CallTransaction.Invocation event, Block block, TransactionReceipt receipt, + int txCount, PendingTransaction.State state) { + // proxies invoke to deprecated implementation for backward compatibility. + return onEvent(event, block, receipt, txCount, translate(state)); + } /** * Called after one or more transactions updated diff --git a/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java b/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java index 4bbf7f1d93..a9cbae91f3 100644 --- a/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java +++ b/ethereumj-core/src/main/java/org/ethereum/mine/BlockMiner.java @@ -29,8 +29,6 @@ import org.ethereum.facade.EthereumImpl; import org.ethereum.mine.MinerIfc.MiningResult; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.PendingStateChanged; -import org.ethereum.publish.event.SyncDone; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -44,6 +42,8 @@ import static java.lang.Math.max; import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.PENDING_STATE_CHANGED; +import static org.ethereum.publish.event.Events.Type.SYNC_DONE; /** * Manages embedded CPU mining and allows to use external miners. @@ -97,13 +97,13 @@ public BlockMiner(final SystemProperties config, Publisher publisher, this.fullMining = config.isMineFullDataset(); publisher - .subscribe(to(PendingStateChanged.class, ps -> onPendingStateChanged())) - .subscribe(to(SyncDone.class, s -> { + .subscribe(PENDING_STATE_CHANGED, ps -> onPendingStateChanged()) + .subscribe(SYNC_DONE, s -> { if (config.minerStart() && config.isSyncEnabled()) { logger.info("Sync complete, start mining..."); startMining(); } - })); + }); if (config.minerStart() && !config.isSyncEnabled()) { diff --git a/ethereumj-core/src/main/java/org/ethereum/mine/Ethash.java b/ethereumj-core/src/main/java/org/ethereum/mine/Ethash.java index e2722bdfd6..8b0b686518 100644 --- a/ethereumj-core/src/main/java/org/ethereum/mine/Ethash.java +++ b/ethereumj-core/src/main/java/org/ethereum/mine/Ethash.java @@ -298,12 +298,12 @@ public ListenableFuture mineLight(final Block block, int nThreads) AtomicLong taskStartNonce = new AtomicLong(startNonce >= 0 ? startNonce : new Random().nextLong()); @Override public MiningResult call() throws Exception { - long threadStartNonce = taskStartNonce.getAndAdd(0x100000000L); - final long nonce = getEthashAlgo().mineLight(getFullSize(), getCacheLight(), - sha3(block.getHeader().getEncodedWithoutNonce()), - ByteUtil.byteArrayToLong(block.getHeader().getDifficulty()), threadStartNonce); - final Pair pair = hashimotoLight(block.getHeader(), nonce); - return new MiningResult(nonce, pair.getLeft(), block); + long threadStartNonce = taskStartNonce.getAndAdd(0x100000000L); + final long nonce = getEthashAlgo().mineLight(getFullSize(), getCacheLight(), + sha3(block.getHeader().getEncodedWithoutNonce()), + ByteUtil.byteArrayToLong(block.getHeader().getDifficulty()), threadStartNonce); + final Pair pair = hashimotoLight(block.getHeader(), nonce); + return new MiningResult(nonce, pair.getLeft(), block); } }).submit(); } diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java index 073bcf02bb..9144adec77 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth62.java @@ -24,13 +24,13 @@ import org.ethereum.config.SystemProperties; import org.ethereum.core.*; import org.ethereum.db.BlockStore; -import org.ethereum.listener.EthereumListener; import org.ethereum.net.eth.EthVersion; import org.ethereum.net.eth.message.*; import org.ethereum.net.message.ReasonCode; import org.ethereum.net.rlpx.discover.NodeManager; import org.ethereum.net.submit.TransactionExecutor; import org.ethereum.net.submit.TransactionTask; +import org.ethereum.publish.Publisher; import org.ethereum.sync.PeerState; import org.ethereum.sync.SyncManager; import org.ethereum.sync.SyncStatistics; @@ -52,6 +52,7 @@ import static org.ethereum.datasource.MemSizeEstimator.ByteArrayEstimator; import static org.ethereum.net.eth.EthVersion.V62; import static org.ethereum.net.message.ReasonCode.USELESS_PEER; +import static org.ethereum.publish.event.Events.onEthStatusUpdated; import static org.ethereum.sync.PeerState.*; import static org.ethereum.util.ByteUtil.toHexString; import static org.ethereum.util.Utils.longToTimePeriod; @@ -126,14 +127,14 @@ public Eth62() { @Autowired public Eth62(final SystemProperties config, final Blockchain blockchain, - final BlockStore blockStore, EthereumListener listener) { - this(version, config, blockchain, blockStore, listener); + final BlockStore blockStore, final Publisher publisher) { + this(version, config, blockchain, blockStore, publisher); } Eth62(final EthVersion version, final SystemProperties config, final Blockchain blockchain, final BlockStore blockStore, - final EthereumListener listener) { - super(version, config, blockchain, blockStore, listener); + final Publisher publisher) { + super(version, config, blockchain, blockStore, publisher); } @Override @@ -339,7 +340,7 @@ protected synchronized void processStatus(StatusMessage msg, ChannelHandlerConte // basic checks passed, update statistics channel.getNodeStatistics().ethHandshake(msg); - ethereumListener.onEthStatusUpdated(channel, msg); + publisher.publish(onEthStatusUpdated(channel, msg)); if (peerDiscoveryMode) { loggerNet.trace("Peer discovery mode: STATUS received, disconnecting..."); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java index 993c1afaa7..0405b160d3 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/Eth63.java @@ -29,7 +29,6 @@ import org.ethereum.core.TransactionReceipt; import org.ethereum.datasource.Source; import org.ethereum.db.BlockStore; -import org.ethereum.listener.EthereumListener; import org.ethereum.net.eth.EthVersion; import org.ethereum.net.eth.message.EthMessage; import org.ethereum.net.eth.message.GetNodeDataMessage; @@ -37,6 +36,7 @@ import org.ethereum.net.eth.message.NodeDataMessage; import org.ethereum.net.eth.message.ReceiptsMessage; import org.ethereum.net.message.ReasonCode; +import org.ethereum.publish.Publisher; import org.ethereum.sync.PeerState; import org.ethereum.util.ByteArraySet; import org.ethereum.util.Value; @@ -76,8 +76,8 @@ public Eth63() { @Autowired public Eth63(final SystemProperties config, final Blockchain blockchain, BlockStore blockStore, - final EthereumListener listener) { - super(version, config, blockchain, blockStore, listener); + final Publisher publisher) { + super(version, config, blockchain, blockStore, publisher); } @Override diff --git a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java index c7e79efe9d..1b15ec0dfc 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/eth/handler/EthHandler.java @@ -23,7 +23,6 @@ import org.ethereum.core.Block; import org.ethereum.core.Blockchain; import org.ethereum.db.BlockStore; -import org.ethereum.listener.EthereumListener; import org.ethereum.net.MessageQueue; import org.ethereum.net.eth.EthVersion; import org.ethereum.net.eth.message.EthMessage; @@ -31,15 +30,12 @@ import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.message.ReasonCode; import org.ethereum.net.server.Channel; -import org.ethereum.listener.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.Publisher; import org.ethereum.publish.Subscription; import org.ethereum.publish.event.BlockAdded; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static java.lang.String.format; - /** * Process the messages between peers with 'eth' capability on the network
      * Contains common logic to all supported versions @@ -53,7 +49,7 @@ public abstract class EthHandler extends SimpleChannelInboundHandler protected SystemProperties config; - protected EthereumListener ethereumListener; + protected Publisher publisher; protected Channel channel; @@ -64,7 +60,7 @@ public abstract class EthHandler extends SimpleChannelInboundHandler protected boolean peerDiscoveryMode = false; protected Block bestBlock; - private Subscription bestBlockSub; + private Subscription bestBlockSubscription; protected boolean processTransactions = false; @@ -74,14 +70,14 @@ protected EthHandler(EthVersion version) { protected EthHandler(final EthVersion version, final SystemProperties config, final Blockchain blockchain, final BlockStore blockStore, - final EthereumListener listener) { + final Publisher publisher) { this.version = version; this.config = config; this.blockchain = blockchain; this.bestBlock = blockStore.getBestBlock(); - this.ethereumListener = listener; - this.bestBlockSub = Subscription.to(BlockAdded.class, this::setBestBlock); - getPublisher().subscribe(this.bestBlockSub); + this.publisher = publisher; + this.bestBlockSubscription = Subscription.to(BlockAdded.class, this::setBestBlock); + this.publisher.subscribe(this.bestBlockSubscription); // when sync enabled we delay transactions processing until sync is complete this.processTransactions = !config.isSyncEnabled(); @@ -93,21 +89,14 @@ private void setBestBlock(BlockAdded.Data data) { @Override public void channelRead0(final ChannelHandlerContext ctx, EthMessage msg) throws InterruptedException { - - if (EthMessageCodes.inRange(msg.getCommand().asByte(), version)) + if (EthMessageCodes.inRange(msg.getCommand().asByte(), version)) { logger.trace("EthHandler invoke: [{}]", msg.getCommand()); - - ethereumListener.trace(String.format("EthHandler invoke: [%s]", msg.getCommand())); + } channel.getNodeStatistics().ethInbound.add(); - msgQueue.receivedMessage(msg); } - public Publisher getPublisher() { - return ((BackwardCompatibilityEthereumListenerProxy) ethereumListener).getPublisher(); - } - @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { logger.warn("Eth handling failed", cause); @@ -117,13 +106,12 @@ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws E @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { logger.debug("handlerRemoved: kill timers in EthHandler"); - getPublisher().unsubscribe(bestBlockSub); + publisher.unsubscribe(bestBlockSubscription); onShutdown(); } public void activate() { logger.debug("ETH protocol activated"); - ethereumListener.trace("ETH protocol activated"); sendStatus(); } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java index dad55527ea..2fc118ddaf 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Publisher.java @@ -19,6 +19,7 @@ import org.apache.commons.lang3.text.StrBuilder; import org.ethereum.core.EventDispatchThread; +import org.ethereum.facade.Ethereum; import org.ethereum.publish.event.Event; import org.ethereum.publish.event.OneOffEvent; import org.slf4j.Logger; @@ -30,9 +31,12 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; +import java.util.function.BiConsumer; +import java.util.function.Consumer; import static java.util.Collections.emptyList; import static java.util.Objects.nonNull; +import static org.ethereum.publish.Subscription.to; /** * Event publisher that uses pub/sub model to deliver event messages.
      @@ -151,6 +155,37 @@ public , P> Publisher subscribe(Subscription subscripti return this; } + /** + * Subscribes client's handler to specific Ethereum event. Does the same thing as {@link #subscribe(Subscription)}, + * in more convenient way, but you don't have access to created {@link Subscription} instance. + *

      + * Supported events list you can find here {@link org.ethereum.publish.event.Events.Type} + * + * @param type event type to subscribe; + * @param handler event handler; + * @param event payload which will be passed to handler; + * @return {@link Ethereum} instance to support fluent API. + */ + public Publisher subscribe(Class> type, Consumer handler){ + return subscribe(to(type, handler)); + } + + /** + * More advanced version of {@link #subscribe(Class, Consumer)} + * where besides of event's payload to client's handler passes subscription's {@link org.ethereum.publish.Subscription.LifeCycle}. + *

      + * Supported events list you can find here {@link org.ethereum.publish.event.Events.Type} + * + * @param type event type to subscribe; + * @param handler extended event handler; + * @param event payload which will be passed to handler; + * @return {@link Publisher} instance to support fluent API. + */ + public Publisher subscribe(Class> type, BiConsumer handler) { + return subscribe(to(type, handler)); + } + + /** * Removes specified {@link Subscription} from publisher. * diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java index 90787f7b3d..e4945acf1b 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java @@ -38,6 +38,9 @@ public class Subscription, D> { private final static Logger log = LoggerFactory.getLogger("event"); + /** + * + */ public static class LifeCycle { private final Subscription subscription; @@ -45,6 +48,9 @@ private LifeCycle(Subscription subscription) { this.subscription = subscription; } + /** + * + */ public void unsubscribe() { subscription.unsubscribeAfter(data -> true); } @@ -99,7 +105,7 @@ public Subscription unsubscribeAfter(Function condition) { * Optionally adds {@link #conditionally(Function)} and {@link #unsubscribeAfter(Function)} clauses with the same * condition. It helps achieve specific behavior, when subscriber consumes and then unsubscribe from event source. * - * @param condition + * @param condition that tests to execute and unsubscribe; * @return current {@link Subscription} instance to support fluent API. */ public Subscription oneOff(Function condition) { @@ -108,6 +114,16 @@ public Subscription oneOff(Function condition) { .unsubscribeAfter(condition); } + /** + * Make one-off subscription like {@link #oneOff(Function)} but without any conditions. + * Handles first matched event and unsubscribes after that. + * + * @return current {@link Subscription} instance to support fluent API. + */ + public Subscription oneOff() { + return oneOff(data -> true); + } + /** * Tests specified event whether it should be consumed. * @@ -145,6 +161,15 @@ boolean needUnsubscribeAfter(E event) { return nonNull(unsubscribeCondition) && unsubscribeCondition.apply(event.getPayload()); } + /** + * Short static alias for {@link Subscription} constructor. + * + * @param eventType event type to process; + * @param biConsumer callback that consumes event's payload and subscription's {@link LifeCycle} object to make extra manipulations; + * @param event type that should be process; + * @param payload's type of specified event type; + * @return new {@link Subscription} instance. + */ public static , D> Subscription to(Class eventType, BiConsumer biConsumer) { return new Subscription<>(eventType, biConsumer); } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java index d77b265dba..389ca4ab26 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java @@ -20,6 +20,7 @@ import org.ethereum.core.Block; import org.ethereum.core.BlockSummary; import org.ethereum.core.PendingState; +import org.ethereum.core.PendingTransaction; import org.ethereum.core.TransactionExecutionSummary; import org.ethereum.core.TransactionReceipt; import org.ethereum.net.eth.message.StatusMessage; @@ -27,13 +28,44 @@ import org.ethereum.net.p2p.HelloMessage; import org.ethereum.net.rlpx.Node; import org.ethereum.net.server.Channel; +import org.ethereum.publish.event.message.AbstractMessageEvent; import org.ethereum.publish.event.message.EthStatusUpdated; import org.ethereum.publish.event.message.MessageReceived; import org.ethereum.publish.event.message.MessageSent; import org.ethereum.publish.event.message.PeerHandshaked; +import org.ethereum.sync.SyncManager; public final class Events { + public interface Type { + + Class> ETH_STATUS_UPDATED = EthStatusUpdated.class; + + Class>> MESSAGE_RECEIVED = MessageReceived.class; + + Class>> MESSAGE_SENT = MessageSent.class; + + Class> PEER_HANDSHAKED = PeerHandshaked.class; + + Class> BLOCK_ADED = BlockAdded.class; + + Class> NODE_DISCOVERED = NodeDiscovered.class; + + Class> PEER_ADDED_TO_SYNC_POOL = PeerAddedToSyncPool.class; + + Class> PEER_DISCONNECTED = PeerDisconnected.class; + + Class> PENDING_STATE_CHANGED = PendingStateChanged.class; + + Class> PENDING_TRANSACTION_UPDATED = PendingTransactionUpdated.class; + + Class> SYNC_DONE = SyncDone.class; + + Class> TRANSACTION_EXECUTED = TransactionExecuted.class; + + Class> VM_TRACE_CREATED = VmTraceCreated.class; + } + private Events() { } @@ -77,11 +109,11 @@ public static Event onPendingStateChanged(PendingState state) { return new PendingStateChanged(state); } - public static Event onPendingTransactionUpdated(Block block, TransactionReceipt receipt, PendingTransactionUpdated.State state) { + public static Event onPendingTransactionUpdated(Block block, TransactionReceipt receipt, PendingTransaction.State state) { return new PendingTransactionUpdated(block, receipt, state); } - public static Event onSyncDone(SyncDone.State state) { + public static Event onSyncDone(SyncManager.State state) { return new SyncDone(state); } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdated.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdated.java index 8ab1f01221..511559c642 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdated.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/PendingTransactionUpdated.java @@ -18,6 +18,7 @@ package org.ethereum.publish.event; import org.ethereum.core.Block; +import org.ethereum.core.PendingTransaction; import org.ethereum.core.TransactionReceipt; /** @@ -27,52 +28,12 @@ */ public class PendingTransactionUpdated extends Event { - public enum State { - /** - * Transaction may be dropped due to: - * - Invalid transaction (invalid nonce, low gas price, insufficient account funds, - * invalid signature) - * - Timeout (when pending transaction is not included to any block for - * last [transaction.outdated.threshold] blocks - * This is the final state - */ - DROPPED, - - /** - * The same as PENDING when transaction is just arrived - * Next state can be either PENDING or INCLUDED - */ - NEW_PENDING, - - /** - * State when transaction is not included to any blocks (on the main chain), and - * was executed on the last best block. The repository state is reflected in the PendingState - * Next state can be either INCLUDED, DROPPED (due to timeout) - * or again PENDING when a new block (without this transaction) arrives - */ - PENDING, - - /** - * State when the transaction is included to a block. - * This could be the final state, however next state could also be - * PENDING: when a fork became the main chain but doesn't include this tx - * INCLUDED: when a fork became the main chain and tx is included into another - * block from the new main chain - * DROPPED: If switched to a new (long enough) main chain without this Tx - */ - INCLUDED; - - public boolean isPending() { - return this == NEW_PENDING || this == PENDING; - } - } - /** * Event DTO */ public static class Data { private final TransactionReceipt receipt; - private final State state; + private final PendingTransaction.State state; private final Block block; /** @@ -81,7 +42,7 @@ public static class Data { * @param block The block which the current pending state is based on (for PENDING tx state) * or the block which tx was included to (for INCLUDED state) */ - public Data(Block block, TransactionReceipt receipt, State state) { + public Data(Block block, TransactionReceipt receipt, PendingTransaction.State state) { this.receipt = receipt; this.state = state; this.block = block; @@ -91,7 +52,7 @@ public TransactionReceipt getReceipt() { return receipt; } - public State getState() { + public PendingTransaction.State getState() { return state; } @@ -100,7 +61,7 @@ public Block getBlock() { } } - public PendingTransactionUpdated(Block block, TransactionReceipt receipt, State state) { + public PendingTransactionUpdated(Block block, TransactionReceipt receipt, PendingTransaction.State state) { super(new Data(block, receipt, state)); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java index 2d9bebfbac..b99300ffc6 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/SyncDone.java @@ -17,34 +17,11 @@ */ package org.ethereum.publish.event; -public class SyncDone extends Event implements OneOffEvent { +import org.ethereum.sync.SyncManager; - public enum State { - /** - * When doing fast sync UNSECURE sync means that the full state is downloaded, - * chain is on the latest block, and blockchain operations may be executed - * (such as state querying, transaction submission) - * but the state isn't yet confirmed with the whole block chain and can't be - * trusted. - * At this stage historical blocks and receipts are unavailable yet - */ - UNSECURE, - /** - * When doing fast sync SECURE sync means that the full state is downloaded, - * chain is on the latest block, and blockchain operations may be executed - * (such as state querying, transaction submission) - * The state is now confirmed by the full chain (all block headers are - * downloaded and verified) and can be trusted - * At this stage historical blocks and receipts are unavailable yet - */ - SECURE, - /** - * Sync is fully complete. All blocks and receipts are downloaded. - */ - COMPLETE - } +public class SyncDone extends Event implements OneOffEvent { - public SyncDone(State payload) { + public SyncDone(SyncManager.State payload) { super(payload); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java index fac2fb158a..8e4edac54d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java @@ -31,11 +31,6 @@ import org.ethereum.facade.EthereumFactory; import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.NodeDiscovered; -import org.ethereum.publish.event.PeerAddedToSyncPool; -import org.ethereum.publish.event.SyncDone; -import org.ethereum.publish.event.message.EthStatusUpdated; import org.ethereum.util.ByteUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,6 +41,11 @@ import java.util.*; import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.ETH_STATUS_UPDATED; +import static org.ethereum.publish.event.Events.Type.NODE_DISCOVERED; +import static org.ethereum.publish.event.Events.Type.PEER_ADDED_TO_SYNC_POOL; +import static org.ethereum.publish.event.Events.Type.SYNC_DONE; /** * The base sample class which creates EthereumJ instance, tracks and report all the stages @@ -136,12 +136,10 @@ private void springInit() { // adding the main EthereumJ callback to be notified on different kind of events this.ethereum - .subscribe(to(SyncDone.class, syncState -> synced = true)) - .subscribe(to(NodeDiscovered.class, node -> nodesDiscovered.add(node)) - .conditionally(node -> nodesDiscovered.size() < 1000)) - .subscribe(to(EthStatusUpdated.class, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage()))) - .subscribe(to(PeerAddedToSyncPool.class, peer -> syncPeers.add(peer.getNode()))) - .subscribe(to(BlockAdded.class, data -> { + .subscribe(SYNC_DONE, syncState -> synced = true) + .subscribe(ETH_STATUS_UPDATED, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage())) + .subscribe(PEER_ADDED_TO_SYNC_POOL, peer -> syncPeers.add(peer.getNode())) + .subscribe(BLOCK_ADED, data -> { BlockSummary blockSummary = data.getBlockSummary(); Block block = blockSummary.getBlock(); List receipts = blockSummary.getReceipts(); @@ -154,7 +152,9 @@ private void springInit() { if (syncComplete) { logger.info("New block: " + block.getShortDescr()); } - })); + }) + .subscribe(to(NODE_DISCOVERED, node -> nodesDiscovered.add(node)) + .conditionally(node -> nodesDiscovered.size() < 1000)); logger.info("Sample component created. Listening for ethereum events..."); diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/BlockReplaySample.java b/ethereumj-core/src/main/java/org/ethereum/samples/BlockReplaySample.java new file mode 100644 index 0000000000..97cb1ef5cd --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/samples/BlockReplaySample.java @@ -0,0 +1,59 @@ +package org.ethereum.samples; + +import org.ethereum.db.BlockStore; +import org.ethereum.db.TransactionStore; +import org.ethereum.facade.EthereumFactory; +import org.ethereum.listener.BlockReplayer; +import org.ethereum.publish.event.BlockAdded; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; + +import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; + +public class BlockReplaySample extends SingleMinerNetSample { + + @Autowired + private BlockStore blockStore; + @Autowired + private TransactionStore transactionStore; + private BlockReplayer replay; + + @Override + protected void onSampleReady() { + ethereum.subscribe(to(BLOCK_ADED, this::enableReplay) + .oneOff(data -> data.getBlockSummary().getBlock().getNumber() % 50 == 0)); + } + + private void enableReplay(BlockAdded.Data data) { + long startBlockNumber = data.getBlockSummary().getBlock().getNumber() - 25; + this.replay = BlockReplayer.startFrom(startBlockNumber) + .withStores(blockStore, transactionStore) + .withHandler(this::onBlock) + .replayAsyncAt(ethereum); + } + + private void onBlock(BlockAdded.Data data) { + long blockNumber = data.getBlockSummary().getBlock().getNumber(); + if (replay.isDone()) { + logger.info("Live chain block #{} handled.", blockNumber); + } else { + logger.info("Replayed block #{} handled.", blockNumber); + } + } + + public static void main(String[] args) { + + class Config extends SingleMinerNetSample.Config { + + @Bean + @Override + public SingleMinerNetSample sample() { + return new BlockReplaySample(); + } + + } + + EthereumFactory.createEthereum(Config.class); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java index 2b1647f9b2..5321d9c817 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java @@ -37,7 +37,7 @@ import java.util.HashMap; import java.util.Map; -import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; import static org.ethereum.util.ByteUtil.toHexString; /** @@ -64,7 +64,7 @@ public class CreateContractSample extends TestNetSample { @Override public void onSyncDone() throws Exception { // when block arrives look for our included transactions - ethereum.subscribe(to(BlockAdded.class, this::onBlock)); + ethereum.subscribe(BLOCK_ADED, this::onBlock); logger.info("Compiling contract..."); SolidityCompiler.Result result = compiler.compileSrc(contract.getBytes(), true, true, diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java index 4e5f95012a..67ef2f1349 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java @@ -17,97 +17,34 @@ */ package org.ethereum.samples; -import org.ethereum.core.*; -import org.ethereum.crypto.ECKey; -import org.ethereum.db.BlockStore; -import org.ethereum.db.ByteArrayWrapper; -import org.ethereum.db.TransactionStore; +import org.ethereum.core.Block; +import org.ethereum.core.CallTransaction; +import org.ethereum.core.PendingStateImpl; +import org.ethereum.core.PendingTransaction; +import org.ethereum.core.TransactionReceipt; import org.ethereum.facade.EthereumFactory; -import org.ethereum.listener.BlockReplay; -import org.ethereum.listener.EthereumListener; import org.ethereum.listener.EventListener; import org.ethereum.listener.TxStatus; -import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.PendingTransactionUpdated; -import org.ethereum.solidity.compiler.CompilationResult; -import org.ethereum.solidity.compiler.SolidityCompiler; -import org.ethereum.util.ByteUtil; -import org.ethereum.vm.program.ProgramResult; +import org.ethereum.samples.util.Account; +import org.ethereum.samples.util.Contract; import org.spongycastle.util.encoders.Hex; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.math.BigInteger; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Scanner; -import static org.ethereum.crypto.HashUtil.sha3; -import static org.ethereum.publish.Subscription.to; -import static org.ethereum.util.ByteUtil.toHexString; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.PENDING_TRANSACTION_UPDATED; /** * Sample usage of events listener API. * {@link EventListener} Contract events listener - * {@link BlockReplay} Listener wrapper for pushing old blocks to any listener in addition to live data - * - * - getting free Ether assuming we are running in test network - * - deploying contract with event, which we are going to track - * - calling contract and catching corresponding events - * - alternatively you could provide address of already deployed contract and - * replay any number of blocks in the past to process old events + *

      + * - getting free Ether assuming we are running in test network + * - deploying contract with event, which we are going to track + * - calling contract and catching corresponding events */ -public class EventListenerSample extends TestNetSample { - - @Autowired - SolidityCompiler compiler; - - @Autowired - BlockStore blockStore; - - @Autowired - TransactionStore transactionStore; - - @Autowired - PendingStateImpl pendingState; - - // Change seed phrases - protected final byte[] senderPrivateKey = sha3("cat".getBytes()); - protected final byte[] sender2PrivateKey = sha3("goat".getBytes()); - - // If no contractAddress provided, deploys new contract, otherwise - // replays events from already deployed contract - String contractAddress = null; -// String contractAddress = "cedf27de170a05cf1d1736f21e1f5ffc1cf22eef"; - - String contract = - "contract Sample {\n" + - " int i;\n" + - " event Inc(\n" + - " address _from,\n" + - " int _inc,\n" + - " int _total\n" + - " ); \n" + - " \n" + - " function inc(int n) {\n" + - " i = i + n;\n" + - " Inc(msg.sender, n, i); \n" + - " } \n" + - " \n" + - " function get() returns (int) {\n" + - " return i; \n" + - " }\n" + - "} "; - - private Map txWaiters = - Collections.synchronizedMap(new HashMap<>()); +public class EventListenerSample extends SingleMinerNetSample { class IncEvent { IncEvent(String address, Long inc, Long total) { @@ -122,11 +59,7 @@ class IncEvent { @Override public String toString() { - return "IncEvent{" + - "address='" + address + '\'' + - ", inc=" + inc + - ", total=" + total + - '}'; + return String.format("IncEvent{address='%s', inc=%d, total=%d}", address, inc, total); } } @@ -137,13 +70,13 @@ class IncEventListener extends EventListener { * After this number of confirmations, event will fire {@link #processConfirmed(PendingEvent, IncEvent)} * on each confirmation */ - protected int blocksToConfirm = 32; + protected int blocksToConfirm = 10; /** * Minimum required Tx block confirmations for this Tx to be purged * from the tracking list * After this number of confirmations, event will not fire {@link #processConfirmed(PendingEvent, IncEvent)} */ - protected int purgeFromPendingsConfirmations = 40; + protected int purgeFromPendingsConfirmations = 12; public IncEventListener(PendingStateImpl pendingState) { super(pendingState); @@ -159,7 +92,7 @@ public IncEventListener(PendingStateImpl pendingState, String contractABI, byte[ } @Override - protected IncEvent onEvent(CallTransaction.Invocation event, Block block, TransactionReceipt receipt, int txCount, EthereumListener.PendingTransactionState state) { + protected IncEvent onEvent(CallTransaction.Invocation event, Block block, TransactionReceipt receipt, int txCount, PendingTransaction.State state) { // Processing raw event data to fill our model IncEvent if ("Inc".equals(event.function.name)) { String address = Hex.toHexString((byte[]) event.args[0]); @@ -197,231 +130,46 @@ protected boolean pendingTransactionUpdated(PendingEvent evt) { } } - /** - * Sample logic starts here when sync is done - */ - @Override - public void onSyncDone() throws Exception { - ethereum.subscribe(to(PendingTransactionUpdated.class, data -> { - TransactionReceipt txReceipt = data.getReceipt(); - ByteArrayWrapper txHashW = new ByteArrayWrapper(txReceipt.getTransaction().getHash()); - // Catching transaction errors - if (txWaiters.containsKey(txHashW) && !txReceipt.isSuccessful()) { - txWaiters.put(txHashW, txReceipt); - } - })); - - requestFreeEther(ECKey.fromPrivate(senderPrivateKey).getAddress()); - requestFreeEther(ECKey.fromPrivate(sender2PrivateKey).getAddress()); - if (contractAddress == null) { - deployContractAndTest(); - } else { - replayOnly(); - } - } - - public void requestFreeEther(byte[] addressBytes) { - String address = "0x" + toHexString(addressBytes); - logger.info("Checking address {} for available ether.", address); - BigInteger balance = ethereum.getRepository().getBalance(addressBytes); - logger.info("Address {} balance: {} wei", address, balance); - BigInteger requiredBalance = BigInteger.valueOf(3_000_000 * ethereum.getGasPrice()); - if (balance.compareTo(requiredBalance) < 0) { - logger.info("Insufficient funds for address {}, requesting free ether", address); - try { - String result = postQuery("https://ropsten.faucet.b9lab.com/tap", "{\"toWhom\":\"" + address + "\"}"); - logger.info("Answer from free Ether API: {}", result); - waitForEther(addressBytes, requiredBalance); - } catch (Exception ex) { - logger.error("Error during request of free Ether,", ex); - } - } - } - - private String postQuery(String endPoint, String json) throws IOException { - URL url = new URL(endPoint); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setConnectTimeout(5000); - conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); - conn.setDoOutput(true); - conn.setDoInput(true); - conn.setRequestMethod("POST"); - - OutputStream os = conn.getOutputStream(); - os.write(json.getBytes("UTF-8")); - os.close(); - - // read the response - InputStream in = new BufferedInputStream(conn.getInputStream()); - String result = null; - try (Scanner scanner = new Scanner(in, "UTF-8")) { - result = scanner.useDelimiter("\\A").next(); - } - - in.close(); - conn.disconnect(); - - return result; - } - - private void waitForEther(byte[] address, BigInteger requiredBalance) throws InterruptedException { - while(true) { - BigInteger balance = ethereum.getRepository().getBalance(address); - if (balance.compareTo(requiredBalance) > 0) { - logger.info("Address {} successfully funded. Balance: {} wei", "0x" + toHexString(address), balance); - break; - } - synchronized (this) { - wait(20000); - } - } - } - - /** - * - Deploys contract - * - Adds events listener - * - Calls contract from 2 different addresses - */ - private void deployContractAndTest() throws Exception { - // when block arrives look for our included transactions - ethereum.subscribe(to(BlockAdded.class, this::onBlock)); - - CompilationResult.ContractMetadata metadata = compileContract(); - - logger.info("Sending contract to net and waiting for inclusion"); - TransactionReceipt receipt = sendTxAndWait(new byte[0], Hex.decode(metadata.bin), senderPrivateKey); - - if (!receipt.isSuccessful()) { - logger.error("Some troubles creating a contract: " + receipt.getError()); - return; - } - - byte[] address = receipt.getTransaction().getContractAddress(); - logger.info("Contract created: " + toHexString(address)); - - IncEventListener eventListener = new IncEventListener(pendingState, metadata.abi, address); - ethereum.addListener(eventListener.listener); - - CallTransaction.Contract contract = new CallTransaction.Contract(metadata.abi); - contractIncCall(senderPrivateKey, 777, metadata.abi, address); - contractIncCall(sender2PrivateKey, 555, metadata.abi, address); + @Autowired + private PendingStateImpl pendingState; - ProgramResult r = ethereum.callConstantFunction(Hex.toHexString(address), - contract.getByName("get")); - Object[] ret = contract.getByName("get").decodeResult(r.getHReturn()); - logger.info("Current contract data member value: " + ret[0]); - } + @Override + protected void onSampleReady() { + Contract contract = contract("sample"); + IncEventListener eventListener = new IncEventListener(pendingState, contract.getAbi(), contract.getAddress()); - /** - * Replays contract events for old blocks - * using {@link BlockReplay} with {@link EventListener} - */ - private void replayOnly() throws Exception { - logger.info("Contract already deployed to address 0x{}, using it", contractAddress); - CompilationResult.ContractMetadata metadata = compileContract(); - byte[] address = Hex.decode(contractAddress); - IncEventListener eventListener = new IncEventListener(pendingState, metadata.abi, address); - BlockReplay blockReplay = new BlockReplay(blockStore, transactionStore, eventListener.listener, - blockStore.getMaxNumber() - 5000); - ethereum.addListener(blockReplay); - blockReplay.replayAsync(); - } + this.ethereum + .subscribe(BLOCK_ADED, eventListener::onBlock) + .subscribe(PENDING_TRANSACTION_UPDATED, eventListener::onPendingTransactionUpdated); - private CompilationResult.ContractMetadata compileContract() throws IOException { - logger.info("Compiling contract..."); - SolidityCompiler.Result result = compiler.compileSrc(contract.getBytes(), true, true, - SolidityCompiler.Options.ABI, SolidityCompiler.Options.BIN); - if (result.isFailed()) { - throw new RuntimeException("Contract compilation failed:\n" + result.errors); - } - CompilationResult res = CompilationResult.parse(result.output); - if (res.getContracts().isEmpty()) { - throw new RuntimeException("Compilation failed, no contracts returned:\n" + result.errors); - } - CompilationResult.ContractMetadata metadata = res.getContracts().iterator().next(); - if (metadata.bin == null || metadata.bin.isEmpty()) { - throw new RuntimeException("Compilation failed, no binary returned:\n" + result.errors); - } + Contract.Caller cow = contractCaller("cow", "sample"); + Contract.Caller cat = contractCaller("cat", "sample"); - return metadata; + cow.call("inc", 777); + cat.call("inc", 555); } - private void contractIncCall(byte[] privateKey, int incAmount, - String contractABI, byte[] contractAddress) throws InterruptedException { - logger.info("Calling the contract function 'inc'"); - CallTransaction.Contract contract = new CallTransaction.Contract(contractABI); - CallTransaction.Function inc = contract.getByName("inc"); - byte[] functionCallBytes = inc.encode(incAmount); - TransactionReceipt receipt = sendTxAndWait(contractAddress, functionCallBytes, privateKey); - if (!receipt.isSuccessful()) { - logger.error("Some troubles invoking the contract: " + receipt.getError()); - return; - } - logger.info("Contract modified!"); - } + public static void main(String[] args) { + class Config extends SingleMinerNetSample.Config { - protected TransactionReceipt sendTxAndWait(byte[] receiveAddress, - byte[] data, byte[] privateKey) throws InterruptedException { - BigInteger nonce = ethereum.getRepository().getNonce(ECKey.fromPrivate(privateKey).getAddress()); - Transaction tx = new Transaction( - ByteUtil.bigIntegerToBytes(nonce), - ByteUtil.longToBytesNoLeadZeroes(ethereum.getGasPrice()), - ByteUtil.longToBytesNoLeadZeroes(3_000_000), - receiveAddress, - ByteUtil.longToBytesNoLeadZeroes(0), - data, - ethereum.getChainIdForNextBlock()); - tx.sign(ECKey.fromPrivate(privateKey)); - logger.info("<=== Sending transaction: " + tx); - ByteArrayWrapper txHashW = new ByteArrayWrapper(tx.getHash()); - txWaiters.put(txHashW, null); - ethereum.submitTransaction(tx); - - return waitForTx(txHashW); - } - - private void onBlock(BlockAdded.Data data) { - for (TransactionReceipt receipt : data.getBlockSummary().getReceipts()) { - ByteArrayWrapper txHashW = new ByteArrayWrapper(receipt.getTransaction().getHash()); - if (txWaiters.containsKey(txHashW)) { - txWaiters.put(txHashW, receipt); - synchronized (this) { - notifyAll(); - } + @Bean + @Override + public SingleMinerNetSample sample() { + return new EventListenerSample(); } - } - } - protected TransactionReceipt waitForTx(ByteArrayWrapper txHashW) throws InterruptedException { - long startBlock = ethereum.getBlockchain().getBestBlock().getNumber(); - while(true) { - TransactionReceipt receipt = txWaiters.get(txHashW); - if (receipt != null) { - return receipt; - } else { - long curBlock = ethereum.getBlockchain().getBestBlock().getNumber(); - if (curBlock > startBlock + 16) { - throw new RuntimeException("The transaction was not included during last 16 blocks: " + txHashW.toString().substring(0,8)); - } else { - logger.info("Waiting for block with transaction 0x" + txHashW.toString().substring(0,8) + - " included (" + (curBlock - startBlock) + " blocks received so far) ..."); - } - } - synchronized (this) { - wait(20000); + @Override + protected void registerAccounts(Account.Register register) { + register + .addSameNameAndPass("cat") + .addSameNameAndPass("cow"); } - } - } - - public static void main(String[] args) throws Exception { - sLogger.info("Starting EthereumJ!"); - class Config extends TestNetConfig{ @Override - @Bean - public TestNetSample sampleBean() { - return new EventListenerSample(); + protected void registerContracts(Contract.Register register) { + register + .add("sample", loadContractSource("sample.sol") ); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java b/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java index fb2e588292..5144fbccb6 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java @@ -21,18 +21,17 @@ import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; import org.ethereum.facade.Repository; -import org.ethereum.publish.event.BlockAdded; import org.spongycastle.util.encoders.Hex; import java.math.BigInteger; -import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; public class FollowAccount { public static void main(String[] args) { Ethereum ethereum = EthereumFactory.createEthereum(); - ethereum.subscribe(to(BlockAdded.class, data -> { + ethereum.subscribe(BLOCK_ADED, data -> { byte[] cow = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826"); // Get snapshot some time ago - 10% blocks ago @@ -49,6 +48,6 @@ public static void main(String[] args) { System.err.printf(" #%d [cd2a3d9] => snapshot_nonce:%d latest_nonce:%d\n", data.getBlockSummary().getBlock().getNumber(), nonce_, nonce); - })); + }); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java index a5e830e912..1058df0fc3 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java @@ -22,7 +22,6 @@ import org.ethereum.db.ByteArrayWrapper; import org.ethereum.facade.EthereumFactory; import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.PendingTransactionUpdated; import org.ethereum.util.ByteUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -30,7 +29,9 @@ import java.math.BigInteger; import java.util.*; -import static org.ethereum.publish.event.PendingTransactionUpdated.State.NEW_PENDING; +import static org.ethereum.core.PendingTransaction.State.NEW_PENDING; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.PENDING_TRANSACTION_UPDATED; import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.ByteUtil.toHexString; @@ -66,10 +67,10 @@ public class PendingStateSample extends TestNetSample { public void onSyncDone() { this.ethereum // listening here when the PendingState is updated with new transactions - .subscribe(to(PendingTransactionUpdated.class, data -> onPendingTransactionReceived(data.getReceipt().getTransaction())) + .subscribe(to(PENDING_TRANSACTION_UPDATED, data -> onPendingTransactionReceived(data.getReceipt().getTransaction())) .conditionally(data -> data.getState() == NEW_PENDING)) // when block arrives look for our included transactions - .subscribe(to(BlockAdded.class, d -> onBlock(d))); + .subscribe(BLOCK_ADED, d -> onBlock(d)); new Thread(() -> { try { diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/PrivateMinerSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/PrivateMinerSample.java index 964d581d19..0f18669499 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/PrivateMinerSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/PrivateMinerSample.java @@ -63,6 +63,7 @@ private static class MinerConfig { // when more than 1 miner exist on the network extraData helps to identify the block creator "mine.extraDataHex = cccccccccccccccccccc \n" + "mine.cpuMineThreads = 2 \n" + + "mine.mine.fullDataSet = false \n" + "cache.flush.blocks = 1"; @Bean diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java b/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java index 07c68ac858..1c431db287 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java @@ -34,7 +34,7 @@ import java.util.HashMap; import java.util.Map; -import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; /** * With this simple example you can send transaction from address to address in live public network @@ -50,7 +50,7 @@ public class SendTransaction extends BasicSample { @Override public void onSyncDone() throws Exception { // when block arrives look for our included transactions - this.ethereum.subscribe(to(BlockAdded.class, this::onBlock)); + this.ethereum.subscribe(BLOCK_ADED, this::onBlock); String toAddress = ""; logger.info("Sending transaction to net and waiting for inclusion"); diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/SingleMinerNetSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/SingleMinerNetSample.java new file mode 100644 index 0000000000..286af27756 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/samples/SingleMinerNetSample.java @@ -0,0 +1,285 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ +package org.ethereum.samples; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.LoggerContext; +import com.typesafe.config.ConfigFactory; +import org.ethereum.config.SystemProperties; +import org.ethereum.core.TransactionReceipt; +import org.ethereum.crypto.ECKey; +import org.ethereum.facade.Ethereum; +import org.ethereum.facade.EthereumFactory; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.samples.util.Account; +import org.ethereum.samples.util.TransactionSubmitter; +import org.ethereum.samples.util.Contract; +import org.ethereum.solidity.compiler.SolidityCompiler; +import org.ethereum.util.blockchain.StandaloneBlockchain; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; + +import javax.annotation.PostConstruct; +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +import static java.nio.file.Files.readAllBytes; +import static org.ethereum.core.Denomination.ETHER; +import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; + +/** + * Basic class for independent private network samples. + * Within this sample single node starts with miner mode. + * To reduce block's waiting time the mining difficulty setted up to pretty low value (block adding speed is about 1 block per second). + * This class can be used as a base for free transactions testing + * (everyone may use that 'usr1pass' sender which has pretty enough fake coins) + *

      + * Created by Eugene Shevchenko on 05.10.2018. + */ +public class SingleMinerNetSample { + + protected abstract static class Config { + + @Autowired + private ResourceLoader resourceLoader; + + protected Resource loadSampleResource(String path) { + return resourceLoader.getResource("classpath:samples" + path); + } + + protected byte[] loadContractSource(String contractName) { + try { + Resource resource = loadSampleResource("/contracts/" + contractName); + return readAllBytes(resource.getFile().toPath()); + } catch (IOException e) { + throw new RuntimeException(contractName + " contract source loading error: ", e); + } + } + + public abstract SingleMinerNetSample sample(); + + protected Map getExtraConfig() { + return new LinkedHashMap() {{ + put("sync.enabled", false); + put("sync.makeDoneByTimeout", 60); + put("peer.discovery.enabled", false); + put("peer.listen.port", 0); + put("peer.privateKey", "6ef8da380c27cea8fdf7448340ea99e8e2268fc2950d79ed47cbf6f85dc977ec"); + put("peer.networkId", 555); + put("mine.start", true); + put("mine.fullDataSet", false); + put("mine.extraDataHex", "cccccccccccccccccccc"); + put("mine.minBlockTimeoutMsec", 0); + put("mine.cpuMineThreads", 1); + put("genesis", "sample-local-genesis.json"); + put("database.dir", "local-net-sample-db"); + put("cache.flush.blocks", 10); + }}; + } + + @Bean + public final SystemProperties systemProperties() { + SystemProperties props = SystemProperties.getDefault(); + props.setBlockchainConfig(StandaloneBlockchain.getEasyMiningConfig()); + + Map extraConfig = getExtraConfig(); + if (!extraConfig.isEmpty()) { + props.overrideParams(ConfigFactory.parseMap(extraConfig)); + } + + return props; + } + + @Bean + public TransactionSubmitter transactionSubmitter(Ethereum ethereum) { + return new TransactionSubmitter(ethereum); + } + + @Bean + public final Account.Register accountRegister() { + Account.Register register = Account.newRegister().withFaucet("usr1pass"); + registerAccounts(register); + return register; + } + + /** + * Template method for custom accounts installing. + * Register own accounts via {@link org.ethereum.samples.util.Account.Register} to get some test ether. + * @param register + */ + protected void registerAccounts(Account.Register register) { + + } + + @Bean + public final Contract.Register contractRegister(SolidityCompiler compiler) { + Contract.Register register = Contract.newRegister(compiler); + registerContracts(register); + return register; + } + + /** + * Register your contract via {@link org.ethereum.samples.util.Contract.Register} to deploy it at sample prepare phase. + * @param register + */ + protected void registerContracts(Contract.Register register) { + + } + } + + protected static final Logger logger = LoggerFactory.getLogger("sample"); + + @Autowired + protected Ethereum ethereum; + @Autowired + protected SolidityCompiler compiler; + @Autowired + protected TransactionSubmitter txSubmitter; + @Autowired + protected Account.Register accountRegister; + @Autowired + protected Contract.Register contractRegister; + + protected final Account account(String id) { + return accountRegister.get(id); + } + + protected final Contract contract(String id) { + return contractRegister.get(id); + } + + protected final Contract.Caller contractCaller(String accountId, String contractId) { + Account caller = account(accountId); + return contract(contractId).newCaller(caller.getKey(), ethereum, txSubmitter); + } + + private CompletableFuture deployContracts() { + ECKey faucetKey = accountRegister.getFaucet().getKey(); + + CompletableFuture[] futures = contractRegister.contracts().stream() + .filter(contract -> !contract.isDeployed()) + .map(contract -> txSubmitter.deployTransaction(faucetKey, contract.getBinaryCode()).submit() + .thenApply(receipt -> contract.deployedAt(receipt.getTransaction().getContractAddress()))) + .toArray(CompletableFuture[]::new); + + + return CompletableFuture.allOf(futures).whenComplete((smth, err) -> { + if (err == null) { + logger.info("All predefined contracts successfully deployed."); + } else { + logger.info("Contract deployment error: ", err); + } + }); + } + + private CompletableFuture transferFundsToAccounts() { + ECKey faucetKey = accountRegister.getFaucet().getKey(); + + CompletableFuture[] futures = accountRegister.accountsWithoutFaucet().stream() + .map(account -> txSubmitter + .transferTransaction(faucetKey, account.getAddress(), 100, ETHER) + .submit()) + .toArray(CompletableFuture[]::new); + + return CompletableFuture.allOf(futures).whenComplete((smth, err) -> { + if (err == null) { + logger.info("All funds transfers for predefined accounts performed successfully."); + } else { + logger.error("Funds transferring error: ", err); + } + }); + } + + @PostConstruct + public final void initSample() { + this.ethereum + .subscribe(to(BLOCK_ADED, this::onImportStarted).oneOff()) + .subscribe(to(BLOCK_ADED, this::printHeartbeat)); + } + + private void printHeartbeat(BlockAdded.Data data) { + if (data.getBlockSummary().getBlock().getNumber() % 15 == 0) { + logger.info("heartbeat: block #{} mined and imported.", data.getBlockSummary().getBlock().getNumber()); + } + } + + private void onImportStarted(BlockAdded.Data data) { + logger.info("Single miner network is up. The first block #{} has been imported.", data.getBlockSummary().getBlock().getNumber()); + + List initActions = new ArrayList<>(); + initActions.add(transferFundsToAccounts()); + initActions.add(deployContracts()); + + CompletableFuture.allOf(initActions.toArray(new CompletableFuture[]{})) + .whenComplete((aVoid, err) -> { + if (err == null) { + logger.info("Sample components successfully deployed."); + onSampleReady(); + } else { + logger.error("Sample setup failed with error: ", err); + onSampleFailed(err); + } + }); + } + + protected void onSampleReady() { + + } + + protected void onSampleFailed(Throwable err) { + System.exit(1); + } + + public static void main(String[] args) { + + class Cfg extends Config { + + @Bean + @Override + public SingleMinerNetSample sample() { + return new SingleMinerNetSample(); + } + } + + EthereumFactory.createEthereum(Cfg.class); + } + + static { + overrideLoggingLevel("mine", Level.WARN); + overrideLoggingLevel("blockchain", Level.WARN); + overrideLoggingLevel("net", Level.WARN); + overrideLoggingLevel("db", Level.WARN); + overrideLoggingLevel("sync", Level.WARN); + } + + private static void overrideLoggingLevel(String loggerName, Level level) { + final LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); + Logger rootLogger = loggerContext.getLogger(loggerName); + ((ch.qos.logback.classic.Logger) rootLogger).setLevel(level); + } + +} diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java b/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java index f8ecf5f2b9..5c2499d8e8 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java @@ -21,13 +21,14 @@ import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.SyncDone; +import org.ethereum.sync.SyncManager; import org.spongycastle.util.encoders.Hex; import java.util.Collections; import static org.ethereum.crypto.HashUtil.sha3; -import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.SYNC_DONE; import static org.ethereum.util.ByteUtil.longToBytesNoLeadZeroes; import static org.ethereum.util.ByteUtil.toHexString; @@ -38,10 +39,9 @@ public class TransactionBomb { boolean startedTxBomb = false; public TransactionBomb(Ethereum ethereum) { - this.ethereum = ethereum; - this.ethereum - .subscribe(to(SyncDone.class, this::onSyncDone)) - .subscribe(to(BlockAdded.class, this::onBlock)); + this.ethereum = ethereum + .subscribe(SYNC_DONE, this::onSyncDone) + .subscribe(BLOCK_ADED, this::onBlock); } public static void main(String[] args) { @@ -49,7 +49,7 @@ public static void main(String[] args) { } - public void onSyncDone(SyncDone.State state) { + public void onSyncDone(SyncManager.State state) { // We will send transactions only // after we have the full chain syncs // - in order to prevent old nonce usage diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/util/Account.java b/ethereumj-core/src/main/java/org/ethereum/samples/util/Account.java new file mode 100644 index 0000000000..9a54c802da --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/samples/util/Account.java @@ -0,0 +1,82 @@ +package org.ethereum.samples.util; + +import org.ethereum.crypto.ECKey; + +import java.math.BigInteger; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import static java.util.Objects.isNull; +import static org.ethereum.crypto.HashUtil.sha3; + +public class Account { + + public static class Register { + + private static final String FAUCET_NAME = "faucet"; + + private final Map map = new HashMap<>(); + + public Register add(String name, String password) { + map.put(name, new Account(password)); + return this; + } + + public Register addSameNameAndPass(String name) { + return add(name, name); + } + + public Account get(String name) { + Account value = map.get(name); + if (value == null) { + throw new RuntimeException("Account with name " + name + " isn't registered."); + } + return value; + } + + public Set accounts(Predicate filter) { + return map.entrySet().stream() + .filter(e -> isNull(filter) || filter.test(e.getKey())) + .map(Map.Entry::getValue) + .collect(Collectors.toSet()); + } + + public Set accounts() { + return accounts(null); + } + + public Register withFaucet(String password) { + return add(FAUCET_NAME, password); + } + + public Account getFaucet() { + return get(FAUCET_NAME); + } + + public Set accountsWithoutFaucet() { + return accounts(name -> !FAUCET_NAME.equals(name)); + } + } + + private final ECKey key; + private BigInteger requiredBalance; + + public Account(String password) { + this.key = ECKey.fromPrivate(sha3(password.getBytes())); + } + + public ECKey getKey() { + return key; + } + + public byte[] getAddress() { + return key.getAddress(); + } + + public static Register newRegister() { + return new Register(); + } +} \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/util/Contract.java b/ethereumj-core/src/main/java/org/ethereum/samples/util/Contract.java new file mode 100644 index 0000000000..b7132eb71c --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/samples/util/Contract.java @@ -0,0 +1,166 @@ +package org.ethereum.samples.util; + +import org.ethereum.core.CallTransaction; +import org.ethereum.crypto.ECKey; +import org.ethereum.facade.Ethereum; +import org.ethereum.solidity.compiler.CompilationResult; +import org.ethereum.solidity.compiler.SolidityCompiler; +import org.ethereum.vm.program.ProgramResult; +import org.spongycastle.util.encoders.Hex; + +import java.io.IOException; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Stream; + +import static java.lang.String.format; +import static java.util.Objects.requireNonNull; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static org.apache.commons.lang3.StringUtils.isEmpty; +import static org.ethereum.util.ByteUtil.toHexString; + +public class Contract { + + private static final SolidityCompiler.Option[] DEFAULT_COMPILATION_OPTIONS = {SolidityCompiler.Options.ABI, SolidityCompiler.Options.BIN}; + + private byte[] address; + private final CompilationResult.ContractMetadata metadata; + private final CallTransaction.Contract accessor; + + public Contract(byte[] address, CompilationResult.ContractMetadata metadata) { + requireNonNull(metadata, "Contract metadata object couldn't be null."); + + this.address = address; + this.metadata = metadata; + this.accessor = new CallTransaction.Contract(metadata.abi); + } + + public boolean isDeployed() { + return address != null; + } + + public Contract deployedAt(byte[] address) { + this.address = address; + return this; + } + + public byte[] getAddress() { + return address; + } + + public String getAbi() { + return metadata.abi; + } + + public byte[] getBinaryCode() { + return Hex.decode(metadata.bin); + } + + public static Contract compile(byte[] source, SolidityCompiler compiler, SolidityCompiler.Option... compilationOpts) throws IOException { + + SolidityCompiler.Option[] options = Stream.concat(Stream.of(DEFAULT_COMPILATION_OPTIONS), Stream.of(compilationOpts)) + .distinct() + .toArray(SolidityCompiler.Option[]::new); + + SolidityCompiler.Result result = compiler.compileSrc(source, true, true, options); + + if (result.isFailed()) { + throw new RuntimeException("Contract compilation failed:\n" + result.errors); + } + CompilationResult res = CompilationResult.parse(result.output); + if (res.getContracts().isEmpty()) { + throw new RuntimeException("Compilation failed, no contracts returned:\n" + result.errors); + } + + CompilationResult.ContractMetadata metadata = res.getContracts().iterator().next(); + if (isEmpty(metadata.bin)) { + throw new RuntimeException("Compilation failed, no binary returned:\n" + result.errors); + } + + return new Contract(null, metadata); + } + + public Caller newCaller(ECKey callerKey, Ethereum ethereum, TransactionSubmitter submitter) { + return new Caller(callerKey, ethereum, submitter); + } + + public static Register newRegister(SolidityCompiler compiler) { + return new Register(compiler); + } + + public class Caller { + + private final Ethereum ethereum; + private final TransactionSubmitter submitter; + + private final ECKey key; + + public Caller(ECKey callerKey, Ethereum ethereum, TransactionSubmitter submitter) { + + if (!isDeployed()) { + throw new RuntimeException("Couldn't create caller for non deployed contract."); + } + + this.ethereum = ethereum; + this.submitter = submitter; + this.key = callerKey; + } + + public CompletableFuture call(String funcName, Object... args) { + CallTransaction.Function func = accessor.getByName(funcName); + if (func == null) { + throw new RuntimeException(format("There is no function with name '%s'.", funcName)); + } + + if (func.constant) { + ProgramResult result = ethereum.callConstantFunction(toHexString(getAddress()), key, func, args); + return completedFuture(result.getHReturn()); + } + + return submitter.invokeTransaction(key, getAddress(), func.encode(args)) + .submit() + .thenApply(receipt -> receipt.getExecutionResult()); + } + } + + public static class Register { + + private final Map contractById = new ConcurrentHashMap<>(); + private final SolidityCompiler compiler; + + public Register(SolidityCompiler compiler) { + this.compiler = compiler; + } + + public Register add(String id, Contract contract) { + contractById.put(id, contract); + return this; + } + + public Register addDeployed(String id, byte[] address, byte[] source) { + try { + return add(id, Contract.compile(source, compiler).deployedAt(address)); + } catch (Exception e) { + throw new RuntimeException("Contract registration error: ", e); + } + } + + public Register add(String id, byte[] source) { + return addDeployed(id, null, source); + } + + public Contract get(String id) { + Contract contract = contractById.get(id); + if (contract == null) { + throw new RuntimeException(format("There is no contract with id '%s' in the register.", id)); + } + return contract; + } + + public Collection contracts() { + return contractById.values(); + } + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/util/TransactionSubmitter.java b/ethereumj-core/src/main/java/org/ethereum/samples/util/TransactionSubmitter.java new file mode 100644 index 0000000000..ec7d6e65f9 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/samples/util/TransactionSubmitter.java @@ -0,0 +1,250 @@ +package org.ethereum.samples.util; + +import org.ethereum.core.Block; +import org.ethereum.core.Denomination; +import org.ethereum.core.Transaction; +import org.ethereum.core.TransactionReceipt; +import org.ethereum.crypto.ECKey; +import org.ethereum.db.ByteArrayWrapper; +import org.ethereum.facade.Ethereum; +import org.ethereum.publish.event.BlockAdded; +import org.ethereum.publish.event.PendingTransactionUpdated; +import org.ethereum.util.ByteUtil; +import org.ethereum.util.FastByteComparisons; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +import static java.lang.String.format; +import static java.util.function.Function.identity; +import static java.util.stream.Collectors.toMap; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.PENDING_TRANSACTION_UPDATED; +import static org.ethereum.util.BIUtil.toBI; + +public class TransactionSubmitter { + + private final Ethereum ethereum; + private final Map activeByTxHash = new ConcurrentHashMap<>(); + private final Map> txQueueBySenderAddr = new ConcurrentHashMap<>(); + + public TransactionSubmitter(Ethereum ethereum) { + this.ethereum = ethereum + .subscribe(PENDING_TRANSACTION_UPDATED, this::onPendingTransactionUpdated) + .subscribe(BLOCK_ADED, this::onBlockAdded); + } + + public TransactionBuilder newTransaction(ECKey senderKey, byte[] receiverAddress) { + return new TransactionBuilder(senderKey, receiverAddress); + } + + public TransactionBuilder transferTransaction(ECKey senderKey, byte[] receiverAddress, long value, Denomination denomination) { + return newTransaction(senderKey, receiverAddress) + .value(toBI(value), denomination); + } + + public TransactionBuilder deployTransaction(ECKey senderKey, byte[] binaryCode) { + return newTransaction(senderKey, ByteUtil.EMPTY_BYTE_ARRAY) + .data(binaryCode); + } + + public TransactionBuilder invokeTransaction(ECKey senderKey, byte[] contractAddress, byte[] encodedInvocationData) { + return newTransaction(senderKey, contractAddress) + .data(encodedInvocationData); + } + + private void onPendingTransactionUpdated(PendingTransactionUpdated.Data data) { + TransactionReceipt receipt = data.getReceipt(); + if (receipt.isSuccessful()) return; + + byte[] txHash = receipt.getTransaction().getHash(); + TransactionBuilder tb = activeByTxHash.get(wrap(txHash)); + if (tb != null && tb.isApplicable(receipt)) { + tb.completeExceptionally(receipt.getError()); + } + } + + private void onBlockAdded(BlockAdded.Data data) { + Block block = data.getBlockSummary().getBlock(); + List receipts = data.getBlockSummary().getReceipts(); + + Map receiptByTxHash = receipts.stream() + .filter(receipt -> activeByTxHash.containsKey(wrap(receipt.getTransaction().getHash()))) + .collect(toMap(receipt -> new ByteArrayWrapper(receipt.getTransaction().getHash()), identity())); + + + activeByTxHash.forEach((txHash, tb) -> { + TransactionReceipt receipt = receiptByTxHash.get(txHash); + if (receipt != null) { + if (receipt.isSuccessful()) { + tb.complete(receipt); + } else { + tb.completeExceptionally(receipt.getError()); + } + } else if (tb.isExpired(block)) { + tb.completeExceptionally("The transaction was not included during last " + tb.waitBlocksCount + " blocks."); + } + }); + } + + + private void activate(TransactionBuilder txBuilder) { + txBuilder.buildAndSubmit(); + activeByTxHash.put(wrap(txBuilder.txHash), txBuilder); + } + + private void addToSubmitQueue(TransactionBuilder txBuilder) { + ByteArrayWrapper address = wrap(txBuilder.senderKey.getAddress()); + Queue queue = txQueueBySenderAddr.computeIfAbsent(address, addr -> new LinkedList<>()); + synchronized (queue) { + if (queue.isEmpty()) { + activate(txBuilder); + } + queue.add(txBuilder); + } + } + + + private void removeFromSubmitQueue(TransactionBuilder txBuilder) { + ByteArrayWrapper address = new ByteArrayWrapper(txBuilder.senderKey.getAddress()); + Queue queue = txQueueBySenderAddr.get(address); + synchronized (queue) { + queue.poll(); + activeByTxHash.remove(wrap(txBuilder.txHash)); + if (queue.isEmpty()) { + txQueueBySenderAddr.remove(address); + } else { + activate(queue.peek()); + } + } + } + + public class TransactionBuilder { + + private final ECKey senderKey; + private final byte[] receiverAddress; + // changeable during building transaction's data + private byte[] value = ByteUtil.longToBytesNoLeadZeroes(0); + private byte[] data = ByteUtil.EMPTY_BYTE_ARRAY; + private byte[] gasPrice = ByteUtil.longToBytesNoLeadZeroes(ethereum.getGasPrice()); + private byte[] gasLimit = ByteUtil.longToBytesNoLeadZeroes(3_000_000); + + private byte[] txHash; + private CompletableFuture futureReceipt; + + private long submitBlockNumber; + private long waitBlocksCount; + + public TransactionBuilder(ECKey senderKey, byte[] receiverAddress) { + this.senderKey = senderKey; + this.receiverAddress = receiverAddress; + } + + public TransactionBuilder data(byte[] data) { + this.data = data; + return this; + } + + public TransactionBuilder gasPrice(byte[] gasPrice) { + this.gasPrice = gasPrice; + return this; + } + + public TransactionBuilder gasPrice(BigInteger gasPrice) { + return gasPrice(gasPrice.toByteArray()); + } + + public TransactionBuilder gasLimit(byte[] gasLimit) { + this.gasLimit = gasLimit; + return this; + } + + public TransactionBuilder gasLimit(BigInteger gasLimit) { + return gasLimit(gasLimit.toByteArray()); + } + + public TransactionBuilder value(byte[] value) { + this.value = value; + return this; + } + + public TransactionBuilder value(BigInteger value, Denomination denomination) { + return value(value.multiply(denomination.value()).toByteArray()); + } + + public TransactionBuilder value(BigInteger value) { + return value(value, Denomination.WEI); + } + + private void buildAndSubmit() { + byte[] nonce = ByteUtil.bigIntegerToBytes(ethereum.getRepository().getNonce(senderKey.getAddress())); + Integer chainId = ethereum.getChainIdForNextBlock(); + + Transaction tx = new Transaction(nonce, gasPrice, gasLimit, receiverAddress, value, data, chainId); + tx.sign(senderKey); + + ethereum.submitTransaction(tx); + + this.txHash = tx.getHash(); + this.submitBlockNumber = ethereum.getBlockchain().getBestBlock().getNumber(); + } + + private boolean isSubmitted() { + return submitBlockNumber > 0; + } + + private boolean isApplicable(TransactionReceipt receipt) { + return isSubmitted() && FastByteComparisons.equal(receipt.getTransaction().getHash(), txHash); + } + + private void complete(TransactionReceipt receipt) { + if (!isSubmitted()) { + throw new IllegalStateException("Cannot complete non submitted transaction."); + } + futureReceipt.complete(receipt); + } + + private void completeExceptionally(String error, Object... args) { + if (!isSubmitted()) { + throw new IllegalStateException("Cannot complete non submitted transaction."); + } + String message = format("Transaction %s execution error: %s", toHexString(txHash, 4), format(error, args)); + futureReceipt.completeExceptionally(new RuntimeException(message)); + } + + public boolean isExpired(Block block) { + return isSubmitted() && (block.getNumber() - submitBlockNumber) > waitBlocksCount; + } + + public CompletableFuture submit(int waitBlocksCount) { + if (futureReceipt != null) { + return futureReceipt; + } + + this.futureReceipt = new CompletableFuture<>(); + this.waitBlocksCount = waitBlocksCount; + + addToSubmitQueue(this); + + return futureReceipt.whenComplete((receipt, err) -> removeFromSubmitQueue(this)); + } + + public CompletableFuture submit() { + return submit(15); + } + } + + private static String toHexString(byte[] bytes, int count) { + return ByteUtil.toHexString(Arrays.copyOf(bytes, count)); + } + + private static ByteArrayWrapper wrap(byte[] bytes) { + return new ByteArrayWrapper(bytes); + } +} diff --git a/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java b/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java index 9bf5a6f0ce..27b32d7e43 100644 --- a/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/sync/FastSyncManager.java @@ -42,7 +42,6 @@ import org.ethereum.net.message.ReasonCode; import org.ethereum.net.server.Channel; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.SyncDone; import org.ethereum.trie.TrieKey; import org.ethereum.util.ByteArrayMap; import org.ethereum.util.ByteArraySet; @@ -80,7 +79,7 @@ import static org.ethereum.listener.EthereumListener.SyncState.COMPLETE; import static org.ethereum.listener.EthereumListener.SyncState.SECURE; import static org.ethereum.listener.EthereumListener.SyncState.UNSECURE; -import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.SYNC_DONE; import static org.ethereum.trie.TrieKey.fromPacked; import static org.ethereum.util.ByteUtil.toHexString; import static org.ethereum.util.CompactEncoder.hasTerminator; @@ -587,7 +586,7 @@ private void syncUnsecure(BlockHeader pivot) { logger.info("FastSync: proceeding to regular sync..."); final CountDownLatch syncDoneLatch = new CountDownLatch(1); - publisher.subscribe(to(SyncDone.class, syncState -> syncDoneLatch.countDown())); + publisher.subscribe(SYNC_DONE, syncState -> syncDoneLatch.countDown()); syncManager.initRegularSync(UNSECURE); logger.info("FastSync: waiting for regular sync to reach the blockchain head..."); diff --git a/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java b/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java index 1e7ec58e91..8262c0c666 100644 --- a/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/sync/SyncManager.java @@ -57,6 +57,31 @@ public class SyncManager extends BlockDownloader { private final static Logger logger = LoggerFactory.getLogger("sync"); + public enum State { + /** + * When doing fast sync UNSECURE sync means that the full state is downloaded, + * chain is on the latest block, and blockchain operations may be executed + * (such as state querying, transaction submission) + * but the state isn't yet confirmed with the whole block chain and can't be + * trusted. + * At this stage historical blocks and receipts are unavailable yet + */ + UNSECURE, + /** + * When doing fast sync SECURE sync means that the full state is downloaded, + * chain is on the latest block, and blockchain operations may be executed + * (such as state querying, transaction submission) + * The state is now confirmed by the full chain (all block headers are + * downloaded and verified) and can be trusted + * At this stage historical blocks and receipts are unavailable yet + */ + SECURE, + /** + * Sync is fully complete. All blocks and receipts are downloaded. + */ + COMPLETE + } + // Transaction.getSender() is quite heavy operation so we are prefetching this value on several threads // to unload the main block importing cycle private ExecutorPipeline exec1 = new ExecutorPipeline<> diff --git a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java index 751ffe4a2b..23a03d8598 100644 --- a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java @@ -34,7 +34,6 @@ import org.ethereum.mine.Ethash; import org.ethereum.listener.BackwardCompatibilityEthereumListenerProxy; import org.ethereum.publish.Subscription; -import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.Event; import org.ethereum.solidity.compiler.CompilationResult; import org.ethereum.solidity.compiler.CompilationResult.ContractMetadata; @@ -57,6 +56,7 @@ import java.util.concurrent.ExecutionException; import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; import static org.ethereum.util.ByteUtil.wrap; /** @@ -445,7 +445,7 @@ public BlockchainImpl getBlockchain() { if (blockchain == null) { blockchain = createBlockchain(genesis); blockchain.setMinerCoinbase(coinbase); - subscribe(to(BlockAdded.class, data -> lastSummary = data.getBlockSummary())); + subscribe(to(BLOCK_ADED, data -> lastSummary = data.getBlockSummary())); } return blockchain; } diff --git a/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java b/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java index 62710058c6..9de5c919e7 100644 --- a/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java +++ b/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java @@ -22,15 +22,14 @@ import org.ethereum.core.BlockHeader; import org.ethereum.mine.EthashValidationHelper; import org.ethereum.publish.Publisher; -import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.SyncDone; import org.ethereum.util.FastByteComparisons; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Random; -import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.SYNC_DONE; import static org.ethereum.validator.EthashRule.ChainType.main; import static org.ethereum.validator.EthashRule.ChainType.reverse; import static org.ethereum.validator.EthashRule.Mode.fake; @@ -107,12 +106,12 @@ public EthashRule(Mode mode, ChainType chain, Publisher publisher) { if (this.chain == main && publisher != null) { publisher - .subscribe(to(SyncDone.class, ss -> EthashRule.this.syncDone = true)) - .subscribe(to(BlockAdded.class, data -> { + .subscribe(SYNC_DONE, ss -> EthashRule.this.syncDone = true) + .subscribe(BLOCK_ADED, data -> { if (data.isBest()) { ethashHelper.preCache(data.getBlockSummary().getBlock().getNumber()); } - })); + }); } } } diff --git a/ethereumj-core/src/main/resources/genesis/sample-local-genesis.json b/ethereumj-core/src/main/resources/genesis/sample-local-genesis.json new file mode 100644 index 0000000000..603e7c40f0 --- /dev/null +++ b/ethereumj-core/src/main/resources/genesis/sample-local-genesis.json @@ -0,0 +1,27 @@ +{ + "alloc": { + "33dc1c95f5a0a25bb82ed171f263bf776f210005": { + "balance": "1606938044258990275541962092341162602522202993782792835301376" + }, + "86549a9def66a77a351fb4321e1674fc4bcb7aad": { + "balance": "1606938044258990275541962092341162602522202993782792835301376" + }, + "07e45810d7d442cc2e2863688ab3eb0effdb1e62": { + "balance": "1606938044258990275541962092341162602522202993782792835301376" + }, + "21840989a52616816c87fb956191eea09bc779ed": { + "balance": "1606938044258990275541962092341162602522202993782792835301376" + }, + "68293c7fbde6f439f65ea0d1afc3af99f70a82f5": { + "balance": "1606938044258990275541962092341162602522202993782792835301376" + } + }, + "nonce": "0x0000000000000000", + "difficulty": "0xff", + "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", + "gasLimit": "0x1000000000" +} \ No newline at end of file diff --git a/ethereumj-core/src/main/resources/samples/contracts/sample.sol b/ethereumj-core/src/main/resources/samples/contracts/sample.sol new file mode 100644 index 0000000000..3819e30a16 --- /dev/null +++ b/ethereumj-core/src/main/resources/samples/contracts/sample.sol @@ -0,0 +1,19 @@ +pragma solidity ^0.4.11; + +contract Sample { + int i; + event Inc( + address _from, + int _inc, + int _total + ); + + function inc(int n) { + i = i + n; + Inc(msg.sender, n, i); + } + + function get() returns (int) { + return i; + } +} \ No newline at end of file diff --git a/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java b/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java index 705ec37dc8..f46ff91510 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java @@ -19,7 +19,6 @@ import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.BlockAdded; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; @@ -27,7 +26,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; -import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; /** * Created by Anton Nashatyrev on 24.06.2016. @@ -44,11 +43,11 @@ public void relaunchTest() throws InterruptedException { Assert.assertNotNull(bestBlock); final CountDownLatch latch = new CountDownLatch(1); AtomicInteger counter = new AtomicInteger(); - ethereum.subscribe(to(BlockAdded.class, data -> { + ethereum.subscribe(BLOCK_ADED, data -> { if (counter.addAndGet(1) > 1100) { latch.countDown(); } - })); + }); System.out.println("### Waiting for some blocks to be imported..."); latch.await(); diff --git a/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java b/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java index c323b3769f..2d4d43429d 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java @@ -28,7 +28,6 @@ import org.ethereum.db.RepositoryRoot; import org.ethereum.mine.Ethash; import org.ethereum.listener.BackwardCompatibilityEthereumListenerProxy; -import org.ethereum.publish.event.TransactionExecuted; import org.ethereum.util.ByteUtil; import org.ethereum.util.blockchain.SolidityContract; import org.ethereum.util.blockchain.StandaloneBlockchain; @@ -46,6 +45,7 @@ import java.util.*; import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.TRANSACTION_EXECUTED; /** * Created by Anton Nashatyrev on 29.12.2015. @@ -774,7 +774,7 @@ public void suicideInFailedCall() throws Exception { SolidityContract a = bc.submitNewContract(contractA, "A"); bc.createBlock(); final BigInteger[] refund = new BigInteger[1]; - bc.subscribe(to(TransactionExecuted.class, tes -> refund[0] = tes.getGasRefund())); + bc.subscribe(to(TRANSACTION_EXECUTED, tes -> refund[0] = tes.getGasRefund())); a.callFunction("f"); bc.createBlock(); @@ -802,7 +802,7 @@ public void logInFailedCall() throws Exception { SolidityContract a = bc.submitNewContract(contractA, "A"); bc.createBlock(); final List logs = new ArrayList<>(); - bc.subscribe(to(TransactionExecuted.class, tes -> logs.addAll(tes.getLogs()))); + bc.subscribe(to(TRANSACTION_EXECUTED, tes -> logs.addAll(tes.getLogs()))); a.callFunction("f"); bc.createBlock(); diff --git a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java index d55f1865bd..dc398ac5c4 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java @@ -24,7 +24,6 @@ import org.ethereum.db.ByteArrayWrapper; import org.ethereum.listener.EthereumListener; import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.PendingStateChanged; import org.ethereum.publish.event.PendingTransactionUpdated; import org.ethereum.util.blockchain.SolidityContract; import org.ethereum.util.blockchain.StandaloneBlockchain; @@ -44,10 +43,13 @@ import java.util.concurrent.TimeUnit; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.ethereum.publish.event.PendingTransactionUpdated.State.DROPPED; -import static org.ethereum.publish.event.PendingTransactionUpdated.State.INCLUDED; -import static org.ethereum.publish.event.PendingTransactionUpdated.State.NEW_PENDING; -import static org.ethereum.publish.event.PendingTransactionUpdated.State.PENDING; +import static org.ethereum.core.PendingTransaction.State.DROPPED; +import static org.ethereum.core.PendingTransaction.State.INCLUDED; +import static org.ethereum.core.PendingTransaction.State.NEW_PENDING; +import static org.ethereum.core.PendingTransaction.State.PENDING; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.PENDING_STATE_CHANGED; +import static org.ethereum.publish.event.Events.Type.PENDING_TRANSACTION_UPDATED; import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.blockchain.EtherUtil.Unit.ETHER; import static org.ethereum.util.blockchain.EtherUtil.convert; @@ -71,9 +73,9 @@ public static void cleanup() { static class PendingListener { public BlockingQueue>> onBlock = new LinkedBlockingQueue<>(); public BlockingQueue onPendingStateChanged = new LinkedBlockingQueue<>(); -// public BlockingQueue> onPendingTransactionUpdate = new LinkedBlockingQueue<>(); +// public BlockingQueue> onPendingTransactionUpdate = new LinkedBlockingQueue<>(); - Map>> + Map>> onPendingTransactionUpdate = new HashMap<>(); public void onBlock(BlockAdded.Data data) { @@ -93,14 +95,14 @@ public void onPendingTransactionUpdate(PendingTransactionUpdated.Data data) { } - public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionUpdated.State state, Block block) { + public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransaction.State state, Block block) { System.out.println("PendingStateTest.onPendingTransactionUpdate:" + "txReceipt.err = [" + txReceipt.getError() + "], state = [" + state + "], block: " + block.getShortDescr()); getQueueFor(txReceipt.getTransaction()).add(Triple.of(txReceipt, state, block)); } - public synchronized BlockingQueue> getQueueFor(Transaction tx) { + public synchronized BlockingQueue> getQueueFor(Transaction tx) { ByteArrayWrapper hashW = new ByteArrayWrapper(tx.getHash()); - BlockingQueue> queue = onPendingTransactionUpdate.get(hashW); + BlockingQueue> queue = onPendingTransactionUpdate.get(hashW); if (queue == null) { queue = new LinkedBlockingQueue<>(); onPendingTransactionUpdate.put(hashW, queue); @@ -108,11 +110,11 @@ public synchronized BlockingQueue pollTxUpdate(Transaction tx) throws InterruptedException { + public Triple pollTxUpdate(Transaction tx) throws InterruptedException { return getQueueFor(tx).poll(5, SECONDS); } } @@ -121,11 +123,11 @@ public Triple pollTx public void testSimple() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAdded.class, l::onBlock)) - .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); + .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) + .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); - Triple txUpd; + Triple txUpd; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -182,7 +184,7 @@ public void testSimple() throws InterruptedException { for (int i = 0; i < SystemProperties.getDefault().txOutdatedThreshold() + 1; i++) { bc.createBlock(); txUpd = l.pollTxUpdate(tx3); - if (txUpd.getMiddle() != PendingTransactionUpdated.State.PENDING) break; + if (txUpd.getMiddle() != PENDING) break; } // tx3 dropped due to timeout @@ -196,11 +198,11 @@ public void testSimple() throws InterruptedException { public void testRebranch1() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAdded.class, l::onBlock)) - .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); + .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) + .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); - Triple txUpd = null; + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -265,11 +267,11 @@ public void testRebranch1() throws InterruptedException { public void testRebranch2() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAdded.class, l::onBlock)) - .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); + .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) + .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); - Triple txUpd = null; + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -355,11 +357,11 @@ public void testRebranch2() throws InterruptedException { public void testRebranch3() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAdded.class, l::onBlock)) - .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); + .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) + .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); - Triple txUpd = null; + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -407,11 +409,11 @@ public void testRebranch3() throws InterruptedException { public void testOldBlockIncluded() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAdded.class, l::onBlock)) - .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); + .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) + .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); - Triple txUpd = null; + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -445,11 +447,11 @@ public void testOldBlockIncluded() throws InterruptedException { public void testBlockOnlyIncluded() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAdded.class, l::onBlock)) - .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); + .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) + .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); - Triple txUpd = null; + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -474,11 +476,11 @@ public void testBlockOnlyIncluded() throws InterruptedException { public void testTrackTx1() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAdded.class, l::onBlock)) - .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); + .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) + .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); - Triple txUpd = null; + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -528,11 +530,11 @@ public void testPrevBlock() throws InterruptedException { PendingListener l = new PendingListener(); bc - .subscribe(to(BlockAdded.class, l::onBlock)) - .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); + .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) + .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); - Triple txUpd; + Triple txUpd; contract.callFunction("getPrevBlockHash"); bc.generatePendingTransactions(); @@ -545,11 +547,11 @@ public void testPrevBlock() throws InterruptedException { public void testTrackTx2() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAdded.class, l::onBlock)) - .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); + .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) + .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); - Triple txUpd = null; + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -578,11 +580,11 @@ public void testTrackTx2() throws InterruptedException { public void testRejected1() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAdded.class, l::onBlock)) - .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); + .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) + .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); - Triple txUpd = null; + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -611,8 +613,8 @@ public void testRejected1() throws InterruptedException { for (int i = 0; i < 16; i++) { bc.createBlock(); - PendingTransactionUpdated.State state = l.pollTxUpdateState(tx1); - if (state == PendingTransactionUpdated.State.DROPPED) { + PendingTransaction.State state = l.pollTxUpdateState(tx1); + if (state == DROPPED) { break; } if (i == 15) { @@ -627,11 +629,11 @@ public void testIncludedRejected() throws InterruptedException { // the transaction becomes the main chain PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAdded.class, l::onBlock)) - .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); + .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) + .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); - Triple txUpd = null; + Triple txUpd = null; PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); ECKey alice = new ECKey(); @@ -672,7 +674,7 @@ public void testInvalidTransaction() throws InterruptedException { final CountDownLatch txHandle = new CountDownLatch(1); PendingListener l = new PendingListener() { @Override - public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransactionUpdated.State state, Block block) { + public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTransaction.State state, Block block) { assert !txReceipt.isSuccessful(); assert txReceipt.getError().toLowerCase().contains("invalid"); assert txReceipt.getError().toLowerCase().contains("receive address"); @@ -681,9 +683,9 @@ public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTran }; StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BlockAdded.class, l::onBlock)) - .subscribe(to(PendingStateChanged.class, l::onPendingStateChanged)) - .subscribe(to(PendingTransactionUpdated.class, l::onPendingTransactionUpdate)); + .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) + .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); PendingStateImpl pendingState = (PendingStateImpl) bc.getBlockchain().getPendingState(); diff --git a/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java b/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java index 53da13c3dc..cf8d344ab3 100644 --- a/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java +++ b/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java @@ -27,9 +27,8 @@ import org.ethereum.net.rlpx.Node; import org.ethereum.net.server.Channel; import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.PeerAddedToSyncPool; -import org.ethereum.publish.event.SyncDone; import org.ethereum.publish.event.message.EthStatusUpdated; +import org.ethereum.sync.SyncManager; import org.ethereum.sync.SyncPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,8 +42,11 @@ import java.util.Vector; import static java.lang.Thread.sleep; -import static org.ethereum.publish.Subscription.to; -import static org.ethereum.publish.event.SyncDone.State.COMPLETE; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.ETH_STATUS_UPDATED; +import static org.ethereum.publish.event.Events.Type.PEER_ADDED_TO_SYNC_POOL; +import static org.ethereum.publish.event.Events.Type.SYNC_DONE; +import static org.ethereum.sync.SyncManager.State.COMPLETE; /** * BasicNode of ethereum instance @@ -107,10 +109,10 @@ private void springInit() { logger = LoggerFactory.getLogger(loggerName); // adding the main EthereumJ callback to be notified on different kind of events this.ethereum - .subscribe(to(SyncDone.class, this::onSyncDone)) - .subscribe(to(BlockAdded.class, this::onBlock)) - .subscribe(to(EthStatusUpdated.class, this::onEthStatusUpdated)) - .subscribe(to(PeerAddedToSyncPool.class, this::onPeerAddedToSyncPool)); + .subscribe(SYNC_DONE, this::onSyncDone) + .subscribe(BLOCK_ADED, this::onBlock) + .subscribe(ETH_STATUS_UPDATED, this::onEthStatusUpdated) + .subscribe(PEER_ADDED_TO_SYNC_POOL, this::onPeerAddedToSyncPool); logger.info("Sample component created. Listening for ethereum events..."); @@ -162,7 +164,7 @@ public void onSyncDone() throws Exception { logger.info("Monitoring new blocks in real-time..."); } - public void onSyncDoneImpl(SyncDone.State state) { + public void onSyncDoneImpl(SyncManager.State state) { logger.info("onSyncDone: " + state); } @@ -171,13 +173,13 @@ public void onSyncDoneImpl(SyncDone.State state) { protected Block bestBlock = null; - SyncDone.State syncState = null; + SyncManager.State syncState = null; boolean syncComplete = false; /** * The main EthereumJ callback. */ - public void onSyncDone(SyncDone.State state) { + public void onSyncDone(SyncManager.State state) { syncState = state; if (state == COMPLETE) syncComplete = true; onSyncDoneImpl(state); diff --git a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java index 23d6e0e6ab..652518b660 100644 --- a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java @@ -31,7 +31,6 @@ import org.ethereum.db.ContractDetails; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.PendingTransactionUpdated; import org.ethereum.sync.SyncManager; import org.ethereum.util.FastByteComparisons; @@ -53,8 +52,10 @@ import java.util.concurrent.atomic.AtomicLong; import static java.lang.Thread.sleep; +import static org.ethereum.core.PendingTransaction.State.NEW_PENDING; import static org.ethereum.publish.Subscription.to; -import static org.ethereum.publish.event.PendingTransactionUpdated.State.NEW_PENDING; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.PENDING_TRANSACTION_UPDATED; /** * Regular sync with load @@ -227,8 +228,8 @@ public RegularNode() { public void run() { try { this.ethereum - .subscribe(to(BlockAdded.class, this::onBlock)) - .subscribe(to(PendingTransactionUpdated.class, this::onPendingTransactionUpdated) + .subscribe(to(BLOCK_ADED, this::onBlock)) + .subscribe(to(PENDING_TRANSACTION_UPDATED, this::onPendingTransactionUpdated) .conditionally(data -> data.getState() == NEW_PENDING)); // Run 1-30 minutes diff --git a/ethereumj-core/src/test/java/org/ethereum/manager/BlockLoaderTest.java b/ethereumj-core/src/test/java/org/ethereum/manager/BlockLoaderTest.java index 5a7fba1796..24f0a8b4e2 100644 --- a/ethereumj-core/src/test/java/org/ethereum/manager/BlockLoaderTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/manager/BlockLoaderTest.java @@ -2,14 +2,13 @@ import org.ethereum.core.Block; import org.ethereum.core.Blockchain; -import org.ethereum.core.EventDispatchThread; import org.ethereum.core.Genesis; import org.ethereum.core.ImportResult; import org.ethereum.db.DbFlushManager; import org.ethereum.listener.CompositeEthereumListener; +import org.ethereum.publish.Publisher; import org.ethereum.validator.BlockHeaderRule; import org.ethereum.validator.BlockHeaderValidator; -import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; @@ -28,7 +27,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; import static java.util.Objects.isNull; import static java.util.stream.Collectors.toList; @@ -104,8 +102,8 @@ public CompositeEthereumListener ethereumListener() { } @Bean - public EventDispatchThread dispatchThread() { - return EventDispatchThread.getDefault(); + public Publisher publisher() { + return Mockito.mock(Publisher.class); } @Bean diff --git a/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java b/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java index 5ee8221f30..0e16f94efa 100644 --- a/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java @@ -30,9 +30,6 @@ import org.ethereum.facade.EthereumFactory; import org.ethereum.net.eth.handler.Eth62; import org.ethereum.net.eth.message.NewBlockMessage; -import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.PendingTransactionUpdated; -import org.ethereum.publish.event.SyncDone; import org.ethereum.util.ByteUtil; import org.junit.BeforeClass; import org.junit.Ignore; @@ -48,8 +45,11 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import static org.ethereum.core.PendingTransaction.State.NEW_PENDING; import static org.ethereum.publish.Subscription.to; -import static org.ethereum.publish.event.PendingTransactionUpdated.State.NEW_PENDING; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.PENDING_TRANSACTION_UPDATED; +import static org.ethereum.publish.event.Events.Type.SYNC_DONE; /** * Long running test @@ -108,7 +108,7 @@ public void startMiningConsumer() throws Exception { Ethereum ethereum2 = EthereumFactory.createEthereum(SysPropConfig2.props, SysPropConfig2.class); final CountDownLatch semaphore = new CountDownLatch(1); - ethereum2.subscribe(to(BlockAdded.class, data -> { + ethereum2.subscribe(BLOCK_ADED, data -> { Block block = data.getBlockSummary().getBlock(); System.err.println("=== New block: " + blockInfo(block)); System.err.println(block); @@ -131,10 +131,10 @@ public void startMiningConsumer() throws Exception { // } // } - })) - .subscribe(to(PendingTransactionUpdated.class, data -> System.err.println("=== Tx: " + data.getReceipt().getTransaction())) + }) + .subscribe(to(PENDING_TRANSACTION_UPDATED, data -> System.err.println("=== Tx: " + data.getReceipt().getTransaction())) .conditionally(data -> data.getState() == NEW_PENDING)) - .subscribe(to(SyncDone.class, syncState -> { + .subscribe(to(SYNC_DONE, syncState -> { semaphore.countDown(); System.err.println("=== Sync Done!"); })); @@ -207,8 +207,8 @@ public void startMiningTest() throws FileNotFoundException, InterruptedException final CountDownLatch semaphore = new CountDownLatch(1); ethereum1 - .subscribe(to(BlockAdded.class, data -> System.out.println("=== New block: " + blockInfo(data.getBlockSummary().getBlock())))) - .subscribe(to(SyncDone.class, syncState -> semaphore.countDown())); + .subscribe(BLOCK_ADED, data -> System.out.println("=== New block: " + blockInfo(data.getBlockSummary().getBlock()))) + .subscribe(SYNC_DONE, syncState -> semaphore.countDown()); // ethereum2.addListener(new EthereumListenerAdapter() { // @Override diff --git a/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java b/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java index d29027b2e5..e3c8b76877 100644 --- a/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java @@ -28,8 +28,6 @@ import org.ethereum.facade.SyncStatus; import org.ethereum.net.eth.handler.Eth62; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.PeerAddedToSyncPool; import org.ethereum.util.FastByteComparisons; import org.ethereum.util.blockchain.EtherUtil; import org.ethereum.util.blockchain.StandaloneBlockchain; @@ -57,6 +55,8 @@ import static java.util.stream.Collectors.toList; import static org.ethereum.crypto.HashUtil.sha3; import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.PEER_ADDED_TO_SYNC_POOL; import static org.ethereum.util.FileUtil.recursiveDelete; import static org.junit.Assert.*; @@ -161,7 +161,7 @@ public void test1() throws InterruptedException { assertTrue(loadedBlocks > 0); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, data -> semaphore.countDown()) + ethereumB.subscribe(to(BLOCK_ADED, data -> semaphore.countDown()) .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks))); semaphore.await(MAX_SECONDS_WAIT, SECONDS); @@ -171,14 +171,14 @@ public void test1() throws InterruptedException { ethereumA.getBlockMiner().startMining(); final CountDownLatch semaphore2 = new CountDownLatch(2); - ethereumB.subscribe(to(BlockAdded.class, data -> { + ethereumB.subscribe(BLOCK_ADED, data -> { if (isBlockNumber(data.getBlockSummary(), loadedBlocks + 2)) { semaphore2.countDown(); ethereumA.getBlockMiner().stopMining(); } - })); + }); - ethereumA.subscribe(to(BlockAdded.class, data -> semaphore2.countDown()) + ethereumA.subscribe(to(BLOCK_ADED, data -> semaphore2.countDown()) .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks + 2))); semaphore2.await(MAX_SECONDS_WAIT, SECONDS); @@ -200,27 +200,27 @@ public void test1() throws InterruptedException { ); tx.sign(sender); final CountDownLatch txSemaphore = new CountDownLatch(1); - ethereumA.subscribe(to(BlockAdded.class, data -> { + ethereumA.subscribe(BLOCK_ADED, data -> { BlockSummary blockSummary = data.getBlockSummary(); if (!blockSummary.getBlock().getTransactionsList().isEmpty() && FastByteComparisons.equal(blockSummary.getBlock().getTransactionsList().get(0).getSender(), sender.getAddress()) && blockSummary.getReceipts().get(0).isSuccessful()) { txSemaphore.countDown(); } - })); + }); ethereumB.submitTransaction(tx); final CountDownLatch semaphore3 = new CountDownLatch(2); - ethereumB.subscribe(to(BlockAdded.class, data -> semaphore3.countDown()) + ethereumB.subscribe(to(BLOCK_ADED, data -> semaphore3.countDown()) .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks + 5))); - ethereumA.subscribe(to(BlockAdded.class, data -> { + ethereumA.subscribe(BLOCK_ADED, data -> { if (isBlockNumber(data.getBlockSummary(), loadedBlocks + 5)) { semaphore3.countDown(); ethereumA.getBlockMiner().stopMining(); } - })); + }); ethereumA.getBlockMiner().startMining(); semaphore3.await(MAX_SECONDS_WAIT, SECONDS); @@ -252,14 +252,14 @@ public void test1() throws InterruptedException { final CountDownLatch semaphore4 = new CountDownLatch(2); - ethereumB.subscribe(to(BlockAdded.class, data -> { + ethereumB.subscribe(BLOCK_ADED, data -> { if (isBlockNumber(data.getBlockSummary(), loadedBlocks + 9)) { semaphore4.countDown(); ethereumA.getBlockMiner().stopMining(); } - })); + }); - ethereumA.subscribe(to(BlockAdded.class, data -> semaphore4.countDown()) + ethereumA.subscribe(to(BLOCK_ADED, data -> semaphore4.countDown()) .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks + 9))); semaphore4.await(MAX_SECONDS_WAIT, SECONDS); @@ -280,7 +280,7 @@ private void setupPeers() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(PeerAddedToSyncPool.class, channel -> semaphore.countDown())); + ethereumB.subscribe(PEER_ADDED_TO_SYNC_POOL, channel -> semaphore.countDown()); ethereumB.connect(nodeA); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java b/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java index 6441e6bd3a..51484be998 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java @@ -31,8 +31,6 @@ import org.ethereum.net.eth.message.GetBlockBodiesMessage; import org.ethereum.net.eth.message.GetBlockHeadersMessage; import org.ethereum.net.server.Channel; -import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.message.EthStatusUpdated; import org.ethereum.util.RLP; import org.junit.Ignore; import org.junit.Test; @@ -52,7 +50,8 @@ import static java.lang.Math.max; import static java.lang.Math.min; import static org.ethereum.crypto.HashUtil.sha3; -import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.ETH_STATUS_UPDATED; /** * Created by Anton Nashatyrev on 13.10.2015. @@ -226,17 +225,17 @@ protected void processGetBlockBodies(GetBlockBodiesMessage msg) { final CountDownLatch semaphore = new CountDownLatch(1); final Channel[] channel1 = new Channel[1]; - ethereum1.subscribe(to(EthStatusUpdated.class, data -> { + ethereum1.subscribe(ETH_STATUS_UPDATED, data -> { channel1[0] = data.getChannel(); System.out.println("==== Got the Channel: " + data.getChannel()); - })); + }); - ethereum2.subscribe(to(BlockAdded.class, data -> { + ethereum2.subscribe(BLOCK_ADED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.getNumber() == 4) { semaphore.countDown(); } - })); + }); System.out.println("======= Waiting for block #4"); semaphore.await(60, TimeUnit.SECONDS); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java b/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java index 10e300da8a..c56b102e46 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/eth/handler/LockBlockchainTest.java @@ -23,12 +23,13 @@ import org.ethereum.core.BlockHeader; import org.ethereum.core.Blockchain; import org.ethereum.core.BlockchainImpl; +import org.ethereum.core.EventDispatchThread; import org.ethereum.db.BlockStore; import org.ethereum.db.BlockStoreDummy; import org.ethereum.net.eth.message.EthMessage; import org.ethereum.net.eth.message.GetBlockBodiesMessage; import org.ethereum.net.eth.message.GetBlockHeadersMessage; -import org.ethereum.listener.BackwardCompatibilityEthereumListenerProxy; +import org.ethereum.publish.Publisher; import org.ethereum.sync.SyncManager; import org.junit.Before; import org.junit.Test; @@ -95,8 +96,8 @@ public synchronized boolean isBlockExist(byte[] hash) { } }; - SysPropConfig1.testHandler = new Eth62(SysPropConfig1.props, blockchain, blockStoreDummy, - BackwardCompatibilityEthereumListenerProxy.createDefault()) { + Publisher publisher = new Publisher(EventDispatchThread.getDefault()); + SysPropConfig1.testHandler = new Eth62(SysPropConfig1.props, blockchain, blockStoreDummy, publisher) { { this.blockstore = blockStoreDummy; this.syncManager = Mockito.mock(SyncManager.class); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/FramingTest.java b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/FramingTest.java index 5867971f5d..f82762c5d0 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/FramingTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/FramingTest.java @@ -23,7 +23,6 @@ import org.ethereum.facade.EthereumFactory; import org.ethereum.net.eth.message.StatusMessage; import org.ethereum.net.message.Message; -import org.ethereum.publish.event.message.MessageReceived; import org.junit.Ignore; import org.junit.Test; import org.springframework.context.annotation.Bean; @@ -34,7 +33,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.MESSAGE_RECEIVED; /** * Created by Anton Nashatyrev on 13.10.2015. @@ -99,19 +98,19 @@ public void testTest() throws FileNotFoundException, InterruptedException { final CountDownLatch semaphore = new CountDownLatch(2); - ethereum1.subscribe(to(MessageReceived.class, messageData -> { + ethereum1.subscribe(MESSAGE_RECEIVED, messageData -> { if (messageData.getMessage() instanceof StatusMessage) { System.out.println("1: -> " + messageData.getMessage()); semaphore.countDown(); } - })); - ethereum2.subscribe(to(MessageReceived.class, messageData -> { + }); + ethereum2.subscribe(MESSAGE_RECEIVED, messageData -> { Message message = messageData.getMessage(); if (message instanceof StatusMessage) { System.out.println("2: -> " + message); semaphore.countDown(); } - })); + }); ethereum2.connect(new Node("enode://a560c55a0a5b5d137c638eb6973812f431974e4398c6644fa0c19181954fab530bb2a1e2c4eec7cc855f6bab9193ea41d6cf0bf2b8b41ed6b8b9e09c072a1e5a" + "@localhost:30334")); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java index 7605e97ece..35758805eb 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java @@ -27,8 +27,6 @@ import org.ethereum.net.message.Message; import org.ethereum.net.shh.MessageWatcher; import org.ethereum.net.shh.WhisperMessage; -import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.message.MessageReceived; import org.junit.Ignore; import org.junit.Test; import org.spongycastle.util.encoders.Hex; @@ -41,6 +39,8 @@ import java.util.concurrent.atomic.AtomicInteger; import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.MESSAGE_RECEIVED; /** * Created by Anton Nashatyrev on 13.10.2015. @@ -112,13 +112,13 @@ public void testTest() throws FileNotFoundException, InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); - ethereum2.subscribe(to(MessageReceived.class, messageData -> { + ethereum2.subscribe(MESSAGE_RECEIVED, messageData -> { Message message = messageData.getMessage(); if (message instanceof StatusMessage) { System.out.println("=== Status received: " + message); semaphore.countDown(); } - })); + }); semaphore.await(60, TimeUnit.SECONDS); if(semaphore.getCount() > 0) { @@ -129,7 +129,7 @@ public void testTest() throws FileNotFoundException, InterruptedException { final CountDownLatch semaphoreFirstBlock = new CountDownLatch(1); AtomicInteger blocksCnt = new AtomicInteger(); - ethereum2.subscribe(to(BlockAdded.class, data -> { + ethereum2.subscribe(BLOCK_ADED, data -> { blocksCnt.addAndGet(1); if (blocksCnt.get() % 1000 == 0 || blocksCnt.get() == 1) { System.out.println("=== Blocks imported: " + blocksCnt); @@ -141,7 +141,7 @@ public void testTest() throws FileNotFoundException, InterruptedException { semaphoreBlocks.countDown(); System.out.println("=== Blocks task done."); } - })); + }); semaphoreFirstBlock.await(180, TimeUnit.SECONDS); if(semaphoreFirstBlock.getCount() > 0) { diff --git a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SnappyConnectionTest.java b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SnappyConnectionTest.java index ead4868115..007aab978b 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SnappyConnectionTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SnappyConnectionTest.java @@ -21,7 +21,6 @@ import org.ethereum.config.SystemProperties; import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumFactory; -import org.ethereum.publish.event.message.EthStatusUpdated; import org.junit.Ignore; import org.junit.Test; import org.springframework.context.annotation.Bean; @@ -31,7 +30,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.ETH_STATUS_UPDATED; /** * @author Mikhail Kalinin @@ -99,14 +98,14 @@ private void runScenario(int vOutbound, int vInbound) throws FileNotFoundExcepti final CountDownLatch semaphore = new CountDownLatch(2); - ethereum1.subscribe(to(EthStatusUpdated.class, data -> { + ethereum1.subscribe(ETH_STATUS_UPDATED, data -> { System.out.println("1: -> " + data.getMessage()); semaphore.countDown(); - })); - ethereum2.subscribe(to(EthStatusUpdated.class, data -> { + }); + ethereum2.subscribe(ETH_STATUS_UPDATED, data -> { System.out.println("2: -> " + data.getMessage()); semaphore.countDown(); - })); + }); ethereum2.connect(new Node("enode://a560c55a0a5b5d137c638eb6973812f431974e4398c6644fa0c19181954fab530bb2a1e2c4eec7cc855f6bab9193ea41d6cf0bf2b8b41ed6b8b9e09c072a1e5a" + "@localhost:30334")); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/shh/ShhLongRun.java b/ethereumj-core/src/test/java/org/ethereum/net/shh/ShhLongRun.java index 91a487fff2..8dc6a55a5f 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/shh/ShhLongRun.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/shh/ShhLongRun.java @@ -23,7 +23,6 @@ import org.ethereum.facade.EthereumFactory; import org.ethereum.manager.WorldManager; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.message.PeerHandshaked; import org.junit.Ignore; import org.junit.Test; import org.spongycastle.util.encoders.Hex; @@ -40,6 +39,7 @@ import java.util.List; import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.PEER_HANDSHAKED; /** * This is not a JUnit test but rather a long running standalone test for messages exchange with another peer. @@ -110,12 +110,12 @@ public TestComponent() { @PostConstruct void init() { System.out.println("========= init"); - worldManager.getPublisher().subscribe(to(PeerHandshaked.class, data -> { + worldManager.getPublisher().subscribe(PEER_HANDSHAKED, data -> { System.out.println("========= onHandShakePeer"); if (!isAlive()) { start(); } - })); + }); } static class MessageMatcher extends MessageWatcher { diff --git a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java index d66f64cd81..172b120795 100644 --- a/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/publish/PublisherTest.java @@ -59,7 +59,7 @@ public void testSingleEvent() { final List strings = new ArrayList<>(); int subscribersCount = createPublisher() - .subscribe(to(Events.OneOffStringEvent.class, s -> strings.add(s))) + .subscribe(Events.OneOffStringEvent.class, s -> strings.add(s)) .publish(new Events.OneOffStringEvent(payload)) .subscribersCount(Events.OneOffStringEvent.class); diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java index 37deeb955d..54f9358c14 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java @@ -31,12 +31,6 @@ import org.ethereum.net.eth.message.*; import org.ethereum.net.message.Message; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.PeerAddedToSyncPool; -import org.ethereum.publish.event.SyncDone; -import org.ethereum.publish.event.message.EthStatusUpdated; -import org.ethereum.publish.event.message.MessageReceived; -import org.ethereum.publish.event.message.MessageSent; import org.ethereum.util.ByteUtil; import org.junit.Ignore; import org.junit.Test; @@ -55,6 +49,12 @@ import java.util.concurrent.atomic.AtomicInteger; import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.ETH_STATUS_UPDATED; +import static org.ethereum.publish.event.Events.Type.MESSAGE_RECEIVED; +import static org.ethereum.publish.event.Events.Type.MESSAGE_SENT; +import static org.ethereum.publish.event.Events.Type.PEER_ADDED_TO_SYNC_POOL; +import static org.ethereum.publish.event.Events.Type.SYNC_DONE; /** * Long running test @@ -121,15 +121,15 @@ private void springInit() { logger = LoggerFactory.getLogger(loggerName); // adding the main EthereumJ callback to be notified on different kind of events this.ethereum - .subscribe(to(SyncDone.class, syncState -> synced = true)) - .subscribe(to(EthStatusUpdated.class, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage()))) - .subscribe(to(PeerAddedToSyncPool.class, peer -> syncPeers.add(peer.getNode()))) - .subscribe(to(BlockAdded.class, data -> { + .subscribe(SYNC_DONE, syncState -> synced = true) + .subscribe(ETH_STATUS_UPDATED, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage())) + .subscribe(PEER_ADDED_TO_SYNC_POOL, peer -> syncPeers.add(peer.getNode())) + .subscribe(BLOCK_ADED, data -> { bestBlock = data.getBlockSummary().getBlock(); if (syncComplete) { logger.info("New block: " + bestBlock.getShortDescr()); } - })); + }); logger.info("Sample component created. Listening for ethereum events..."); @@ -482,13 +482,13 @@ public void testTest() throws Exception { Ethereum miner = EthereumFactory.createEthereum(MinerConfig.class); miner - .subscribe(to(BlockAdded.class, data -> { + .subscribe(BLOCK_ADED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.getNumber() != 0L) { blocks.put(Hex.toHexString(block.getHash()), Boolean.FALSE); } - })) - .subscribe(to(MessageReceived.class, messageData -> { + }) + .subscribe(MESSAGE_RECEIVED, messageData -> { Message message = messageData.getMessage(); if (!(message instanceof EthMessage)) return; switch (((EthMessage) message).getCommand()) { @@ -512,7 +512,7 @@ public void testTest() throws Exception { default: break; } - })); + }); testLogger.info("Starting EthereumJ regular instance!"); EthereumFactory.createEthereum(RegularConfig.class); @@ -520,7 +520,7 @@ public void testTest() throws Exception { testLogger.info("Starting EthereumJ txSender instance!"); Ethereum txGenerator = EthereumFactory.createEthereum(GeneratorConfig.class); txGenerator - .subscribe(to(MessageReceived.class, messageData -> { + .subscribe(to(MESSAGE_RECEIVED, messageData -> { Message message = messageData.getMessage(); if (!(message instanceof EthMessage)) return; switch (((EthMessage) message).getCommand()) { @@ -555,7 +555,7 @@ public void testTest() throws Exception { } })) - .subscribe(to(MessageSent.class, messageData -> { + .subscribe(to(MESSAGE_SENT, messageData -> { Message message = messageData.getMessage(); if (!(message instanceof EthMessage)) return; if (((EthMessage) message).getCommand().equals(EthMessageCodes.TRANSACTIONS)) { diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java index f9e519e739..0e99a1ad08 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java @@ -33,10 +33,6 @@ import org.ethereum.net.eth.message.GetBlockHeadersMessage; import org.ethereum.net.p2p.DisconnectMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.PeerAddedToSyncPool; -import org.ethereum.publish.event.message.EthStatusUpdated; -import org.ethereum.publish.event.message.MessageReceived; import org.ethereum.util.blockchain.StandaloneBlockchain; import org.junit.*; import org.springframework.context.annotation.Bean; @@ -54,7 +50,10 @@ import java.util.concurrent.CountDownLatch; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.ETH_STATUS_UPDATED; +import static org.ethereum.publish.event.Events.Type.MESSAGE_RECEIVED; +import static org.ethereum.publish.event.Events.Type.PEER_ADDED_TO_SYNC_POOL; import static org.ethereum.util.FileUtil.recursiveDelete; import static org.junit.Assert.fail; import static org.spongycastle.util.encoders.Hex.decode; @@ -161,11 +160,11 @@ public void test1() throws InterruptedException { // A == b10, B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, data -> { + ethereumB.subscribe(BLOCK_ADED, data -> { if (data.getBlockSummary().getBlock().isEqual(b10)) { semaphore.countDown(); } - })); + }); semaphore.await(40, SECONDS); @@ -198,11 +197,11 @@ protected void processGetBlockBodies(GetBlockBodiesMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(MessageReceived.class, messageData -> { + ethereumA.subscribe(MESSAGE_RECEIVED, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } - })); + }); semaphoreDisconnect.await(10, SECONDS); @@ -245,11 +244,11 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(MessageReceived.class, messageData -> { + ethereumA.subscribe(MESSAGE_RECEIVED, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } - })); + }); semaphoreDisconnect.await(10, SECONDS); @@ -287,11 +286,11 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(MessageReceived.class, messageData -> { + ethereumA.subscribe(MESSAGE_RECEIVED, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } - })); + }); semaphoreDisconnect.await(10, SECONDS); @@ -333,11 +332,11 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(MessageReceived.class, messageData -> { + ethereumA.subscribe(MESSAGE_RECEIVED, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } - })); + }); semaphoreDisconnect.await(10, SECONDS); @@ -383,11 +382,11 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(MessageReceived.class, messageData -> { + ethereumA.subscribe(MESSAGE_RECEIVED, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } - })); + }); semaphoreDisconnect.await(10, SECONDS); @@ -429,11 +428,11 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(MessageReceived.class, messageData -> { + ethereumA.subscribe(MESSAGE_RECEIVED, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } - })); + }); semaphoreDisconnect.await(10, SECONDS); @@ -476,11 +475,11 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b10, B == genesis final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(MessageReceived.class, messageData -> { + ethereumA.subscribe(MESSAGE_RECEIVED, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } - })); + }); semaphoreDisconnect.await(10, SECONDS); @@ -508,11 +507,11 @@ private void setupPeers(Block best) throws InterruptedException { // A == best ethereumB = EthereumFactory.createEthereum(SysPropConfigB.props, SysPropConfigB.class); - ethereumA.subscribe(to(EthStatusUpdated.class, data -> ethA = (EthHandler) data.getChannel().getEthHandler())); + ethereumA.subscribe(ETH_STATUS_UPDATED, data -> ethA = (EthHandler) data.getChannel().getEthHandler()); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(PeerAddedToSyncPool.class, channel -> semaphore.countDown())); + ethereumB.subscribe(PEER_ADDED_TO_SYNC_POOL, channel -> semaphore.countDown()); ethereumB.connect(nodeA); semaphore.await(10, SECONDS); diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java index ae51aed0a3..fd19fbdf57 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java @@ -30,10 +30,6 @@ import org.ethereum.net.eth.message.*; import org.ethereum.net.p2p.DisconnectMessage; import org.ethereum.net.rlpx.Node; -import org.ethereum.publish.event.BlockAdded; -import org.ethereum.publish.event.PeerAddedToSyncPool; -import org.ethereum.publish.event.message.EthStatusUpdated; -import org.ethereum.publish.event.message.MessageReceived; import org.ethereum.util.blockchain.StandaloneBlockchain; import org.junit.*; import org.springframework.context.annotation.Bean; @@ -55,6 +51,10 @@ import static java.util.concurrent.TimeUnit.SECONDS; import static org.ethereum.publish.Subscription.to; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.ETH_STATUS_UPDATED; +import static org.ethereum.publish.event.Events.Type.MESSAGE_RECEIVED; +import static org.ethereum.publish.event.Events.Type.PEER_ADDED_TO_SYNC_POOL; import static org.ethereum.util.FileUtil.recursiveDelete; import static org.junit.Assert.fail; import static org.spongycastle.util.encoders.Hex.decode; @@ -160,7 +160,7 @@ public void test1() throws InterruptedException { // A == b10, B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, data -> semaphore.countDown()) + ethereumB.subscribe(to(BLOCK_ADED, data -> semaphore.countDown()) .conditionally(data -> data.getBlockSummary().getBlock().isEqual(b10))); ethA.sendNewBlock(b10); @@ -192,7 +192,7 @@ public void test2() throws InterruptedException { // A == b8', B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, data -> semaphore.countDown()) + ethereumB.subscribe(to(BLOCK_ADED, data -> semaphore.countDown()) .conditionally(data -> data.getBlockSummary().getBlock().isEqual(b8_))); ethA.sendNewBlock(b8_); @@ -228,12 +228,12 @@ public void test3() throws InterruptedException { // A == b10, B == b8' final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, data -> { + ethereumB.subscribe(BLOCK_ADED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); } - })); + }); ethA.sendNewBlock(b10); @@ -273,7 +273,7 @@ public void test4() throws InterruptedException { // A == b5, B == b9 final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, blockSummary -> semaphore.countDown()) + ethereumB.subscribe(to(BLOCK_ADED, blockSummary -> semaphore.countDown()) .conditionally(data -> data.getBlockSummary().getBlock().equals(b10))); ethA.sendNewBlockHashes(b5); @@ -322,7 +322,7 @@ public void test5() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB8_ = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, data -> { + ethereumB.subscribe(BLOCK_ADED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -330,7 +330,7 @@ public void test5() throws InterruptedException { if (block.isEqual(b8_)) { semaphoreB8_.countDown(); } - })); + }); ethA.sendNewBlockHashes(b8_); @@ -382,7 +382,7 @@ public void test6() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB7 = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, data -> { + ethereumB.subscribe(BLOCK_ADED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b7)) { semaphoreB7.countDown(); @@ -390,7 +390,7 @@ public void test6() throws InterruptedException { if (block.isEqual(b10)) { semaphore.countDown(); } - })); + }); ethA.sendNewBlockHashes(b7); @@ -442,7 +442,7 @@ public void test7() throws InterruptedException { // A == b8', B == b4 - ethereumB.subscribe(to(MessageReceived.class, data -> { + ethereumB.subscribe(MESSAGE_RECEIVED, data -> { if (data.getMessage() instanceof NewBlockMessage) { // it's time to do a re-branch for (Block b : mainB1B10) { @@ -450,15 +450,15 @@ public void test7() throws InterruptedException { } } - })); + }); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, data -> { + ethereumB.subscribe(BLOCK_ADED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); } - })); + }); ethA.sendNewBlock(b8_); ethA.sendNewBlock(b10); @@ -501,7 +501,7 @@ public void test8() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB7_ = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, data -> { + ethereumB.subscribe(BLOCK_ADED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b7_)) { // it's time to do a re-branch @@ -514,7 +514,7 @@ public void test8() throws InterruptedException { if (block.isEqual(b10)) { semaphore.countDown(); } - })); + }); ethA.sendNewBlockHashes(b7_); @@ -583,11 +583,11 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { ethA.sendNewBlock(b8_); final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(MessageReceived.class, messageData -> { + ethereumA.subscribe(MESSAGE_RECEIVED, messageData -> { if (messageData.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } - })); + }); semaphoreDisconnect.await(10, SECONDS); @@ -604,16 +604,16 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { } final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, data -> { + ethereumB.subscribe(BLOCK_ADED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); } - })); + }); final CountDownLatch semaphoreConnect = new CountDownLatch(1); - ethereumB.subscribe(to(PeerAddedToSyncPool.class, channel -> semaphoreConnect.countDown())); + ethereumB.subscribe(PEER_ADDED_TO_SYNC_POOL, channel -> semaphoreConnect.countDown()); ethereumB.connect(nodeA); // await connection @@ -681,11 +681,11 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { ethA.sendNewBlockHashes(b8_); final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(MessageReceived.class, data -> { + ethereumA.subscribe(MESSAGE_RECEIVED, data -> { if (data.getMessage() instanceof DisconnectMessage) { semaphoreDisconnect.countDown(); } - })); + }); semaphoreDisconnect.await(10, SECONDS); @@ -699,15 +699,15 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { LongSyncTest.SysPropConfigA.eth62 = null; final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, data -> { + ethereumB.subscribe(BLOCK_ADED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); } - })); + }); final CountDownLatch semaphoreConnect = new CountDownLatch(1); - ethereumB.subscribe(to(PeerAddedToSyncPool.class, channel -> semaphoreConnect.countDown())); + ethereumB.subscribe(PEER_ADDED_TO_SYNC_POOL, channel -> semaphoreConnect.countDown()); ethereumB.connect(nodeA); // await connection @@ -760,7 +760,7 @@ public void test11() throws InterruptedException { final CountDownLatch semaphore1 = new CountDownLatch(1); final CountDownLatch semaphore2 = new CountDownLatch(1); - ethereumB.subscribe(to(BlockAdded.class, data -> { + ethereumB.subscribe(BLOCK_ADED, data -> { if (data.getBlockSummary().getBlock().isEqual(b6_)) { if (semaphore1.getCount() > 0) { semaphore1.countDown(); @@ -768,7 +768,7 @@ public void test11() throws InterruptedException { semaphore2.countDown(); } } - })); + }); ethA.sendNewBlock(b6_); semaphore1.await(10, SECONDS); @@ -823,7 +823,7 @@ protected void processGetBlockBodies(GetBlockBodiesMessage msg) { final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); this.ethereumA - .subscribe(to(MessageReceived.class, data -> semaphoreDisconnect.countDown()) + .subscribe(to(MESSAGE_RECEIVED, data -> semaphoreDisconnect.countDown()) .conditionally(data -> data.getMessage() instanceof DisconnectMessage)); ethA.sendNewBlock(b10); @@ -882,7 +882,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b8', B == b10 final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(MessageReceived.class, data -> semaphoreDisconnect.countDown()) + ethereumA.subscribe(to(MESSAGE_RECEIVED, data -> semaphoreDisconnect.countDown()) .conditionally(data -> data.getMessage() instanceof DisconnectMessage)); ethA.sendNewBlockHashes(b8_); @@ -942,7 +942,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { // A == b8', B == b10 final CountDownLatch semaphoreDisconnect = new CountDownLatch(1); - ethereumA.subscribe(to(MessageReceived.class, data -> semaphoreDisconnect.countDown()) + ethereumA.subscribe(to(MESSAGE_RECEIVED, data -> semaphoreDisconnect.countDown()) .conditionally(data -> data.getMessage() instanceof DisconnectMessage)); ethA.sendNewBlockHashes(b8_); @@ -960,11 +960,11 @@ private void setupPeers() throws InterruptedException { ethereumA = EthereumFactory.createEthereum(SysPropConfigA.props, SysPropConfigA.class); ethereumB = EthereumFactory.createEthereum(SysPropConfigB.props, SysPropConfigB.class); - ethereumA.subscribe(to(EthStatusUpdated.class, data -> ethA = (EthHandler) data.getChannel().getEthHandler())); + ethereumA.subscribe(ETH_STATUS_UPDATED, data -> ethA = (EthHandler) data.getChannel().getEthHandler()); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(PeerAddedToSyncPool.class, channel -> semaphore.countDown())); + ethereumB.subscribe(PEER_ADDED_TO_SYNC_POOL, channel -> semaphore.countDown()); ethereumB.connect(nodeA); semaphore.await(10, SECONDS); diff --git a/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java b/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java index 4bb7dd3353..4d72456822 100644 --- a/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/validator/EthashRuleTest.java @@ -13,7 +13,7 @@ import static org.ethereum.publish.event.Events.onBlockAdded; import static org.ethereum.publish.event.Events.onSyncDone; -import static org.ethereum.publish.event.SyncDone.State.COMPLETE; +import static org.ethereum.sync.SyncManager.State.COMPLETE; import static org.ethereum.validator.BlockHeaderRule.Success; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; From 3bd0f73fd3808569b719b45ea6468439dc86a82c Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Mon, 8 Oct 2018 15:13:27 +0300 Subject: [PATCH 24/28] Develop merge --- ethereumj-core/build.gradle | 2 +- .../main/java/org/ethereum/solidity/Abi.java | 1 + .../org/ethereum/solidity/SolidityType.java | 76 ++++++++++++++----- .../util/blockchain/StandaloneBlockchain.java | 11 ++- .../org/ethereum/vm/PrecompiledContracts.java | 7 +- .../src/main/java/org/ethereum/vm/VM.java | 9 ++- .../main/java/org/ethereum/vm/VMUtils.java | 7 ++ .../ethereum/config/DaoLightMiningTest.java | 2 +- .../org/ethereum/core/ImportLightTest.java | 17 +++-- .../org/ethereum/core/TransactionTest.java | 8 +- .../ethereum/solidity/SolidityTypeTest.java | 53 +++++++++++++ .../java/org/ethereum/util/HashUtilTest.java | 39 ++++++++++ .../util/StandaloneBlockchainTest.java | 18 ++++- 13 files changed, 208 insertions(+), 42 deletions(-) create mode 100644 ethereumj-core/src/test/java/org/ethereum/solidity/SolidityTypeTest.java diff --git a/ethereumj-core/build.gradle b/ethereumj-core/build.gradle index 93c4123933..ca9eeb2f5d 100644 --- a/ethereumj-core/build.gradle +++ b/ethereumj-core/build.gradle @@ -130,7 +130,7 @@ dependencies { compile "org.ethereum:rocksdbjni:5.9.2" // RocksDB Java API - compile "org.ethereum:solcJ-all:0.4.19" // Solidity Compiler win/mac/linux binaries + compile "org.ethereum:solcJ-all:0.4.25" // Solidity Compiler win/mac/linux binaries compile "com.google.guava:guava:24.1-jre" diff --git a/ethereumj-core/src/main/java/org/ethereum/solidity/Abi.java b/ethereumj-core/src/main/java/org/ethereum/solidity/Abi.java index d795602fe4..120edda378 100644 --- a/ethereumj-core/src/main/java/org/ethereum/solidity/Abi.java +++ b/ethereumj-core/src/main/java/org/ethereum/solidity/Abi.java @@ -172,6 +172,7 @@ public static Entry create(@JsonProperty("anonymous") boolean anonymous, result = new Constructor(inputs, outputs); break; case function: + case fallback: result = new Function(constant, name, inputs, outputs, payable); break; case event: diff --git a/ethereumj-core/src/main/java/org/ethereum/solidity/SolidityType.java b/ethereumj-core/src/main/java/org/ethereum/solidity/SolidityType.java index 5393aa80a8..b814415af9 100644 --- a/ethereumj-core/src/main/java/org/ethereum/solidity/SolidityType.java +++ b/ethereumj-core/src/main/java/org/ethereum/solidity/SolidityType.java @@ -58,7 +58,8 @@ public String getCanonicalName() { public static SolidityType getType(String typeName) { if (typeName.contains("[")) return ArrayType.getType(typeName); if ("bool".equals(typeName)) return new BoolType(); - if (typeName.startsWith("int") || typeName.startsWith("uint")) return new IntType(typeName); + if (typeName.startsWith("int")) return new IntType(typeName); + if (typeName.startsWith("uint")) return new UnsignedIntType(typeName); if ("address".equals(typeName)) return new AddressType(); if ("string".equals(typeName)) return new StringType(); if ("bytes".equals(typeName)) return new BytesType(); @@ -356,23 +357,14 @@ public Object decode(byte[] encoded, int offset) { return ByteUtil.bigIntegerToBytes(bi, 20); } } - - public static class IntType extends SolidityType { - public IntType(String name) { + + public static abstract class NumericType extends SolidityType { + public NumericType(String name) { super(name); } - @Override - public String getCanonicalName() { - if (getName().equals("int")) return "int256"; - if (getName().equals("uint")) return "uint256"; - return super.getCanonicalName(); - } - - @Override - public byte[] encode(Object value) { + BigInteger encodeInternal(Object value) { BigInteger bigInt; - if (value instanceof String) { String s = ((String)value).toLowerCase().trim(); int radix = 10; @@ -393,14 +385,20 @@ public byte[] encode(Object value) { } else { throw new RuntimeException("Invalid value for type '" + this + "': " + value + " (" + value.getClass() + ")"); } - return encodeInt(bigInt); + return bigInt; + } + } + + public static class IntType extends NumericType { + public IntType(String name) { + super(name); } @Override - public Object decode(byte[] encoded, int offset) { - return decodeInt(encoded, offset); + public String getCanonicalName() { + if (getName().equals("int")) return "int256"; + return super.getCanonicalName(); } - public static BigInteger decodeInt(byte[] encoded, int offset) { return new BigInteger(Arrays.copyOfRange(encoded, offset, offset + 32)); } @@ -410,6 +408,48 @@ public static byte[] encodeInt(int i) { public static byte[] encodeInt(BigInteger bigInt) { return ByteUtil.bigIntegerToBytesSigned(bigInt, 32); } + @Override + public Object decode(byte[] encoded, int offset) { + return decodeInt(encoded, offset); + } + @Override + public byte[] encode(Object value) { + BigInteger bigInt = encodeInternal(value); + return encodeInt(bigInt); + } + } + + public static class UnsignedIntType extends NumericType { + public UnsignedIntType(String name) { + super(name); + } + + @Override + public String getCanonicalName() { + if (getName().equals("uint")) return "uint256"; + return super.getCanonicalName(); + } + public static BigInteger decodeInt(byte[] encoded, int offset) { + return new BigInteger(1, Arrays.copyOfRange(encoded, offset, offset + 32)); + } + public static byte[] encodeInt(int i) { + return encodeInt(new BigInteger("" + i)); + } + public static byte[] encodeInt(BigInteger bigInt) { + if (bigInt.signum() == -1) { + throw new RuntimeException("Wrong value for uint type: " + bigInt); + } + return ByteUtil.bigIntegerToBytes(bigInt, 32); + } + @Override + public byte[] encode(Object value) { + BigInteger bigInt = encodeInternal(value); + return encodeInt(bigInt); + } + @Override + public Object decode(byte[] encoded, int offset) { + return decodeInt(encoded, offset); + } } public static class BoolType extends IntType { diff --git a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java index 23a03d8598..c9ec797635 100644 --- a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java @@ -17,9 +17,14 @@ */ package org.ethereum.util.blockchain; +import org.ethereum.config.BlockchainConfig; import org.ethereum.config.BlockchainNetConfig; import org.ethereum.config.SystemProperties; +import org.ethereum.config.blockchain.ByzantiumConfig; +import org.ethereum.config.blockchain.DaoHFConfig; +import org.ethereum.config.blockchain.DaoNoHFConfig; import org.ethereum.config.blockchain.FrontierConfig; +import org.ethereum.config.blockchain.HomesteadConfig; import org.ethereum.core.*; import org.ethereum.core.genesis.GenesisLoader; import org.ethereum.crypto.ECKey; @@ -767,12 +772,12 @@ public synchronized void updateBatch(Map rows) { } // Override blockchain net config for fast mining - public static FrontierConfig getEasyMiningConfig() { - return new FrontierConfig(new FrontierConfig.FrontierConstants() { + public static ByzantiumConfig getEasyMiningConfig() { + return new ByzantiumConfig(new DaoNoHFConfig(new HomesteadConfig(new HomesteadConfig.HomesteadConstants() { @Override public BigInteger getMINIMUM_DIFFICULTY() { return BigInteger.ONE; } - }); + }), 0)); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/PrecompiledContracts.java b/ethereumj-core/src/main/java/org/ethereum/vm/PrecompiledContracts.java index 562b75e42a..4feb782cb2 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/PrecompiledContracts.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/PrecompiledContracts.java @@ -30,6 +30,7 @@ import static org.ethereum.util.BIUtil.isLessThan; import static org.ethereum.util.BIUtil.isZero; import static org.ethereum.util.ByteUtil.*; +import static org.ethereum.vm.VMUtils.getSizeInWords; /** * @author Roman Mandeleil @@ -102,7 +103,7 @@ public long getGasForData(byte[] data) { // gas charge for the execution: // minimum 1 and additional 1 for each 32 bytes word (round up) if (data == null) return 15; - return 15 + (data.length + 31) / 32 * 3; + return 15 + getSizeInWords(data.length) * 3; } @Override @@ -120,7 +121,7 @@ public long getGasForData(byte[] data) { // gas charge for the execution: // minimum 50 and additional 50 for each 32 bytes word (round up) if (data == null) return 60; - return 60 + (data.length + 31) / 32 * 12; + return 60 + getSizeInWords(data.length) * 12; } @Override @@ -142,7 +143,7 @@ public long getGasForData(byte[] data) { // gas charge for the execution: // minimum 50 and additional 50 for each 32 bytes word (round up) if (data == null) return 600; - return 600 + (data.length + 31) / 32 * 120; + return 600 + getSizeInWords(data.length) * 120; } @Override diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/VM.java b/ethereumj-core/src/main/java/org/ethereum/vm/VM.java index 04619a6181..37101de763 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/VM.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/VM.java @@ -41,6 +41,7 @@ import static org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY; import static org.ethereum.util.ByteUtil.toHexString; import static org.ethereum.vm.OpCode.*; +import static org.ethereum.vm.VMUtils.getSizeInWords; /** * The Ethereum Virtual Machine (EVM) is responsible for initialization @@ -320,7 +321,7 @@ else if (!currentValue.isZero() && newValue.isZero()) { case SHA3: gasCost = gasCosts.getSHA3() + calcMemGas(gasCosts, oldMemSize, memNeeded(stack.peek(), stack.get(stack.size() - 2)), 0); DataWord size = stack.get(stack.size() - 2); - long chunkUsed = (size.longValueSafe() + 31) / 32; + long chunkUsed = getSizeInWords(size.longValueSafe()); gasCost += chunkUsed * gasCosts.getSHA3_WORD(); break; case CALLDATACOPY: @@ -394,8 +395,10 @@ else if (!currentValue.isZero() && newValue.isZero()) { memNeeded(stack.get(stack.size() - 2), stack.get(stack.size() - 3)), 0); break; case CREATE2: - gasCost = gasCosts.getCREATE() + calcMemGas(gasCosts, oldMemSize, - memNeeded(stack.get(stack.size() - 2), stack.get(stack.size() - 3)), 0); + DataWord codeSize = stack.get(stack.size() - 3); + gasCost = gasCosts.getCREATE() + + calcMemGas(gasCosts, oldMemSize, memNeeded(stack.get(stack.size() - 2), codeSize), 0) + + getSizeInWords(codeSize.longValueSafe()) * gasCosts.getSHA3_WORD(); break; case LOG0: case LOG1: diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/VMUtils.java b/ethereumj-core/src/main/java/org/ethereum/vm/VMUtils.java index 252ebcf225..8fe6809aae 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/VMUtils.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/VMUtils.java @@ -153,4 +153,11 @@ public static String unzipAndDecode(String content) { return content; } } + + /** + * Returns number of VM words required to hold data of size {@code size} + */ + public static long getSizeInWords(long size) { + return size == 0 ? 0 : (size - 1) / 32 + 1; + } } diff --git a/ethereumj-core/src/test/java/org/ethereum/config/DaoLightMiningTest.java b/ethereumj-core/src/test/java/org/ethereum/config/DaoLightMiningTest.java index 0d9db20b31..90c4a81a58 100644 --- a/ethereumj-core/src/test/java/org/ethereum/config/DaoLightMiningTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/config/DaoLightMiningTest.java @@ -74,7 +74,7 @@ private String getData(StandaloneBlockchain sb, long blockNumber) { private StandaloneBlockchain createBlockchain(boolean proFork) { final BaseNetConfig netConfig = new BaseNetConfig(); - final FrontierConfig c1 = StandaloneBlockchain.getEasyMiningConfig(); + final BlockchainConfig c1 = StandaloneBlockchain.getEasyMiningConfig(); netConfig.add(0, StandaloneBlockchain.getEasyMiningConfig()); netConfig.add(FORK_BLOCK, proFork ? new DaoHFConfig(c1, FORK_BLOCK) : new DaoNoHFConfig(c1, FORK_BLOCK)); diff --git a/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java b/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java index 2d4d43429d..d891fca0f4 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/ImportLightTest.java @@ -516,7 +516,7 @@ public void operateNotExistingContractTest() throws IOException, InterruptedExce // checking balance of not existed address should take // less that gas limit - Assert.assertEquals(21532, spent); + Assert.assertTrue(spent < 100_000); } { @@ -529,7 +529,10 @@ public void operateNotExistingContractTest() throws IOException, InterruptedExce // invalid jump error occurred // all gas wasted // (for history: it is worked fine in ^0.3.1) - Assert.assertEquals(5_000_000L, spent); + // Assert.assertEquals(5_000_000L, spent); + + // FIX for 0.4.25 and apparently some earlier versions + Assert.assertTrue(spent < 100_000); } } @@ -605,7 +608,7 @@ public void rollbackInternalTx() throws Exception { " uint public b;" + " function f() {" + " b = 1;" + - " this.call(bytes4(sha3('exception()')));" + + " this.call.gas(10000)(bytes4(sha3('exception()')));" + " a = 2;" + " }" + @@ -641,7 +644,7 @@ public void selfdestructAttack() throws Exception { " function f() {" + " B b = new B();" + " for (uint i = 0; i < 3500; i++) {" + - " b.suicide(address(i));" + + " b.suicide.gas(10000)(address(i));" + " }" + " a = 2;" + " }" + @@ -857,12 +860,12 @@ public void functionTypeTest() throws IOException, InterruptedException { "contract A {" + " int public res;" + " function calc(int b, function (int a) external returns (int) f) external returns (int) {" + - " return f(b);" + + " return f.gas(10000)(b);" + " }" + " function fInc(int a) external returns (int) { return a + 1;}" + " function fDec(int a) external returns (int) { return a - 1;}" + " function test() {" + - " res = this.calc(111, this.fInc);" + + " res = this.calc.gas(100000)(111, this.fInc);" + " }" + "}"; @@ -871,7 +874,7 @@ public void functionTypeTest() throws IOException, InterruptedException { bc.createBlock(); a.callFunction("test"); bc.createBlock(); - Assert.assertEquals(a.callConstFunction("res")[0], BigInteger.valueOf(112)); + Assert.assertEquals(BigInteger.valueOf(112), a.callConstFunction("res")[0]); BigInteger r1 = (BigInteger) a.callConstFunction("calc", 222, a.getFunction("fInc"))[0]; Assert.assertEquals(223, r1.intValue()); diff --git a/ethereumj-core/src/test/java/org/ethereum/core/TransactionTest.java b/ethereumj-core/src/test/java/org/ethereum/core/TransactionTest.java index fed322ebe3..bf808643b2 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/TransactionTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/TransactionTest.java @@ -563,10 +563,10 @@ public void multiSuicideTest() throws IOException, InterruptedException { " }" + " function multipleHomocide() {" + " PsychoKiller k = this;" + - " k.homicide();" + - " k.homicide();" + - " k.homicide();" + - " k.homicide();" + + " k.homicide.gas(10000)();" + + " k.homicide.gas(10000)();" + + " k.homicide.gas(10000)();" + + " k.homicide.gas(10000)();" + " }" + "}"; SolidityCompiler.Result res = SolidityCompiler.compile( diff --git a/ethereumj-core/src/test/java/org/ethereum/solidity/SolidityTypeTest.java b/ethereumj-core/src/test/java/org/ethereum/solidity/SolidityTypeTest.java new file mode 100644 index 0000000000..28fe7d4d7d --- /dev/null +++ b/ethereumj-core/src/test/java/org/ethereum/solidity/SolidityTypeTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ +package org.ethereum.solidity; + +import static org.junit.Assert.assertEquals; + +import java.math.BigInteger; + +import org.junit.Test; +import org.spongycastle.util.encoders.Hex; + +/** + * Created by Maximilian Schmidt on 25.09.2018. + */ +public class SolidityTypeTest { + @Test + public void ensureUnsignedInteger_isDecodedWithCorrectSignum() { + byte[] bigNumberByteArray = { -13, -75, 19, 86, -119, 67, 112, -4, 118, -86, 98, -46, 103, -42, -126, 63, -60, -15, -87, 57, 43, 11, -17, -52, + 0, 3, -65, 14, -67, -40, 65, 119 }; + SolidityType testObject = new SolidityType.UnsignedIntType("uint256"); + Object decode = testObject.decode(bigNumberByteArray); + assertEquals(decode.getClass(), BigInteger.class); + BigInteger actualBigInteger = (BigInteger) decode; + BigInteger expectedBigInteger = new BigInteger(Hex.toHexString(bigNumberByteArray), 16); + assertEquals(expectedBigInteger, actualBigInteger); + } + + @Test + public void ensureSignedInteger_isDecoded() { + byte[] bigNumberByteArray = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 127, -1, -1, -1, -1, -1, -1, -1 }; + SolidityType testObject = new SolidityType.IntType("int256"); + Object decode = testObject.decode(bigNumberByteArray); + assertEquals(decode.getClass(), BigInteger.class); + BigInteger actualBigInteger = (BigInteger) decode; + BigInteger expectedBigInteger = new BigInteger(bigNumberByteArray); + assertEquals(expectedBigInteger, actualBigInteger); + } +} diff --git a/ethereumj-core/src/test/java/org/ethereum/util/HashUtilTest.java b/ethereumj-core/src/test/java/org/ethereum/util/HashUtilTest.java index 376e72541d..a7a62d3b59 100644 --- a/ethereumj-core/src/test/java/org/ethereum/util/HashUtilTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/util/HashUtilTest.java @@ -23,6 +23,7 @@ import org.spongycastle.util.encoders.Hex; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; public class HashUtilTest { @@ -101,4 +102,42 @@ public void testRIPEMD160_Multiple() { String result2 = Hex.toHexString(HashUtil.ripemd160("test2".getBytes())); assertEquals(expected2, result2); } + + @Test + public void testCalcSaltAddress() { + assertArrayEquals(Hex.decode("4D1A2e2bB4F88F0250f26Ffff098B0b30B26BF38"), HashUtil.calcSaltAddr( + Hex.decode("0000000000000000000000000000000000000000"), + Hex.decode("00"), + Hex.decode("0000000000000000000000000000000000000000000000000000000000000000"))); + + assertArrayEquals(Hex.decode("B928f69Bb1D91Cd65274e3c79d8986362984fDA3"), HashUtil.calcSaltAddr( + Hex.decode("deadbeef00000000000000000000000000000000"), + Hex.decode("00"), + Hex.decode("0000000000000000000000000000000000000000000000000000000000000000"))); + + assertArrayEquals(Hex.decode("D04116cDd17beBE565EB2422F2497E06cC1C9833"), HashUtil.calcSaltAddr( + Hex.decode("deadbeef00000000000000000000000000000000"), + Hex.decode("00"), + Hex.decode("000000000000000000000000feed000000000000000000000000000000000000"))); + + assertArrayEquals(Hex.decode("70f2b2914A2a4b783FaEFb75f459A580616Fcb5e"), HashUtil.calcSaltAddr( + Hex.decode("0000000000000000000000000000000000000000"), + Hex.decode("deadbeef"), + Hex.decode("0000000000000000000000000000000000000000000000000000000000000000"))); + + assertArrayEquals(Hex.decode("60f3f640a8508fC6a86d45DF051962668E1e8AC7"), HashUtil.calcSaltAddr( + Hex.decode("00000000000000000000000000000000deadbeef"), + Hex.decode("deadbeef"), + Hex.decode("00000000000000000000000000000000000000000000000000000000cafebabe"))); + + assertArrayEquals(Hex.decode("1d8bfDC5D46DC4f61D6b6115972536eBE6A8854C"), HashUtil.calcSaltAddr( + Hex.decode("00000000000000000000000000000000deadbeef"), + Hex.decode("deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"), + Hex.decode("00000000000000000000000000000000000000000000000000000000cafebabe"))); + + assertArrayEquals(Hex.decode("E33C0C7F7df4809055C3ebA6c09CFe4BaF1BD9e0"), HashUtil.calcSaltAddr( + Hex.decode("0000000000000000000000000000000000000000"), + Hex.decode(""), + Hex.decode("0000000000000000000000000000000000000000000000000000000000000000"))); + } } diff --git a/ethereumj-core/src/test/java/org/ethereum/util/StandaloneBlockchainTest.java b/ethereumj-core/src/test/java/org/ethereum/util/StandaloneBlockchainTest.java index 3132a9c6d7..e970d90436 100644 --- a/ethereumj-core/src/test/java/org/ethereum/util/StandaloneBlockchainTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/util/StandaloneBlockchainTest.java @@ -115,14 +115,28 @@ public void encodeTest1() { StandaloneBlockchain sb = new StandaloneBlockchain().withAutoblock(true); SolidityContract a = sb.submitNewContract( "contract A {" + - " uint public a;" + - " function f(uint a_) {a = a_;}" + + " int public a;" + + " function f(int a_) {a = a_;}" + "}"); a.callFunction("f", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); BigInteger r = (BigInteger) a.callConstFunction("a")[0]; System.out.println(r.toString(16)); Assert.assertEquals(new BigInteger(Hex.decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")), r); } + + @Test + public void encodeTest2() { + StandaloneBlockchain sb = new StandaloneBlockchain().withAutoblock(true); + SolidityContract a = sb.submitNewContract( + "contract A {" + + " uint public a;" + + " function f(uint a_) {a = a_;}" + + "}"); + a.callFunction("f", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + BigInteger r = (BigInteger) a.callConstFunction("a")[0]; + System.out.println(r.toString(16)); + Assert.assertEquals(new BigInteger(1, Hex.decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")), r); + } @Test public void invalidTxTest() { From 67e9c6a262bb08dbc71dc50bedeb2b691ea2e2ed Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Mon, 8 Oct 2018 17:12:45 +0300 Subject: [PATCH 25/28] Fixes typo. --- .../org/ethereum/facade/EthereumImpl.java | 4 +-- .../org/ethereum/listener/BlockReplayer.java | 4 +-- .../org/ethereum/publish/event/Events.java | 2 +- .../org/ethereum/samples/BasicSample.java | 4 +-- .../ethereum/samples/BlockReplaySample.java | 4 +-- .../samples/CreateContractSample.java | 4 +-- .../ethereum/samples/EventListenerSample.java | 4 +-- .../org/ethereum/samples/FollowAccount.java | 4 +-- .../ethereum/samples/PendingStateSample.java | 4 +-- .../org/ethereum/samples/SendTransaction.java | 4 +-- .../samples/SingleMinerNetSample.java | 6 ++--- .../org/ethereum/samples/TransactionBomb.java | 4 +-- .../samples/util/TransactionSubmitter.java | 4 +-- .../util/blockchain/StandaloneBlockchain.java | 7 ++--- .../org/ethereum/validator/EthashRule.java | 4 +-- .../java/org/ethereum/core/CloseTest.java | 4 +-- .../org/ethereum/core/PendingStateTest.java | 27 +++++++++---------- .../java/org/ethereum/longrun/BasicNode.java | 4 +-- .../ethereum/longrun/SyncWithLoadTest.java | 4 +-- .../java/org/ethereum/mine/MinerTest.java | 6 ++--- .../java/org/ethereum/mine/SyncDoneTest.java | 18 ++++++------- .../java/org/ethereum/net/TwoPeerTest.java | 4 +-- .../ethereum/net/rlpx/SanityLongRunTest.java | 4 +-- .../org/ethereum/sync/BlockTxForwardTest.java | 6 ++--- .../java/org/ethereum/sync/LongSyncTest.java | 4 +-- .../java/org/ethereum/sync/ShortSyncTest.java | 24 ++++++++--------- 26 files changed, 82 insertions(+), 86 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index 65c8716f97..6fd5779f71 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -66,7 +66,7 @@ import java.util.function.Consumer; import static org.ethereum.publish.Subscription.to; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.util.ByteUtil.toHexString; /** @@ -122,7 +122,7 @@ public EthereumImpl(final SystemProperties config) { @PostConstruct public void init() { - worldManager.subscribe(to(BLOCK_ADED, data -> gasPriceTracker.onBlock(data.getBlockSummary()))); + worldManager.subscribe(to(BLOCK_ADDED, data -> gasPriceTracker.onBlock(data.getBlockSummary()))); } @Override diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/BlockReplayer.java b/ethereumj-core/src/main/java/org/ethereum/listener/BlockReplayer.java index e5e3db46d7..10fd28a541 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/BlockReplayer.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/BlockReplayer.java @@ -37,7 +37,7 @@ import static java.util.Objects.requireNonNull; import static java.util.stream.Collectors.toList; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; /** * Class capable of replaying stored blocks prior to 'going online' and @@ -198,7 +198,7 @@ public BlockReplayer replayAsyncAt(Ethereum ethereum) { } BlockReplayer blockReplay = build(); - ethereum.subscribe(BLOCK_ADED, blockReplay::onBlock); + ethereum.subscribe(BLOCK_ADDED, blockReplay::onBlock); new Thread(() -> blockReplay.replay()).start(); return blockReplay; diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java index 389ca4ab26..4a942f6b89 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java @@ -47,7 +47,7 @@ public interface Type { Class> PEER_HANDSHAKED = PeerHandshaked.class; - Class> BLOCK_ADED = BlockAdded.class; + Class> BLOCK_ADDED = BlockAdded.class; Class> NODE_DISCOVERED = NodeDiscovered.class; diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java index 8e4edac54d..5552743f58 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/BasicSample.java @@ -41,7 +41,7 @@ import java.util.*; import static org.ethereum.publish.Subscription.to; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.ETH_STATUS_UPDATED; import static org.ethereum.publish.event.Events.Type.NODE_DISCOVERED; import static org.ethereum.publish.event.Events.Type.PEER_ADDED_TO_SYNC_POOL; @@ -139,7 +139,7 @@ private void springInit() { .subscribe(SYNC_DONE, syncState -> synced = true) .subscribe(ETH_STATUS_UPDATED, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage())) .subscribe(PEER_ADDED_TO_SYNC_POOL, peer -> syncPeers.add(peer.getNode())) - .subscribe(BLOCK_ADED, data -> { + .subscribe(BLOCK_ADDED, data -> { BlockSummary blockSummary = data.getBlockSummary(); Block block = blockSummary.getBlock(); List receipts = blockSummary.getReceipts(); diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/BlockReplaySample.java b/ethereumj-core/src/main/java/org/ethereum/samples/BlockReplaySample.java index 97cb1ef5cd..92773cbef7 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/BlockReplaySample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/BlockReplaySample.java @@ -9,7 +9,7 @@ import org.springframework.context.annotation.Bean; import static org.ethereum.publish.Subscription.to; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; public class BlockReplaySample extends SingleMinerNetSample { @@ -21,7 +21,7 @@ public class BlockReplaySample extends SingleMinerNetSample { @Override protected void onSampleReady() { - ethereum.subscribe(to(BLOCK_ADED, this::enableReplay) + ethereum.subscribe(to(BLOCK_ADDED, this::enableReplay) .oneOff(data -> data.getBlockSummary().getBlock().getNumber() % 50 == 0)); } diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java index 5321d9c817..c3d28d44b9 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/CreateContractSample.java @@ -37,7 +37,7 @@ import java.util.HashMap; import java.util.Map; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.util.ByteUtil.toHexString; /** @@ -64,7 +64,7 @@ public class CreateContractSample extends TestNetSample { @Override public void onSyncDone() throws Exception { // when block arrives look for our included transactions - ethereum.subscribe(BLOCK_ADED, this::onBlock); + ethereum.subscribe(BLOCK_ADDED, this::onBlock); logger.info("Compiling contract..."); SolidityCompiler.Result result = compiler.compileSrc(contract.getBytes(), true, true, diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java index 67ef2f1349..7294bcaf04 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/EventListenerSample.java @@ -33,7 +33,7 @@ import java.math.BigInteger; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.PENDING_TRANSACTION_UPDATED; /** @@ -139,7 +139,7 @@ protected void onSampleReady() { IncEventListener eventListener = new IncEventListener(pendingState, contract.getAbi(), contract.getAddress()); this.ethereum - .subscribe(BLOCK_ADED, eventListener::onBlock) + .subscribe(BLOCK_ADDED, eventListener::onBlock) .subscribe(PENDING_TRANSACTION_UPDATED, eventListener::onPendingTransactionUpdated); Contract.Caller cow = contractCaller("cow", "sample"); diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java b/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java index 5144fbccb6..5fabca0395 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/FollowAccount.java @@ -25,13 +25,13 @@ import java.math.BigInteger; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; public class FollowAccount { public static void main(String[] args) { Ethereum ethereum = EthereumFactory.createEthereum(); - ethereum.subscribe(BLOCK_ADED, data -> { + ethereum.subscribe(BLOCK_ADDED, data -> { byte[] cow = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826"); // Get snapshot some time ago - 10% blocks ago diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java index 1058df0fc3..ef1a46ae28 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/PendingStateSample.java @@ -30,7 +30,7 @@ import java.util.*; import static org.ethereum.core.PendingTransaction.State.NEW_PENDING; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.PENDING_TRANSACTION_UPDATED; import static org.ethereum.publish.Subscription.to; import static org.ethereum.util.ByteUtil.toHexString; @@ -70,7 +70,7 @@ public void onSyncDone() { .subscribe(to(PENDING_TRANSACTION_UPDATED, data -> onPendingTransactionReceived(data.getReceipt().getTransaction())) .conditionally(data -> data.getState() == NEW_PENDING)) // when block arrives look for our included transactions - .subscribe(BLOCK_ADED, d -> onBlock(d)); + .subscribe(BLOCK_ADDED, d -> onBlock(d)); new Thread(() -> { try { diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java b/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java index 1c431db287..9b5683cff2 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/SendTransaction.java @@ -34,7 +34,7 @@ import java.util.HashMap; import java.util.Map; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; /** * With this simple example you can send transaction from address to address in live public network @@ -50,7 +50,7 @@ public class SendTransaction extends BasicSample { @Override public void onSyncDone() throws Exception { // when block arrives look for our included transactions - this.ethereum.subscribe(BLOCK_ADED, this::onBlock); + this.ethereum.subscribe(BLOCK_ADDED, this::onBlock); String toAddress = ""; logger.info("Sending transaction to net and waiting for inclusion"); diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/SingleMinerNetSample.java b/ethereumj-core/src/main/java/org/ethereum/samples/SingleMinerNetSample.java index 286af27756..ddba7afebb 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/SingleMinerNetSample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/SingleMinerNetSample.java @@ -49,7 +49,7 @@ import static java.nio.file.Files.readAllBytes; import static org.ethereum.core.Denomination.ETHER; import static org.ethereum.publish.Subscription.to; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; /** * Basic class for independent private network samples. @@ -217,8 +217,8 @@ private CompletableFuture transferFundsToAccounts() { @PostConstruct public final void initSample() { this.ethereum - .subscribe(to(BLOCK_ADED, this::onImportStarted).oneOff()) - .subscribe(to(BLOCK_ADED, this::printHeartbeat)); + .subscribe(to(BLOCK_ADDED, this::onImportStarted).oneOff()) + .subscribe(to(BLOCK_ADDED, this::printHeartbeat)); } private void printHeartbeat(BlockAdded.Data data) { diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java b/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java index 5c2499d8e8..714ead8523 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/TransactionBomb.java @@ -27,7 +27,7 @@ import java.util.Collections; import static org.ethereum.crypto.HashUtil.sha3; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.SYNC_DONE; import static org.ethereum.util.ByteUtil.longToBytesNoLeadZeroes; import static org.ethereum.util.ByteUtil.toHexString; @@ -41,7 +41,7 @@ public class TransactionBomb { public TransactionBomb(Ethereum ethereum) { this.ethereum = ethereum .subscribe(SYNC_DONE, this::onSyncDone) - .subscribe(BLOCK_ADED, this::onBlock); + .subscribe(BLOCK_ADDED, this::onBlock); } public static void main(String[] args) { diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/util/TransactionSubmitter.java b/ethereumj-core/src/main/java/org/ethereum/samples/util/TransactionSubmitter.java index ec7d6e65f9..a199bbdbf7 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/util/TransactionSubmitter.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/util/TransactionSubmitter.java @@ -24,7 +24,7 @@ import static java.lang.String.format; import static java.util.function.Function.identity; import static java.util.stream.Collectors.toMap; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.PENDING_TRANSACTION_UPDATED; import static org.ethereum.util.BIUtil.toBI; @@ -37,7 +37,7 @@ public class TransactionSubmitter { public TransactionSubmitter(Ethereum ethereum) { this.ethereum = ethereum .subscribe(PENDING_TRANSACTION_UPDATED, this::onPendingTransactionUpdated) - .subscribe(BLOCK_ADED, this::onBlockAdded); + .subscribe(BLOCK_ADDED, this::onBlockAdded); } public TransactionBuilder newTransaction(ECKey senderKey, byte[] receiverAddress) { diff --git a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java index c9ec797635..5af496240f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/util/blockchain/StandaloneBlockchain.java @@ -17,13 +17,10 @@ */ package org.ethereum.util.blockchain; -import org.ethereum.config.BlockchainConfig; import org.ethereum.config.BlockchainNetConfig; import org.ethereum.config.SystemProperties; import org.ethereum.config.blockchain.ByzantiumConfig; -import org.ethereum.config.blockchain.DaoHFConfig; import org.ethereum.config.blockchain.DaoNoHFConfig; -import org.ethereum.config.blockchain.FrontierConfig; import org.ethereum.config.blockchain.HomesteadConfig; import org.ethereum.core.*; import org.ethereum.core.genesis.GenesisLoader; @@ -61,7 +58,7 @@ import java.util.concurrent.ExecutionException; import static org.ethereum.publish.Subscription.to; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.util.ByteUtil.wrap; /** @@ -450,7 +447,7 @@ public BlockchainImpl getBlockchain() { if (blockchain == null) { blockchain = createBlockchain(genesis); blockchain.setMinerCoinbase(coinbase); - subscribe(to(BLOCK_ADED, data -> lastSummary = data.getBlockSummary())); + subscribe(to(BLOCK_ADDED, data -> lastSummary = data.getBlockSummary())); } return blockchain; } diff --git a/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java b/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java index 9de5c919e7..38895ba742 100644 --- a/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java +++ b/ethereumj-core/src/main/java/org/ethereum/validator/EthashRule.java @@ -28,7 +28,7 @@ import java.util.Random; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.SYNC_DONE; import static org.ethereum.validator.EthashRule.ChainType.main; import static org.ethereum.validator.EthashRule.ChainType.reverse; @@ -107,7 +107,7 @@ public EthashRule(Mode mode, ChainType chain, Publisher publisher) { if (this.chain == main && publisher != null) { publisher .subscribe(SYNC_DONE, ss -> EthashRule.this.syncDone = true) - .subscribe(BLOCK_ADED, data -> { + .subscribe(BLOCK_ADDED, data -> { if (data.isBest()) { ethashHelper.preCache(data.getBlockSummary().getBlock().getNumber()); } diff --git a/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java b/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java index f46ff91510..fccbb93f7d 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/CloseTest.java @@ -26,7 +26,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; /** * Created by Anton Nashatyrev on 24.06.2016. @@ -43,7 +43,7 @@ public void relaunchTest() throws InterruptedException { Assert.assertNotNull(bestBlock); final CountDownLatch latch = new CountDownLatch(1); AtomicInteger counter = new AtomicInteger(); - ethereum.subscribe(BLOCK_ADED, data -> { + ethereum.subscribe(BLOCK_ADDED, data -> { if (counter.addAndGet(1) > 1100) { latch.countDown(); } diff --git a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java index dc398ac5c4..30467f7693 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/PendingStateTest.java @@ -22,7 +22,6 @@ import org.ethereum.config.SystemProperties; import org.ethereum.crypto.ECKey; import org.ethereum.db.ByteArrayWrapper; -import org.ethereum.listener.EthereumListener; import org.ethereum.publish.event.BlockAdded; import org.ethereum.publish.event.PendingTransactionUpdated; import org.ethereum.util.blockchain.SolidityContract; @@ -47,7 +46,7 @@ import static org.ethereum.core.PendingTransaction.State.INCLUDED; import static org.ethereum.core.PendingTransaction.State.NEW_PENDING; import static org.ethereum.core.PendingTransaction.State.PENDING; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.PENDING_STATE_CHANGED; import static org.ethereum.publish.event.Events.Type.PENDING_TRANSACTION_UPDATED; import static org.ethereum.publish.Subscription.to; @@ -123,7 +122,7 @@ public Triple pollTxUpdate( public void testSimple() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(BLOCK_ADDED, l::onBlock)) .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); @@ -198,7 +197,7 @@ public void testSimple() throws InterruptedException { public void testRebranch1() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(BLOCK_ADDED, l::onBlock)) .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); @@ -267,7 +266,7 @@ public void testRebranch1() throws InterruptedException { public void testRebranch2() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(BLOCK_ADDED, l::onBlock)) .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); @@ -357,7 +356,7 @@ public void testRebranch2() throws InterruptedException { public void testRebranch3() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(BLOCK_ADDED, l::onBlock)) .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); @@ -409,7 +408,7 @@ public void testRebranch3() throws InterruptedException { public void testOldBlockIncluded() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(BLOCK_ADDED, l::onBlock)) .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); @@ -447,7 +446,7 @@ public void testOldBlockIncluded() throws InterruptedException { public void testBlockOnlyIncluded() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(BLOCK_ADDED, l::onBlock)) .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); @@ -476,7 +475,7 @@ public void testBlockOnlyIncluded() throws InterruptedException { public void testTrackTx1() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(BLOCK_ADDED, l::onBlock)) .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); @@ -530,7 +529,7 @@ public void testPrevBlock() throws InterruptedException { PendingListener l = new PendingListener(); bc - .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(BLOCK_ADDED, l::onBlock)) .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); @@ -547,7 +546,7 @@ public void testPrevBlock() throws InterruptedException { public void testTrackTx2() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(BLOCK_ADDED, l::onBlock)) .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); @@ -580,7 +579,7 @@ public void testTrackTx2() throws InterruptedException { public void testRejected1() throws InterruptedException { PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(BLOCK_ADDED, l::onBlock)) .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); @@ -629,7 +628,7 @@ public void testIncludedRejected() throws InterruptedException { // the transaction becomes the main chain PendingListener l = new PendingListener(); StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(BLOCK_ADDED, l::onBlock)) .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); @@ -683,7 +682,7 @@ public void onPendingTransactionUpdate(TransactionReceipt txReceipt, PendingTran }; StandaloneBlockchain bc = new StandaloneBlockchain() - .subscribe(to(BLOCK_ADED, l::onBlock)) + .subscribe(to(BLOCK_ADDED, l::onBlock)) .subscribe(to(PENDING_STATE_CHANGED, l::onPendingStateChanged)) .subscribe(to(PENDING_TRANSACTION_UPDATED, l::onPendingTransactionUpdate)); diff --git a/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java b/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java index cf8d344ab3..fa30e9dfd0 100644 --- a/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java +++ b/ethereumj-core/src/test/java/org/ethereum/longrun/BasicNode.java @@ -42,7 +42,7 @@ import java.util.Vector; import static java.lang.Thread.sleep; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.ETH_STATUS_UPDATED; import static org.ethereum.publish.event.Events.Type.PEER_ADDED_TO_SYNC_POOL; import static org.ethereum.publish.event.Events.Type.SYNC_DONE; @@ -110,7 +110,7 @@ private void springInit() { // adding the main EthereumJ callback to be notified on different kind of events this.ethereum .subscribe(SYNC_DONE, this::onSyncDone) - .subscribe(BLOCK_ADED, this::onBlock) + .subscribe(BLOCK_ADDED, this::onBlock) .subscribe(ETH_STATUS_UPDATED, this::onEthStatusUpdated) .subscribe(PEER_ADDED_TO_SYNC_POOL, this::onPeerAddedToSyncPool); diff --git a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java index 652518b660..c589e43cfc 100644 --- a/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/longrun/SyncWithLoadTest.java @@ -54,7 +54,7 @@ import static java.lang.Thread.sleep; import static org.ethereum.core.PendingTransaction.State.NEW_PENDING; import static org.ethereum.publish.Subscription.to; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.PENDING_TRANSACTION_UPDATED; /** @@ -228,7 +228,7 @@ public RegularNode() { public void run() { try { this.ethereum - .subscribe(to(BLOCK_ADED, this::onBlock)) + .subscribe(to(BLOCK_ADDED, this::onBlock)) .subscribe(to(PENDING_TRANSACTION_UPDATED, this::onPendingTransactionUpdated) .conditionally(data -> data.getState() == NEW_PENDING)); diff --git a/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java b/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java index 0e16f94efa..02dc1ba93d 100644 --- a/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/mine/MinerTest.java @@ -47,7 +47,7 @@ import static org.ethereum.core.PendingTransaction.State.NEW_PENDING; import static org.ethereum.publish.Subscription.to; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.PENDING_TRANSACTION_UPDATED; import static org.ethereum.publish.event.Events.Type.SYNC_DONE; @@ -108,7 +108,7 @@ public void startMiningConsumer() throws Exception { Ethereum ethereum2 = EthereumFactory.createEthereum(SysPropConfig2.props, SysPropConfig2.class); final CountDownLatch semaphore = new CountDownLatch(1); - ethereum2.subscribe(BLOCK_ADED, data -> { + ethereum2.subscribe(BLOCK_ADDED, data -> { Block block = data.getBlockSummary().getBlock(); System.err.println("=== New block: " + blockInfo(block)); System.err.println(block); @@ -207,7 +207,7 @@ public void startMiningTest() throws FileNotFoundException, InterruptedException final CountDownLatch semaphore = new CountDownLatch(1); ethereum1 - .subscribe(BLOCK_ADED, data -> System.out.println("=== New block: " + blockInfo(data.getBlockSummary().getBlock()))) + .subscribe(BLOCK_ADDED, data -> System.out.println("=== New block: " + blockInfo(data.getBlockSummary().getBlock()))) .subscribe(SYNC_DONE, syncState -> semaphore.countDown()); // ethereum2.addListener(new EthereumListenerAdapter() { diff --git a/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java b/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java index e3c8b76877..ad1a4cbeb2 100644 --- a/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/mine/SyncDoneTest.java @@ -55,7 +55,7 @@ import static java.util.stream.Collectors.toList; import static org.ethereum.crypto.HashUtil.sha3; import static org.ethereum.publish.Subscription.to; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.PEER_ADDED_TO_SYNC_POOL; import static org.ethereum.util.FileUtil.recursiveDelete; import static org.junit.Assert.*; @@ -161,7 +161,7 @@ public void test1() throws InterruptedException { assertTrue(loadedBlocks > 0); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BLOCK_ADED, data -> semaphore.countDown()) + ethereumB.subscribe(to(BLOCK_ADDED, data -> semaphore.countDown()) .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks))); semaphore.await(MAX_SECONDS_WAIT, SECONDS); @@ -171,14 +171,14 @@ public void test1() throws InterruptedException { ethereumA.getBlockMiner().startMining(); final CountDownLatch semaphore2 = new CountDownLatch(2); - ethereumB.subscribe(BLOCK_ADED, data -> { + ethereumB.subscribe(BLOCK_ADDED, data -> { if (isBlockNumber(data.getBlockSummary(), loadedBlocks + 2)) { semaphore2.countDown(); ethereumA.getBlockMiner().stopMining(); } }); - ethereumA.subscribe(to(BLOCK_ADED, data -> semaphore2.countDown()) + ethereumA.subscribe(to(BLOCK_ADDED, data -> semaphore2.countDown()) .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks + 2))); semaphore2.await(MAX_SECONDS_WAIT, SECONDS); @@ -200,7 +200,7 @@ public void test1() throws InterruptedException { ); tx.sign(sender); final CountDownLatch txSemaphore = new CountDownLatch(1); - ethereumA.subscribe(BLOCK_ADED, data -> { + ethereumA.subscribe(BLOCK_ADDED, data -> { BlockSummary blockSummary = data.getBlockSummary(); if (!blockSummary.getBlock().getTransactionsList().isEmpty() && FastByteComparisons.equal(blockSummary.getBlock().getTransactionsList().get(0).getSender(), sender.getAddress()) && @@ -212,10 +212,10 @@ public void test1() throws InterruptedException { ethereumB.submitTransaction(tx); final CountDownLatch semaphore3 = new CountDownLatch(2); - ethereumB.subscribe(to(BLOCK_ADED, data -> semaphore3.countDown()) + ethereumB.subscribe(to(BLOCK_ADDED, data -> semaphore3.countDown()) .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks + 5))); - ethereumA.subscribe(BLOCK_ADED, data -> { + ethereumA.subscribe(BLOCK_ADDED, data -> { if (isBlockNumber(data.getBlockSummary(), loadedBlocks + 5)) { semaphore3.countDown(); ethereumA.getBlockMiner().stopMining(); @@ -252,14 +252,14 @@ public void test1() throws InterruptedException { final CountDownLatch semaphore4 = new CountDownLatch(2); - ethereumB.subscribe(BLOCK_ADED, data -> { + ethereumB.subscribe(BLOCK_ADDED, data -> { if (isBlockNumber(data.getBlockSummary(), loadedBlocks + 9)) { semaphore4.countDown(); ethereumA.getBlockMiner().stopMining(); } }); - ethereumA.subscribe(to(BLOCK_ADED, data -> semaphore4.countDown()) + ethereumA.subscribe(to(BLOCK_ADDED, data -> semaphore4.countDown()) .conditionally(data -> isBlockNumber(data.getBlockSummary(), loadedBlocks + 9))); semaphore4.await(MAX_SECONDS_WAIT, SECONDS); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java b/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java index 51484be998..c7c02f91ed 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/TwoPeerTest.java @@ -50,7 +50,7 @@ import static java.lang.Math.max; import static java.lang.Math.min; import static org.ethereum.crypto.HashUtil.sha3; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.ETH_STATUS_UPDATED; /** @@ -230,7 +230,7 @@ protected void processGetBlockBodies(GetBlockBodiesMessage msg) { System.out.println("==== Got the Channel: " + data.getChannel()); }); - ethereum2.subscribe(BLOCK_ADED, data -> { + ethereum2.subscribe(BLOCK_ADDED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.getNumber() == 4) { semaphore.countDown(); diff --git a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java index 35758805eb..a911402dcd 100644 --- a/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/net/rlpx/SanityLongRunTest.java @@ -39,7 +39,7 @@ import java.util.concurrent.atomic.AtomicInteger; import static org.ethereum.publish.Subscription.to; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.MESSAGE_RECEIVED; /** @@ -129,7 +129,7 @@ public void testTest() throws FileNotFoundException, InterruptedException { final CountDownLatch semaphoreFirstBlock = new CountDownLatch(1); AtomicInteger blocksCnt = new AtomicInteger(); - ethereum2.subscribe(BLOCK_ADED, data -> { + ethereum2.subscribe(BLOCK_ADDED, data -> { blocksCnt.addAndGet(1); if (blocksCnt.get() % 1000 == 0 || blocksCnt.get() == 1) { System.out.println("=== Blocks imported: " + blocksCnt); diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java index 54f9358c14..d3671967ca 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/BlockTxForwardTest.java @@ -49,7 +49,7 @@ import java.util.concurrent.atomic.AtomicInteger; import static org.ethereum.publish.Subscription.to; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.ETH_STATUS_UPDATED; import static org.ethereum.publish.event.Events.Type.MESSAGE_RECEIVED; import static org.ethereum.publish.event.Events.Type.MESSAGE_SENT; @@ -124,7 +124,7 @@ private void springInit() { .subscribe(SYNC_DONE, syncState -> synced = true) .subscribe(ETH_STATUS_UPDATED, data -> ethNodes.put(data.getChannel().getNode(), data.getMessage())) .subscribe(PEER_ADDED_TO_SYNC_POOL, peer -> syncPeers.add(peer.getNode())) - .subscribe(BLOCK_ADED, data -> { + .subscribe(BLOCK_ADDED, data -> { bestBlock = data.getBlockSummary().getBlock(); if (syncComplete) { logger.info("New block: " + bestBlock.getShortDescr()); @@ -482,7 +482,7 @@ public void testTest() throws Exception { Ethereum miner = EthereumFactory.createEthereum(MinerConfig.class); miner - .subscribe(BLOCK_ADED, data -> { + .subscribe(BLOCK_ADDED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.getNumber() != 0L) { blocks.put(Hex.toHexString(block.getHash()), Boolean.FALSE); diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java index 0e99a1ad08..02419c1a25 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/LongSyncTest.java @@ -50,7 +50,7 @@ import java.util.concurrent.CountDownLatch; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.ETH_STATUS_UPDATED; import static org.ethereum.publish.event.Events.Type.MESSAGE_RECEIVED; import static org.ethereum.publish.event.Events.Type.PEER_ADDED_TO_SYNC_POOL; @@ -160,7 +160,7 @@ public void test1() throws InterruptedException { // A == b10, B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(BLOCK_ADED, data -> { + ethereumB.subscribe(BLOCK_ADDED, data -> { if (data.getBlockSummary().getBlock().isEqual(b10)) { semaphore.countDown(); } diff --git a/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java b/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java index fd19fbdf57..f766e41d80 100644 --- a/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/sync/ShortSyncTest.java @@ -51,7 +51,7 @@ import static java.util.concurrent.TimeUnit.SECONDS; import static org.ethereum.publish.Subscription.to; -import static org.ethereum.publish.event.Events.Type.BLOCK_ADED; +import static org.ethereum.publish.event.Events.Type.BLOCK_ADDED; import static org.ethereum.publish.event.Events.Type.ETH_STATUS_UPDATED; import static org.ethereum.publish.event.Events.Type.MESSAGE_RECEIVED; import static org.ethereum.publish.event.Events.Type.PEER_ADDED_TO_SYNC_POOL; @@ -160,7 +160,7 @@ public void test1() throws InterruptedException { // A == b10, B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BLOCK_ADED, data -> semaphore.countDown()) + ethereumB.subscribe(to(BLOCK_ADDED, data -> semaphore.countDown()) .conditionally(data -> data.getBlockSummary().getBlock().isEqual(b10))); ethA.sendNewBlock(b10); @@ -192,7 +192,7 @@ public void test2() throws InterruptedException { // A == b8', B == genesis final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BLOCK_ADED, data -> semaphore.countDown()) + ethereumB.subscribe(to(BLOCK_ADDED, data -> semaphore.countDown()) .conditionally(data -> data.getBlockSummary().getBlock().isEqual(b8_))); ethA.sendNewBlock(b8_); @@ -228,7 +228,7 @@ public void test3() throws InterruptedException { // A == b10, B == b8' final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(BLOCK_ADED, data -> { + ethereumB.subscribe(BLOCK_ADDED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -273,7 +273,7 @@ public void test4() throws InterruptedException { // A == b5, B == b9 final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(to(BLOCK_ADED, blockSummary -> semaphore.countDown()) + ethereumB.subscribe(to(BLOCK_ADDED, blockSummary -> semaphore.countDown()) .conditionally(data -> data.getBlockSummary().getBlock().equals(b10))); ethA.sendNewBlockHashes(b5); @@ -322,7 +322,7 @@ public void test5() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB8_ = new CountDownLatch(1); - ethereumB.subscribe(BLOCK_ADED, data -> { + ethereumB.subscribe(BLOCK_ADDED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -382,7 +382,7 @@ public void test6() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB7 = new CountDownLatch(1); - ethereumB.subscribe(BLOCK_ADED, data -> { + ethereumB.subscribe(BLOCK_ADDED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b7)) { semaphoreB7.countDown(); @@ -453,7 +453,7 @@ public void test7() throws InterruptedException { }); final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(BLOCK_ADED, data -> { + ethereumB.subscribe(BLOCK_ADDED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -501,7 +501,7 @@ public void test8() throws InterruptedException { final CountDownLatch semaphore = new CountDownLatch(1); final CountDownLatch semaphoreB7_ = new CountDownLatch(1); - ethereumB.subscribe(BLOCK_ADED, data -> { + ethereumB.subscribe(BLOCK_ADDED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b7_)) { // it's time to do a re-branch @@ -604,7 +604,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { } final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(BLOCK_ADED, data -> { + ethereumB.subscribe(BLOCK_ADDED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -699,7 +699,7 @@ protected void processGetBlockHeaders(GetBlockHeadersMessage msg) { LongSyncTest.SysPropConfigA.eth62 = null; final CountDownLatch semaphore = new CountDownLatch(1); - ethereumB.subscribe(BLOCK_ADED, data -> { + ethereumB.subscribe(BLOCK_ADDED, data -> { Block block = data.getBlockSummary().getBlock(); if (block.isEqual(b10)) { semaphore.countDown(); @@ -760,7 +760,7 @@ public void test11() throws InterruptedException { final CountDownLatch semaphore1 = new CountDownLatch(1); final CountDownLatch semaphore2 = new CountDownLatch(1); - ethereumB.subscribe(BLOCK_ADED, data -> { + ethereumB.subscribe(BLOCK_ADDED, data -> { if (data.getBlockSummary().getBlock().isEqual(b6_)) { if (semaphore1.getCount() > 0) { semaphore1.countDown(); From d576607ddd1a7ea102342728e18a80d80090ba7a Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Mon, 8 Oct 2018 17:30:15 +0300 Subject: [PATCH 26/28] Adds minor fixes --- .../src/main/java/org/ethereum/db/DbFlushManager.java | 3 ++- .../listener/BackwardCompatibilityEthereumListenerProxy.java | 2 +- .../src/main/java/org/ethereum/publish/event/Events.java | 4 ---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java b/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java index 6c9837cd40..0e811f45e2 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/DbFlushManager.java @@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.ArrayBlockingQueue; @@ -51,7 +52,7 @@ public class DbFlushManager { List> writeCaches = new CopyOnWriteArrayList<>(); List> sources = new CopyOnWriteArrayList<>(); - Set dbSources ; + Set dbSources = new HashSet<>(); AbstractCachedSource stateDbCache; long sizeThreshold; diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java b/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java index 380151eb00..33a2817ec0 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/BackwardCompatibilityEthereumListenerProxy.java @@ -109,7 +109,7 @@ public void onSendMessage(Channel channel, Message message) { @Override public void onBlock(BlockSummary blockSummary) { compositeListener.onBlock(blockSummary); - publisher.publish(Events.onBlockAdded(blockSummary)); + publisher.publish(Events.onBlockAdded(blockSummary, false)); } @Override diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java b/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java index 4a942f6b89..f72b9e82b2 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/event/Events.java @@ -89,10 +89,6 @@ public static Event onBlockAdded(BlockSummary summary, boolean isBest) { return new BlockAdded(summary, isBest); } - public static Event onBlockAdded(BlockSummary summary) { - return onBlockAdded(summary, false); - } - public static Event onNodeDiscovered(Node node) { return new NodeDiscovered(node); } From f0bf19aa009ff3c76bb911507edd8e347edb6586 Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Tue, 9 Oct 2018 15:37:15 +0300 Subject: [PATCH 27/28] Adds several comments/ --- .../src/main/java/org/ethereum/listener/BlockReplay.java | 2 ++ .../src/main/java/org/ethereum/publish/Subscription.java | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/listener/BlockReplay.java b/ethereumj-core/src/main/java/org/ethereum/listener/BlockReplay.java index fbb25ad1db..e1aa9f2b18 100644 --- a/ethereumj-core/src/main/java/org/ethereum/listener/BlockReplay.java +++ b/ethereumj-core/src/main/java/org/ethereum/listener/BlockReplay.java @@ -37,6 +37,8 @@ import static org.ethereum.sync.BlockDownloader.MAX_IN_REQUEST; /** + * @deprecated This component uses deprecated {@link EthereumListenerAdapter}, use {@link BlockReplayer} instead. + * * Class capable of replaying stored blocks prior to 'going online' and * notifying on newly imported blocks * diff --git a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java index e4945acf1b..882fbd2412 100644 --- a/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java +++ b/ethereumj-core/src/main/java/org/ethereum/publish/Subscription.java @@ -39,7 +39,7 @@ public class Subscription, D> { private final static Logger log = LoggerFactory.getLogger("event"); /** - * + * Abstraction that helps manage subscription state */ public static class LifeCycle { private final Subscription subscription; @@ -49,7 +49,7 @@ private LifeCycle(Subscription subscription) { } /** - * + * Unsubscribes owner's subscription from current event flow. */ public void unsubscribe() { subscription.unsubscribeAfter(data -> true); From 7ee581141e4c18941401825b420e92395caeaa87 Mon Sep 17 00:00:00 2001 From: "e.shevchenko" Date: Tue, 9 Oct 2018 18:04:19 +0300 Subject: [PATCH 28/28] Adds copyright headers. --- .../org/ethereum/samples/BlockReplaySample.java | 17 +++++++++++++++++ .../java/org/ethereum/samples/util/Account.java | 17 +++++++++++++++++ .../org/ethereum/samples/util/Contract.java | 17 +++++++++++++++++ .../samples/util/TransactionSubmitter.java | 17 +++++++++++++++++ 4 files changed, 68 insertions(+) diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/BlockReplaySample.java b/ethereumj-core/src/main/java/org/ethereum/samples/BlockReplaySample.java index 92773cbef7..0c1e520460 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/BlockReplaySample.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/BlockReplaySample.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.samples; import org.ethereum.db.BlockStore; diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/util/Account.java b/ethereumj-core/src/main/java/org/ethereum/samples/util/Account.java index 9a54c802da..f0d2334a77 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/util/Account.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/util/Account.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.samples.util; import org.ethereum.crypto.ECKey; diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/util/Contract.java b/ethereumj-core/src/main/java/org/ethereum/samples/util/Contract.java index b7132eb71c..32b99a15c5 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/util/Contract.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/util/Contract.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.samples.util; import org.ethereum.core.CallTransaction; diff --git a/ethereumj-core/src/main/java/org/ethereum/samples/util/TransactionSubmitter.java b/ethereumj-core/src/main/java/org/ethereum/samples/util/TransactionSubmitter.java index a199bbdbf7..d67ca35b05 100644 --- a/ethereumj-core/src/main/java/org/ethereum/samples/util/TransactionSubmitter.java +++ b/ethereumj-core/src/main/java/org/ethereum/samples/util/TransactionSubmitter.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ package org.ethereum.samples.util; import org.ethereum.core.Block;