Skip to content

Conversation

@dmitry-worker
Copy link
Contributor

Description

Concurrent EthashConsensus.startMiningProcess() method invocation can lead to several miner actors.
There's no thread mutual exclusion and atomicity between AtomicReference.get() and AtomicReference.set() calls.

Proposed Solution

synchronized or ReentrantReadWrite is recommended to ensure that only one miner is created.
AtomicReference is redundant, since no CAS-related methods are used.
Solution assumes that no thread synchronization is needed when miner already exists.

@dmitry-worker dmitry-worker changed the title Fixed concurrency issue to ensure that only one miner is created. Fixed concurrency issue that allowed multiple miners instantiation. Nov 5, 2020
@mmrozek
Copy link
Contributor

mmrozek commented Nov 19, 2020

Good catch, but I think the simpler solution is to use atomicMiner.getAndUpdate. WDYT?

@dmitry-worker
Copy link
Contributor Author

dmitry-worker commented Nov 21, 2020

Good catch, but I think the simpler solution is to use atomicMiner.getAndUpdate. WDYT?
Thanks!

I was actually about to implement one of CompareAndSet-based methods, like getAndUpdate.
But one thing stops me doing that: the side effect that initializes a new Actor in the ActorSystem

            case Ethash => EthashMiner(node)
            case MockedPow => MockedMiner(node)

^ Those lines create a new actor in a system as a side effect.

Although getAndUpdate will guarantee that minerRef equals our newly created Actor at some point -
it cannot guarantee that no other miners are instantiated as well when the same method is called.
So, only mutual exclusion helped me to solve this :(

.getOrElse(Future.successful(MinerNotExist))
}

private[this] val mutex = new Object
Copy link
Contributor

Choose a reason for hiding this comment

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

locks/mutex/semaphores are low level, declarative programming approach to concurrencly. They are hard to maintain and super hard to write correctly.

Would it be possible to use sth like STM here. Maybe Ref from cats effect: https://typelevel.org/cats-effect/concurrency/ref.html

blockchain = blockchain,
blockchainConfig = blockchainConfig
)

Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible to write a test that will show the problem/solution?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants