Skip to content

Commit 3982b03

Browse files
author
Leonor Boga
authored
[ETCM-893] Add support for chains with ids bigger than 127 (#1006)
[ETCM-893] Add support for networks with a chainid bigger than 127
1 parent a7a62c7 commit 3982b03

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+178
-140
lines changed

crypto/src/main/scala/io/iohk/ethereum/crypto/ECDSASignature.scala

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ object ECDSASignature {
3131

3232
val allowedPointSigns = Set(negativePointSign, positivePointSign)
3333

34-
def apply(r: ByteString, s: ByteString, v: Byte): ECDSASignature = {
34+
def apply(r: ByteString, s: ByteString, v: BigInt): ECDSASignature = {
3535
ECDSASignature(BigInt(1, r.toArray), BigInt(1, s.toArray), v)
3636
}
3737

@@ -46,7 +46,11 @@ object ECDSASignature {
4646
sign(messageHash.toArray, keyPairFromPrvKey(prvKey.toArray), None)
4747

4848
/** Sign a messageHash, expected to be a Keccak256 hash of the original data. */
49-
def sign(messageHash: Array[Byte], keyPair: AsymmetricCipherKeyPair, chainId: Option[Byte] = None): ECDSASignature = {
49+
def sign(
50+
messageHash: Array[Byte],
51+
keyPair: AsymmetricCipherKeyPair,
52+
chainId: Option[BigInt] = None
53+
): ECDSASignature = {
5054
require(
5155
messageHash.size == 32,
5256
s"The message should be a hash, expected to be 32 bytes; got ${messageHash.size} bytes."
@@ -61,10 +65,10 @@ object ECDSASignature {
6165
.getOrElse(throw new RuntimeException("Failed to calculate signature rec id"))
6266

6367
val pointSign = chainId match {
64-
case Some(id) if v == negativePointSign => (id * 2 + newNegativePointSign).toByte
65-
case Some(id) if v == positivePointSign => (id * 2 + newPositivePointSign).toByte
66-
case None => v
67-
case _ => throw new IllegalStateException(s"Unexpected pointSign. ChainId: ${chainId}, v: ${v}")
68+
case Some(id) if v == negativePointSign => id * 2 + newNegativePointSign
69+
case Some(id) if v == positivePointSign => id * 2 + newPositivePointSign
70+
case None => BigInt(v)
71+
case _ => throw new IllegalStateException(s"Unexpected pointSign. ChainId: $chainId, v: $v")
6872
}
6973

7074
ECDSASignature(r, s, pointSign)
@@ -74,17 +78,18 @@ object ECDSASignature {
7478
* new formula for calculating point sign post EIP 155 adoption
7579
* v = CHAIN_ID * 2 + 35 or v = CHAIN_ID * 2 + 36
7680
*/
77-
private def getRecoveredPointSign(pointSign: Byte, chainId: Option[Byte]): Option[Byte] = {
81+
private def getRecoveredPointSign(pointSign: BigInt, chainId: Option[BigInt]): Option[Byte] = {
82+
val signByte = pointSign.toByte
7883
(chainId match {
7984
case Some(id) =>
80-
if (pointSign == negativePointSign || pointSign == (id * 2 + newNegativePointSign).toByte) {
85+
if (signByte == negativePointSign || signByte == (id * 2 + newNegativePointSign).toByte) {
8186
Some(negativePointSign)
82-
} else if (pointSign == positivePointSign || pointSign == (id * 2 + newPositivePointSign).toByte) {
87+
} else if (signByte == positivePointSign || signByte == (id * 2 + newPositivePointSign).toByte) {
8388
Some(positivePointSign)
8489
} else {
8590
None
8691
}
87-
case None => Some(pointSign)
92+
case None => Some(signByte)
8893
}).filter(pointSign => allowedPointSigns.contains(pointSign))
8994
}
9095

@@ -106,8 +111,8 @@ object ECDSASignature {
106111
private def recoverPubBytes(
107112
r: BigInt,
108113
s: BigInt,
109-
recId: Byte,
110-
chainId: Option[Byte],
114+
recId: BigInt,
115+
chainId: Option[BigInt],
111116
messageHash: Array[Byte]
112117
): Option[Array[Byte]] = {
113118
Try {
@@ -152,15 +157,15 @@ object ECDSASignature {
152157
* @param s - part of the signature calculated with signer private key
153158
* @param v - public key recovery id
154159
*/
155-
case class ECDSASignature(r: BigInt, s: BigInt, v: Byte) {
160+
case class ECDSASignature(r: BigInt, s: BigInt, v: BigInt) {
156161

157162
/**
158163
* returns ECC point encoded with on compression and without leading byte indicating compression
159164
* @param messageHash message to be signed; should be a hash of the actual data.
160165
* @param chainId optional value if you want new signing schema with recovery id calculated with chain id
161166
* @return
162167
*/
163-
def publicKey(messageHash: Array[Byte], chainId: Option[Byte] = None): Option[Array[Byte]] =
168+
def publicKey(messageHash: Array[Byte], chainId: Option[BigInt] = None): Option[Array[Byte]] =
164169
ECDSASignature.recoverPubBytes(r, s, v, chainId, messageHash)
165170

166171
/**

crypto/src/test/scala/io/iohk/ethereum/crypto/ECDSASignatureSpec.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class ECDSASignatureSpec extends AnyFlatSpec with Matchers with ScalaCheckProper
1818
val pointSign = 28
1919

2020
val sig =
21-
ECDSASignature(BigInt(1, signatureRandom.toArray[Byte]), BigInt(1, signature.toArray[Byte]), pointSign.toByte)
21+
ECDSASignature(BigInt(1, signatureRandom.toArray[Byte]), BigInt(1, signature.toArray[Byte]), pointSign)
2222

2323
sig.publicKey(bytesToSign).isEmpty shouldBe false
2424
}
@@ -30,7 +30,7 @@ class ECDSASignatureSpec extends AnyFlatSpec with Matchers with ScalaCheckProper
3030
val pointSign = 0x1f
3131

3232
val sig =
33-
ECDSASignature(BigInt(1, signatureRandom.toArray[Byte]), BigInt(1, signature.toArray[Byte]), pointSign.toByte)
33+
ECDSASignature(BigInt(1, signatureRandom.toArray[Byte]), BigInt(1, signature.toArray[Byte]), pointSign)
3434

3535
sig.publicKey(bytesToSign).isEmpty shouldBe true
3636
}
@@ -39,7 +39,7 @@ class ECDSASignatureSpec extends AnyFlatSpec with Matchers with ScalaCheckProper
3939
val sig = ECDSASignature(
4040
ByteStringUtils.string2hash("149a2046f51f5d043633664d76eef4f99cdba8e53851dcda57224dfe8770f98a"),
4141
ByteStringUtils.string2hash("a8898478e9aae9fadb71c7ab5451d47d2efa4199fc26ecc1da62ce8fb77e06f1"),
42-
28.toByte
42+
28
4343
)
4444
val messageHash = ByteStringUtils.string2hash("a1ede9cdf0b6fe37a384b265dce6b74a7464f11799dcee022f628450a19cf4eb")
4545

src/benchmark/scala/io/iohk/ethereum/rlp/RLPSpeedSuite.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class RLPSpeedSuite
8888
pointSign = 28,
8989
signatureRandom = ByteString(Hex.decode("cfe3ad31d6612f8d787c45f115cc5b43fb22bcc210b62ae71dc7cbf0a6bea8df")),
9090
signature = ByteString(Hex.decode("57db8998114fae3c337e99dbd8573d4085691880f4576c6c1f6c5bbfe67d6cf0")),
91-
chainId = 0x3d.toByte
91+
chainId = 0x3d
9292
)
9393

9494
lazy val blockGen: Gen[Block] = for {

src/it/scala/io/iohk/ethereum/txExecTest/ECIP1017Test.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class ECIP1017Test extends AnyFlatSpec with Matchers {
1919
monetaryPolicyConfig = MonetaryPolicyConfig(EraDuration, 0.2, 5000000000000000000L, 3000000000000000000L),
2020
// unused
2121
maxCodeSize = None,
22-
chainId = 0x3d.toByte,
22+
chainId = 0x3d,
2323
networkId = 1,
2424
forkBlockNumbers = ForkBlockNumbers(
2525
frontierBlockNumber = 0,

src/it/scala/io/iohk/ethereum/txExecTest/ForksTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class ForksTest extends AnyFlatSpec with Matchers {
3535
ecip1099BlockNumber = Long.MaxValue,
3636
ecip1049BlockNumber = None
3737
),
38-
chainId = 0x3d.toByte,
38+
chainId = 0x3d,
3939
monetaryPolicyConfig = MonetaryPolicyConfig(5000000, 0.2, 5000000000000000000L, 3000000000000000000L),
4040
// unused
4141
bootstrapNodes = Set(),

src/main/resources/conf/testmode.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,5 @@ mantis {
5454
}
5555

5656
}
57+
58+
akka.http.server.request-timeout = 30.seconds

src/main/scala/io/iohk/ethereum/domain/SignedTransaction.scala

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ object SignedTransaction {
4545

4646
def apply(
4747
tx: Transaction,
48-
pointSign: Byte,
48+
pointSign: BigInt,
4949
signatureRandom: ByteString,
5050
signature: ByteString,
51-
chainId: Byte
51+
chainId: BigInt
5252
): SignedTransaction = {
5353
val txSignature = ECDSASignature(
5454
r = new BigInteger(1, signatureRandom.toArray),
@@ -58,7 +58,12 @@ object SignedTransaction {
5858
SignedTransaction(tx, txSignature)
5959
}
6060

61-
def apply(tx: Transaction, pointSign: Byte, signatureRandom: ByteString, signature: ByteString): SignedTransaction = {
61+
def apply(
62+
tx: Transaction,
63+
pointSign: BigInt,
64+
signatureRandom: ByteString,
65+
signature: ByteString
66+
): SignedTransaction = {
6267
val txSignature = ECDSASignature(
6368
r = new BigInteger(1, signatureRandom.toArray),
6469
s = new BigInteger(1, signature.toArray),
@@ -67,14 +72,14 @@ object SignedTransaction {
6772
SignedTransaction(tx, txSignature)
6873
}
6974

70-
def sign(tx: Transaction, keyPair: AsymmetricCipherKeyPair, chainId: Option[Byte]): SignedTransactionWithSender = {
75+
def sign(tx: Transaction, keyPair: AsymmetricCipherKeyPair, chainId: Option[BigInt]): SignedTransactionWithSender = {
7176
val bytes = bytesToSign(tx, chainId)
7277
val sig = ECDSASignature.sign(bytes, keyPair, chainId)
7378
val address = Address(keyPair)
7479
SignedTransactionWithSender(tx, sig, address)
7580
}
7681

77-
private def bytesToSign(tx: Transaction, chainId: Option[Byte]): Array[Byte] = {
82+
private def bytesToSign(tx: Transaction, chainId: Option[BigInt]): Array[Byte] = {
7883
chainId match {
7984
case Some(id) =>
8085
chainSpecificTransactionBytes(tx, id)
@@ -128,7 +133,7 @@ object SignedTransaction {
128133
crypto.kec256(rlpEncode(RLPList(tx.nonce, tx.gasPrice, tx.gasLimit, receivingAddressAsArray, tx.value, tx.payload)))
129134
}
130135

131-
private def chainSpecificTransactionBytes(tx: Transaction, chainId: Byte): Array[Byte] = {
136+
private def chainSpecificTransactionBytes(tx: Transaction, chainId: BigInt): Array[Byte] = {
132137
val receivingAddressAsArray: Array[Byte] = tx.receivingAddress.map(_.toArray).getOrElse(Array.emptyByteArray)
133138
crypto.kec256(
134139
rlpEncode(

src/main/scala/io/iohk/ethereum/extvm/VMServer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ class VMServer(messageHandler: MessageHandler) extends Logger {
192192
aghartaBlockNumber = BigInt(9573000), //TODO include agharta block number in protobuf
193193
petersburgBlockNumber = BigInt(10000000), //TODO include petersburg block number in protobuf
194194
phoenixBlockNumber = BigInt(10500839), //TODO include phoenix block number in protobuf
195-
chainId = 0x3d.toByte //TODO include chainId in protobuf
195+
chainId = 0x3d //TODO include chainId in protobuf
196196
)
197197
}
198198
}

src/main/scala/io/iohk/ethereum/jsonrpc/EthInfoService.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import io.iohk.ethereum.utils.BlockchainConfig
2626

2727
object EthInfoService {
2828
case class ChainIdRequest()
29-
case class ChainIdResponse(value: Byte)
29+
case class ChainIdResponse(value: BigInt)
3030

3131
case class ProtocolVersionRequest()
3232
case class ProtocolVersionResponse(value: String)
@@ -174,7 +174,7 @@ class EthInfoService(
174174
val toAddress = req.tx.to.map(Address.apply)
175175

176176
val tx = Transaction(0, req.tx.gasPrice, gasLimit, toAddress, req.tx.value, req.tx.data)
177-
val fakeSignature = ECDSASignature(0, 0, 0.toByte)
177+
val fakeSignature = ECDSASignature(0, 0, 0)
178178
SignedTransactionWithSender(tx, fakeSignature, fromAddress)
179179
}
180180
}

src/main/scala/io/iohk/ethereum/jsonrpc/JsonMethodsImplicits.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ object JsonMethodsImplicits extends JsonMethodsImplicits {
220220
implicit val personal_sign = new JsonMethodCodec[SignRequest, SignResponse] {
221221
override def encodeJson(t: SignResponse): JValue = {
222222
import t.signature._
223-
encodeAsHex(ByteString(r.toUnsignedByteArray ++ s.toUnsignedByteArray :+ v))
223+
encodeAsHex(ByteString(r.toUnsignedByteArray ++ s.toUnsignedByteArray ++ v.toUnsignedByteArray))
224224
}
225225

226226
override def decodeJson(params: Option[JArray]): Either[JsonRpcError, SignRequest] =

src/main/scala/io/iohk/ethereum/keystore/Wallet.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ import org.bouncycastle.crypto.AsymmetricCipherKeyPair
88
case class Wallet(address: Address, prvKey: ByteString) {
99
lazy val keyPair: AsymmetricCipherKeyPair = keyPairFromPrvKey(prvKey.toArray)
1010

11-
def signTx(tx: Transaction, chainId: Option[Byte]): SignedTransactionWithSender =
11+
def signTx(tx: Transaction, chainId: Option[BigInt]): SignedTransactionWithSender =
1212
SignedTransaction.sign(tx, keyPair, chainId)
1313
}

src/main/scala/io/iohk/ethereum/network/p2p/messages/CommonMessages.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ object CommonMessages {
135135

136136
object SignedTransactions {
137137

138-
lazy val chainId: Byte = Config.blockchains.blockchainConfig.chainId
138+
lazy val chainId: BigInt = Config.blockchains.blockchainConfig.chainId
139139

140140
implicit class SignedTransactionEnc(val signedTx: SignedTransaction) extends RLPSerializable {
141141
override def toRLPEncodable: RLPEncodeable = {
@@ -187,7 +187,7 @@ object CommonMessages {
187187
val receivingAddressOpt = if (receivingAddress.bytes.isEmpty) None else Some(Address(receivingAddress.bytes))
188188
SignedTransaction(
189189
Transaction(nonce, gasPrice, gasLimit, receivingAddressOpt, value, payload),
190-
(pointSign: Int).toByte,
190+
pointSign: BigInt,
191191
signatureRandom,
192192
signature,
193193
chainId

src/main/scala/io/iohk/ethereum/network/rlpx/AuthInitiateEcdsaCodec.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ trait AuthInitiateEcdsaCodec {
2626
val r = input.take(RLength)
2727
val s = input.slice(SIndex, SIndex + SLength)
2828
val v = input(VIndex) + 27
29-
ECDSASignature(BigInt(1, r), BigInt(1, s), v.toByte)
29+
ECDSASignature(BigInt(1, r), BigInt(1, s), v)
3030
}
3131
}

src/main/scala/io/iohk/ethereum/utils/BlockchainConfig.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ case class BlockchainConfig(
2121
customGenesisJsonOpt: Option[String],
2222
daoForkConfig: Option[DaoForkConfig],
2323
accountStartNonce: UInt256,
24-
chainId: Byte,
24+
chainId: BigInt,
2525
networkId: Int,
2626
monetaryPolicyConfig: MonetaryPolicyConfig,
2727
gasTieBreaker: Boolean,
@@ -104,11 +104,9 @@ object BlockchainConfig {
104104
val daoForkConfig = Try(blockchainConfig.getConfig("dao")).toOption.map(DaoForkConfig(_))
105105
val accountStartNonce: UInt256 = UInt256(BigInt(blockchainConfig.getString("account-start-nonce")))
106106

107-
val chainId: Byte = {
107+
val chainId: BigInt = {
108108
val s = blockchainConfig.getString("chain-id")
109-
val n = parseHexOrDecNumber(s)
110-
require(n >= 0 && n <= 127, "chain-id must be a number in range [0, 127]")
111-
n.toByte
109+
parseHexOrDecNumber(s)
112110
}
113111

114112
val networkId: Int = blockchainConfig.getInt("network-id")

src/main/scala/io/iohk/ethereum/vm/BlockchainConfigForEvm.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ case class BlockchainConfigForEvm(
3434
aghartaBlockNumber: BigInt,
3535
petersburgBlockNumber: BigInt,
3636
phoenixBlockNumber: BigInt,
37-
chainId: Byte
37+
chainId: BigInt
3838
) {
3939
def etcForkForBlockNumber(blockNumber: BigInt): EtcFork = blockNumber match {
4040
case _ if blockNumber < atlantisBlockNumber => BeforeAtlantis

0 commit comments

Comments
 (0)