-
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-355] Send fork id to peers #1030
Changes from all commits
8ca6e12
cd35475
355e494
7283008
1dea7d6
d068296
626d41a
367e6c4
0605e8e
eb751bc
fda64e9
224f32a
b0ec96e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,13 +30,21 @@ case class EtcHelloExchangeState(handshakerConfiguration: EtcHandshakerConfigura | |
override def applyResponseMessage: PartialFunction[Message, HandshakerState[PeerInfo]] = { case hello: Hello => | ||
log.debug("Protocol handshake finished with peer ({})", hello) | ||
// FIXME in principle this should be already negotiated | ||
Capability.negotiate(hello.capabilities.toList, handshakerConfiguration.capabilities) match { | ||
case Some(ProtocolVersions.ETC64) => EtcNodeStatus64ExchangeState(handshakerConfiguration) | ||
case Some(ProtocolVersions.ETH63) => EtcNodeStatus63ExchangeState(handshakerConfiguration) | ||
Capability.negotiate(hello.capabilities.toList, handshakerConfiguration.blockchainConfig.capabilities) match { | ||
case Some(ProtocolVersions.ETC64) => | ||
log.debug("Negotiated protocol version with client {} is etc/64", hello.clientId) | ||
EtcNodeStatus64ExchangeState(handshakerConfiguration) | ||
case Some(ProtocolVersions.ETH63) => | ||
log.debug("Negotiated protocol version with client {} is eth/63", hello.clientId) | ||
EthNodeStatus63ExchangeState(handshakerConfiguration) | ||
case Some(ProtocolVersions.ETH64) => | ||
log.debug("Negotiated protocol version with client {} is eth/64", hello.clientId) | ||
EthNodeStatus64ExchangeState(handshakerConfiguration) | ||
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. could you also fix the 'orElse' clause that I introduced ( 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. I would like to do this in a follow up PR, this one has become quite old and heavy |
||
case _ => | ||
log.debug( | ||
s"Connected peer does not support {} / {} protocol. Disconnecting.", | ||
s"Connected peer does not support {} / {} / {} protocol. Disconnecting.", | ||
ProtocolVersions.ETH63, | ||
ProtocolVersions.ETH64, | ||
ProtocolVersions.ETC64 | ||
) | ||
DisconnectedState(Disconnect.Reasons.IncompatibleP2pProtocolVersion) | ||
|
@@ -57,7 +65,7 @@ case class EtcHelloExchangeState(handshakerConfiguration: EtcHandshakerConfigura | |
Hello( | ||
p2pVersion = EtcHelloExchangeState.P2pVersion, | ||
clientId = Config.clientId, | ||
capabilities = handshakerConfiguration.capabilities, | ||
capabilities = handshakerConfiguration.blockchainConfig.capabilities, | ||
listenPort = listenPort, | ||
nodeId = ByteString(nodeStatus.nodeId) | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package io.iohk.ethereum.network.handshaker | ||
|
||
import io.iohk.ethereum.forkid.ForkId | ||
import io.iohk.ethereum.network.EtcPeerManagerActor.PeerInfo | ||
import io.iohk.ethereum.network.EtcPeerManagerActor.RemoteStatus | ||
import io.iohk.ethereum.network.p2p.Message | ||
import io.iohk.ethereum.network.p2p.MessageSerializable | ||
import io.iohk.ethereum.network.p2p.messages.ETH64 | ||
import io.iohk.ethereum.network.p2p.messages.ProtocolVersions | ||
|
||
case class EthNodeStatus64ExchangeState( | ||
handshakerConfiguration: EtcHandshakerConfiguration | ||
) extends EtcNodeStatusExchangeState[ETH64.Status] { | ||
|
||
import handshakerConfiguration._ | ||
|
||
def applyResponseMessage: PartialFunction[Message, HandshakerState[PeerInfo]] = { case status: ETH64.Status => | ||
// TODO: validate fork id of the remote peer | ||
applyRemoteStatusMessage(RemoteStatus(status)) | ||
} | ||
|
||
override protected def createStatusMsg(): MessageSerializable = { | ||
val bestBlockHeader = getBestBlockHeader() | ||
val chainWeight = blockchain.getChainWeightByHash(bestBlockHeader.hash).get | ||
val genesisHash = blockchainReader.genesisHeader.hash | ||
|
||
val status = ETH64.Status( | ||
protocolVersion = ProtocolVersions.ETH64.version, | ||
networkId = peerConfiguration.networkId, | ||
totalDifficulty = chainWeight.totalDifficulty, | ||
bestHash = bestBlockHeader.hash, | ||
genesisHash = genesisHash, | ||
forkId = ForkId.create(genesisHash, blockchainConfig)(blockchainReader.getBestBlockNumber()) | ||
) | ||
|
||
log.debug(s"Sending status $status") | ||
status | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package io.iohk.ethereum.network.p2p.messages | ||
|
||
import akka.util.ByteString | ||
|
||
import org.bouncycastle.util.encoders.Hex | ||
|
||
import io.iohk.ethereum.forkid.ForkId | ||
import io.iohk.ethereum.forkid.ForkId._ | ||
import io.iohk.ethereum.network.p2p.Message | ||
import io.iohk.ethereum.network.p2p.MessageSerializableImplicit | ||
import io.iohk.ethereum.rlp.RLPImplicitConversions._ | ||
import io.iohk.ethereum.rlp.RLPImplicits._ | ||
import io.iohk.ethereum.rlp._ | ||
|
||
object ETH64 { | ||
|
||
case class Status( | ||
protocolVersion: Int, | ||
networkId: Int, | ||
totalDifficulty: BigInt, | ||
bestHash: ByteString, | ||
genesisHash: ByteString, | ||
forkId: ForkId | ||
) extends Message { | ||
|
||
override def toString: String = | ||
s"Status { " + | ||
s"code: $code, " + | ||
s"protocolVersion: $protocolVersion, " + | ||
s"networkId: $networkId, " + | ||
s"totalDifficulty: $totalDifficulty, " + | ||
s"bestHash: ${Hex.toHexString(bestHash.toArray[Byte])}, " + | ||
s"genesisHash: ${Hex.toHexString(genesisHash.toArray[Byte])}," + | ||
s"forkId: $forkId," + | ||
s"}" | ||
|
||
override def toShortString: String = toString | ||
override def code: Int = Codes.StatusCode | ||
} | ||
|
||
object Status { | ||
implicit class StatusEnc(val underlyingMsg: Status) | ||
extends MessageSerializableImplicit[Status](underlyingMsg) | ||
with RLPSerializable { | ||
override def code: Int = Codes.StatusCode | ||
|
||
override def toRLPEncodable: RLPEncodeable = { | ||
import msg._ | ||
RLPList(protocolVersion, networkId, totalDifficulty, bestHash, genesisHash, forkId.toRLPEncodable) | ||
} | ||
} | ||
|
||
implicit class StatusDec(val bytes: Array[Byte]) extends AnyVal { | ||
def toStatus: Status = rawDecode(bytes) match { | ||
case RLPList( | ||
protocolVersion, | ||
networkId, | ||
totalDifficulty, | ||
bestHash, | ||
genesisHash, | ||
forkId | ||
) => | ||
Status( | ||
protocolVersion, | ||
networkId, | ||
totalDifficulty, | ||
bestHash, | ||
genesisHash, | ||
decode[ForkId](forkId) | ||
) | ||
|
||
case _ => throw new RuntimeException("Cannot decode Status") | ||
} | ||
} | ||
} | ||
} |
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.
would be so cool to have this fail if a new block type is introduced. just a thought, no great ideas.
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.
Not sure what you mean here
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.
thinking out loud:
and an ADT out of the capabilities?