Skip to content
This repository has been archived by the owner on Aug 23, 2020. It is now read-only.

Feature: Add solidification stage to pipeline and only broadcast solid transactions #1646

Open
wants to merge 79 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
53ea166
Add ubiquitous Broadcast Queue
DyrellC Oct 14, 2019
be7c132
Update unit tests with broadcasting queue
DyrellC Oct 15, 2019
6593388
Remove unneeded log
DyrellC Oct 17, 2019
33f193f
Merge branch 'dev' into add-Broadcast-queue
Oct 30, 2019
ff58495
Fix broadcast queue injection
DyrellC Nov 4, 2019
1a0ea43
remove unused function
DyrellC Nov 4, 2019
ad3a203
Merge branch 'add-Broadcast-queue' of https://github.com/DyrellC/iri …
DyrellC Nov 4, 2019
2283fb0
Merge branch 'dev' of https://github.com/iotaledger/iri into add-Broa…
DyrellC Nov 4, 2019
24e31a5
Clean up imports
DyrellC Nov 4, 2019
03590dd
Remove BroadcastQueue, add TransactionSolidifier class
DyrellC Nov 8, 2019
06242eb
Add docs
DyrellC Nov 8, 2019
1ec3794
Add to solidification queue if update status fails
DyrellC Nov 8, 2019
bc5897f
Fix network injection test
DyrellC Nov 8, 2019
62a2330
Remove unused import, lower checkSolidity complexity
DyrellC Nov 8, 2019
9fc4cba
Reduce complexity further
DyrellC Nov 8, 2019
ccca691
Comments
DyrellC Nov 8, 2019
f0c1955
Change queue type, log error messages differentely
DyrellC Nov 12, 2019
fa72acc
Condense code slightly
DyrellC Nov 12, 2019
c3b1417
Synchronize solidifier queue access, add received transactions to sol…
DyrellC Nov 13, 2019
1538b36
Move solidification queue entry point, reduce interval for scans
DyrellC Nov 14, 2019
a34c5e8
Broadcast from reply stage to increase transactions to request speed
DyrellC Nov 18, 2019
14e784d
Merge branch 'dev' into add-Broadcast-queue
Nov 19, 2019
89ec550
Clean up PR, add interface
DyrellC Nov 21, 2019
8801ef2
Add unit tests
DyrellC Nov 21, 2019
26b9521
Wrap in try/catch, fix styling
DyrellC Nov 21, 2019
16170cf
Merge branch 'add-Broadcast-queue' of https://github.com/DyrellC/iri …
DyrellC Nov 21, 2019
7e34c91
Update src/main/java/com/iota/iri/network/pipeline/TransactionProcess…
DyrellC Nov 27, 2019
778c833
Remove solidification from broadcast queue next stage
DyrellC Nov 27, 2019
0b61c89
Add quick solid transactions to broadcast queue, comments and tests u…
DyrellC Nov 27, 2019
1a2d950
Merge branch 'add-Broadcast-queue' of https://github.com/DyrellC/iri …
DyrellC Nov 27, 2019
864c2db
codacy conflict
DyrellC Nov 27, 2019
4bfb138
Add messages to solidifier test
DyrellC Nov 27, 2019
d623d1d
Pop eldest on queue fill
DyrellC Nov 27, 2019
48258b1
Remove unused function
DyrellC Nov 27, 2019
1cde4bf
Iterator -> poll()
DyrellC Nov 27, 2019
6543981
Add transaction solidification stage
DyrellC Dec 2, 2019
7b4d3c5
Comments/clean-up
DyrellC Dec 2, 2019
5e0a974
update tests
DyrellC Dec 2, 2019
f86fe55
Remove unused payload Mock
DyrellC Dec 2, 2019
de08907
Remove log
DyrellC Dec 2, 2019
4086fce
Remove circular solidified queue
DyrellC Dec 2, 2019
b16c752
Make addToBroadcastQueue private again
DyrellC Dec 4, 2019
f5de8fe
Ensure solidTip is solid before broadcasting
DyrellC Dec 4, 2019
30f226e
Update tests, only broadcast solid transactions from solidify stage
DyrellC Dec 4, 2019
303648b
Move validator test to appropriate package
DyrellC Dec 5, 2019
7e36e1c
Downgrade log error to log info
DyrellC Dec 5, 2019
eb53b2f
Remove unnecessary solidity propogation thread in validator
DyrellC Dec 10, 2019
0409d3e
only import used parts of junit
DyrellC Dec 10, 2019
1b5294a
Add propagation queue back, remove addToSolidificationQueue from soli…
DyrellC Dec 24, 2019
ab6e628
Codacy corrections
DyrellC Dec 30, 2019
839d9cb
Move update status from validation to solidification
DyrellC Dec 30, 2019
031180b
Merge branch 'dev' of https://github.com/iotaledger/iri into add-Broa…
DyrellC Dec 30, 2019
f61e6ff
Codacy conflicts
DyrellC Dec 30, 2019
6e0a383
reremove old transaction validator
DyrellC Dec 30, 2019
4126903
Merge branch 'dev' into add-Broadcast-queue
Jan 6, 2020
ff4a13c
Fix codacy import error, break up runValidation
DyrellC Jan 6, 2020
5bd3066
Merge branch 'add-Broadcast-queue' of https://github.com/DyrellC/iri …
DyrellC Jan 6, 2020
10baada
Merge branch 'dev' into add-Broadcast-queue
DyrellC Jan 15, 2020
4327b10
Merge branch 'dev' into add-Broadcast-queue
DyrellC Jan 16, 2020
092cfa5
Merge branch 'dev' of https://github.com/iotaledger/iri into add-Broa…
DyrellC Jan 17, 2020
cc220b0
Merge branch 'add-Broadcast-queue' of https://github.com/DyrellC/iri …
DyrellC Jan 17, 2020
82359a7
Update regression logging
DyrellC Jan 21, 2020
7adfdc5
Merge branch 'dev' of https://github.com/iotaledger/iri into add-Broa…
DyrellC Jan 21, 2020
d3baeee
Remove double import from merge
DyrellC Jan 21, 2020
ffea048
Verbose logging for debugging
DyrellC Jan 21, 2020
0f29416
Merge branch 'dev' of https://github.com/iotaledger/iri into add-Broa…
DyrellC Feb 3, 2020
0084b48
Merge branch 'dev' of https://github.com/iotaledger/iri into add-Broa…
DyrellC Feb 6, 2020
4664000
Revert "Fix: sort milestone candidates before analyzing for faster so…
DyrellC Feb 10, 2020
cc5e8b8
Broadcast latest tip even if not solid (will be latest milestone)
DyrellC Feb 14, 2020
d488a1d
Correct cpu load issues
DyrellC Feb 26, 2020
9ad4886
Remove max to propagation cascade
DyrellC Feb 26, 2020
9ab2a7d
Reintroduce limiter to adding duplicates for solidification
DyrellC Feb 26, 2020
5663d30
Merge branch 'dev' of https://github.com/iotaledger/iri into dev
DyrellC Mar 5, 2020
b2cb269
Update DagHelper
DyrellC Mar 6, 2020
31223b3
Update regression logging
DyrellC Jan 21, 2020
ea3bbf8
Move validation to validation service package
DyrellC Mar 18, 2020
e4feaf6
Merge branch 'update-regression-logging' into merge-transaction-solid…
DyrellC Mar 18, 2020
059e7e4
Merge branch 'dev' of https://github.com/iotaledger/iri into add-Broa…
DyrellC Mar 18, 2020
7528b22
Merge branch 'merge-transaction-solidifier' into add-Broadcast-queue
DyrellC Mar 19, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/main/java/com/iota/iri/Iota.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import com.iota.iri.service.spentaddresses.SpentAddressesService;
import com.iota.iri.service.tipselection.TipSelector;
import com.iota.iri.service.transactionpruning.TransactionPruner;
import com.iota.iri.service.validation.TransactionSolidifier;
import com.iota.iri.service.validation.TransactionValidator;
import com.iota.iri.storage.Indexable;
import com.iota.iri.storage.Persistable;
import com.iota.iri.storage.PersistenceProvider;
Expand Down Expand Up @@ -98,6 +100,8 @@ public class Iota {

public final MilestoneSolidifier milestoneSolidifier;

public final TransactionSolidifier transactionSolidifier;

public final BundleValidator bundleValidator;

public final Tangle tangle;
Expand All @@ -116,7 +120,7 @@ public class Iota {
* @param configuration Information about how this node will be configured.
*
*/
public Iota(IotaConfig configuration, SpentAddressesProvider spentAddressesProvider, SpentAddressesService spentAddressesService, SnapshotProvider snapshotProvider, SnapshotService snapshotService, LocalSnapshotManager localSnapshotManager, MilestoneService milestoneService, LatestMilestoneTracker latestMilestoneTracker, LatestSolidMilestoneTracker latestSolidMilestoneTracker, SeenMilestonesRetriever seenMilestonesRetriever, LedgerService ledgerService, TransactionPruner transactionPruner, MilestoneSolidifier milestoneSolidifier, BundleValidator bundleValidator, Tangle tangle, TransactionValidator transactionValidator, TransactionRequester transactionRequester, NeighborRouter neighborRouter, TransactionProcessingPipeline transactionProcessingPipeline, TipsRequester tipsRequester, TipsViewModel tipsViewModel, TipSelector tipsSelector) {
public Iota(IotaConfig configuration, SpentAddressesProvider spentAddressesProvider, SpentAddressesService spentAddressesService, SnapshotProvider snapshotProvider, SnapshotService snapshotService, LocalSnapshotManager localSnapshotManager, MilestoneService milestoneService, LatestMilestoneTracker latestMilestoneTracker, LatestSolidMilestoneTracker latestSolidMilestoneTracker, SeenMilestonesRetriever seenMilestonesRetriever, LedgerService ledgerService, TransactionPruner transactionPruner, MilestoneSolidifier milestoneSolidifier, BundleValidator bundleValidator, Tangle tangle, TransactionValidator transactionValidator, TransactionRequester transactionRequester, NeighborRouter neighborRouter, TransactionProcessingPipeline transactionProcessingPipeline, TipsRequester tipsRequester, TipsViewModel tipsViewModel, TipSelector tipsSelector, TransactionSolidifier transactionSolidifier) {
this.configuration = configuration;

this.ledgerService = ledgerService;
Expand All @@ -134,6 +138,7 @@ public Iota(IotaConfig configuration, SpentAddressesProvider spentAddressesProvi
this.neighborRouter = neighborRouter;
this.txPipeline = transactionProcessingPipeline;
this.tipsRequester = tipsRequester;
this.transactionSolidifier = transactionSolidifier;

// legacy classes
this.bundleValidator = bundleValidator;
Expand Down Expand Up @@ -185,8 +190,6 @@ public void init() throws Exception {
tangle.clearMetadata(com.iota.iri.model.persistables.Transaction.class);
}

transactionValidator.init();

txPipeline.start();
neighborRouter.start();
tipsRequester.start();
Expand All @@ -195,6 +198,7 @@ public void init() throws Exception {
latestSolidMilestoneTracker.start();
seenMilestonesRetriever.start();
milestoneSolidifier.start();
transactionSolidifier.start();

if (localSnapshotManager != null) {
localSnapshotManager.start(latestMilestoneTracker);
Expand Down Expand Up @@ -236,6 +240,7 @@ private void rescanDb() throws Exception {
public void shutdown() throws Exception {
// shutdown in reverse starting order (to not break any dependencies)
milestoneSolidifier.shutdown();
transactionSolidifier.shutdown();
seenMilestonesRetriever.shutdown();
latestSolidMilestoneTracker.shutdown();
latestMilestoneTracker.shutdown();
Expand All @@ -250,7 +255,6 @@ public void shutdown() throws Exception {
tipsRequester.shutdown();
txPipeline.shutdown();
neighborRouter.shutdown();
transactionValidator.shutdown();
tangle.shutdown();

// free the resources of the snapshot provider last because all other instances need it
Expand Down
17 changes: 13 additions & 4 deletions src/main/java/com/iota/iri/MainInjectionConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
import com.iota.iri.service.tipselection.impl.WalkerAlpha;
import com.iota.iri.service.transactionpruning.TransactionPruner;
import com.iota.iri.service.transactionpruning.async.AsyncTransactionPruner;
import com.iota.iri.service.validation.TransactionSolidifier;
import com.iota.iri.service.validation.TransactionValidator;
import com.iota.iri.service.validation.impl.TransactionSolidifierImpl;
import com.iota.iri.storage.Persistable;
import com.iota.iri.storage.PersistenceProvider;
import com.iota.iri.storage.Tangle;
Expand Down Expand Up @@ -137,8 +140,8 @@ SeenMilestonesRetriever provideSeenMilestonesRetriever(Tangle tangle, SnapshotPr

@Singleton
@Provides
MilestoneSolidifier provideMilestoneSolidifier(SnapshotProvider snapshotProvider, TransactionValidator transactionValidator) {
return new MilestoneSolidifierImpl(snapshotProvider, transactionValidator);
MilestoneSolidifier provideMilestoneSolidifier(SnapshotProvider snapshotProvider, TransactionSolidifier transactionSolidifier) {
return new MilestoneSolidifierImpl(snapshotProvider, transactionSolidifier);
}

@Singleton
Expand All @@ -163,6 +166,12 @@ TransactionValidator provideTransactionValidator(Tangle tangle, SnapshotProvider
return new TransactionValidator(tangle, snapshotProvider, tipsViewModel, transactionRequester, configuration);
}

@Singleton
@Provides
TransactionSolidifier provideTransactionSolidifier(Tangle tangle, SnapshotProvider snapshotProvider, TransactionRequester transactionRequester){
return new TransactionSolidifierImpl(tangle, snapshotProvider, transactionRequester);
}

@Singleton
@Provides
TipSelector provideTipSelector(Tangle tangle, SnapshotProvider snapshotProvider,
Expand All @@ -178,8 +187,8 @@ TipSelector provideTipSelector(Tangle tangle, SnapshotProvider snapshotProvider,

@Singleton
@Provides
Iota provideIota(SpentAddressesProvider spentAddressesProvider, SpentAddressesService spentAddressesService, SnapshotProvider snapshotProvider, SnapshotService snapshotService, @Nullable LocalSnapshotManager localSnapshotManager, MilestoneService milestoneService, LatestMilestoneTracker latestMilestoneTracker, LatestSolidMilestoneTracker latestSolidMilestoneTracker, SeenMilestonesRetriever seenMilestonesRetriever, LedgerService ledgerService, @Nullable TransactionPruner transactionPruner, MilestoneSolidifier milestoneSolidifier, BundleValidator bundleValidator, Tangle tangle, TransactionValidator transactionValidator, TransactionRequester transactionRequester, NeighborRouter neighborRouter, TransactionProcessingPipeline transactionProcessingPipeline, TipsRequester tipsRequester, TipsViewModel tipsViewModel, TipSelector tipsSelector) {
return new Iota(configuration, spentAddressesProvider, spentAddressesService, snapshotProvider, snapshotService, localSnapshotManager, milestoneService, latestMilestoneTracker, latestSolidMilestoneTracker, seenMilestonesRetriever, ledgerService, transactionPruner, milestoneSolidifier, bundleValidator, tangle, transactionValidator, transactionRequester, neighborRouter, transactionProcessingPipeline, tipsRequester, tipsViewModel, tipsSelector);
Iota provideIota(SpentAddressesProvider spentAddressesProvider, SpentAddressesService spentAddressesService, SnapshotProvider snapshotProvider, SnapshotService snapshotService, @Nullable LocalSnapshotManager localSnapshotManager, MilestoneService milestoneService, LatestMilestoneTracker latestMilestoneTracker, LatestSolidMilestoneTracker latestSolidMilestoneTracker, SeenMilestonesRetriever seenMilestonesRetriever, LedgerService ledgerService, @Nullable TransactionPruner transactionPruner, MilestoneSolidifier milestoneSolidifier, BundleValidator bundleValidator, Tangle tangle, TransactionValidator transactionValidator, TransactionRequester transactionRequester, NeighborRouter neighborRouter, TransactionProcessingPipeline transactionProcessingPipeline, TipsRequester tipsRequester, TipsViewModel tipsViewModel, TipSelector tipsSelector, TransactionSolidifier transactionSolidifier) {
return new Iota(configuration, spentAddressesProvider, spentAddressesService, snapshotProvider, snapshotService, localSnapshotManager, milestoneService, latestMilestoneTracker, latestSolidMilestoneTracker, seenMilestonesRetriever, ledgerService, transactionPruner, milestoneSolidifier, bundleValidator, tangle, transactionValidator, transactionRequester, neighborRouter, transactionProcessingPipeline, tipsRequester, tipsViewModel, tipsSelector, transactionSolidifier);
}

@Singleton
Expand Down
18 changes: 2 additions & 16 deletions src/main/java/com/iota/iri/controllers/TransactionViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.iota.iri.model.*;
import com.iota.iri.model.persistables.*;
import com.iota.iri.service.snapshot.Snapshot;
import com.iota.iri.service.validation.TransactionValidator;
import com.iota.iri.storage.Indexable;
import com.iota.iri.storage.Persistable;
import com.iota.iri.storage.Tangle;
Expand Down Expand Up @@ -712,26 +713,11 @@ public void setMetadata() {
: TransactionViewModel.FILLED_SLOT;
}

public static void updateSolidTransactions(Tangle tangle, Snapshot initialSnapshot, final LinkedHashSet<Hash> analyzedHashes)
throws Exception {
Object[] hashes = analyzedHashes.toArray();
TransactionViewModel transactionViewModel;
for(int i = hashes.length -1; i >= 0; i--){
transactionViewModel = TransactionViewModel.fromHash(tangle, (Hash) hashes[i]);

transactionViewModel.updateHeights(tangle, initialSnapshot);

if (!transactionViewModel.isSolid()) {
transactionViewModel.updateSolid(true);
transactionViewModel.update(tangle, initialSnapshot, "solid|height");
}
}
}

/**
* Updates the {@link Transaction#solid} value of the referenced {@link Transaction} object.
*
* Used by the {@link com.iota.iri.TransactionValidator} to quickly set the solidity of a {@link Transaction} set.
* Used by the {@link TransactionValidator} to quickly set the solidity of a {@link Transaction} set.
*
* @param solid The solidity of the transaction in the database
* @return True if the {@link Transaction#solid} has been updated, False if not.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.iota.iri.TransactionValidator;
import com.iota.iri.service.validation.TransactionSolidifier;
import com.iota.iri.service.validation.TransactionValidator;
import com.iota.iri.conf.IotaConfig;
import com.iota.iri.controllers.TipsViewModel;
import com.iota.iri.network.impl.TipsRequesterImpl;
Expand Down Expand Up @@ -46,9 +47,9 @@ TipsRequester provideTipsRequester(NeighborRouter neighborRouter, Tangle tangle,
TransactionProcessingPipeline provideTransactionProcessingPipeline(NeighborRouter neighborRouter,
TransactionValidator txValidator, Tangle tangle, SnapshotProvider snapshotProvider,
TipsViewModel tipsViewModel, LatestMilestoneTracker latestMilestoneTracker,
TransactionRequester transactionRequester) {
TransactionRequester transactionRequester, TransactionSolidifier transactionSolidifier) {
return new TransactionProcessingPipelineImpl(neighborRouter, configuration, txValidator, tangle,
snapshotProvider, tipsViewModel, latestMilestoneTracker, transactionRequester);
snapshotProvider, tipsViewModel, latestMilestoneTracker, transactionRequester, transactionSolidifier);
}

@Singleton
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.iota.iri.network.pipeline;

import com.iota.iri.TransactionValidator;
import com.iota.iri.service.validation.TransactionValidator;
import com.iota.iri.controllers.TransactionViewModel;
import com.iota.iri.network.TransactionRequester;
import com.iota.iri.network.neighbor.Neighbor;
Expand Down Expand Up @@ -91,8 +91,8 @@ public ProcessingContext process(ProcessingContext ctx) {
}

// broadcast the newly saved tx to the other neighbors
ctx.setNextStage(TransactionProcessingPipeline.Stage.BROADCAST);
ctx.setPayload(new BroadcastPayload(originNeighbor, tvm));
ctx.setNextStage(TransactionProcessingPipeline.Stage.SOLIDIFY);
ctx.setPayload(new SolidifyPayload(originNeighbor, tvm));
return ctx;
}
}
39 changes: 39 additions & 0 deletions src/main/java/com/iota/iri/network/pipeline/SolidifyPayload.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.iota.iri.network.pipeline;

import com.iota.iri.controllers.TransactionViewModel;
import com.iota.iri.network.neighbor.Neighbor;

/**
* Defines a payload which gets submitted to the {@link SolidifyStage}.
*/
public class SolidifyPayload extends Payload {
private Neighbor originNeighbor;
private TransactionViewModel tvm;

/**
* Constructor for solidification payload.
*
* @param originNeighbor The originating point of a received transaction
* @param tvm The transaction that needs to be solidified
*/
public SolidifyPayload(Neighbor originNeighbor, TransactionViewModel tvm){
this.originNeighbor = originNeighbor;
this.tvm = tvm;
}

/**
* {@inheritDoc}
*/
@Override
public Neighbor getOriginNeighbor(){
return originNeighbor;
}

/**
* Fetches the transaction from the payload.
* @return The transaction stored in the payload.
*/
public TransactionViewModel getTransaction(){
return tvm;
}
}
108 changes: 108 additions & 0 deletions src/main/java/com/iota/iri/network/pipeline/SolidifyStage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package com.iota.iri.network.pipeline;

import com.google.common.annotations.VisibleForTesting;
import com.iota.iri.controllers.TipsViewModel;
import com.iota.iri.controllers.TransactionViewModel;
import com.iota.iri.model.Hash;
import com.iota.iri.service.validation.TransactionSolidifier;
import com.iota.iri.service.validation.TransactionValidator;
import com.iota.iri.storage.Tangle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.iota.iri.controllers.TransactionViewModel.fromHash;

/**
* The {@link SolidifyStage} is used to process newly received transaction for solidity. Once a transaction has been
* passed from the {@link ReceivedStage} it will be placed into this stage to have the {@link TransactionSolidifier}
* check the solidity of the transaction. If the transaction is found to be solid, it will be passed forward to the
* {@link BroadcastStage}. If it is found to be unsolid, it is put through the solidity check so that missing reference
* transactions get requested. If the transaction is unsolid, a random solid tip is broadcast instead to keep the
* requests transmitting to neighbors.
*/
public class SolidifyStage implements Stage {
private static final Logger log = LoggerFactory.getLogger(SolidifyStage.class);

private TransactionSolidifier txSolidifier;
private TransactionValidator txValidator;
private TipsViewModel tipsViewModel;
private Tangle tangle;
private TransactionViewModel tip;

/**
* Constructor for the {@link SolidifyStage}.
*
* @param txSolidifier Transaction solidifier implementation for updating transaction's solidity status
* @param txValidator Transaction validator implementation for determining the validity of a transaction
* @param tipsViewModel Used for broadcasting random solid tips if the subject transaction is unsolid
* @param tangle A reference to the nodes DB
*/
public SolidifyStage(TransactionSolidifier txSolidifier, TransactionValidator txValidator,
TipsViewModel tipsViewModel, Tangle tangle){
this.txSolidifier = txSolidifier;
this.txValidator = txValidator;
this.tipsViewModel = tipsViewModel;
this.tangle = tangle;
}

/**
* Processes the payload of the {@link ProcessingContext} as a {@link SolidifyPayload}. First the transaction will
* be checked for solidity and validity. If the transaction is already solid or can be set solid quickly by the
* transaction validator, the transaction is passed to the {@link BroadcastStage}. If not, the transaction is
* added to the solidification queue, and a random solid tip is pulled form the {@link TipsViewModel} to be
* broadcast instead.
*
* @param ctx The context to process
* @return The output context, in most cases a {@link BroadcastPayload}.
*/
@Override
public ProcessingContext process(ProcessingContext ctx){
try {
SolidifyPayload payload = (SolidifyPayload) ctx.getPayload();
TransactionViewModel tvm = payload.getTransaction();

if (tvm.isSolid() || txValidator.quickSetSolid(tvm)) {
ctx.setNextStage(TransactionProcessingPipeline.Stage.BROADCAST);
ctx.setPayload(new BroadcastPayload(payload.getOriginNeighbor(), payload.getTransaction()));
return ctx;
}

txSolidifier.addToSolidificationQueue(tvm.getHash());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally missed...
Delete this line :-P

Explanation:
What you are basically doing here is reviving the old tip solidifier...
We decided that we don't need to actively request transactions that are not needed to solidify milestones.
This is because:
a. It is most likely that most txs will get quickly solid
b. If not due to receiving txs out of order then they should get solid by propagateSolidTransactions (this is optional and could be left out, maybe)
c. Else they may either become solid by milestone or never become solid

Basically, we assume that a&b will be enough most of the time, and if not a milestone will fix the situation.
If a milestone never comes then it doesn't matter because they are not in a consensus state.

The problems with actively requesting transactions for solidifying are:

  1. We are wasting bandwidth to request txs that will not be approved
  2. A malicious actor can slow us down by sending txs that approve imaginary txs


return broadcastTip(ctx, payload);
}catch (Exception e){
log.error("Failed to process transaction for solidification", e);
ctx.setNextStage(TransactionProcessingPipeline.Stage.ABORT);
return ctx;
}

}

private ProcessingContext broadcastTip(ProcessingContext ctx, SolidifyPayload payload) throws Exception{
if(tip == null) {
Hash tipHash = tipsViewModel.getRandomSolidTipHash();

if (tipHash == null) {
ctx.setNextStage(TransactionProcessingPipeline.Stage.FINISH);
return ctx;
}

tip = fromHash(tangle, tipHash);
}

if(tip.isSolid()) {
ctx.setNextStage(TransactionProcessingPipeline.Stage.BROADCAST);
ctx.setPayload(new BroadcastPayload(payload.getOriginNeighbor(), tip));
return ctx;
}

ctx.setNextStage(TransactionProcessingPipeline.Stage.FINISH);
return ctx;
}

@VisibleForTesting
void injectTip(TransactionViewModel tvm) throws Exception {
tip = tvm;
tip.updateSolid(true);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.iota.iri.network.pipeline;

import com.iota.iri.network.neighbor.Neighbor;
import com.iota.iri.service.validation.TransactionSolidifier;

import java.nio.ByteBuffer;
import java.util.concurrent.BlockingQueue;
Expand All @@ -14,7 +15,7 @@ public interface TransactionProcessingPipeline {
* Defines the different stages of the {@link TransactionProcessingPipelineImpl}.
*/
enum Stage {
PRE_PROCESS, HASHING, VALIDATION, REPLY, RECEIVED, BROADCAST, MULTIPLE, ABORT, FINISH,
PRE_PROCESS, HASHING, VALIDATION, REPLY, RECEIVED, BROADCAST, MULTIPLE, ABORT, FINISH, SOLIDIFY,
}

/**
Expand Down Expand Up @@ -65,6 +66,12 @@ enum Stage {
*/
void process(byte[] txTrits);

/**
* Fetches a set of transactions from the {@link TransactionSolidifier} and submits
* the object into the {@link BroadcastStage} queue.
*/
void refillBroadcastQueue();

/**
* Shut downs the pipeline by shutting down all stages.
*/
Expand Down Expand Up @@ -111,4 +118,11 @@ enum Stage {
* @param hashingStage the {@link HashingStage} to use
*/
void setHashingStage(HashingStage hashingStage);

/**
* Sets the solidify stage. This method should only be used for injecting mocked objects.
*
* @param solidifyStage the {@link SolidifyStage} to use
*/
void setSolidifyStage(SolidifyStage solidifyStage);
}
Loading