Skip to content

Commit fa63c4a

Browse files
authoredApr 18, 2024··
Merge pull request #41 from icon-project/eunki-bsc-tycho
Support tycho upgrade on bsc network
2 parents 74faf00 + b5e08a2 commit fa63c4a

File tree

5 files changed

+96
-10
lines changed

5 files changed

+96
-10
lines changed
 

‎bmv/bsc2/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version = '0.5.0'
1+
version = '0.6.0'
22

33
dependencies {
44
compileOnly("foundation.icon:javaee-api:$javaeeVersion")

‎bmv/bsc2/src/main/java/foundation/icon/btp/bmv/bsc2/BTPMessageVerifier.java

+4
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,10 @@ private void verify(ChainConfig config, Header head) {
301301
Context.require(head.getGasLimit().compareTo(MAX_GAS_LIMIT) <= 0, "Invalid gas limit(> max)");
302302
Context.require(head.getGasUsed().compareTo(head.getGasLimit()) < 0, "Invalid gas used");
303303
Context.require(head.getSigner(BigInteger.valueOf(config.ChainID)).equals(head.getCoinbase()), "Coinbase mismatch");
304+
305+
if (config.isTycho(head.getNumber())) {
306+
Context.require(head.getWithdrawalsHash().equals(EMPTY_WITHDRAWALS_HASH), "Invalid withdrawals hash");
307+
}
304308
}
305309

306310
private void verify(ChainConfig config, Header head, Header parent, Snapshot snap) {

‎bmv/bsc2/src/main/java/foundation/icon/btp/bmv/bsc2/ChainConfig.java

+11-4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public class ChainConfig {
2424
public final long Epoch;
2525
public final long Period;
2626
public final BigInteger Hertz;
27+
public final BigInteger Tycho;
2728

2829
private static ChainConfig instance;
2930

@@ -34,11 +35,12 @@ public static ChainConfig setChainID(BigInteger cid) {
3435
return instance;
3536
}
3637

37-
private ChainConfig(long chainId, long epoch, long period, BigInteger hertz) {
38+
private ChainConfig(long chainId, long epoch, long period, BigInteger hertz, BigInteger tycho) {
3839
this.ChainID = chainId;
3940
this.Epoch = epoch;
4041
this.Period = period;
4142
this.Hertz = hertz;
43+
this.Tycho = tycho;
4244
}
4345

4446
public static ChainConfig getInstance() {
@@ -48,13 +50,14 @@ public static ChainConfig getInstance() {
4850
public static ChainConfig fromChainID(BigInteger cid) {
4951
if (cid.longValue() == 56L) {
5052
// BSC Mainnet
51-
return new ChainConfig(56L, 200L, 3L, BigInteger.valueOf(31302048L));
53+
return new ChainConfig(56L, 200L, 3L, BigInteger.valueOf(31302048L), null);
5254
} else if (cid.longValue() == 97L) {
5355
// BSC Testnet
54-
return new ChainConfig(97L, 200L, 3L, BigInteger.valueOf(31103030L));
56+
return new ChainConfig(97L, 200L, 3L, BigInteger.valueOf(31103030L),
57+
BigInteger.valueOf(39539137L));
5558
} else if (cid.longValue() == 99L) {
5659
// Private BSC Testnet
57-
return new ChainConfig(99L, 200L, 3L, BigInteger.valueOf(8));
60+
return new ChainConfig(99L, 200L, 3L, BigInteger.valueOf(8), null);
5861
}
5962

6063
Context.require(false, "No Chain Config - ChainID(" + cid.intValue() + ")");
@@ -69,4 +72,8 @@ public boolean isHertz(BigInteger number) {
6972
return Hertz != null && Hertz.compareTo(number) <= 0;
7073
}
7174

75+
public boolean isTycho(BigInteger number) {
76+
return Tycho != null && Tycho.compareTo(number) <= 0;
77+
}
78+
7279
}

‎bmv/bsc2/src/main/java/foundation/icon/btp/bmv/bsc2/Header.java

+48-5
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ public class Header {
3131
public static final int VALIDATOR_NUMBER_SIZE = 1;
3232
public static final int VALIDATOR_BYTES_LENGTH = EthAddress.LENGTH + BLSPublicKey.LENGTH;
3333
// pre-calculated constant uncle hash:) rlp([])
34-
public static final Hash UNCLE_HASH = Hash.of("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347");
34+
public static final Hash UNCLE_HASH =
35+
Hash.of("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347");
36+
// known hash of empty withdrawl set
37+
public static final Hash EMPTY_WITHDRAWALS_HASH =
38+
Hash.of("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421");
3539
public static final BigInteger INTURN_DIFF = BigInteger.valueOf(2L);
3640
public static final BigInteger NOTURN_DIFF = BigInteger.valueOf(1L);
3741
public static final BigInteger GAS_LIMIT_BOUND_DIVISOR = BigInteger.valueOf(256L);
@@ -54,6 +58,9 @@ public class Header {
5458
private final Hash mixDigest;
5559
private final byte[] nonce;
5660
private final BigInteger baseFee;
61+
private final Hash withdrawalsHash;
62+
private final BigInteger blobGasUsed;
63+
private final BigInteger excessBlobGas;
5764

5865
// caches
5966
private Hash hashCache;
@@ -63,7 +70,8 @@ public class Header {
6370
public Header(Hash parentHash, Hash uncleHash, EthAddress coinbase, Hash root,
6471
Hash txHash, Hash receiptHash, byte[] bloom, BigInteger difficulty,
6572
BigInteger number, BigInteger gasLimit, BigInteger gasUsed, long time,
66-
byte[] extra, Hash mixDigest, byte[] nonce, BigInteger baseFee)
73+
byte[] extra, Hash mixDigest, byte[] nonce, BigInteger baseFee, Hash withdrawalsHash,
74+
BigInteger blobGasUsed, BigInteger excessBlobGas)
6775
{
6876
this.parentHash = parentHash;
6977
this.uncleHash = uncleHash;
@@ -81,6 +89,9 @@ public Header(Hash parentHash, Hash uncleHash, EthAddress coinbase, Hash root,
8189
this.mixDigest = mixDigest;
8290
this.nonce = nonce;
8391
this.baseFee = baseFee;
92+
this.withdrawalsHash = withdrawalsHash;
93+
this.blobGasUsed = blobGasUsed;
94+
this.excessBlobGas = excessBlobGas;
8495
}
8596

8697
public static Header readObject(ObjectReader r) {
@@ -100,17 +111,37 @@ public static Header readObject(ObjectReader r) {
100111
byte[] extra = r.readByteArray();
101112
Hash mixDigest = r.read(Hash.class);
102113
byte[] nonce = r.readByteArray();
114+
115+
// For Hertz Upgrade
103116
BigInteger baseFee = null;
104117
if (ChainConfig.getInstance().isHertz(number)) {
105118
baseFee = r.readBigInteger();
106119
}
120+
121+
// For Tycho Upgrade
122+
Hash withdrawalsHash = Hash.EMPTY;
123+
BigInteger blobGasUsed = null;
124+
BigInteger excessBlobGas = null;
125+
if (ChainConfig.getInstance().isTycho(number)) {
126+
withdrawalsHash = r.read(Hash.class);
127+
blobGasUsed = r.readBigInteger();
128+
excessBlobGas = r.readBigInteger();
129+
}
130+
107131
r.end();
108132
return new Header(parentHash, uncleHash, coinbase, root, txHash, receiptHash, bloom,
109-
difficulty, number, gasLimit, gasUsed, time, extra, mixDigest, nonce, baseFee);
133+
difficulty, number, gasLimit, gasUsed, time, extra, mixDigest, nonce, baseFee,
134+
withdrawalsHash, blobGasUsed, excessBlobGas);
110135
}
111136

112137
public static void writeObject(ObjectWriter w, Header o) {
113-
w.beginList(15 + (o.baseFee != null ? 1 : 0));
138+
if (ChainConfig.getInstance().isTycho(o.number)) {
139+
w.beginList(19);
140+
} else if (ChainConfig.getInstance().isHertz(o.number)) {
141+
w.beginList(16);
142+
} else {
143+
w.beginList(15);
144+
}
114145
w.write(o.parentHash);
115146
w.write(o.uncleHash);
116147
w.write(o.coinbase);
@@ -126,9 +157,17 @@ public static void writeObject(ObjectWriter w, Header o) {
126157
w.write(o.extra);
127158
w.write(o.mixDigest);
128159
w.write(o.nonce);
129-
if (o.baseFee != null) {
160+
if (ChainConfig.getInstance().isHertz(o.number)) {
161+
Context.require(o.baseFee != null, "no fields for hertz");
130162
w.write(o.baseFee);
131163
}
164+
if (ChainConfig.getInstance().isTycho(o.number)) {
165+
Context.require(o.withdrawalsHash != Hash.EMPTY && o.blobGasUsed != null
166+
&& o.excessBlobGas != null, "no fields for tycho");
167+
w.write(o.withdrawalsHash);
168+
w.write(o.blobGasUsed);
169+
w.write(o.excessBlobGas);
170+
}
132171
w.end();
133172
}
134173

@@ -275,4 +314,8 @@ public byte[] getExtra() {
275314
public Hash getMixDigest() {
276315
return this.mixDigest;
277316
}
317+
318+
public Hash getWithdrawalsHash() {
319+
return this.withdrawalsHash;
320+
}
278321
}

‎bmv/bsc2/src/test/resources/testnet.json

+32
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.