-
Notifications
You must be signed in to change notification settings - Fork 2
mvp2 - planner #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
GusevTimofey
wants to merge
111
commits into
master
Choose a base branch
from
mvp2-planner
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
mvp2 - planner #43
Changes from 69 commits
Commits
Show all changes
111 commits
Select commit
Hold shift + click to select a range
4574cb3
initial commit
GusevTimofey e3413b5
added planner logic
GusevTimofey 0d10706
tests
GusevTimofey 880dc0e
tests
GusevTimofey fcd2152
tests
GusevTimofey f5ba488
tests
GusevTimofey d993e76
tests
GusevTimofey 3111e4d
changed logic with keys
GusevTimofey 045cdcf
tests
GusevTimofey dbd040e
tests
GusevTimofey cc4f96f
tests
GusevTimofey d73f951
tests
GusevTimofey 82d7ea9
tests
GusevTimofey 9fbd0ae
tests
GusevTimofey 66920eb
tests
GusevTimofey 975921d
tests
GusevTimofey 8f79637
tests
GusevTimofey 8c94469
tests
GusevTimofey 778cd9d
tests
GusevTimofey 4ddb430
tests
GusevTimofey 7fc3c61
tests
GusevTimofey f045691
tests
GusevTimofey b01512c
tests
GusevTimofey 7c38e2e
tests
GusevTimofey 7a4ce05
tests
GusevTimofey 2dbf2a7
tests
GusevTimofey 47b405f
tests
GusevTimofey d862fae
Merge branch 'master' into mvp2-planner
GusevTimofey efb40da
tests
GusevTimofey 80aa075
tests
GusevTimofey 85af2d7
Some additions
Bromel777 8393e40
Merge remote-tracking branch 'origin/mvp2-planner' into mvp2-planner
Bromel777 17dc4e5
Some additions
Bromel777 51e230f
tests
GusevTimofey d755a07
Some additions
Bromel777 f3d55a2
tests
GusevTimofey 403f05e
Merge branch 'master' into mvp2-planner
GusevTimofey 136a5e7
merged
GusevTimofey efb49a4
Some additions
Bromel777 67d9002
merged
GusevTimofey b48080b
Some additions
Bromel777 921aa27
Some additions
Bromel777 f6c2834
Some additions
Bromel777 ba6115f
Some additions
Bromel777 520feba
Some additions
Bromel777 1f3c7fc
Add knownPeers test
Bromel777 c814569
Some additions
Bromel777 452bc82
qtyOfPrepareSchedulerSteps 15 -> 5
Bromel777 1e0a8b2
added schedule in first epoch block
GusevTimofey df54631
Merge remote-tracking branch 'origin/mvp2-planner' into mvp2-planner
GusevTimofey fc5d232
move multiplier to settings
Bromel777 c9ca5f6
added tests
GusevTimofey 0de1f43
fixed sorting
GusevTimofey 482f305
fixed sorting
GusevTimofey 84a09e3
Some additions
Bromel777 a06fa55
Some additions
Bromel777 3e10a6c
Rename
Bromel777 196cdb3
fixed allKeys collection
GusevTimofey 7f42438
Some additions
Bromel777 2e34a88
Merge master
Bromel777 88c4964
some additions
GusevTimofey f0f02e6
some additions
GusevTimofey 8c23952
some additions
GusevTimofey 71faa4d
some additions
GusevTimofey 3c7ba11
Remove updating last response peer time, during height msg sending
Bromel777 f6986b0
Merge remote-tracking branch 'origin/mvp2-planner' into mvp2-planner
Bromel777 4345a80
some additions
GusevTimofey e64fc00
Change condition of sending height msg
Bromel777 5519118
Change sync condition
Bromel777 67b64f5
Increase time to block period
Bromel777 19ddfec
Some additions
Bromel777 9ea08c9
added logic for syncing epoch
GusevTimofey a666490
added logic for syncing epoch
GusevTimofey 486ab7c
Merge remote-tracking branch 'origin/mvp2-planner' into mvp2-planner
GusevTimofey 6a1ebbd
added logic for syncing epoch
GusevTimofey 2f7247d
Change case class Epoch. Remove height
Bromel777 10af3a9
Merge remote-tracking branch 'origin/mvp2-planner' into mvp2-planner
Bromel777 7dd0670
Remove schedule from blockcache
Bromel777 72ae971
qtyOfPrepareSchedulerSteps 5 -> 1
Bromel777 40a99e7
travis, hi!
Bromel777 cb5780c
plannerHeartbeat 2000 -> 200
Bromel777 dfcb602
allPublicKeys (Set -> List). New logging
Bromel777 4565716
Fix tests
Bromel777 8bc8f8c
New logging
Bromel777 65dc1da
added logic for syncing epoch
GusevTimofey 413029a
added logic for syncing epoch
GusevTimofey e995f96
added logic for syncing epoch
GusevTimofey 05d29be
Remove hasWritten
Bromel777 9a70999
Remove lastblock from schedule
Bromel777 d06a86a
Add logging
Bromel777 8978ea9
Add logging
Bromel777 452989e
Add sorting allpublicKeys
Bromel777 4320dbb
Add deleting peer when get block with schedule
Bromel777 f5af81d
added some logging
GusevTimofey 12d4b5e
added some logging
GusevTimofey 07c667a
added some logging
GusevTimofey 6d20131
fixed epoch
GusevTimofey 0fe198d
fixed epoch
GusevTimofey 55b555c
fixed epoch
GusevTimofey 5134d9e
fixed epoch
GusevTimofey 4e6c2ed
fixed epoch
GusevTimofey 37e664c
fixed epoch
GusevTimofey d7f40c8
fixed epoch
GusevTimofey 06a7f40
fixed epoch
GusevTimofey 7fa363a
fixed epoch
GusevTimofey a07ec57
fixed epoch
GusevTimofey 1af0afe
fixed epoch
GusevTimofey 7df62e0
fixed epoch
GusevTimofey 85ada5d
fixed epoch
GusevTimofey d3c4046
fixed epoch
GusevTimofey e577e74
fixed epoch
GusevTimofey File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,14 @@ | ||
| package mvp2.actors | ||
|
|
||
| import java.security.{KeyPair, PublicKey} | ||
| import akka.actor.{ActorRef, ActorSelection, Cancellable, Props} | ||
| import mvp2.data.InnerMessages.{Get, MyPublicKey, PeerPublicKey} | ||
| import akka.actor.{ActorRef, Props} | ||
| import akka.actor.{ActorSelection, Cancellable} | ||
| import akka.util.ByteString | ||
| import com.typesafe.scalalogging.StrictLogging | ||
| import mvp2.actors.Planner.Epoch | ||
| import mvp2.data.InnerMessages._ | ||
| import mvp2.data.KeyBlock | ||
| import mvp2.utils.{ECDSA, EncodingUtils, Settings} | ||
| import mvp2.utils.{EncodingUtils, Settings} | ||
| import scala.collection.immutable.SortedMap | ||
| import scala.concurrent.duration._ | ||
| import scala.language.postfixOps | ||
| import scala.concurrent.ExecutionContext.Implicits.global | ||
|
|
@@ -15,31 +19,87 @@ class Planner(settings: Settings) extends CommonActor { | |
|
|
||
| var nextTurn: Period = Period(KeyBlock(), settings) | ||
| val keyKeeper: ActorRef = context.actorOf(Props(classOf[KeyKeeper]), "keyKeeper") | ||
| val myKeys: KeyPair = ECDSA.createKeyPair | ||
| var allPublicKeys: Set[PublicKey] = Set.empty[PublicKey] | ||
| var myPublicKey: ByteString = ByteString.empty | ||
| var allPublicKeys: Set[ByteString] = Set() | ||
| var nextPeriod: Period = Period(KeyBlock(), settings) | ||
| if (settings.canPublishBlocks) | ||
| context.system.scheduler.schedule(0 seconds, settings.plannerHeartbeat milliseconds, self, Tick) | ||
| var lastBlock: KeyBlock = KeyBlock() | ||
| var epoch: Epoch = Epoch(SortedMap()) | ||
| var nextEpoch: Option[Epoch] = None | ||
| val heartBeat: Cancellable = | ||
| context.system.scheduler.schedule(10.seconds, settings.plannerHeartbeat milliseconds, self, Tick) | ||
| val publisher: ActorSelection = context.system.actorSelection("/user/starter/blockchainer/publisher") | ||
| val networker: ActorSelection = context.system.actorSelection("/user/starter/blockchainer/networker") | ||
| var scheduleForWriting: List[ByteString] = List() | ||
| var hasWritten: Boolean = false | ||
|
|
||
| override def specialBehavior: Receive = { | ||
| case GetNewScheduleFromRemote(shedule) => | ||
| logger.info(s"Got new schedule from remote") | ||
| epoch = Epoch(lastBlock, shedule.toSet, settings.epochMultiplier) | ||
| logger.info(s"Epoch from remote is: $epoch") | ||
| case SyncingDone => | ||
| logger.info(s"Synced done on Planner.") | ||
| if (settings.canPublishBlocks) | ||
| context.system.scheduler.schedule(0 seconds, settings.plannerHeartbeat milliseconds, self, Tick) | ||
| context.become(syncedNode) | ||
| case keyBlock: KeyBlock => lastBlock = keyBlock | ||
| case PeerPublicKey(key) => | ||
| allPublicKeys = allPublicKeys + key | ||
| logger.info(s"Set allPublickKeys to1: ${allPublicKeys.map(EncodingUtils.encode2Base16).mkString(",")}") | ||
| case MyPublicKey(key) => | ||
| logger.info(s"Set allPublickKeys to2: ${EncodingUtils.encode2Base16(key)}") | ||
| allPublicKeys = allPublicKeys + key | ||
| myPublicKey = key | ||
| if (settings.otherNodes.isEmpty) self ! SyncingDone | ||
| case _ => | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. planner extends CommonActor, case Any is useless |
||
| } | ||
|
|
||
| def syncedNode: Receive = { | ||
| case keyBlock: KeyBlock => | ||
| logger.info(s"Planner received new keyBlock with height: ${keyBlock.height}.") | ||
| if (!hasWritten && keyBlock.scheduler.nonEmpty) hasWritten = true | ||
| nextPeriod = Period(keyBlock, settings) | ||
| lastBlock = keyBlock | ||
| context.parent ! nextPeriod | ||
| case PeerPublicKey(key) => | ||
| logger.info(s"Got public key from remote: ${EncodingUtils.encode2Base16(ECDSA.compressPublicKey(key))} on Planner.") | ||
| allPublicKeys = allPublicKeys + key | ||
| case KeysForSchedule(keys) => | ||
| logger.info(s"Get peers public keys for schedule: ${keys.map(EncodingUtils.encode2Base16).mkString(",")}") | ||
| allPublicKeys = (keys :+ myPublicKey).sortWith((a, b) => a.utf8String.compareTo(b.utf8String) > 1).toSet | ||
| case MyPublicKey(key) => | ||
| logger.info("Get key") | ||
| allPublicKeys = allPublicKeys + key | ||
| myPublicKey = key | ||
| case Tick if epoch.isDone => | ||
| logger.info(s"epoch.isDone. Height of last block is: ${lastBlock.height}") | ||
| hasWritten = false | ||
| epoch = Epoch(lastBlock, allPublicKeys, settings.epochMultiplier) | ||
| logger.info(s"New epoch is: ${epoch.schedule}") | ||
| scheduleForWriting = epoch.schedule.values.toList | ||
| checkMyTurn(isFirstBlock = true, scheduleForWriting) | ||
| case Tick if nextPeriod.timeToPublish => | ||
| publisher ! Get | ||
| logger.info("Planner sent publisher request: time to publish!") | ||
| checkMyTurn(isFirstBlock = false, List()) | ||
| checkScheduleUpdateTime() | ||
| logger.info("nextPeriod.timeToPublish. Height of last block is: ${lastBlock.height}") | ||
| case Tick if nextPeriod.noBlocksInTime => | ||
| val newPeriod = Period(nextPeriod, settings) | ||
| logger.info(s"No blocks in time. Planner added ${newPeriod.exactTime - System.currentTimeMillis} milliseconds.") | ||
| nextPeriod = newPeriod | ||
| case Tick => | ||
| logger.info("nextPeriod.noBlocksInTime. Height of last block is: ${lastBlock.height}") | ||
| epoch = epoch.noBlockInTime | ||
| if (!hasWritten) checkMyTurn(isFirstBlock = true, scheduleForWriting) | ||
| else checkMyTurn(isFirstBlock = false, List()) | ||
| nextPeriod = Period(nextPeriod, settings) | ||
| context.parent ! nextPeriod | ||
| checkScheduleUpdateTime() | ||
| case Tick => logger.info("123") | ||
| } | ||
|
|
||
| def checkMyTurn(isFirstBlock: Boolean, schedule: List[ByteString]): Unit = { | ||
| if (epoch.nextBlock._2 == myPublicKey) publisher ! RequestForNewBlock(isFirstBlock, schedule) | ||
| context.parent ! ExpectedBlockPublicKeyAndHeight(epoch.nextBlock._1, epoch.nextBlock._2) | ||
| epoch = epoch.delete | ||
| } | ||
|
|
||
| def checkScheduleUpdateTime(): Unit = | ||
| if (epoch.prepareNextEpoch) { | ||
| networker ! PrepareScheduler | ||
| logger.info("epoch.prepareNextEpoch") | ||
| } | ||
| } | ||
|
|
||
| object Planner { | ||
|
|
@@ -62,31 +122,37 @@ object Planner { | |
| } | ||
|
|
||
| def apply(previousPeriod: Period, settings: Settings): Period = { | ||
| val exactTimestamp: Long = previousPeriod.exactTime + settings.blockPeriod / 2 | ||
| val exactTimestamp: Long = previousPeriod.exactTime + settings.blockPeriod | ||
| Period(exactTimestamp - settings.biasForBlockPeriod, exactTimestamp, exactTimestamp + settings.biasForBlockPeriod) | ||
| } | ||
| } | ||
|
|
||
| case class Epoch(schedule: Map[Long, PublicKey]) { | ||
| case class Epoch(schedule: SortedMap[Long, ByteString]) { | ||
|
|
||
| def nextBlock: (Long, PublicKey) = schedule.head | ||
| def nextBlock: (Long, ByteString) = schedule.head | ||
|
|
||
| def delete: Epoch = this.copy(schedule - schedule.head._1) | ||
| def delete: Epoch = this.copy(schedule.tail) | ||
|
|
||
| def delete(height: Long): Epoch = this.copy(schedule = schedule.drop(height.toInt)) | ||
| def delete(height: Long): Epoch = this.copy(schedule.drop(height.toInt)) | ||
|
|
||
| def noBlockInTime: Epoch = this.copy((schedule - schedule.head._1).map(each => (each._1 - 1, each._2))) | ||
| def noBlockInTime: Epoch = this.copy(schedule.map(each => (each._1 - 1, each._2))) | ||
|
|
||
| def isDone: Boolean = this.schedule.isEmpty | ||
|
|
||
| def prepareNextEpoch: Boolean = schedule.size <= 2 | ||
|
|
||
| override def toString: String = this.schedule.map(epochInfo => | ||
| s"Height: ${epochInfo._1} -> ${EncodingUtils.encode2Base16(epochInfo._2)}").mkString(",") | ||
| } | ||
|
|
||
| object Epoch { | ||
| def apply(lastKeyBlock: KeyBlock, publicKeys: List[PublicKey], multiplier: Int = 1): Epoch = { | ||
| object Epoch extends StrictLogging { | ||
| def apply(lastKeyBlock: KeyBlock, publicKeys: Set[ByteString], multiplier: Int = 1): Epoch = { | ||
| val startingHeight: Long = lastKeyBlock.height + 1 | ||
| val numberOfBlocksInEpoch: Int = publicKeys.size * multiplier | ||
| var schedule: Map[Long, PublicKey] = | ||
| (for (i <- startingHeight until startingHeight + numberOfBlocksInEpoch) | ||
| yield i).zip(publicKeys).toMap[Long, PublicKey] | ||
| val keysSchedule: List[ByteString] = (1 to multiplier).foldLeft(publicKeys.toList) { case (a, _) => a ::: a } | ||
| val schedule: SortedMap[Long, ByteString] = | ||
| SortedMap((for (i <- startingHeight until startingHeight + numberOfBlocksInEpoch) | ||
| yield i).zip(keysSchedule): _*) | ||
| Epoch(schedule) | ||
| } | ||
| } | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 variables with the same meaning
var epoch: Epoch = Epoch(SortedMap())
var nextEpoch: Option[Epoch] = None