diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index c1962a79..e6441136 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 31839a89..a4413138 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-rc-4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index aeb74cbb..1aa94a42 100755 --- a/gradlew +++ b/gradlew @@ -83,7 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -130,10 +131,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -141,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -149,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -198,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index 93e3f59f..25da30db 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/hildr-node/src/main/java/io/optimism/cli/Cli.java b/hildr-node/src/main/java/io/optimism/cli/Cli.java index c09d4e12..a0d1a705 100644 --- a/hildr-node/src/main/java/io/optimism/cli/Cli.java +++ b/hildr-node/src/main/java/io/optimism/cli/Cli.java @@ -170,10 +170,8 @@ private Config toConfig() { Config.ChainConfig chain = switch (network) { case "optimism" -> Config.ChainConfig.optimism(); - case "optimism-goerli" -> Config.ChainConfig.optimismGoerli(); case "optimism-sepolia" -> Config.ChainConfig.optimismSepolia(); case "base" -> Config.ChainConfig.base(); - case "base-goerli" -> Config.ChainConfig.baseGoerli(); case "base-sepolia" -> Config.ChainConfig.baseSepolia(); default -> { if (network.endsWith(".json")) { diff --git a/hildr-node/src/main/java/io/optimism/config/Config.java b/hildr-node/src/main/java/io/optimism/config/Config.java index e6161612..862c1e75 100644 --- a/hildr-node/src/main/java/io/optimism/config/Config.java +++ b/hildr-node/src/main/java/io/optimism/config/Config.java @@ -64,6 +64,12 @@ public record Config( SyncMode syncMode, ChainConfig chainConfig) { + private static final int MAX_CHANNEL_SIZE_BEDROCK = 100_000_000; + + private static final int MAX_CHANNEL_SIZE_FJORD = 1_000_000_000; + + private static final int MAX_SEQUENCER_DRIFT_FJORD = 1800; + /** * Create Config. * @@ -219,7 +225,6 @@ public Map toConfigMap() { * @param batchInbox The batch inbox address. * @param depositContract The deposit contract address. * @param systemConfigContract The L1 system config contract. - * @param maxChannelSize The maximum byte size of all pending channels. * @param channelTimeout The max timeout for a channel (as measured by the frame L1 block number). * @param seqWindowSize Number of L1 blocks in a sequence window. * @param maxSeqDrift Maximum timestamp drift. @@ -227,6 +232,7 @@ public Map toConfigMap() { * @param canyonTime Timestamp of the canyon hardfork. * @param deltaTime Timestamp of the deltaTime hardfork. * @param ecotoneTime Timestamp of the ecotone hardfork. + * @param fjordTime Timestamp of the fjord hardfork. * @param blockTime Network blocktime. * @param l2Tol1MessagePasser L2 To L1 Message passer address. * @author grapebaba @@ -242,7 +248,6 @@ public record ChainConfig( String batchInbox, String depositContract, String systemConfigContract, - BigInteger maxChannelSize, BigInteger channelTimeout, BigInteger seqWindowSize, BigInteger maxSeqDrift, @@ -250,6 +255,7 @@ public record ChainConfig( BigInteger canyonTime, BigInteger deltaTime, BigInteger ecotoneTime, + BigInteger fjordTime, BigInteger blockTime, String l2Tol1MessagePasser) { @@ -267,6 +273,7 @@ public boolean isEcotoneActivationBlock(BigInteger time) { /** * Check if the time is the ecotone activation block. + * * @param time the block timestamp * @return true if the time is the ecotone activation block, otherwise false. */ @@ -276,6 +283,7 @@ public boolean isEcotone(BigInteger time) { /** * Check if the time is the ecotone activation block and not the first ecotone block. + * * @param time the block timestamp * @return true if the time is the ecotone activation block and not the first ecotone block, otherwise false. */ @@ -283,8 +291,31 @@ public boolean isEcotoneAndNotFirst(BigInteger time) { return isEcotone(time) && time.compareTo(blockTime) >= 0 && isEcotone(time.subtract(blockTime)); } + /** + * Check if the time is the fjord activation block. + * + * @param time the block timestamp + * @return true if the time is the fjord activation block, otherwise false. + */ + public boolean isFjord(BigInteger time) { + return fjordTime.compareTo(BigInteger.ZERO) > 0 && time.compareTo(fjordTime) >= 0; + } + + /** + * Check if the time is the fjord activation block. + * + * @param time the block timestamp + * @return true if the time is the fjord activation block, otherwise false. + */ + public boolean isFjordActivationBlock(BigInteger time) { + return isFjord(time) + && time.compareTo(blockTime) >= 0 + && time.subtract(blockTime).compareTo(fjordTime) < 0; + } + /** * Check if the time is the canyon activation block. + * * @param time the block timestamp * @return true if the time is the canyon activation block, otherwise false. */ @@ -292,6 +323,26 @@ public boolean isCanyon(BigInteger time) { return canyonTime.compareTo(BigInteger.ZERO) > 0 && time.compareTo(canyonTime) >= 0; } + /** + * Max channel size int. + * + * @param time the time + * @return the int + */ + public int maxChannelSize(BigInteger time) { + return isFjord(time) ? MAX_CHANNEL_SIZE_FJORD : MAX_CHANNEL_SIZE_BEDROCK; + } + + /** + * Max sequencer drift big integer. + * + * @param time the time + * @return the big integer + */ + public BigInteger maxSequencerDrift(BigInteger time) { + return isFjord(time) ? BigInteger.valueOf(MAX_SEQUENCER_DRIFT_FJORD) : this.maxSeqDrift(); + } + /** * Optimism chain config. * @@ -321,14 +372,14 @@ public static ChainConfig optimism() { "0xff00000000000000000000000000000000000010", "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", "0x229047fed2591dbec1eF1118d64F7aF3dB9EB290", - BigInteger.valueOf(100_000_000L), BigInteger.valueOf(300L), BigInteger.valueOf(3600L), BigInteger.valueOf(600L), BigInteger.ZERO, BigInteger.valueOf(1704992401L), BigInteger.valueOf(1708560000L), - BigInteger.valueOf(-1L), + BigInteger.valueOf(1710374401L), + BigInteger.valueOf(1720627201L), BigInteger.valueOf(2L), "0x4200000000000000000000000000000000000016"); } @@ -362,59 +413,18 @@ public static ChainConfig base() { "0xff00000000000000000000000000000000008453", "0x49048044d57e1c92a77f79988d21fa8faf74e97e", "0x73a79fab69143498ed3712e519a88a918e1f4072", - BigInteger.valueOf(100_000_000L), BigInteger.valueOf(300L), BigInteger.valueOf(3600L), BigInteger.valueOf(600L), BigInteger.ZERO, BigInteger.valueOf(1704992401L), - BigInteger.valueOf(-1L), - BigInteger.valueOf(-1L), + BigInteger.valueOf(1708560000L), + BigInteger.valueOf(1710374401L), + BigInteger.valueOf(1720627201L), BigInteger.valueOf(2L), "0x4200000000000000000000000000000000000016"); } - /** - * Optimism goerli chain config. - * - * @return the chain config - */ - public static ChainConfig optimismGoerli() { - return new ChainConfig( - "optimism-goerli", - BigInteger.valueOf(5L), - BigInteger.valueOf(420L), - new Epoch( - BigInteger.valueOf(8300214L), - "0x6ffc1bf3754c01f6bb9fe057c1578b87a8571ce2e9be5ca14bace6eccfd336c7", - BigInteger.valueOf(1673550516L), - BigInteger.ZERO), - new BlockInfo( - "0x0f783549ea4313b784eadd9b8e8a69913b368b7366363ea814d7707ac505175f", - BigInteger.valueOf(4061224L), - "0x31267a44f1422f4cab59b076548c075e79bd59e691a23fbce027f572a2a49dc9", - BigInteger.valueOf(1673550516L)), - new SystemConfig( - "0x7431310e026b69bfc676c0013e12a1a11411eec9", - BigInteger.valueOf(25_000_000L), - BigInteger.valueOf(2100), - BigInteger.valueOf(1000000), - "0x715b7219D986641DF9eFd9C7Ef01218D528e19ec"), - "0xff00000000000000000000000000000000000420", - "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383", - "0xAe851f927Ee40dE99aaBb7461C00f9622ab91d60", - BigInteger.valueOf(100_000_000L), - BigInteger.valueOf(300L), - BigInteger.valueOf(3600L), - BigInteger.valueOf(600L), - BigInteger.valueOf(1679079600L), - BigInteger.valueOf(1699981200L), - BigInteger.valueOf(1703116800L), - BigInteger.valueOf(1707238800L), - BigInteger.valueOf(2L), - "0xEF2ec5A5465f075E010BE70966a8667c94BCe15a"); - } - /** * Optimism sepolia ChainConfig. * @@ -444,7 +454,6 @@ public static ChainConfig optimismSepolia() { "0xff00000000000000000000000000000011155420", "0x16fc5058f25648194471939df75cf27a2fdc48bc", "0x034edd2a225f7f429a63e0f1d2084b9e0a93b538", - BigInteger.valueOf(100_000_000L), BigInteger.valueOf(300L), BigInteger.valueOf(3600L), BigInteger.valueOf(600L), @@ -452,47 +461,7 @@ public static ChainConfig optimismSepolia() { BigInteger.valueOf(1699981200L), BigInteger.valueOf(1703203200L), BigInteger.valueOf(1708534800L), - BigInteger.valueOf(2L), - "0x4200000000000000000000000000000000000016"); - } - - /** - * Base goerli ChainConfig. - * - * @return the chain config - */ - public static ChainConfig baseGoerli() { - return new ChainConfig( - "base-goerli", - BigInteger.valueOf(5L), - BigInteger.valueOf(84531L), - new Epoch( - BigInteger.valueOf(8410981L), - "0x73d89754a1e0387b89520d989d3be9c37c1f32495a88faf1ea05c61121ab0d19", - BigInteger.valueOf(1675193616L), - BigInteger.ZERO), - new BlockInfo( - "0xa3ab140f15ea7f7443a4702da64c10314eb04d488e72974e02e2d728096b4f76", - BigInteger.valueOf(0L), - Numeric.toHexString(new byte[32]), - BigInteger.valueOf(1675193616L)), - new SystemConfig( - "0x2d679b567db6187c0c8323fa982cfb88b74dbcc7", - BigInteger.valueOf(25_000_000L), - BigInteger.valueOf(2100L), - BigInteger.valueOf(1000000L), - "0x32a4e99A72c11E9DD3dC159909a2D7BD86C1Bc51"), - "0x8453100000000000000000000000000000000000", - "0xe93c8cd0d409341205a592f8c4ac1a5fe5585cfa", - "0xb15eea247ece011c68a614e4a77ad648ff495bc1", - BigInteger.valueOf(100_000_000L), - BigInteger.valueOf(300L), - BigInteger.valueOf(3600L), - BigInteger.valueOf(600L), - BigInteger.valueOf(1683219600L), - BigInteger.valueOf(-1L), - BigInteger.valueOf(-1L), - BigInteger.valueOf(-1L), + BigInteger.valueOf(1716998400L), BigInteger.valueOf(2L), "0x4200000000000000000000000000000000000016"); } @@ -526,14 +495,14 @@ public static ChainConfig baseSepolia() { "0xff00000000000000000000000000000000084532", "0x49f53e41452C74589E85cA1677426Ba426459e85", "0xf272670eb55e895584501d564AfEB048bEd26194", - BigInteger.valueOf(100_000_000L), BigInteger.valueOf(300L), BigInteger.valueOf(3600L), BigInteger.valueOf(600L), BigInteger.ZERO, - BigInteger.valueOf(-1L), - BigInteger.valueOf(-1L), - BigInteger.valueOf(-1L), + BigInteger.valueOf(1699981200L), + BigInteger.valueOf(1703203200L), + BigInteger.valueOf(1708534800L), + BigInteger.valueOf(1716998400L), BigInteger.valueOf(2L), "0x4200000000000000000000000000000000000016"); } @@ -582,7 +551,6 @@ public static ChainConfig fromExternal(ExternalChainConfig external) { external.batchInboxAddress, external.depositContractAddress, external.l1SystemConfigAddress, - BigInteger.valueOf(100_000_000L), external.channelTimeout, external.seqWindowSize, external.maxSequencerDrift, @@ -590,6 +558,7 @@ public static ChainConfig fromExternal(ExternalChainConfig external) { external.canyonTime == null ? BigInteger.valueOf(-1L) : external.canyonTime, external.deltaTime == null ? BigInteger.valueOf(-1L) : external.deltaTime, external.ecotoneTime == null ? BigInteger.valueOf(-1L) : external.ecotoneTime, + external.fjordTime == null ? BigInteger.valueOf(-1L) : external.fjordTime, external.blockTime, "0x4200000000000000000000000000000000000016"); } @@ -636,7 +605,6 @@ public Map toConfigMap() { entry("config.chainConfig.batchInbox", this.batchInbox), entry("config.chainConfig.depositContract", this.depositContract), entry("config.chainConfig.systemConfigContract", this.systemConfigContract), - entry("config.chainConfig.maxChannelSize", this.maxChannelSize.toString()), entry("config.chainConfig.channelTimeout", this.channelTimeout.toString()), entry("config.chainConfig.seqWindowSize", this.seqWindowSize.toString()), entry("config.chainConfig.maxSeqDrift", this.maxSeqDrift.toString()), @@ -644,6 +612,7 @@ public Map toConfigMap() { entry("config.chainConfig.canyonTime", this.canyonTime.toString()), entry("config.chainConfig.deltaTime", this.deltaTime.toString()), entry("config.chainConfig.ecotoneTime", this.ecotoneTime.toString()), + entry("config.chainConfig.fjordTime", this.fjordTime.toString()), entry("config.chainConfig.blockTime", this.blockTime.toString()), entry("config.chainConfig.l2Tol1MessagePasser", this.l2Tol1MessagePasser)); } @@ -679,6 +648,7 @@ public enum SyncMode { /** * is execution layer sync mode + * * @return true if execution layer sync mode, otherwise false. */ public boolean isEl() { @@ -732,10 +702,8 @@ public static SystemAccounts defaultSystemAccounts() { * * @param batchSender batch sender address. * @param gasLimit gas limit. - * @param l1FeeOverhead L1 fee overhead. Pre-Ecotone this is passed as-is to engine. - * Post-Ecotone this is always zero, and not passed into the engine. - * @param l1FeeScalar L1 fee scalar. Pre-Ecotone this is passed as-is to the engine. - * Post-Ecotone this encodes multiple pieces of scalar data. + * @param l1FeeOverhead L1 fee overhead. Pre-Ecotone this is passed as-is to engine. Post-Ecotone this is always zero, and not passed into the engine. + * @param l1FeeScalar L1 fee scalar. Pre-Ecotone this is passed as-is to the engine. Post-Ecotone this encodes multiple pieces of scalar data. * @param unsafeBlockSigner unsafe block signer address. * @author grapebaba * @since 0.1.0 @@ -749,9 +717,10 @@ public record SystemConfig( /** * Create SystemConfig from Bedrock tx input. + * * @param unsafeBlockSigner the unsafe block signer - * @param gasLimit l2 gas limit - * @param input l2 block tx input + * @param gasLimit l2 gas limit + * @param input l2 block tx input * @return the system config */ public static SystemConfig fromBedrockTxInput(String unsafeBlockSigner, BigInteger gasLimit, byte[] input) { @@ -763,9 +732,10 @@ public static SystemConfig fromBedrockTxInput(String unsafeBlockSigner, BigInteg /** * Create SystemConfig from Ecotone tx input. + * * @param unsafeBlockSigner the unsafe block signer - * @param gasLimit l2 gas limit - * @param input l2 block tx input + * @param gasLimit l2 gas limit + * @param input l2 block tx input * @return the system config */ public static SystemConfig fromEcotoneTxInput(String unsafeBlockSigner, BigInteger gasLimit, byte[] input) { @@ -790,6 +760,7 @@ public String batcherHash() { /** * Get base fee scalar. + * * @return tuple contains blobBaseFeeScalar and baseFeeScalar */ public Tuple2 ecotoneScalars() { @@ -827,6 +798,7 @@ public Tuple2 ecotoneScalars() { * @param canyonTime canyon time * @param deltaTime delta time * @param ecotoneTime ecotone time + * @param fjordTime fjord time * @param batchInboxAddress batch inbox address * @param depositContractAddress deposit contract address * @param l1SystemConfigAddress l1 system config address @@ -845,6 +817,7 @@ public record ExternalChainConfig( BigInteger canyonTime, BigInteger deltaTime, BigInteger ecotoneTime, + BigInteger fjordTime, String batchInboxAddress, String depositContractAddress, String l1SystemConfigAddress) {} diff --git a/hildr-node/src/main/java/io/optimism/derive/EctoneUpgradeTransactions.java b/hildr-node/src/main/java/io/optimism/derive/EctoneUpgradeTransactions.java deleted file mode 100644 index f045ff7e..00000000 --- a/hildr-node/src/main/java/io/optimism/derive/EctoneUpgradeTransactions.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.optimism.derive; - -import java.util.List; - -/** - * The EctoneUpgradeTransactions class. - * Contains all the content of the Ectone upgrade transactions. - * - * @author thinkAfCod - * @since 0.3.0 - */ -public class EctoneUpgradeTransactions { - - private EctoneUpgradeTransactions() {} - - /** - * The upgrade deposit tx for ecotone. - */ - public static final List UPGRADE_DEPORIT_TX = List.of( - "0x7ef9059fa0877a6077205782ea15a6dc8699fa5ebcec5e0f4389f09cb8eda09488231346f89442100000000000000000000000000000000000008080808305b8d880b9055e608060405234801561001057600080fd5b5061053e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638381f58a11610097578063c598591811610066578063c598591814610229578063e591b28214610249578063e81b2c6d14610289578063f82061401461029257600080fd5b80638381f58a146101e35780638b239f73146101f75780639e8c496614610200578063b80777ea1461020957600080fd5b806354fd4d50116100d357806354fd4d50146101335780635cf249691461017c57806364ca23ef1461018557806368d5dca6146101b257600080fd5b8063015d8eb9146100fa57806309bd5a601461010f578063440a5e201461012b575b600080fd5b61010d61010836600461044c565b61029b565b005b61011860025481565b6040519081526020015b60405180910390f35b61010d6103da565b61016f6040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161012291906104be565b61011860015481565b6003546101999067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610122565b6003546101ce9068010000000000000000900463ffffffff1681565b60405163ffffffff9091168152602001610122565b6000546101999067ffffffffffffffff1681565b61011860055481565b61011860065481565b6000546101999068010000000000000000900467ffffffffffffffff1681565b6003546101ce906c01000000000000000000000000900463ffffffff1681565b61026473deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610122565b61011860045481565b61011860075481565b3373deaddeaddeaddeaddeaddeaddeaddeaddead000114610342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c31426c6f636b3a206f6e6c7920746865206465706f7369746f72206163636f60448201527f756e742063616e20736574204c3120626c6f636b2076616c7565730000000000606482015260840160405180910390fd5b6000805467ffffffffffffffff98891668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116998916999099179890981790975560019490945560029290925560038054919094167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009190911617909255600491909155600555600655565b3373deaddeaddeaddeaddeaddeaddeaddeaddead00011461040357633cc50b456000526004601cfd5b60043560801c60035560143560801c600055602435600155604435600755606435600255608435600455565b803567ffffffffffffffff8116811461044757600080fd5b919050565b600080600080600080600080610100898b03121561046957600080fd5b6104728961042f565b975061048060208a0161042f565b9650604089013595506060890135945061049c60808a0161042f565b979a969950949793969560a0850135955060c08501359460e001359350915050565b600060208083528351808285015260005b818110156104eb578581018301518582016040015282016104cf565b818111156104fd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea164736f6c634300080f000a", - "0x7ef91016a0a312b4510adf943510f05fcc8f15f86995a5066bd83ce11384688ae20e6ecf42944210000000000000000000000000000000000001808080830f424080b90fd5608060405234801561001057600080fd5b50610fb5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806354fd4d5011610097578063de26c4a111610066578063de26c4a1146101da578063f45e65d8146101ed578063f8206140146101f5578063fe173b97146101cc57600080fd5b806354fd4d501461016657806368d5dca6146101af5780636ef25c3a146101cc578063c5985918146101d257600080fd5b8063313ce567116100d3578063313ce5671461012757806349948e0e1461012e5780634ef6e22414610141578063519b4bd31461015e57600080fd5b80630c18c162146100fa57806322b90ab3146101155780632e0f26251461011f575b600080fd5b6101026101fd565b6040519081526020015b60405180910390f35b61011d61031e565b005b610102600681565b6006610102565b61010261013c366004610b73565b610541565b60005461014e9060ff1681565b604051901515815260200161010c565b610102610565565b6101a26040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161010c9190610c42565b6101b76105c6565b60405163ffffffff909116815260200161010c565b48610102565b6101b761064b565b6101026101e8366004610b73565b6106ac565b610102610760565b610102610853565b6000805460ff1615610296576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f47617350726963654f7261636c653a206f76657268656164282920697320646560448201527f707265636174656400000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103199190610cb5565b905090565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663e591b2826040518163ffffffff1660e01b8152600401602060405180830381865afa15801561037d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a19190610cce565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610481576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f47617350726963654f7261636c653a206f6e6c7920746865206465706f73697460448201527f6f72206163636f756e742063616e2073657420697345636f746f6e6520666c6160648201527f6700000000000000000000000000000000000000000000000000000000000000608482015260a40161028d565b60005460ff1615610514576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f47617350726963654f7261636c653a2045636f746f6e6520616c72656164792060448201527f6163746976650000000000000000000000000000000000000000000000000000606482015260840161028d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000805460ff161561055c57610556826108b4565b92915050565b61055682610958565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16635cf249696040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff166368d5dca66040518163ffffffff1660e01b8152600401602060405180830381865afa158015610627573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103199190610d04565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663c59859186040518163ffffffff1660e01b8152600401602060405180830381865afa158015610627573d6000803e3d6000fd5b6000806106b883610ab4565b60005490915060ff16156106cc5792915050565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa15801561072b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074f9190610cb5565b6107599082610d59565b9392505050565b6000805460ff16156107f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f47617350726963654f7261636c653a207363616c61722829206973206465707260448201527f6563617465640000000000000000000000000000000000000000000000000000606482015260840161028d565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663f82061406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b6000806108c083610ab4565b905060006108cc610565565b6108d461064b565b6108df906010610d71565b63ffffffff166108ef9190610d9d565b905060006108fb610853565b6109036105c6565b63ffffffff166109139190610d9d565b905060006109218284610d59565b61092b9085610d9d565b90506109396006600a610efa565b610944906010610d9d565b61094e9082610f06565b9695505050505050565b60008061096483610ab4565b9050600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109eb9190610cb5565b6109f3610565565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a769190610cb5565b610a809085610d59565b610a8a9190610d9d565b610a949190610d9d565b9050610aa26006600a610efa565b610aac9082610f06565b949350505050565b80516000908190815b81811015610b3757848181518110610ad757610ad7610f41565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016600003610b1757610b10600484610d59565b9250610b25565b610b22601084610d59565b92505b80610b2f81610f70565b915050610abd565b50610aac82610440610d59565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610b8557600080fd5b813567ffffffffffffffff80821115610b9d57600080fd5b818401915084601f830112610bb157600080fd5b813581811115610bc357610bc3610b44565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610c0957610c09610b44565b81604052828152876020848701011115610c2257600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b81811015610c6f57858101830151858201604001528201610c53565b81811115610c81576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600060208284031215610cc757600080fd5b5051919050565b600060208284031215610ce057600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461075957600080fd5b600060208284031215610d1657600080fd5b815163ffffffff8116811461075957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610d6c57610d6c610d2a565b500190565b600063ffffffff80831681851681830481118215151615610d9457610d94610d2a565b02949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610dd557610dd5610d2a565b500290565b600181815b80851115610e3357817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610e1957610e19610d2a565b80851615610e2657918102915b93841c9390800290610ddf565b509250929050565b600082610e4a57506001610556565b81610e5757506000610556565b8160018114610e6d5760028114610e7757610e93565b6001915050610556565b60ff841115610e8857610e88610d2a565b50506001821b610556565b5060208310610133831016604e8410600b8410161715610eb6575081810a610556565b610ec08383610dda565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610ef257610ef2610d2a565b029392505050565b60006107598383610e3b565b600082610f3c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610fa157610fa1610d2a565b506001019056fea164736f6c634300080f000a", - "0x7ef876a018acb38c5ff1c238a7460ebc1b421fa49ec4874bdf1e0a530d234104e5e67dbc940000000000000000000000000000000000000000944200000000000000000000000000000000000015808082c35080a43659cfe600000000000000000000000007dbe8500fc591d1852b76fee44d5a05e13097ff", - "0x7ef876a0ee4f9385eceef498af0be7ec5862229f426dec41c8d42397c7257a5117d9230a94000000000000000000000000000000000000000094420000000000000000000000000000000000000f808082c35080a43659cfe6000000000000000000000000b528d11cc114e026f138fe568744c6d45ce6da7a", - "0x7ef857a00c1cb38e99dbc9cbfab3bb80863380b0905290b37eb3d6ab18dc01c1f3e75f9394deaddeaddeaddeaddeaddeaddeaddeaddead000194420000000000000000000000000000000000000f808083013880808422b90ab3", - "0x7ef8aaa069b763c48478b9dc2f65ada09b3d92133ec592ea715ec65ad6e7f3dc519dc00c940b799c86a49deeb90402691f1041aa3af2d3c8758080808303d09080b86a60618060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500"); -} diff --git a/hildr-node/src/main/java/io/optimism/derive/ForkUpgradeTransactions.java b/hildr-node/src/main/java/io/optimism/derive/ForkUpgradeTransactions.java new file mode 100644 index 00000000..2f62a5fc --- /dev/null +++ b/hildr-node/src/main/java/io/optimism/derive/ForkUpgradeTransactions.java @@ -0,0 +1,34 @@ +package io.optimism.derive; + +import java.util.List; + +/** + * The ForkUpgradeTransactions class. + * Contains all the content of Forks upgrade transactions. + * + * @author thinkAfCod + * @since 0.3.0 + */ +public class ForkUpgradeTransactions { + + private ForkUpgradeTransactions() {} + + /** + * The upgrade txs for ecotone. + */ + public static final List ECOTONE_UPGRADE_TXS = List.of( + "0x7ef9059fa0877a6077205782ea15a6dc8699fa5ebcec5e0f4389f09cb8eda09488231346f89442100000000000000000000000000000000000008080808305b8d880b9055e608060405234801561001057600080fd5b5061053e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638381f58a11610097578063c598591811610066578063c598591814610229578063e591b28214610249578063e81b2c6d14610289578063f82061401461029257600080fd5b80638381f58a146101e35780638b239f73146101f75780639e8c496614610200578063b80777ea1461020957600080fd5b806354fd4d50116100d357806354fd4d50146101335780635cf249691461017c57806364ca23ef1461018557806368d5dca6146101b257600080fd5b8063015d8eb9146100fa57806309bd5a601461010f578063440a5e201461012b575b600080fd5b61010d61010836600461044c565b61029b565b005b61011860025481565b6040519081526020015b60405180910390f35b61010d6103da565b61016f6040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161012291906104be565b61011860015481565b6003546101999067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610122565b6003546101ce9068010000000000000000900463ffffffff1681565b60405163ffffffff9091168152602001610122565b6000546101999067ffffffffffffffff1681565b61011860055481565b61011860065481565b6000546101999068010000000000000000900467ffffffffffffffff1681565b6003546101ce906c01000000000000000000000000900463ffffffff1681565b61026473deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610122565b61011860045481565b61011860075481565b3373deaddeaddeaddeaddeaddeaddeaddeaddead000114610342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c31426c6f636b3a206f6e6c7920746865206465706f7369746f72206163636f60448201527f756e742063616e20736574204c3120626c6f636b2076616c7565730000000000606482015260840160405180910390fd5b6000805467ffffffffffffffff98891668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116998916999099179890981790975560019490945560029290925560038054919094167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009190911617909255600491909155600555600655565b3373deaddeaddeaddeaddeaddeaddeaddeaddead00011461040357633cc50b456000526004601cfd5b60043560801c60035560143560801c600055602435600155604435600755606435600255608435600455565b803567ffffffffffffffff8116811461044757600080fd5b919050565b600080600080600080600080610100898b03121561046957600080fd5b6104728961042f565b975061048060208a0161042f565b9650604089013595506060890135945061049c60808a0161042f565b979a969950949793969560a0850135955060c08501359460e001359350915050565b600060208083528351808285015260005b818110156104eb578581018301518582016040015282016104cf565b818111156104fd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea164736f6c634300080f000a", + "0x7ef91016a0a312b4510adf943510f05fcc8f15f86995a5066bd83ce11384688ae20e6ecf42944210000000000000000000000000000000000001808080830f424080b90fd5608060405234801561001057600080fd5b50610fb5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806354fd4d5011610097578063de26c4a111610066578063de26c4a1146101da578063f45e65d8146101ed578063f8206140146101f5578063fe173b97146101cc57600080fd5b806354fd4d501461016657806368d5dca6146101af5780636ef25c3a146101cc578063c5985918146101d257600080fd5b8063313ce567116100d3578063313ce5671461012757806349948e0e1461012e5780634ef6e22414610141578063519b4bd31461015e57600080fd5b80630c18c162146100fa57806322b90ab3146101155780632e0f26251461011f575b600080fd5b6101026101fd565b6040519081526020015b60405180910390f35b61011d61031e565b005b610102600681565b6006610102565b61010261013c366004610b73565b610541565b60005461014e9060ff1681565b604051901515815260200161010c565b610102610565565b6101a26040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161010c9190610c42565b6101b76105c6565b60405163ffffffff909116815260200161010c565b48610102565b6101b761064b565b6101026101e8366004610b73565b6106ac565b610102610760565b610102610853565b6000805460ff1615610296576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f47617350726963654f7261636c653a206f76657268656164282920697320646560448201527f707265636174656400000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103199190610cb5565b905090565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663e591b2826040518163ffffffff1660e01b8152600401602060405180830381865afa15801561037d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a19190610cce565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610481576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f47617350726963654f7261636c653a206f6e6c7920746865206465706f73697460448201527f6f72206163636f756e742063616e2073657420697345636f746f6e6520666c6160648201527f6700000000000000000000000000000000000000000000000000000000000000608482015260a40161028d565b60005460ff1615610514576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f47617350726963654f7261636c653a2045636f746f6e6520616c72656164792060448201527f6163746976650000000000000000000000000000000000000000000000000000606482015260840161028d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000805460ff161561055c57610556826108b4565b92915050565b61055682610958565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16635cf249696040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff166368d5dca66040518163ffffffff1660e01b8152600401602060405180830381865afa158015610627573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103199190610d04565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663c59859186040518163ffffffff1660e01b8152600401602060405180830381865afa158015610627573d6000803e3d6000fd5b6000806106b883610ab4565b60005490915060ff16156106cc5792915050565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa15801561072b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074f9190610cb5565b6107599082610d59565b9392505050565b6000805460ff16156107f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f47617350726963654f7261636c653a207363616c61722829206973206465707260448201527f6563617465640000000000000000000000000000000000000000000000000000606482015260840161028d565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663f82061406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b6000806108c083610ab4565b905060006108cc610565565b6108d461064b565b6108df906010610d71565b63ffffffff166108ef9190610d9d565b905060006108fb610853565b6109036105c6565b63ffffffff166109139190610d9d565b905060006109218284610d59565b61092b9085610d9d565b90506109396006600a610efa565b610944906010610d9d565b61094e9082610f06565b9695505050505050565b60008061096483610ab4565b9050600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109eb9190610cb5565b6109f3610565565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a769190610cb5565b610a809085610d59565b610a8a9190610d9d565b610a949190610d9d565b9050610aa26006600a610efa565b610aac9082610f06565b949350505050565b80516000908190815b81811015610b3757848181518110610ad757610ad7610f41565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016600003610b1757610b10600484610d59565b9250610b25565b610b22601084610d59565b92505b80610b2f81610f70565b915050610abd565b50610aac82610440610d59565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610b8557600080fd5b813567ffffffffffffffff80821115610b9d57600080fd5b818401915084601f830112610bb157600080fd5b813581811115610bc357610bc3610b44565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610c0957610c09610b44565b81604052828152876020848701011115610c2257600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b81811015610c6f57858101830151858201604001528201610c53565b81811115610c81576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600060208284031215610cc757600080fd5b5051919050565b600060208284031215610ce057600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461075957600080fd5b600060208284031215610d1657600080fd5b815163ffffffff8116811461075957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610d6c57610d6c610d2a565b500190565b600063ffffffff80831681851681830481118215151615610d9457610d94610d2a565b02949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610dd557610dd5610d2a565b500290565b600181815b80851115610e3357817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610e1957610e19610d2a565b80851615610e2657918102915b93841c9390800290610ddf565b509250929050565b600082610e4a57506001610556565b81610e5757506000610556565b8160018114610e6d5760028114610e7757610e93565b6001915050610556565b60ff841115610e8857610e88610d2a565b50506001821b610556565b5060208310610133831016604e8410600b8410161715610eb6575081810a610556565b610ec08383610dda565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610ef257610ef2610d2a565b029392505050565b60006107598383610e3b565b600082610f3c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610fa157610fa1610d2a565b506001019056fea164736f6c634300080f000a", + "0x7ef876a018acb38c5ff1c238a7460ebc1b421fa49ec4874bdf1e0a530d234104e5e67dbc940000000000000000000000000000000000000000944200000000000000000000000000000000000015808082c35080a43659cfe600000000000000000000000007dbe8500fc591d1852b76fee44d5a05e13097ff", + "0x7ef876a0ee4f9385eceef498af0be7ec5862229f426dec41c8d42397c7257a5117d9230a94000000000000000000000000000000000000000094420000000000000000000000000000000000000f808082c35080a43659cfe6000000000000000000000000b528d11cc114e026f138fe568744c6d45ce6da7a", + "0x7ef857a00c1cb38e99dbc9cbfab3bb80863380b0905290b37eb3d6ab18dc01c1f3e75f9394deaddeaddeaddeaddeaddeaddeaddeaddead000194420000000000000000000000000000000000000f808083013880808422b90ab3", + "0x7ef8aaa069b763c48478b9dc2f65ada09b3d92133ec592ea715ec65ad6e7f3dc519dc00c940b799c86a49deeb90402691f1041aa3af2d3c8758080808303d09080b86a60618060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500"); + + /** + * The upgrade txs for fjord. + */ + public static final List FJORD_UPGRADE_TXS = List.of( + "0x7ef91857a086122c533fdcb89b16d8713174625e44578a89751d96c098ec19ab40a51a8ea39442100000000000000000000000000000000000028080808316201080b91816608060405234801561001057600080fd5b506117f6806100206000396000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80636ef25c3a116100b2578063de26c4a111610081578063f45e65d811610066578063f45e65d81461025b578063f820614014610263578063fe173b971461020d57600080fd5b8063de26c4a114610235578063f1c7a58b1461024857600080fd5b80636ef25c3a1461020d5780638e98b10614610213578063960e3a231461021b578063c59859181461022d57600080fd5b806349948e0e11610109578063519b4bd3116100ee578063519b4bd31461019f57806354fd4d50146101a757806368d5dca6146101f057600080fd5b806349948e0e1461016f5780634ef6e2241461018257600080fd5b80630c18c1621461013b57806322b90ab3146101565780632e0f262514610160578063313ce56714610168575b600080fd5b61014361026b565b6040519081526020015b60405180910390f35b61015e61038c565b005b610143600681565b6006610143565b61014361017d3660046112a1565b610515565b60005461018f9060ff1681565b604051901515815260200161014d565b610143610552565b6101e36040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b60405161014d9190611370565b6101f86105b3565b60405163ffffffff909116815260200161014d565b48610143565b61015e610638565b60005461018f90610100900460ff1681565b6101f8610832565b6101436102433660046112a1565b610893565b6101436102563660046113e3565b61098d565b610143610a69565b610143610b5c565b6000805460ff1615610304576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f47617350726963654f7261636c653a206f76657268656164282920697320646560448201527f707265636174656400000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa158015610363573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038791906113fc565b905090565b3373deaddeaddeaddeaddeaddeaddeaddeaddead000114610455576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f47617350726963654f7261636c653a206f6e6c7920746865206465706f73697460448201527f6f72206163636f756e742063616e2073657420697345636f746f6e6520666c6160648201527f6700000000000000000000000000000000000000000000000000000000000000608482015260a4016102fb565b60005460ff16156104e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f47617350726963654f7261636c653a2045636f746f6e6520616c72656164792060448201527f616374697665000000000000000000000000000000000000000000000000000060648201526084016102fb565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60008054610100900460ff16156105355761052f82610bbd565b92915050565b60005460ff16156105495761052f82610bdc565b61052f82610c80565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16635cf249696040518163ffffffff1660e01b8152600401602060405180830381865afa158015610363573d6000803e3d6000fd5b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff166368d5dca66040518163ffffffff1660e01b8152600401602060405180830381865afa158015610614573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103879190611415565b3373deaddeaddeaddeaddeaddeaddeaddeaddead0001146106db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f47617350726963654f7261636c653a206f6e6c7920746865206465706f73697460448201527f6f72206163636f756e742063616e20736574206973466a6f726420666c61670060648201526084016102fb565b60005460ff1661076d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f47617350726963654f7261636c653a20466a6f72642063616e206f6e6c79206260448201527f65206163746976617465642061667465722045636f746f6e650000000000000060648201526084016102fb565b600054610100900460ff1615610804576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f47617350726963654f7261636c653a20466a6f726420616c726561647920616360448201527f746976650000000000000000000000000000000000000000000000000000000060648201526084016102fb565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663c59859186040518163ffffffff1660e01b8152600401602060405180830381865afa158015610614573d6000803e3d6000fd5b60008054610100900460ff16156108da57620f42406108c56108b484610dd4565b516108c090604461146a565b6110f1565b6108d0906010611482565b61052f91906114bf565b60006108e583611150565b60005490915060ff16156108f95792915050565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa158015610958573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097c91906113fc565b610986908261146a565b9392505050565b60008054610100900460ff16610a25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f47617350726963654f7261636c653a206765744c314665655570706572426f7560448201527f6e64206f6e6c7920737570706f72747320466a6f72640000000000000000000060648201526084016102fb565b6000610a3283604461146a565b90506000610a4160ff836114bf565b610a4b908361146a565b610a5690601061146a565b9050610a61816111e0565b949350505050565b6000805460ff1615610afd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f47617350726963654f7261636c653a207363616c61722829206973206465707260448201527f656361746564000000000000000000000000000000000000000000000000000060648201526084016102fb565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa158015610363573d6000803e3d6000fd5b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663f82061406040518163ffffffff1660e01b8152600401602060405180830381865afa158015610363573d6000803e3d6000fd5b600061052f610bcb83610dd4565b51610bd790604461146a565b6111e0565b600080610be883611150565b90506000610bf4610552565b610bfc610832565b610c079060106114fa565b63ffffffff16610c179190611482565b90506000610c23610b5c565b610c2b6105b3565b63ffffffff16610c3b9190611482565b90506000610c49828461146a565b610c539085611482565b9050610c616006600a611646565b610c6c906010611482565b610c7690826114bf565b9695505050505050565b600080610c8c83611150565b9050600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1391906113fc565b610d1b610552565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9e91906113fc565b610da8908561146a565b610db29190611482565b610dbc9190611482565b9050610dca6006600a611646565b610a6190826114bf565b6060610f63565b818153600101919050565b600082840393505b838110156109865782810151828201511860001a1590930292600101610dee565b825b60208210610e5b578251610e26601f83610ddb565b52602092909201917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090910190602101610e11565b8115610986578251610e706001840383610ddb565b520160010192915050565b60006001830392505b6101078210610ebc57610eae8360ff16610ea960fd610ea98760081c60e00189610ddb565b610ddb565b935061010682039150610e84565b60078210610ee957610ee28360ff16610ea960078503610ea98760081c60e00189610ddb565b9050610986565b610a618360ff16610ea98560081c8560051b0187610ddb565b610f5b828203610f3f610f2f84600081518060001a8160011a60081b178160021a60101b17915050919050565b639e3779b90260131c611fff1690565b8060021b6040510182815160e01c1860e01b8151188152505050565b600101919050565b6180003860405139618000604051016020830180600d8551820103826002015b81811015611096576000805b50508051604051600082901a600183901a60081b1760029290921a60101b91909117639e3779b9810260111c617ffc16909101805160e081811c878603811890911b90911890915284019081830390848410610feb5750611026565b600184019350611fff8211611020578251600081901a600182901a60081b1760029190911a60101b1781036110205750611026565b50610f8f565b838310611034575050611096565b600183039250858311156110525761104f8787888603610e0f565b96505b611066600985016003850160038501610de6565b9150611073878284610e7b565b96505061108b8461108686848601610f02565b610f02565b915050809350610f83565b50506110a88383848851850103610e0f565b925050506040519150618000820180820391508183526020830160005b838110156110dd5782810151828201526020016110c5565b506000920191825250602001604052919050565b60008061110183620cc394611482565b61112b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd763200611652565b905061113b6064620f42406116c6565b81121561052f576109866064620f42406116c6565b80516000908190815b818110156111d35784818151811061117357611173611782565b01602001517fff00000000000000000000000000000000000000000000000000000000000000166000036111b3576111ac60048461146a565b92506111c1565b6111be60108461146a565b92505b806111cb816117b1565b915050611159565b50610a618261044061146a565b6000806111ec836110f1565b905060006111f8610b5c565b6112006105b3565b63ffffffff166112109190611482565b611218610552565b611220610832565b61122b9060106114fa565b63ffffffff1661123b9190611482565b611245919061146a565b905061125360066002611482565b61125e90600a611646565b6112688284611482565b610a6191906114bf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156112b357600080fd5b813567ffffffffffffffff808211156112cb57600080fd5b818401915084601f8301126112df57600080fd5b8135818111156112f1576112f1611272565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561133757611337611272565b8160405282815287602084870101111561135057600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b8181101561139d57858101830151858201604001528201611381565b818111156113af576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000602082840312156113f557600080fd5b5035919050565b60006020828403121561140e57600080fd5b5051919050565b60006020828403121561142757600080fd5b815163ffffffff8116811461098657600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561147d5761147d61143b565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156114ba576114ba61143b565b500290565b6000826114f5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600063ffffffff8083168185168183048111821515161561151d5761151d61143b565b02949350505050565b600181815b8085111561157f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156115655761156561143b565b8085161561157257918102915b93841c939080029061152b565b509250929050565b6000826115965750600161052f565b816115a35750600061052f565b81600181146115b957600281146115c3576115df565b600191505061052f565b60ff8411156115d4576115d461143b565b50506001821b61052f565b5060208310610133831016604e8410600b8410161715611602575081810a61052f565b61160c8383611526565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561163e5761163e61143b565b029392505050565b60006109868383611587565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561168c5761168c61143b565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156116c0576116c061143b565b50500190565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156117075761170761143b565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156117425761174261143b565b6000871292508782058712848416161561175e5761175e61143b565b878505871281841616156117745761177461143b565b505050929093029392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036117e2576117e261143b565b506001019056fea164736f6c634300080f000a", + "0x7ef876a01e6bb0c28bfab3dc9b36ffb0f721f00d6937f33577606325692db0965a7d58c694000000000000000000000000000000000000000094420000000000000000000000000000000000000f808082c35080a43659cfe6000000000000000000000000a919894851548179a0750865e7974da599c0fac7", + "0x7ef857a0bac7bb0d5961cad209a345408b0280a0d4686b1b20665e1b0f9cdafd73b19b6b94deaddeaddeaddeaddeaddeaddeaddeaddead000194420000000000000000000000000000000000000f808083015f9080848e98b106"); +} diff --git a/hildr-node/src/main/java/io/optimism/derive/Pipeline.java b/hildr-node/src/main/java/io/optimism/derive/Pipeline.java index ab8fed99..a537be7e 100644 --- a/hildr-node/src/main/java/io/optimism/derive/Pipeline.java +++ b/hildr-node/src/main/java/io/optimism/derive/Pipeline.java @@ -39,7 +39,7 @@ public Pipeline(AtomicReference state, Config config, BigInteger sequence // batcherTransactionQueue = new MpscGrowableArrayQueue<>(1024 * 4, 1024 * 64); batcherTransactionQueue = new MpscUnboundedXaddArrayQueue<>(1024 * 64); BatcherTransactions batcherTransactions = new BatcherTransactions(batcherTransactionQueue); - Channels channels = Channels.create(batcherTransactions, config); + Channels channels = Channels.create(batcherTransactions, config, state); Batches> batches = Batches.create(channels, state, config); attributes = new Attributes<>(batches, state, config, sequenceNumber); } diff --git a/hildr-node/src/main/java/io/optimism/derive/State.java b/hildr-node/src/main/java/io/optimism/derive/State.java index 33b58998..f6a493a7 100644 --- a/hildr-node/src/main/java/io/optimism/derive/State.java +++ b/hildr-node/src/main/java/io/optimism/derive/State.java @@ -290,12 +290,10 @@ private void prune() { this.l1Hashes.pollFirstEntry(); } + BigInteger maxSeqDrift = this.config.chainConfig().maxSequencerDrift(this.safeEpoch.timestamp()); pruneUntil = this.safeHead .number() - .subtract(this.config - .chainConfig() - .maxSeqDrift() - .divide(this.config.chainConfig().blockTime())); + .subtract(maxSeqDrift.divide(this.config.chainConfig().blockTime())); Entry> blockRefEntry; while ((blockRefEntry = this.l2Refs.firstEntry()) != null) { @@ -312,14 +310,15 @@ private void prune() { * @param headNum the l2 head block number * @param chainConfig the chain config * @param l2Client the l2 web3j client + * @param l1OriginTime the l1 origin time * @return the L2 refs tree map. * @throws ExecutionException throws the ExecutionException when the Task has been failed * @throws InterruptedException throws the InterruptedException when the thread has been interrupted */ public static TreeMap> initL2Refs( - BigInteger headNum, Config.ChainConfig chainConfig, Web3j l2Client) + BigInteger headNum, BigInteger l1OriginTime, Config.ChainConfig chainConfig, Web3j l2Client) throws ExecutionException, InterruptedException { - final BigInteger lookback = chainConfig.maxSeqDrift().divide(chainConfig.blockTime()); + final BigInteger lookback = chainConfig.maxSequencerDrift(l1OriginTime).divide(chainConfig.blockTime()); BigInteger start; if (headNum.compareTo(lookback) < 0) { start = chainConfig.l2Genesis().number(); diff --git a/hildr-node/src/main/java/io/optimism/derive/stages/Attributes.java b/hildr-node/src/main/java/io/optimism/derive/stages/Attributes.java index 4d9fdb37..0a58a601 100644 --- a/hildr-node/src/main/java/io/optimism/derive/stages/Attributes.java +++ b/hildr-node/src/main/java/io/optimism/derive/stages/Attributes.java @@ -4,7 +4,7 @@ import io.optimism.common.BlockNotIncludedException; import io.optimism.config.Config; import io.optimism.config.Config.SystemAccounts; -import io.optimism.derive.EctoneUpgradeTransactions; +import io.optimism.derive.ForkUpgradeTransactions; import io.optimism.derive.PurgeableIterator; import io.optimism.derive.State; import io.optimism.engine.ExecutionPayload.PayloadAttributes; @@ -30,7 +30,8 @@ import org.slf4j.LoggerFactory; import org.web3j.abi.TypeEncoder; import org.web3j.abi.datatypes.Uint; -import org.web3j.abi.datatypes.generated.*; +import org.web3j.abi.datatypes.generated.Bytes32; +import org.web3j.abi.datatypes.generated.Uint256; import org.web3j.crypto.Hash; import org.web3j.protocol.core.methods.response.EthBlock; import org.web3j.protocol.core.methods.response.EthLog.LogObject; @@ -154,7 +155,11 @@ private List deriveTransactions(SingularBatch batch, L1Info l1Info) { } if (this.config.chainConfig().isEcotoneActivationBlock(batch.timestamp())) { - transactions.addAll(EctoneUpgradeTransactions.UPGRADE_DEPORIT_TX); + transactions.addAll(ForkUpgradeTransactions.ECOTONE_UPGRADE_TXS); + } + + if (this.config.chainConfig().isFjordActivationBlock(batch.timestamp())) { + transactions.addAll(ForkUpgradeTransactions.FJORD_UPGRADE_TXS); } List rest = batch.transactions(); diff --git a/hildr-node/src/main/java/io/optimism/derive/stages/Batches.java b/hildr-node/src/main/java/io/optimism/derive/stages/Batches.java index 5062beec..1edd7d4c 100644 --- a/hildr-node/src/main/java/io/optimism/derive/stages/Batches.java +++ b/hildr-node/src/main/java/io/optimism/derive/stages/Batches.java @@ -8,13 +8,14 @@ import io.optimism.derive.stages.Channels.Channel; import io.optimism.l1.L1Info; import io.optimism.type.Epoch; +import io.optimism.utilities.compression.Compressors; import io.optimism.utilities.derive.stages.Batch; import io.optimism.utilities.derive.stages.BatchType; import io.optimism.utilities.derive.stages.IBatch; import io.optimism.utilities.derive.stages.SingularBatch; import io.optimism.utilities.derive.stages.SpanBatch; import io.optimism.utilities.derive.stages.SpanBatchElement; -import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; @@ -22,8 +23,6 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.stream.Collectors; -import java.util.zip.DataFormatException; -import java.util.zip.Inflater; import org.apache.commons.lang3.ArrayUtils; import org.apache.tuweni.bytes.Bytes; import org.jctools.queues.atomic.SpscAtomicArrayQueue; @@ -171,7 +170,7 @@ public Batch next() { * @return the list */ public static List decodeBatches(final Config.ChainConfig chainConfig, final Channel channel) { - byte[] channelData = decompressZlib(channel.data()); + byte[] channelData = decompressChannelData(channel.data()); List batches = RlpDecoder.decode(channelData).getValues(); return batches.stream() .map(rlpType -> { @@ -197,23 +196,22 @@ public static List decodeBatches(final Config.ChainConfig chainConfig, fi .collect(Collectors.toList()); } - private static byte[] decompressZlib(byte[] data) { - try { - Inflater inflater = new Inflater(); - inflater.setInput(data); - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length); - byte[] buffer = new byte[1024]; - while (!inflater.finished()) { - int count = inflater.inflate(buffer); - if (count == 0) { - break; - } - outputStream.write(buffer, 0, count); + private static byte[] decompressChannelData(byte[] data) { + byte compressType = data[0]; + if ((compressType & 0x0F) == Compressors.ZlibCM8 || (compressType & 0x0F) == Compressors.ZlibCM15) { + try { + return Compressors.zlibDecompress(data); + } catch (IOException e) { + throw new DecompressException(e); } - - return outputStream.toByteArray(); - } catch (DataFormatException e) { - throw new DecompressZlibException(e); + } else if (compressType == Compressors.ChannelVersionBrotli) { + try { + return Compressors.brotliDecompress(ArrayUtils.subarray(data, 1, data.length)); + } catch (IOException e) { + throw new DecompressException(e); + } + } else { + throw new IllegalArgumentException("invalid compress type"); } } @@ -284,12 +282,9 @@ private BatchStatus singularBatchStatus(final Batch batchWrapper) { return BatchStatus.Drop; } + BigInteger maxSeqDrift = this.config.chainConfig().maxSequencerDrift(batchOrigin.timestamp()); // handle sequencer drift - if (batch.timestamp() - .compareTo(batchOrigin - .timestamp() - .add(this.config.chainConfig().maxSeqDrift())) - > 0) { + if (batch.timestamp().compareTo(batchOrigin.timestamp().add(maxSeqDrift)) > 0) { if (batch.transactions().isEmpty()) { if (epoch.number().compareTo(batch.epochNum()) == 0) { if (nextEpoch != null) { @@ -432,10 +427,10 @@ private BatchStatus spanBatchStatus(final Batch batchWrapper) { LOGGER.warn("block timestamp is less than L1 origin timestamp"); return BatchStatus.Drop; } - final var max = batchL1Origin - .blockInfo() - .timestamp() - .add(this.config.chainConfig().maxSeqDrift()); + BigInteger maxSeqDrift = this.config + .chainConfig() + .maxSequencerDrift(batchL1Origin.blockInfo().timestamp()); + final var max = batchL1Origin.blockInfo().timestamp().add(maxSeqDrift); if (blockTimestamp.compareTo(max) > 0) { if (!spanBatch.getBlockTransactions(i).isEmpty()) { LOGGER.warn(String.format( diff --git a/hildr-node/src/main/java/io/optimism/derive/stages/Channels.java b/hildr-node/src/main/java/io/optimism/derive/stages/Channels.java index 9337516e..d0a8167e 100644 --- a/hildr-node/src/main/java/io/optimism/derive/stages/Channels.java +++ b/hildr-node/src/main/java/io/optimism/derive/stages/Channels.java @@ -3,6 +3,7 @@ import com.google.common.collect.Lists; import io.optimism.config.Config; import io.optimism.derive.PurgeableIterator; +import io.optimism.derive.State; import io.optimism.derive.stages.BatcherTransactions.BatcherTransaction; import io.optimism.derive.stages.Channels.Channel; import io.optimism.utilities.derive.stages.Frame; @@ -11,6 +12,7 @@ import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; import org.apache.commons.lang3.ArrayUtils; /** @@ -22,28 +24,33 @@ */ public class Channels> implements PurgeableIterator { + private static final long MaxChannelSizeBedrock = 100_000_000L; + + private static final long MaxChannelSizeFjord = 1_000_000_000L; + private final I batcherTxIterator; private final List pendingChannels; private final List frameBank; - private final BigInteger maxChannelSize; + private final AtomicReference state; - private final BigInteger channelTimeout; + private final Config config; /** * Instantiates a new Channels. * * @param batcherTxIterator the batcher tx iterator - * @param config the config + * @param config the config + * @param state the state */ - public Channels(I batcherTxIterator, Config config) { + public Channels(I batcherTxIterator, Config config, AtomicReference state) { this.batcherTxIterator = batcherTxIterator; + this.state = state; + this.config = config; this.pendingChannels = Lists.newArrayList(); this.frameBank = Lists.newArrayList(); - this.maxChannelSize = config.chainConfig().maxChannelSize(); - this.channelTimeout = config.chainConfig().channelTimeout(); } @Override @@ -73,7 +80,7 @@ protected void pushFrame(Frame frame) { // Otherwise, construct a new pending channel with the frame's id if (existedPc.isPresent()) { existedPc.get().pushFrame(frame); - if (existedPc.get().isTimedOut(this.channelTimeout)) { + if (existedPc.get().isTimedOut(this.config.chainConfig().channelTimeout())) { this.pendingChannels.remove(existedPc.get()); } } else { @@ -114,7 +121,7 @@ private Optional processFrames() { Frame frame = this.frameBank.removeFirst(); BigInteger frameChannelId = frame.channelId(); this.pushFrame(frame); - this.prune(); + this.prune(frame); Optional channel = this.fetchReadyChannel(frameChannelId); if (channel.isPresent()) { @@ -139,8 +146,15 @@ private long totalSize() { .reduce(0, Integer::sum); } - private void prune() { - while (this.totalSize() > this.maxChannelSize.longValue()) { + private void prune(Frame frame) { + int maxChannelSize = this.config + .chainConfig() + .maxChannelSize(this.state + .get() + .l1Info(frame.l1InclusionBlock()) + .blockInfo() + .timestamp()); + while (this.totalSize() > maxChannelSize) { Optional removed = this.removePendingChannel(); if (removed.isEmpty()) { throw new RuntimeException("should have removed a channel"); @@ -163,11 +177,12 @@ public List getPendingChannels() { * @param the type parameter * @param batcherTxIterator the batcher tx iterator * @param config the config + * @param state the state * @return the channels */ public static > Channels create( - I batcherTxIterator, Config config) { - return new Channels<>(batcherTxIterator, config); + I batcherTxIterator, Config config, AtomicReference state) { + return new Channels<>(batcherTxIterator, config, state); } /** diff --git a/hildr-node/src/main/java/io/optimism/derive/stages/DecompressZlibException.java b/hildr-node/src/main/java/io/optimism/derive/stages/DecompressException.java similarity index 59% rename from hildr-node/src/main/java/io/optimism/derive/stages/DecompressZlibException.java rename to hildr-node/src/main/java/io/optimism/derive/stages/DecompressException.java index dadb9640..8a403980 100644 --- a/hildr-node/src/main/java/io/optimism/derive/stages/DecompressZlibException.java +++ b/hildr-node/src/main/java/io/optimism/derive/stages/DecompressException.java @@ -1,19 +1,19 @@ package io.optimism.derive.stages; /** - * The type DecompressZlibException. + * The type DecompressException. * * @author grapebaba * @since 0.1.0 */ -public class DecompressZlibException extends RuntimeException { +public class DecompressException extends RuntimeException { /** * Instantiates a new Decompress zlib exception. * * @param throwable the throwable */ - public DecompressZlibException(Throwable throwable) { + public DecompressException(Throwable throwable) { super(throwable); } } diff --git a/hildr-node/src/main/java/io/optimism/driver/Driver.java b/hildr-node/src/main/java/io/optimism/driver/Driver.java index 2d4dad25..2592c11d 100644 --- a/hildr-node/src/main/java/io/optimism/driver/Driver.java +++ b/hildr-node/src/main/java/io/optimism/driver/Driver.java @@ -230,7 +230,8 @@ public static Driver from(Config config, CountDownLatch latch) finalizedHead = BlockInfo.EMPTY; l2Refs = new TreeMap<>(); } else { - l2Refs = io.optimism.derive.State.initL2Refs(finalizedHead.number(), config.chainConfig(), l2Provider); + l2Refs = io.optimism.derive.State.initL2Refs( + finalizedHead.number(), finalizedEpoch.timestamp(), config.chainConfig(), l2Provider); } var l2Fetcher = Driver.l2Fetcher(l2Provider); AtomicReference state = new AtomicReference<>( diff --git a/hildr-node/src/main/java/io/optimism/driver/EngineDriver.java b/hildr-node/src/main/java/io/optimism/driver/EngineDriver.java index 20fafbde..1f21989c 100644 --- a/hildr-node/src/main/java/io/optimism/driver/EngineDriver.java +++ b/hildr-node/src/main/java/io/optimism/driver/EngineDriver.java @@ -74,7 +74,6 @@ public class EngineDriver { private L2BlockRef buildingOnto; private PayloadInfo buildingInfo; private boolean buildingSafe; - private PayloadAttributes safeAttrs; /** * Instantiates a new Engine driver. @@ -287,7 +286,6 @@ public void resetBuildingState() { this.buildingInfo = null; this.buildingOnto = null; this.buildingSafe = false; - this.safeAttrs = null; } /** diff --git a/hildr-node/src/test/java/io/optimism/TestConstants.java b/hildr-node/src/test/java/io/optimism/TestConstants.java index 34b62e6b..24c7e24e 100644 --- a/hildr-node/src/test/java/io/optimism/TestConstants.java +++ b/hildr-node/src/test/java/io/optimism/TestConstants.java @@ -59,6 +59,6 @@ public static Config createConfig() { Config.SyncMode.Full, false, false); - return Config.create(null, cliConfig, Config.ChainConfig.optimismGoerli()); + return Config.create(null, cliConfig, Config.ChainConfig.optimismSepolia()); } } diff --git a/hildr-node/src/test/java/io/optimism/config/ConfigTest.java b/hildr-node/src/test/java/io/optimism/config/ConfigTest.java index 0c813e84..5e0d20b6 100644 --- a/hildr-node/src/test/java/io/optimism/config/ConfigTest.java +++ b/hildr-node/src/test/java/io/optimism/config/ConfigTest.java @@ -29,89 +29,69 @@ void create() { CliConfig cliConfig = new CliConfig( null, null, null, null, null, null, "testjwt", null, null, Config.SyncMode.Full, false, false); Config config = Config.create( - Paths.get("src", "test", "resources", "test.toml"), cliConfig, ChainConfig.optimismGoerli()); + Paths.get("src", "test", "resources", "test.toml"), cliConfig, ChainConfig.optimismSepolia()); assertEquals("https://example2.com", config.l2RpcUrl()); assertEquals("http://127.0.0.1:8551", config.l2EngineUrl()); assertEquals("", config.l1RpcUrl()); assertEquals("testjwt", config.jwtSecret()); assertEquals(9545, config.rpcPort()); assertEquals( - "0x6ffc1bf3754c01f6bb9fe057c1578b87a8571ce2e9be5ca14bace6eccfd336c7", + "0x48f520cf4ddaf34c8336e6e490632ea3cf1e5e93b0b2bc6e917557e31845371b", config.chainConfig().l1StartEpoch().hash()); assertEquals( - BigInteger.valueOf(8300214L), + BigInteger.valueOf(4071408L), config.chainConfig().l1StartEpoch().number()); assertEquals( - BigInteger.valueOf(1673550516L), + BigInteger.valueOf(1691802540L), config.chainConfig().l1StartEpoch().timestamp()); - assertEquals("optimism-goerli", config.chainConfig().network()); + assertEquals("optimism-sepolia", config.chainConfig().network()); assertEquals( - "0x0f783549ea4313b784eadd9b8e8a69913b368b7366363ea814d7707ac505175f", + "0x102de6ffb001480cc9b8b548fd05c34cd4f46ae4aa91759393db90ea0409887d", config.chainConfig().l2Genesis().hash()); + assertEquals(BigInteger.valueOf(0L), config.chainConfig().l2Genesis().number()); assertEquals( - BigInteger.valueOf(4061224L), config.chainConfig().l2Genesis().number()); - assertEquals( - "0x31267a44f1422f4cab59b076548c075e79bd59e691a23fbce027f572a2a49dc9", + "0x0000000000000000000000000000000000000000000000000000000000000000", config.chainConfig().l2Genesis().parentHash()); assertEquals( - BigInteger.valueOf(1673550516L), + BigInteger.valueOf(1691802540L), config.chainConfig().l2Genesis().timestamp()); assertEquals( - "0x7431310e026b69bfc676c0013e12a1a11411eec9", + "0x8F23BB38F531600e5d8FDDaAEC41F13FaB46E98c", config.chainConfig().systemConfig().batchSender()); assertEquals( - BigInteger.valueOf(25_000_000L), + BigInteger.valueOf(30_000_000L), config.chainConfig().systemConfig().gasLimit()); assertEquals( - BigInteger.valueOf(2100), config.chainConfig().systemConfig().l1FeeOverhead()); + BigInteger.valueOf(188), config.chainConfig().systemConfig().l1FeeOverhead()); assertEquals( - BigInteger.valueOf(1000000), config.chainConfig().systemConfig().l1FeeScalar()); + BigInteger.valueOf(684000), config.chainConfig().systemConfig().l1FeeScalar()); assertEquals( - "0xff00000000000000000000000000000000000420", + "0xff00000000000000000000000000000011155420", config.chainConfig().batchInbox()); assertEquals( - "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383", + "0x16fc5058f25648194471939df75cf27a2fdc48bc", config.chainConfig().depositContract()); assertEquals( - "0xAe851f927Ee40dE99aaBb7461C00f9622ab91d60", + "0x034edd2a225f7f429a63e0f1d2084b9e0a93b538", config.chainConfig().systemConfigContract()); assertEquals( - "0xEF2ec5A5465f075E010BE70966a8667c94BCe15a", + "0x4200000000000000000000000000000000000016", config.chainConfig().l2Tol1MessagePasser()); - assertEquals(BigInteger.valueOf(111_111_111L), config.chainConfig().maxChannelSize()); assertEquals(BigInteger.valueOf(300L), config.chainConfig().channelTimeout()); - assertEquals(BigInteger.valueOf(3600L), config.chainConfig().seqWindowSize()); + assertEquals(BigInteger.valueOf(111111111L), config.chainConfig().seqWindowSize()); assertEquals(BigInteger.valueOf(600L), config.chainConfig().maxSeqDrift()); - assertEquals(BigInteger.valueOf(1679079600L), config.chainConfig().regolithTime()); + assertEquals(BigInteger.valueOf(0L), config.chainConfig().regolithTime()); assertEquals(BigInteger.valueOf(1699981200L), config.chainConfig().canyonTime()); assertEquals(BigInteger.valueOf(2L), config.chainConfig().blockTime()); } - /** - * Base goerli. - */ - @Test - void baseGoerli() { - ChainConfig chainConfig = ChainConfig.baseGoerli(); - assertEquals(chainConfig.regolithTime(), BigInteger.valueOf(1683219600L)); - } - /** * Base sepolia. */ @Test void baseSepolia() { ChainConfig chainConfig = ChainConfig.baseSepolia(); - assertEquals(chainConfig.canyonTime(), BigInteger.valueOf(-1L)); - } - - /** - * Base goerli. - */ - @Test - void optimismGoerli() { - ChainConfig chainConfig = ChainConfig.optimismGoerli(); - assertEquals(chainConfig.regolithTime(), new BigInteger("1679079600")); + assertEquals(chainConfig.canyonTime(), BigInteger.valueOf(1699981200L)); } @Test @@ -195,7 +175,6 @@ void readExternalChainFromJson() { assertEquals(chain.depositContract(), "0x6900000000000000000000000000000000000001"); assertEquals(chain.systemConfigContract(), "0x6900000000000000000000000000000000000009"); - assertEquals(chain.maxChannelSize(), BigInteger.valueOf(100_000_000L)); assertEquals(chain.channelTimeout(), BigInteger.valueOf(120L)); assertEquals(chain.seqWindowSize(), BigInteger.valueOf(200L)); assertEquals(chain.maxSeqDrift(), BigInteger.valueOf(300L)); diff --git a/hildr-node/src/test/java/io/optimism/derive/stages/BatchesTest.java b/hildr-node/src/test/java/io/optimism/derive/stages/BatchesTest.java index c766def4..e5c4b4f9 100644 --- a/hildr-node/src/test/java/io/optimism/derive/stages/BatchesTest.java +++ b/hildr-node/src/test/java/io/optimism/derive/stages/BatchesTest.java @@ -176,4 +176,38 @@ void testDecodeSpanBatch() { }); }); } + + @Test + @DisplayName("Test brotli decompress successfully") + void testBrotliDecompress() { + final Config.ChainConfig chainConfig = Config.ChainConfig.optimismSepolia(); + String data = + "011bd930006400ced916f9203df809787af4c297bd00ac9ef4ea4f780f146cc019fa4401f380c330ec31369d8388ba0fe55c8679e69c8754ce60796fd398a27db55394cec37de3bfd07b3e4130ba23bead865dcca2c0e30e179e6984d830134da7f8ef15b32786da0ba803e9d87cb787a692cb7206c0aeb1ae9ed2c911de4ebf6e9f3923a1b017c067d8131040052c6ed981ae4a657a1409c8972b098c94aa2f14600ec79a0848d36052335eda678511fbdb8af33b56d2d5d8229e09cc0f5afb939f04030385b547b7cd455b0df3ac15d613141004e6f42bce5b6b636569480babd984daaa6dd9d956fc2f6b3ae7da560dc4aef64838ebfc9159f853de635a34b04a1e3facb52908570affb0fb88f1d2fe6bc193b10b46fef407d9b816f2e5abbc97bd80a8b6751b51cfc0b8d9e718cb47ea0212b11889d7fe86e0b361f2267266315b62cf59997f2c6febd58ecf5924704a479f38ed626016069589aa757928cbf00fa51eae3519ec50a6a9b8c2b6b028ab017d33ed775581de96ceb9fd050454ac9c86a19b59695fa1ba072487a2c52aae391c901b5e4455bf56c04216c520b5b41a2bbc3bb66b82eb3f491a04913ec1bd06543f13b1fecd2e6e417cec590d3c6312c71651ad3f2c1d59c2cbed031a2efec46e852bde77cdc85835154ef8eb6f7a4439e63b35a9b18391162202c0017f8808d4464d437209b1ab1f2775a2fa6e3f569255fb5bb0a94ccc55c75fbd5b2e649dd84bb7a33675e70a9ad58cd304567a23d27aa9f532b79920b1a25fef931e48e999bb9e52d25b0a7d54adb42a869fe68b060054fbf2af664acdd8beffd5d5d44341706b36ac3e76ebd714cc3cadaf6e18cecf7560ac6aaf7febacd99bc77dd1d13861c10aa80aa005b5adc29875a9ad356634906292fd9fb82147b3464465b6cef48b94558ef28ecb4de3cc7af87a061dc7fea07ff9f996166562425843ea434d6bf4cd013c7adfb7832ad6fa0e76310079e04b458cf827f1eef9d76eab824d1f6d85955e2faca9b02fd6beb951b8ee1f998f6d4d028594133fe908ac5453e86c0b8ed0ae7c9ec7cd9dd6ebb4c2727e9a4e170638fbc4910d017f13d5db7d366a9f6653ba4c60d4768d13f8e0ccb48e31c06c7e336505bfaae68122febcd80aa2f89a1bae72a35cf03c7288345b01817082a2a906e566f28d07c7928df84537233d367e57e5069956864d6625f11d0e4765f3bd1ad6120a59447d0d1e185d6702f98da03d3c295bf429cb502e0d6d706c81bb63260effcbfe9623203da61609376b1c6f4f16020b9b3f93d47f59369fc97b8ed2ea14a0aa9c81b287d728f34e84ed1a7d60d8c0ef379524b3744027d0d4614c1f3d275cd21f77b1e0acb6999b91cb539424d6935152de981c411b7a20d0983e7086dd6d6c90f1fd8404c5d04d0557967d5d707335a5cd3eda7ffcce58df0de483c03568f92693f3e242b3688771c15ccbb656998a671ec439dab780948586c4a050e7285fc68532660446eb0f85a09ad040bc2cccd46944767c6749025021750e0079e73eae11c57a64174c0407085be145ab0f8921ff2cadbff2488cf57cca6db2a32e7075812cb38d4590e25d0e0a20043c03f040001570456acd37020d544e30d5fd2a2c3c77f5713801d2401aaa0b3dc777e378ccc7cd89ae8ca8954723df1491d0ce426fe94816573721df58fbebe411d571be98107a2f4b611afb67c4487c73137419f5cf42a314e81a95dc8b10ed1481b919e7d49f7f46b50dcddd513bd6e8ed368a1a4a094da22242ed6dbbd20af15b63c81bb997fa950df8f397d3aca8acedf9e6d1330df1925d35522a27604dad3d4af5fa33c0cdd703c9e8e6a3b4d1d0d71a35ba722d4f939ee8f3a6fccc5da30dc9543f657b75610cf3f3bccfc3e31a91eefe50c806d2690d12f0cd62eac68937c02a466772da91cf52632098a38c8d3b3edf601fc230cfe343a70517efe8fd26b8716116c9278035c84b95aa3ba96c2cda9761b10805663d03d3c1bbe1d760826e745230ab7eb523ce7ff06d388a2f579a31292ede799a24a5944b1dbf2450a48bd96db8186c41fb719cfa0b06060a247a85cd03282f3b7007405bee0bc2bc6f7d6853230f029bbe5324d47e925d181aa6a5634bc5edba3ed5d912de36844d52f818a2f2e9c86ef82437d6b9bd5270307d91b4a924300ad6880cf56036945ddbf562c7e1f9f4c9576dc76b60b5ed3dcb90083b9bf93b6b8ddafc9b250a41619888b31c7d6bca4b3ea222543e117e76315c4800dfb5e5fbb8d155bcadfa8e05f5839bb8ae00338ccbb4595ee6bd61d652fc2a9370532f2d48ac3aae11519e6c2cc6df0e4093f923e047d81bf537492b1f03c8c4d70ee1ca1cb2245624cf8fff8d55412fcd5999cc84fc918283d1cae59b79289222ec599bcab862a6a160e488ccc846fb5d1a6bd46751251024d9bfbef2bdaa0491190a41518acd0d10126ba1df97e49a7980584fdf15bd214c58ec237918f43335895117b6fa2cd990d4698e99aa0b0dab032b612b643cc1194e038ebf72f707262a3267f87db0fa19f7ae0c9da04c53140b80689c9414cd2d55ac90d7c985711208716b134575522f66618e03f5b8bbde5e713528fce0912ca000b68d33165fd358c5cfd5a831c971eb58ee08d170f40f352faf03a4dcf14cf09870cfdf92b2857a97be2f71c954ce27010f51596ed2b2e332e15977220339888968d3bf36a1f8dc7ee0bd902ca3bd9345825453b9f60c5351d21e44b1e4ed4c9bae04767d258bbc9f8668c66c4710251bc672361b3538e033f996f68e9b23fff9130e0852b7f5a764f95647f8741eab213e1152a19adc6b9eb8ee0b02f642cc6433cc77adcef491e86677fabc4400eb70927e4f96ee280ce104d250bcb47b88fa8ba7ccd6c117e7f70e9c72b94b8fe20dde0e51e309b0145a38aee6426d702c144eff194e075c84b037e08c102e0426f2181e957c2dea0e4748a44e83478ba074ac9a674b9d9506cb4aeff7f0bda5cc80f9411d1d98575b609f2edb7fda82d8824fa87e2b059a2ce7ff0967954fa50db18bf8909bf627fc7d1260a412bb095c037ad71645d6cd5014cf3a7160833f03fb5c3a4739a3b36103585296e9905512eb575c508965da4cf66e9dbbddfef5296d731cd022bae36e0db83674776b3bf0080ddd147d15f2f70feae895b546f1582211aa19876fa4ee95b0c85a416ee7c89e73ba2be9d33111ffeea214ed7af645c0dab277e4a683f13f3a446ea9e5f644e3de4d3d84fb4a8e9ba318ee6ac43eb05bb7b56dcc8ff977292630c556e3c5cd507cfb06672c6ee1ec37a3e11a6b5cf70f93bf25207eba5655a6eac9d35c4bda67cc5fd18606a14ba2a5b6e070f64cef46db1f49ff6b7f3d958e18b4d3fd85519e51feeed0901ff4834d50cd848f8bc2fffdcf08ac68ed9455bf3632ef7d3ade4475ccd060fda7fc03edcdfa7ca8e5db8cac0d79ca5bc8dbde46b252e3da21dc7eb343ac474bd76502841a4cfec5d6a5ae72efdb12951f3fee645c948f1774faaf30820de82db7dad510836c9458e96b538bd07c97f0cc94445b245a5dbfacf6ff416a829fc8c940e4d15a5128bcea33456d3d9b7b7ef0be7c56510476fb1cba418ee8b68a96d77ed504a6f01f5fb9bcc61b94b7caf43d543d7bf12d2bfd10196230e319db42a556acd2e950a17bf9882a7f0e62c7e2563febb4defa27ae7b6edffe6144563fe909ce11679ada4c114d87c0b77f6b992bab53e1e4daccedab2d769e8be24da1833d9a0b4e1557db41e268b7d33ab924aa1a5da9d3e9723e5d0c5557dcc1eda3310d876a35bf65b1a8d03b1462ce3ee7f1954d2fe3ce0f74b65bd9ccb4efcb58d4cc8eed63a4ad6e3129edb9ad16b03c67c4853c025514a2ae2e422e40891d88cca1e67cb8af2a4e54f92f72757552420fadfc1b4485c2bf6cf07ebac5b23b4bba87f20c4ada316755ddbad4384b58de1d9d06dc5445c59dacd4d9f8db5d55ab335ae0ae6732f1d1c3d22c37e16a7187691c21242f6a746f3f5e13786e9bb45e7bd5d71a25dbc6b8b18ad06457f9d440dff358b446babedff49ff072324a38f295ba323e4613ee34c3f7e50aff712146ea9196af19ba66a68503b5f666fdeb08f4fcbc0b4e59f9ea611a4a6bb38feab748b65ff121536564830a4f6a51c6b4784f3a330a5bfcdfae0447787b84da6a7b02dfc7a64968768bf495418b3405f6b6201af703ad263f0eaf29a00e00d3e124b140f6bd5ed8ffe2fea141cd7616f79de9344fe939ed4ae5ac0e178c9e4fde1265c8b9a38d119522ccc79787437e535e2a641153daa463fe126a0ba834dab5908d9dc973fe2d58173c2c8f5cd79f14342313e6c3231448f31501be1378fb395f6fd1d29bce5a7cf97244cd5e30d37e2229ee1ee30bb307667f099abd04017b2126ed49bf3bfec5690e0e7949c6a1549dccb0dca9b250246cfd207d6ca0bb98c28504658434b153c078d4d5ca6ed9399823b4a0fb6238e0fe6c38f39e9cbd72c5df85026801cf004a104005bce9824c9bde718707161f69d32603885885c3216da7d5dfba504aec9b974b34446f7531649f58a1a4a78049069ced54c761603a4b1aa00298298cd4cac4650535d8a60b042c72c4c517d82d0bb5a977ed25bc8430fe7e61aea1146afaec84b1f249f02bd7483ba5b54b8fb58c9174a187c20e5f924e88afa5f96caf67153f1bab666c0c8df5a625929a2168880ce6dad6e47b94aa2b9508ffe75aaa2b644468f724b3697966ccdbc8a87506a69861a8addbd6d6b9e143144d342d7f60de69ed5c9991a383d22c14f0fb0158913c968b64391d5bc2ae44a3fd008839e3c63007ba18e9d224f9327f904644a8a5b3ee3886f3979369c9b39b5b643dc8b71f58592d30eddcd9995d53a6b6c117cbcc020fc3dbeb6ed9f2c2134520bb152890fa194801eecf8ad2fab5b5e5017e1d0d81db1ff5610fc7ee314ebb385b5a23df9340167b448f8b2a7651195ec3d6076b49cbf39ee9c3c04001250a8732035345d97ac3dfbe7066f33ef62968fb467c65fb70368acdb7d0665b4998b2200c590b130a7145abfa01962b117ed2a14f5a251f3f7a711d241140cbfb4ea27d645037ef244274f85e82683a50f257ee5c703c45a2dbe306615921247538085a6974886b20bf9d853c903eb53051e2772eabf4183c62b96b3ec29242770d3b4fc3a7e87e544157c7c253a2931233e55066d51e8483bea9fdf7fb2396a574f6c62967e384d24fea4b366be2bd4282bb2afc4529f53379b1915fef99f25bc58c4387221705c5f275910828232462df79b61fdd1ee94a6d1b5e186584e6dd9dfd94ab9b695ebcc7a169b52642e409479c7b2f9b5bbe169e7c8ab7587970cb4b88b5457e5f87f99ca55747f89d4ad44eabcb715c83cf543946469b6c6379d4799005668375343733ea23aae067ec9f77658ca66a38ad5110299f5b0de21341a7b3b9f32cc1207c2d581c218c15343d7e0dcffe78ee3aa15d6d3ad24c2e47269fdbe2f79bf5a291746411308351dd88aa509dcd63a0eebd095cd3c1d2777173fd13c01a8df51ba5b74123e3ea8896db98f723f701b7ce064140fa93deeee4bab2ed4b0f08d803310f47b0b455c9f0d2b2acfbd79f04fa399167ee4dfa3c568e0b0f4e3b69dfcf86184cd35a2c54a6e9fffb5e77f3f3e390d857b406a51a5edf9faab5a6e8b79ae90714e00b7806782e6a6ad618b9e32231dd128cb21f19791b5e3d154eeefe100a36862950d8c3e259d52aaa3cef876a6ffb9fa50a95c3dd4958a09b6ac549632f7abf280a7df63a916c230c63bb9f60515d032810cb1451a000c284e66d7a66198b18248d90349146ee8bb3941f52528bf348797826458b5c8cf549a4c7c4612294c61646037f72a3f4abd694d9e812775d5c5e2da33793e16d059c67ab1e85a5e185db6568565e1ea1f0c606f4e96f924e7c707e033bb30f716563192673a8dffdb23210fe54f4af33de04d7291a90ef583fea74f086c9ea3b391047729ec98a2e6b5fc3bc8cc29e7d35ef9746f21c6069f21b16a2d943d6eb9176a1f36890f8f615eff8ca36e64681ecd842b7aa8ff7976cbe46aa16fcdd26fc97d04ed5acb3f0f4d7058efea1db43099461b79cbbfe50488e8f4ac76eb1bded399494c24f17922ca92e7d32ab5f28651c0f573da1c56f0d91a25bd4e6b14ec9f4987218d1b9ff43c839917937e7c25667180cefdc7e557c008565033ec332d14f8362ec7e3186eb2c47640d4e71454a56139b6f86c3bfb6e34402ec41626db97d9138bd72e92668b8589dfa773b975dc0b1418eedb6d5a49d87f09f60f34df5d057939b50d13e1c7b4c3e64131983079aae28d1f0868eb22001f788a8fe5099d1d4dcf68945fbdfb6eb67a076da810feff4bbccf319faf540568b5e3b864a044a5705abae1da2b2545fd9f6558081eb152108bdfd8de5494a621aa87cb9a733414bffe4bd4f7c8679fe7f65a15a1cb6fa21134d7e256b658539023b1bc363fccc8f9975b888699f7ee685a74c99bf16f7ec6e77249353797d9ec1556d228405d284d570e1bb66fc4d769e57690e537732b9a32b9e93965a3214e499d8102bcfd89562d80461294f3f885a5321f7cab5d66d1488197ff72e1476b7e2eee59bff22d6bb25deb642fd61b92c6c9963a931be979315b7b99fedcd60b0093b8185def658197888c5b641154e8ec897a24683f9e1d0e008a0a5d9d5b00cc64e641960e02bb157d2fe1e9930ca0543d084bea376687655d36fde740074fba7e9d9da7dd5a1032927f845731fbcc3e814aa1eb508522eedb6ccd4363626fd7d25bc251c742b922eba4ec8cfc9f50d793c3c65afe7017c3dd7c1c91537d124bf071ebcde0d573714e073f732a4263fdcfc18297d0c0efeb08513fdee80631d7a02a8bcc4747f2ef32b803db2aa34f22f730277e899fce8ce7f422e16cfc817626147fae149c5b91bf7e1ebbaeed73d1716918df362410ed7b9817e921b5436eb609b51a05d937ff925378f8c97cc2d2715442a5ee7648e67ad6ce6c3afdc23efec10f8e1b5bca2f0871665dc811449aaba39a44b852bd0ddb409e0c5087b6237bfcde2abd44a7b71f068bb2b6a6bfd1b5be84144bb8ba1b3f2186ec4fddfb7992cf9a912853c71215273b20eff10be3969a0f2c9dfd5a57a05a5e060cc9417b37099789322c1531c1fe4dd0daff1c4c5474de96d3392cee91e4eddbe320b416956d4da3e6eab9b825b05d9634668e9757fe4fea630f22de98f9f8201ab82fd00486cced02fa682cf84f311f2f94fc4608535972619c870fa1d67864cd8bb0a0d2ac4ec9291bf126687ab8400447f9f9345c6aaf4e79792f26bd57758b7357256620b281ccb331c23986a54a186f8e8c4169cb13416aa5de76f138e431c9db6cba464999015cd31e2b0fbf6eb4893deb05cef102c63950c92be838181c2d6027c465dceea34787954a3ef4cc7b6c27151c44c6b88bbbdba1aab7903afa4fbf5e924e1fcbf6547ce4be5b844c2d922604b3648575146e9eef876d491cc6cf10a4e01f27ff4fdd4efd9dd92cf2d131fa1b9f68534ea0c7cfce363f8d86390f56ff79219d0c672846e0d30bb510e782db91488410985f6c7acd1955b7b4427940354d10a0f31ec59bfcd306c9db63ab6b07814dbc3fa7b7b1017624b499dc0470c3d1e4fca70ce4499e71ad438ba1ffe7362454bb74f4ade72f8da60540c53f4fd52fedb3696ee578c883535668375f7c5a5cc394ba8aed911b1478cfc9c6221699c42b91b1649c7ba69bbcaa98c22767023a6f214d7afd47e8b63af1a677e033b6d456684cfd87c83beedb3a67f728b5a4ed626dee28c23ff7d6e6f559cfcb27d8d5c9b7eae9ec9721d898ca665977ec6fcc92abf0ef07990aff1475cbc80d7afbc1cc89705e871e942e855d86d3c8fec06ce4a694e06defbb632023aafe868a7d8b2bfe211ffb528fcc896ff0affba618f7bbdfdd11143f0e61836063f4ede18af0b6cccdc38b37e18e251cfab3ff7a2dbdd95976926d7dd9354ac322f5479eac6bd25d5966fef393f52c9c939ad7a1b8a114968babd25094d4e80d3b41d5bcaa5638d7a6a7323617dc4fdc12a1a35cb898f343660ab33f47930238eb7b968986e355882a8a90e7e0778467d9e5c2ce87b0084fcc42baaf024a15e08c6dec6dcda0e17b9302415f191565b82e3e7838a29cf777af58c04eccd05f853faf19ae38786ba8675c489f9ce3cd8d1c57284834e4495224e1f24bd83779dbe5e3941bdad9ffdbab1492c64af840d3063003546ea0c93cd3667ff337530b516214f1d6b54ce6717457a9fe8fbf5ec062953da2a1c740457102683358c7ff9edf80a5a3123a7f299ec71feebb2b58f574770b32299168beb18d175fc2ae73efd94183213de35fc9a9b92b3bc2382393e7f36261383989492f7a81f37a893ece0841f46813c33e1de9cf6ff60fb5170e478fea413e0a86b1ce9ba4732fdff92edb52f3d19e5a0d48191273953f2cc20b7600e6ef6c9e9a0ab8c07b6601e69a5179d318b9653f454bbc1ac507d058c88ab9428296f7c8683c7bd1f1b3e5e3fc9fd6669298c3094f78d1c238584a43374ee14e0e5bb7f2b4457c25b897b456db0ddc412e35d856233f3a59b4a9c1b923e1d4dd8110a3b8f0571a0759830c6b1002793acc5d8d28807a2d77126d0950a3cc67922d307b8a7e176ccc99757c62d297b6047675f218755ab395a15486acee712208c468d790b1d0f139f04c8be2fc40e27a9331f7913981a7e865b4c8d70d68180bd9046cac29af1b2fe9db21ea4e3f236ee457cd7bb2fb87f617cc26e82151a5da7d6217e7a3a771f3484e244ce1141581881d7fb3628dbeed168b2698cf4794df0034e5058f2675812309dcd90de1043211af8188027c92c87220b3a068782998a69891f586160a0c056dad764db1f6b450e1b27768fac05a86395f0c26b063e3ffe33630c3d8e25bef45f1c87dc183cb350f187a5d69f6c00b51ac199456a58355a41eddcc0d289c784d696ec4563433a8708bcfb449926e403ea18af73f2c60c863b25dd53adbcaf2a77382d180777278210c572b7fae3c32f0179ed39758a4dabcbc6ce49b7f2e192cdb96d799967ef2c676ad924c8ea02d01d8c5303126b0aeb5d76754a5ccc98f886408ddfcf22a5e6a50700ee700da2e77cb808cdbc7b899ac214966b435f3a2ac883471ef97abcd2a003e2017f125280327282caa30c0f0fea6398ba20b733c9bf863241eeff279fb025e499a31e2263c0e90596ed0439fc0d74809a58b223da85107e8fe65fb710d35783d76089f1bdfee58ba3ae940b2326613a0bf6e39246383eeb63c2e26a1673e6a979bdf11b0e0116fc07feb6108ef38e95070bf71b76bb29b81bce9d8409c79444e9c22eab8e2896212caab0a5b13e04d1546f3ee1d8234a807d3578d88e7ba4869ce85f4f4c6f8b1a39e92f2bda88d528552b3419bbfe2b4596fb681391867a120cd7bd8113c68555bd18900505f24633ab88b4f8118de34e5fded9fc8b755336674394f572bc0b56755eb2f03e7f1f8b56815092e4a2a76acb6cf7807396ae34b88ca4d4749d01b7d5b6b75617317af8bca43f83a4068625fdb4ea1e072bfe825db0d22b0fae2926e51b07730d3b6909c6181f095dbd5b0a27c3847a7fb46c1665e999d8283cd3b57a6eca25dc6b48adeb8d899869d9683188fe83882b6061e68e32122c4e59dccc3689b1b26f8e3261dffa8cb5af66e19559a904ef23e7bd94d62530353f0b6fe82ef35579a3e937e5f21680d1500f860cb6f98de229b5064e1667bdaa059bd68b7159012527442c506c458b507abe93e93f1fdc91f68fa385a1e512a4794ade2f39672f94f5b2e607ffd2da8b74aa7dbfa0005e319ce4dbcd21571a3506b5bfefd441c01e48e822c9c715dfbbb26aaf9b46b397892d020ebbae16cdcf9f006ce188b728ed44884b8b12f07fbb95417d68fafc90a09d50736593c0db73fddc0283530cbe94a1792718f0140902a880bbe773a65c87a8f3c1aae39865bada8273e1d83911696cd1f57043df26974d459ca43ae99b6d2d8d22d5c0379d1ba2b167af5584dc89e0aefb0110d93e8b4334fb341186e0c799bcfd43bf220c3eb7bf6761926298e938da9bd573109c172fcf98978a0c8f554582795d5b9824808f214b546c6e789e0f82ae42f7291420f50c10076f4f427eb0ee81fe81e1a0710d516f57d1e1f0a344a160f4adf6960a6b1898ced548552d9411bb8eb982f355fc24c89ca057f26851d33d42ec604a87f843b589008c50aa08bc7926991ca0854c2ba463e0f3fb30c6953b155221bf1d09162e320c06c6d42f494639ee6a180ed616a2a0cb6cb9c1e60fb9f98fe2cb31120a91a530243638d15f786e650e2628c65e0171d89a3ec50dec70aabafbbb837f7feaaeef13f3b866949e2cb8ec7f53867dc3c2dc822974e458aadb491c4fe134674fa1cae090c1f144d2eb0c9130c355a456d650d8f5fca0be854b44a0bcee599fa8fd471f63b2cde44c6f546bf346afdef25fe7e0d72ffa5f2a80f5476d4d65c47817240b7654a571d542345a38da33928b9ccc213c4129e195fba98b90f42e08a901caddc0db7c6d0563b76103ec5dcc6fea31dd4a6fc4d62f4286a3bd06a76d506012f0191807bcba336cf44314d533a2718d852f527290ab6f2f1cdb202d34fbd6af94955cfef571bfb56604970b915395f24c5011fb70ff5cbefcc5c27e2f668e5437ed1823c08f235c79a541f1ff86efa09acaed52c91851c799dab615a0fa7f2b7d3516cac11bb2500502f4d267a04b6aadb94c23ff54e293492f0d489f6bc38c5b30a04ac5b32f01f66664fb647ab51532fc3f61aede2306a0c875d2955ac076cceb5c0f68b748b2a8f5aa5a8e911a3966b533f47652e2d565a3aeb138216cccf16b0bf3698e419852c2b42aff8c8873e121d063ce97198ff846617193d90e16e2277e98a43ed3f8f2a6707d462bb035f7b02795ae0e82ac968d7c22e822e6b4de3df00f48191e09dc6a83fd45620e52286e18d164f2f878125090138fd6d206b49dbeacfb7d5f6a0691d09eff59300cacbce96b8676fb2b04a4a3ae35f8902cfb1c138203d1d91ce63b58f1418c7785f55ff42db7ba2e3963fed86b9a3bd8a25e6ca397bcb331b5d572dd2c9af2aca59532a8922cf9bd48fe9a3269f484b87666ef44cb7f47078d51a7d0acc816150f244b6d648fc50eb37e55408dec55b72b36b3b258ea846df9a291bfa34df445efcc9ec86e6a68e667a75ffe8b3eb8ce33d6ff07be0a648cfe1745b20556fb870340646b27d6af774b664eddc6df958a6c80d8e4c2beb8dfb4e0fcbf9643363658ccf4e6c2dbbdf0e975a87aeb05b7c4b9014094e33f8a4a35f6560bb33c5a8969bc8dea7767eb6c5f546a24366e5d1642e1b290422da295aac1edec4fd714fb77c53e44e7d8dd3c20c3ab6901fd44b8b4bfa53f1472902300dc5fdf67540b0bae861fb36028898efabaa0a9265ad5151f1c90d5400331a47777cf01f08db897c72a286f28fc911becdfe505b503ac5884c8bedc4e094001e68067803108a0022e300f887e9e73f3045f08998457e056bd8413771c848676be7a295fee58f00df9776d492ff726100bc7947cd2a0efe9e522f5e100310aca1d3818d9ef15a643dc6774ffcfa2711453ec0a7ee8ba199897764dda681afdc777839427df29632c820e54f8b3872f6484d4ba5dd106382f1e9c46ed715789daab1ce7c9df447df66aff0a05da6b7a1126cced57d8d0efb93a9e04dd293f94b840f74431f8ff9afc1031ca12b7dc0fbc681a39a89a19262cab14f6199e28f899fd5a1cb012b14f6672bbfec5f2051577124be3d244d3be954add5740ad52f9d746ea74b0ddacede92bf8e49fcfdf1a07e477f2ca270e2d8cbf964be804cec29b6aeca7f701326ddc5dd66eaf5a5cecdc4332cca37901683b0ce5e4f6bffb4321522ab7d89b2fdd8acf9b2e2b14f2618a2bf77cbc760b5423b2d6347dc26b53f010581a891d2e69ee2b3dc024352be3f76871c1836ddd8befeea7e31e39ca32a5a2506010e019e80702a88091a404ace896499ec1322ebf55c98759d7c21100136923874c0473e48a9047da73d25e8084db75afed67281408bb05fa7b22bfd2bd2c3a7c933de44ffff6811355ce4670d037cb19511af26b9a9359da07b51a1699cdbfa42ff10b23c97f1ec2b6f2072ca29cc0aa9001b227f8f8238a7ff09aae72f3ec18320ceb58d36bc5db4549cb1bdb5981f0806298cd8413c4257208309af3509256a35532fd4ff263feb6ce127eee92325a5dbd1fb941bb973450cc6cfa30b80d794922be9a60bd2a1f13795024e831debc50f171a02ebd9194febc9e3254c731c1aad68acdb733b82df8863f79f0ab9dd7d43587e57aa9a34d59db18c0f53b91da5c47df35114d2d5b97306479278e7cee92d484d27e3bba3f7784fc558fd4ea269af8f7b40377d038162130e9d93e5de2aedd68239a77cbf309e9e7fcc3ddd0d9b2a1f684b677b3a3e41593f580c3161db794a8fcab91994fba25b50a497ff63dd95756bb3f93e416b9d345f53be6d8a556e90c445921ae4638afddb7aa82d14b6d23842c1b23f6afda26bbc99758b024d78d0f1e5727c499560f9a96f29abd4757f98b0474e81541b3694f5c30515d9ab0d438e7025b7855dddfe4568a9c16acaa7c4aa52e808bda09ddc61a098600ba516b33e6b9458eecfa91f1b8bb9a8a64bbc944571c017bfc0f9628d1e220fc8aa1217569f6be5ced32fba9b70f3555ebc86f2b5807652d2d9355b59174c5e6ea26380a2cd9521ec8cf4ac91bdfc76c40c9f0ecac2a126a3f07963b7af66dfc2836b361a4f0afd8ef96fb0110756928e3545d39ec0f6e5d1308b496446301726ae2cafeea4b1cce8a8360530b61e8fde0b9fb8b7eca7f4997051a44dd6ec07861eea0dffad1c2cf57c381cab30f05443d03c2c1c4c8c5d7e3d33bc3e0c153e404620d6ee7f02f7974a16019ab6490f41d0c0c1440622d422df4bb476728f84df2bbba577cab6907640a8ab4ba53e380c316c6446511d3a0ca39e4731e176804ca926df570a5cd380ae1a845f1fd48a930a716949020e8ca971cd26e34d5b1b8e1d97bf33e7b6234fc458080918541805b7255034bac35ea1598c9cec713a98fc7d78c39a95846cb486e67536fc0c7b11331e99447bf9b85768692cb61312bfd2307dfef1ddeec37526e38d8bdd825caa931efa4accc1f014fbc4b8887117145c8305c3fc73db3a18b55c6c9325abb64ad5463529232247f8763716dc6d63a202161e1dbd4fc2d2f1328d99c62c5c39f7d29afb300dee32de1d240e6fb20dfd3b3f74f4cb62a119b47fff3aa7a82159c6de7fa542788fd5ef4fc0aa53e9a950b0ebeb2879f29631094eddf98e8528b843808d803e9ac8b995fa44ac060c0d38c92c94de778db261a6609c013153a4844ca26b5c882042ca13acf5f4e0a2e70f4087fb979304bb738b74090978cbcad9ae39dcb606585c2563dc396834510b59ead34ae32c03f9ab037fa7d4c48c391caeb43c12403ce76aae33030505831a741879df39aa3477a2d438bc300640527ef153cc4ba3d59fbd4055f63fc7adb3cc1b2e70bc29f5ad1e53032de2569364b564cdb51b2b08e85f73601456736b9cdb5e76b8c963231d64c0ab366544813131538543fd8f27111fd7115ed4755aae501f1e146daac2fbe16451ca78f1d49340df24fe6fc412ab1cf19825d96fec7112a1b59b4023b6548ed93d1e3414abeb7e4924f920fcccfd306e585aad199945f5cfc9937c97812726db5c3f00d1f604a1ec36a2f20fa295fae9cfba9df19dfcce93e2377173a068d791379cfcdcc80a6cd8d673ad856d2691a86442162087747c51f0fd9b7dff46bdcf86dc25a7526ef53b60ff4b0b5e5d735f967b0049364b66866963233710928ffdb7c76850d63f1dbf869ac0b2fbe8de874f6d94b978750f4d7e7ff9f5c87ea780a45cdfd06b5d3e4c85dcdfb184c0a4f55ad9af8cf44f480ec675c9c2e0a3e9b0938332ea97f9a7464e27127b285f6d63a7d2a7d4becd93d21c6126f079b44fd4a11c498bb2ca30a9b7f7be8b0e82f528a203811f09dc79eb7c74ca54bd08b4848b1b27e4331ff578d4f4cba7aa2b66613681a9568f0cb99ed9c9c5e110bf351f375888dd33d117759cdbc2895f47a9a93f90c78f73b4d1b97b7ffca2d704d7ac2765d99955c93216d6bca307f457589d72c334f818b06870ed9f99b0d715126e64af9ff506e43c780af964de4172de264d7027d3f25bbd3deaac4cf659e5a5383f0652662d66619f99a0a90dbf267f7fe0251d8543fea151aae98d152b4825ea71575317e3aa38856100b70b2bf1b441da2c0a7f4b32a26e80a44e57762ef05eee3751f124f46c984aedef6321d7e8bb9d697e02c95ef344651f443f74211b52bbd1eda67416f1a3b63ec4c1eb5711d4f83a69b21e36551305e5eca5b38c22857c8bdad4bc7a39038bb65ecfc866127f87b601ad018ca00353a21e8425f8496fab93b1acf3363ee886b0e3634591d207e3da8f1799a9d7b40f8ffa58498ad69bc03e4c9d3aee6a7140afaf98013a91cf40404d1884bb336a2c6a927742e2b5af1ac496811e90429c6b581e42a0e8c3d2fa90522becdb0d12e551a5cb16a87d4fce04dfa662f286b50dcd40d7c8d2ec7f510f913a8f844f0d0f997753751d2acb22df7db8937039f752795093c2c5178aab4488aa31e08d803c136e1e041a637ac66a352c1de2ee49248052bef2a737bded1c59b2157b9b9bf41241258effd56a53c1a2bc96dad2ccceb38c8f60c3c651acc67cef88fab7c5cff77829e42c1981ac48d8155ffb6c19932ffb5e8aa7d31c2b13f06d2684ffd7853e27f980d7aa5497a5f206224412d0ac05ad2f2bc67fa30305192317c4f1f5d20600f647e8e6abf66828ce4ce9dac50030b753d98ee6ebbf9944f9412a5a8b13f93a11be20d96948804a9fccfe533e3dad1cf0a795bbf1d577fce665f41c770db97c3f984029781cfc079104005bc278e995301dbf41c0958a7a95c89943a0b108d0a474e574adbcf927c51a89434cfdb271f283d7e3484594bc00985020d395fd6d16673e07f0751aecf25be938f492de660db57702293ec863f8cb88d1047e23d6f3c6710eb270af408fc8c9a38bc1c993924ad2c08a1ade00684178a1ff32768c1df11c8698e5e5cb97b148f60215f49a9d79c9338f77d8aa38c3e26013819db1c2089ea497bf2c201ef2448702c511a9bcd5e942df8c1b9c9ecfcdd9787d75c5a7ae44ff53437b02a573987fc07ee3dc82b19dd8029582d6a71ff96dfcc4017b278a3930e80ef4868b9fa4f453ddfa094f65b8a90a88bd4dca79741169ad1765b4753a0c4abce868a6008a9ef8773d59b98ede0aeb8fe0e4da96e105d811831af79d7f1fdceeee1268947447b438e84cef5453bb1e35ddbb6c23a35569e95716f8ea4eda5fc20f6070e5fef941c6b475436c28e9beded15c11faf59f08b6b026cc876997bae5434adb94c84ef7475720345aadd34b635a5122d10078bdc8ab4071818a6fa4e2ecb17cb0f47c897a1325a6107180263dd3af5331f8b6d2c9e1e89d06aba4b9799fe3973963b8bbf6bd27fc7b6ad9859eebe80e3e38e649f4e30aca15d262028e63e397e999469e379d4807dd3bb9f4ecc8ce1a35628fae1c81f2e2d3c82853abbd2dd2383a7146825f8cd24cc7e5880c2daa8bb663c7b8b7a3121403215c7c44925f8519baf559b9ed0caa559ae35f189e69e43c24afed53bc44276e04e0a2fa0fec4d8a9e2fdefae9f293236352d27c5cf115b57860e25ed7ffdb7c3db0a4507fee54f55e2db37d144a1e5fb3620620a8445ea8bfd503ef587fecef17b1946b8e7615d1db4ceeb055060c8ecf8874f07f16fa1cbdc6debb4d2be20f166cfb984d5e99462fc5ce7fdf717b1d9f6cb70c2fe5008d230c20235ce35bb8052626c47b7f8ccb02daa1dd05656caa92c7a56ea7ca40aa2f36a93c1efee39ed70cf965ec43002dbdf6014f4b06970a620ca726d7cc5320985b3003ec39980002a60eadd51952e8d948e0891cf79dd484955bdef70e1c4c547698dc0baf9f20f91377a34fe184277dcf6ae61be5b70e08193fa4e040c0c14768377f3632f415f077a77b8e0cd79f3e5ab1a2dab472c73edd40fc530c36574a62aa5c58ff2c099a9487dde9adc2752df2c845dec47e9cd21d70c744d59e47cd77d643d3cfea15172ecc14c02d0f269afe81cd710d0c076b19effa358b7c61c5770dd7b880eace427589be0c371af1c96316fdc49332dc918f87ba500933834e5777d8a05cb78e69f6d278f8118c1b2a62ea3914d8fde26a4bfc6d10e9248fc9f5a0f070078f67e8243135eedfeba4a615fcfff0be735b1c474bb79bac3b60e3b611c471c36f78f0b34354204dc169f4c0a86a63391d86eb3831638b994969f2f6aa3a049094135d3deaf4683d428bdc1e9e8392f91b7f027c38217e3a755d41e9af729a16a46729471f42cd468e42df93f9e7252cec4ae348ea7ca256d62e213745a4c7df545fd9dde00bf8cf2f572bee00d02e62539bfab4a4516f9a8c59a09b411e1832aa1245a4ed3025417e2498c84e898a6350fdb3bbbff7a4fb6565957c434ebbf47b03c8681943bfec57d41e4230b826d146e320bf147c9bda672dbc2437a40e57567360ccb0f4a467c3b21492394309fce4ababec7a20c92f3e2180cd177cfab54400d3b714737fb7d480665cec583c9860b91d174a66f30a9ecdbdd23b9fcc05b9c9ddc2599dd47cd1380b6a45e2a91e8e0c16328a6aaa403de5c572ff8298b39b623bfb6524e17139fc4c98b19cd4fca452dfd61c3cc9c2dd7a2137b270586fbb0c7ec71e2ae9766a3b68fad8e2105a2e772cc77e49fad567865e58575064e36ed2cb50c6f3af792040be105ad7cda6741fef57ed3f0cdbe59ef1e032fc2a8b0edce71d3d24720cc709c3576e970d168c6394a3cdc1b9e3cdd3257d855dd628b5491a5ecfc7bd09dbef479b62d6f9eacfc2a6e135336e800998cdb57dc2d3322affe78b0b3fa5439769b7640b5290fc5cfe25f9b9069acb816b0f6d3754d61cdde1c6d2b93355597aa23e186dfd3cb7bc3800d41554589a56e5bdae80aa26dc1055ba22b76853f291be2f2d013e92c52a7f5c4ea2e1318bed6030cbed690633c938759c82626547b973f5675c7250e1019e527deff53d4f8f4a8504210cfce3dfd3369ce7769e76473fc6244b2c3e88ec4143d62e85b383c4847abf9185524a21a151bf93a8ddcd51edd6dbb598f3778e24a6bedbfeac3f8ff1c964b0926a857969490ef3824251c69bec0f04dea426887e32ee4939057ebde0e1b8c3672e93eb2e4a8caea6243aac74526ffd65f3f66f97220ad68b44d90da0b376e54e5a96ec7f7d343f53b318588b57d4614189d7be1ef4f4a16853fb8afe33e147f39170d84253ecbf12c47c52da473595168eb6260e742d551c7cd157a748afde1975171c6de5de1b4d76fa372b973285eb2d3ce06cbcfd2dd77ebaa6174fb4321b81f0b1c3f7e6f194f437be2c7131664fcda2b7f6213bac1e83fb2323dac0b27404429d1305bf6241c34b4e2594a498ee23ec2312b94193162956ca7bed5d19e2100"; + Channel channel = new Channel(BigInteger.ONE, Hex.decode(data), BigInteger.ZERO); + List batches = Batches.decodeBatches(chainConfig, channel); + assertEquals(1, batches.size()); + + String data1 = + "011bd930e08e94a89daf73710d130fc039db221fa427e3e9d10b5ff602fca4577fc203ad9313f493c51668a017c2a4ed1260401ae0dd8967eb390d13f2fab12f43bdb0cf432a6630bc76a84c50bedb2a48e562bff35eeabe9cc219de13de55412f6692e1708609ce3440ac1909a693fdf68b581342ecf8d480342c3e3b435349a5d903609718170fa9a4702fc7df772fec119dd097c017e8531040192c66d18eaa4261721c01c8932d0e8890ac2be0630cc398f04f556750355a3a608612f9d782f52746c2c5c83c8e01cc0b5afb9b97080505da0ed526076535d4a34650979f8f1f98ddaf306fa58591a92e25a86a1d62a3ba6d6b53be59da78c1b1a3128059e51e7fdef133a3e0979cfbb47040a51c6e684b6320b624ee51f731fd95ddf7fc672367b4bce94f92714dc4ab37394f3b3e612dab56829e8171d3af31a6cf940504421122cf830dfe1783a42dc48c2296849ef352bf18ee96eb5deff308e094b61e61eae5c02c14320345cbf250a6c15f725d6c2b12e8a10c1331f91d4161667dda26ea1f2a7cbdcd1d73070b70c818d9f543b7b3523e02b58f08f6858b951c735820579cf0ca7e4dff854cb2414a29556658374c977897ff125470427dfcfbf5c8bec622fd5b5d9cfcb898b3ea3846440ecdc29a7f99da330597db06d49dfd085d0b56bcee9b1031aacb1d71d7df7509b2cd76ab53620623cc85f880037e10a14e6b55758925f8ae7eac9489aafb831809662dd12013e9e8ebf67fba771c88da3157aec7ad6a4ee554abe967f1ccb486c47592eba5ae33812285bf3f26dd11d232f63c24a5b6e5fb285aa8950dbecc16f501c87665df4d159b307d36d554d54240306bd6ccdeb6eb37648c5c2d6fae684e2fb5608c2acfffebcc595b277d515158a141f2c8f2a005d5ed82e875c9ed3546149042a2dddfd82107d3067825968eb4cbe455b6b2f6ab2da38c3ad83a3a6d87fec0ff797916e6a5220218436a438d6bb44dfe5cba3f7602cbd7fa0ef7d000b9e02b05b4b867b1eef9b76ecbfc2d6f2df9955e4f8ca9d06f563e3991d86e9f194fad8d7c05e413bf68f02c5592696cf28f51aebd5fc6cd1cd76b3543b37f994c17f83b79c7920c01ff10d4d97e35689d65913b4fa0d5748de37963cdb48cd1416d899a3083df547241e17f5f6df8917ccc0c5639912eb99ed8849a2c8140187ee114fd3253b986c3138906dcc2db911e6bdfeb32fd0c4b8346d3e2b876fbe3d2f95e752b71f94c82be7a77b4ae73bebc06d03e8ea40dea94450887ba163826dfcd21038bf7f560db0190165d83809d398eb32f038186ce9b49ecbf2a9dcfe0be406a71f457514a47dac76990fe20c074893a34a8e7f59d4a945e3aa4e16b6c37a28d9a132cee8fbd5c7052ddca49cfe12a4c14e9492f2e6b480aa70e39e46b481b38c7ec36d24fff714a8464e0aa8c2dc3bacebfb59adc6a17e5377e6fa4e70af286e318b47897ce7e75a65ab445bb64ac6159ab48c1310b641fed5b40c84441a093af75902be5401a3304a3f48740908da9209ee6a66a5442bb3eb344fec8905a7b809c531fc788421da2333a9c3d84a5e0b2c59bc8807796da4f6924da6a3ef92ec94107b8ba4092d1cac44ff621db09c007bc007040006570794ab5289e3a323b98e261151a96b3ea240c0f612015d99996ed87511cfad3d644577ae4ca93a14fb250484781975404938bab804f8cdd4dd288ca384f7430ada7852095dd0b7c04ae9931aab4da57816172e71a85ecab00f5149e9929fbd4dfff8635f54ddd91bb56a86dd60aea8af18dc242026dad7b52f271db63881b39577a15f5b8f357d3ccc8cc6d79665133f571125dd592caa7600dcd7d72b5ba73c0edf74389a8a6e3d4d190b76a559a324d0fe39ea88bc6bc8c3dc30d89145f253b354134b38bdcafa3936aa1eefe10c806c2593502f0dd7cead691dbdf325a7b72da81c7427d2088ad9485332e4fff004237cfe54da30913e7e0f5cebf71691ac1c38731c84d91a233a96424dc976ebed809cc7c01a681f7c26ec078dda8c46066bd2a07ac4df05d18920f47aa113136ce45aa04b9a4732daf0450a88bd175b8086c4efd7992f21b0a0a90e00d3a17a0b46ccfe9dfd9fc901fea75e74d9d127118d0f8832cbee68be4d2c020350d533276cfe5b9d606ffae3e7492ccdb0099475b66c33ba9a1d6f58d8c8de19b8475059e61907a44883ba381ccda9e272b16d797779e4a1b4e3db34def79ba78e8f9ccbf592be4a63f4c9170f2c304ec65a8db539e72e1e5217209b0b38b61027cb82ecd3fc60dafe36cd476cd291f5dc574f818a19ca74d73331e0c3297e25619041b7ba9412255b10df0722463d17eb600aa8c9ffe3f43df2945252cbdf52113dfdb052bb2491299113c3e371b2a035f9b323318f17923f807a394cab6729124845833b794b0454c42c088e119110d767b5456c82fc28a2048925f5dc54765313c632704493126c75f40a499f6408263e61162357d5ff80e37617e80e0aedfcfd0284259d0e2bd644d54ab3166a22630ac06ac802e97f600a73b0e38fcce39189828cf98e1f5c6e8a7dfbf3670ec6498225b00446125276b6cab6004bf4d2e8c1341085b1ac9aa127bd10bb2ed29c7dd74f78baa4061874f24fef9d0adec31b81a46cabe2e860d890edb27b2c7f006a37f29b9b9ed21650ee7fc27f8fb7e16e4cd947bb47d094b26b2def138f04ab29316ed57f12f3a13e988810c045b7e35f1451776031f0524e96d1d4ce2c41a4a35e7e80a127620b2252f27ea3445b0cb1b49c4c33444237a279c20c92086bdc9b0de1e97c1a7a477dc0cf1efdf3040a09a8d1f3993682dfef3458cbad84470b94a52af59c2ba0f08d80b31954937dbb33cd743a099ddedf31402acc348f83e5bb821d185e14975e2a43e40d45e3da4b70fbf397db46395c95eb9176d70b70b1b4d802551c2b035166a82623a61f45e60b4c18570fb034e7061026002f7e15189b7c2ee30b804ca545894707287ca7996945929b08cd4410fcf7bf28c385be9abcdd0cf576dbf6c402c41a7147f14038c97f3fe8631cba55007db867fca4efbe1ff39f537548ed902ae01bd6a0a236a67c88a661dd930c15f017dce1da3ec5159d0fe4cc9cb3488ca09752bcec884d2adc6fb774eddaefffb1477d80ea9e1ddb0b7075ceabbbbb5ecb904866e0bbf0bf8f905b6f7ca5821b92f1109548fc33650f68a9b67ae20b6b165cd39de17f7691b8bfd70568c7239ffc66765d13b72db4ebf890a915d6abe3b557f70550be6bc96e5642b82b91eb10be8d669691df365fc53820e4cb6517f753510dbb9c51a8b5d38ff436fb0c61cdbfdd3f85f318897a64585a16af22cc782fa05fd7794817ec89270890d388c35c3abc1e667e266cdefe79211fd369a7f504a334a3fecebf3027fb2f0ab1af37090f97dfc1d8116ae99b2ecd742e47e48c399a88a1e1aacfb927ba4be5d9f0fb1789f91b1264d7e0f7edfdf48526c583b823968b28f716feeba8a87508249bfd938d756ec8b2e51f8f2624fc6467a7b764eff1384b306bde754b918a0918c122a7e6f6c1698ef129c99126f8d40a9ed97d1da1ca4c4fb859804441cad11ee84557921aba96371cb0b3a90cb2c0cc76c9b43d5cf16de51d6f43ca89c4017fceb239bdb708bf45e91b68fac6b27b66da9172c4d08a63f6759a8d08c513c1b2a702b1b51e1cd866f5fdcee679ed65dffc276cbe93b380acfec273ec53a664f559d29a46ae713fdbf96b1b23a1546aac5d8b6da6cebb128d61832d8a3b1e0587ebd1328867237ad9d43a4a2de95329d26ebdd455779cd19d4361a5d7fa45afd47068302b55d3efafc6b1e57c9e42af6e2507ba785c554eba19449d5f4c42e5acaf20e9ddc8ed37201c363464cc03d40593ef2fa32f81294d00ecf1862c683fda6ec4891f72a5b5b2b29f0d8c2bb415020f8db1ae7976b0cab93845b08d7a0842d6366e59d73b593b8c5fdf199ff6d6564ece94aadb59fed75951abd39f67a06030f2d34d57223b62667a8fa315cd2a27af7ced30d9ec78e71cb8d675d8d61924db42bb3105556a57775e7472e93e648d78fdbfe536e767a71079e1217faa728fcdd26d8be1cc1bfce84083d5272d543378cd430a096deccffed011e5ff741c92bdfdd4d42a8ad0f907d17490eca3fa52b0dad916189cd4b19161f886746a18b366d8bb1047746282d772670bdad1b0566b789dfe8348993a1eff2a3b03f51aaf362711afd6b0150ed8ee20b243fea04fd2e1f1eeb556d66b13f18ce72155f52af95cf6bb1c1a879a4cd9106ecbb5a6891c9823c3cb958a4b7652502e6d1258dda66af2136800ac33d739998995ca73ffcb541c37288b5fd898133d2a1de5c020154dfe1603b80775ff375e6cdbd69cc4557afc794acf9336da712626ed13e50fb60d6d7c0d92b10b01762dc96f8a7fd7facc6e090a7442c52e5e90cd3bd0a1359fcf64fe2a77a9acb296c48607a70232b19947b6d8dccb6adbd195c33aa0f9a3df6affa73afc9d96b17dcbd4e0035e005400e022883b79c11a9d3daef71c06223ad5a240021cb3018849dd4ba3b6772f103b332f1faa8ed2ebaac534ba4b46430d18093adca381454c5f59d7ce8c9f4944a84a5f9d598260b784cb284459798cd0b3529f76dc5dcf8507ebea12e2164aa7aacf8317289b02b3708bb25354b4f35f41134214782f6df124f096fa4786c6e6615be1a2a67ac0d8c74a7c5139b2028f074665a56a4fbe42a2b15709b73cd55e5d242d4fb1259d45c3366ad2494da03538c509456ad6beb9cb0c10ac61a163fd1ef3577af4d495141a9e6f2b8fd008c082e8b4592ecf66d411782d17e00c48c7e63980d5584786992749937503d3cc4c249671ccde9dbe9b4c4f9ed1da22e44f427466633541b675646d794894dd0e53223dfe3f0ceba6b969ce04421c876a51348f9022403f767466afedede7607bf8d06c31c8c7ab38661f618a55e9e2fad91ee8b238a3ca1c64616392b0faf61ea8135a5e4b8cff5a0a0008ae58fa407a60ab3748745bfb167713ff5c96bf9847f67f974328cc933d76259899f32c70f5e0b15087641a9fc09962d167cd6a64d5c251d3f7e751924e243c9fd41a475ac5f3bef284470f4510c6f3250fc4ff6827f3c59bcdbfd166e593e386538b0b3c2f0085b5f6e271371206d6a61a2d8f74246f12968c462cf6c842999e6067a9e8a47c1edb89ca69689ab583b397acabed4b22d100b754bebdf8f270c0ba9ac8d33f68609c55f94572c5684fb0578f795b88b926ae7722223bf3f32e4b68be8878e842ef38be46a23e0904688447e70ed3cb93ed194d8d4bfd24b0bccbb39f92a553551bd7a8d77a6d6180b90c61fb3efbf6e6dfb987bf028dc61e4c22c2fc1d714fa7e1fe671925a1de1752c563dab2ac372093a57611b196db489e152e342e49b0dd2d6d84aaf0baf849db17bd993369caa66b74282277f69d18f4b009dcde6cc3305817035a1b104d056507479d53dfae3386b05f6b4688833381c18bcef8a3e6ed70b47d21085c07486b5232a02b5d64f013a0fc6308d874b3fc4ccf44e016b5456efe45efa0df4ab239aae635e4f9c879cda1b78fe69cfba7b93eb4a36af3d20600fc42c0ccec24639dd53d3a2f67f7f22e8d744ae9917f1cb5819362c38f5b4ed200ba23f4d6dbe5091aaf7ff47ededafcf23421fe16aa42a583d3f8a96eac23faa269f9d001fc00bc003045006cf1a21b65f26a45980910e2222eec2aaa6c248dd1e433ae25f22b186c631ab96577a3c0cd5dcf5bf48162885b91131756ea916258ebdeafe262bf0deef40b0093788e97e864676f127832f5540ea04e0c737edd0324a9b4723a807a70a35705e9e27ff94945c9c47c8c5312e5ce4a0af4b243e210c15223732371cf89b13a957b9a6c44293b0e7ecfc6611b595046bc3e7345bf92428052bd8264db5f2fad4096ba44f9bf62ee1c803e33bb03bfb185b3a966e3c87fcc337331dee6f79ff3afd6d50ad823ee9aed593763b77a88c9ea33d6104fbb98cf0b2d60dd4eb28f4f977b37e29048f01a646df6101aa7d44dd1e29671af77a71d1ef3827d736d1b7f22427e63a957ddcbf65f2d4533461efb760bf8574a8649e87a5bd2db0f50fdd1d89230dbb66dff78740b2bd95dbf78aec6c2e3a89c97c752049126a52a7b37a059246713055139abc5610499a452d2eabe40cf729fb11ed87bff8ec1319f773ce2cb50641b04e6dd745879dd02cc01768061040190c8ab6fd4d1fa6bd1c9e3938c51121514568b61506fbd696f91b12600f0273f3ddabf8d9b573375efde5ead4ffbbb9ac7cb60d524cd7ed46ad5cb84dbcad7795231f0d4e7c05bb30cc31b9e02d4434aece3405f1fa7754a40571982778b5c78af4c6a6d62f0cea4d9bae5f015aa987dedcd31fd22fe7a8370399cdba6d68cae1485de5cc3ab6f04a927da53bd7fefa2ed7f820d4b677a66749f169a0d2d5bef60435edb3d701e139fac5e6ca42951874d563068adc4ae6ca0a633866169afbf8b92f23f37021c301edcc2b57a9126f0df6f9fdde4806bbd2fa3c9d8bea443013a411a3fed267cd4854669e5b710e5d6732a9bd2b8e9d9a522204e491501f2347df956cd008612a4b3b8c5c5326f5ccb1d269e08b1efff02a1074b3e4ece599ff26d2bb2dd6ba42f969b12c68916da13ebe9f9d19bb7590e545a7bf053d8181dafa54117084c1b24111460acf93ac4a85fe695fef00a0a6da53b708c24c601aa0e329b653d4fa11113fca0185d788baab7a647a5ddd6fd6780874fdafe1d1d27dddae0d29c3fb4df510b44bef18a216b908522ae9b6c8d0323222fe732db82d1878279426bc8ecfcbce218a381e96bcdff308be996b67e7889d6894db070fdeec85a919f0f1b8791a50921e6d7d8e943c05057ddac008ffb0c7b20a3905545ca1bbbd94fae6431f5b5618fa953a82db758d7f76e73d231689a5e70930b122fcf4a060df8bfdf47159f7ed9e0b0dcfc27a352785e9d8403dcd092c9db5b749cfd7aacebbfa96934bc24de29a9d022216ab7534c3b15232f5e655ea9173b20ff8f45c5e91ff4b8d346e4f8c2059d514dca5cc11e066d208f0a4873eb59ddf61f2516ca1be3c7cb2d913b6b1fa8329f028a4d545d751710233e2f65f7426536eaa583e574c80d88ca4dd2f98674e0aa874fa6f75a94e5e3128083df9d5344c3aceb890ff0ccb1b716fc3733c61f149436ac794a863ba875da7afd49c5f8a19b9a68fd3f236ff4e5ee684beb3e4a63fe2604b10f18ef8e72f7eff55fe7e0024267be83743fe57fcc508e9fc177c90fc9a73a3346438ed9e3d5d3af443990a19627a45cf5b01b5cb518c07a27dc8ce246156fcfb5b51e9adf207b4eb1a2933a179270cd30b0c3d986254be9af0f8d4069cbe3416a255eb671d86451895bac7a068119f19c53662bff7fefb5883d6a04cf7082c6d990492ba8782025d03f01e753eaf55e7e65289ba3719db0ec3461231a926ecf6ec6aa8e20eb896ead7a39180f113cd8a9897cc768e80b181c394a897aa248fd4d9f569af259ad9e6e69f02e4fdecfba5d7b3b72d97532a364275e30369d01ef8fccf43f7b94f27e3d7e6293da085e1d0b93dc0e84a3ee0b9e49c2fd2892f70306685aad4d2233ca1e4af8252708466c72c3a43b77dd6e2d0cce45e6407ede7e54e58802929790a1b3ef4743229cd3e136996a35fede076f4df911925cd2e3169dbfe7bbd611154e18f2b39d11d0c9def68e16baa8cfaeb6e8b4b1973169d3aa6c784eed172730a05c4b1f265ae1844edeb266dca67d20a98410de84a531cbf53facd4f3cab9d78f56db51418e1be62f2f4fb76ce1bffcb2e6a3a5a197b89d18f6c7adfdd293bfa66f918ba34fe5a3d97e138161a4dcd2af98afe9b5976e3effd2857ed07bf7809ab577135902703d0e5d081d02ab35a7b1cdb0e9c97509d0e7cf46da7fb775cd3504fb1647dc721fc675ef09925f71df66dc30efb66e7b33d1aefdd21740c769cb4214e07d890b1716ef538c4a5965b77e149b3b72727dd44aab32fa1506956a0fcdc8d7d47ac25d7d67371ac9c9d7d56f93e142d14df7877471492140fa36133b69443c31cf9dcea4ac4fc84fd93593872961d17616cc0467be8eb70460c676bd120cd72b0185e430dfc01f088fc3abd5cd0730708f88a9557e248747ac2197919716ad95fe6401195c745586ef38f5f0c2a24bfdcebd6d1e3b136e5e34ee9c5698c1f19e818d41226e43971614615c9e20f3a125408397e12f50ede77f8786607f6b67cf5ebc4243291bce1d7438d0154e929d38db75a9dfcced5c0949af85cb5cc91d95f5d64697dc21f37b31bc40ca9ab309d23d8fc50e9cca1bccbef27d79de533b2ca5f49ee17bfaf5afab8b5f9b7ca93a831384ee05dc6afb31fd2ce082133615dc36f39c9d9cbbb42e8e3f3e763d2d1f089c9b94f7ab183da49f68eb8a1648833136e4da99b873b4ffc2327f3a71d00071da308977da2e9cd2b96b7beb424a4c3127b7aaea40c8973fd9cfc3998d967c7c3ae522ee8fc7984955e54fa4c6a76e133ad7ad302b515303cb66282849cd139160ee7414cd878dd24e7bb858520dc50ae28295a32115147c8dc19c0d3e7e04e80a698bb02fb9a527fa79129daab12c97ae65b37851827246d3a0abf3d047a1e03624f6d3f6184650e4e225a8bb6a1120b40ad658fa729e17b8af540a4f5774bc56e9f932bab885d5272c78ccaba460cad5275b0cc97d098cfc1831b8d1cf3123819263cf597f95888194e54633cf6c23331f80a339f1a61af05017b210de405d5e3a5fdbba53d082765ad9c8bb82ef7dfb0ff417987de06c937b84cad437c75b5ef3fa9f0c5089cc20331d0026e0eac9176dca2506452e969731b61071c3ba1495fa089c034d643ba43740528e013008e04a32c920ce8041c026628a2267c648682026ca17e4bb2f9b95668bf716afbc49c8f3c56012bb8a6effd7393116de8692ce1b5fff224f856ff8589823734a5ee7403a8d900ce2854c5a8d60c6ce304964c3cc5b734672d1a19d0d887e33c244837221e52467b5e9036a4d3dd2bea9c69e67e57bec76a463bbc3fe5872894b9d69d1c7df3cf6dcbae55685c5d36724abc930b9368ca69cdcd38ff603a57cd224254e3ebdc453bd327b222b3da635523c7468f8eab0f50fff3225462567208e00c532778c98309d7c87d10af2e4866ba31f0a1a1803cbae792aec7290edac31ff22622f82b21c62b3f497371213f85aaf1733a11fdaf2fe5e7dc3cfd822e26cd1875171a034e2f30edc4cbe26ea0025445921c502e05707b34feb9069bbce9bf05898feff72f5f1e77255f1a3208d298b39e1437c0f0589de017553199314ecdeb8edfb2f131e13ef2b606b35db4af3c9abbddb2da4ec1dcb2efc64f38242748157459b647320d6150842e8df5c109a778f108c61c9303ecaac0c3b69c23d5a404ff7ba27b9b5549897f5b5287af46aa58a248dbf65f2b303d44190bd5d711a1b9ec0f9cd22facea4683ccc910379a9885a4c48ea91c76fb72cfe75fad1ab3d8eb23ad96e39c31aa7293040f78fb9834f3051225163d549a67bb079c3275a4c0a5442526eb74d82d36bd353af051c317c5fde944d5504c6967950f58187197acfc159eb9308dd1c9a26c8cd5acc4c568633c443475aec9ec74136afd513299e425e722a3b00c376a39c957306fc1352eb7c62226a5a34520da4f020eff85997bf208b018795113cb24daca8119d2845dcb0bc681aab967468522acb7acd7526a17dfd4fc2cac819bf477a58dc63fe4cbdb007a035d2812e8a677b2e7946a1819acf5ca664c6a4ffa6579a4ec60910091154d7ca9f90e864d1e9863ad9fc70b43cbc508f3e4dcdfb2cf5fc9eb64cc0effa7b6156a57f97c4302bca139cab59941aed5abf56bfedcab81803d909045a2cf6b9e0f25955e57f5264f631b382c561d4daa5fbf009882e1ef915a0910e76645e0669ba57e5d48dafc10bfad40534523dffb4bdddc029d6334aea481590718f01c01022883bbe7b3a75c8628f3c02ae3e8a53a5afc736198d9e1a92c51753043a293cb26428e921db44d36168611aaffb96e38e6ec8db2801b01cc4d3f0022d3677e8462972a4417f434937b70e45b88c6e3faef3c5442043d0d4b6bab6a0e82f5eae911fd5a9eeebeaa8037af63039508f036608a8cc909cbf586d391ef3eeb0448be00c4c03b93909fccfba0ff6098ced8fac8f7eba830d851821030ea765b73b9151454ab112a9a4823b6ed73f917abb88990397ecfa4d1c2c607b898c1e476b1c72a633e2881142158b30c12594033896670fbc0d78f61b46b370a84025e5b220c6c442834b4a9df12f4b29c55506ccccd04815759b2834d9fb2f39f4557634464424ba1082c30c2bf715c4bed8d918c3cfd633135bc8bea596154740ef606fffdd2593f20e472492f395d703e1055827ec740df862a70605baadd4d184f6637634da6486793c6f240d0ed081637c556a0545297dff3f8a4bc83498023bfe9599fa8f94f1b6dbcc3e0446b5863fd4eabd6bca97df8fb37ed6f65c0fa9356316944b81724f27755a4b05583d59bd9dad2930a1dcd205c81c9611507298b90b42e08b13ed2fdc0fb7c4d397db7413df47df41fca319d0a2ff8966f0206a3bdfa67ad9dc044e00b301699aa8ed0d14f61648ff08635269e0889418ebe7d04fdd4a1e711915770f8d5c5fed19ce15f2e404c51cc354686efc3fe7bf5fa0f03f3a3883142cda47d0c0f37167fe58d0ac94f14d75e2585d3b9823ebc963da575db5f65733b6d35a6938d3b78a11204e8a54d4795d05c739e46fca5c8239d56e29f36d78a1ebba04f918263570cec4dcff2cef06c2da0db3c65acda270420c976d0949843b7cf6bdf0c68354b30a9f6aa588c111b3a64b6d1f57690e3d46621af3139c26dccf16a09f2688c41189243352bfe8e8871e0c0d1a2cf971a8df844627092d80c16e0267c1aa7bc50f97027737c45c9b334f5b02696ac0e822c970dbdc369c2e7343fdc710f89e99ef05c6b82fc84a20f93c96ee951a47379b8e29110138ed75207b41cbfadfbfe586a0211515ffc5d3008a8b8ed6beaecf693f74f435eabf7265af63ec10707a0b2d8cfb733e382e8ef0beabee9596c775db147ffb5d330b3b741bedc412dfe606168ade1b85d34e15a4b2da153215af27d95f83d65dce00171e9c8da8d92fb810a1aa34ca65a91292c1a4892dcc81a8b1966fe2e8f1cd1ab665b646a69bed401ddfc4d3d6f578be09beeb91d81edd4d0ccaf0edfbc573d70ad478cdf4f5c65c818ed6fb224738cb64f7b80d0f66e8c6fefb6f49c9ab59f0b05c900a1f1a55d51bf49fec5a6a67d162658c4e4f6d2cbade0f96da86afb15bbd8a91e4090ed378a4c31f65e03b53c5a816eb483ec7b6fe36457586228326e551a4ce6bc904c29a499a2cee9e447d318f36fc52e58fbc4cdcc3fddb37101f554b0a4bfb93f047298cd073c583fa0570d0daa821d33a72b8e8afcbea0a12a5cd91517e49f594f0531a07573cb06f08cb895c5c82b6dc8ff951decdfe306b5012c990448bedd4df17502cc002f00231040199c6fe61ff532e7ea01be14300e2bc7ae7c0d236c3f0c09e978f354bada35e719f2ebda965aee8d27148c2efea242ddd7cd41e8c302a2e597d9b3d1b33ec84f07bbcde86ccea2b01591edf17feab8ea9b95744d5a6b186ee2ba42ca92ee95d0164187cabc59c397d202aadd2e2803ec978f8ea376d8ab046d950ef3a4efc2defb35ff0402ec343cf1e3e70ecaad69f75d1c4e03ef951e8b9d3bf785d178ff19ff1432cc14b33808b86c1c39ac9c19c62fad10f41e9ec8ff95f556e4bf127e40627cb7fecde215197b1243fdca58c3ae8542cd874fb542e9f746ca7490edaccdd91bf8f4bff7bf6a7bc40fd28a67364db47f164ba8784e825baaac670ffed2ad9c5d56ae6f9a1cac9c43d28ca3b9fe28bb7465a4767ffa432092ca77985bafdd0a2f5bce2b6472a10a2b0f3cdcb60b14233256547d826b53b010682af15d0e29ce6b5dc0242533fd8f2831fec31d9dcb1f6e67e3eed94ad225c29dc040c00bd0170450062348f259d22c13bd80a59dffa8900e33af85c1012652478e18f0e64815204fd417c4bd0071d79b5e9baf904e20f436e8dfa9dc4af7b2f0f06dd6901fedfb275664190bde61df2c7b7849f0ef697646296fe42a684416bfe2be846ff4449b5cf8ad658f1804d90195c10324cfb071c764ff61355c64e759d1a4e9d631a6d78a760a139737763203600145505bf1a7f04ba4106014fb9104b57a8b44dadfa4a7bc1ded25dc9c252594da3a5f52fd364f29a088e9f451502be292785c15de7a651e3ae2a050e0539c5981c2d3406d5a0331ed451d7988b643bc658d258b4f47506bd02d6fd2e0775bcfa91b368bf51207ebd2d63180cb0f02d5b9f6be1b02aa1a962e41c8f26e2ce9dc15b131b9dd4e547fce08e99b2eb1e56d14e19f697bcec0710c7c60e28b5d9af87d9be14614f7b6c733c2aff9c7fba1f36503ad092daf2607896b06ab01fb6d1a4e4961b9374353ef340b4a65a2feac0792efccb67f2749cd73a60beb76cd304b2cd3e80832835d0cb1debaef54f8a3965a47f0993646ecdeb48cf792ae30a0896e1a1eddaf4f09332c1f352ce4347a8faff316f16850cb0367539f39a022bb34a029b12ef8b6712abb4565570a1d172c2bbd4b242f818b5af1dd46eaf106009a512b53c6b945b6acba91f1d8fbeaf224dbc904172c3e3bdc4fa648e1a240dcf2a1213529d6be1cad52bba9f74f5515ab08d1158cc3d2e6e6c9ca9a089a223335632c79a62c4977c417c5a48d1f63d6a0245856666571d55f03cbed3d07d6be645b595092b8d7acf7cbfd00889a5427fd546d19f44f4e1d6348670d91fa02e4ccd885f5cd87308c190bceba0642d7fbc975ff0ff58cf78a26133488bc538ff6cad84ebbfdb39997a79a0d99eba01310f9020803132216dd8c4fef0e8307cf10e309d5399dc2bee5d2845cdfd30320b212a214f8d3a33d14f42ef143cd33aec5a41d32d589b0ba5b6d8fc512ca40611e5dafc23ee47d111b6008ca94697177a14e3f0e66ab41f2f94c2e37a3e41717c7ebca9318d26a30d136bfe5da7ff73a7fa637f88d0787968986875d7c5d0d4da839ea1990c1cac315a187c3d3843ea9504a4d4f6a6b5da7cfc3b61b3ee9984bbb9789728e94c3663e2bf5331bd7f703d6f40f424e18d8adc839d2b121f7b4b4d40f0e47ac4b808b1e7e45c0204c2fdb2da3be8b59dad1224aab78ad447d52823c386f976d716dc6c6ca3f3e7e41746afe8e9b01946446b6e2eec7ba94db910febfe1e7fa52ffd6390e7f9c5eb173a4ba590f593df45651dde0ad68e535d8a23c46e3f6a7e855c0fc5d2190b57c9ddd7843eb093e5ff98f052b3b81808d803e9a88d9e5fa48847a3c3d18894ce49637bdf211866f2c71116384c40c82236cf84f82f213bcd5f4df22fb0f5087ebb7d344d33bf3087939388b8ab9ce39e4b6766ee84ae7c812e030bc16bbe58aa5fa7837f36626ef47b1b13872194d585381f3b17b488e3a0fdee45f5f113ada681f9913fa2bca3d70a0e7cedbe8c5dca828f116e9d4d2e7fe9cb25fe2fcda8322869afe254eb254b869d4819688782076bffc273eb9ca69a8b357a0be9682b06f959530a848989722c8a9f2c79d8f07ed80a76a3ca557280b830432de6571ff342b6b3a7f644aa7ab96733de40e5989774fe2e0bbf9370e58d4c6abedd5284b6c9a8f140459f3b5289678947c69769fdb20295a80cf26fce7e8c5b245cf139365aa1b8068f50c54fa1359710bde46fd74efd941ff4ef66345f117b0bed8346dc09dc17a6a64093a686736d4c4ba9547503826011b8fbe3a2cfc7ac3b51bd6a575eebd016edc987e49d435d4c2db9750dde190cfe44e96daa99a58c0c6c3cf24debafaed0610c5e6b5ff575c1c5f711ed8e3e3ba9b260b2febabccdc9f54e6d0f81c8b93fa036aa6cd9eb796ffd49c1a9ca5563bf99f01e90dd8cb3e365fe57131e7bfa15e52fe3f60c1cce049690de1ac72f45d1849ebd53420cb136b071e4ef647eb4b9ab528ad0f9f7c776f3fe42c570bc533e9f79cc793bf4149a78ddf0f8644bab7724b3ff55b884c4aba7aa6bd601269109fabf9d582e48691530d09f34de8658d8dd12b09755cd0a53886fa6d919cf81f77f52b5b0b9fbaf5d03d6a4266cd695984935e852b7a70cf2565496b84d3372e539a8b068109d44ad090b33d057ca3643380d1cfcbf5b34925e368b91dcf0f5fd92e84e7daf14bb907e6e4909c4959e885e9ba5e769cc476ccd9bddff07446251f9ac93afbf664449d60c7c9b56d041fbe584245c4ec8c7cefaa11f7984049bdccfac10afc31799d781b91f7080d37d443819291db27ad7cb70241a7da327ce5e22d76184a4e08bea89246c5b723374c084da38764edf91346aed329eda99668a889349467f752567ee00a5542efbbe2e158744e4e49abefb078a15efdfa1897f43085da7e1295e17ea626789af9b83d13c23faae98c6607da3e521fcf7c36aefe7d9b947b8cd6fc5842c8de3ed200fae36555fc510d0af47ac08a5c06720884a4c8ab90139562dbe6359c1926b4d5c93403b5021b615245b7e68e47145c9172e3ac342bd54a17fcdac155cfd933b51d48e5f46bfa8b11bf8165586ed2ef43740e119efb1e31ff35e828469456b8ee8a9171d8f550785312c3441588a9450b2832e08d803c13466e342a435a862a150c6dc29e0104f012bed29717adcd3c4992256bababd43c4e3991f7c5725dd1b2a486d2ccdcd6ad948f6f53da4ebcd66ce794f2abd5d363b40cf21607475c28680caff3be00ce94d4d9a2a1fb430cccf8154ea335feee4b89fa6839ea9125e97f068899de6f916004e229ae7f9b32b009af9398a83ea0912a27b379202750ce4f5209afb9da6331e6172a4c286fe0cba6e881758423c02a4bc99c363cab1ab9719fcbe7e37aef692c5ba828ae67a208bf5d5095c06be00e7b786da7d31f4ec72e8c69708c03a55c54a84e4b9bf706418629a62ea41a6c4ab7c858459ee01e940c9c99301d45a3c16b5c980fd751d65361bf64f20f9fa5cc207e998e46236a65d393b22d15ed8e388eb086104cecbc64b3aa15e025f0fdfafc889a3ab919923e28afc60ea724e405881d8096fbc26ec3d9eacc6e8e5b59b7bd10806e2b5a45af5059153df9718d2e85322809dbed51e92a096b82f27e8ff418400c314a9bed5e449de8c1b9493c4cadb7d7574c3a1a94bfa5c47750bad7c9d7dc47be8d683b892de0d9882d6a414f36bfec308742689333c6d07f88c8494a9fd52d0f5094c6ebb230b8ebc4cc9797e1d64a21a6db37130018abf696f28f30713fb7c3a55be8bd80cee89e9ed5295e804d2e48b10729b759d3cecee1d6d11b987b7d5678b6bdf5cb6113adcb7eec8af5362e45a1af5664bd85cc90d627e62f1f44ec932b74766c1edbadadc5de3fdf59c05bfbac44307ef94bae54846519b4987fb4c5725d593a5d84e635a912b5203b130482d897b8001a12a1fa4323c31bc30f83ce9caa3e5b6802130c69d633fe389c8c6e2d9b110b5869b54a9c9df7327d9f3b8fb46bd0f4c9bf299e5ee4b181ece08d6e978836aea653cbc22ced393d749e956ae2775e877dd87e9848c681e4af9c29f0ebc6152822318c8b32bdd3dd2388a0196fca2c6a176c37c645686ddd5e359db948bf1fe122958c68eca414f5a3c2d5ab4f896ce4db22d09cf540f6ce296726f5ec1e63203f79238fe75a7468ee51ffff67c4d103129a9d9c97e8dd8b8d0b52b6afdefbf1bde912f3cf42b7bae14dbb98d2208293bb0061192c12d525e1e84f0a83df6778c3f48d3c3bc0ceb68a374dc2c80028267c73fbddb09ff085ce5ec58a596f4058a3579ccc5af4e2717e1e6381d7cbc8accb65d85e1f787401086e11628b16e58f9141362dabbc566866d906d813632928ea551b39217239510ed37eb745e378f69fb0796b442ba11e8fe7ac3c0c72dfd737961a61ba36ba6c94e1873e00b8c3108a00ca6dc1b55ee524f6e0f17fa9ad7899050d1fd01134658749cda00ac9d2ffb147aa745e18dc677c36eeb1ae6b903071c3aaaed860ba4c06f706f7deec7eb6977de1f2d78b1df7efbae4acdec1ec35833f55321d4601995a15271f1b32c60662a428fbb3ae799d827136e0ff3496a6bc8251d55430631cfe500511787776894147330030fb47cd62b3cc73104d4b759ace3fd2cd2a936c3e65ff71aa2012bfaf2d7c47bb33d2885a6cf1b75504d4bd007fc59c947270c49fe53976cce349ef177c7d17d209abfb4b1cb7064cbbdb711e19f5194bd0402ef97e6e3210096b51fefc8985babbfb642d0c76373e1a23a8690662f5767d8c67e3794ed98cdfae16981aa5a008fd3fc8b41dec0642602d37576d01c2b87dce2eb5575143429ceaf6ad2fbdd709012a937280d35fb35e20ef67498ff72fcac92d25de3213944d550963c9696891285b439efe77376f2b9c8b5fac954998475745cbc76b3898f9eb09fe33be0b7619e6ef6379c41c0bc04fb0f15c988426fd51853be56025c50452791a6e3341fc5a558223d3e2aba49f5e3ceeedeffded3ed55e615118dba1fe14c4fa120a5f6ffb1dfe0794802a11b041b4d83fd90726e285cb771101e91b9dd180d42f30293e0df4f8952f1c5cda633136f1e30c803653dd90683f5dc722be491434fdd504dff1c917432e6e04065c1044b6b38d1d61b57f4eded135d7de22cce4eee11cd1e20e7f27536a75c291269e3c0a229a428a701de5d562f79c98bd87622beb7904f17119ec6ca8918ce4fca462efd6541cf982dd3a411f920068679b346efb363af976421b78dad8e2104a0e6b0cdb7e79daf967b66e68676044c36ee2e350f6f39f5120509e004ae7cd96542fef78aaafb64ddae778f8117a19459f6e638a969c3e166d8ce1bbab439a834621dc41f1f0c4e9fef18cb6d2bef30852a499277ff3fea4c5f79bfd894354d567c17b38e2e1db4874cc61e28ec951a92567d3eda5a7e299fb84edb235b9785e066f2ae4d483794dff059f9eab82433676d8db696ca98a849d61271c2eeebe6bea3410723ab20c550b62e6d7405523763832d5015bac29e950cb0b96809b41729537b627496f10cdeea00fadfab49d15e4843cd6512e2abbcca9e2abb631306080cf3121efe2ba87fb9972bc28965e59cfd9d34e3b9b275b43e793524daa5774360881a31f029181ea4a1d6788a2c1452898c89789b46ec6a8beab6d9aac3193c75a1b6f25bf5a6dfbc80e650840aec9521c6e739094e0e4398cf377897bc14d865bb0ffec2e7d67cb0c504a38c5cb98d2c39a8303b5b13eb7290c8bdf7d78d59bc1e4a2918eee0a5f4c28c1b567aa8d9f2fc7257f94148266465971e0946e55cf8f78b9c49fe2ff6dbb837d93ff6457d41f1af321c8b513173a91c6624eada68e8b91035e47133f91eed223fd86564acb10f1718adf5bbc81cce6cb2d7acd4f3c1b2f334b7bdda2a289dfe1008f6e702dbcf3fdb46d39d3d71e3f10bd2be6d15bf30f15da1f49e98191ed705e321c2e428e8cdfbe2f6ea9a714c2544c7b19f61e8e54af468318a3653a2b5d4e770"; + Channel channel1 = new Channel(BigInteger.ONE, Hex.decode(data1), BigInteger.ZERO); + List batches1 = Batches.decodeBatches(chainConfig, channel1); + assertEquals(1, batches1.size()); + + String data2 = + "011bd930e08e94a89daf73710d130fc0395bf483f4c425f8015af602fca4577fc2030dffb613f4918d6da05177e1974407cae1c72703d6dc9c9fcce76c4682f9d78f6d05e2956d015c398beeb94b6984fcd35a4e220feb83e74afbf50c56ff81e0be1a6a298b149b234c60b6116cc9803f93e27b50cc92186ccbab0249cdecbd3b3c9d5c963308728e757697480ef774f87dffca16d1057505f90a75160a5004899a75a028911b9d4400f2a54bfc23c4eb0b7919c2d027fdd254e9950d960f992084ffb562fe89053a1b98c6d3837842d7ffe627414080b245b1ca455e0b71af15d0e6e3e583cc19905bb0d040cf52951050b60cb652deb1b6aad82a6bba64df55f2c7a8764bb8e8fc95591825e33623e45f258313d2da1480258e73dc7342776dfbb3e0c5c009357fe68b78421de1fa5dc6c3965748c3a20dbf7770c2f87b9cf12b75119e4098d0e37093ef552f791b21b39839b1f7a2cc3796abf566cfeb2202725a538720ed6a700e02899ebc7565384bef2f9936960531d470a691a8ecae8010932e4d33958d126f5f4be7fce1222c127a4ec3f0dd9c84377fdd13bc5dd15215fb3c66a80b7678d580badf6216e910858432138c2b867382f37f2025ac603fdf4103928fa1f0c07637071f0ec69c2ab601a17d8b90fa5fc68e2c8195f64155275f0297c255cf876604f49a0a079c8d0f6dfc1c93bd9ad4d8a10853415ec8415fb06097a5b22a7019ae7b003375b2fae13016c8a4211268241973d3f14ffb9e1d4133f6dae5a44dc5b182722de33c8189469fa85e7ca3cc653640b8e8f7e7941b7c7ae6bebbb8c48e6c3f792b95a2deb7c9922e00c9b6fca7b17c3386f7968ab24a7028f4ba259397f5c62d290367ebbb0baae36b1d08bddae3ff0653f6f6697f74346648a02c926ce8a2f24e61cc86f8ce3a0372a85c92eddfb8617be3463805e6cef4ab9435d6f28eeb6d83cc7a987a5a4dfb8180fff9f966a665c2fce8c32ac34deb34cd7e9cda36bb0115ebfd47fba8803cd0b51c6afc8b68cfc27b8f79c1b69786ec6a9f07fa74c80f0befdc482cd7afcce7b626de42b2c9286a5c73a5146aab8213e41bafd70913878d3af5909c28a399423f47af38e261c83ff8f5d6df8d1ae7d9644e93a8b5dd13b85e98b3ade3b410db22464ca077a5bcd0f0bf6f567c88de267a6b1c88579ccfac82cde69090d07c42a9bae5c6328d47a7c0469ca2bbd15e4b9f9b72dd4c73bd26e392f80ebb93b2853e550b31d92cfcfe0637d4ee0bdefcc6d0036c712b9469b36076550d506c81ab7d2626cfdbe18e3d203da6161e2b6b02fb400a0c05953f9b34705db690c97589d8eae0a7a490817880dd28f9898fe11c7da4d7c0e3339d24b97c44cddbd46140133d2f50321077b5e8a8bc9d9b91cb599424dc9b5152de981c4e157cc4db983e7881d163a09b61734688a8e7a28825c5b2c1b7bd96d2661bed3bf160a0e312ea05cb3e64f62199f3e644b9648d7ac550cbbc5e998a6d12c036d6bf089f850c4f2b5b672f53c68e38ae0f421e0806231952823d4c8d552805f7bce708fd90c075760019c77ef651b97a042734583b3073e155ab17a11ecf1c95afc2688cc542ca7db2bd16e4da2271661b231fe9a77417000ff00ac00e0528822a526b44705591d840e48f6b50301cd5a761b8f08369484e34ac3606f168cfdb93dd1991abcffade2982c19d859e12118cce2efcdeb1b6b7c9a34a13dc3141341e660294b6af701138268628922adf85fa295debe4d26ffc54d3b826c66cd37fffebd73634f744ee59a0b45bcaa9ca27340909f2b7b7ed4bc8c6ef8c236ce65eeb5436e02c5ccf302131b5e79b44cf36c403bb6bc415cf406aea07642af51780bb9f47c0e8e693b4b1e0f71a65ea727577c3dee8cba6fccc7dfd4d60aa8f82ad8a00aac965def7f1698d60cf40307813febc061ef2c374face81cbcf3c46736ac69edb4c753090b58c99233e5ff7104cbbc0e945ad0e1d6feff9c1b779651cc1cd8b3ec4459eaa35a56020d49f61bad40599f50a990eda0fbb05e1f6a010819874aaed31b740f76188deec69064458d89769403271a73a1e20a4603783cb4831c894eaeb34f537040448fc77a83c80c28a1d875f57cb634188e7bd17556ac4917f930d6942ed37f1959e5e5a3a8678dcbef34b9d15de7d43c814a9971e12b7a6d4a65772639dcb3b292bfd0fa06525ae7ea06a44b01b839ed4fabe070b26e7b757be523b76039355df458658c8c5ecbf390ba4e63f8c91b0b223f86ce5283bd31e32e115c1328930734b61fcbc38ce2d3613fa37f1562a7ba6144f2ea25abc0c104e33c679998f7a59cbf16bf4024d7d54a1c2d5718d7032c4e331bed600cacc5f7ebf423e284480e65ebae0c99f1d029539c4494cf0ee5f5b8d55016fcd59990c783c117c43d10ae5db7988404196ac6d052c61a3601042786644a3ed3ea505d2ab907c2838d9b7bef2b3aa048ea10b8c281f9bebc72fdc427308649f7d025bcc3c147dc04e9a1ec2bbe90ed037095314b67a2d5b12d6a98d1ba9f08fa84056425548ba83321c06ed7fe71e0e4e5664cef278a10fd01ddce83974d14f932e02a2315352d47694d083dea7162708c104ad4da4d5497d688539761413aeda07c5d5a16147cfc47e05506d6cb1386a068a3ecefa8d49f63ba7d227707a637f29b8b8ecc0e5f6177ca77807be66642d14fb34fd89cb46d25e09d8700ad253661dd709af5a93190801f4f8dbbeb509c597b6839f85c419ed9d8c62446a0ab517687240db50d2654f47aa747990f33b71c4e30c582d66371c3f592f96ad59bfc10e87debbb46fc204e1efdf3040808a952f19a3481ddecb65acaae864508552729f49e2867728641fd8582ac364dffc42079e7a6eafdf4310b0010df479317345a40dc395e8c24e7b04abbcb94bee1cfd70fcecc02c97be762bdee4ea1032980489238761a92dd606c67641ebbc426b828a600f061d61c3f841f86e2363c0f7a29e30d8448a3418e47032fbaa05e6d439099094c4612ff747caac388379ad05eae5ba3dca2a9439f08cfc8fbcbfe14afedf30269954aa20ebf02fe9195fbc3f677efa8ab1db90eb909eb5451175b3a4c5730eac18a06fff7ea7ce31b6e86c283fc694156a04c5c4fa55272402c936c3837bc71e97fffdf2bbac475470ae583b83ce0d3d3d1a769cfcc377453ff97d7d033afaa42c10dd9609f96b26601a29fac44cb35611da59b3e71d1e4afa350d456d9ce4a39d2f7ef05a98f58dde75d06da180a5975beecf541f5d5482386ea439588ba16f466dfd7bb45adbc67d18fe94a241a658a9beb9e889eede618ec72d5efca1d35b678aebf965f8af249487ba5589be7aea3cd78cea15ed77b49e6ef0b250a915288c25d3b3d1ea57d256edef97d251dd76ea7f100ab30a36760df901bf98f9940db9d9497d3fff8e4209d54e9b0f6820703da6634f56c70c0fd57fcb3c51dd6d2c049b7dcc4a5992a47c047d1c6c26cb37ae1f431f36dbc5bab5745f27802940243fac9cea2a0f4496c97d78b0a6e222bd3cba66fe09c05a867ee4563beba1128f11c8ff6c6ae15fe816989d166b8b40ae1b90d2d81aa2c08d4248864418ab15ea82517a25adad6776cd0f3c94c92a0ac7689f47d1cd11da5554f738ac9a4413f8eb2d9dd77887f851997e80a46d2bba63ae13244900a2bb605eac548f953f1f2e742d1f55e2c981eb58da19609ad1def8c672cded3f3c0ecf1a203ac33c614b539e2da2ece015f9bf9eb9ba361d46a2c1d0bed662edbe24da143cd4abb6e85071b31b208a7c3fa3994ba8a4da9d3a932eedd54d5b75c311d83e16d370ac5cf3470a9d1ca54336e6e27b0147c1e83aeef24873b795d958e3b18c51d9f8d43646c2fc1e8dcc96c37c11dd7d5694dfcd5f5136f2e62ae82a34b1038e21d8841beb5dd1813cff4dbaae4e9cffa9956713bf50e0b72576944b2c8b23d03598730868cd905575ef54e32866f67072ee7757151977b65a67e96b7d53ad42678ab59149cf4d0345b9d284a5ce11a27a029bbca4dab3fb7c8bebbe6bd87aeb515fab9f6c15e3c22448995de555d3f599c7a83eda6d733770c6c5462766cf5dea4cf71c8db7d70cd39f2bf0d78900be5742a666f896810a3ab4b52feb7f87bffbf74360caea4f37a3602acb43249f25e2c38a2fc92a7d4b241822d332faa547a2d931a8e22deb124c81dd510af3dd491c2fcb26feb91da2775a75a214a8fb8268ac2fe49afc38ec26bf3a00448783d822b14dbd80efd5e35383b2d51cd627fd799efc6bda8de2451d1608259fa425528f6d4f03353245809b3b0f93e4aebc94df34a6b449d3e42dd80a50a9bf6f2a153b9be7f887af2e704406a16e2029605632c48b93df9ff2272c4c27e4fdf742bd694b5f3a53f1f5db09054bc16cfb1950d435c61be200c4f2163077dd57640cdb93fe74fc8f531b1af600c621569dcd323e28319226ecfc227a6ea0be9ac60207640435b19042b8d5d54aed58db99c0b6a078a3da6145355c784ecddd38e3ec7701a800af00323780c16d2704aaf48e076c90e8689b063140d03c0c1a7e37adfede894cecd0a45cac217aa79b36fbcc1c313d054438e868ad340101514943172f5a0a1d85024159410d86d1222ea33441f11546cb626dea437b09171e84af4f887330a9b20e0b5eac4c12ccea2dfc5e69edf2732d5d0475f0b180dd8fa433825b096eabdb39b9efc6aa594b3d03ed19b1a46630321cad898605c90199d26a25ecd67c4b7585a420d501309b8a73d6a48d984273709a0182c2a26d7d83032648ce50cdec17da83fade8d31094a689aa92cce00003d82d36c8938a76347c0197f6c000036a1db1c614511265a9e2259e109500d0f3673d49a4075fc713603bcb8bb47d0068bfc42cf6a8168e7c8ceec9e36b20abc5a61e07d1ad9dd70c99611982c0ab55eed82a4788524050d6445aaffded97103bd8f05411f8e79b18461f41aa45d5d2caf931c8821083fa3c445163b298eac63e880d42564b82e742020004a648f2507a78bb2b547447eb065733df7cb6a7887ff64fe72d48fcd37d5605e4d9836c50b5a0fe10f7246aefa05922e1178d1a4495a23993879731e22e445ceb321d438d1ad5b7010c43ffe2c81331a2cf9277dc9379122d6e37607bb221b943a12d055a97f8ca52bb39b8530983ebd3859e2732925ff1c386ab66f32ca98427d0bb540c92de77a52415dc7c859a29912336d5766de1e8089b2adf1cfe619dd4c227bf39cad71523e8ae29ad982e0a010f7a10a67495ce5424678f4f767a6cc4e31ddf0b1e05541b14c5d042ce228a1b00de7eeb3cb3375a955c31b9d24ff82aba38f427533e59be744575aad213f49c209dbc1dbf68eb7a93bb7dc3d7a1ef4ca325c6d91cfcf116e4789b5511e8712e5f3ea724ce7c00b25d6d1b126ab584e154e04deb9404db5ed8cfaf02a9859dbd77d49fde91a360b4438b2d756ddf8c4d0f3b9dc05c6c0501c75284c7ed455646d1e55f781788e3afe7d0d6aa24c767b7aaffbe2cfbb8da2d174044110ad7edda8127f9de5b3bfd6a32174d3d1b28da889ce19609dd2e283cc53b7916e6d54dd65dcf399e388437313d72ffd457b7f6a43c1eaad3714b2176c12066b66a598e1a16e56f77f2029346a32cfc493e875bc1c0b069476d67e980dd69da1325dac4cd3f96f537717f5754ce02d5483580da3e34bde5a53f447d9e8ab0be00d7805b83fa4e63903848eabc4743310e26144c47d58f5741889eb5330234c81c81212cfa45c51e5fe385c7b3ff02a5ea810e64ac8d8b5ad5c9c34fea6fd9bb4d0eba013de2a5c2fb6e7050ac9d98f14ae4c0eb10b8097d0bc4bc320691a03af1a9426d8c8717591f24b5c7c69013e0fdbb068899dae3e89e894204490ccc0547ff06f6ea44ed5ba023375e2be93d3bb59f476328c15afe35cd5b380048c40bb24e5eadb73178c812e4dfa07d0811bda67706fee29ae6c3cc3701ec9c6272b03f66fc5c006dd5d609d9c2ec99ec5b366075788948e831d4104db8594d08ac62dc4db18d4c54f93010978f741c6269f117eca0304ed5e09276ab70631919fd8a737563177b2c4a7a65a55fd5cbfa5f25553d5611eb6617e04772a655d84a5bf2fb20e0cdf1f8b218eb8e43c0c048373bc143bf68b6dad2ebb88487db4c0c9401589b3399d42718378e8ea49751e0bb038f59206a7454aa6dbb4dda8e6e35f3cb6c9cc877927e63abd4018c7f69be2a32e2866c85728faba7787c658ffa60bd35c09cf1a9a668f005613986c87c1bcb7837c90bdf04c2df76f62e7374e3db80d576bd3ffefe7b30b583749305c769a34f260b770b73f948ebdd538f0e46cc330c66582b6115039bbd2e5c41a3e501017c5a09fe1549e2a339a9adbbed1a9b6acbaa3fc35d28ebcb8663e255f2f506e07b35ab4db5115c311bb2b98b4ace114c4fbcb766ffc749d6ff04251da3f185fc4c5662015ae0f3427a9685e3c0f092ed02eb75617ab45a1aa9f32916556b3565719c231b251dd262e7c1898468ae80f6966df38cb14786ab12e1ef64733d9143616689d95278318c14de80d57deeb0622520b5cf2f3685a53c91dddf16c5414c0e050f7c4865819baee14bd26306379fa51e4ba228947ae8556236fccc4a767a180ab39471ff7c20fe1be1dd1b6558a2fb31501b31c33d589839cacb8edc36c4f5add6da8497494b6e74aff6374e64df2301238ee14654ab42fbb067b0015e5beaa59204622e3202d7789adbc864d44c2183b046e13ca9ef2b1f14dcd8049d311a4cb7f35f7d69e9b0e4d7039ee6fcac7c03d3a876095c8a55085d21eb34c0d0303a23f37023b0201f782e9421b783c6cec220813612907bd4fa0dbf90e36f6b8c9269903d0d0ed7e988a1e2fb7ab871e05c9f1f6d768e97360e09715b4908d1da645f019a0f21acdf5b5cca700eac4bc52dfb7cc01d4a16df8ab27ff05a15834239f9f9105fe973b39db7edc97b7f3864fcf7c487836e69b290974e726ca596e40d99c9d554681464dfef58fdc3c622e62979cd45022d13a07136c0b05632f1e855e19473bff2f8f9555d9bf5488137644f0e2d5cd41dd8aecfeae464d000f3aa833eb855d466ff956aaaba367ab7d212b8b3f18fc4f821addb49d95a7d0a3aeff4566b364a64b64f344f9894c883b7c83b8e7252015cefead2dd7cbca0706a2a5bc198749c61b16f19d637a21ec6f7a4c242e3dab49ec1a1376cef4b269f59799f2493021d5f67398df15dccb4a9dd27595de0e441c6e0b20dc13fd8ae2f35be31b00806373867fd3177c275c8e922c7cc305caae3b35498247d21fd83224433e152991c0c6d7743c95107bec25b8a1348f3959c44cf27f7fcb2bbc57d940b9ac93301198764133be42d381c8c7646b084eceac4019cbe3c11a75be96619804d169fbf4f2660959d1aca376fb1fbf4fd468f4cab58f4192e6c9a1120fe304d36b015e634e1775aa5c9c4ad10f46e33b615888c24635043d1edd8dd55cfe3712033ad440685f91ec8805f11ca708682b580c6083441559a4d69e77471de1ec0e17df3420ff577f944eeffe8e4c6e99e828e5ad37b85173f0eb3f37edd701ad946fbb87e4a006ba7dd7ce20830bd9a0c7b2538170171effe1b8058a426bafd0a4829f1272e131aa2d93c82cedce79ab7d0ba35bb12d94afa71b412186b8f8194cf8f0f3e99424db6ca449ae6e8dbdebf17f0726e474dba4e41dbb9f0dfac5104536d73222bbe85a3f51c3d7951974375c979633e7cdbab48c4f08dc6264e6e50a89e264cb5dd0093b368cda15cf25e530021bd114a6d97fa70e989e7ad438f2e85a6bc831c07ec7e6ebf6ef5e34fd975e5277b030f414a51bddf2babf5774f0c9f6d6776e8a5abb90623f111c4bcb2efd8ef99b557eebe7f52453e30bb77405a353793d982f05d066d702d328b258ba9f580f5e94529e0d7ef6ef64f875de50534d3367ffc426f8675af8952df313e67dd316eb76f7ab2306f7c33e641c6682a4315e0bb23173f3c2e269985325affed2837a7f5f46b29944eb0028576552a8f8d283754fa421d3de7b79a29893735ef5311c2398d0747f4f189c9c00ad6635be9c4bcd14f9d2e642c8f48cf58b4928728e0d077e7cd04a73f8fb6856147b7b492fdd7ca8044e4d05f409708ffc3ebb5ad47103f0fb8856546103bb3c600d3c0d3834ecae7221082be223cc77f8262e87e4525e1fb4ebe970599a0b70a675e2d5268ef5b4f4ea0812f31d3931a28ba5f1861cf02b051dbe08fb861e3abd3d7202fa5abf07b462931889dff11a20c601ca74141986db6d8ebe172a200a753cce3aa6c89cef6ed2f47ea1cfdbb94d22fab435e8ae512c3e880ca6109e958fd39bae8a5969c5ef64b7cbdfd7adfd5c9a7cdb15c954e8eca770ce1337398fe9e704e0d9b0ee91f7dc949c953d41b489858b71c918b8a494bc679db821cd643b079c105284d949d7e6b4ada3dd67bed1d385b34e80bd964184f301e1ccd635f37b7f7a32e251a91d1d677226f04237b7601e7aeec5e1a8bb8c13aa60017eb50f852e8b8a4de85ca3c1b85065150487259f089431b8c0c4e6388c0d9ba89fe2f8303313801dce1321414d2124ec0c9e3f0778781fdef35397705562dd50e8ee3631c67856215acefee82117e500a7cf44e37504432da083eda8ec260d304d41c984eb315694a2fe28756c09d4a5bccf71ee08347eae69581df332e59571cb0a6e18d1d9370821d5caf6e60540b5855c5cd8b1c8714ffed31182333fa9cfc5d891241586134f5c23bdef30d3e951b6ba50c83e70235961cd44d9c05e592ffc69791bc7128ef3c30fac7f105e217781b28dced31b601f6dcd872f4a3c517cc7f0007454ffdb434bc45dd76864a9343a9abc269841872e289257284210b5e5b0f6306d2132e814800d649046940a3d050583e88ba9089e98349539ad54efc956bfd68bec36cfac9f990a90c62b6104d675bd7e6d31a00e3f8f27be0d5c9d06dde9be3292f384a4d69f6d42aa3782328b94d16bd403da39204b279f135a5bb2970cf4a8edc2b11f13259b108e28623c2e491a33681fe4b5ced5f37e2a3e60b6a01e3d9cf181e5ca5dea4f8f7ff8e5b5e7d4c935adad183826ddcb84019b73dbf2322f3e192f94b309115478bbf650cf75092d482df65954c8b0d062e21bfc55ffbc0a969a941e0138c254f15ff3a1c3d5f21ec56a0a53186ff5bca9c9c14f6e79241bf1f2437670473c49f07e0a08098acf929c9c48cf212a7c1c8e84ff1bcaf838b6cebea14a4832c7dc04c7216716197713a471365100cac2c9f6c857fc38bd6aff5c828cde75df03c5260e0656ae4eba53aef4e905a84d594e4b1aa1b92d4ef18aab194d18a617b427ee587919719e78da82582f3b569f4c5def58aca7a1efd8f61226ed5312250abbcd3b221987d1c94396c7fb6185523db905624fc800b6d5a0116b8ed11a12fcffbd317d2dca2444bfcda9c2d72295cc9125ad076ee4181fa30d051bea09519d0f06cfe816d7b463424d4911369b990425444f28edf7faf32e16de2c9ab2d91a222d56e29dd0abf392050e79fa19d50bf893804bee4a2d733d838e595a12a032c252a30d5aac56abbe5a2db8e891cb92810cc21a08c6f4f3aa474cf4f82b16be4a8f3ce8a698141156861a16a212d4716e42ea7a971436da49958168a92cb2d20be13118fa5b95dc946be8f7a05ae73b4361a3b2b1e2509a2f7c76bfc5d907b2089028597133f314eaeaa109e2a46deb2bfaa1b2a94766a53c8c97b4e7725a37eff4c21c8c9eabe44f85cda63f642b3b003a3d6d0862a8e60fd297d41a6829cc8daa160c2a0fba1559c49c20617fe155753c89854efa2d6ee8138d5f278bc32b25f00b645c3f722edec8eaa54c8efea7b51769567bff4004bca33ac8b49b806f546b746bff3ca8d87e91e025c2af1bee4f05a53e17d5660f432b584c162d75caa828008640f847a44622d8a9451e72abdd5cb73e387d6198cf9abfb9b289f7e3b57e7e91d62106475ccfa413047889888d3d0b39d3cec314f920a509b4322d0dbef9308c9cf034e6e87ae86191a915234107f14e9a662b33fd08e5ff39371c63ee5691df151ffa76000096ea373d46b64d13a40d7c9ecd3b3cf62942e576f977110214464bc7d4d8ae9e0763be79b8c7bc5564b8adc9e12e6859412401bcf418236373c3f2bc60b5647bcebb00e2af0051d0ee14f817d341e87f1074575c43e4c74d7418cc187e300865a7bda5c20202a2b5082575c451eb8ef982cb359c24f03c9f47f25851d3236cec504a87e853b5212f047faa208c4926b134a085583da863f0db6604f5c6951cbe90c79a101d0b01021575fa37904e9aa31a8295a9053fe03a5b7aa8f94b7ae1abf87a9c90547039049e195ae837b64b999d21a281875f1c869a5771030bb492d6e1fed0bf28ad8d43024ee78cd2b345a7431105a80f74b41d88427bd6e5babdc4891436139614f20c56494c7778edce2031632c390a0555d97df72f8a7be84458b2dbde8dc9daff343186bbf48e34fab5961f342a2d5b9a47bf7fd3fc56046c3c6b5ca68c30d722b0604f49024b3948b585b53d23b9c8c104cc199012567998ba044eef0613e9223e0c7e2cd456d0f5e835403dc4fca118d7aaf4846bfdc1af37d6a77bded6059904f90a19874a7567c8d89710927b78e33a2377047088bdff004937ade9a182ac92ddb73eee8ffa2cdf4a2142aa7c9e21125c3fd6dfebb77fe8189fc50c112a461de3b8387178abef9488be2238764aa91c4e9574e1756ca96d3b7e4a5b3be96bb15dac5c418b55a1803e9a0c14a0fabad30c42943cb7647aa95ffa7c1b5adca22e792ab66d09645f46b657a6475b21edd61943f501010051ba93bad414aa6341f37650a305c8a8dca764364ea46f9fd54edbd749865d978db4cee800bb39cfa321c0ad360ea64f0951affc3b2aca8e0d4b83b6506630ea1d89ce416c35548893f86598fa4ae9cd95c2fe1d2dcbdcdccb9254ba36146abea2ef154e1d3eaffee986734444fb8ceb521be82b187394427a47872c99c7cd9980889078b29e36a8e1f063c3c766b9399490eaf2efa29e7fe55d7f73578fafac5f3ad27a8317e18ad7291ec81f85d96ea183092794eea1b0fe878ed94ef7355bcc5f5b35133b2ba4ab5d94924f66fab65af6bb2523cef5b4525a25c2659f37e0ef69c34677b07367f65eb48c0d4ae838450ae5aa5451f160b2f866f678ec08d34f59a4883e15eb626373d3e54ea8961faaf97b1af83fb42f6cf1ada78767a33a7df2df744075eeb1bebf7014c1e334bf49934dd1dbbfec00823b7bb13e7d3b92f32a96becee4c483048657b6c5034605975bea76d9182061a3bb2b4fd7c297f7e1ea9d37ac12c706007e8eef1812f9f8472dc4ca58259ac12e92cf8395a36d51a9bef084455910a9d3620a85a07aaa2a87a32f7553ecbf55db20cd535713bf0c8fa645943381d281968160f0510e2fe4e1c6219d72486035ccb8296d4974e4cf453565a1aaeef840bfac064ab01e8dab6b0e807bd4b53c56566153f6aff4d0c03e57683bc09c919ff8c7fd346f17c004f00a30e0a33b0a4cfca25fe75ddc4157fc86611558556f61041d47c1c19def1e0ad77ba6dcc3bedd3b122b7d0904023125df942807dab9f0fd9890a805e576ac742c8fb23341aeb35a5b73c8acc5a4fb7c5f5a2eba26a5dd53966afa5b382ee0f2e40705d4a5d023459eec912b497ee51e67e441b6ab2787315bac35fcf62afb05920f21af83da7ffcfeb66a1e7809f38715963407cef667010f0a4f254e5d0742a83cff0c7f09ea67899a1dfa5f358d1e55cd8ee095550a788d4c164465bf17fbad861f121bde6ffc307b43c29a4257bd3654b36d2557f1e655ae54f8bd993a13683d6775fe0e3afbeff5afc60ee193a4f285551df59fd9320aaea3c0b632cbf9a39f641b47b785cbbb3a3b0bc7b024c3589e1ff21e6d3989ed9f8160b0b8e23dc6f65b8fdcebb6d32aa94c88dcea233797f522f9a8940565bfc0fa340c188a526c8f5d82e3461b3045c14467132dca77b4ab7565e37a3ee196a320592ad40519007885f4a9ef448117e735a75e217c05493afd512219615a0f83054ca68d1ed3e3ce93c8819fa92e89fa00622eb77d56dfc15d90503ba1ffce64567b568446eeb2877d693ebe3023cb99718ffae7d8c24b837ecfb03148782155432130fb96f427fea023dce2c46b2b7f42c7cff1af0a1a247e81893f21fd0fa3e62cbdc0822a49bb813eb35ebc5b94b4b2b99be50f032886d84e38835b26014346b31d03a9545b81e97f939ff37735977172971590ebea7d4874db3d2420858d678e03db1096c5e2ab7137aaf2d1108604039ee34d0ae59e07ebd21b89682eebc98235ed13cc6bcd99bd3b03db02ef7892877e5a7b4cdfb29a6d94da5b96b58d039c6df095e73bfa6ff1296b99bb05c02b7b7124f3d7448664b6bbd103b9a324efda44e677d1047f66ec380226d0f120935e6dd3c51edaf537a3b976dc5fe0a3169e1e862f56f43426353c9bed8137f41683763bd41ce24232effac65ee966148a8403d98fc43f99acff4e9198e6ce14d5ef9960949aa7d3e2670539eb63bef7dc2bf1452fb78de2316e8edabe6b18ee275fa34311de363eb9dd9c11649a3fa999c9a8f59ddce42fe152a35404cca5bdb0434476ab4151605ef2ee6057f58848af16392c9a5779958a5f412e6924f418a826e801a8c72c8c19e69758b3eb4727e21e6a2a92ada7129d31796d71be1823858a03702a8687552458fa7335ca6ca73fbe94952c224456d18fca5a5aa6aa6a23a88b4d540c316519b3c5dd105ee593376dc62d439361589814c594a306573a7a0f2d7d48b7b321c4716e581e5606006015892ebae9ba72a85f1c5a86e0ae5a42d545f0b9a133cbbb3741181326ac652d98b6ef8bf3e11fca39cf357556e810d26e03ea1b4307cdceaf161eee1a5624cec32e40e42b200c4480507c3b31b337021a3a47482050e5700cfb91471d0c9abedf1640682148c1ffa7577338f00368a3e211df6ad4019eee825fdbabb1c3640ea127378d6950621bf6ba8cf3d70fcd926a7573a6ca380962ad45f4fe4aa930a1e01313c3edce070e6b341a699ade711e7c785ebcd0e9fdc68545cd42c5c52ab9a98122501ff3f0cf64e1e68cd0c1e66e469b922ba3a223b1b6acd7e566dd0b9f72c8a3d9cf42be40cc65359d93f89583e3f30963fc073e370ce45aec14e9d098775656e60b8b2ddacdcf4907b7caaf17a693e39ad9d0cd24e96016ad51b25eaa3a05240bcadf635d5a9fb5b2f04b485814995eb8e7a20f4d36215d75f36559ceeb2c8071fb48b8d695b419e27e79f58c4263ae12b47cf6bdacaac75dc5dc75ac4f7500db1e442fac92e9209b3b61e228b8f918d1057431ff1f175a6e1113d5fecb3beb621696c8135069b1d5222573d3593f76f14718fdb085f88f12e1b3894cb3c07ecb488e0bd7537c8bacbd023fee9e8cd34d2f4d61658011f755f35cf3194c4c5d5055af50e5204138f55773d59b0cd0af268ccd012f43a230f8f2fae0cdc7cc0525ec3064b7775973f24ca3ae677aec8720ebe0b98a0d577720659bbae86d80536f95c757f67a8517a51e5d0e21e9599266b96c4ebf1b2905655ff868e957746199db5c7bb94e67261963412f3b674c0e3f39598149fe8b391f0bce174bce764cb15a06101fa6afc1f4e66d5ac47afedc9144d920f362c213a018fb9ac1d76de67b1aaeb89945c5bb5706df3e153d1120ef7d4f027c013e31bccee896172a456792fd70f265d826e64cc8b5d208c1d17b8228790ea9bd02eba4fcb8711ca0f8a4fb30a1fe8ed85fec1832e04ae4ba343686346a6ebcd0c430974853d5c30f12867d3829fe7acabe17d1a971e1b10c69d59c7a4cd93dd2c6d090d950e39945e74b92dca19c5dceccc4c225dbb2fcee0e1941e7b1f451dd1058fa18d5ececb795280f221da8cfdf9adae8d274e78f9cff13da4e99237db3e0a53b25305db566e83b1bde1b6a3bebe47055f0dd8ccb96714d1165d89189cd91c81cdc57ebf02d2f92d8bb7f46802eda0e328cfc9dc2873a7f5d461eb2f0f1d4613a50241f8e7bc6ebbd80b1608b964a9da01d9e90626ef18168f2bf1a878068ed4c79ddd2df283251f7b723f325098d1c3adab3dafb30339b6b22d68ab249512ad1ed0c1bc305e4c39f340d2cae811b17ff758949ab0d05261235dab49d69bdfc55a5652ee3cc3c59764a4c6a0447114b82a24cb4d5f2ad600e3d7bbf9f664d24572da2c4b7bcfd51c09eb48f2ad14bc997d6d4001cc9c998f5393aeea60284b6fcb9837f9088cc4a5ff5b20d370cc829ea01ef33725aa8518e88421504bc6c2c9fba91c7883029034c72095abc91f99d1807fe87d83dc704539192c16bf77df4c72231b73a626ca5329d0688723e281e8842d6a5b7c3878c284de317749dc96396ce13695de9c608d859a474d7d732a6f6100a15d21f1b12f188848e2e197b7f205870ff1d19f93506d376e99fe176a32c7595fab8da1b2c30a0ed89aa0d3534991fc1fd3caaf17a999b7f82ddfa5142c0dc34d111eaced9aeec231f1c1af58419a110f002194a292ac1d48814a792d0b92267ceb92ea68eaf192017d7162a5d7164e07e4dc11b2e32cb4cb55ca97bc3a41154f38b2b49c4964f4ab7b8a907f23dba1ccb4df0afbfdc0bee53e73fa6fd44a071655baec899272db74527b9210c147e58aa84608abd7628642f18c39095138146af9a995c1163b7905d2c15a4b0afc0e1fe401d6f8c50e5e2fa01164b607af45913776bac24b1323735a963253ed075976c3099bde039adf272deea0c7d0906a1a91234fa57fddf05654a6ea953577ba386617c0da6519dfb70a5c4ff321ef248037a5ec1a126759916ac00e28031dc2f5fdd07905998273fac9924267c70252e544547da08a47ed86d3ee71622432c6a1cc8a4ed017b82806211a18a5bb9dcc6ec7b3a59411f1bf7132aafd92cab28a82e87d298df5d902b90af900bae61ed81285a4e0554d36b046083b2723542fcc24f28320c215d3eed300bf8265b0934c93b24192c3d7dd683584fc04cc8e8b1bd6d20cfe5c0fc0920db984ffc2419175fcac1b0ad604320dc0f7b1a75192588c07edd7ccd20d049e4ede58d8a9c3cbe1e9d3d26aa2c08a2aae00084158a9ef224a8c33ce04aab8d5dddb8ba158fa223dc88abd45c123af67f8b228e3d2701d8e8daecc0892a490732027e9f84f0d08c91aadbcd1e642d3881b9c92c3c3dd7c7b7eceada242ff59477508a3739c73c47aebd08ab193d806928750a51df963f0c904ec4f1fa671d00efd1e0729528396def8094f67bd2a0c8abd4dc97b72146cab1762b7b2348b177cd4d45be2022ef2fc7aa0f61aba17d519d3dca52ad00ea0261022e93eed3c7bdfde36d42b7f0f6861c31cddbab7602fb87b65dd90d0af43c7383be1ca0d5b5cc10c6172677dfb43453476436ec9e8bd5fd0dee5f8f39d09b730254d06e996bae7834958964b8f74c75720369aaf50c8605993c1524263a8939512fa47f88d2278914772c0f341e7786e25885356018847eef30c0702abcb9747e2248a5e62a5166f4f7c251fa22fea149e713c3aa6276a5e70a9a9b2382652641af866a0517b798e3ecf46d4ab28df35915ea43fb71263133869b42b6e8973d4f9884c0283ad2dc6a4faf24b6bcbf399f886188ed082fa9857e4fcd44f60ec552821f3015d3d04131f05983bb558306cfdca959ba35f185f29155cc5ce6dd33c8546af0411cdbaffeccc0a1e2f3dfbe8f11020605151b69d4a895336d87bcc6ff81fb915dd9a223dff2972ad1ddbb68fce0f243cb500252d8258aabc3606e95a781ce8947493ae8d7112d4de4cedbc550ffa0b9892faf0e823ffcd7b9bb1669a5fd01a2cdeef3096b3329c538b98e879f6fc273edd7617803c160f811d8450acc5b165ef9c4d88e1ed1d9112b246b482b297187b2e839f1cbd12ab0e6bb65068fabfb8cdd23737a11ed28d440837ec0d3b6ee85ac10e3adc10de35417b429e42bb421ad4f50ec8f2976aba674840b7e2f68450095b46da0c3088a4fd21a21eb16cabf043f68907962f05cb1dabb47b8ef41fe470e2a7be10209f84daeedaf83041dcdae87e3454fb6bb1f3f95a998dc62196aa77fc985e8ada0d057c92f7d95fbcf4e47e870d5e4be107967c1ee633c4b6c0f3b67a0a84921e43b1f226863f30c8f91600c65e286ae9cf709cdb30f43ea5a2dd5f37c156bd59860f16d780e5383e47df86a13bc581f154232160c3a29678074fe7f560bd0088253fed4a798324e64fedd75701b8ce12b6bead61fdd76eb6b82ff67106d0784e7f9567f3a02c0b00ce01e1b72690cd4550a78bb6f2d5ed6c41250efe7698d58d9ed85b09eb05a3e3e2f52d6f0e372987ed3cbea19cd4660b8cc0d9962e692997dbf298f854e89f1291bf5fdd41fa240ec0b4c47c9798bb887391be1bb9a38afa270537b4c0956d697268ba361a4402669c9fff5929372217ca37a3a5d0eb48c894fd06c31f2d611f275f800fcd6cfd7cef9813d045800b2d9288947147929c71af3b6e1e384567611aa3bccf0925f8926d1e1a1a019d53cedeeedffef3bdb59635a1556abb709677c0e0955e8f81ff7038e9b3800aa51a0c938c81731f796dc65071bfe0989cb95412f243f2019eee38c300d4fcc64262be9f6119d2c40da83752848c735af521629e4cc15c5f8cf317117432e3644367490a49a234d836165fffe01e1f517f6d2dcd43ee1dc21521e6f574beab53ca126360caa5caa623ae0c379ed8a87ac987537e2672bd94c31c1599c8cb0fec29474e4f25f66b4ccb972756ae14f22c8302f96980336ac8dd26ca4f6f1b571787f945cd6858efc8bb50a8facbc904effa9a6bde596916dc73ec2407eec80d56fdb2cf0ff3e1155efecbb8d9e71d0128422f3fe3c07154d38ec2ceb4563b7263ba55a9cbdd8d3a3ded9cb3d438575d53d86601571cadeff27ad996baf57abf2e6a9ca9fa29631654376e0a9b843b9fd327d92eaaf276bf36fc55397193b24cbf2609c2c9ef549c9c68a5b5e0b1f2de714a6ecedb1b632292315f13a420e9803edbc0f54a8202425c4588ab6e5cdee00aa162c90198a5c77d88b821e16270dbee612455a6facd60aaede7b3d40f7670d09ea2b4988a9546242b567f973554f5ce220be7e7ee2e37f39d56fb70a7958d1ecdcf3bf5326dcd7d60e96a76ffa847b74aef0f4d1a37ade852343d4546acf9145824a91b111ef3308ddedd13d56dbf5d84367ce5416be6b5e745b9750ecf210017d524478dca7412961f00b057a1fe257fc7bac0f41df785cea8fd61820e4d16bd7d1657b2526274b226d7662998f81fa71b3b7230939fd5ddcd43ee809fd2a77156bee2837251b0252410bdb8c48100ac7e2bf283246d9bf58ef135ea4ffd8967405c4becbb1cdc6444d25729910a9ea62a0e6835590264c647b358b7d61569030c73f9da13536ee2373397248dfb2d32e86ca2fd25df7ebaa21b40682c1585f8bacbffeec18cc74f5c64f242c4afab4574661e0b940e83c33d13f6d08248085c890d15a0ec4ec54d5e3194b094fe2bec2d02a14e85063e5ada645eaa82e6001"; + Channel channel2 = new Channel(BigInteger.ONE, Hex.decode(data2), BigInteger.ZERO); + List batches2 = Batches.decodeBatches(chainConfig, channel2); + assertEquals(1, batches2.size()); + } + + @Test + @DisplayName("Test Zlib decompress successfully") + void testZlibDecompress() { + final Config.ChainConfig chainConfig = Config.ChainConfig.optimismSepolia(); + String data = + "789c4c79737b1ceef77436b61bdb5663dbb68d468d6d6f6c6b639b9b347693b4311bdbb69eebf3cfeff9be83fb9a337366e63e60b6658817b67950e50cbae70ea531f2771b79c93cac779e4b9d975358837b82bb6aa8c52c526c8e30819946901503fe748aef7e314b62b02daf2a2435b3f7ced0547259ce00d039d6d95d3239dcd3e1d7dd0b5b0418ea12f205ea3414a0041435ef405126373e8e00e4cb94f84748d417f23284a14ff8a5a9d1ab182e1d304108ff6dc5fc1d2bee6c68164f0fe4095dfb939f04010186b245b1ce455e0d71af15d0e1e3e583cce9979fb7d444cf52931450b10ab656d9b6b1aed82c6bba60df51f6c7a8764b38effc99591825eb362de45f258b13d2da1480258173d47d4c7765fbbde0d9d009357ffa93785c03e1ea4dd6c3965748d3b20dbf6760dce46b8cf13375019e4098d0e36083ef453f790b21b39839b1e7bccc3796abf57ad7eb3c02724a4b9720ed72601602899ebc7579284bff0f990e962531d450a6b1a8dc8e8010931e4d33d50f65dede96ceb983055824f49c86a1db59496ffeba4778bba2c52af639cc5017ecf0aa7e0dbf852cd2410a49152618570ce704e77fe294b0827d7cfb0d483e46c2fd5b5d1c7c3818b36ad88684f62d421a7f183bb20496db07d49c7c095c0a573cef9b11d06b2a1c70d6df75f0734c776b52630723cc047921077c4182602b1535f125b8ae7eccd489eafb835871264d914063a998eb8ebf3a77ec085ab1572ec76daa8e1594ab1967094c340644f512eb652e3301c245bf3e26dde0d333f7dc2524b7e5fac85ba994f4bf4c17f50048b6e5df4d149a31bc375555548343a1d7ac98bc6cd66f4819385bdf5c501d5fea80e8d51effd699b2b74efaa2a3314302e590e4421754b60b63d625b6d7189043e5936cffc40dd99b34c2293277a65fa6acb296775c6d1966d6c3d4d36ad9f707fccbcf37372b13e6471f521d6a5aa369f6e3d4f9b11350b1d677b8870ac8035ec9a3c63f8b76cfbf755b146c7969caadf47aa04f857cb3f4ce8dc472fdcc7c6a6be22d249b88a2c6b5504ea1b62e3846bef67a19377558afd308c989329e2ef473f48a231e82fc8d5f6ff3d5a879964de634815adb358eeb8539d33a460bb12562cc047c53ce0b0dfff36acd87e86daabfca8178c9f9c42ad86c010909cd2794aa576e22db787822de8853743bd263e5735dae9769a1df645212df61775c36dfab6629269785dfd7e086da75ce9bdf18ba8f2d618d32651eccaea6098c2d70b5cfc4e4793dd8b607a4c7d4c263658d63ef4b83a0a0f26792faafcae633b92e105b1dfc94153310f7b11ba53ef0319ca30ff51b787ca692a4960ea9799b3a0c69a2e7044afae32e171c55b6723372398b92847b324aca1b93c3a9820f791bd307ce31ba0df5327e9c1222eabb286149b3acf36dada6b4d946fb8edf1beaba847ac1b20f9abf4be5bc3a512edaa05e32d432af55a6629b06b08df62dc06721c3d3cad5d9cb96b1238e190091fb8341484694200f3313554ac15def59423f24509d1d40d6b18f7d44be1ec1090dd60ec45c78d9ea45a8cf334be5ab381263399f72976caf0db9ba409cd9c6c847fa210306e0015e00d8ff09be22b54604570d890d48feb00a05c3517d12860b3f9086e444c3fac3301eed696ba22b2372e5c9c03b4530b8b3d0533282d1d985df3bd6f6267944799c3b2688c6c35c80d2f6052e02c7d408454af5abd02005bc462ef3ca4f35856b6ac236f5e79f416d437377e4ae254abb95bc9a42429390207f7bdb9ea45cfcf618c246ee956e6503cefcd5341312537bbe69f44c43bc78578d84d229505d639f4cb5fe1c70fbfd503cbaf9386d34f8ad4685ba5cc3dda827faa2293f73cf60433cd547d1565500d5f422efebe8a446b0bb3f18b4017f56030ff96e3675ebc0e56711a335396dcf6dae3610c85ac6cc119faf7700a29de7f4a2d6808eb7f77ce7dbb83489e0e6451fe4224fd59e543414eacb305b044366bd40a603f7c26e80b8dd28444026dd6a7bcc4de05d18a2377b9a211116f6459a389984531d8f38a4601783cb7031d08ceaf324f51704041812ff0d2a0fa0b86cc7e1076e792808f1bcf3a24a8d38f46ffa419a50fb457ca9af9f968e2111b7e7fc5c678d77d7103249eaa58fc4ad25bde195dc58e7f246ca4aff4ddcaa12d720502d22d88d415f7a6dcf830593f3cb2b5fb91dbb81c9baf73c432ce47ce6efac2552f36fc64858b9617cb67294ed290fd9f08a60d94498d9c5307e5e1ce7961fe306d7f1d6aabb66148f2ea2dabc0c104ed32679990ffa594bf1abf4024dbd54a1c2d5718d70b2c46331be3600cacc9f7e3f43de2944c42dbcf44013df3b042a73889398e0dd3f371bab025e9bb33219f07822f806a315cbb7f210c50559b2b614b1848d838108e199118db67b9496482f420aa1a064dffaca8faa1238063008512136d78f5fb885e6409c7de61164397d5ff40e3b617600efa6d74fdf244c51d8eab5644558a73e66acca3fac0a59095521e50ecc7018b0ff957b3030519139c3e385de4fb77fadef00a69f225d004463a6a4a86f2ba307bd4d2e8c1382085a9b48ab937ad10a73ec28c65d75f68bab43c30e9f88fd0aa0dad86271d40d957c9c0d1a93ecb74f648ee1f447ff507071d981caedcff94ef0f67dcdc95a28f668fa12978c65bc12b0e1146526cd3bae125eb427321002e8f1b77c6b138a2f6c073e0a8933da3b19c588d4156bcfd1e4c56d4349973c1da9d21580ce6fc4110fd320f5989d70fc64fd58b66683063b1c7aefd2de7153843f7fc20001aad6be648c227578cf17b16aa2134115cac9bda689ebdea190bd2013e90cd33d8b735d78ead9dd3e0f41c03ab4b8cfb3b92b226d18ae24183bed01a4faea2eb57df8cdf1a303b35ce6caad7883ab43c8700228811c86a5be501b180b86d67d81d60216c1ee0f38c286f103f1dd8647c5df8abac3601329d26090c3c9ecabe69953672581d292073ddcef2933ffe3cfab2d50cf57ed51d6a1cc81a7e4bf15fc8d96f3ff8431c9a65205d9847fca4cfbe2fd3ef533508add825c83f4ac2d8aa89b212d9e7560c5007ef9f739758eb2456743f931a62c53232825d6af38211148b519eddf3976bbfceb53d8613da48273c5da1e706ee8eed6b4e3e41fba2dfaceefeb1bd0d12b6d89e8b644c85f330ed348d12b6696b582d0ce9a3de7705fd2a76524fac34921daf9fc1bafa579efc86d07dd260a4866a9e5ee54edc1453588e35a8683b518fa7ac4d6bf5bbbb56dcc87e177291a648ab5daab8bbee8ce2de658dcc2f96f3afd35a6b8ee9f467f4b4279a85b95e9ab27cf72cda95ed07e45ebeb052f09955a03c358323d1bad7f266dd6fe7a2e1dd16ba7fe0ba138a3f8c3ae213fe027339f8a11373ba9efc79f1128a1da298b7e4d04ae8774ec89ea98a1c1fa2fd947aadbf5f960f3f719692b9294f7a0f7fd8d6485c6b523e88366bb58b796aeab04100590e49bb5535de5bec812b90f0fd6645ca4970778faaf00ac55e87b6eb5b33e2af12881c2f7a616fef92e819929b1b608e4ba7e69cdcd410adc2884644884d15a21308cf20b696d3db36b7ee0816c56513846fb1c8a5e8ed08e9286c741d5049ac01f6f99bcc65bc4f7caf47d241d5bd16d0bdd20290220dd39f342a546acc2d950a16bf988324f0e5cc7e2763fd3b4cefa17966b6edfc15178563fd129e6315b9aca4c116507afc8bfb5cc95d5a930124d86f6d5161bf745d1a6e0c11ef505878aeb9d0051e4bb69ad5c4265b5aed4e97419af2edaaa6b8ec0f6d1988623959adfd2e8e4281d7231e75ff3388ac6577117875a3badcc269a0f658c2a2627b6319216776864b61c160be8ee33a2fc6efe4a7291d7974197a1891d700cc1a6dc586f4a0ee4f9af32757512fc8fad3c1bf88502bfacb0a35c62591cc55d833907c56d18b2aaee9c6a1cc5ccef8fcffc6eab22e34e57eaac7c6daeab55e9ccb0d633e9b969a028979bb0343842d48e619317d5ba779e6e70dd778c5a6f3cea6b0d92ad635c980429b3abbc6ac01f798c1a235d3f6efb4fb9d8e8c4ecb94b9de99ea2f1769b61fa7205fe3811c0f748cad60cdd30504187b6f666fdebf077ffba0f4c59f9ee661c4c657580e4b3487c50f129556560850443645646bff84034330a55bc69538229b0334261b13381e365d5c43fbb4df446ab4194027557108df5895c931f87dde4570780e870105b20fe512fe07bf9f0d8a0623d8bf5417f96a7f09276ad745e870544c9276989d467dbd5448d4c11e0e6cec324b92d2fe5378b296dd2327d0db606541aec9949c7cee439fee6ab0b1c9645a8eb4f0a98910af1e2e4f7a7fc0e0bd30979f7355f6fd6d29bce547cf57a4cc15230d37e2a2eea1ae30db10f64790d98bdfa6fb518b527fdeef817a73e38e4211e8758753ac378afcc489ab0fd93e8a981fa720a0b149011d4c4420ae156572bbd6d63670adb82e28d6a8715d570ee39397bed8cb3070650015e0064ff05822d2704aaf48e7b6ca0e8489b263140d0220c1a7e27adfece894cecc0b45cac217abb8b36fbd402313d054838e068a33c0e01d159d200e6454ba1a35024282ba8c1305ec065942128bec46859a84dbd6f2fe1c283f0f509710e2655d165c18b954d8259b981df2dad5d7aaaa58ba00e3e12b0fb96744a7023c96d7d332bffd5583563a56fa8332d96d40c4286a335d5b424d927535ea984dd9c6ba9ae9012a4da17cfa6e29c316d23a6d01a986280a0b06c5b5be7800992375237ff8976afb17b6d4282129a662687d30f408fe0345f24cee9d81670c61fed07804ce9368659518489962649967902d4c283cd1db5c7511dbf9d4e8b9fdfde21e880447ea267b540b4736467764d195b075e2e33f03e0eefacbb64cb0a4c1485daac8021295e204981fd59911abfb6b7dd806fa341d007a35e2c61183d866997e74b6b24fb6208c24f287191c54e4ac36b18ba400d4959ae735d080830a044ee486a60aa285b6758e41b5b36d7539f9ca677f877e64f4783d87c334de695842933bca0b510fe2067e4aa9f40991281672d9aa45592f1e357e741425ee4bc1f849ac77a75f30e82f8471f2570c603257f652ef8c653c4badd6e6197e582528703c0950647587ab23b590803e9530b13253e17d20a4f8123e67ba6238c29d43750f394dcf2aec715d4758c9c255a293153766516ed0198285b9a7f7f3ca19b4b666f9cb1354e2844515c315b12ec17e2de57e12c4aa89ecb0a8ffcfac894dd2ea61b3a12bc2c2896ad8b80451c2114fec1b9f3e4f2445d6addf04a27c53fefeae8a358dd4cf9ea390e4eab35e227493866db7fdddaf63673e796bf43cf835e5e82ab2df2f93ecced28b93ac2e350a272565d8ee91c78aecc3a32da641dcba9ca89c03b1ba8a5be95511f5e053363fbb227653055c366890847f6d2aa179f187a369b3bcf18188aa30185c98fba82acc3a3e6de1fcf51c7bfa7494d94c96e4fef7557fc71bb5e34928e2008a435a81b51e6afb37af2d77e30826e3a5cfa216aaa7b0a58a3b47c27f3d46ba45b1dd17019f37ce238e4d0dac0f54b7fd6d99b5c57b47eed0985ec019986c19a5b2b65786898d7fdeb4f0a8d9ac833f5247a192bc78201a69db61f6483f4a6a9cc162ad374fffda8bb8dfa3c22f016aa41ac86d1f5256fad29faad62fc090678035e00eeff6969d610a1e33231dd1c887810117117563d1546e2fa18fc3fa4406409896752a9a8727f18aabdeb7f9128540c732564046fa914278dbdeafc222df4daef84b70ed78fed7e864272f623852b93470403f0129a776818a4cc62e0d582d2041b392ecf537e4a482ccec3e7611b152db2d3d527119d10840892199a190cfcc98dd4ad5a5364a64edc73727a338fde4a86b1e6759cad7a129084116897a25c797d02c318ead1a4bf8b3b7043fb0cecce3ec6958d6518cd21fdf0c9ca80fd53d1bf4e771b5827af47b26bf9a4d5c11522adeb604710c1762e2db4ac7903f13a0a75feddb45f12de7d80b1c967989f721f41a747d289daad414ce43bf6c9b575ccad1cf1899976551fd72fe97cb5540d98fb2d986fc19dca59e761e96f0bacfd4377476288c32e39f7fdc1a01c2fa58ebd625beb0b3011a98f3628595c55f27456b750c2301eba7a4283c7122441bda8c9699992e9366537a2f5f0078f6d22f37ece89b94e3f10c6b1fdbaf8100cc50cf90245ff1ff4a13136bfe8c2b496c3b306a7d823c4ab094cb7c260dedaff077cc81e78a696bb57b1b36ba76edc86cbd5a97f7773d905ac1b24182edb4d9a79b09bb85befca47deea1c78f2b6611863b2415b08a89ce07479b1867714c40531e82738d5c7ca8ca6e6b62f74aa4debae287fcdb4432faee90fa99773949b81ac169d7654a570c4ae0a266d1b384589beb29d6b3f3de76bbc5094f677c66709b16948c5ab7dad092a9a67cf038273b48bcd95856a51a8eac74c64d995ac951586708c6c54b7f1731f06a6e122fa039a9957ce32459e5aacf3fbbd914c36c5f5795a679589204650137ac3a5f79aa188f43c97c21c9af6647247573c1b15857870a87b6243ac2c5d578a7e1388b13cfd30724d89c423d752bb913766fcc3b350c0d582a3977bfe9b70efb668db0ac5a7f9b280798eb9daf87e4e56dcd641b627adde16d4043a4adb53a5ff113af3067918091c778a0a25daa75d833d808a724fcd3c102391718096bbc45641f34744c2283b046e13caaeca91c9754dbf69d321a4cb3f75f7d6eeeb0e2d5039ee2fca87c05d3a8760d5c8c550c5d26ef34c4d4343a2dfd702db02017782e942eb783c6cec2208e36129fb3d8fc09bb90e36f6b88926d97de0e0cd5e98aa3e2fb7ab873e05c9d1d6e748e95360e0a735b4d00f3b4ccbe05340e5159aeb4b994f01d4b145a5816f9903b043c7e86777fe3342b168463e3f230bfc4f7772b6bdb84f6fe7759feeb990f06ccc573312e8ce0d94d3dc80b2593beb8c02cd9afcab6fb979c45cc42e39a9a144a2750ea6d8968a265e3c8a3db28e76fe9f1ecb2b727fa810c7ed88e025aa9b83ba94d8fd5d8d9b001e7450a736f33b8cde0aad5497874fd67b42d696bf31f81f0535bb683b2b4fa0475cff89cc64c94e95c8e589f213991277f80671cf49422a9efe5d5daa9753080c444b793509938a372ae23bc3f442d8dbf0184f5c7c5297dc3121ec9cee61d3ee2b33e3936442aaede3b0b82db893933ea10397def4471c6c0920dc11fd8ce2f35be5eb07806273867ed1177c255c8c90cc7fc105caad3935498186d3efd932a4423e942891402657743c9510bbec25b8a1340f3959c44c0a7f7e2928be55fd80725923612230034333be40d301c947e56a088e4fad81194b63c19a75be56619804d1697bf40ae60959d1ac23767befbf8ed569f4cb758e805216c9a192f7ff358a5a80d7a8d3799d1a17a772f4bdf1d8761816a2b0710d41b74757633597ffb564bf2eb538b4af4876c4bc448e5304b4352c867883641559a4f6ae77471de1cc3617df1420ff675f946ecfdeb66c6e99e808e58d37a8516be0f31f37ede73eadb46fbb87d48026ba3d787b80c1856cc063c9a940188cc77f306689a2d8da2334a1e8a78c5c78846acb243243bb7dd66adfc2e8566c0be5ebe94650882121710a133ef4743229c53613699aab5763ef7af4cf810939dd362979dbee7b83413144d18f2b59911d74edefa8e16b2a0c7aebae8b4b9973e6606d936302b718d939f942a238b9721774c28e75e376a53329798cc04634c529f65fa9fd66271e358e3c7a369af20cb05fb1f97a7d3be74dff6416351c2c8d3c45e94636bdeeee941c7cb2bd0d9c9ba256cfa5d98f0547d3b24bbf62fe6495dff8793dcad6f8c22d5ec2e8565e0de44b0374d8b541344a2c56eec73603e7a594a7031f7ddb197e9dd7d45453ccd9dfb109fe9a157e66cb7e8779dbb0c5bad9f9ec88c17db70f19831927698cd7866cccdc38b77c1ce254cdabbff0a0dedb93956a26d1de1797af322d547aeec6ba23d2946defb93856cac939ab7a1f8a114c68babb230c4e4e8056b71e5bcaa5668a7c6e7321647ac2fac9241439cb86033f3660ad35f47538238abdb5a89f6e315802a7ae0afc00b8477e9d5e2ee8ba01f87d442baab0c5c11eb0869e861c9a7697b9108415f11116db7ce31783f2292ff73af574b82ccd053853baf1eae347fadafa750489f98e9c18d1c53278830ef895820e9f84bd83f79dde1e3901bdad5ffddab1498cc46f780d106300153a8a0ca3ad3647df73552085061e671d5364ce5717697a9fd0c7cdec06117dda2a3478048b0f2283298467f9fde41a5c3123a3f495ec76f1ebaab58f4b8b6fab22990a9dfd04ce79fc3ae721fd8c003413d635fc969b92b3bc2b88363e7f3e261503979492f7a41b37a8956ce78013428a3033e1da9cb679b8f3c43772327fda09b0d7368c70de279cdebc627eeb4b4f463c2cb5a3e34cce143fd7cb2d98839e7d7638ec2ae3842a98875fe945a1cba262133ad36c3029545d01c26129248acb1a9e6362731cc4868dd74f72bc9b9b0bc00ee58990a0a610127606cf9d013cbc0feef8a94bb82ab1ae29f4769a18633cab10ad66be75938b7280d2a7a3f13a82a1e6d14176547613869866c064c2b5186b4a517f943ab604ea52dea73877041a3fd734ac8e39d9f2cab82545378ce8ec6b84906a157b8b0271f5f95c5cd8d1c8314ffe936182533fe98f85d8e1245586634f5c63fdaf30b3a911b6baff4a42235961cd7859ff6e590ffc49791bc7228ef3fd37acbf105e21b781728dce53eb201f1dadfb4f4a3c517cc7f0007454ff9b032bc41dd76864e9343a9abc269801073014c90b142190da6a486788b610197802c016679041940e3d010603e98ba9081e99feb3d556aab764eb9f6b45761ba7364f4c0548639530026b7a5e3f371950879ec6125ffb2f4f826ef55e18c9794252eb4f3720351a8199452ae8351a01ed1c90a5134f09ad2dd98b86fad476e1d80f89524d088714311e17248d19b4f70ada671a79df95ee315b500fef4ff940f2e52ef52747dffcf2da73eae49b56970d1d93ee64c3c49b73dbf232cf3f18cf55b209115479c1bba8677a8496a4967b2caa64586831f10dfe6abf5f044b4d4b0f011c616af82ff9d0e1ea790f623585298c37faded4e4a047b73c92f57885413bb8439e24783f458404a527294e4ea4a710553e0e47c27f0d657c1c9ba75f50252499a36e826390d30b8c3b0932381b280015e1647be44b7e9c1ef5bf2e41c66f7a6f8162e3fbfdcb97c75d299706f402d4662c27258dd0dc962778c5d58ca60c53f33ae3b7acbc8c388f3c6d41ac171d2b8f66aeb72c3653d0b76cbb0913f6298992855d161d918c43e8e4214b637db042a99edc02b1c76400db6ae0b00dc7480d09febf9e98de161512a25f1654e1ab91ca16c85236fdd7f28c0fd146820df584a8cefb03a7740bab3a31a166a4081bcd4c8292a2c794f6bb7d79e7f3af964dd96c0d9196cbf14ee8d579c902073c7d8c1a05fc49e28beeca2db3dd038e59da92c032c252e3755aac56ebde5a6db8e8e18b92fe0cc21a08c6f4b3aa074cf4f84b16be4a8f3ce8a698141156861a16a212d4316e42ea7a971436da09d5fe68e92cb2d273e15118fa1bd5dc942be8b7a05ae75b2361e3b2d1e2509a4f7c76bf85997bb208a028597133f324eaca8129e2846deb0bfa818a994766a5028c978ce7525a17efd4fc2c8cbeabd477c58da6df64cbdb003a7d1d0862a8e677d2e7d41a6869ccf5aa160c2a0fba6539c49c20617fe1150d3cc9f94efa4d6ee863cd9fc70b43cb25f0f3645cdf72ce5fc9eaa54d0fffa5b51769557b7f4304bca13ac8b69b82aed56af46a7fdfabfe97fc8317093fafb93f14957b5dd49a3d8cac613159b43528a3a2001802e1ef919a8920a71605c8cd760bbdfae0f4f9213e1bfee6ca26def797fab9055a87181c097dd34e20e039e2bff0d93d9f33e53c44910f541e472bd3d6e49b0bc3c8094f638eae871e12995c36167490e8a469b636378850f9bf2fba688cd91b257e577ce89b7e0048bacfec08d9364d9036f06926efe0c8a70895dbe5ef7988b8305a3aa6e656f51c08f3d5c33de6b522c36d551e775edb1a2209e0a5cf18199b1b96e705ab2dd77d060648bc0044813b93a09f4cfba1ff80d0e0b886c8f7ebe8309851fc6020ca767b4b85250444e76a84b206e2884dc75cc1c52a4e12688ecf2379b4a8e901367630a543f4b1da8817823f5510c634935806d042ac11d431f0f56318f5da951cbe90c786101d0b01021575ea97389d0c4735042b530b7ec055b6cc60f3a7ccfc67f1d51821a9e052083c33b4d02f6c97323b2344430fbf380c75afe206166865ed83bdc1bf51daeb07049cce19a5a70b4e07228a50efe868db1085f6ac4b75bb89e3296ca62c29e419ac5298eef03a9d41622658f2148a6a727bee9f1477d089b064373deb13b5ff68628c76e81d690c6aadde69545b36b50e7ffda2f9a504587fd2fc6f9ec25c0be205bbca92582a416a2daced19c9450ea620ce8094b0ca83d445507a1788480ff17ee07dbeb682ae5bbf01ea3ee637c59876a5275ceb377efdd15ebdb336306412e40b64dc7f13adee0c19fd1442720f6f5c63e48e101f64efdb0fc3d04bfbdfbd4756c9ee5b1ff75b63866fb910215521cf0809ae0febcfd5eb5f748c8f62860855e38e315c9c38bc95374a445f111c3be5540ea74abaf03ab6d4b66d3fe5cdedf4d558302b57d0425528a0972603455c63cd691a214a815b2abdd42f7dae0d2d6e418f3c15dbb604b23723db2bd3a3ad9076f394a17a9f008028d3495d6a06d531af7533a0d922cea8d2ab6c3e4664609fd54edbdb49865d978db4c6e800bb31c7a329c0ad3e06a24f09d1a8fc3322ca8e0d4b83365f6638e21d89ce416c3d588893f86994fa42e9cd95c2fe152dc7dcdcc39254ba3a186ab16ce0154e1d3ea7f1e186734844fb84eb521be82b187398427a4b872c95c7cd9980889078bc9636a0e9f06ddde7c752732821d5c59f057dffcadbbe6670b7af9c5f3ad25a8317e1b2d7091ed01f85d96ebe83092794eebeb0fe9baef976d7155bcc1f5b75533b6ba4cb1d94920f66fab65af6db4563ceb5b4525a65c2259f57f15f53468dee20e7ceecdd68d91f28a1631429942bd245c503c9121bd963b1c34cdfe590227a556d8a4d2ccc963aa15abea9e5ef6ae27fd339b7c5b7991a9a89eaf4c97fd505d6b9c7fafec451028dd1fc224d36436fffb403086eefc6faf46e4bcda95af93a93130f10185dda16f71b175c6c6ad8656300858d6f2f3d5d0b9fdf86aab75fb14a1c1b00f839bea348e463efb510cba39568863b483ef7d68eb645a506c2e3966541a44e0b2914821aa96a1c8ebed44db17f576c83b44e5c4dfd323c9a16504e054afb5bfa83418739bc9007eb07742a2181d5306366b425d191df17d45584aabae203fdb21a2841fa34aeae3900ee11d7f25839c50db93f3283fd7b5ca1ed000b467ee26f7753bc608029e00560f81f250b4cfda25fe65cdc8197fc4661155855af61041d87c1c19d6f1e8a57bb66dc43be5ddb92cbbd09040231255f9428fb3ab9f07d9890a805e576ac742c0f72d341ae33da9bb3c8acc5a47b7c9fda2e7aa6a55d9356ea069b382ea0f2e47b45d4c5d043259eece14b297e956e67e401b6cb4787515bac55fcf62afb79927721affddabffcfeb6ea1e78097307155634fbcef6a701f78a8f254ee07d21549ebf463f050db244cd0ffc2f9b460eab6686f1ca2a05bc86270aa2b2df8afd56c20f888deed6bf99bf22614da2ab5d19a9dbb692ab7af3aa542afeda489d0eb499b53e7b039efef3fa5b6387f04152f9ccaa81fad77c0905d751604b85e5ecc14faa8da3cbd2e54d839d8563488a6134cf0f7997b69cc4f6777f304842e90e63ebb55bfe65cb69855436447ee5819bcb66817c44da92b24f606d0a06044529b6cb2ec971ad0398a460a2fb112dca77b8a37df9c3f56cdc2d4751aa54080c19007881f4f90f6278095e0bea65c217a094d36f659261a6b53058c044dac8113dee1c893ce889ea82a81720e672d36bfd150c8684da0efd7b2abbd2bd2c347c9b3de44bf3fe891959ce8c7bd837cb165e1af46b9a8d41d20ba91a0a81d9b7a42ff11b1de126275e5bf9233a7e8e7f55d000f1334cfc31e93f1875679979165429da75f4e9b5e29da2a4e58d9d2c7f184031c456c229dc120908329aed489c4aad553cfd4ff253fe8ed6124eee9222725dbd0f895ebb8724a4b0c9f451601bc292587c35ee7a553e1ac2a060c053bc69a1fcd3405d7a2311cd453d59b0967d8245ad05b37767605be02d4ff2e0771b8fa91b56f3f5527babb2b63180f30f7c95b98ebe1b7cca5ae62e01d0f26e1cc9dc15911199ed4e747fee08c99b0e91c56d34c1ef693b8e8071743cc8a417db74b1fb76838d68ae6df767f8a8f9c7fba1f3657dcd094dcf667bf16b7acb01bb6d6a0e0921d9370313af74730a25c2feec07e2ef4c367f2649cc72a78bea774d314a2dd269f1b3829c0d30dfbaef94f9a297da46f01837466cdf348df692afd0a1086f1a1fddae4f09322d1ed5cd65d57b8faff31771a9512a0266d39ed92122bbd4a128302f78b7b1abba4564568a1c162caabc4a252e21173513ba0dd512f401d4a396260c738bacd9f523e371f73515c9369389ce98bcb6389f8c9142c50138154343aa922c7db99a65b653ef9f2aca9611222be887652d2d9355b511d4c5a6aa4698728cd9126e082f0ac91b3fc6ac429361589894c454a206963b7a0eac7c48b7b2212470ae59ee97fb0120554930dd545d39d44f0e6d2310b896506d017466e4ccf2e64d10c684096b550ba2edfde4bcff8b72c673459d153a88b4d380facad041b3fdb38587bb861589f3000c887c01840109108a6fc6a777878183670809046a1c8e61dff2a883ff7f0107105a0a52f0ffeed11a0a7c17ffa1ea11df6adc019a02c3afeed6d8613287d0939bc53428b30d795dc4f91b846649b7ba3953651c07b1d6227a7fa6549852f08989e176e58b0f69361a6b99dd72eebf7b9e3fd3e9ffc28545cd42c5c52ab9ae8122d018f5f0cf64e1e68cd0c5e66e469b942fa3a223b1b1aad7e366dd0d9f74c8a3d9cb423e47cc65359b95fc9983e3f30163f21b3e370ce85aec14e9d098775a56e60b8b2ddac5cf4907b7c2af1fa69be39ad9d0c524e5601ead59b256aa36294e1694bfcbbab836636de99790b02032357fc7451f9a6c4abae2e6cbb294d75900e3f69e70a527f56390fbf9c5330a8db94ad0eac9f7a2aa1e770573c7b13ed50164bb1f3dbf42a68b6ce18489a3e8e6634c170066fe3726b4d42226fa9ffd77d6c5cc2f9227a0d262ab474ae5a6b3beefe00f33fa610bf11f26c26713996581fc96901ce7af26f916587b04bedd3e9aa49b5d98c1ca8a47dc55cd71cd65303181a1aa5ea0ca8182701a2f166ad719c09f4d181bfd5e464461f0e5f5c1ff77fc0043093b0cdaed5ed41c3fd168e89b1df921c83978ae60c3d5ed4bdba62e781be2d45be7f195bd5ce24569449743487996a4592d59d0ef444a43d9173e58f9159d5be536d75eacd1994bc558d2cbcd9a90c34f4c546092ff64cec782f3c592b71d55aa9605c487196832bd7a9b15b19e3d75245136c83e9bf20428c5be64f07599fb9e842b6d6451f1ee96c1b74f468f072878df91883f8b3f32bc4ceb95172a4767927d73f265d822e64cc8b5d60cc1d17f8428790aa9bd04e9a67cbb76eca7f8a07b37a5fe8ad85be81834e44ae4ba303181346e6e3cd7c2b0904c53d3c70f1286bd3f2efe7cccbe13d1ad71e1b10a69d59a7c48d939d4c1d0945d57e79941e74b92daa69c59caccc4c225dbb4faea0a1946e7b1f2515b17587c1fd1eaecb3952c0f22edafcfdf9c5c076bb9f347cefd0e6da7cc91b99ef7d29b1498aa5a35f29d09ef09b59d7172b82cf86ac665cbb8a28832eac8c4e648640eeead75f8521049ecd93b2540176d071a45fe4ae1439dbb2a230f997f7fec30eb2f5208c73de5f59ec798b7454ba54ed0094f48b1b07c4734fd578d4340b47aaab266e56f1c99a8f7cb91f98284461e1ded49fd6d8899cd35116b59c5b42895e8669a8de11cf2fe779a261657ffb58bff9ae484f5ba2213893a6ddaf6947efe8af2129749669e1c3b25263582a38815415126da4af9663087bebddf77f32692cb1651e21bdebe28f1eeb4f72ad10ba9e7d6d4001ca98998b5593aeea60284b6fcd9fdbf9088ccca9ff5720dd70cc8291a016fd3f2daa8518e88421504bc6c2c1f7a9147883029fd4cf209dabc91f99d18fbfe07d8dd4704939152c1ab77bdf447223137ba626ca5b29d8688f23e281e884236a53743078c284d63e7749dc9a356cee369e0741304ec2c52baab2b59337b08c50a99f775c978444247978cdddf102cb87f0f8dfd1a8369c106a7b85d288be0521f577bc37906b45d51f5c186268b43b8ef87355ecfb3738fb09bdf4a08989bc63b42dd39db557c148243a31e312314039e2143294525991a91e254133a97e52d38d7c434f0b502e4e3da42652a0e0dddaf2878c3456698a9962af5ae9934836a7e722589d8f249eb15377543be459763b909fef1977fc67decfccbb497286e52d9962b72ea49cb6dd9496e0403851f962a299862aff39f56318c58391168f4ab99c99530760ad9c552818a7b8a1ceef7d4f12608552eaeef20b104a6079f5509b7c64a126b0b33d33a56e27d3d77a906d399739e932a2fe7cdced0e760209a1a41a37fd5bf1d60a6d4a60675b5376a18c6e7401ad5990f574afc4f93418f3471cf4b38d424b059c1ff5d0122c563b89f3fbbfe7bc3fc1cf941cd0431e1bd2b71a11a3ad27a20f5fd4ef319b710196251637f266d37c813282e1611aab499cb6dc2beab9b15f4be7e37aefa92cdb28282ea722083f905865c867c819cff2f38ec8ba2e5544035bd4400d6292b572224cefd8422c310d215d20eb2c45fe52ac54df30e48064a4f9ef421d6123083c190fa6cafebc8b33930bf03c8d6e7123f48c6241673306c2bd81008f7c21e475c460822b05f365e32087413797b78a322278eae46668e882a0b82a82a38006185a2273c091a30f7b832eaa397d7ae6ec523e808d712aa3517848e7d5fa288a34f490036ba363b50a26ad2beac80df07213c3463a4da56b307590b4e606e320b4ff7d5d10dbb860ec9733de52d94d275ce11cfa16b0fc24a4637600a4a8342d4b7e53703a41371bcc16907c07b24b85c354a5ec73b20a5fd8e3428f23235f7f975909172b4dddade1852ec4d6b43892f88c8fbd3b1ea5dd87a704f547797b2543b80ba409880cbb4ebe46177ef688bd02dbcbd21474cebe6b29dc0febe6d476e9d023dcfc2b03747dcfa4a7610e31393bb774a86a923321b76d7c5faee1af78fc72cf0d539012a68a7cc3557229aca542adc7bba3ab98134d5661ac3924c810a12139dc482a807d23f44f983449a3b96071a8f3b4369b4c206300444bf73e8673811de583c3b16a45277952c33fe73ee28731e7fdfa4fb81615d31b3dc7d09cdcd11c1329da05f43b58c8b5bcc717af23a29d5c6f9a406f5aef3309d9819c34d2157f4d39e274c5260041d6976a5bb470a5bc1df824fc428c4769897d4d2a0bb663c7b9b6231c14f3c15d3c84129f04993bb559306cfc2a959a635f199f28155cc42f6cd33c84c7ae05e02dbaffed4d0a1e2e3ef9e8f31020605151b69d488b5336d8782e6bffebbe11db9a243dff2e72ad19ddb68fce0f203ab500252d8458acb83606ed5c7fecef107293ae897616d2de4ce9b8550ffa0d9f14faf0e82dffc57b93b9669a57d01a2cdee7309abd329c538b98e071fafc2b3ed576178fdc120f861d8050acc1b165e85c4d88e6ed199616b241b486b690987b2e859898b912a90d69b55068fabfbb4dd03737a11ed08547f8341c0e396deb99c10e38de135e32418da0cf205dae83f6653ec8d2a75a9a574840b7ecd6b47882bebfc800e23283e4e6b84ac9b2fff147ca741e689c173c56aef1ae6be03fa1f3aa8ee86ffe7911b5c5b9ffb09ba5ae0fba3054fb6db6fdf55a898dc62196aa77eca87e82fa3d057292c7e96fbcf4c45e872d5e43e137967c1ee613c496e0d3967a0a84b23e43b1f20e860f30c8d92600c66e2862e9ff50acdb10f41ea592fd6f37c166bd79862f1ad7b0e5103157cf86a13bc581f144332e60d3b29a7c5e9fc7faf14a01104a7fcae4f31631ccffcb3e3e03610c357d6d46530b2e5d6db04ffd730da4e1c9ee74be3f11000c3d28f7b64c4a5d95f5729e0edbeb97051134b40bd97a73d6c6db71bc27acc6af5f0b44059c38fcb61f6452fa76f3c1381e1323b6886994b66fef5aa321a3a29c6a762dcfbdd609002b137301d25e735e20ee67498ef72fcac8ac24dfd212558c540862c8e86910299a425ffe7734ecab9f0b5dac954b9b8554c7c82568bb1b7ae90afc33be09741be4ece37ec41c0bc38db0f658988222f955813de367c9cd04a30a186c3342ff9a568121d1e0a9a71cde3ceeedebfded3ed55a61561f5fa1fe18c4f21a18a1dffe2bec171130740350a349904f922e6de90bb6c63c33f2271b932e887e40724c3bd9f12a6e189994e6725dd3ca09305c878b00e06e9bae655ca21859cbaa298fc3e220633e4624364430749a93bd2341855f6eded135e7d622fce4eee11ce1e20e5f1825b52af1408b5b06150e55395d201efceab973c64c5ac3b11df5bc9a68b094ee364850de627652297fe30a365ce966b500b7f10418679b1c4ecb361ad976623b58fad8ec1fba3e4b2ce77e49faf567864e58574fa4f36ed2eb50c6f39f61206f26307ac7cd96681fef58aa87967dfae778f0117219498f7e638a868c2616758cf1bbbb4d829d5e3ecc51e1ff44f9fef182a6caaee3004ab885376ff3d6a4f5f79bd5897374f567e17b58a291bb4034dc61dc8ef951990547f3eda587c299db84cdb21599507e364f1ac4d483556dcf05afa683ba730656f8db695491bab4ad41172c0ecebe4bda34205212923c652b42d6d740550b56001cd51e4bbc29e15f5b13869f0b51629d27a62b59771f5dfea017adf6b48505f4842cca41313aa3dcb9faabae31207f00df2131ffec9ab7db95528c08a66e79efd9934e5beb271b03a793520dca57385a78f1ed1f72e1c1ea4a6527f8a2c12548e8c8d789b46e86a8feeb6deaac71e3c75a6b2f45df5a2dbbc8062578008e89526c2e33e094a09839f2fd07f97b8e4df65bd0ffac2e3d278b0c100228f5cb98e2cd92b33395911e9b013cbbef7d78f99bf1e4aca1bece0a6f6428f1b54b9abda7047b929ff202015b4b4cd8804a2702cfc8d226394fb83f536ee45fa976d514f40ecab1cdb7c54d44c32970991aa2e066a2e581569dc54ae47abd81766190973ecc3195a73fd2e32972387f4353bed7cb0fc3cdd75afae1a42bb3f1884f5b9c0faf3f7b6e134b8277e3c6141caa7bd320a03cf0542f78989fe715d20012444868cd6b22f66a7a611cf584a781cf7198656a148871aab603d255247750efbff020000ffffd0f8110c"; + Channel channel = new Channel(BigInteger.ONE, Hex.decode(data), BigInteger.ZERO); + List batches = Batches.decodeBatches(chainConfig, channel); + assertEquals(1, batches.size()); + } } diff --git a/hildr-node/src/test/java/io/optimism/derive/stages/ChannelsTest.java b/hildr-node/src/test/java/io/optimism/derive/stages/ChannelsTest.java index df745c1c..e28b3f53 100644 --- a/hildr-node/src/test/java/io/optimism/derive/stages/ChannelsTest.java +++ b/hildr-node/src/test/java/io/optimism/derive/stages/ChannelsTest.java @@ -7,12 +7,15 @@ import io.optimism.config.Config; import io.optimism.config.Config.ChainConfig; +import io.optimism.derive.State; import io.optimism.derive.stages.BatcherTransactions.BatcherTransactionMessage; import io.optimism.derive.stages.Channels.Channel; import io.optimism.utilities.derive.stages.Frame; import java.math.BigInteger; import java.util.List; import java.util.Optional; +import java.util.TreeMap; +import java.util.concurrent.atomic.AtomicReference; import org.bouncycastle.util.encoders.Hex; import org.jctools.queues.MessagePassingQueue; import org.jctools.queues.MpscGrowableArrayQueue; @@ -129,11 +132,13 @@ private Tuple2, MessagePassingQueue transactionMessageMessagePassingQueue = new MpscGrowableArrayQueue<>(4096); + AtomicReference state = + new AtomicReference<>(State.create(new TreeMap<>(), null, null, null, config)); Channels channels = - Channels.create(new BatcherTransactions(transactionMessageMessagePassingQueue), config); + Channels.create(new BatcherTransactions(transactionMessageMessagePassingQueue), config, state); return new Tuple2<>(channels, transactionMessageMessagePassingQueue); } } diff --git a/hildr-node/src/test/java/io/optimism/driver/DriverTest.java b/hildr-node/src/test/java/io/optimism/driver/DriverTest.java index 097f2e02..0c3357aa 100644 --- a/hildr-node/src/test/java/io/optimism/driver/DriverTest.java +++ b/hildr-node/src/test/java/io/optimism/driver/DriverTest.java @@ -40,7 +40,7 @@ void testNewDriverFromFinalizedHead() throws IOException, ExecutionException, In false, false); - Config config = Config.create(null, cliConfig, ChainConfig.optimismGoerli()); + Config config = Config.create(null, cliConfig, ChainConfig.optimismSepolia()); Web3j provider = Web3j.build(new HttpService(config.l2RpcUrl())); EthBlock finalizedBlock = provider.ethGetBlockByNumber(FINALIZED, true).send(); Driver driver = Driver.from(config, new CountDownLatch(1)); diff --git a/hildr-node/src/test/java/io/optimism/network/OpStackNetworkTest.java b/hildr-node/src/test/java/io/optimism/network/OpStackNetworkTest.java index 1f6e8819..240061ca 100644 --- a/hildr-node/src/test/java/io/optimism/network/OpStackNetworkTest.java +++ b/hildr-node/src/test/java/io/optimism/network/OpStackNetworkTest.java @@ -20,7 +20,7 @@ class OpStackNetworkTest { @Disabled void start() throws InterruptedException { MpscUnboundedXaddArrayQueue unsafeBlockQueue = new MpscUnboundedXaddArrayQueue<>(1024 * 64); - OpStackNetwork opStackNetwork = new OpStackNetwork(Config.ChainConfig.optimismGoerli(), unsafeBlockQueue); + OpStackNetwork opStackNetwork = new OpStackNetwork(Config.ChainConfig.optimismSepolia(), unsafeBlockQueue); opStackNetwork.start(); sleep(120000); diff --git a/hildr-node/src/test/resources/test.toml b/hildr-node/src/test/resources/test.toml index 21f4fb6e..2be452f7 100644 --- a/hildr-node/src/test/resources/test.toml +++ b/hildr-node/src/test/resources/test.toml @@ -2,4 +2,4 @@ l2RpcUrl = "https://example2.com" [config.chainConfig] -maxChannelSize = 111_111_111 \ No newline at end of file +seqWindowSize = 111_111_111 \ No newline at end of file diff --git a/hildr-utilities/build.gradle b/hildr-utilities/build.gradle index 59d961a6..24cd5cd5 100644 --- a/hildr-utilities/build.gradle +++ b/hildr-utilities/build.gradle @@ -9,6 +9,13 @@ plugins { group = 'io.optimism' version = '0.4.0' +import org.gradle.nativeplatform.platform.internal.Architectures +import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform + +def brotliVersion = "1.16.0" +def operatingSystem = DefaultNativePlatform.getCurrentOperatingSystem() +def currentArchitecture = DefaultNativePlatform.getCurrentArchitecture() + repositories { // Use Maven Central for resolving dependencies. mavenCentral() @@ -103,6 +110,25 @@ dependencies { } errorprone("com.google.errorprone:error_prone_core:2.18.0") + + implementation "com.aayushatharva.brotli4j:brotli4j:$brotliVersion" + runtimeOnly("""com.aayushatharva.brotli4j:native-${ + if (operatingSystem.isWindows()) + if (currentArchitecture.isAmd64()) "windows-x86_64" + else if (currentArchitecture.isArm()) "windows-aarch64" + else + throw new IllegalStateException("Unsupported architecture: ${currentArchitecture.getName()}"); + else if (operatingSystem.isMacOsX()) + if (currentArchitecture.isArm()) "osx-aarch64" + else "osx-x86_64" + else if (operatingSystem.isLinux()) + if (currentArchitecture.isArm()) "linux-aarch64" + else if (currentArchitecture.isAmd64()) "linux-x86_64" + else + throw new IllegalStateException("Unsupported architecture: ${currentArchitecture.getName()}"); + else + throw new IllegalStateException("Unsupported operating system: $operatingSystem"); + }:$brotliVersion""") } test { diff --git a/hildr-utilities/src/main/java/io/optimism/utilities/compression/Compressors.java b/hildr-utilities/src/main/java/io/optimism/utilities/compression/Compressors.java new file mode 100644 index 00000000..eec8cf6e --- /dev/null +++ b/hildr-utilities/src/main/java/io/optimism/utilities/compression/Compressors.java @@ -0,0 +1,119 @@ +package io.optimism.utilities.compression; + +import com.aayushatharva.brotli4j.Brotli4jLoader; +import com.aayushatharva.brotli4j.decoder.Decoder; +import com.aayushatharva.brotli4j.decoder.DecoderJNI; +import com.aayushatharva.brotli4j.decoder.DirectDecompress; +import com.aayushatharva.brotli4j.encoder.Encoder; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.zip.DataFormatException; +import java.util.zip.Inflater; + +/** + * The type Compressors. + * + * @author grapebaba + * @since 0.4.0 + */ +public class Compressors { + + /** + * The constant ZlibCM8. + */ + public static int ZlibCM8 = 8; + + /** + * The constant ZlibCM15. + */ + public static int ZlibCM15 = 15; + + /** + * The constant ChannelVersionBrotli. + */ + public static byte ChannelVersionBrotli = 0x01; + + static { + // Load the native library + Brotli4jLoader.ensureAvailability(); + } + + /** + * Instantiates a new Compressors. + */ + public Compressors() {} + + /** + * Brotli compress byte [ ]. + * + * @param data the data + * @return the byte [ ] + * @throws IOException the io exception + */ + public static byte[] brotliCompress(byte[] data) throws IOException { + return Encoder.compress(data); + } + + /** + * Brotli decompress byte [ ]. + * + * @param data the data + * @return the byte [ ] + * @throws IOException the io exception + */ + public static byte[] brotliDecompress(byte[] data) throws IOException { + DirectDecompress res = Decoder.decompress(data); + if (res.getResultStatus() == DecoderJNI.Status.DONE) { + return res.getDecompressedData(); + } else { + throw new IOException("Decompression failed"); + } + } + + /** + * Zlib decompress byte [ ]. + * + * @param data the data + * @return the byte [ ] + * @throws IOException the io exception + */ + public static byte[] zlibDecompress(byte[] data) throws IOException { + try { + Inflater inflater = new Inflater(); + inflater.setInput(data); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length); + byte[] buffer = new byte[1024]; + while (!inflater.finished()) { + int count = inflater.inflate(buffer); + if (count == 0) { + break; + } + outputStream.write(buffer, 0, count); + } + + return outputStream.toByteArray(); + } catch (DataFormatException e) { + throw new IOException(e); + } + } + + /** + * Zlib compress byte [ ]. + * + * @param data the data + * @return the byte [ ] + */ + public static byte[] zlibCompress(byte[] data) { + java.util.zip.Deflater deflater = new java.util.zip.Deflater(); + deflater.setInput(data); + deflater.finish(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length); + byte[] buffer = new byte[1024]; + while (!deflater.finished()) { + int count = deflater.deflate(buffer); + outputStream.write(buffer, 0, count); + } + deflater.end(); + return outputStream.toByteArray(); + } +} diff --git a/hildr-utilities/src/test/java/io/optimism/utilities/compression/CompressorsTest.java b/hildr-utilities/src/test/java/io/optimism/utilities/compression/CompressorsTest.java new file mode 100644 index 00000000..59dc3864 --- /dev/null +++ b/hildr-utilities/src/test/java/io/optimism/utilities/compression/CompressorsTest.java @@ -0,0 +1,23 @@ +package io.optimism.utilities.compression; + +import java.io.IOException; +import org.apache.commons.lang3.ArrayUtils; +import org.bouncycastle.util.encoders.Hex; +import org.junit.jupiter.api.Test; + +/** + * Created by IntelliJ IDEA. + * Author: kaichen + * Date: 2024/6/11 + * Time: 17:14 + */ +class CompressorsTest { + + @Test + void brotli9Decompress() throws IOException { + String data = + "011bd930006400ced916f9203df809787af4c297bd00ac9ef4ea4f780f146cc019fa4401f380c330ec31369d8388ba0fe55c8679e69c8754ce60796fd398a27db55394cec37de3bfd07b3e4130ba23bead865dcca2c0e30e179e6984d830134da7f8ef15b32786da0ba803e9d87cb787a692cb7206c0aeb1ae9ed2c911de4ebf6e9f3923a1b017c067d8131040052c6ed981ae4a657a1409c8972b098c94aa2f14600ec79a0848d36052335eda678511fbdb8af33b56d2d5d8229e09cc0f5afb939f04030385b547b7cd455b0df3ac15d613141004e6f42bce5b6b636569480babd984daaa6dd9d956fc2f6b3ae7da560dc4aef64838ebfc9159f853de635a34b04a1e3facb52908570affb0fb88f1d2fe6bc193b10b46fef407d9b816f2e5abbc97bd80a8b6751b51cfc0b8d9e718cb47ea0212b11889d7fe86e0b361f2267266315b62cf59997f2c6febd58ecf5924704a479f38ed626016069589aa757928cbf00fa51eae3519ec50a6a9b8c2b6b028ab017d33ed775581de96ceb9fd050454ac9c86a19b59695fa1ba072487a2c52aae391c901b5e4455bf56c04216c520b5b41a2bbc3bb66b82eb3f491a04913ec1bd06543f13b1fecd2e6e417cec590d3c6312c71651ad3f2c1d59c2cbed031a2efec46e852bde77cdc85835154ef8eb6f7a4439e63b35a9b18391162202c0017f8808d4464d437209b1ab1f2775a2fa6e3f569255fb5bb0a94ccc55c75fbd5b2e649dd84bb7a33675e70a9ad58cd304567a23d27aa9f532b79920b1a25fef931e48e999bb9e52d25b0a7d54adb42a869fe68b060054fbf2af664acdd8beffd5d5d44341706b36ac3e76ebd714cc3cadaf6e18cecf7560ac6aaf7febacd99bc77dd1d13861c10aa80aa005b5adc29875a9ad356634906292fd9fb82147b3464465b6cef48b94558ef28ecb4de3cc7af87a061dc7fea07ff9f996166562425843ea434d6bf4cd013c7adfb7832ad6fa0e76310079e04b458cf827f1eef9d76eab824d1f6d85955e2faca9b02fd6beb951b8ee1f998f6d4d028594133fe908ac5453e86c0b8ed0ae7c9ec7cd9dd6ebb4c2727e9a4e170638fbc4910d017f13d5db7d366a9f6653ba4c60d4768d13f8e0ccb48e31c06c7e336505bfaae68122febcd80aa2f89a1bae72a35cf03c7288345b01817082a2a906e566f28d07c7928df84537233d367e57e5069956864d6625f11d0e4765f3bd1ad6120a59447d0d1e185d6702f98da03d3c295bf429cb502e0d6d706c81bb63260effcbfe9623203da61609376b1c6f4f16020b9b3f93d47f59369fc97b8ed2ea14a0aa9c81b287d728f34e84ed1a7d60d8c0ef379524b3744027d0d4614c1f3d275cd21f77b1e0acb6999b91cb539424d6935152de981c411b7a20d0983e7086dd6d6c90f1fd8404c5d04d0557967d5d707335a5cd3eda7ffcce58df0de483c03568f92693f3e242b3688771c15ccbb656998a671ec439dab780948586c4a050e7285fc68532660446eb0f85a09ad040bc2cccd46944767c6749025021750e0079e73eae11c57a64174c0407085be145ab0f8921ff2cadbff2488cf57cca6db2a32e7075812cb38d4590e25d0e0a20043c03f040001570456acd37020d544e30d5fd2a2c3c77f5713801d2401aaa0b3dc777e378ccc7cd89ae8ca8954723df1491d0ce426fe94816573721df58fbebe411d571be98107a2f4b611afb67c4487c73137419f5cf42a314e81a95dc8b10ed1481b919e7d49f7f46b50dcddd513bd6e8ed368a1a4a094da22242ed6dbbd20af15b63c81bb997fa950df8f397d3aca8acedf9e6d1330df1925d35522a27604dad3d4af5fa33c0cdd703c9e8e6a3b4d1d0d71a35ba722d4f939ee8f3a6fccc5da30dc9543f657b75610cf3f3bccfc3e31a91eefe50c806d2690d12f0cd62eac68937c02a466772da91cf52632098a38c8d3b3edf601fc230cfe343a70517efe8fd26b8716116c9278035c84b95aa3ba96c2cda9761b10805663d03d3c1bbe1d760826e745230ab7eb523ce7ff06d388a2f579a31292ede799a24a5944b1dbf2450a48bd96db8186c41fb719cfa0b06060a247a85cd03282f3b7007405bee0bc2bc6f7d6853230f029bbe5324d47e925d181aa6a5634bc5edba3ed5d912de36844d52f818a2f2e9c86ef82437d6b9bd5270307d91b4a924300ad6880cf56036945ddbf562c7e1f9f4c9576dc76b60b5ed3dcb90083b9bf93b6b8ddafc9b250a41619888b31c7d6bca4b3ea222543e117e76315c4800dfb5e5fbb8d155bcadfa8e05f5839bb8ae00338ccbb4595ee6bd61d652fc2a9370532f2d48ac3aae11519e6c2cc6df0e4093f923e047d81bf537492b1f03c8c4d70ee1ca1cb2245624cf8fff8d55412fcd5999cc84fc918283d1cae59b79289222ec599bcab862a6a160e488ccc846fb5d1a6bd46751251024d9bfbef2bdaa0491190a41518acd0d10126ba1df97e49a7980584fdf15bd214c58ec237918f43335895117b6fa2cd990d4698e99aa0b0dab032b612b643cc1194e038ebf72f707262a3267f87db0fa19f7ae0c9da04c53140b80689c9414cd2d55ac90d7c985711208716b134575522f66618e03f5b8bbde5e713528fce0912ca000b68d33165fd358c5cfd5a831c971eb58ee08d170f40f352faf03a4dcf14cf09870cfdf92b2857a97be2f71c954ce27010f51596ed2b2e332e15977220339888968d3bf36a1f8dc7ee0bd902ca3bd9345825453b9f60c5351d21e44b1e4ed4c9bae04767d258bbc9f8668c66c4710251bc672361b3538e033f996f68e9b23fff9130e0852b7f5a764f95647f8741eab213e1152a19adc6b9eb8ee0b02f642cc6433cc77adcef491e86677fabc4400eb70927e4f96ee280ce104d250bcb47b88fa8ba7ccd6c117e7f70e9c72b94b8fe20dde0e51e309b0145a38aee6426d702c144eff194e075c84b037e08c102e0426f2181e957c2dea0e4748a44e83478ba074ac9a674b9d9506cb4aeff7f0bda5cc80f9411d1d98575b609f2edb7fda82d8824fa87e2b059a2ce7ff0967954fa50db18bf8909bf627fc7d1260a412bb095c037ad71645d6cd5014cf3a7160833f03fb5c3a4739a3b36103585296e9905512eb575c508965da4cf66e9dbbddfef5296d731cd022bae36e0db83674776b3bf0080ddd147d15f2f70feae895b546f1582211aa19876fa4ee95b0c85a416ee7c89e73ba2be9d33111ffeea214ed7af645c0dab277e4a683f13f3a446ea9e5f644e3de4d3d84fb4a8e9ba318ee6ac43eb05bb7b56dcc8ff977292630c556e3c5cd507cfb06672c6ee1ec37a3e11a6b5cf70f93bf25207eba5655a6eac9d35c4bda67cc5fd18606a14ba2a5b6e070f64cef46db1f49ff6b7f3d958e18b4d3fd85519e51feeed0901ff4834d50cd848f8bc2fffdcf08ac68ed9455bf3632ef7d3ade4475ccd060fda7fc03edcdfa7ca8e5db8cac0d79ca5bc8dbde46b252e3da21dc7eb343ac474bd76502841a4cfec5d6a5ae72efdb12951f3fee645c948f1774faaf30820de82db7dad510836c9458e96b538bd07c97f0cc94445b245a5dbfacf6ff416a829fc8c940e4d15a5128bcea33456d3d9b7b7ef0be7c56510476fb1cba418ee8b68a96d77ed504a6f01f5fb9bcc61b94b7caf43d543d7bf12d2bfd10196230e319db42a556acd2e950a17bf9882a7f0e62c7e2563febb4defa27ae7b6edffe6144563fe909ce11679ada4c114d87c0b77f6b992bab53e1e4daccedab2d769e8be24da1833d9a0b4e1557db41e268b7d33ab924aa1a5da9d3e9723e5d0c5557dcc1eda3310d876a35bf65b1a8d03b1462ce3ee7f1954d2fe3ce0f74b65bd9ccb4efcb58d4cc8eed63a4ad6e3129edb9ad16b03c67c4853c025514a2ae2e422e40891d88cca1e67cb8af2a4e54f92f72757552420fadfc1b4485c2bf6cf07ebac5b23b4bba87f20c4ada316755ddbad4384b58de1d9d06dc5445c59dacd4d9f8db5d55ab335ae0ae6732f1d1c3d22c37e16a7187691c21242f6a746f3f5e13786e9bb45e7bd5d71a25dbc6b8b18ad06457f9d440dff358b446babedff49ff072324a38f295ba323e4613ee34c3f7e50aff712146ea9196af19ba66a68503b5f666fdeb08f4fcbc0b4e59f9ea611a4a6bb38feab748b65ff121536564830a4f6a51c6b4784f3a330a5bfcdfae0447787b84da6a7b02dfc7a64968768bf495418b3405f6b6201af703ad263f0eaf29a00e00d3e124b140f6bd5ed8ffe2fea141cd7616f79de9344fe939ed4ae5ac0e178c9e4fde1265c8b9a38d119522ccc79787437e535e2a641153daa463fe126a0ba834dab5908d9dc973fe2d58173c2c8f5cd79f14342313e6c3231448f31501be1378fb395f6fd1d29bce5a7cf97244cd5e30d37e2229ee1ee30bb307667f099abd04017b2126ed49bf3bfec5690e0e7949c6a1549dccb0dca9b250246cfd207d6ca0bb98c28504658434b153c078d4d5ca6ed9399823b4a0fb6238e0fe6c38f39e9cbd72c5df85026801cf004a104005bce9824c9bde718707161f69d32603885885c3216da7d5dfba504aec9b974b34446f7531649f58a1a4a78049069ced54c761603a4b1aa00298298cd4cac4650535d8a60b042c72c4c517d82d0bb5a977ed25bc8430fe7e61aea1146afaec84b1f249f02bd7483ba5b54b8fb58c9174a187c20e5f924e88afa5f96caf67153f1bab666c0c8df5a625929a2168880ce6dad6e47b94aa2b9508ffe75aaa2b644468f724b3697966ccdbc8a87506a69861a8addbd6d6b9e143144d342d7f60de69ed5c9991a383d22c14f0fb0158913c968b64391d5bc2ae44a3fd008839e3c63007ba18e9d224f9327f904644a8a5b3ee3886f3979369c9b39b5b643dc8b71f58592d30eddcd9995d53a6b6c117cbcc020fc3dbeb6ed9f2c2134520bb152890fa194801eecf8ad2fab5b5e5017e1d0d81db1ff5610fc7ee314ebb385b5a23df9340167b448f8b2a7651195ec3d6076b49cbf39ee9c3c04001250a8732035345d97ac3dfbe7066f33ef62968fb467c65fb70368acdb7d0665b4998b2200c590b130a7145abfa01962b117ed2a14f5a251f3f7a711d241140cbfb4ea27d645037ef244274f85e82683a50f257ee5c703c45a2dbe306615921247538085a6974886b20bf9d853c903eb53051e2772eabf4183c62b96b3ec29242770d3b4fc3a7e87e544157c7c253a2931233e55066d51e8483bea9fdf7fb2396a574f6c62967e384d24fea4b366be2bd4282bb2afc4529f53379b1915fef99f25bc58c4387221705c5f275910828232462df79b61fdd1ee94a6d1b5e186584e6dd9dfd94ab9b695ebcc7a169b52642e409479c7b2f9b5bbe169e7c8ab7587970cb4b88b5457e5f87f99ca55747f89d4ad44eabcb715c83cf543946469b6c6379d4799005668375343733ea23aae067ec9f77658ca66a38ad5110299f5b0de21341a7b3b9f32cc1207c2d581c218c15343d7e0dcffe78ee3aa15d6d3ad24c2e47269fdbe2f79bf5a291746411308351dd88aa509dcd63a0eebd095cd3c1d2777173fd13c01a8df51ba5b74123e3ea8896db98f723f701b7ce064140fa93deeee4bab2ed4b0f08d803310f47b0b455c9f0d2b2acfbd79f04fa399167ee4dfa3c568e0b0f4e3b69dfcf86184cd35a2c54a6e9fffb5e77f3f3e390d857b406a51a5edf9faab5a6e8b79ae90714e00b7806782e6a6ad618b9e32231dd128cb21f19791b5e3d154eeefe100a36862950d8c3e259d52aaa3cef876a6ffb9fa50a95c3dd4958a09b6ac549632f7abf280a7df63a916c230c63bb9f60515d032810cb1451a000c284e66d7a66198b18248d90349146ee8bb3941f52528bf348797826458b5c8cf549a4c7c4612294c61646037f72a3f4abd694d9e812775d5c5e2da33793e16d059c67ab1e85a5e185db6568565e1ea1f0c606f4e96f924e7c707e033bb30f716563192673a8dffdb23210fe54f4af33de04d7291a90ef583fea74f086c9ea3b391047729ec98a2e6b5fc3bc8cc29e7d35ef9746f21c6069f21b16a2d943d6eb9176a1f36890f8f615eff8ca36e64681ecd842b7aa8ff7976cbe46aa16fcdd26fc97d04ed5acb3f0f4d7058efea1db43099461b79cbbfe50488e8f4ac76eb1bded399494c24f17922ca92e7d32ab5f28651c0f573da1c56f0d91a25bd4e6b14ec9f4987218d1b9ff43c839917937e7c25667180cefdc7e557c008565033ec332d14f8362ec7e3186eb2c47640d4e71454a56139b6f86c3bfb6e34402ec41626db97d9138bd72e92668b8589dfa773b975dc0b1418eedb6d5a49d87f09f60f34df5d057939b50d13e1c7b4c3e64131983079aae28d1f0868eb22001f788a8fe5099d1d4dcf68945fbdfb6eb67a076da810feff4bbccf319faf540568b5e3b864a044a5705abae1da2b2545fd9f6558081eb152108bdfd8de5494a621aa87cb9a733414bffe4bd4f7c8679fe7f65a15a1cb6fa21134d7e256b658539023b1bc363fccc8f9975b888699f7ee685a74c99bf16f7ec6e77249353797d9ec1556d228405d284d570e1bb66fc4d769e57690e537732b9a32b9e93965a3214e499d8102bcfd89562d80461294f3f885a5321f7cab5d66d1488197ff72e1476b7e2eee59bff22d6bb25deb642fd61b92c6c9963a931be979315b7b99fedcd60b0093b8185def658197888c5b641154e8ec897a24683f9e1d0e008a0a5d9d5b00cc64e641960e02bb157d2fe1e9930ca0543d084bea376687655d36fde740074fba7e9d9da7dd5a1032927f845731fbcc3e814aa1eb508522eedb6ccd4363626fd7d25bc251c742b922eba4ec8cfc9f50d793c3c65afe7017c3dd7c1c91537d124bf071ebcde0d573714e073f732a4263fdcfc18297d0c0efeb08513fdee80631d7a02a8bcc4747f2ef32b803db2aa34f22f730277e899fce8ce7f422e16cfc817626147fae149c5b91bf7e1ebbaeed73d1716918df362410ed7b9817e921b5436eb609b51a05d937ff925378f8c97cc2d2715442a5ee7648e67ad6ce6c3afdc23efec10f8e1b5bca2f0871665dc811449aaba39a44b852bd0ddb409e0c5087b6237bfcde2abd44a7b71f068bb2b6a6bfd1b5be84144bb8ba1b3f2186ec4fddfb7992cf9a912853c71215273b20eff10be3969a0f2c9dfd5a57a05a5e060cc9417b37099789322c1531c1fe4dd0daff1c4c5474de96d3392cee91e4eddbe320b416956d4da3e6eab9b825b05d9634668e9757fe4fea630f22de98f9f8201ab82fd00486cced02fa682cf84f311f2f94fc4608535972619c870fa1d67864cd8bb0a0d2ac4ec9291bf126687ab8400447f9f9345c6aaf4e79792f26bd57758b7357256620b281ccb331c23986a54a186f8e8c4169cb13416aa5de76f138e431c9db6cba464999015cd31e2b0fbf6eb4893deb05cef102c63950c92be838181c2d6027c465dceea34787954a3ef4cc7b6c27151c44c6b88bbbdba1aab7903afa4fbf5e924e1fcbf6547ce4be5b844c2d922604b3648575146e9eef876d491cc6cf10a4e01f27ff4fdd4efd9dd92cf2d131fa1b9f68534ea0c7cfce363f8d86390f56ff79219d0c672846e0d30bb510e782db91488410985f6c7acd1955b7b4427940354d10a0f31ec59bfcd306c9db63ab6b07814dbc3fa7b7b1017624b499dc0470c3d1e4fca70ce4499e71ad438ba1ffe7362454bb74f4ade72f8da60540c53f4fd52fedb3696ee578c883535668375f7c5a5cc394ba8aed911b1478cfc9c6221699c42b91b1649c7ba69bbcaa98c22767023a6f214d7afd47e8b63af1a677e033b6d456684cfd87c83beedb3a67f728b5a4ed626dee28c23ff7d6e6f559cfcb27d8d5c9b7eae9ec9721d898ca665977ec6fcc92abf0ef07990aff1475cbc80d7afbc1cc89705e871e942e855d86d3c8fec06ce4a694e06defbb632023aafe868a7d8b2bfe211ffb528fcc896ff0affba618f7bbdfdd11143f0e61836063f4ede18af0b6cccdc38b37e18e251cfab3ff7a2dbdd95976926d7dd9354ac322f5479eac6bd25d5966fef393f52c9c939ad7a1b8a114968babd25094d4e80d3b41d5bcaa5638d7a6a7323617dc4fdc12a1a35cb898f343660ab33f47930238eb7b968986e355882a8a90e7e0778467d9e5c2ce87b0084fcc42baaf024a15e08c6dec6dcda0e17b9302415f191565b82e3e7838a29cf777af58c04eccd05f853faf19ae38786ba8675c489f9ce3cd8d1c57284834e4495224e1f24bd83779dbe5e3941bdad9ffdbab1492c64af840d3063003546ea0c93cd3667ff337530b516214f1d6b54ce6717457a9fe8fbf5ec062953da2a1c740457102683358c7ff9edf80a5a3123a7f299ec71feebb2b58f574770b32299168beb18d175fc2ae73efd94183213de35fc9a9b92b3bc2382393e7f36261383989492f7a81f37a893ece0841f46813c33e1de9cf6ff60fb5170e478fea413e0a86b1ce9ba4732fdff92edb52f3d19e5a0d48191273953f2cc20b7600e6ef6c9e9a0ab8c07b6601e69a5179d318b9653f454bbc1ac507d058c88ab9428296f7c8683c7bd1f1b3e5e3fc9fd6669298c3094f78d1c238584a43374ee14e0e5bb7f2b4457c25b897b456db0ddc412e35d856233f3a59b4a9c1b923e1d4dd8110a3b8f0571a0759830c6b1002793acc5d8d28807a2d77126d0950a3cc67922d307b8a7e176ccc99757c62d297b6047675f218755ab395a15486acee712208c468d790b1d0f139f04c8be2fc40e27a9331f7913981a7e865b4c8d70d68180bd9046cac29af1b2fe9db21ea4e3f236ee457cd7bb2fb87f617cc26e82151a5da7d6217e7a3a771f3484e244ce1141581881d7fb3628dbeed168b2698cf4794df0034e5058f2675812309dcd90de1043211af8188027c92c87220b3a068782998a69891f586160a0c056dad764db1f6b450e1b27768fac05a86395f0c26b063e3ffe33630c3d8e25bef45f1c87dc183cb350f187a5d69f6c00b51ac199456a58355a41eddcc0d289c784d696ec4563433a8708bcfb449926e403ea18af73f2c60c863b25dd53adbcaf2a77382d180777278210c572b7fae3c32f0179ed39758a4dabcbc6ce49b7f2e192cdb96d799967ef2c676ad924c8ea02d01d8c5303126b0aeb5d76754a5ccc98f886408ddfcf22a5e6a50700ee700da2e77cb808cdbc7b899ac214966b435f3a2ac883471ef97abcd2a003e2017f125280327282caa30c0f0fea6398ba20b733c9bf863241eeff279fb025e499a31e2263c0e90596ed0439fc0d74809a58b223da85107e8fe65fb710d35783d76089f1bdfee58ba3ae940b2326613a0bf6e39246383eeb63c2e26a1673e6a979bdf11b0e0116fc07feb6108ef38e95070bf71b76bb29b81bce9d8409c79444e9c22eab8e2896212caab0a5b13e04d1546f3ee1d8234a807d3578d88e7ba4869ce85f4f4c6f8b1a39e92f2bda88d528552b3419bbfe2b4596fb681391867a120cd7bd8113c68555bd18900505f24633ab88b4f8118de34e5fded9fc8b755336674394f572bc0b56755eb2f03e7f1f8b56815092e4a2a76acb6cf7807396ae34b88ca4d4749d01b7d5b6b75617317af8bca43f83a4068625fdb4ea1e072bfe825db0d22b0fae2926e51b07730d3b6909c6181f095dbd5b0a27c3847a7fb46c1665e999d8283cd3b57a6eca25dc6b48adeb8d899869d9683188fe83882b6061e68e32122c4e59dccc3689b1b26f8e3261dffa8cb5af66e19559a904ef23e7bd94d62530353f0b6fe82ef35579a3e937e5f21680d1500f860cb6f98de229b5064e1667bdaa059bd68b7159012527442c506c458b507abe93e93f1fdc91f68fa385a1e512a4794ade2f39672f94f5b2e607ffd2da8b74aa7dbfa0005e319ce4dbcd21571a3506b5bfefd441c01e48e822c9c715dfbbb26aaf9b46b397892d020ebbae16cdcf9f006ce188b728ed44884b8b12f07fbb95417d68fafc90a09d50736593c0db73fddc0283530cbe94a1792718f0140902a880bbe773a65c87a8f3c1aae39865bada8273e1d83911696cd1f57043df26974d459ca43ae99b6d2d8d22d5c0379d1ba2b167af5584dc89e0aefb0110d93e8b4334fb341186e0c799bcfd43bf220c3eb7bf6761926298e938da9bd573109c172fcf98978a0c8f554582795d5b9824808f214b546c6e789e0f82ae42f7291420f50c10076f4f427eb0ee81fe81e1a0710d516f57d1e1f0a344a160f4adf6960a6b1898ced548552d9411bb8eb982f355fc24c89ca057f26851d33d42ec604a87f843b589008c50aa08bc7926991ca0854c2ba463e0f3fb30c6953b155221bf1d09162e320c06c6d42f494639ee6a180ed616a2a0cb6cb9c1e60fb9f98fe2cb31120a91a530243638d15f786e650e2628c65e0171d89a3ec50dec70aabafbbb837f7feaaeef13f3b866949e2cb8ec7f53867dc3c2dc822974e458aadb491c4fe134674fa1cae090c1f144d2eb0c9130c355a456d650d8f5fca0be854b44a0bcee599fa8fd471f63b2cde44c6f546bf346afdef25fe7e0d72ffa5f2a80f5476d4d65c47817240b7654a571d542345a38da33928b9ccc213c4129e195fba98b90f42e08a901caddc0db7c6d0563b76103ec5dcc6fea31dd4a6fc4d62f4286a3bd06a76d506012f0191807bcba336cf44314d533a2718d852f527290ab6f2f1cdb202d34fbd6af94955cfef571bfb56604970b915395f24c5011fb70ff5cbefcc5c27e2f668e5437ed1823c08f235c79a541f1ff86efa09acaed52c91851c799dab615a0fa7f2b7d3516cac11bb2500502f4d267a04b6aadb94c23ff54e293492f0d489f6bc38c5b30a04ac5b32f01f66664fb647ab51532fc3f61aede2306a0c875d2955ac076cceb5c0f68b748b2a8f5aa5a8e911a3966b533f47652e2d565a3aeb138216cccf16b0bf3698e419852c2b42aff8c8873e121d063ce97198ff846617193d90e16e2277e98a43ed3f8f2a6707d462bb035f7b02795ae0e82ac968d7c22e822e6b4de3df00f48191e09dc6a83fd45620e52286e18d164f2f878125090138fd6d206b49dbeacfb7d5f6a0691d09eff59300cacbce96b8676fb2b04a4a3ae35f8902cfb1c138203d1d91ce63b58f1418c7785f55ff42db7ba2e3963fed86b9a3bd8a25e6ca397bcb331b5d572dd2c9af2aca59532a8922cf9bd48fe9a3269f484b87666ef44cb7f47078d51a7d0acc816150f244b6d648fc50eb37e55408dec55b72b36b3b258ea846df9a291bfa34df445efcc9ec86e6a68e667a75ffe8b3eb8ce33d6ff07be0a648cfe1745b20556fb870340646b27d6af774b664eddc6df958a6c80d8e4c2beb8dfb4e0fcbf9643363658ccf4e6c2dbbdf0e975a87aeb05b7c4b9014094e33f8a4a35f6560bb33c5a8969bc8dea7767eb6c5f546a24366e5d1642e1b290422da295aac1edec4fd714fb77c53e44e7d8dd3c20c3ab6901fd44b8b4bfa53f1472902300dc5fdf67540b0bae861fb36028898efabaa0a9265ad5151f1c90d5400331a47777cf01f08db897c72a286f28fc911becdfe505b503ac5884c8bedc4e094001e68067803108a0022e300f887e9e73f3045f08998457e056bd8413771c848676be7a295fee58f00df9776d492ff726100bc7947cd2a0efe9e522f5e100310aca1d3818d9ef15a643dc6774ffcfa2711453ec0a7ee8ba199897764dda681afdc777839427df29632c820e54f8b3872f6484d4ba5dd106382f1e9c46ed715789daab1ce7c9df447df66aff0a05da6b7a1126cced57d8d0efb93a9e04dd293f94b840f74431f8ff9afc1031ca12b7dc0fbc681a39a89a19262cab14f6199e28f899fd5a1cb012b14f6672bbfec5f2051577124be3d244d3be954add5740ad52f9d746ea74b0ddacede92bf8e49fcfdf1a07e477f2ca270e2d8cbf964be804cec29b6aeca7f701326ddc5dd66eaf5a5cecdc4332cca37901683b0ce5e4f6bffb4321522ab7d89b2fdd8acf9b2e2b14f2618a2bf77cbc760b5423b2d6347dc26b53f010581a891d2e69ee2b3dc024352be3f76871c1836ddd8befeea7e31e39ca32a5a2506010e019e80702a88091a404ace896499ec1322ebf55c98759d7c21100136923874c0473e48a9047da73d25e8084db75afed67281408bb05fa7b22bfd2bd2c3a7c933de44ffff6811355ce4670d037cb19511af26b9a9359da07b51a1699cdbfa42ff10b23c97f1ec2b6f2072ca29cc0aa9001b227f8f8238a7ff09aae72f3ec18320ceb58d36bc5db4549cb1bdb5981f0806298cd8413c4257208309af3509256a35532fd4ff263feb6ce127eee92325a5dbd1fb941bb973450cc6cfa30b80d794922be9a60bd2a1f13795024e831debc50f171a02ebd9194febc9e3254c731c1aad68acdb733b82df8863f79f0ab9dd7d43587e57aa9a34d59db18c0f53b91da5c47df35114d2d5b97306479278e7cee92d484d27e3bba3f7784fc558fd4ea269af8f7b40377d038162130e9d93e5de2aedd68239a77cbf309e9e7fcc3ddd0d9b2a1f684b677b3a3e41593f580c3161db794a8fcab91994fba25b50a497ff63dd95756bb3f93e416b9d345f53be6d8a556e90c445921ae4638afddb7aa82d14b6d23842c1b23f6afda26bbc99758b024d78d0f1e5727c499560f9a96f29abd4757f98b0474e81541b3694f5c30515d9ab0d438e7025b7855dddfe4568a9c16acaa7c4aa52e808bda09ddc61a098600ba516b33e6b9458eecfa91f1b8bb9a8a64bbc944571c017bfc0f9628d1e220fc8aa1217569f6be5ced32fba9b70f3555ebc86f2b5807652d2d9355b59174c5e6ea26380a2cd9521ec8cf4ac91bdfc76c40c9f0ecac2a126a3f07963b7af66dfc2836b361a4f0afd8ef96fb0110756928e3545d39ec0f6e5d1308b496446301726ae2cafeea4b1cce8a8360530b61e8fde0b9fb8b7eca7f4997051a44dd6ec07861eea0dffad1c2cf57c381cab30f05443d03c2c1c4c8c5d7e3d33bc3e0c153e404620d6ee7f02f7974a16019ab6490f41d0c0c1440622d422df4bb476728f84df2bbba577cab6907640a8ab4ba53e380c316c6446511d3a0ca39e4731e176804ca926df570a5cd380ae1a845f1fd48a930a716949020e8ca971cd26e34d5b1b8e1d97bf33e7b6234fc458080918541805b7255034bac35ea1598c9cec713a98fc7d78c39a95846cb486e67536fc0c7b11331e99447bf9b85768692cb61312bfd2307dfef1ddeec37526e38d8bdd825caa931efa4accc1f014fbc4b8887117145c8305c3fc73db3a18b55c6c9325abb64ad5463529232247f8763716dc6d63a202161e1dbd4fc2d2f1328d99c62c5c39f7d29afb300dee32de1d240e6fb20dfd3b3f74f4cb62a119b47fff3aa7a82159c6de7fa542788fd5ef4fc0aa53e9a950b0ebeb2879f29631094eddf98e8528b843808d803e9ac8b995fa44ac060c0d38c92c94de778db261a6609c013153a4844ca26b5c882042ca13acf5f4e0a2e70f4087fb979304bb738b74090978cbcad9ae39dcb606585c2563dc396834510b59ead34ae32c03f9ab037fa7d4c48c391caeb43c12403ce76aae33030505831a741879df39aa3477a2d438bc300640527ef153cc4ba3d59fbd4055f63fc7adb3cc1b2e70bc29f5ad1e53032de2569364b564cdb51b2b08e85f73601456736b9cdb5e76b8c963231d64c0ab366544813131538543fd8f27111fd7115ed4755aae501f1e146daac2fbe16451ca78f1d49340df24fe6fc412ab1cf19825d96fec7112a1b59b4023b6548ed93d1e3414abeb7e4924f920fcccfd306e585aad199945f5cfc9937c97812726db5c3f00d1f604a1ec36a2f20fa295fae9cfba9df19dfcce93e2377173a068d791379cfcdcc80a6cd8d673ad856d2691a86442162087747c51f0fd9b7dff46bdcf86dc25a7526ef53b60ff4b0b5e5d735f967b0049364b66866963233710928ffdb7c76850d63f1dbf869ac0b2fbe8de874f6d94b978750f4d7e7ff9f5c87ea780a45cdfd06b5d3e4c85dcdfb184c0a4f55ad9af8cf44f480ec675c9c2e0a3e9b0938332ea97f9a7464e27127b285f6d63a7d2a7d4becd93d21c6126f079b44fd4a11c498bb2ca30a9b7f7be8b0e82f528a203811f09dc79eb7c74ca54bd08b4848b1b27e4331ff578d4f4cba7aa2b66613681a9568f0cb99ed9c9c5e110bf351f375888dd33d117759cdbc2895f47a9a93f90c78f73b4d1b97b7ffca2d704d7ac2765d99955c93216d6bca307f457589d72c334f818b06870ed9f99b0d715126e64af9ff506e43c780af964de4172de264d7027d3f25bbd3deaac4cf659e5a5383f0652662d66619f99a0a90dbf267f7fe0251d8543fea151aae98d152b4825ea71575317e3aa38856100b70b2bf1b441da2c0a7f4b32a26e80a44e57762ef05eee3751f124f46c984aedef6321d7e8bb9d697e02c95ef344651f443f74211b52bbd1eda67416f1a3b63ec4c1eb5711d4f83a69b21e36551305e5eca5b38c22857c8bdad4bc7a39038bb65ecfc866127f87b601ad018ca00353a21e8425f8496fab93b1acf3363ee886b0e3634591d207e3da8f1799a9d7b40f8ffa58498ad69bc03e4c9d3aee6a7140afaf98013a91cf40404d1884bb336a2c6a927742e2b5af1ac496811e90429c6b581e42a0e8c3d2fa90522becdb0d12e551a5cb16a87d4fce04dfa662f286b50dcd40d7c8d2ec7f510f913a8f844f0d0f997753751d2acb22df7db8937039f752795093c2c5178aab4488aa31e08d803c136e1e041a637ac66a352c1de2ee49248052bef2a737bded1c59b2157b9b9bf41241258effd56a53c1a2bc96dad2ccceb38c8f60c3c651acc67cef88fab7c5cff77829e42c1981ac48d8155ffb6c19932ffb5e8aa7d31c2b13f06d2684ffd7853e27f980d7aa5497a5f206224412d0ac05ad2f2bc67fa30305192317c4f1f5d20600f647e8e6abf66828ce4ce9dac50030b753d98ee6ebbf9944f9412a5a8b13f93a11be20d96948804a9fccfe533e3dad1cf0a795bbf1d577fce665f41c770db97c3f984029781cfc079104005bc278e995301dbf41c0958a7a95c89943a0b108d0a474e574adbcf927c51a89434cfdb271f283d7e3484594bc00985020d395fd6d16673e07f0751aecf25be938f492de660db57702293ec863f8cb88d1047e23d6f3c6710eb270af408fc8c9a38bc1c993924ad2c08a1ade00684178a1ff32768c1df11c8698e5e5cb97b148f60215f49a9d79c9338f77d8aa38c3e26013819db1c2089ea497bf2c201ef2448702c511a9bcd5e942df8c1b9c9ecfcdd9787d75c5a7ae44ff53437b02a573987fc07ee3dc82b19dd8029582d6a71ff96dfcc4017b278a3930e80ef4868b9fa4f453ddfa094f65b8a90a88bd4dca79741169ad1765b4753a0c4abce868a6008a9ef8773d59b98ede0aeb8fe0e4da96e105d811831af79d7f1fdceeee1268947447b438e84cef5453bb1e35ddbb6c23a35569e95716f8ea4eda5fc20f6070e5fef941c6b475436c28e9beded15c11faf59f08b6b026cc876997bae5434adb94c84ef7475720345aadd34b635a5122d10078bdc8ab4071818a6fa4e2ecb17cb0f47c897a1325a6107180263dd3af5331f8b6d2c9e1e89d06aba4b9799fe3973963b8bbf6bd27fc7b6ad9859eebe80e3e38e649f4e30aca15d262028e63e397e999469e379d4807dd3bb9f4ecc8ce1a35628fae1c81f2e2d3c82853abbd2dd2383a7146825f8cd24cc7e5880c2daa8bb663c7b8b7a3121403215c7c44925f8519baf559b9ed0caa559ae35f189e69e43c24afed53bc44276e04e0a2fa0fec4d8a9e2fdefae9f293236352d27c5cf115b57860e25ed7ffdb7c3db0a4507fee54f55e2db37d144a1e5fb3620620a8445ea8bfd503ef587fecef17b1946b8e7615d1db4ceeb055060c8ecf8874f07f16fa1cbdc6debb4d2be20f166cfb984d5e99462fc5ce7fdf717b1d9f6cb70c2fe5008d230c20235ce35bb8052626c47b7f8ccb02daa1dd05656caa92c7a56ea7ca40aa2f36a93c1efee39ed70cf965ec43002dbdf6014f4b06970a620ca726d7cc5320985b3003ec39980002a60eadd51952e8d948e0891cf79dd484955bdef70e1c4c547698dc0baf9f20f91377a34fe184277dcf6ae61be5b70e08193fa4e040c0c14768377f3632f415f077a77b8e0cd79f3e5ab1a2dab472c73edd40fc530c36574a62aa5c58ff2c099a9487dde9adc2752df2c845dec47e9cd21d70c744d59e47cd77d643d3cfea15172ecc14c02d0f269afe81cd710d0c076b19effa358b7c61c5770dd7b880eace427589be0c371af1c96316fdc49332dc918f87ba500933834e5777d8a05cb78e69f6d278f8118c1b2a62ea3914d8fde26a4bfc6d10e9248fc9f5a0f070078f67e8243135eedfeba4a615fcfff0be735b1c474bb79bac3b60e3b611c471c36f78f0b34354204dc169f4c0a86a63391d86eb3831638b994969f2f6aa3a049094135d3deaf4683d428bdc1e9e8392f91b7f027c38217e3a755d41e9af729a16a46729471f42cd468e42df93f9e7252cec4ae348ea7ca256d62e213745a4c7df545fd9dde00bf8cf2f572bee00d02e62539bfab4a4516f9a8c59a09b411e1832aa1245a4ed3025417e2498c84e898a6350fdb3bbbff7a4fb6565957c434ebbf47b03c8681943bfec57d41e4230b826d146e320bf147c9bda672dbc2437a40e57567360ccb0f4a467c3b21492394309fce4ababec7a20c92f3e2180cd177cfab54400d3b714737fb7d480665cec583c9860b91d174a66f30a9ecdbdd23b9fcc05b9c9ddc2599dd47cd1380b6a45e2a91e8e0c16328a6aaa403de5c572ff8298b39b623bfb6524e17139fc4c98b19cd4fca452dfd61c3cc9c2dd7a2137b270586fbb0c7ec71e2ae9766a3b68fad8e2105a2e772cc77e49fad567865e58575064e36ed2cb50c6f3af792040be105ad7cda6741fef57ed3f0cdbe59ef1e032fc2a8b0edce71d3d24720cc709c3576e970d168c6394a3cdc1b9e3cdd3257d855dd628b5491a5ecfc7bd09dbef479b62d6f9eacfc2a6e135336e800998cdb57dc2d3322affe78b0b3fa5439769b7640b5290fc5cfe25f9b9069acb816b0f6d3754d61cdde1c6d2b93355597aa23e186dfd3cb7bc3800d41554589a56e5bdae80aa26dc1055ba22b76853f291be2f2d013e92c52a7f5c4ea2e1318bed6030cbed690633c938759c82626547b973f5675c7250e1019e527deff53d4f8f4a8504210cfce3dfd3369ce7769e76473fc6244b2c3e88ec4143d62e85b383c4847abf9185524a21a151bf93a8ddcd51edd6dbb598f3778e24a6bedbfeac3f8ff1c964b0926a857969490ef3824251c69bec0f04dea426887e32ee4939057ebde0e1b8c3672e93eb2e4a8caea6243aac74526ffd65f3f66f97220ad68b44d90da0b376e54e5a96ec7f7d343f53b318588b57d4614189d7be1ef4f4a16853fb8afe33e147f39170d84253ecbf12c47c52da473595168eb6260e742d551c7cd157a748afde1975171c6de5de1b4d76fa372b973285eb2d3ce06cbcfd2dd77ebaa6174fb4321b81f0b1c3f7e6f194f437be2c7131664fcda2b7f6213bac1e83fb2323dac0b27404429d1305bf6241c34b4e2594a498ee23ec2312b94193162956ca7bed5d19e2100"; + byte[] compressed = Hex.decode(data); + Compressors.brotliDecompress(ArrayUtils.subarray(compressed, 1, compressed.length)); + } +}