-
Notifications
You must be signed in to change notification settings - Fork 75
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
[ETCM-263] improve BlockImport wrt checkpoints - ChainWeight #769
Conversation
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.
only minor things
val newBlockNr = block.number | ||
val nextExpectedBlock = state.lastFullBlockNumber + 1 | ||
|
||
println("CODO KURWY???") |
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.
💯 ❤️ 💟
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.
😅
def getChainWeightByNumber(blockNumber: BigInt): Option[ChainWeight] = | ||
getHashByBlockNumber(blockNumber).flatMap(getChainWeightByHash) | ||
|
||
// /** |
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.
can be removed now
|
||
object ChainWeight { | ||
//FIXME: a shorter name? | ||
def totalDifficultyOnly(td: BigInt): ChainWeight = |
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.
hmm totalDifficulty
for me looks ok too.
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.
I'd rather have these extra 4 letters to distinguish from ChainWeight#totalDifficulty
|
||
//Test API | ||
|
||
def increaseTd(td: BigInt): ChainWeight = |
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.
increaseTd => increaseTotalDifficulty
ChainWeight(0, 0) | ||
} | ||
|
||
case class ChainWeight( |
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.
❤️
RLPList( | ||
protocolVersion, | ||
networkId, | ||
//TODO: should it be an RLPList? Should we define encoding in ChainWeight object? |
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.
👍 for encoding in ChainWeight object but move it to the end or merge both RLPLists into one
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.
I'm not yet sure how to handle that while keeping the compatibility with v63 messages
RLPList( | ||
RLPList( | ||
block.header.toRLPEncodable, | ||
RLPList(block.body.transactionList.map(_.toRLPEncodable): _*), | ||
RLPList(block.body.uncleNodesList.map(_.toRLPEncodable): _*) | ||
), | ||
totalDifficulty, | ||
latestCheckpointNumber | ||
//TODO: should it be an RLPList? Should we define encoding in ChainWeight object? |
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.
ditto
@@ -103,6 +103,9 @@ object ByteUtils { | |||
ByteString(compactPickledBytesToArray(buffer)) | |||
} | |||
|
|||
def byteSequenceToBuffer(bytes: IndexedSeq[Byte]): ByteBuffer = |
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.
Can you use it in other KeyValueStorages ?
src/test/resources/logback-test.xml
Outdated
@@ -10,7 +10,7 @@ | |||
|
|||
<logger name="io.iohk.ethereum.vm.VM" level="OFF" /> | |||
|
|||
<root level="INFO"> | |||
<root level="DEBUG"> |
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.
is it spamming too much ?
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.
Reverted
@@ -92,7 +92,10 @@ class RegularSyncSpec | |||
regularSync ! SyncProtocol.Start | |||
|
|||
peerEventBus.expectMsgClass(classOf[Subscribe]) | |||
peerEventBus.reply(MessageFromPeer(NewBlock(testBlocks.last, testBlocks.last.number), defaultPeer.id)) | |||
// It's weird that we're using block number for total difficulty but I'm too scared to fight this dragon |
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.
😂
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.
This test continues to be the most difficult one to follow, at least among the ones I've dealt with recently
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.
First round of comments
src/main/scala/io/iohk/ethereum/db/storage/ReceiptStorage.scala
Outdated
Show resolved
Hide resolved
case Left(executionError) => | ||
go(executedBlocks, remainingBlocks, 0, Some(executionError)) | ||
go(executedBlocks, remainingBlocks, parentWeight, Some(executionError)) |
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.
Instead of parentWeight
shouldn't it be parentWeight.increase(blockToExecute.header)
? The next block to be executed will be the son of the current one
Although I'm not sure what's the purpose of continuing executing a branch on which one of the blocks failed to be executed
@@ -43,6 +43,8 @@ object EthereumMessageDecoder extends MessageDecoder { | |||
//wire protocol | |||
case (_, Hello.code) => payload.toHello | |||
|
|||
//FIXME: I still have an issue with protocolVersion, we are use PV62 and PV63 and code names for Status and NewBlock | |||
// suggest that there is PV64, but there isn't |
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.
Hmm now that you say it makes sense to have a PV64
It's weird that ETC has some duplication between the capability from Hello messages and this status field (we even use the same Versions.PV63
variable), but in copying them we should probably have that duplication as well
It might also be worth researching the difference in purposes between the 2 in case we are missing something
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.
Should we research that as part of 280? Or maybe a separate task?
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.
Hmm maybe it would be better to make it part of ETCM-280? In order to be sure of the approach we are taking there
We could split it later into more tasks if we detect that it's taking longer than expected
src/main/scala/io/iohk/ethereum/blockchain/sync/regular/BlockImporter.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/network/handshaker/EtcNodeStatusExchangeState.scala
Show resolved
Hide resolved
a914015
to
7dd7354
Compare
@@ -118,7 +118,13 @@ class GenesisDataLoader(blockchain: Blockchain, blockchainConfig: BlockchainConf | |||
case None => | |||
storage.persist() | |||
stateStorage.forcePersist(GenesisDataLoad) | |||
blockchain.save(Block(header, BlockBody(Nil, Nil)), Nil, header.difficulty, saveAsBestBlock = true) | |||
// TODO: factory for ChainWeight? |
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.
you have it already ;) ChainWeight.totalDifficultyOnly
@@ -31,7 +29,7 @@ class BlockHeadersStorage(val dataSource: DataSource) | |||
blockHeader => compactPickledBytes(Pickle.intoBytes(blockHeader)) | |||
|
|||
override def valueDeserializer: IndexedSeq[Byte] => BlockHeader = | |||
bytes => Unpickle[BlockHeader].fromBytes(ByteBuffer.wrap(bytes.toArray[Byte])) | |||
byteSequenceToBuffer _ andThen Unpickle[BlockHeader].fromBytes |
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.
WDYT about creating helper for byteSequenceToBuffer _ andThen Unpickle[Type].fromBytes
?
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.
I'd prefer to merge it ASAP, but added a TODO
case (None, None) => | ||
compareByDifficulty(newBranch, oldBranch) | ||
case None => | ||
// TODO: should we log if parentWeight not found? |
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.
why not
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.
Cause the code would be ugly :) This match
doesn't capture the situation - there could be no parent to get the weight for
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.
Maybe we could change it a bit it to detect that case? More of this logs never bothered, we never know when it will be useful
def genesisHash: ByteString | ||
genesisHash: ByteString | ||
): Status = | ||
//TODO: explain, remove if possible |
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.
? :)
def as63: NewBlock63 = | ||
NewBlock63(block, totalDifficulty) | ||
def apply(block: Block, chainWeight: ChainWeight): NewBlock = | ||
//TODO: explain, remove if possible |
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.
? :)
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.
Last comments, got to take a look at all the changes!
Code is looking much nicer ❤️
case (None, None) => | ||
compareByDifficulty(newBranch, oldBranch) | ||
case None => | ||
// TODO: should we log if parentWeight not found? |
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.
Maybe we could change it a bit it to detect that case? More of this logs never bothered, we never know when it will be useful
src/test/scala/io/iohk/ethereum/blockchain/sync/regular/RegularSyncSpec.scala
Show resolved
Hide resolved
src/test/scala/io/iohk/ethereum/db/storage/ChainWeightStorageSuite.scala
Outdated
Show resolved
Hide resolved
@@ -43,6 +43,8 @@ object EthereumMessageDecoder extends MessageDecoder { | |||
//wire protocol | |||
case (_, Hello.code) => payload.toHello | |||
|
|||
//FIXME: I still have an issue with protocolVersion, we are use PV62 and PV63 and code names for Status and NewBlock | |||
// suggest that there is PV64, but there isn't |
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.
Hmm maybe it would be better to make it part of ETCM-280? In order to be sure of the approach we are taking there
We could split it later into more tasks if we detect that it's taking longer than expected
src/main/scala/io/iohk/ethereum/network/p2p/messages/CommonMessages.scala
Show resolved
Hide resolved
src/test/scala/io/iohk/ethereum/blockchain/sync/BlockBroadcastSpec.scala
Show resolved
Hide resolved
7dd7354
to
5ef06b3
Compare
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.
Synced 50k blocks from mordor without any problems! Though I had to fix an issue
.orElse(newHeaders.headOption) | ||
.map { header => | ||
blockchain | ||
.getChainWeightByHash(header.hash) |
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.
Shouldn't we fetch here for the header.parentHash? Syncing to mordor fails if not due to ChainWeight for 1 not found when resolving branch
5ef06b3
to
ee341ce
Compare
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.
LGTM! Syncing to mordor now works, played a bit around with the mocked miner and qa checkpoints and it all worked
.\\ //.
. \ \ / /.
.\ ,\ /` /,.-
-. \ /'/ / .
` - `-' \ -
'. /.\`
- .-
:`//.'
.`.'
.' BP
ee341ce
to
6e722c8
Compare
Description
Improves branch comparison wrt checkpoints during block import
Proposed Solution
Introduces a unified idea of
ChainWeight
Testing
Unit tests