From 5b5e9213fe3d3b03e41dbdb8895682b37c662f0f Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Thu, 21 Nov 2024 23:58:07 -0400 Subject: [PATCH 1/5] - Add the use of serializeCompactV2 - Add the use of deserializeCompactV2 --- .../peg/RepositoryBtcBlockStoreWithCache.java | 28 +- .../test/java/co/rsk/peg/BridgeSupportIT.java | 4 +- ...ryBtcBlockStoreWithCacheChainWorkTest.java | 441 ++++++++++++++++++ 3 files changed, 468 insertions(+), 5 deletions(-) create mode 100644 rskj-core/src/test/java/co/rsk/peg/RepositoryBtcBlockStoreWithCacheChainWorkTest.java diff --git a/rskj-core/src/main/java/co/rsk/peg/RepositoryBtcBlockStoreWithCache.java b/rskj-core/src/main/java/co/rsk/peg/RepositoryBtcBlockStoreWithCache.java index de4cf0dc03..cf783d9edb 100644 --- a/rskj-core/src/main/java/co/rsk/peg/RepositoryBtcBlockStoreWithCache.java +++ b/rskj-core/src/main/java/co/rsk/peg/RepositoryBtcBlockStoreWithCache.java @@ -18,6 +18,9 @@ package co.rsk.peg; +import static co.rsk.bitcoinj.core.StoredBlock.deserializeCompactLegacy; +import static co.rsk.bitcoinj.core.StoredBlock.deserializeCompactV2; + import co.rsk.bitcoinj.core.BtcBlock; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.bitcoinj.core.Sha256Hash; @@ -307,17 +310,36 @@ public StoredBlock getStoredBlockAtMainChainDepth(int depth) throws BlockStoreEx } private byte[] storedBlockToByteArray(StoredBlock block) { - ByteBuffer byteBuffer = ByteBuffer.allocate(128); - block.serializeCompact(byteBuffer); + ByteBuffer byteBuffer = serializeBlock(block); byte[] ba = new byte[byteBuffer.position()]; byteBuffer.flip(); byteBuffer.get(ba); return ba; } + private ByteBuffer serializeBlock(StoredBlock block) { + if (shouldUseLegacy12ByteChainworkFormat()) { + ByteBuffer byteBuffer = ByteBuffer.allocate(StoredBlock.COMPACT_SERIALIZED_SIZE_LEGACY); + block.serializeCompactLegacy(byteBuffer); + return byteBuffer; + } + + ByteBuffer byteBuffer = ByteBuffer.allocate(StoredBlock.COMPACT_SERIALIZED_SIZE_V2); + block.serializeCompactV2(byteBuffer); + return byteBuffer; + } + + private boolean shouldUseLegacy12ByteChainworkFormat() { + return !activations.isActive(ConsensusRule.RSKIP454); + } + private StoredBlock byteArrayToStoredBlock(byte[] ba) { ByteBuffer byteBuffer = ByteBuffer.wrap(ba); - return StoredBlock.deserializeCompact(btcNetworkParams, byteBuffer); + if (ba.length == StoredBlock.COMPACT_SERIALIZED_SIZE_LEGACY) { + return deserializeCompactLegacy(btcNetworkParams, byteBuffer); + } + + return deserializeCompactV2(btcNetworkParams, byteBuffer); } private void checkIfInitialized() { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java index a52b3a83b0..a649e7bf16 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java @@ -386,10 +386,10 @@ private InputStream getCheckpoints(NetworkParameters networkParameters, List cacheBlocks; + private static final RskAddress BRIDGE_ADDR = PrecompiledContracts.BRIDGE_ADDR; + private BridgeStorageProvider bridgeStorageProvider; + private RepositoryBtcBlockStoreWithCache repositoryBtcBlockStoreWithCache; + + // Just an arbitrary block + private static final String blockHeader = "00e00820925b77c9ff4d0036aa29f3238cde12e9af9d55c34ed30200000000000000000032a9fa3e12ef87a2327b55db6a16a1227bb381db8b269d90aa3a6e38cf39665f91b47766255d0317c1b1575f"; + private static final int blockHeight = 849137; + private static final BtcBlock BLOCK = new BtcBlock(mainneNetworkParameters, Hex.decode(blockHeader)); + + @BeforeEach + void setUp() { + repository = spy(new MutableRepository( + new MutableTrieCache(new MutableTrieImpl(null, new Trie())) + )); + } + + void arrange(ActivationConfig.ForBlock activations) { + bridgeStorageProvider = new BridgeStorageProvider(repository, BRIDGE_ADDR, mainneNetworkParameters, activations); + + repositoryBtcBlockStoreWithCache = new RepositoryBtcBlockStoreWithCache( + mainneNetworkParameters, + repository, + cacheBlocks, + BRIDGE_ADDR, + bridgeMainnetConstants, + bridgeStorageProvider, + activations + ); + } + + @ParameterizedTest() + @MethodSource("invalidChainWorkForV1") + void put_preRskip_whenInvalidChainWorkForV1_shouldFail(BigInteger chainWork) { + arrange(arrowHeadActivations); + StoredBlock storedBlock = new StoredBlock(BLOCK, chainWork, blockHeight); + + // act + IllegalArgumentException actualException = Assertions.assertThrows( + IllegalArgumentException.class, () -> { + repositoryBtcBlockStoreWithCache.put(storedBlock); + }); + + String expectedMessage = "The given number does not fit in 12"; + String actualMessage = actualException.getMessage(); + Assertions.assertEquals(expectedMessage, actualMessage); + } + + private static Stream invalidChainWorkForV1() { + return Stream.of( + Arguments.of(TOO_LARGE_WORK_V1), + Arguments.of(MAX_WORK_V2), + Arguments.of(TOO_LARGE_WORK_V2) + ); + } + + @ParameterizedTest() + @MethodSource("validChainWorkForV1") + void put_preRskip_whenValidChainWorkForV1_shouldStoreBlock(BigInteger chainWork) { + arrange(arrowHeadActivations); + StoredBlock storedBlock = new StoredBlock(BLOCK, chainWork, blockHeight); + + // act + repositoryBtcBlockStoreWithCache.put(storedBlock); + + // assert + Sha256Hash expectedHash = storedBlock.getHeader().getHash(); + + int expectedCompactSerializedSize = COMPACT_SERIALIZED_SIZE_LEGACY; + ByteBuffer byteBufferForExpectedBlock = ByteBuffer.allocate(expectedCompactSerializedSize); + storedBlock.serializeCompactLegacy(byteBufferForExpectedBlock); + + byte[] expectedSerializedBlock = byteBufferForExpectedBlock.array(); + verify(repository, times(1)).addStorageBytes( + BRIDGE_ADDR, + DataWord.valueFromHex(expectedHash.toString()), + expectedSerializedBlock + ); + byte[] actualSerializedBlock = repository.getStorageBytes(BRIDGE_ADDR, + DataWord.valueFromHex(expectedHash.toString())); + Assertions.assertNotNull(actualSerializedBlock); + Assertions.assertEquals(expectedCompactSerializedSize, actualSerializedBlock.length); + + Assertions.assertArrayEquals(expectedSerializedBlock, actualSerializedBlock); + } + + private static Stream validChainWorkForV1 () { + return Stream.of( + Arguments.of(BigInteger.ZERO), // no work + Arguments.of(BigInteger.ONE), // small work + Arguments.of(BigInteger.valueOf(Long.MAX_VALUE)), // a larg-ish work + Arguments.of(MAX_WORK_V1) + ); + } + + @ParameterizedTest() + @MethodSource("validChainWorkForV2") + void put_postRskip_whenChainWorkAnySizeUnder32Bytes_shouldStoreBlock(BigInteger chainWork) { + int expectedCompactSerializedSize = COMPACT_SERIALIZED_SIZE_V2; + + arrange(lovellActivations); + StoredBlock storedBlock = new StoredBlock(BLOCK, chainWork, blockHeight); + + // act + repositoryBtcBlockStoreWithCache.put(storedBlock); + + // assert + Sha256Hash expectedHash = storedBlock.getHeader().getHash(); + + ByteBuffer byteBufferForExpectedBlock = ByteBuffer.allocate(expectedCompactSerializedSize); + storedBlock.serializeCompactV2(byteBufferForExpectedBlock); + + byte[] expectedSerializedBlock = byteBufferForExpectedBlock.array(); + verify(repository, times(1)).addStorageBytes( + BRIDGE_ADDR, + DataWord.valueFromHex(expectedHash.toString()), + expectedSerializedBlock + ); + byte[] actualSerializedBlock = repository.getStorageBytes(BRIDGE_ADDR, + DataWord.valueFromHex(expectedHash.toString())); + Assertions.assertNotNull(actualSerializedBlock); + Assertions.assertEquals(expectedCompactSerializedSize, actualSerializedBlock.length); + + Assertions.assertArrayEquals(expectedSerializedBlock, actualSerializedBlock); + } + + private static Stream validChainWorkForV2() { + return Stream.of( + Arguments.of(BigInteger.ZERO), // no work + Arguments.of(BigInteger.ONE), // small work + Arguments.of(BigInteger.valueOf(Long.MAX_VALUE)), // a larg-ish work + Arguments.of(MAX_WORK_V1), + Arguments.of(TOO_LARGE_WORK_V1), + Arguments.of(MAX_WORK_V2) + ); + } + + @ParameterizedTest() + @MethodSource("invalidChainWorkForV2") + void put_postRskip_whenInvalidChainWorkForV2_shouldFail(BigInteger chainWork) { + arrange(lovellActivations); + StoredBlock storedBlock = new StoredBlock(BLOCK, chainWork, blockHeight); + + // act + IllegalArgumentException actualException = Assertions.assertThrows( + IllegalArgumentException.class, () -> { + repositoryBtcBlockStoreWithCache.put(storedBlock); + }); + + String expectedMessage = "The given number does not fit in 32"; + String actualMessage = actualException.getMessage(); + Assertions.assertEquals(expectedMessage, actualMessage); + } + + private static Stream invalidChainWorkForV2() { + return Stream.of( + Arguments.of(TOO_LARGE_WORK_V2) + ); + } + + @ParameterizedTest() + @MethodSource("validChainWorkForV1") + void get_preRskip_whenValidChainWorkForV1_shouldGetStoredBlock(BigInteger chainWork) { + arrange(arrowHeadActivations); + StoredBlock expectedStoreBlock = new StoredBlock(BLOCK, chainWork, blockHeight); + Sha256Hash expectedHash = expectedStoreBlock.getHeader().getHash(); + arrangeRepositoryWithExpectedStoredBlock(expectedStoreBlock); + + // act + StoredBlock actualStoreBlock = repositoryBtcBlockStoreWithCache.get(expectedHash); + + // assert + verify(repository, times(1)).getStorageBytes( + BRIDGE_ADDR, + DataWord.valueFromHex(expectedHash.toString()) + ); + + Assertions.assertEquals(expectedStoreBlock, actualStoreBlock); + } + + private void arrangeRepositoryWithExpectedStoredBlock(StoredBlock expectedStoreBlock) { + Sha256Hash expectedHash = expectedStoreBlock.getHeader().getHash(); + ByteBuffer byteBuffer = ByteBuffer.allocate(COMPACT_SERIALIZED_SIZE_LEGACY); + expectedStoreBlock.serializeCompactLegacy(byteBuffer); + when(repository.getStorageBytes( + BRIDGE_ADDR, + DataWord.valueFromHex(expectedHash.toString()) + )).thenReturn(byteBuffer.array()); + } + + @ParameterizedTest() + @MethodSource("validChainWorkForV1") + void get_postRskip_whenChainWorkForV1_shouldGetStoredBlock(BigInteger chainWork) { + arrange(lovellActivations); + StoredBlock expectedStoreBlock = new StoredBlock(BLOCK, chainWork, blockHeight); + Sha256Hash expectedHash = expectedStoreBlock.getHeader().getHash(); + arrangeRepositoryWithExpectedStoredBlockV2(expectedStoreBlock); + + // act + StoredBlock actualStoreBlock = repositoryBtcBlockStoreWithCache.get(expectedHash); + + // assert + verify(repository, times(1)).getStorageBytes( + BRIDGE_ADDR, + DataWord.valueFromHex(expectedHash.toString()) + ); + + Assertions.assertEquals(expectedStoreBlock, actualStoreBlock); + } + + private void arrangeRepositoryWithExpectedStoredBlockV2(StoredBlock expectedStoreBlock) { + Sha256Hash expectedHash = expectedStoreBlock.getHeader().getHash(); + ByteBuffer byteBuffer = ByteBuffer.allocate(COMPACT_SERIALIZED_SIZE_V2); + expectedStoreBlock.serializeCompactV2(byteBuffer); + when(repository.getStorageBytes( + BRIDGE_ADDR, + DataWord.valueFromHex(expectedHash.toString()) + )).thenReturn(byteBuffer.array()); + } + + @ParameterizedTest() + @MethodSource("validChainWorkForV2") + void get_postRskip_whenStoredBLochHasChainWorkOver12Bytes_shouldGetStoredBlock(BigInteger chainWork) { + arrange(lovellActivations); + StoredBlock expectedStoreBlock = new StoredBlock(BLOCK, chainWork, blockHeight); + Sha256Hash expectedHash = expectedStoreBlock.getHeader().getHash(); + arrangeRepositoryWithExpectedStoredBlockV2(expectedStoreBlock); + + // act + StoredBlock actualStoreBlock = repositoryBtcBlockStoreWithCache.get(expectedHash); + + // assert + verify(repository, times(1)).getStorageBytes( + BRIDGE_ADDR, + DataWord.valueFromHex(expectedHash.toString()) + ); + + Assertions.assertEquals(expectedStoreBlock, actualStoreBlock); + } + + @ParameterizedTest() + @MethodSource("validChainWorkForV1") + void getChainHead_preRskip_whenValidChainWorkForV1_shouldGetChainHead(BigInteger chainWork) { + arrange(arrowHeadActivations); + reset(repository); + StoredBlock expectedStoreBlock = new StoredBlock(BLOCK, chainWork, blockHeight); + + arrangeRepositoryWithExpectedChainHead(expectedStoreBlock); + + // act + StoredBlock actualStoreBlock = repositoryBtcBlockStoreWithCache.getChainHead(); + + // assert + verify(repository, times(1)).getStorageBytes( + BRIDGE_ADDR, + DataWord.fromString(BLOCK_STORE_CHAIN_HEAD_KEY) + ); + + Assertions.assertEquals(expectedStoreBlock, actualStoreBlock); + } + + private void arrangeRepositoryWithExpectedChainHead(StoredBlock expectedStoreBlock) { + ByteBuffer byteBuffer = ByteBuffer.allocate(COMPACT_SERIALIZED_SIZE_LEGACY); + expectedStoreBlock.serializeCompactLegacy(byteBuffer); + when(repository.getStorageBytes( + BRIDGE_ADDR, + DataWord.fromString(BLOCK_STORE_CHAIN_HEAD_KEY)) + ).thenReturn(byteBuffer.array()); + } + + @ParameterizedTest() + @MethodSource("validChainWorkForV1") + void getChainHead_postRskip_whenChainWorkForV1_shouldGetChainHead(BigInteger chainWork) { + arrange(lovellActivations); + reset(repository); + StoredBlock expectedStoreBlock = new StoredBlock(BLOCK, chainWork, blockHeight); + + arrangeRepositoryWithChainHeadV2(expectedStoreBlock); + + // act + StoredBlock actualStoreBlock = repositoryBtcBlockStoreWithCache.getChainHead(); + + // assert + verify(repository, times(1)).getStorageBytes( + BRIDGE_ADDR, + DataWord.fromString(BLOCK_STORE_CHAIN_HEAD_KEY) + ); + + Assertions.assertEquals(expectedStoreBlock, actualStoreBlock); + } + + private void arrangeRepositoryWithChainHeadV2(StoredBlock expectedStoreBlock) { + ByteBuffer byteBuffer = ByteBuffer.allocate(COMPACT_SERIALIZED_SIZE_V2); + expectedStoreBlock.serializeCompactV2(byteBuffer); + when(repository.getStorageBytes( + BRIDGE_ADDR, + DataWord.fromString(BLOCK_STORE_CHAIN_HEAD_KEY)) + ).thenReturn(byteBuffer.array()); + } + + @ParameterizedTest() + @MethodSource("validChainWorkForV2") + void getChainHead_postRskip_whenStoredBLochHasChainWorkOver12Bytes_shouldGetChainHead(BigInteger chainWork) { + arrange(lovellActivations); + reset(repository); + StoredBlock expectedStoreBlock = new StoredBlock(BLOCK, chainWork, blockHeight); + + arrangeRepositoryWithChainHeadV2(expectedStoreBlock); + + // act + StoredBlock actualStoreBlock = repositoryBtcBlockStoreWithCache.getChainHead(); + + // assert + verify(repository, times(1)).getStorageBytes( + BRIDGE_ADDR, + DataWord.fromString(BLOCK_STORE_CHAIN_HEAD_KEY) + ); + + Assertions.assertEquals(expectedStoreBlock, actualStoreBlock); + } + + @ParameterizedTest() + @MethodSource("validChainWorkForV1") + void setChainHead_preRskip_whenValidChainWorkForV1_shouldStoreChainHead(BigInteger chainWork) { + arrange(arrowHeadActivations); + reset(repository); + StoredBlock expectedStoreBlock = new StoredBlock(BLOCK, chainWork, blockHeight); + + // act + repositoryBtcBlockStoreWithCache.setChainHead(expectedStoreBlock); + + // assert + ByteBuffer byteBuffer = ByteBuffer.allocate(COMPACT_SERIALIZED_SIZE_LEGACY); + expectedStoreBlock.serializeCompactLegacy(byteBuffer); + + verify(repository, times(1)).addStorageBytes( + BRIDGE_ADDR, + DataWord.fromString(BLOCK_STORE_CHAIN_HEAD_KEY), + byteBuffer.array() + ); + } + + @ParameterizedTest() + @MethodSource("validChainWorkForV1") + void setChainHead_postRskip_whenChainWorkForV1_shouldStoreChainHead(BigInteger chainWork) { + arrange(lovellActivations); + reset(repository); + StoredBlock expectedStoreBlock = new StoredBlock(BLOCK, chainWork, blockHeight); + + // act + repositoryBtcBlockStoreWithCache.setChainHead(expectedStoreBlock); + + // assert + ByteBuffer byteBuffer = ByteBuffer.allocate(COMPACT_SERIALIZED_SIZE_V2); + expectedStoreBlock.serializeCompactV2(byteBuffer); + + verify(repository, times(1)).addStorageBytes( + BRIDGE_ADDR, + DataWord.fromString(BLOCK_STORE_CHAIN_HEAD_KEY), + byteBuffer.array() + ); + } + + @ParameterizedTest() + @MethodSource("validChainWorkForV2") + void setChainHead_postRskip_whenStoredBLochHasChainWorkOver12Bytes1_shouldStoreChainHead(BigInteger chainWork) { + arrange(lovellActivations); + reset(repository); + StoredBlock expectedStoreBlock = new StoredBlock(BLOCK, chainWork, blockHeight); + + // act + repositoryBtcBlockStoreWithCache.setChainHead(expectedStoreBlock); + + // assert + ByteBuffer byteBuffer = ByteBuffer.allocate(COMPACT_SERIALIZED_SIZE_V2); + expectedStoreBlock.serializeCompactV2(byteBuffer); + + verify(repository, times(1)).addStorageBytes( + BRIDGE_ADDR, + DataWord.fromString(BLOCK_STORE_CHAIN_HEAD_KEY), + byteBuffer.array() + ); + } +} \ No newline at end of file From 10b254037d9e0f859496c6e5066f09cd2927de2e Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Tue, 26 Nov 2024 15:45:58 -0400 Subject: [PATCH 2/5] Add tests validating 32 byte chainwork checkpoints can be processed once RSKIP454 is activated --- .../test/java/co/rsk/peg/BridgeSupportIT.java | 143 ++++-- ...hainwork-mix-format.production.checkpoints | 433 ++++++++++++++++++ .../12-byte-chainwork.production.checkpoints | 433 ++++++++++++++++++ .../32-byte-chainwork.production.checkpoints | 433 ++++++++++++++++++ 4 files changed, 1409 insertions(+), 33 deletions(-) create mode 100644 rskj-core/src/test/resources/checkpoints/12-byte-chainwork-mix-format.production.checkpoints create mode 100644 rskj-core/src/test/resources/checkpoints/12-byte-chainwork.production.checkpoints create mode 100644 rskj-core/src/test/resources/checkpoints/32-byte-chainwork.production.checkpoints diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java index a649e7bf16..cabdd6b5bd 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java @@ -60,6 +60,10 @@ import java.io.*; import java.math.BigInteger; import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import java.security.*; import java.time.Instant; import java.util.*; @@ -70,6 +74,7 @@ import org.ethereum.TestUtils; import org.ethereum.config.Constants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ActivationConfig.ForBlock; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.core.*; import org.ethereum.crypto.ECKey; @@ -82,6 +87,8 @@ import org.hamcrest.MatcherAssert; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; @@ -192,17 +199,114 @@ void testInitialChainHeadWithoutBtcCheckpoints() throws Exception { void testInitialChainHeadWithBtcCheckpoints() throws Exception { BridgeConstants bridgeTestNetConstants = BridgeTestNetConstants.getInstance(); + BridgeSupport bridgeSupport = arrangeBridgeSupport(bridgeTestNetConstants, + activationsBeforeForks); + + // Force instantiation of blockstore + bridgeSupport.getBtcBlockchainBestChainHeight(); + + InputStream checkpointsStream = bridgeSupport.getCheckPoints(); + CheckpointManager manager = new CheckpointManager(bridgeTestNetConstants.getBtcParams(), checkpointsStream); + long time = bridgeSupport.getActiveFederation().getCreationTime().toEpochMilli() - 604800L; // The magic number is a substraction CheckpointManager does when getting the checkpoints. + StoredBlock checkpoint = manager.getCheckpointBefore(time); + + assertEquals(checkpoint.getHeight(), bridgeSupport.getBtcBlockchainBestChainHeight()); + } + + @ParameterizedTest + @CsvSource( + { + "12-byte-chainwork.production.checkpoints", + "12-byte-chainwork-mix-format.production.checkpoints" + } + ) + void testInitialChainHeadWithBtcCheckpoints_whenCheckpointsWith12BytesChainWork_before_RSKIP454_ok( + String checkpointFileName) throws Exception { + var arrowhead631 = ActivationConfigsForTest.arrowhead631().forBlock(0); + BridgeConstants bridgeConstants = BridgeMainNetConstants.getInstance(); + String checkpointToCreate = "/rskbitcoincheckpoints/" + bridgeConstants.getBtcParams().getId() + ".checkpoints"; + + Path target = Paths.get(getClass().getResource(checkpointToCreate).getPath()); + + Path source = Paths.get(getClass().getResource("/checkpoints/" + checkpointFileName).getPath()); + Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); + + BridgeSupport bridgeSupport = arrangeBridgeSupport(bridgeConstants, arrowhead631); + + // Force instantiation of blockstore + bridgeSupport.getBtcBlockchainBestChainHeight(); + + InputStream checkpointsStream = bridgeSupport.getCheckPoints(); + CheckpointManager manager = new CheckpointManager(bridgeConstants.getBtcParams(), checkpointsStream); + long time = bridgeSupport.getActiveFederation().getCreationTime().toEpochMilli() - 604800L; // The magic number is a substraction CheckpointManager does when getting the checkpoints. + StoredBlock checkpoint = manager.getCheckpointBefore(time); + + assertEquals(checkpoint.getHeight(), bridgeSupport.getBtcBlockchainBestChainHeight()); + } + + @Test + void testInitialChainHeadWithBtcCheckpoints_whenCheckpointsWith32BytesChainWork_before_RSKIP454_shouldFail() throws Exception { + var arrowhead631 = ActivationConfigsForTest.arrowhead631().forBlock(0); + BridgeConstants bridgeConstants = BridgeMainNetConstants.getInstance(); + String checkpointToCreate = "/rskbitcoincheckpoints/" + bridgeConstants.getBtcParams().getId() + ".checkpoints"; + + Path target = Paths.get(getClass().getResource(checkpointToCreate).getPath()); + + Path source = Paths.get(getClass().getResource("/checkpoints/32-byte-chainwork.production.checkpoints").getPath()); + Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); + + BridgeSupport bridgeSupport = arrangeBridgeSupport(bridgeConstants, arrowhead631); + + Assertions.assertThrows(IllegalArgumentException.class, bridgeSupport::getBtcBlockchainBestChainHeight, "The given number does not fit in 12"); + } + + @ParameterizedTest + @CsvSource( + { + "12-byte-chainwork.production.checkpoints", + "12-byte-chainwork.production.checkpoints", + "12-byte-chainwork-mix-format.production.checkpoints" + } + ) + void testInitialChainHeadWithBtcCheckpoints_whenCheckpointsWith32BytesChainWork_after_RSKIP454_ok( + String checkpointFileName) throws Exception { + var lovell = ActivationConfigsForTest.lovell700().forBlock(0); + BridgeConstants bridgeConstants = BridgeMainNetConstants.getInstance(); + String checkpointToCreate = "/rskbitcoincheckpoints/" + bridgeConstants.getBtcParams().getId() + ".checkpoints"; + + Path target = Paths.get(getClass().getResource(checkpointToCreate).getPath()); + + Path source = Paths.get(getClass().getResource("/checkpoints/" + checkpointFileName).getPath()); + Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); + + BridgeSupport bridgeSupport = arrangeBridgeSupport(bridgeConstants, lovell); + + // Force instantiation of blockstore + bridgeSupport.getBtcBlockchainBestChainHeight(); + + InputStream checkpointsStream = bridgeSupport.getCheckPoints(); + CheckpointManager manager = new CheckpointManager(bridgeConstants.getBtcParams(), checkpointsStream); + long time = bridgeSupport.getActiveFederation().getCreationTime().toEpochMilli() - 604800L; // The magic number is a substraction CheckpointManager does when getting the checkpoints. + StoredBlock checkpoint = manager.getCheckpointBefore(time); + + assertEquals(checkpoint.getHeight(), bridgeSupport.getBtcBlockchainBestChainHeight()); + } + + private BridgeSupport arrangeBridgeSupport(BridgeConstants bridgeTestNetConstants, + ForBlock activations) { Repository repository = createRepository(); Repository track = repository.startTracking(); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(bridgeTestNetConstants.getBtcParams()); - BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeTestNetConstants.getBtcParams(), activationsBeforeForks); + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( + bridgeTestNetConstants.getBtcParams()); + BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeTestNetConstants.getBtcParams(), + activations); FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); FederationSupport federationSupport = federationSupportBuilder .withFederationConstants(federationConstants) .withFederationStorageProvider(federationStorageProvider) - .withActivations(activationsBeforeForks) + .withActivations(activations) .build(); BridgeSupport bridgeSupport = bridgeSupportBuilder @@ -211,17 +315,9 @@ void testInitialChainHeadWithBtcCheckpoints() throws Exception { .withRepository(track) .withBtcBlockStoreFactory(btcBlockStoreFactory) .withFederationSupport(federationSupport) + .withActivations(activations) .build(); - - // Force instantiation of blockstore - bridgeSupport.getBtcBlockchainBestChainHeight(); - - InputStream checkpointsStream = bridgeSupport.getCheckPoints(); - CheckpointManager manager = new CheckpointManager(bridgeTestNetConstants.getBtcParams(), checkpointsStream); - long time = bridgeSupport.getActiveFederation().getCreationTime().toEpochMilli() - 604800L; // The magic number is a substraction CheckpointManager does when getting the checkpoints. - StoredBlock checkpoint = manager.getCheckpointBefore(time); - - assertEquals(checkpoint.getHeight(), bridgeSupport.getBtcBlockchainBestChainHeight()); + return bridgeSupport; } @Test @@ -247,26 +343,7 @@ void feePerKbFromStorageProvider() { @Test void testGetBtcBlockchainBlockLocatorWithoutBtcCheckpoints() throws Exception { - Repository repository = createRepository(); - Repository track = repository.startTracking(); - - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()); - BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); - - FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); - FederationSupport federationSupport = federationSupportBuilder - .withFederationConstants(federationConstants) - .withFederationStorageProvider(federationStorageProvider) - .withActivations(activationsBeforeForks) - .build(); - - BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) - .withProvider(provider) - .withRepository(track) - .withBtcBlockStoreFactory(btcBlockStoreFactory) - .withFederationSupport(federationSupport) - .build(); + BridgeSupport bridgeSupport = arrangeBridgeSupport(bridgeConstants, activationsBeforeForks); // Force instantiation of blockstore bridgeSupport.getBtcBlockchainBestChainHeight(); diff --git a/rskj-core/src/test/resources/checkpoints/12-byte-chainwork-mix-format.production.checkpoints b/rskj-core/src/test/resources/checkpoints/12-byte-chainwork-mix-format.production.checkpoints new file mode 100644 index 0000000000..0fa8d25461 --- /dev/null +++ b/rskj-core/src/test/resources/checkpoints/12-byte-chainwork-mix-format.production.checkpoints @@ -0,0 +1,433 @@ +TXT CHECKPOINTS 1 +0 +430 +AAAAAAAAB+EH4QfhAAAH4AEAAABjl7tqvU/FIcDT9gcbVlA4nwtFUbxAtOawZzBpAAAAAKzkcK7NqciBjI/ldojNKncrWleVSgDfBCCn3VRrbSxXaw5/Sf//AB0z8Bkv +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPwQ/BD8EAAA/AAQAAAN8/zdLHwxn1GyudkK+rMDCoHYxr5l6w0AmtN/AAAAAALARJo0qG9GDPpa4TtQV0WTXHDN9Fj84h0g4/NfnJoB2OdZRJ//8AHQas2rk +AAAAAAAAF6EXoRehAAAXoAEAAADonWzAaUAKd30XT3NnHKobZMnLOuHdzm/xtehsAAAAAD8cUJA6NBIHHcqPHLc4IrfHw+6mjCGu3e+wRO81EvpnMVqrSf//AB1ffy8G +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgR+BH4EAAB+AAQAAABxgvU0i2WW+tfzX4u4Crqoh2heutSIFEt6YMlYAAAAAq63hWG72/vWbK56UDhmo7eQ/h5O6pv64tATz4LGN+SGy4sJJ//8AHSkWDuM +AAAAAAAAJ2EnYSdhAAAnYAEAAABGqWHkclp5E4ehRawBs45b5x4XYaqgtDMoSwqbAAAAALTV1vKUrdjXiTPqPUgmGGmaDGPvVaSoLzWx8iK3xMoSZ3zaSf//AB06PHGe +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvQS9BL0EAAC9AAQAAAIQFdXxYpJfkJowmMXucTCbfXsWOyP326GNzivoAAAAAG+Etw4aXZQZyQdjJs17S6b19Xbpt+JkwVoHZ/ys3FIA6CvJJ//8AHSc4fQE +AAAAAAAANyE3ITchAAA3IAEAAACSILqxEicC8TnZGcfxX9/p8FckbxdcatdcW8WKAAAAAEvnJo5A8+Y0mjJYV7kKVLj6Ul/9j/ODgf0w6gefxnUm+eoISv//AB0Usifw +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AT8BPwEAAD8AAQAAAITAafHSKV2ejI8gvBg1jWMtQAssVA/wMWZ5DH8AAAAA6K/j+sIacsN9TmoOFu4tLCpT3qWTJglpObwgmZ7NZ2796yFK//8AHSwCzOI +AAAAAAAARuFG4UbhAABG4AEAAAD9pdvx0xs07by26iadZjBdkL97+LVOnWwpYrD/AAAAAK28IuIFDZQEvOwRV/f5ojcFS/6weEx11ir8PLW1uu5XhT5FSv//AB25x8ke +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOwU7BTsEAAE7AAQAAAC+CuHZwhF+q3eP+3Q2/UEDbYrorJcI+LIQIwXQAAAAA7XPfUCPI6PR3+5Zf5MPL/l7jS32LVsPvo/P5wLJ1yRMYUmpK//8AHdlTlwQ +AAAAAAAAVqFWoVahAABWoAEAAAAin9TRvZzHe1UspvNuSaHkjGdwPF2/P6eEL9xnAAAAAGZsu6+oXMrRFQzwfmOzChP3du3xlBraNR1IelOBukZvsg+hSv//AB0GJxxm +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABegV6BXoEAAF6AAQAAAMxalcgaQKwIN5ctvKraa8+8l7HsYkJiwEdv8NsAAAAAzlGS6tLQGsqtr78gDGRio3irSUyh32pn+iqNsstQYfcMc8VK//8AHcHyhwA +AAAAAAAAZmFmYWZhAABmYAEAAACsBE+FLo8osvJgV3Nhn8XcKfQicTbvieww/mCSAAAAAH+sbigSSrJl6CmsC6CyPQhLaDKza0QbkIv5vZli/8QtlFfsSv//AB3Nm/kq +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuQW5BbkEAAG5AAQAAAAvIc5SUsMfFpXWgmzOvHkT9bq9xBk6MiQCn8fkAAAAAN08li2KYbUDxWWUyFRVn4whKs5EXfnZ2qwRubit81ZTLSRBL//8AHdxP1gQ +AAAAAAAAdiF2IXYhAAB2IAEAAADmv3/X93kKY3hvqoeNDcf9jy/zZXMuRYYsZgdRAAAAAHANNC9lx7aDTf+2FTWKGJcBbwRIkTNyGQy+PSektTNVsVErS///AB2/sCUZ +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AazULdIAAH4AAQAAAEsDYNg0ozDseDPjDh9SPuBaB5M2HimnNCGWT5gAAAAAJ7ZKAgrylOkD/u2TdocFM2ogCQYSoEP0evRiovXltWT47jpLatgAHdOkNwc +AAAAAAAAh1KPIu8gAACF4AEAAADOUzZxCACLCrZb56MIxIoEIWeq6nsqRTl+BDZeAAAAAED71QTWHLGhEIJrymjIHUFzaQjcvbP2UVS/r5ySz1DZxapLSyjEAB3+ZlwF +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRmaTJIJAAAI3AAQAAAFiS1S7mZv1R2TXfJ+6cs8txowMCwL7/eZV4jRIAAAAAEj/xUHCFc87NjMC47xEQ74jxA9H0ZETJ/J7zGD9J4oWvl11Lcb4AHdGSLgc +AAAAAAAAnDAd9NKmAACVoAEAAACFilxtRYgzqoP3t+VtccYEy3EWXruBBLgvZN6NAAAAAOQIwRAptf27kuoO6436E4/6Oszg9p197r6xQAyFBC4Bcj9rS8OMAB0JvYvV +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACqg0cLAiIAAJ2AAQAAABojEJe2q2J5yA8kZ0osjuW5qEjh1FcVrYm2NYEAAAAAqCK6/m7YYA4//ObWHRDfGSfq/pu/Z3y0TE0gnxQ8a6jbjHhLV0ZlHM4iIRg +AAAAAAAAvmyHarHKAAClYAEAAADnCfys/hFGQgTkzB2vSntj33KnQqWfTz7vloQwAAAAAABWa9XPFhrodgII7+bi7V7ZKY4LdK32GsS2u4/OLRurIOaES+WzQxxj7JoP +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADcNECovLUAAK1AAQAAANVeG0aMInmJcScgN9bMBP2sc5E8ABLQ12MMLhoAAAAA6ruo0VlGjDwH91Dbd27ft8zi7YirRPMFS+ROirf+D6B5T5RLb384HHJtkxI +AAAAAAAA/+MWO9HLAAC1IAEAAAB0sfE3ZrOH9/bpE7QmobN2hQGrURvpzWzCCgwuAAAAAMHzQY7OI3TA/mkBu2E506clAApINgYlj7dWP5YemTVAoKOmS3UTOBwat3W4 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEj2B21XesAAL0AAQAAAFVTF5RcC+YXgPFjM1JeNOzch/CVh7biX/gmMhAAAAAAgtPYn4bx/vi42bIBb0mdYMWdIKXytFhh478IZXZxBPlqfrRLFREqHMUr5RI +AAAAAAABU8Zb6gtBAADE4AEAAABzkQWrX5ewFL+e88S/O5SY51fz1vhH3tRv9uYaAAAAAJTaTzK11MIXSRfGlZ6U4TmS6ig5c5ursTao8hscqvB1UtzCS6e8IByBlYEF +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRXvR0w3gAAMzAAQAAAHNDwXqyOYus0rOvJRpmLsl0tsA7TXRiAWkiPwoAAAAA/UuBjYrw5y6kd1Q6loKzKv19QheWnNt0G3Rq9jEKpy+0c89Lb1QWHAX7igI +AAAAAAAB66jAzOGJAADUoAEAAAChpKuAo68wSmzShRxQOiDBWPhqRJdaUTxsQ9wGAAAAAM4DdGfpuItjzlXnWMf7MSwgVK8RgKssPtXqwdXN88sT6OzfS1PsExwAKkUF +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJQ2BlBLwIAANyAAQAAAEbLtxy8T05mV8HyiiqEjv+QB+WMScz/gBb+QwkAAAAAxb1W3rLhw6h1VHV7oIL6HwqzMs0Uk4nX8xLY1VX1zfAj8vNLJJwVHITjYwA +AAAAAAACric7YGodAADkYAEAAADpBN+TLkJyTO13QgCm1Seg1aF+BfvBdkMUskcIAAAAAGLtcb3OjIaURBNKOaF4p0mBbLm7wNHFqhwx4c5GMsJKSB0BTFxnDxxWg7AB +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMxCJGASPUAAOxAAQAAAJNMK9WkVhgLQENBo4DSD1HQhis4MR3rTZUFRQkAAAAAKZoXAuSc9pvD0Kbu4nUQzDzKWkJ+HQALLMr5BxFqr0gixhJMZLoOHFQjwgQ +AAAAAAADuew03p6EAAD0IAEAAAA6WlncsAaw4UiyqiobivpJ8SzBiun3s+wsJwkBAAAAADRA95fGOcOU0tS3CRxB1QIXkXUSwHLdWnY8eXTGzKBGLk8jTEIxDRyYDQAB +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARSwPgpG/0AAPwAAQAAAHeZEFQ86JnmFL2lYFD/1qIY6/8lBnmb4w+q5gkAAAAATnjvFnFTOK+ynjViIBQ4OsiVf+YbVmmMIXoU7s9qlFKYjTJMk+QKHKXYcgQ +AAAAAAAFC+ocnh7zAAED4AEAAABOjlzzxOS49jqc+IvrLbq6GUkYIQGuTlz1StEAAAAAAJ8qI0ToESsNe9gIlBQQbuXxe7bNZAeIg+G2YfolGqxr7R08TPSjBRxNzSsC +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZx3Xw/K60AAQvAAQAAAPtXxxzNIRs95MzC4jtQp823KquR5gc3s6K/3wMAAAAAiKiK2d9okl6IDl1St+UM7yJYccaLQKLNC8oQhM1DYDfziEBM/WgBHK6x+AE +AAAAAAAMB8kDIyyqAAEToAEAAADD6WaCS7mIy8rpGowIPm8ADfcBKSRt1oHRacEAAAAAAIXKGhu6Zhlug2n/7LzalLkMyfbryxZSk3HmsnB0OWijnkdOTFoMARzC4UAe +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOLalUJeAAAARuAAQAAAG65RV87tMc/E/BbJ3Q2hI7bVqTBL2qdQ9H3CQAAAAAASIh/FGgEwJVkndECBp0ObxTYSaTCJpr4LvXyaTjAM6YbFVtMGLoAHI9Loxs +AAAAAAAeYVnHFS1UAAEjYAEAAABPNXbFSDLkdMOHdA9poStLbQ+1SDWX1/qouBEAAAAAAOQ4wJ3d+Vwy2ler4Em9KqKYX13FSuZO5Uwrn8MuTnvKT8tnTA6AABwRqw5P +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4gEJTE9k0AAStAAQAAAAwsfKpPwk5ne42snEwhEZgRhPecXUfMtlbodwAAAAAAPNNVzaUOItuYQ/mdwzyrVMTDQ/V3WRmRmojSo6y1NYIT9XZMmCBpG1JAQ0w +AAAAAABBTaleRTLoAAEzIAEAAAAlZmyAjIigoxs18ypRBJig75D2ZTq/LE9Hu0wAAAAAAAxuq8lWaFwsEaZxcX1OTJA15F0DjrkhHxnywMPxRSpvcRmHTObtWxuucMl/ +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFc8hCJTP2IAATsAAQAAAA6GDeZcNalNLjNb59eaq7bj3fORjm1lxh5bIwAAAAAA42q8IScinTqUrg4gZ6CnXKthYp1bLwG5J99DtsACWgiXb5VM7WZHG/sRuwM +AAAAAABzehv9C0l3AAFC4AEAAACT7yN15axxWGpjC1n+47CGMLk9SeWolSw6FSoAAAAAABA+E4IjPusGLerk7HrCivj8acYXn2aCEu372jArVFnn5EiiTKOyMRsHDdHI +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJwLBrvXrUIAAUrAAQAAABi7YfLn+QkHAsQbXTHx+XSLThr5jJCE4FCVDgAAAAAACtdDo+TOusGC+EpSRO3MWojGhReLId9/+Gygl0iZNqmJ87NMnY4vG8cklm8 +AAAAAADGcizpOqWNAAFSoAEAAACN8pQ3PhGo4sERrtXTpnOb0/zTY7SFu/P+LCwAAAAAAGOKxXywyaEdnE6m2j/R329FjWcT7Ik00IteEtdUebhr68u/TMp+HhusHmHS +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQiRqbph9jQAAVqAAQAAAOHfSBbXVUGputJA0zq6SYrpl6p0luJ+dSupDwAAAAAAIMckTKwkI1Sw3wRsRXDPpJCYmiq2Lmyam22RnrmPqPMno8xMYzIVG4DdopY +AAAAAAFnsxsL7bFwAAFiYAEAAAAc4v5GJY2z3zyrtqhu7k4ARQ3QE468HWBxBQMAAAAAALGcBXeoG0iIxmCRWbmxxJuqTw2MbxO7yaWFqtPGnA7vqD7ZTFZyDhuzuSCd +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfNIikgIBC0AAWpAAQAAAG6YqSkfw6QSNZdRTDIb3LHSD7KCMOZC7622CwAAAAAA1opIRv2UMvMs1/CmmuNGrRS+KfQy4TakhPK73lZczNsSdOVMKosJG5Vaaqk +AAAAAALGiuyDfLOtAAFyIAEAAAAvM57vt+IeRLFZmxK3SNIwrK2425iKeJRQdgAAAAAAAP7NnzKGhchO/AA4XJp1+Iz4RdKW5I2Ta00HmYMK0VYfYyj1TNIcCBsMkObi +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA78b/IZWG6wAAXoAAQAAAIQgh5kVBa8SlVVM0GRPbzyfcHUp+CWWqqAxBAAAAAAAKKqvrhnZevCI0yK6gPDcDwJQSr4aHybnZlLBEHBvjQ4SVgFNU1kFGwLUYnY +AAAAAAU4Cq0i+3IeAAGB4AEAAAD56JBkoYAvTbuvRNqKp7TLA01rjlf4uFC4kgIAAAAAAJNpGsZYATB7pFLumTP7IhNBHlmmwGrXksjxewgYcrfRG/MQTUyGBBvh1Pog +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABvWiUU7MWuAAAYnAAQAAAN33UJC+vgT9AL1dVJRafndf8hoBI3TihP5aAgAAAAAAenEQDaMrRU8V4YY7bdoUjIMPksDpmAbBD2msY5LqPLkzWiFNywQEGyTaBPg +AAAAAAjrUYnT6V5sAAGRoAEAAABlHWfOi38ecTZB4glpgP105XtDQCquzJw4DgAAAAAAABST87fUh282dXEyCJyhQITFUHXXxa4fx7UMfHzLTIMSf64xTe6NAxvI2xyO +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyKOKuVrEuAAAZmAAQAAAA6kXFOS3OX9048sSsYQQG4uzyaXZMFrvxAFAwAAAAAAH7ZOw4jhjXfXtjn4Xrezasvp2Oe1qAHtBnJlRWPYBG7LKUFNKfoCG6qBdmk +AAAAAA3Hw+JhyZf6AAGhYAEAAAAi6PTZIB2swuWyr3tAauRsnHc1yE/xV4BkggAAAAAAADsWVAiBrukpas4xPzUaJeMtomg9TH+XAOeTxuaSr8HYQMxQTVKFAhs5IzHm +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEOetLjydwSkAAalAAQAAAE4lAQIiPMXUqfI71Fnx2aZxBAFZKbLWzIrzAAAAAAAAXmwGks6bp/we1/qcdS/q8J4TLDM0ybpwXtoscz5V1seIAF5NJswBG7mbVck +AAAAABVJjeXJZ4UuAAGxIAEAAADu9Ez5w+BKEGyy3xS/gojNg7hei2czMafXTgAAAAAAABFxY2+JKb1awlsDJVEzV/ZNb72GbemXrE1P6F7mU9wqeCBqTc0tARvDXXY/ +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG/fsg80jcnMAAbkAAQAAAJYfmCx5FCJKm1KT+BDMjgLUVxeaZM/0P7s3AAAAAAAA5Yqi3tsuzwkesHeUB75kd6vKYf89iWOjtzy+0OZt3yoDnHdNMdwAG+9bbVQ +AAAAACUfql1QEymxAAHA4AEAAAAv8ohrUL/oduWhcjQhj2TAnR4Yf/5ZZfQIgAAAAAAAAElAgSvR2+lo/Oed1Io1FCCTJWyMZrjt+lhRLfLvvEQccQCMTTnzABsay2jS +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALWnG7RktN64AAcjAAQAAAMjYMQq7acJcxc03WslMhIjA9jtx20QkDB1pAAAAAAAA7gDUNTjm6FjN/8JNNl/6imGs4lWDHF951ZhX22H6eLAVd5tNvcsAG3yNIGk +AAAAADdPD9bcmy/0AAHQoAEAAAB19iO31C1znhGXB2FJl8JChF9CSsb8CjsVcQAAAAAAAEKihOUu5fWUpyoyUnLOrWnULP+0/Ajx71vtFMyNb5xtEO2rTay1ABvUDtpP +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQmgj4deAEbYAAdiAAQAAAD0D72fpIxDx8RYfz242MbzSWpPl5CK1rISjAAAAAAAAcJYXMJbnPbFzxLIa52u7v2Veu1vZZi6R2nIRRMVO6tqMebtN+pgAG1iYuFQ +AAAAAE+Wj98/9B88AAHgYAEAAACXSksZfv5mthMtrzxYxrcfEpISkD7UkyBTLgAAAAAAAMd5iTUg08WipCJhx8CS8T5hurf7gPrOAG8H7U/2rVtz5FnITbOTahrmxhR4 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYoJbnT+YBhkAAehAAQAAAE0U3eWeOq+DKYMa5hh/qkZRJevH3bvENeQzAAAAAAAA8qxlwbyJyllhuR4m1w9XlTy4C8MPT2ugtYHecRZIgSF/QtRN8rlEGhqUXVo +AAAAAH/as/mBH3ZiAAHwIAEAAAATL2aG9zIfGmonitIhGPqRP3E+Dl/UC0v/KAAAAAAAAFB4Cs4JOIIEgOcbrugep4UTC8gp2hRS/bWJzFgWLwpm9J7eTSGUJhpFQ3Lb +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtB5+IY/45f4AAfgAAQAAANWgX/t5Z+53hnh89rSP5k2vB6YW4RhTx/keAAAAAAAAeaGB47XrzsRcqU5/MJLIqPcvfhvca3jXlujebLh4l6chx+xNL5MdGiEfCgU +AAAAAPhNq5KCvJBVAAH/4AEAAAAjYupMfkApQ+F7WuwrHqo61qpHgstMaZhuDgAAAAAAAJjY1qtpNn506DxHOfKO2yv3KZQ14pMjv2NeVvYXsSe9brj4TYUhExoLyjiL +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYbZfe+51MI4AAgfAAQAAALTr1MXYbYR1JV4ILbg8TITRpiMlS1dTIQoAAAAAAAAAew4adirDAsWoTAmXhGXPl6OH1xz5w85NZl9dWdwiMNrTeAROEioMGgK5lEg +AAAAAgd0Jpp8J4p3AAIPoAEAAAA96H6SIrmh4lozEuOYB/Ocl4iDKvsfGyypAgAAAAAAAFtPgBPFjrDD9Abvtt7rIfpF/ZCmXtK/hiyElBCjLnAsIscUTs+7ChraDJcW +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACw0hDYpMcLBEAAheAAQAAAKbazWVl4A1s+dyGzC5OKmfnIjlzziIUS9UEAAAAAAAAnaErgnB0O2Kcude+spGv/iMD+jDTFF6sXkTO0H+Dfpad2SVOBOwJGqXavoo +AAAAA4568Asa4obxAAIfYAEAAAAtJnC0MPYlp2pgsxXHCws0Qq9nv8uWrpHdCQAAAAAAACfx8m614tr8PBSy8Kext/FHqJjZJvH7VGT5PCP0UE80p182TuXhCBosiyag +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEcXDhwSv6SzAAAidAAQAAAApdiMzQxWubvkyErK5yUKLU3FupL1J4PdMHAAAAAAAALJIDDmKBvle+x3awhNwxb+v8skh6uW7HFwivNlMZVel2r0lOhkoJGh3aCe0 +AAAABUprw7t3ffo+AAIvIAEAAADSRgUSvXLJuiZdImMAcIa1kIP2KBLd9VfdAwAAAAAAAObyH80swCvzJBXItN3SAM8ogjQDawFZivOgF6TUzi4x13FcTuNvCRoWqGlT +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGIAuoGemAMvMAAjcAAQAAAAR2U+tdMH3PEpbmsUOlvR/1ksNHi4fK3msHAAAAAAAAyJbddYGWN01gXc4sPowT+DRJrCjUX8c0VRbXUWW4z7EMI29OpY4JGoePw4Q +AAAABvL7X0R+mhkXAAI+4AEAAAAwPla4OPbkCMpZTRG/HHYNIWL+nY3htxvrCAAAAAAAAPy77i4U+Lzixlo7w3Utr1lkWBDW2i83x8zth5Ch/JARaFKCTl3uCRoOcCKg +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHvfee3W7vr2IAAkbAAQAAAAlfhBUZGU3AmiKPpqv98ehRfH3X5IXY2LABAAAAAAAAEluYSrnn/OPVADYIyXZjn5FxxYVr54rM7/h0AbKrZGYDlJdOS20LGgTF9Es +AAAACG5gfCYS94FlAAJOoAEAAAAwfCgqsDrim0wjAIl5O/zJcrCaX21xOqobCAAAAAAAAOD0xYkK2PKCePrC5H16jhMbyyvoZYVMuEQHvKYmiom2FhmuTsrwDRoWLVAc +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI/v1wmm9JETwAAlaAAQAAAFdGHA9El5IcuZtgkx2m6T1dttSwuSQCjbgFAAAAAAAA3MGeCZYV9sfe5Xkhuf6H9iachm224HIpc4Bhk3PaoD2Ku8BOmhEOGgPF8Dw +AAAACY5HuhbVBVwFAAJeYAEAAAAf79lak+p5Wjc/JGFumn0LZTqkP0BwaGp9AgAAAAAAAPXPYczT7AW2lY4zD1T7vUC0MVSV8xf9J2MTzoLTxmY/JOrUTrFhDxpRYTHJ +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKEVmCZkB4uz4AAmZAAQAAAJQn9wyP7AkrDGLIxSGWf1X2AvPkhgtJoxAIAAAAAAAAHav17aLEwBUIWYmzBBBYRaelGJWCvikCMARGDXGVCGcrWeZOaIYOGkoOyKU +AAAACpwlFy5EWSkdAAJuIAEAAABg7Z7T1Yqlqsyzt3YVJX5x3p+Q6tCovDM4BwAAAAAAANFu2klbATzndp0N9uY2vlDa6LPMt+TLFqlJQWHv7t3YTcD4Trp2DhrnmPoE +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALJ4hyKETOS/8AAnYAAQAAAMSDgcQ7HS69OGxwlxKJqmnpdP8oH+3SfxsDAAAAAAAA/OwBRQJbisgRtIb8kfB/WjmiFwwu7hBmI43aRUWvcLbI3wlP12kNGjUJmbU +AAAAC73VXDIumXtpAAJ94AEAAACmS77xVScJJnHVjObyMbVAHYGDKTi6vDgHCwAAAAAAAOlTxivTggIx0puQOlthPcJsCIx1jzjl02blLi/e3xVkmIgbTz/UDBrwMAUO +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMWvsLHev2HBgAAoXAAQAAAKSaSmOA6fsBPrg0CTrDFHbAl6Q/Xv3LZAYAAAAAAAAA/QPxwLxfqu4wBqN4mYDi2nt7tWwoH8zZWSlXTiFrOTZJCS1PCykMGmo/yOY +AAAADQDD92shJKLCAAKNoAEAAADEVRQMfQ6UxE2SR4wqglkM5HCaKDnfILUeAgAAAAAAAIDF6zgqmMVXOTTQlUNF41Jz7gJAJmgWAER/CytVTkiBX4o/T5wwDBqqr1mz +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANpifgj20fMn0AApWAAQAAAJbUM3HGKFyfRKq6jgzmxYfoDyW8ERvE4HUCAAAAAAAAzefnw9m27c3Sfr2fMe6wwdxgK3B+URy8SWpUAjDMXS8AhFBPDDULGgY2sHk +AAAADloKPAUfc8b1AAKdYAEAAADQvnrUsCSWVD2f1Pr4ThpOj37uDO6+/bB/CQAAAAAAAM4luTI2jCl6KmxqQgCcPh8KqmfiVME5nP97OfQI4IauUvViT4cyCxonLq60 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDhcBMHMbxG0AAqVAAQAAAPWaCfykV0fNaWwv6nj5NOV3UjY0neGaGT8FAAAAAAAAXTYv99DR5JK8dZry7Dj+1xiFJxSObzGk1rvV41MuCzMb9nNPflAKGlCIwfk +AAAAD9GKm05qR8mfAAKtIAEAAAD2Mh/cMirqRe0nn9Iq1leTS9KCFva057IXAgAAAAAAAHfoU9TLw51Oniu2LYCbHyq0JcA3+7Y0D/RPDpIK1EXeIf2GT+OhChpQgJaI +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQjyWe0L1RyAoAArUAAQAAAFkjS2kcFN6aIMBPxoMZpoz0kyNw1Kx3HZwDAAAAAAAAde+MXBPfOoPe4IWBHJm5zIGfj4WMukpSXR64U3Nl81gyTZpP9x4LGvrRro4 +AAAAEURwkTBm0hBWAAK84AEAAACw0l+csvrkIyh0w5uQUifOvi9sDzN4DD/lCgAAAAAAAIsgmncZxVK6S4NyzNFMUetb9Fi18GyH0Zk9YlP5pacwQV6qTwKuCRpdiCRi +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASFLOnatrVK7YAAsTAAQAAALgHwt7ItzX3G7oTGW9p3CbSx16oMYYr17QEAAAAAAAAkGHHGWoAm5YWsMvBqT5wxjNOG9bv4nkIhQqwNMZZ/vKVeb5PX4sKGiJdd6c +AAAAEtPkexWmwmgDAALMoAEAAAAOVsA9yv1hZqT0M/wRg93KXSEvffu/NWfgBgAAAAAAAHuzpeREEX+2b6wH0wGNPrt8qLDKEavOcaQOrDQ+CtMQhQnRT9aYChrRBrot +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATkiSu/wNXjJQAAtSAAQAAAGCotrUhPWTUVfOusMgwvOo4s/84Sg0RwF8FAAAAAAAApyKOnD82VOZYwNMMeilWKDjScGUeF9plv6al7j4DPghE9+FPircJGmCRdEs +AAAAFGGeB1erGaGZAALcYAEAAADoP3M4pxcBIDcMFEoOH4bEhEDBBuBNy2kbCAAAAAAAAFNVavLdhzXOWO+njASenf6QnHLa761w7Y0m669TbsVo8Sr0TzGUCRrNjfIK +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVNBZbQAM5av0AAuRAAQAAABrkJ5zb41YPG8lVuGnZM7qKalsL1PJwB5IJAAAAAAAAnB8lnYD1Iumbt/YLAYqNltzhMD/egUYH+50mTspQDTzOfQVQLv0IGim8+ZY +AAAAFhRfPDePwG9uAALsIAEAAABB6bFBFgVuPvzw/1n0Ud7MckylhKa3HN2RBwAAAAAAAK1J//wVA6Cm1OtFEXe1ixsLmnO2OfqJzKF//X4x92IlWW8WUMk8CBorBXkf +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXCR4MHA+Nd98AAvQAAQAAAEm0qQPCZ2zz0O4Ustl/S1Moz7WYpaF0pJ0BAAAAAAAAqZuW+R+JNZbJpWcXYFOWduEEiJ4wxaETObZ3WdxfxQr3midQXqgHGkDqqU4 +AAAAGBBlsJgRRBm8AAL74AEAAACryGtgxuPGIrHtB53M5GUrd/kwx7qI6DNDBwAAAAAAAFzIff2abwkijY+AnPqk7dMjm9ZPSqbfo4jp0SU2VwCtfy44UL7fBhrISt0+ +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZNbEQSFRxBJYAAwPAAQAAACB3XeydOyYDDo1Vh5fB3vN480XEFZFmgHAGAAAAAAAAX2ncMhqWv/WbkPkcfAiKjLQynq+pC9cBz3qb1lBNxi0d50hQODoGGhomYvc +AAAAGnlueBNyjGqcAAMLoAEAAADxMAVyLCW6TmMToi8xd/5fHCSs9IP1C3YEAwAAAAAAADx5cYOZfXdScyl5oKbjMjjNawr0xA7EYHrK+JA9lZFNs0NaUIvbBRoA5+c0 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb0Zya2Flt2NAAAxOAAQAAAJ1vTgnVeckwFag+kIH+6DpcixujyGUWth8EAAAAAAAAJTmTF7tcfE2u/o/ixN+sDOp+ToWRPNZnAwN3JAyt/pOkkGtQCH4FGoQpffc +AAAAHUCr5swt9qOtAAMbYAEAAAAOv2o9GRg/8y1XLWbrxHEtdKsre8il8scvAgAAAAAAABeUG1JXau20Seou1gCnOZlXswxzeP9ML1f0Pc1AZN7PCOZ9UO91BRpFpYNz +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAesd7IBXlhJzQAAyNAAQAAAEBmYGTc7y8RlCZgeJ1bUZnmJF+8OLpDbTwBAAAAAAAA182cxbsIEwO05vfQvQu+N6tStaLdWCqpDhvOIAdZIuJjHI9QxRMFGgtoTk0 +AAAAID7w/0q0w+tEAAMrIAEAAACEAu3/yPyJMhG/gP38DabMJ9/9EKi5dlFmAQAAAAAAAHvvIIvSBR3lDrxUytZSfsnG6fpXIKLJ1rmh1lUQKZ2IEjmhUOv6BBolhGb6 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAh08C3U48cmGAAAzMAAQAAAAvrdwvqtNrrVra/6SyUHUeREA+gVg/4btwCAAAAAAAA+AbQ/DMplkuuTAZynpO4s5TUXda3gmRpdbLAfFgLG10lTrNQ6uAEGpdwrRw +AAAAI3D8CCdlC05fAAM64AEAAAATq9as/QRQZ7NbiW0sDnHluYjKSOxGVfqhAgAAAAAAANQbrFUPE8FvhfwF+W7JNRJHVh14heISWRWR7b5VfmSh9SPGUGL6BBqMTELu +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlBfA9NcOEAKMAA0LAAgAAADE8/phnqOU9ZPtEroTap+yPuUnmEXxRF/UAAAAAAAAAGX+qcZkqMmnQgjHlLyjhoPLeSDgs2Aq1GqrnPrXiurE0BNtQa6EFGiY4pjk +AAAAJmwAf/q9P+cfAANKoAEAAACPblqJbabQH2TbrMtrZR8l+axIM5IqucqZAgAAAAAAAC09O54ycjSjp8dTzItlFq538Jt1bF0CvcEpFWOs4q/BovfrULEpBRpX6ilq +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAn8nd4pcjPUPcAA1KAAgAAAAFFk4AYZjBmU3nQGjFu8/EGDzos93e5CHUCAAAAAAAAvOA3h4POJioTDXX0PPPDO6tzn6lTCwn4kNWCvoBFEm3XLgBRsaYFGnUHkbI +AAAAKVc6LSc1FRwRAANaYAIAAAAbH93FOSRPWG/NfO3rBAHvv2/MUpQiWVmSAQAAAAAAAKY7Csuyrndi76Fs/hyUdggrElc5MqdWbxukEnHoaooGquoQUTwfBRomGdg6 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAq4NhdXvTD9ngAA2JAAQAAAHR8zFB8sL6LRY2qr5TBaPSKVV/aCZWoTLMDAAAAAAAAFGDy8YVddfwb6KryG1iwBP7KrgT/xoG5xs/aZB9iIdc2eiFRXJgEGiNtDf8 +AAAALJecaPrZYKPwAANqIAEAAACzrQE86vYXPV1BiJTXT+NSxWzIsEoxnlV2AAAAAAAAAK2LAZvcSpmHGAjlUShbA7ZaLT3IfXRkE/gsz1XgLbsplOgwUUvXAxoIBach +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAupIEnfHFAKpkAA3IAAgAAADtGwRaPR7Ekg2Xxbn6xf/PSDsPNUjIEWDoAAAAAAAAALgH6zTl6AKM8RNsOaF5vIIJxsGl1tPe7fY7/xrL5ikkai0FR+nUDGqI52Ho +AAAAMOshluKShCFIAAN54AIAAAAzU7TKXCHZoH19IRxxk7aVgWVAAuZn96sbAQAAAAAAAPL2RBMH+xgPoT10EWBjnN1BWoWmBDPMkwMq5bpLx4sS2epOUW6BAhrKeVCM +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0D8rEmxo/vswAA4HAAgAAAF2VgsjAT/3jGRlMnSHRFiWOrcyAtI/SeXUCAAAAAAAAP0JIXYo7LlmTf1XJhh0DWQm6nHXgNFUz8kt1npoKyvebDF9Rvi8CGqx+Gtk +AAAAN6nk5ERfML0DAAOJoAIAAAAAtdqp/fl9ct41VWrFfomB/BW6gH/gb1R0AAAAAAAAADNrYZ0Eb5RiuhZPF7JFQBTvEDG3/WnZbaX8nL0zfFk3ltVuUZTeARobGMYL +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA74FqwhQ1Y8aIAA5GAAgAAAKMsdSIuFh0bvN3lhrY7TUxPiQcMuDNYxbYAAAAAAAAArmaoakLplDtmdfIrQtcUXwFhvNIjfAaKbdY44Vlv4L3XSX9RPaoBGtrM+nM +AAAAQJs8dZBfNdApAAOZYAIAAAANsIJdf+Ui6vXdRtBYM9+/NS4SUweXL28yAQAAAAAAABsqQ5um7w9WRee0f7Vb7HNcdvueFJCBObOC9hVPuFhbS+qPUel/ARqqe+Tl +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABF25u4e/wvIYQAA6FAAgAAAAbTGfCVYjDd9gv9unTJc/9kJJETVnSEEGQAAAAAAAAAZ8UTyN3nAPcJrSgNmmMp4p2A2uJ68HgkQs8tI3IoTo1i6KBRZGEBGgbXjAc +AAAAS5A5744UbeXgAAOpIAIAAABZRaZ2UpQ6X1IBwpWNV6Yxaay7pbHdBeEaAQAAAAAAAMQVh2dfNpqzbdKuLC0oArnPECnFYm3bzluL38N0NMKaTkqvUTcTARol+LMX +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABS47JQ3YYA1u0AA7EAAgAAAEEKvqvwB8EkeWHSrNEzOT+v6omvGe5vttkAAAAAAAAAN+sTwRf1CZKJpDq71aFz/vBAR9uYDAy4TGoZMPO5xhQeML5RFd4AGowUMe0 +AAAAW/e2rO3bMUVEAAO44AIAAABXsaSPxeKYWXcGqFcGrESz7nUvDGdCbZURAAAAAAAAAPzO8HRUDoriCg9qFxl3JwrlqXrNON+E1NbYJ2d5pHIfje3OUU7JABroq+pP +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl+8G/WUlXaWgAA8DAAgAAAAABM6P7zdndRXK9E+5oTklt0Y82kKkem5UAAAAAAAAAESEgLZnquDaTcHEWA407AJ86EDm2jg7rS664XKQpoRfT+t1RKaQAGgIgyAE +AAAAckPqyEdtb+UEAAPIoAIAAABgqXEY9fKFjHPC/BwY23KMNf4kPkIea/iRAAAAAAAAAP598fQiaQ7fEf3dWvsPLTY040Kyx0sGDg9gbgI29y0yc3LtUWiJABr2oHhz +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACA8ETqWibGNCcAA9CAAgAAACbMn034GMwKuHI+w7j08qFW5p+0c+RG4VUAAAAAAAAAUb+bkqUYmdOX18CnW2JXgdeg6T/xtN7L20GsgH/+IT7L4PxR8ttyGXBWgcw +AAAAkn5c9io9/C99AAPYYAIAAADBZC/d504+FDryeR8KwyspNUcnYTIaGWpPAAAAAAAAAG1hClgMQacQYbiM42rd2qMyZcr1SUoe7bDVYbeXtIzY0nYKUjKHVBlIs5nQ +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACqWN4i9dfh+BUAA+BAAgAAAFgjDEG1+p+LyE7nYjMzdwLGAygnFOfIJ1MAAAAAAAAAOHW2eyijPRY1AmbHxWF1D6hGFhS8kx/ix3HXyVGgQv1nvhhSV1JBGTRE7V8 +AAAAyTb5Fqr47ML+AAPoIAIAAACX7rVSkZhpCkUal478RqfWOExWBYcrpuICAAAAAAAAACZt+4ZLsZe8wnMe31jhPrKk217aW2kZbfGAgDXUZRy+LLUmUpxnMRnQtVj1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADyBssGmohebO0AA/AAAgAAAAQUtvksvk72Xqs4ZFwHtdm/OJUQMP/zKyAAAAAAAAAAPFJ2nn4aXkEWXo5JOYs6epMBJtWMGMewc7DtgrHSmkvI9DRSIiImGRE0aM0 +AAABJubv3Tndk1a0AAP34AIAAAAKM90ssmxG+APltlb4X3ZFy5FZP4kFcZkcAAAAAAAAAJwm+n3C0u+pTKFYGN/E+YGiyya3lPrXI/ykIP8M4c3Wgu5CUiDcHBlSx+6b +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFsxC1/0AsW9FEAA//AAgAAAMH/hOlfmnPXYLN+REBWt0hn/NijguE8wRAAAAAAAAAAOZh0G/H2gGsmvISW9O+8zVLKNrJ7gnwt+28fBV5yw6TYdlFSyrAWGRtFgHY +AAABxaHL+NVHoUz/AAQHoAIAAADoHUz2iigStnsjLSd4bTeTg8yet2jbSbsLAAAAAAAAAJE1SXE8H/4K1acSmQz/coP+ODNPp1MO7xcyFtYOvWi9nINeUrYKEBlp4UEx +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJDVQLqGvBb9Y0ABA+AAgAAAI+FpEH1zDul3t1L6dkWJO8O02fDcwn9uwEAAAAAAAAAbskDuliN7b5MqooipxArUaXMw8BjGt2H30ZBWN3GQSrgJ2tShfwKGXI8k/o +AAAC+twK7X+2FztrAAQXYAIAAAA1cxzFmotPC0zH2yyV3ebxRrdqmc5qW+4EAAAAAAAAAFGUvhEXMIryB1ag6FKcDCOu4svzxBRLWYEcJgwfBNFAY0x5UvNnCBmTtj5x +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPqta96crIxeYYABB9AAgAAAKwNjVRIalShfMtMMCQoevPJ0IVQUTvy8gIAAAAAAAAAqiSm4nxdbvLLMsYfkbPbGmVtunyShpYLoor8Fw4JMKlr1ohS+wsHGSXXnNI +AAAFCNHimKfmYljJAAQnIAIAAABUFjK7kH+hlwj6cEphh4oUPXWh7P3DkFUEAAAAAAAAAG9DyVe/GGRD9XOHS1cohSqeNooOwSvIT6wGPdmdZEzbOMGYUkISBhkH1JlO +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZU6297L/zSlA4ABC8AAgAAADSYd4HrltHCG9t6VAsEFiH+NRS/wO0EtwIAAAAAAAAAtjafvp5xHC9tDDyw7PDuFGV6vFSmt7kVLSxaX7fkMwEOIadSbroEGcGA0rc +AAAH/1t6zJkptGOSAAQ24AIAAADfcmfSNpovmr1d5j2K7S2+D65o3cadxYwDAAAAAAAAAPhaPQ0zPVLKuwrBNs1CMA28iE3BvPNX99H3d3XKWNo+WFu1UgyjAxmJ1R/W +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAopuwk4h8ULUYQABD7AAgAAAD9U9uoai3ktC5EUc08npQ3ffF4HULx5qQAAAAAAAAAAMndI3DjqYpR2gkQLe4Y8Gz7fs2lSpkgIoCzfZJjWKOC+ucRSHwcDGU9d18k +AAAMw6Su4LKwrErjAARGoAIAAACFcF4ulUEs9DkuVM0xVm7efLf1jIxUjt0BAAAAAAAAAIFj2Y/SNomyfmn93vY9LKpgDuFqgdsxcAjrjgVYn7widFvTUmZmAhkGG1Ph +AAAAAAAAAAAAAAAAAAAAAAAAAAAAABALvVQdWmGSPh0ABE6AAgAAAOA/QBvX0khKMj7NS2v5lFoaNd5hpEI1UQIAAAAAAAAAPrLfIjguQ/W1J8CmuLIwvMuTlHBDt/k1etP2WR8ol0mOauJSLPUBGaLKZzU +AAAUEZ4ZJqWngOInAARWYAIAAADwfcFacIKz/xtkQBANbOWnmdV4PhYHzFABAAAAAAAAAG6cdoXTGFMoIltzbAilUhwYcqO4aXk6LAviFEIJt1VYyOTxUm6jARlAIc26 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAABjgNOxLbIUgbcYABF5AAgAAALux3ZsDQ6H2rAcpfPYSdlRcrW0nPdhRkAAAAAAAAAAAEdO2kfgyrn5nXbogzx0JEz7MM92JybvoK0KfG3t8EptPWwFTU18BGUShW6Y +AAAenV5ZFhaJCAWSAARmIAIAAADgYdTpsw4Pj43roethu8sLq5AnfZTTgwsAAAAAAAAAAHNuoPIB8WKYIFws2Vq9HY1JB6H8uFsPD8G6rfBoqeLyOYEQUyYgARmxDAjQ +AAAAAAAAAAAAAAAAAAAAAAAAAAAAACWci+xx/T5L+YEABG4AAgAAAP0zrUZMJjCbDPlZxdidMvpSbe7/rrtPWgAAAAAAAAAAoxoxBtixndNIZ/RR2N/ZVy9LPH7WKs2Pu0MP7eL1uuUcFCFTsQIBGcRBlSU +AAAtZ7+ZYBB+PISnAAR14AIAAABIMc8GBdlAgDhBgYxqAsV4Wok+6Lo0aGsAAAAAAAAAAHRh3QIKzF7zCY8VulZBVJmhzbPwOcUE/3WAnd9YbU5cGMAwU5nbABkWcEB+ +AAAAAAAAAAAAAAAAAAAAAAAAAAAAADaWMlIRozJo7QUABH3AAgAAAF4pnmu3d4hcs5ETL2fz/+cIsM2abAY8vwAAAAAAAAAAuR+1DH22frpPULtbkkvrHI9uB8J6AzJNWEslTUbSEHPO3T9TqrMAGWQsTVg +AABBzvUssHCgSb9TAASFoAIAAAC6PytCCOwElbLjdDRlyuK0TY8cd4tEz2sAAAAAAAAAANKH5S6ARcBgwc7kfRzHVZx7irjbWAU5+1X8V5qZjqFO/g5QU4ydABkmwMGA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAE6bBU54ywdza4kABI2AAgAAANwMgO30y7gOzKPVdi365HfsL8JMsGpomAAAAAAAAAAARNuaeeFokLUCNogpRaobC2db7DUdvjfcSZ7xtkF2COknKmBTbIkAGSOkzDg +AABdRsdNbDb1KtjbAASVYAIAAAAarq5w/eZlSZDo73f4MPqxlSWYgH1jzDYAAAAAAAAAACiEa2cQS2gGiskqmbA9Dzwg4Z9gwSF0hILuRl6+bz3UN9hwU1MwfBg7lmHj +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAG2C48k6acP0nUAABJ1AAgAAAGZTMxeJRC2jj/QFqfOAfH00B6fghbXpDgAAAAAAAAAAxWUr0h8noIc1FcWlOPx0HuYSAdckE8GFbgmGcHzjYE3ueYBTQihpGGvaJPM +AACArwrQuiUdIFFfAASlIAIAAADcqCVUPO/WYrMZngKvoTxqrUsBiQGAAQQAAAAAAAAAAAGHdD1IHbUgFw8icB80oUSThERqVVdeLEbhg94otIVHAeaQU5qFXRixibXk +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJY95C8Jx2lB1ZsABK0AAgAAALKz0gT70f2l8b+o6D1vZ75zB8BaZNREGwAAAAAAAAAAzRmzaOp29UpgTVxSItGQES82TfGlrzf7wkyz+9Mrl2QgBKFToqtRGIJNH6w +AACu7exs4xD7A/iuAAS04AIAAAAQRk0sLUuMJa1ZdBfAg3MNkZjuUjGl8j8AAAAAAAAAAGiejOiJWhvDUIQZ+cStIlPEBXjFUWuJ/y4QSpoKY8tTdMqvU9FfQRjdeDT7 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAM3EhkvYTBX+OYYABLzAAgAAACschifKcLCsg9eL1KaZap4bUTtGyUKyGwAAAAAAAAAAxasqA6JYDNRZfb8UFHjwsJ86j6LO5pO008JHE1hinOiGvcFT5ms/GMfowUA +AADtjmjE/SjRXGm9AATEoAIAAADpWcsIJjhutzPI2IbHsfh+ioRrNUcy1BkAAAAAAAAAAO1gHyh8+IQmcQ/clbfzVr6Wa6F/COOxRMSMdB/crB/rZNHSU6KuOhjH/Npj +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ/paKytYDYILJsABMyAAgAAAEuyZ8pIcmsXvKjPNFPix9R3jN77JLYRNwAAAAAAAAAA0HVwapChfrS7kATPXIvGW8UvlaZ+0jTBsPWDDotgztHAWeRTYro3GLhc0aY +AAE0F1bcWn2c11U6AATUYAIAAACiw5fpBhLcKlyaQObfcw79B20LbpkfLAkAAAAAAAAAAJ2aASe6Uu8icLpRGmEQBC6asItujpoOKkDubRXc8ugefqHzU1gcLhgmDweu +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAV/Qtm4MwjfBBVMABNxAAgAAAIMydamRcMYeB5Z47Pzprig8nd9mDRjOIAAAAAAAAAAAnXjv+PifVWtOwtomH2mUmLmR48Ul8Lb35TuNt5XlPAxwrQNU7hUoGLGpWOM +AAGSHBls3JawQjhAAATkIAIAAADqk8Ja9r3BmT4lRpKN++40NuECrlN90xgAAAAAAAAAAONJaW0QOG0g/swxcTI5Y5Dja9+7gfoEI9AGaOK0HNIRMKQUVOnbJBhKVXAa +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAcjPHUJoPaYQ7mAABOwAAgAAAA9q+TgyCn77NU352pjz5cCh3gcVotEHFgAAAAAAAAAAurpQohFrZQIrQ3qckSyD0Yw5oWHYjV0mEBFBPHlXC3NQhyRUk7gfGGnlcCs +AAIIXQzQMYMX3DJQAATz4AIAAABfim6ucWDYDDzRcTKcq91Q9mEwUkTiyhoAAAAAAAAAAGNlYsg+8U5nM/D07mezkVzm5if3fxIYMMjo7wMZlm3SKs42VHNpHxhfVFYE +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAkiLOZPP8kB9Sb8ABPvAAgAAAA8lcVvKmmBxIoxOgpDd47AZErqdGDBEEAAAAAAAAAAA+ZzcjJe1sUQcTHFTL+ygU9AAN/ZqR5m27qGQ9iB8glnhxUhUwI0eGKzQgqg +AAKKh4BnqEMeRTn8AAUDoAIAAABryq6Of7GLJ3NZ5TWvkiCqj49tO3NgohoAAAAAAAAAAPhpvLQRDzvi3PmC/oX5D4hFa798Pp++VaYGBUfacUbbx4tZVDDDGxhLrvor +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAtMlYHHuRGNjeXUABQuAAgAAACvbsTgLR7XHzHsTmZM92KGznGqG1VqSCQAAAAAAAAAAlHJZ3Zz3mU7NDHHXxwXLB3YQZKdiJlASVkDt/Z2fXhgktmtUYUgbGFEbPNo +AAMdCeP85TvOJPIDAAUTYAIAAAD+31BVesiYSho2I3lIOvZK4kMuuaysMxEAAAAAAAAAAA2KxHtLwtB5Iczh5LrDq6xugBYSJ5yiroqMNMfqbCkFOU5+VHR7GxiFv4U5 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAA2ZlBMckFMhyqmUABRtAAgAAAK8kbLOtg5h6jDapnQbuJE4gacp2SmvGGAAAAAAAAAAASqOEMG+7jTGfP1VuYrbbSYuwodP6T92cmH9yRRYIIddwCJFUfN0bGJc/g8k +AAOuvnpjW2Yg+9FGAAUjIAIAAAD5GNf87na5jTBRWxIHX81cw5YLIu06sRAAAAAAAAAAAKJQM880j/xFqgWWD6wicStgyihqdNDEHQBZijlxQyqylPSiVMoNGxh8Hgue +AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/lD3Qs/98AElFAABSsAAgAAACtq9ORVMfc0aGfSPEdOdyMO2s/h7BQbAwAAAAAAAAAADPYrW3CzDRbndof3QI9hAhYewnAO3VuzYsDfBX84ndmpBbRULwEZGAVoffQ +AARJ40ILi2s9531gAAUy4AIAAABUx0Uw+/UR2daHbXfkXqth2AXTyCekvxAAAAAAAAAAAIVkvibj0bsg3IQLFalyFxBhHG6W/Ob16bbLXbrsMcxNUrDHVMCjGhjD2lhm +AAAAAAAAAAAAAAAAAAAAAAAAAAAABJWROkYBVop4nQkABTrAAgAAANwK4VythzFi8n2y/zPZ++IZOqSS4enRBQAAAAAAAAAAM5Fnwr3wT1qnqlaxq4klYZ59hR4lhtdxxRlALGQO1eff1NhUh7sYGGScelI +AATnFNcvmhfCEIsUAAVCoAIAAAD4QZrnTwgYXJxMZzomI2kf6UfWS3gwng8AAAAAAAAAAGviTewuZJ+ALDtXrEvc2ilz0Ae5pCOcQAVwdqd+i0xz6WrqVDqNFxgyfc4g +AAAAAAAAAAAAAAAAAAAAAAAAAAAABTyuXhtp07W4EsUABUqAAgAAAOiGDDVgHpZlrulsN9ZKPpqVS27D4dM2AAAAAAAAAAAAmCAewlc9EBODVdtoIK/Z/HmNF1fZyfzfIhTsuxC8JkclmPxUwC4XGLEWlow +AAWTpGZSBCtYHUPeAAVSYAIAAACo7EaE50E1m38zUaYbSRK7GcPret/JPgsAAAAAAAAAAN+76k321Ttgblny9CWJGm+V8jHBXT7EA9F1tdmbktOb+1UPVfKIFxiUXtM1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAABelN9d0/GkHHqWIABVpAAgAAAERovMOEodvAUveIziuPFEwdyOMi4kzSEgAAAAAAAAAAdM+PkRV2uDurhjidRPhb4lfyhDfWpioL8l3Hi27pkhWRxiBVcTwWGDR8enA +AAZD91v1txqyGqYbAAViIAIAAAB0xRwcxTqvR4xkO7YS2mvReyaM2b3MxAAAAAAAAAAAAMzAomGKH5c9+sN4J0NbRjq9GMv9DygKkEMtPXhJejbMAvMzVfAXFxi3Kh3H +AAAAAAAAAAAAAAAAAAAAAAAAAAAABptDd8HqXUoNLp0ABWoAAgAAAD+ZgUo20qIEOx1L9hpBD3GCjsod7L9WAAAAAAAAAAAAs3Yu0nisRLuVPiQmLP65UtCr5tO3+LdP0k4Am5a2y5ZdZ0ZV3RMXGGQ2550 +AAbyn0BqaMRnY/EsAAVx4AIAAAD2RpmBinoT4pBhSm1/93RvVJDm3MrRdRIAAAAAAAAAAEuJqkMTnRSvQtA85jDmCibXYY79jW3Vfn2mE1CimTZbAW1YVfWGFhhFIRcL +AAAAAAAAAAAAAAAAAAAAAAAAAAAAB0wc5aPzQI9NXi8ABXnAAgAAAFayHnHJLoe1ekm6Ofbivky4E2QM6GqBAwAAAAAAAAAAgsy05NqIg0YD1Sn8teHGyxYwrB2cQzDhDNJCGChXHeKxW2tVixoXGAk8zIo +AAejX6SPTLkyaECxAAWBoAMAAAD29DiiCRqzxKMc2pQxVQkbUg9XJDKVkg0AAAAAAAAAAHzG9cuYYQmV95kdCdPiN/nipIbtjwJbzlnj4M3cUvc3Ywl9VUMgFhi2Ml5r +AAAAAAAAAAAAAAAAAAAAAAAAAAAAB/583srgXxQC/5QABYmAAgAAAAY8LvkBa/MqkE7q1ip8wSDP+jzyQxlyBgAAAAAAAAAAGLZGHesNTZ/JxmOhAUdDMq6q93UMx7AD+3HgSU5QPYwunY9VjkEWGCawfto +AAhZEkG11cDZSx+GAAWRYAMAAADEVA0hTsdntv2BMSH7YQNBAsw4/vKaHQMAAAAAAAAAAPd272QzhiykKFteshui+Sj+XFekHj9YlkOep5WBi2IfjnuhVciGFRgox3uT +AAAAAAAAAAAAAAAAAAAAAAAAAAAACLa5dpAq9Nn48a0ABZlAAwAAAHU+RwXu0uur8OPsaujIVRaWlGnvE4ouFAAAAAAAAAAA2/TnG1SJE/7xbgfTSiQ09uOsZ8x23g14Be5VXD60twG9hLNVFQgVGKeDPec +AAkWlKuZ6iMxEO/QAAWhIAMAAADnlPPiXnH9CFZzKKtuau83Zm10erONegwAAAAAAAAAAHZHfpKkuUHl62wICqHNv7q1FFlwPkxkNjhO3yfEE/hzwtbFVQTdFBg6fjkM +AAAAAAAAAAAAAAAAAAAAAAAAAAAACXc2AkhRO7MS9gcABakAAwAAAIFaXm3W5M++F/jW8iAN9JqkcWzGd0iFBwAAAAAAAAAA/qclgvKJZsQjJtuoHwOwuJn6mSmEg7LRL/Jbd2Wqg/gnx9dVxEMUGJoRcYQ +AAnaslxFZ2oPdv/9AAWw4AMAAAB6aDb6o44WSorZWegzgtP03rmuEC0dzgUAAAAAAAAAAHzLZzcUwL2LXqKQ8ewJIinFp5b2aE3C2NfshA1FQ3I9w17pVcFNExgnIqOG +AAAAAAAAAAAAAAAAAAAAAAAAAAAACkMiekjSHIQoQ84ABbjAAwAAACrzpW2NWttlMXEuSqrCndlahXT+7B3HBwAAAAAAAAAA/k80rrcj/flu8XOhM6TYniPTWzD+r3Oep2jolrH5X/xsGftVuocSGMfVRn8 +AAqv7nbV8gI4gQVWAAXAoAcAACBnp0LqRjXO6+s3Xmh8h2kFduYbFjRPzggAAAAAAAAAAOx90gednMp8jwoRnPuL430VF6vl3TCv0MKRTfo+8Jzmph4NVnIUEhhp7WAg +AAAAAAAAAAAAAAAAAAAAAAAAAAAACx9v08rIb3XkW4QABciAAwAAAPndV72eXP37d1UKk1jLukfrgjaE9DNiCAAAAAAAAAAA0errvD27B9WcD0tpr7mVGODk/GUSwc00lbO268usJ6PPjh9WFA8SGKygBbE +AAuPEqIEXhjZL5S4AAXQYAMAAACAFfcaPPZS1o82T4h404hrPHb85O4EqRAAAAAAAAAAAFuabbGwhWZQ+jLvOayxrCx1haRssKUd374jDMf82FoGop8xVlSpERi5kRXr +AAAAAAAAAAAAAAAAAAAAAAAAAAAADAE5GXJFPoIp3rIABdhAAwAAAC496KiZK1s0fBTXhIz3ok8tYp10VEcRDAAAAAAAAAAAULuwO/D3XsU/GSvXfXbkqvoZYOgBWAbb1TQZeAf66AtUFENWibIQGBWTkbk +AAx593VzlH8jtrJaAAXgIAMAAAAd8AR5EiSXrsmLHjnhvf+uiZrMMp4DpQAAAAAAAAAAAHS7CaZQHNLKgrZmaLm472N/XgfLjwnI8WnyGL/wNEBNrsxTVnYeDxgcuacc +AAAAAAAAAAAAAAAAAAAAAAAAAAAADP9Qj+qAhtmA378ABegABAAAAPpzN38/WEVF1rU1Y4qkzBjDWTKbPbewAwAAAAAAAAAAUhx6U10tUrxNBga0frLL5UMRe6aqd3gN72T7NjO5JOYsxWRWT+YNGBuYzk0 +AA2QXhCcuWjDvZMgAAXv4AQAAABCUOD+y5YCqA4X4Ek7fhzNDP1lvcW8mAEAAAAAAAAAAFQt2ikzPQa5wHMP5SPZEzw5Yt6yFJIbTl9QVsVyqR7vqWd0VgnECxhMqn1Z +AAAAAAAAAAAAAAAAAAAAAAAAAAAADju4tv6f2pk3mtIABffABAAAAOfcE8ZCFMgCu3ypCQg2H0kTFNzTefNgCgAAAAAAAAAALhIGqSkpDbRpro29pIkUdAtWQpuOq6VzG3OtGSgjWEOiBoVWkZUKGPZM5Kg +AA76M7POkqug+Z9NAAX/oAQAAAAHKZZL8pX2fjMkS4/MHTd+3Iy6+KVziQMAAAAAAAAAAKSFN4eizDLUmtQ5PfjBNPpmfmpaQcJ+wjCSqsN+dzFhKvGVVhuzCRhZxxSe +AAAAAAAAAAAAAAAAAAAAAAAAAAAAD8oNDmOZKDdek+wABgeABAAAABl7Hz0vrMIBb4wq3Pc6KgU9kXQZR+y4BAAAAAAAAAAAMvLuIiO1KPqDlD7xoiAPG8oobWVbgASuIAfjNCU3Azo5ZKdW8CgJGDpml8I +ABCmKY/w5K9ccX99AAYPYAQAAADE/juFAwCo8NeGCeT0q8etEEIc7y5XXQcAAAAAAAAAAN17xvJ5b6zUu6ZM4I8ALN6/1Ga9wQD/uegKKCxXpIeROMS2VhShBxgC8+Oh +AAAAAAAAAAAAAAAAAAAAAAAAAAAAEa5tbpLjxdwAs14ABhdABAAAACC8szE0pv4/mPBIgrqSQ8eNZAf8255PBwAAAAAAAAAAqo4m15PBp3RIxZEjyGD4Qqqr3Js2Qyheya6UD6S50Q7IC8dWn7kGGPSa1+c +ABLaMjZMj0fVGWBNAAYfIAQAAADqsdQ60ilyN2qK707hr5NIfzorxtmkxAMAAAAAAAAAAAdmm8141IyLhH6c6nbSJ6VrVLyibtpcSvr9VSpQoK+0hBnaVqjwBhjZyz3h +AAAAAAAAAAAAAAAAAAAAAAAAAAAAE/ywmImZMVyUXxkABicABAAAAEc+17fvL86CjDGP1eWGg0SlNWyek7YEBAAAAAAAAAAARAnK5bey+PGOpV9VjJv6fF9HeKGlMXKkj8V+Fy0O09JkxetWw6QGGK+bwcc +ABUsJBbzwzhj/RTNAAYu4AQAAAD37yiBuKDLQVuoHoicebxfGwmBZ8lWRgMAAAAAAAAAAKSIaf6NZ3eCH6hVJROct30SxEDBYYLGN+lD3+p9k32qexb+VvSWBhhWKCct +AAAAAAAAAAAAAAAAAAAAAAAAAAAAFl4V5jC/6R3eYnsABjbABAAAAIlRbEtuN9WAD5+eNgk6K42oQNes4kVWBAAAAAAAAAAAm00/XiFD8aRUKvLBdngKDFfvZoOmGF8cX42KHZRZsuQFVA9XSycGGFyWh+I +ABeltF+z3kz9tZTwAAY+oAQAAADR7x73u97v/1ByQ7M+/tZHZYwwOKHmgQMAAAAAAAAAAETWTugwPNlatypt7HduiToghEoXJhzY1x2YAHP6aZITrskhV3YnBhhaaUYC +AAAAAAAAAAAAAAAAAAAAAAAAAAAAGO1Nis4eHSp8hkoABkaAAQAAILy4xP+rEEFKda1OEL/rsV/mAiG73QAhAQAAAAAAAAAA7spLOmXH09Gq2vpd9U1rvs8BmDD6pURgkEKdV+n17kNixDJX+qgFGEIkoas +ABpRfLdgJt4nqRNjAAZOYAQAAADmLvKMuXk/T5zSpnpYwee1kxKbm+VWbwQAAAAAAAAAAGSfiOKI1oe8gZu13AlKjE939fRsL2osAVIllw97PFFXdsFEVzaEBRigCrKE +AAAAAAAAAAAAAAAAAAAAAAAAAAAAG77vy9c5V4owbPUABlZABAAAALuTLJCG/ER+7dJCRU1Fk29H9JEeKRy9AQAAAAAAAAAA+ut4EB+MKmwAS2LhNGhnWbdSZa+kGz/MjtzfVc8AMOP2hVdXoJsFGLZ8J1U +AB0mcOta9RlcQHkgAAZeIAEAACDNHXKw/agnsGcB2HlbfO3Wb/91M0h6wwEAAAAAAAAAAHO4pz6FxGfyz45cs3SgR4/MpfRnt7UwhSKVEaFATK6uQs5oV9Y/BRgO0kEv +AAAAAAAAAAAAAAAAAAAAAAAAAAAAHqZ91uuCmfAkLA8ABmYAAAAAIEIuw56kJg6/QkIdv4YzV8SYUtrCtAQYBQAAAAAAAAAA+d6fanMohD338aNyRR2FTOhDG+nd5oYw2VqXc3B5Vw4x7npX/SYFGL5xp1A +ACAtxfsiGV2z0xFqAAZt4AAAACDh2VuHjAFXFHz3IpMZ8BFDKffxiHj/SwMAAAAAAAAAAGA+JCR1kdW3pIFA/zuSI+PMFCTWoRZ0YDqTbhQyQcoHwmSNV2kmBRh4+yfw +AAAAAAAAAAAAAAAAAAAAAAAAAAAAIbU3UuafPrmByNQABnXAAAAAMCFiLCak5iyvqOQ0x+CD9UC8zIOSPLQGBQAAAAAAAAAASPrFuiKivUisChkc0YERiNDYqN7iBWl9KaQULc5m76CC66BXKHIFGP2zdM4 +ACMnalaEJ1NTfQI5AAZ9oAAAACC5fXDa4zD0YCudAQ8FeDmjUAea4WhwkwMAAAAAAAAAADp+YYP4pmo57SYqnmIshNH5qkvcEszlYEEz5KjgAfqRAhGyV9wOBRgYcYix +AAAAAAAAAAAAAAAAAAAAAAAAAAAAJLX90NyOT+8b7RgABoWAAAAAMHE5ro9Laxsg3t6njXhscKpluZ487PbiAgAAAAAAAAAAboCE3Oxi684vhXiVptbvAvzvyzJieT1bGs4VZjbFBeR1QsRXCPsEGInWxnE +ACZKxHB79ab4pJEeAAaNYAAAACCxliE8dmLJ4CSzvJX4FUO7YjWxNmYHswAAAAAAAAAAANxevoKSYvotUK1wKjEkvrYhWtFRgroZhfZ6HQEdJRcMi03WV17eBBgvWejH +AAAAAAAAAAAAAAAAAAAAAAAAAAAAJ+jcj2lfxWD4XfwABpVAAAAAINW7sFLjGBZUzrMQ7AUCO6P7DB0dlrglAAAAAAAAAAAA/ayXTCM0rFWj00ZfmuJOkFBnJ4s9i8s4WHrgaHNjVYwHludX1I4EGGWaxe8 +ACmjLx/5YpHTniFvAAadIAAAACAlCbO45PmCkMfJVR0YDrKkY/C5eIvVIQQAAAAAAAAAAKqNoGCd1mcCs+i1I7Wi1Lv1jroo7bHepqVSZRYRkszZKtD4V8RABBh++Xtk +AAAAAAAAAAAAAAAAAAAAAAAAAAAAK30y8VVXed+krAwABqUAAAAAIKMujidFUhagLUcEs6PEcxzzQRfUaNl/AgAAAAAAAAAAlI+kZULC0xo3cz3KA7LMgv+twGf9YDR59k13P8/BOAHSqQtY0lUEGD1O47Q +AC1OOf5J2N/elcOrAAas4AAAACClkM9dyJtNLsIhRAlyMdEJwKK4hDGiZAMAAAAAAAAAAKN+LTmq8x2L18AKB/qXhP7oirNhCC8DYBEZ2sSg2HyNAg0eWHRRBBibZltl +AAAAAAAAAAAAAAAAAAAAAAAAAAAALyEdcaQ91y5UNHUABrTAAAAAIP9y7mmnjxQuT6V01yV4QGBAQgSl1C4qBAAAAAAAAAAAdTuwAfXh0k/1pX24J3iwqX+DHf3qF2E2reAWLTXDUKwXvC5Y1OYDGGvKcBE +ADEl0i+0xC2+0MbMAAa8oAAAACDTxa+JdxdIkPF+GouU2Rntb4DyE592XwIAAAAAAAAAAC5Atl/p/FL5QjniJgRHOm9GFoTgaEkkyfndzyMUoN6hguBAWInVAxho9k9N +AAAAAAAAAAAAAAAAAAAAAAAAAAAAMzOlsAw+jbUeSS8ABsSAAAAAIP9Fx4PQlwbjWdzHYIPhXlGDnk7VMf+zAAAAAAAAAAAAhBWXC9zINSk6EQ7iOHl0Sz4VOPUZo/b5CY2i2gKp1DPB8VFYhYsDGMbd/g4 +ADVsV7hkrnpwZcyeAAbMYAAAACDwZ24cV3C7qIhqq9iL/T7CZs5oI8vNHgIAAAAAAAAAABjU10kV7C0+g1eqjT5QD4ZeokqZ0NKsN41JYm5nuMmzJ/ljWP91Axh6IlTj +AAAAAAAAAAAAAAAAAAAAAAAAAAAAN7LdI8imfC1n6esABtRAAgAAIGwSCQS+rmn9HH0/cjo/3MEnK4Y7syyXAQAAAAAAAAAAG6xGqmcn2t0qN4wGKPPpNKji19H5M8X3xDDaCB2rQI30YnVYeUMDGCBWJMY +ADocpOmmgGMKNFU2AAbcIAAAACA+evIAa711Ial9nNhBzAxngI0BsdImywAAAAAAAAAAAI24Czc2VsD4Mg6PTX+zNtohrAfjoruMFLnRJPSjLyRnxDeFWEfMAhh7mQNN +AAAAAAAAAAAAAAAAAAAAAAAAAAAAPO0yNWM3Zd6DFZ8ABuQAAAAAIPQhS2Frg0Dn97TWDGmcks3KZi8CtN52AgAAAAAAAAAAiVJT99qHJDgtONzJ3QWqdigWfa7xPL4tmzq1a/6JeRQJZpZYuZoCGDyEBYY +AD/zSsNCs+c6akJ0AAbr4AIAACAXD60LaxzL3EQB17HI7oaMaXfWzhJ5WAAAAAAAAAAAAOYp8InMviL4HtmJZ+qXbpQZa8lqYCLwZB7gwEnpTc4LEhaoWJN+Ahi5Hn+P +AAAAAAAAAAAAAAAAAAAAAAAAAAAAQxuCvmpdrroTxmkABvPAAgAAIMjntZu2g1yNm67rzNjOvR4ixGokmpifAAAAAAAAAAAA9f+0bT0HuGprDT1s1OmqW7otJTc0Jlb1Zzm7ZBp4xpdOvrlY32ICGFRioAE +AEZoYHlBPSBbr3gxAAb7oAIAACAH1iE5ncNJo/fFTdZtBxMs6MSJi+2LAwAAAAAAAAAAAEguaQj5jPDyXdaqhlieIH6e4iBSliCangqNRT67w1A0/5/LWLFPAhhCxCu3 +AAAAAAAAAAAAAAAAAAAAAAAAAAAASdCjF0PBCmGpHMgABwOAAgAAIM22CnJMl/rkNppmRsu2tKWjAAdYffQiAQAAAAAAAAAA8/gt4eNk9haIilM1m27ilKGMfplAA9UxpS4JSlJAkQasNN1YWjMCGCqvtCQ +AE1kxf+UqjKJBDiUAAcLYAAAACCZ7QwAT9f0nw5QAqlk89D+vZBqpZ6tcgEAAAAAAAAAAFxkwm2ofXOccNo4M0KkS7ST+vKvrvhUEcxoEAL/sKsOpunuWHMcAhjUm2BO +AAAAAAAAAAAAAAAAAAAAAAAAAAAAUR+2ovHOfR5H2oQABxNAAgAAIHHcEMfQqHwWe7W/xZmWXgXHM7KdQtcBAgAAAAAAAAAAJ0FdN88XQHIRB00WnnZtGBHJLx8QRtIlCAesBI8DGZxRVQFZPhsCGJUhL0c +AFTc0w4mC90KhU9hAAcbIAAAACABgs9JpUR8CNbE/WGfkGy/79uKKptUwAAAAAAAAAAAANQNMFOfWTFb4YvHrCLuS3dwGavPGkXzJl6+H9boQj/TwIsSWaf2ARgA0Z/e +AAAAAAAAAAAAAAAAAAAAAAAAAAAAWN+aQfGjROJ7BnMAByMAAAAAIP33QLDknPdbs9UWj7NYb3YT3MXNiWdbAQAAAAAAAAAALjexRMC6ztB+t+e2TakWzTEh8kJwBVUa6w7GpkAqx9fw5CNZVNgBGH9dqfU +AF0kV5ADzGNCCJLEAAcq4AAAACCoGJH1orG0in8CAflT/1tGl12En7IxOgEAAAAAAAAAABngc7dr0++rCbkOMxmNUC6BwrSKgFVWaXqbC9Z1kGs2mxo0Wa+eARhX3jJH +AAAAAAAAAAAAAAAAAAAAAAAAAAAAYgDs+mJiqOsUScEABzLAAAAAIDRxEBu9o/4wdmSzKDqe8Ol9mjin6s2IAAAAAAAAAAAAEMirqEebuqXghIFS/TwiicpQ4cPljJpPqq+99YA8VEjduEVZfosBGOQ6gdM +AGcZ3nr5KS2Pc8sQAAc6oAIAACCZ1qcMVHu6oaggSQvQLMN407xuIEaUOAEAAAAAAAAAALZqCwJM/fB9Ddl+GK1u8aQRsEUhKdO/4+brrlXe/sTdlUJYWTCNARi8JgoI +AAAAAAAAAAAAAAAAAAAAAAAAAAAAbC1VHlBts/v41g0AB0KAAAAAINzyUXEESl09g/XQ0Hd09N5uawV/Kx70AAAAAAAAAAAAippCyKd8Z6MyO3OWBWg7Uf0eQZu0CnQf3LsRrzL6LSK2hGhZ3F0BGLnVA4E +AHHwiS0wpgoU4a2uAAdKYAIAACC4eVrYZELObYKJcY195BPnOHWbcXMDDgEAAAAAAAAAAC9LtwzWjKpXXeYF6TpIN+wGjqi8hahEW63uWpIUruMomsh5WTVHARjEptgJ +AAAAAAAAAAAAAAAAAAAAAAAAAAAAeBneqYLEiQR0XI8AB1JAAgAAIGajOhObtnBhHXFlSWGHd1utA9cL0eJTAAAAAAAAAAAAIHTVr57FNQxvzEtc3egS7kYC3VADiuBvpoiz/iJAkJ/iAYtZ4DABGEmnzq8 +AH62plJTHFrWpLjpAAdaIAIAACCAG4FikzS+jnr16/ud8JwY4fgztfDvywAAAAAAAAAAAEDRygd/7+f7eXcRuqDAY+ypuO2Uaa4BKJgrRK0MJThkkTKeWek8ARgi/1Qi +AAAAAAAAAAAAAAAAAAAAAAAAAAAAhRM0rQ/eSn6NkjYAB2IAAAAAIHgiBAzAR0MEsiaLi2ETMUx8HtaKY63QAAAAAAAAAAAAPHBQ/dy2bjCAUxN4OxKxLGxiwOvDI7kldtlIDgNAuYfD9q9ZCzEBGHZlzmk +AIuvP/EAUEY/eZ48AAdp4AAAACChi8JZfSP7eFbEyvTKqNeidphjQ6m9pwAAAAAAAAAAABMYNEx8WGnQzO0yKAG2lntPZvbc3DGn+5T2DU5f3XYFNGi/WRj/ABhT01Vf +AAAAAAAAAAAAAAAAAAAAAAAAAAAAk5ZuMkWegfzDYhIAB3HAAAAAIGGOQwrBaXdZmWK6mTSHI+ljg3wwamz7AAAAAAAAAAAAjevjOcHY6MwfMnguBFywUpB53mcF3tQCdMeR61jZrjICiNFZc/oAGNg1r98 +AJujLZFGK2U7jmYBAAd5oAAAACDZXG7YWfHa/yfFmfHx3LEPqrz/R4FAbwAAAAAAAAAAAHeJUflLt8RCKl7vCcWt2zkGOhJvC8pwh05/YSs+PSwzbt7iWTDrABgbBtzU +AAAAAAAAAAAAAAAAAAAAAAAAAAAApDXQLsMq2RWMZAcAB4GAAAAAILTqnh6WGa/Oud05PH3UwJJ3PTT3PL7jAAAAAAAAAAAAyGPTxj6JnuH24yDnOxsqf2612tVqx6XhaEIaky3v1RvaEvJZvcEAGDAZ5QM +AK6dnX5YX6bYxakBAAeJYAAAACBpopofHqz8DGjp1cH5IH5ll/He1gn7swAAAAAAAAAAAEcfGy5Yer3X5Jf6aFd7YUvadTrELBgixG5yiuiz8mMcL8IFWkvOABhGVPBx +AAAAAAAAAAAAAAAAAAAAAAAAAAAAuGNcnvlUimjokoYAB5FAAAAAIJgq/Gr6gF4hKu4jpbPfL7ThRUEEH+e/AAAAAAAAAAAAQaER/QydVgtaVlZAzZ78ZmSQKwpPGhx2PWml+L/P3GOseBha9tAAGA1uDIs +AMIJZ3KMyNccgCcuAAeZIAAAACBl165IP0v4xn2hf9HL0ZYPnORu9b/jzgAAAAAAAAAAAIqwdYAuU8F/SVUQIJH3F0Q8KyGIaWt/4QwykQuEUZIdeRkoWu2wABjQAO0Q +AAAAAAAAAAAAAAAAAAAAAAAAAAAAzW6uNsDO5WQIltMAB6EAAAAAION8gKeouFDj6JrdCQkLa4m4dEllE++JAAAAAAAAAAAAKF3ceYXnw06yBdLDEpcn97wQhz4R4FS0jRqSeGpC19LIyDdaRZYAGJs6p5I +ANrZM7W6oNFt8uZnAAeo4AAAACDdX5Qm4nuyoj9Y4VriMauNMXxBZ6AFMQAAAAAAAAAAAGLVx5fnY6BKSpQjKjfcc8C9mTHoCoOlzz1Xb5CwEbUZWrFJWsGRABgSLQaq +AAAAAAAAAAAAAAAAAAAAAAAAAAAA6K5YKD1EqCJTS6sAB7DAAAAAICOSKrd75V79Bc7hI5KiuTeT8mafow1yAAAAAAAAAAAAPLmaVOg1bvegu4VCHtjMeDc0WGeCNo18sK7V3gz+lWFisVlajFd+F0m3ht8 +APijmUI2IMbP+2pXAAe4oAAAACBM/YPL1ZJj9/n3BvEUFYY4ICzVy1eJagAAAAAAAAAAALp9U/IU2smDwyedYEAoN8kvXRZmTbNpL4oGbgFQkLGCtH1pWkYhbBflmY/7 +AAAAAAAAAAAAAAAAAAAAAAAAAAABC0jEr2O3ld4ANcgAB8CAAAAAIIEGrDx7jgNSVoCe/pSMOJQXVDJU5WhrAAAAAAAAAAAAzmt5y8eHiY2BW8GUJIrj8mGL69yzGvJ8meEkPV4oRjJXNXpa+OlhFxGNfUU +AR/fzayx9nuiacKMAAfIYAAAACDO+kcNtN8CqD3VGt9QEtvqAgOf6t7JAQAAAAAAAAAAAAJVqpnEuysv0y+KFVCd0QW055B31OyVHpJXOuquqbjba9qLWtyXXReVC7vR +AAAAAAAAAAAAAAAAAAAAAAAAAAABNWpOx24WsJHdZGIAB9BAAAAAINEEm2aSjIdKb05+5T9qYgpTEYF3qKoTAAAAAAAAAAAAmpL7GKZnv97o6q7pjbzbq7CSo8n1HvK4e5AnTVSEin++xZxao4lVFwStonA +AUz8BKngasmFxGtjAAfYIAAAACAwTKyssD5pyDS7/0vlMkowmJt4mKpnLwAAAAAAAAAAADezJ/Yacj838NQgdAlCR6Tp95q8LTWAQwdaZM9suE+3IlCuWklKURd9IESy +AAAAAAAAAAAAAAAAAAAAAAAAAAABZcjfruGehXpX3OkAB+AAAAAAIHnJk3BBzr7bvFGQ9txsW7In7pgjB18uAAAAAAAAAAAAc7/z/07xSLWu8tofmETNqnQw9zCV05O+u9OVZJqP/0jVhMBatypQFwyateY +AX7u8fTowemGBM0dAAfn4AAAACAYDV0zdLyxX+sWip70ujsF4q0gfETXKAAAAAAAAAAAAI1E1QMy+cLTC20QKlRrr7Af1S03Ni1yaPT9k4gGli3NZGfRWg1QSRdLHQYe +AAAAAAAAAAAAAAAAAAAAAAAAAAABmm7D0tTcr1iLp1AAB+/AAAAAIBBlYVRXbBcklZ6qCUwtvoczBLlGlNhCAAAAAAAAAAAAx+itNjFqFesRErh2EjKvY5ZP9sKLQdcFflhZdv+3YkxdCONaU/tFF5cf6UU +Abc9mZiFlmDZF06CAAf3oAAAACDWa9SFVsinzt44IaA0SBcTLKubNk3sGAAAAAAAAAAAAKtczARVeFx0TAiZB0DG74AGATVTY4oYVswDDRTv6Uxox/f0WqnsQxdBDCJJ +AAAAAAAAAAAAAAAAAAAAAAAAAAAB1OvWLfw+bKIVnmwAB/+AAAAAIHhm641RFUkMhZwN9hc7lmvExjcibEoNAAAAAAAAAAAAnk521PiXcelqnNPB919K4Rzqw044hNYGokSON1ln0hQ1vAZbSVpBF0Ib2e0 +AfPFgOhy1wDEwBC6AAgHYAAAACBqtiGOq5D48LeQU65Xa+B8IyHahrmtMQAAAAAAAAAAADlUYADGVX+lwB8xxK51Aof5PKccBvhJNPUFvzJh+wMl3tMWW0H4OBfe970O +AAAAAAAAAAAAAAAAAAAAAAAAAAACFyjAs+bgxJuVdW4ACA9AAAAAIBObTAEFqDSY+SmVzTOTVYk3zQES9B0DAAAAAAAAAAAAiWYE+g7PlbB2c3fFWwgB0gwBVdKZu7L+5itt8LR3OQntyihbVm83F1aEp4g +AjuG9ZjLnxX5qtizAAgXIAAAACDYzyjPVWQMfqZhUfRsLd3JS+GN/IvGIAAAAAAAAAAAAFHksafEa/I1XtqntoZ32R2wlMPh8K6/sbKQa8woDPSj/UU6Wyh6NBc545gl +AAAAAAAAAAAAAAAAAAAAAAAAAAACYfF3nSpii+JzWbwACB8AAAAAIPArnCiTSATGiC4fjIrzvaZGfSIu5dwJAAAAAAAAAAAAQG6h3I+Fwt6UjR/6um6Def9UM+iF79PRNCKJ2P0H7kOZZ01bF1o2F/ofong +AocJntsfncQRNhF5AAgm4AAAACD+Fi95ceJM/+CsiRaFFUEUz03k9JLKLgAAAAAAAAAAAKprEDp2Vq3kFitaooGc74BKhddkkRfoJqbsaUZb1sjhk3hdW3tPLxdc6RrD +AAAAAAAAAAAAAAAAAAAAAAAAAAACsaa57wGSETY7Z4UACC7AAAAAIMXuwpB5wmHcXhN98lX/U/CVRF/oPZQAAAAAAAAAAAAAQdXN2CNYNDXFRW5xMirPeZv/SKSxgXjQiJPUgQn3exYrr25bpw0sFwoRJFw +At9qSfVMp/iybC+YAAg2oAAAACDPsRJxflyQ79R2wRdtX1uoqpM32UidHQAAAAAAAAAAAFGjv1vfVTUk9oQdbi43LK7dar/Kp74eg7UNEIwO+tA6VzeAWy3XKReXHySN +AAAAAAAAAAAAAAAAAAAAAAAAAAADD5ljdm+jvpyDrF8ACD6AAAAAIM4r8Ln7pICk69ntuOj5XLrRRrUW5ncYAAAAAAAAAAAAZDdxdX4xiAf+Q8+maqMkCjutSDHPmFT2fTw5C5t2dnof7ZFboRkoF49xDNc +A0HfsrWhrUX/AS70AAhGYAAAACCke7zeOAAMRUgCSw8mtIrWKS8/eCzrJQAAAAAAAAAAANtrcrSw1Vf2lYZTvXiofzXjV7uhkbydtdfvFYJfbR9W+w2kWx9aJxctEW7n +AAAAAAAAAAAAAAAAAAAAAAAAAAADdRrSbF0eZnqL0KAACE5AAAAAIOKHO/4XOXbG/KO5Q6OM6EbMnXenuGEMAAAAAAAAAAAABrSzkdsvXRm0ceBbBxBKFndw0b9YPoXFmHV3cy6SJoYCxrVbkcElF3jsSiM +A6p/xq47klb8dUKnAAhWIAAAACDGSqyFPFpIQQ3a7mcBZCu5oKbb/qnbAwAAAAAAAAAAABrjq2aDGqfl7vaTs/7YYWxgGRjhdjRyh791ZinAmqQHG+/IW70vJxeCTESF +AAAAAAAAAAAAAAAAAAAAAAAAAAAD3fII9Bk8j640GqUACF4AAAAAIHvb97ZXDj5O8ijemT+JVZIWtn7tW8caAAAAAAAAAAAAfchXXCL0subnqachCxf4FsTNRMTb9VezxppfM4zmMgn4Z9tbki0nFwQoCzI +BBFmqAAfbeNmLFCnAAhl4AAAACBmF+NNB4n+fX0oF/2E3qKoyM3F6ZZXDgAAAAAAAAAAANfsscIddXjoVx+x2mAvgTWqjkMmq0LNUHDuzFOMrwTs/FfvWy9OKhdhIu7X +AAAAAAAAAAAAAAAAAAAAAAAAAAAEQQ0IZ5piPayieJkACG3AAAAAIOKss+ceTkQ69I6B04Hep9NeLo1eaf4VAAAAAAAAAAAAfyraIk3Er7pso3AQsJnAIyLLXfJPztsP9bh/s8pk7q6gGgVcfNkxF3Hyhh4 +BGl9nUzOC8OwGd2XAAh1oAAAQCDTstfWGtLZX/vVVtngDweHdCNgCo2gFQAAAAAAAAAAANGSdDosGQp0Ifkv7+klBVede47aVoys7hOyV1GscExmnYMZXPQeNxchuuPn +AAAAAAAAAAAAAAAAAAAAAAAAAAAEjhEPgYXNtsunZT0ACH2AAAAAIBILMmRWLUnfWcQAoPJ2RI2yqapL9vQIAAAAAAAAAAAAXLS1IVD+fewhe3TbQk5ELviyQQXCROuutZ9jjbnEjvPJTypcpRgyF7QSpTA +BLZPYwRzFg1IUIWVAAiFYADA/y9lULXa52VZWJ4+PhNSNwcra8SYlJ2mKAAAAAAAAAAAAFmIeDQ19QbSzPuttITlbW8dXf3UgGUKyuHjtD00ZOpzyvE7XDPWLxcdUI/b +AAAAAAAAAAAAAAAAAAAAAAAAAAAE4HQGNiE4OwmZEwoACI1AAAAAIGsFvSxKBrPYUDoDPCWTOWolp54dytsUAAAAAAAAAAAAGwjfPULNmjjYtmrfncXrRk9QNjO9hhCF//9yNjRTFZahok5cNWgwF79ntyo +BQoZ1ZncIovd5BnrAAiVIAAAACCuVddkC3OOHBYJHMc2ZlJuf6Eq9mwEGQAAAAAAAAAAAPeCX+BxQnX+VFIfZuiYz3Q+1D3ZPxhctijfmVgj5O4tfVhgXIhvLhdtCFpM +AAAAAAAAAAAAAAAAAAAAAAAAAAAFNYQO/+hHKOik6nAACJ0AAAAAIAzVNrPrHNnAKOCB8UVQBidrKTRnw+UXAAAAAAAAAAAAe8GydInbAchdOKS8bSKAYR6YBPUG2DrQDSoz69ZjmS92x3JcUFsuF0+5D1U +BWEBNNZ028ybHZsOAAik4AAAACAbYeiWFxCZGkf/gYfZRtk+T7M1acCWIgAAAAAAAAAAANAJhlj1NTHm5n/JRImGtaj5lNpC10YHnqvhD1XlYeJDED+FXBdhLhc1xK/b +AAAAAAAAAAAAAAAAAAAAAAAAAAAFjHk4zTwmVQeIs8MACKzAAAAAIBTDFGtoCLjQq8TG+e4J1+QHf3qjes8cAAAAAAAAAAAAaBSaYrk8LJ+R+6opc8obeboR/F7oxszp8Bhh6K0CzYJVzpZcbB8sF3f6v3g +BboqD0YQ/vPy0wHrAAi0oAAAQCAhMy8YgNByq9ZaTqGwn6zbMBFxp+fjDQAAAAAAAAAAAHGzphJHpM9riSBV8ngkfzPXb6kLSMdv2mn1gyaMuWX4rzmpXB0HLBcAIgYt +AAAAAAAAAAAAAAAAAAAAAAAAAAAF5/QTRjyJIQhdq8UACLyAAAAAIKokbst4Fpx+9nV6F1yj5YzpXSTBKWgOAAAAAAAAAAAA5H9jTRcU8XZESQJN9Q7KJdTxGBFc7yxGScmO4V4pR1BUzbtcEU4sF+FodXY +BhV1HVeWh249HUpfAAjEYAAAgCAqUgoJ8YtRhvZ5wz5zvinPnxERXFCyAQAAAAAAAAAAAJDPhQlQdAWfEiNUUxhvEUmEP/drtJ5rgoXJzNhf2QnMDU7NXDj/KRfWGLus +AAAAAAAAAAAAAAAAAAAAAAAAAAAGRXYCgOwMTrZydpMACMxAAAAAIL8mKzmNX3VTV/tstdzUNYUSklFs30oKAAAAAAAAAAAAXg97V3Je6mEva4j5ZtaigvlHtu1199PP5RILywrmIR3owt9cRfspF3wazVU +BnV8GunthUu4x0TVAAjUIAAAACDXdi8B59cAJ+SzQJf8rDogYOr1lKuFBAAAAAAAAAAAAHkiwaMxpVidI1uP2PSAZvDJ1VPm+H9LJkbMzj0NxXYueFzwXHa7JReuEDNC +AAAAAAAAAAAAAAAAAAAAAAAAAAAGqunmo5j/r3g6IVkACNwAAAAAIHPGpEqsmHgW89EO4ycU7db7Kj/7bbwMAAAAAAAAAAAAEDDd14USQnd7A1LqmyTKKRJX5/RvrS8PDUC301UJDq528gJdA/0lFzff4zc +Bt/8BpMe+l+0cvlVAAjj4AAAACA0pUTAWqILhKoJ/P6ZJlUA8/VY32WYHQAAAAAAAAAAAKQR1SRjcuTNE/r79SrUYD1HUiH5qda9A2NpSdUJXSEWEjEUXSx5IxennK4/ +AAAAAAAAAAAAAAAAAAAAAAAAAAAHGNHmQyphfkBfALUACOvAAAAAIKY5NFjwLLu7j+y6AmCkI7+YegvBtl4RAAAAAAAAAAAA5kiyphvNGYPPU/BqqQAy4tYuCjt4pPT4z0v4MMDb1rm8WyRdmw0fF9gy2u8 +B1m9nmok83qfrm9oAAjzoAAAgCDP8OB6s52w8x1N7YG6IzkXMVW5xXg5EQAAAAAAAAAAAHotddzlmB7EIaVN9wbT1Af2bckXDx4NbkjtHoocrXck6e02XQg6Hxe8Q7EK +AAAAAAAAAAAAAAAAAAAAAAAAAAAHmk3nyxGUfMU5H/8ACPuAAAAAIFJgCsjpvk8419GLrulxWPtxZNskjWsJAAAAAAAAAAAAqHU8/UU1cv/JTAQyFelgE/Hx/qILvtPYEMHB6Y1v5E7YmUddOTAcFwAWt7A +B+HS6cYPTvV6+snbAAkDYAAAwCD/aBvTWiuCtoAhxbQRpupP82voj93gFgAAAAAAAAAAAIDkuWjcUvoGa94vzaFmniQN1z6cVysCVsBwbetPXZvp5rlZXdGjGxdcc04A +AAAAAAAAAAAAAAAAAAAAAAAAAAAIKsOUhSdzUtnw2PsACQtAAAD/P0VXcqJKUYN+Br1Ogd7zKyrRaKhHDuIRAAAAAAAAAAAA1SgiWRKjFWjppXTI1DAFY0UlAdZRzmOFHGKDpPDhexBVLmtdPiEaF6tE130 +CHfrzMTnNH4hN5sYAAkTIAAA/z+HbkJNgw5nAYXntDFX57V72pTVvvZIDAAAAAAAAAAAAIaAZN99p5iv3Uy5KzLVIn4oJdXuWwQtoiPuVvR37fNGt+h7XfWrFxeUDV+5 +AAAAAAAAAAAAAAAAAAAAAAAAAAAIzRbR/iGI/l9ZVyIACRsAAAAAIP3j2ac1Ig5NYf3ZpkNjzR4b9UDccXgPAAAAAAAAAAAAfPvnf2DwiNoFXG/szY379s9yZjo2KTivQhkzE48VtsCRII1dJA8WFxGIndU +CSh7DyaX/kiv4GZrAAki4AAAQCBkJtVoaqbUq7I+EEmnUlsQDTY688BYFQAAAAAAAAAAAN8JpiIqwffNT/xQxjdHpDrq3zyloPsBWmA2IQWQQO0LdzufXVyjFReQWFDz +AAAAAAAAAAAAAAAAAAAAAAAAAAAJhabrEIiG9cLdUJcACSrAACAAIFrflS3YoVg2ydFIyfjgAepxN786RnYGAAAAAAAAAAAAXheD4M7C6O+YXWG1MRALAzL3CxZjnKG28bZ5OcpcQSRdybBd344UFzZDM0E +Cee2T+SyTIWzqlyJAAkyoAAAACAwzYQY7c/FVOgHRQts7iXBTtoSZjkkDgAAAAAAAAAAAMBIbtwe998H0gZ6M6rpIxqKxjCjoZalWQSeOQmxxfDZHKnEXdEgFhcHWk2u +AAAAAAAAAAAAAAAAAAAAAAAAAAAKQtGNsv/ycfUsci0ACTqAAAAAII4kTSxVvEA8ql1urw+SIXDkE+seAvsCAAAAAAAAAAAA4DtNnfctjbIyoguy/zXEM6mfFGfzkfdbX2IYDZbwbWqkxNZdPrIVF575FjM +Cp+8ywGs/RHkC2XvAAlCYAAAACBNintTpR6/Rnifd3mKRLpTtkf3SpB7BgAAAAAAAAAAAHMiuQ07JARU4fxwJSnQB4yP90UIdJITeDi20Qyg1qGFUWLpXdLbFRfl/eXh +AAAAAAAAAAAAAAAAAAAAAAAAAAAK+/dwx8gqcau67BIACUpAAABAIODxBdCTawrF+sHLXZ8IHW0bL8984AoIAAAAAAAAAAAA6I3BjhoTTFdod1AjaolLZuTtEKgEI2OyryDK6Ry6pCWdvvtd0LwVF1Ji8ps +C1i2W21eJGmELC2pAAlSIAAAACBhQw6GlSeLc+kpkzn8iZZFwb5N8t35CAAAAAAAAAAAAEEoFPY0abk13Y9PYgozJiGsehGP8W+ysLDDiBRgvvnxExUNXvJlFBcVxSxe +AAAAAAAAAAAAAAAAAAAAAAAAAAALu4xFyko1KZmrXGEACVoAAACAIFemuYtSHv8grz/jSh6DsFZ7ux5UuqwKAAAAAAAAAAAAEFJ4CPo9pW8TuJQR6c3pdwqSc9TK0gOJ9XTBLWwvc7DtUR5eeAwTF1z8mmw +DCViZM3ipYUuK6mLAAlh4ADA/z/MI1qZk8vf6Ti1S5hQSFxGtqQI3SP+EAAAAAAAAAAAAG15Ry3Qz4Cf9jJWW23i+wUfX4egal2vebuVQS81f0NDU/QvXv8yEhdhE5lJ +AAAAAAAAAAAAAAAAAAAAAAAAAAAMlCihmpueuL7Aw/gACWnAAAD/P0wgeNA4jjhE/mJBcj6VQwdL06l0wWYRAAAAAAAAAAAAC0OWXgagh7R3JvNaqIbfVjAFchW7RqWCFiQ+I2VlrClgU0Je1BoSF4G5gjY +DQOCnM/692T/c/vpAAlxoAAgACBpKU8xBXETUdlfq3ziC5HqY2sbxpLaBgAAAAAAAAAAAC2Podb2UVE3Lz98swMLSdirCyqr/Lp6GODK5wBbDTIfutpUXrwsEhd5M2Bk +AAAAAAAAAAAAAAAAAAAAAAAAAAANcm/pPJkLp0k0Il8ACXmAAADAILzbUr7TSftxUREv13onOjTCQTw1Jj8EAAAAAAAAAAAA0S+ONDCYoFgfB/uqx3MdKsz7sALjAaEfEwGWIHAOc+LtImZeGQERFzIKNgI +Dej8cVmdICmGlGmsAAmBYAAAgCAMNQrVauCVnJhLXbUm+wi+s6FYCIDGCwAAAAAAAAAAAHSgbycFfzUIokW6wOwg6yoHf88c9CrCsoU3LGXqo65Awhh8XkE7FBcTwPq1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAOTKK/8JGSYwqaQTMACYlAAOAAIEPjGe8IhTDcQPERF0e7f9sCY+PAnXkMAAAAAAAAAAAAeI8ZtFaswwzIvoEDp5ol80ijleJQxejQHu7vZLVCoNkukY1evCATFyGe5q8 +DrYJPtE6p0g5WpqUAAmRIAAAACAUOgCoJeMzIDa34vdMEznyR1cSUIbpDQAAAAAAAAAAAKlIg5av2zB0dTVJcJhbennqbQ9kisot+0OheDaM0jzyNJueXjOjEReyl0xD +AAAAAAAAAAAAAAAAAAAAAAAAAAAPKFasWU+oRz9z364ACZkAACAAINyu8wy5FLL0ZDGHwEU23rAgNZiG9TgRAAAAAAAAAAAAFU4/lAqhbH1q2litSHov5R5hGuAPiyPdk4GeDKfda5EB5rBeOXoRF4wdMsc +D5uvExILinkBRJMsAAmg4ADg/yfO2pclcPlRE5XVKCPZeF63mn30v+yHDgAAAAAAAAAAAPaDA4g+h9tjjVWtJ587WMHb07Mcfa1BoDJCANQd+z94wJDEXvaXEhf5l8cN +AAAAAAAAAAAAAAAAAAAAAAAAAAAQCBpyg2p5uWbCvIMACajAAAAAIGvDiMo8tmBmlVYXnR53AJcUNILJ2sQHAAAAAAAAAAAAnMPsWpHy4l0TYkO/4BWOdxVxyW7vQjdDMb9ofYf9sd986dheNX8UF3KJmxw +EGp3iH6JaGGCuz8LAAmwoAAAQCAgBboCfncZ/s4WkKcsLjW+V4vlPQoDAwAAAAAAAAAAALs0nxXJbP7VZ+Fc3dhRpL6RN6QfYphMw8iCNdqEKGL6e/joXvLUERcyQVAj +AAAAAAAAAAAAAAAAAAAAAAAAAAAQ24X0iTGAih0zL/cACbiAAAAAIJM642a37vHa/EUyQdFsPFESVmIAE/0MAAAAAAAAAAAAAREDBXQo0rqo8IvHAOlAKStseLaMVz8qV2/Q3mkkyQT5c/teGdURF63mtjI +EUyU1REypM3OngUzAAnAYAAAgCB898coFK4fvpBHu54gmeu1eEuspbAwCAAAAAAAAAAAAHQ93L5j0nbFj5FI6biHU0sUuxN+qzGCaK4mc2P3nQYZpEoMXxU6EBeWCMCJ +AAAAAAAAAAAAAAAAAAAAAAAAAAARyNFg1yiMlgCBobsACchAAAAAIKMCHH7UTuYThuV44WnOq0QbeYYuz9UOAAAAAAAAAAAAWvuDBNFFIXKxs4r0rsldVDFdqrbc86hgbGt7SYmBgzmkTB9f+LQQFyRCI9k +EkF8pCJpsBtpkPH6AAnQIADg/z9tCoMocT196c1IBJkoKNhgXJT3k1ysCgAAAAAAAAAAAPESYEteACbYsgdEuoUXLrDqFqut46D/RLAoOw+IITSkU6cxX6ybEBdqMa4t +AAAAAAAAAAAAAAAAAAAAAAAAAAASuuAqh569gyl/H5YACdgAAOD/L9mOuypqumR3k8iFHbUcnnlxIzLKZpoEAAAAAAAAAAAAo+F2KvViI8aOqwLfT2XG6YIRjxpK7Yc5OtVToiFzii2Le0Nf6gcQF6zAzVw +EzihxS/9MDJCHTIfAAnf4AAAQCAGq48tARXjK5m5ygIMjtFJqlySqsdXBgAAAAAAAAAAAPJaEbuOk1ZnpJ4y6SR6yn+dY6fB5QaJHhb6QWgMXit2KCxWXxI6EBdJ5KeT +AAAAAAAAAAAAAAAAAAAAAAAAAAATtOCmV6i8hqvPjM0ACefAAOD/N6VNMNQZqzYrGqAQfZZXkSKUYRjxUBIGAAAAAAAAAAAAlUkVk0jgrGHUBSMUt1juTowtVjjthJ/ETVpwki4QyUylxGZfqpIOFzpCswE +FD83ZUplM/sW8MloAAnvoAAAQCBUTUlenrKovQvyeNaLUYJBmxfT5hcuDQAAAAAAAAAAAIaxf5jfjr8MifLPauOJeh6OWDYxSUUPluG5E8hVh+rrWD95X96VDhf7Be0Q +AAAAAAAAAAAAAAAAAAAAAAAAAAAUyXBpaygvwzXLewYACfeAAAAgIPYi3hUXV1kLtdHnVKOS4E/LZzWi3uIFAAAAAAAAAAAA62jY1S5wdzMP1mmcLlfUvTkdyJ+8akyHyDAi3uZnYNbcFYtfThMOF0pfWTo +FVin/nTPxZEaUhFJAAn/YADg/zdLnpRRoj5nb9aeuWAA1TG1ZV/ig3PhBQAAAAAAAAAAAP7jjrVesvd94nsFrp03Zj496k0mgpUa+z2F/FaP1R7omhShXzPEEBcdNBS1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAV0OZJezgtWtOzUJoACgdAAAAAIO+5BV+JZrMQ6ZQGRS5txX0cPptDhgMJAAAAAAAAAAAAikBZDK692/SLpx/LGAv9yo41xi1R0/p4NNA6U6CY5zmHsLJf3f4PF2JXlDg +Fk7wqQvRa3I8HIU0AAoPIAAAACClMk0cUuhV+1lsN2AW0bLOzyOjOxhvBAAAAAAAAAAAAHvW0itHeUSYGKmni03ZQ4CQz/twR/T8aM+iCLhkzgVuGaXDX1axDheZrIxe +AAAAAAAAAAAAAAAAAAAAAAAAAAAW2CYwKbEdgN9lUOcAChcAAOD/J1RqECTIM4OurNn8D2+DVY3I5Y8oSNIGAAAAAAAAAAAAgXVhUchigUX0LsauRee5d5ifaP7Zw1eFzmGtD2K4yLJbmdZfchMPFy86zr0 +F13fK/nssCNHFGj5AAoe4AAAQCDp4pHELBlNIcdX51i41BvbBjtbfHsECgAAAAAAAAAAAIcgs1NcVR2veWwlmJK7rkICXTqwbukwNfe5scvzGUskkCDpXxciDxc/NQHe +AAAAAAAAAAAAAAAAAAAAAAAAAAAX4xikAoMFzO/glZMACibAAAAAIFLX8F3ve8aCbNp09b2vhV/hPNLIq6UOAAAAAAAAAAAAu7RF35tQ9lVXUt9+SNCcT129jlyOvzCv8bVfjtRNnoC1yvlfoagNFxR2Roc +GHax93pF7gaxq0XZAAouoAAAoCCqU8YdV933DGrl49Dn/tEwGvNAEx6tCAAAAAAAAAAAAFYHby9tEq0dadLbjJDzL1bca6HRgkdDHRIWmM7snd7JCQ8MYFeEDRdjn+Zp +AAAAAAAAAAAAAAAAAAAAAAAAAAAZC9fo38Y4p6rVzkMACjaAAAAAILiD2NDOfLQLAkj2YjZ94rqBIoWQk/IEAAAAAAAAAAAAJi5/fvqMuYL+uUO+E468qeHh6YqCccb0YnDdY8cUHZv//R1guSENFwvHSpA +GaVdn56xd5nImNufAAo+YAAAACAHKVwriCjnfwq5aifRmVw5M7Iuu3iqCAAAAAAAAAAAAMPe34CBzFKsON/ycucEEY0p3fNEZHYcCGAK7L4ZvypzBDUwYOP0DBd5TI71 +AAAAAAAAAAAAAAAAAAAAAAAAAAAaQPYUUdKV1pXXKUUACkZAAACgIK4h6Iz14Ir1mGK3AOuNtEVz/n2/LIQLAAAAAAAAAAAAhfB5tiRIVJt4ttN4wrL1B2PgoJLD6mnejMMr7//X/w/M6EJgjB8NFzA9m+I +GtqVXMqQe3Ns6MYJAApOIADg/y/0bK1WbDzJeTdiOFGeHwKaSoE1q1JZBgAAAAAAAAAAAORrAS9sz/29N1IuVV4B/HEQl5WopixICLmtrqR9Nv5HVQRVYG/fDBeoizkq +AAAAAAAAAAAAAAAAAAAAAAAAAAAbdzKI/wotYsUzi8sAClYAAABAIBxI2TVM2XZAfPBvNMJDhrkqB2f8NrEAAAAAAAAAAAAAC5eRr4azsCvqfa2DIPmznpy4HmxgqZ55O2QzYECDRlyhemZgSCoMFwRMLrE +HBzrCdbrVdEyWlGcAApd4AAA/z/mbi0FasGvYrNFR173cCsBqX8ZYNuiBQAAAAAAAAAAAOmmNMCtRFFdI9dL6JvZx2SzyiAlAMvHZxXu0fSBYyBi95Z4YJPvCxfASl8A +AAAAAAAAAAAAAAAAAAAAAAAAAAAcxc+IDtirZMC+DugACmXAAOD/Lw+g1dmq7HsnbZO3o4AIreC3PKgYXF0DAAAAAAAAAAAAkmWnO0TXjXtQOrTDXp7k7LhpgBJfKbYD5owu75VnH1aWuY1gY6gNF6hNUig +HVlvUHhtZuK/0YNBAAptoAAAACDh3dGZyflMEQKf8NvR3vmO7MEz9i2IDQAAAAAAAAAAAD75AXEYjGSu6ZpHyNYEaaakf00ekgDHHmPsKXObB4tGUuqcYOk8CxcuZVP2 +AAAAAAAAAAAAAAAAAAAAAAAAAAAeDNAl6A6ALhZxU0EACnWABOD/Lx12HTkMGd+G3AH5cMD1NmMXGnUojCQGAAAAAAAAAAAAJFRw1kQUoVxzM8riPD+pyqkstEkPYaaiFWYOCaoTTlPx57Jge18NF5Ku1m8 +HqOPm0g0EfB2QAYpAAp9YAQAACBzRspT3kPAohduihLzvxeIYTuJKERGAQAAAAAAAAAAABjAluwpHEG4GSBIoiOYvLyyOPteUqSlw3yjGKU2//kudGXGYPkeDhdfieEn +AAAAAAAAAAAAAAAAAAAAAAAAAAAfMk6xx2MWtDvH1joACoVABCDRKXxlqYQsEXAocLb9T8Kceg5DHasWyMsJAAAAAAAAAAAALQNSaWZUJsmWRNHPPN3hyqwU3jwHN7DCmzho6xZPAXjeBOBgzpgTFy8/I5g +H5ktq1x9uHtpjBQ4AAqNIATg/y9CDJuC938Yw8sm9bc915euxkMzZU6WCwAAAAAAAAAAADp8W223dpxHsusEUDSLQd0mlsdekJ3DD1VhohCRHNnkgWjzYCSWFBehiuEs +AAAAAAAAAAAAAAAAAAAAAAAAAAAf+xwRV6qgfCJHhcIACpUABAAAICns6rf4PKTyfyKsLw26tuBb5PKop8EDAAAAAAAAAAAAyl0wuzeveQGGxnyhD0fbkhc5b14Gv1No/krHbzAwU1UO0wRhomoTFzkM0ZE +IGLxQ5ggT209mY8YAAqc4AQA/z+UNYXSpcMbQedgEG83G6j+JomAmZkBAAAAAAAAAAAAALF2cIhIGcY/Y5hk97vS8iowfcasg8RKMU+1GnC8peaJ6wgWYQsYEhc3Dc2x +AAAAAAAAAAAAAAAAAAAAAAAAAAAg0l5P/tYepxS/8BIACqTABAAAIBbVs/dQsJvuXVaudmHUWF22vmISiI0JAAAAAAAAAAAAv4YlAP74Uu3xt7SHTJ39/ugnr7Adutz1avHh3hSYzjyMViZhoPoPF8rocv0 +IVCJbIepFmtNRMOrAAqsoATg/z9jvkqOCEjsMXZ5NSTR70jjJY6jcMsZAAAAAAAAAAAAAJ3FfWBYz4SZErDMatFIMKICRh05en60mvmWrgW1GboLNQQ4YeRIDxfArM0V +AAAAAAAAAAAAAAAAAAAAAAAAAAAh1G9rfXRUAv/VPooACrSABAAAINhE2HKRJkTQUI0NswPd6nfuyml5ERUFAAAAAAAAAAAAJBVPyehHgRBK0zJ/QHDFTtfWhc9K/hdee3LM0jY/D2d87Ulh69AOF0Ud0Ho +IlyBuc55IaovtRgZAAq8YAQAACAFDOUuzSPi2Pb5kdp+wxKBfvspFnUcDgAAAAAAAAAAADcc9lDs5JP/E+v1DrUxBRV/PfB8Sbd7hC7mhLrwNS5Rt49bYTImDheC4ukE +AAAAAAAAAAAAAAAAAAAAAAAAAAAi6v0suVIusxXbCP4ACsRABACgIFhJ7tgLMgJzpz05kzwDYOEn0VA2pp0CAAAAAAAAAAAAbMJQSBRQW7aGPZYFmcHR92pHaAkKwVsK1RcvWlzZGKFV2G1hCAQOF12qt54 +I3rVMPIOKThn6cAlAArMIAQAoCBR8ft4+iRzKcX0u+ahG+N51fQzm83ABgAAAAAAAAAAAETUrMchRjFlfJPF1mfN1qicGLS0C7DCbgGbGkIs92o7ovV+Yc/+DBclxWqD +AAAAAAAAAAAAAAAAAAAAAAAAAAAkFfgGGniATkVSlCcACtQABAAgIMy8xnRpPvh1HJOcDm1HKN3mLiT8EjcBAAAAAAAAAAAAd+wURzdfxoApq3qF/WmJxdMTUbYZ6PcJ3mggCBA72mpvm5Bh6mkMFwJzD1Q +JLheVogqg5I4QSKlAArb4AQAgCCYaz0b8w5+8goLpK5VNH1SoF2mQx+HAQAAAAAAAAAAAFYqLA5fUU4p4FgFXyc4QVmVT6Uv2B0WGqNdwgZnSnypMFqjYROaDBcFwXOD +AAAAAAAAAAAAAAAAAAAAAAAAAAAlWFoCJ/f6LtRuMSsACuPABACAIDnA7/DLyyWQmb+81cSgUgG6pN+0VIwKAAAAAAAAAAAAa+9mSwsJQyKa6kj23VYlfo3FPd2D4uPiOYQk7l6Ay3TZdrRhH6ILF68CAR0 +JgWl0Fc4/Nn+a9kbAArroAQAQCCpohVQfZ0fO2W1O3oZPcBN6cXTIQ1oBAAAAAAAAAAAAFzaGLaDJbBCJhFrfdLqB3wk1BoxulTzOSH0OXqbJY3zV97GYauYCxcN4mjM +AAAAAAAAAAAAAAAAAAAAAAAAAAAms37oNj5iOXWaeksACvOAAABAIJrKpdJtOSrOZWwkKMmRsKPT13OEWhMAAAAAAAAAAAAAqo4iWx8+psS3r9WqHOz2kai+qn+h5XnOJA5KYrWsjswhQdlhi4wLFw1cBbs +J2IQfm0nWPG2tTKfAAr7YAAAQCD2bam62hMXPCh+++QRwly9Is31ytPVAgAAAAAAAAAAAAw2QehCn7MDuLTZ1H9FDMease3xRr7LvxMavcDHyZ3imiPqYYCQChfSAidm +AAAAAAAAAAAAAAAAAAAAAAAAAAAoIOSp0kv6cgdNk24ACwNABACAIG3Zofz2R1JQ60rc+RvDpXp+dsE7yB8AAAAAAAAAAAAAzxm/IpxfPz3mVuxH52xwJBv2nt2PzZvFDxuWRBIrSgapkPxhtIsKF4lbhFU +KOAQwI0Be2KdOqQZAAsLIAQAQCD2ezB7HoSjcAtZ5O+f6Fc3QC9HNLbdBAAAAAAAAAAAACNBqxx1j+R+5YgHIhp7Z/xDugdJakEI7uNGmaqmbRQ0Ky4OYngQCheEVrUv +AAAAAAAAAAAAAAAAAAAAAAAAAAApqGAV0yCNut5Au+MACxMAAAAAIHdKt+UMoimzRv4gEAsUhJrm737gOR4EAAAAAAAAAAAA6o4MnaA3QoInckFY8S55NCdrHSRB1N/IkFX8Y4JdeuQf6yBiczcKF61GrAo +Km2zcIJk+5rOUI7uAAsa4ADg/zcGM/Q0Eq4q9j2F7Iq3DZ+Xo6lo7T72BQAAAAAAAAAAAIe+zpSjeKQXMSaisZtJWOwFvBWYl3q/ftaymsom3x3zeHIzYsBAChdHs5be +AAAAAAAAAAAAAAAAAAAAAAAAAAArMlTpyTr2JfY5Lj4ACyLABCAAINhZdCeteUXZoMLaVTBS+mjqZ/WiI2wHAAAAAAAAAAAABX6/orjUXG+e5tC5Ma300SrK4GuD0RuZBkrpSsqv6+g5LUVil9gJF9vdvS4 +K/8VHaXo7AiNSA2RAAsqoADA7iJ9hvh2gYu9NS80kfgz3Vevq9bPR8ylAQAAAAAAAAAAAEs1x2dX3wxdekio3Y60SY60XAHD2m3A0m0NCCFWFuppM99XYtn4CRdn8AxU +AAAAAAAAAAAAAAAAAAAAAAAAAAAsyUC80r5BYpgdJDAACzKAAAD/P5It/bnjeyVTTMl9uCMuezpaxa8uRcECAAAAAAAAAAAA43O12d0ifL6c+4gfsKSQW246TJKjccQqgVD5wvIU8vZDX2lidXIJFzCVuSg +LZ6oLGZ+LdD7/UUeAAs6YAQAACDiKnqJjobN73F94ZqE4fGLk93Ra2jHBQAAAAAAAAAAAFdidSeFJw1xm4LjZOuhn4o53kWJPr9Qnk11EUfoRJknHvh6YroBCRdN8kQe +AAAAAAAAAAAAAAAAAAAAAAAAAAAufnwAkDpV1P6cLEcAC0JAAIDcK5Y8CjIgeT+lLmCEr/R70k1gG66g/7UIAAAAAAAAAAAAx6dL5t7G2RYW/94IEehWwbui7uwyZKPOGw4J+Bw9MO8pRY5iIGoJFxrefCI +L1SfU1wu9n0DvayGAAtKIADg/zdLLg0yQjDtKerrIG42tiAkpjw+qgQMBQAAAAAAAAAAAGqXJAH8CsjzOlDMhhfL3qpYTy4jNI4XvXhpmk4de31i8IKgYmpLCRehJqwD +AAAAAAAAAAAAAAAAAAAAAAAAAAAwLYUxvNnoZnY8tDQAC1IABIAAIAIJKcjoqGM4IDL0BFyAtYy1iGcw54IIAAAAAAAAAAAAhqFb3qRw5/BKn53gq3DHnFvhAwJJKB3k8IW44bRmn3HxarNizIQJFxdn6uQ +MQFPxJukU2VxMFdOAAtZ4AAAACApa4oHrXf6puy7j32rMvUjTGRrfJWLAQAAAAAAAAAAABKnBBe1oFke1naU3WG6h+4aDnIXwuoVwPZ1LCm3a+ZzTifGYq+nCRcq/XE0 +AAAAAAAAAAAAAAAAAAAAAAAAAAAx0hwd4UZ8CVuRUOoAC2HAAACgIMU1mL1x46Enf/5v5mStJfy915lphygFAAAAAAAAAAAADUro7iDDCxt6u4tbKZdxznizdsf5dq1bLCxrYH5AeKeSl9liBCoKFw69pSc +Mph0zCx2KAMI6InuAAtpoABAsyTjQA9eJiBMBDJ6IThPx4BPlifrbV8JAQAAAAAAAAAAAGfrz/SA8MEfTHiLB8tcShTk4rD1I/EjnHH066hcM5Czk8HrYn79CRc8AIO8 +AAAAAAAAAAAAAAAAAAAAAAAAAAAzYkEqYdvmQtocn+kAC3GAAIAUMrlBmxgUAD1ojNN8ogu3Jz4+qEhuYXMAAAAAAAAAAAAA4Q3YTuONV2ZWbIYHz7v9ATa7ypK2vcpB8bZZMMS1dRyNHf5iiO0JFxMto/M +NC1UMGZLlbCSuE38AAt5YAAAwCDcRLXks2hCLaYzVk8TlLKI89Trk6NsAQAAAAAAAAAAAIrKOI1NRRpuruAK4vI9jRGDH/l+geGKPLg9S6iu9XZTdwIPYyAWCRcGkq+O +AAAAAAAAAAAAAAAAAAAAAAAAAAA1CzO7UVlqZP0og4cAC4FAAICoJtKVKKb0v2kEqefACHFDdeckveKER4oCAAAAAAAAAAAALudUbj56U+7QUb278jkz9oiXb2YMi2II0VaaxqtM16cC2iBjlMgIF13W1pA +NfC4fwu7CmvjS/Y4AAuJIAAAgCA8qGdg3veehG31Bkp/+B6WdcIbE+s2AQAAAAAAAAAAANqRkVp0BKEErH5aHxqf7j/VL6XZqZSiYkGXlui1zfU54rczY675CBd3SE5G +AAAAAAAAAAAAAAAAAAAAAAAAAAA20VoZpLjKWo7LJvoAC5EAAOB+Llb0v9+51y8QbyncrpG3yjdSIfIB8wkAAAAAAAAAAAAAI/SvMphv2FBkUipaj6a5b+xmvpxvzxbDrKWM/VLbolDS+kNjcucHFwrMGyc +N9BqErIv1larCSevAAuY4ABADSAPbmk9CFtEe4F68Ynbo9rRXVmYqlesBwAAAAAAAAAAAMJFkFlvtHWmUBEqPnE1vbxrGTymn4/PXMKTk6iqAyigg9NVYymkBxcyRshh +AAAAAAAAAAAAAAAAAAAAAAAAAAA42D7IYdFjgdoSe6QAC6DAAEANJ9I6aiUblDiBX4HjrJp2fgUmcCQ8+OYGAAAAAAAAAAAAmc6GaRbWh2ciPM3hJUgeCULrpYXOSCgz1pv3mfRUKH0rUmhjEqgHF30JZX4 +Od+M/jeZ+goRDKLJAAuooAAABCD5uNBGT3HY764ZKxRqn3A0Rz+pYoE0AQAAAAAAAAAAALKSZiVLd7ABMblq8OvwAnIJa/5dfcyEHiIE1oTQKmU8y7R6YxWeBxd9Qyhf +AAAAAAAAAAAAAAAAAAAAAAAAAAA66DHSvA3g40BnsIoAC7CAAABAIIkTjkDNi0gyvrgBO8gLFCXIvL4Q/CgEAAAAAAAAAAAAWKBqsO3FZTpqt4SQZ1qVT42LTU8TFyjc+WXNACKgLN3ln45jMDgIF2u+ORk +O914MlYVCQywQOE+AAu4YAAAYCAl9jB3+Vv+wJRGQ7qJb5czIA+BWlJSAQAAAAAAAAAAAKG1jcjAN/WEDaKsVmYhRpS66oJJv3wv/ESSGZ5JdSwTpICgY5D1BxeN4Rn6 +AAAAAAAAAAAAAAAAAAAAAAAAAAA82sGBrPK25nLUI3YAC8BAAOAJKIgZtxc+QCn5JwjpjQkSQi709EjgUf4BAAAAAAAAAAAAxch526w45JTQnygTm0LjpfxDvgO1DNPtxx65uCcn3pGarbNjfkEIF1rkGSY +Pc71nFqhxdGM3sXKAAvIIACgDSCnAU+3H5TwLNHtzLE6iNQna6ghMw9NBgAAAAAAAAAAABTS8UrjhTgl1hjhviTR4ACp9NXNQpIsAuRHhZFyni1sFmzEY+J8BxcOohVi +AAAAAAAAAAAAAAAAAAAAAAAAAAA+3DPp4poMSm9Hm3QAC9AAAAAAIFFKm9h8Ucrt1FogxJXwuhmDtvP1FjkFAAAAAAAAAAAAH0xgqX9BJ7T5D7t6ahBBiBsQ1Pc1E0C2dwMB9is2clzhDdZjICcHF8EcXns +P/YMaqVeSWh9G49uAAvX4ADgACDXJ3LRBq/6XxYE6SUw6GRrcrRgAj2BBgAAAAAAAAAAAF6NtFPHWWG5mETywmdlpgbVOCJCzD3uxOHmju8BYMfx05roYzkwBxc9ukAU +AAAAAAAAAAAAAAAAAAAAAAAAAABBDoPvLCc07wOMfkwAC9/AAEA3MUHhI6M7wZXkMP74qq91QNwWqXAmmsMFAAAAAAAAAAAAQQLVVdd+v7d1ctACyf7mwDoxAWhz6EXIlqCZl4UY1eCUZfljo4kGF78oMcY +QkLimArftIz+jP4KAAvnoAAAYCBQdTxbdUYAcOkQp7EYOi8g3o5R8XvgBQAAAAAAAAAAAFC4iIpS2sYKegNSZvC7aAs0KLxIRwUBW3+ToJB+JPEzmqULZIF2BhdBFqz0 +AAAAAAAAAAAAAAAAAAAAAAAAAABDetSwOvncOl7iyVkAC++AACABIGE/F/0kPR6FiEEReiSdxb9e3kJCancFAAAAAAAAAAAAEti0VrX0VjMWwxLVfFnxWkDXWAw0CVE26vE60d0Nc7vKzxxkPgIGFwdgrMM +RMpYQj+Cw7NCOct0AAv3YACAgCJ5elo7JPTGqX8DGQQ9A7MTwM3TrwDrAAAAAAAAAAAAAFvBXkz7kGcU1u4NWVistYFiv4bYtMGUYr/LYt21mfvUP+YuZLLgBRcMzevC +AAAAAAAAAAAAAAAAAAAAAAAAAABGIVaLDihaSQ5UAqIAC/9AAAAEKcwfAN7G1RsQNSwxzue18JiL639k32AAAAAAAAAAAAAAPCgeIfAmJcfE1w5q9jrKSgILwKGeb0QuEfte6i4HC2aNDEFkOccFF2FRyAw +R347eOKumIKe/mNeAAwHIAAAoCCTajoam/bxt1NV4Bbs9WODSc0eQ7hMBAAAAAAAAAAAAF6yFZEuLy84vclCw7SkdcyezDP2jsbESAIXS8n+p9o5B89TZAHdBRcaJvcW +AAAAAAAAAAAAAAAAAAAAAAAAAABI1hJZtlgyBP75g3AADA8AAIDcLEIAkExlz45VV11hq8Gj7SvZ0mv3UckBAAAAAAAAAAAAKEYWM2TayozqSRRAbVKpbqbv2pdn17sU5FpFN+dw+liesmVkOq4FF3kO8Lg +Sjj4snF7VnnnjPrqAAwW4ADg/z+/XYfw0AieOnF5JGfaF9tPbjvR8LJuAwAAAAAAAAAAAOwzpnTM2qgjyzUCeYOqLOidFEy54DBQ52zKOz+x2NiUr493ZGl+BReNvQNW +AAAAAAAAAAAAAAAAAAAAAAAAAABLp+9sPpgSAhqCQHcADB7AAKDvIWIeoqPngEnrUQF20xiFi3q2JYBwWTwDAAAAAAAAAAAAArYGF7UnRrFDuTx7kIe+6TMbpKeIj60hm9vrM6JRfKcupIlkbWAFFzqJNQU +TR7iCAG4NUBXaJBUAAwmoADADiCTtcyr4694B/aJ/O3CF+5e37njqa9iAAAAAAAAAAAAAC/rPNA8ZVT7RTdNcmLzxu2/a0ycnzzLak3PtHnW8l6sw7icZL6OBRdwxWwJ +AAAAAAAAAAAAAAAAAAAAAAAAAABOiaRUdJN+pMb4e1UADC6AAED5IdNUhPxYGUzabEKWxxiJlHjFwNrDu6MDAAAAAAAAAAAAAgTaiywdrGbA1FLTMDMWqxkNky7n7YNdQnyLjC0MyWcTEK5klDgFF3EoY+w +UAvEwwiB8eN5p+qxAAw2YADg+ixqPkmjZKL73JBN/8etNYaOXt+qLIzcAAAAAAAAAAAAALlxE2Ttb34s1hRSB9ijcxTQkI8EinHcfH+KSAuaBX6RsxTBZAJhBRd/hyrt +AAAAAAAAAAAAAAAAAAAAAAAAAABRgpBnxwWezzuJceQADD5AAAD/PxfdMYQ21mh1N2pVoQliw+f+HnyPGk4DAAAAAAAAAAAA6xUL5CSdEo/1ynPlvxy8uxJCbdskFD2ttqXZmcGlGHdEhtNkW18FF8Q5RgA +UvnSM1aF8mujzYqeAAxGIACg4yNON9vvLJPOG+8QTMyE7a7Cqqcw1nqWAAAAAAAAAAAAALXHmGx1iAsbhemb/3KdzFr4x+wPqr+KsSm/cjH7DZuId+3kZHsPBRcC8Jac +AAAAAAAAAAAAAAAAAAAAAAAAAABUiDKidOetzWO9RnUADE4AAGAAIO+2bgELpWdYx4oMwYqIBH2JQAqhhfkCAAAAAAAAAAAAvB7Swtb+Hg5xWdEyXTYmjDqVzxgjsjRRbMZ181/ZCAOK4/dkrjIFFyOMX28 +VgwNX8I6xxnzRDlsAAxV4AAgMinzC8ESCMjX5Ke6BmdJsMDFHNrCeMx+AgAAAAAAAAAAAHt1ajEaBGNw2KeDxe9tv6jOKQdOlHJgEJ1O7+u11SC5tWQJZX/tBBdjoTfG +AAAAAAAAAAAAAAAAAAAAAAAAAABXpSrMudRuk46mJ3AADF3AACDlMUMDUIDAth3RuaKYhJxWzqjEWcLagXMEAAAAAAAAAAAAkrZsXwVhQC51jBQcB3ZwfoEHLIMTS04dzI27RHXYqSuwyRtlD+kEFyO6bEI +WT+9IXpPVlWoPspxAAxloAAgMCgqC3zDvgFujUAxHNyJN8tS7ZwhlJPfAQAAAAAAAAAAAMi3jw6X9GL788lDCVfFVd2PhHgEcrWCxzIu1v/49VTyXR8tZamcBBd+5A1j +AAAAAAAAAAAAAAAAAAAAAAAAAABa9N5rJnOzslDloK0ADG2AAGAAIObcs3DVIUWPcVebRp1XxPya6TA9gVMDAAAAAAAAAAAAbLMk5jE8JjHFZ/aoI4kMfdI1hTbvH+roof4avtE4Nv6zKD9llIEEF+c9iOs +XLRDiXuwil2HwFphAAx1YADg/z95a3Hs5h2hUo/r29Z61yEao1h/WviaAAAAAAAAAAAAACIEK6PtQxI7jDaaXiQJzEEg98+MIP3r+5vn5NTHtZK4QfxQZRJaBBc7/5Jz +AAAAAAAAAAAAAAAAAAAAAAAAAABeg4cxOEHKa21hQqAADH1AAIC/MVzphFCQxJhnF9B6gouOtdc+Y1HzhcwAAAAAAAAAAAAAymONd9P99ynlOX0JRCBP1mh0XfIg1P/fUnInIjyQMM1DjmJlUCQEFxQsib4 +YGpD6sniSdqURUzjAAyFIADACSD9Cx5NlJq7+d3suazWHdRTprpaNqslAQAAAAAAAAAAAFdk61xUuiknwv0zGN8XZaV/PoJe4NQBTsVpgbCu7bYwJDd1ZZUuBBdqNUx0 +AAAAAAAAAAAAAAAAAAAAAAAAAABiTFo8h24+b//ZyAAADI0AAOD/P4L3qs9g+sOHOwvq3mHQcBY5CQrl9HgAAAAAAAAAAAAArLwbM4HGcbK3dTuyJS0+vWkASG7IFTzrEOlUqG4/nhRoeIZls+gDF/UXFkk +ZFAXlFh+9HJeUEH5AAyU4ADgVC/JTquIfmwNfcyMd6yJfZn4mJeYFltZAQAAAAAAAAAAABqlNemkv33MMX8UZcZ6udcypBFdBDJoiX/CsblUTLbfvKGYZWnYAxcBxkrB +AAAAAAAAAAAAAAAAAAAAAAAAAABmXFnrFq3AywXbfrQADJzAAACzKP8OtODUdxhQC3LGPezyDDL5ReS1sWoCAAAAAAAAAAAA4Um6cdBTvno40ozQqoOMngXhHc2OTr6PwYa+MOsE/AmD2atlWgAEFw4oOF0 +aFQyVBb0KxU3lxNgAAykoAAgeS/AdPjCCyHuGA0lB99vR9plhVYhhzVoAgAAAAAAAAAAAHER9quKvINhreHBJEeRIHoDcWUI4r97bXHz5wMiLM9yTg29ZV26AxdsyO/i +AAAAAAAAAAAAAAAAAAAAAAAAAABqcP5w8oczMMdSnbAADKyAAADAILLLacwRUAh1iojss7UAjP3Lmq+IM1sAAAAAAAAAAAAAY+LWS4Wo2ZsLDX/4jsCzxB1dAmffCUJq1+xXVJBZwM+uIs5lsXEDF1hPJZQ +bLpVSFE4iaADC9e0AAy0YABg2C/1Xm3RJPXfMwBNHjSIm0e50Tg4yCsOAQAAAAAAAAAAANvQ+3JvgS9fg7D9elqPzpk3+fBfFy9Yzfag+TF8zgkYMSXhZRKMAxd0UcBC +AAAAAAAAAAAAAAAAAAAAAAAAAABu8rFwU+U70t8UYnwADLxAAAAYIo0mP/QHDi/bMbZUcE6Z+FCk8xdiFVADAAAAAAAAAAAA95zNEUQKnTg7FDjuYGkvx7eKS4gA+vbsYexfw3oHg4f5mPJlWVoDF1eZSEs +cUv1Ah9n1D9sQjjAAAzEIADgACALa5JleFtHAXpjg5ApolORZacJR9HBAAAAAAAAAAAAAKVvKwUS9GTsuMZhooDBTe8ViQY+ZNqJ9G7wRAp/0a36hz0FZtNiAxePFesU +AAAAAAAAAAAAAAAAAAAAAAAAAABzn1sVs3V8E69bGmsADMwAAACBLijgrj3qExgNWCWeXggMz4UDQ4m56joCAAAAAAAAAAAAGtldgem7buviZowIJq4UzeKxnsnV3Km8NDafHbVmrSXtARdmGUIDF19MOLA +dgocDey9X2lTZXieAAzT4ATgACBL6AGEzATXd9qtEYlyS8MqlJ4EYB6/AgAAAAAAAAAAAHjOihGV0AtYxTAEbsNphoqkzIVr8TnvJjYZLO2IbtQSiBwpZtsxAxcrHR8G +AAAAAAAAAAAAAAAAAAAAAAAAAAB4gSCv0Hy/aRfVQIwADNvAAOD/J0wSA6Wwtx9X7LlTGjSF7QM5yHy3QhMCAAAAAAAAAAAAYrFyIAO8MVljn2DlQNeftio5OabfDzmP55dmCPeHcNm+rDxmmmIDF6Nugsw +etSsFFb7Q60zJ6IWAAzjoAAAACAjxxe3UTJ6PDNRoGHrYy6NGjdqfqiiAAAAAAAAAAAAAB4kCH4AfNlDydhR6BlUrT1GHwgJHMskYF304t5PlaPmyt9OZvBVAxcSUN56 +AAAAAAAAAAAAAAAAAAAAAAAAAAB9MQq7fAuiZoUBzdoADOuAAKAUIEwSBqlWFn2c2wwaHuTRQ6F0ZXPf9TIBAAAAAAAAAAAAOfSvhH5aD71QsU2TNVkerTNfP/vFoKwq0QwJx5mIrP6Xe2FmuFwDF1SmIF8 +f4im+5JF3UQWPF1VAAzzYADA2yPiX8bkId18OcyFdpjiXuWkOx7L7L4SAQAAAAAAAAAAAENU3iawe/UPc1bH+MQtKspjAMxVtBzcTGXYa4eA5WxrlfZzZiVdAxedJgLG +AAAAAAAAAAAAAAAAAAAAAAAAAACB3/OSnzHVcZW53a4ADPtAAAAAPpmYt5u+W5DHEKl00KzpMABlvcMveW4BAAAAAAAAAAAA8mit+AHArV+ZywzFXTRNrAwdglE9Ds8mqjG4p6JRB6upZodmbYoDF6kKoxQ +hBlV1/uDULpLgegAAA0DIABA7yMFhyk6HdHZwqJk20LEv0EGptMA6IGkAQAAAAAAAAAAANlDwtHDlOcslbu80qzOArkBJCV3DNIdG+5eSUs1IIQjWEyZZjpuAxd6FlKO +AAAAAAAAAAAAAAAAAAAAAAAAAACGZQXg2NP9KI9FFYYADQsAAADAIPOCrx9tIochtJ89ovW4MVh4A7Fll7MBAAAAAAAAAAAA5PdqrmTYMW0ZWpJCSHG3QWi1jRw8aYhUjg6YkLFfwvw8AKpmvhoDFwguS8c +iO5lve65VG4KlSzuAA0S4AAAvyZJUGB6rcHvHuTBOuGaU79wiyGBGbwUAwAAAAAAAAAAAJ8CZEkSMpex9ZC+nbMOaiBuoiSpqIOALimcQMoPXC6D2US9ZnY9AxeLaoP3 +AAAAAAAAAAAAAAAAAAAAAAAAAACLXJz5knCQcogUvuIADRrAAGCwMp/WHfeihLovfeu/rvnFFSJx74FlA3MAAAAAAAAAAAAAViE5hQ/PwusyBLHnkABaq6ROY6JjMlL9vO1Y0qmofizbNM9mWyUDFyRd3Go +jd10Yfkq1r67J+5zAA0ioABgiSOcfEXabYcsk9yeg4nVKwS90Kgk6zCAAgAAAAAAAAAAAPtMOsiU68mcent23tNewccZkHMgq3gWibod7cpAxanXxQ3hZowJAxcWyAwN +AAAAAAAAAAAAAAAAAAAAAAAAAACQdTBCM+zI2SL6mGQADSqAAEDbLMjiVVHsJYPIIbQkHmGpiyV1GGosjakAAAAAAAAAAAAAIl7AjMlFZyEcbv+19MOyCxF7LbLmN6KfXGLNQckk7FssZ/RmFC8DF14Yjj0 +ku5jK/0HoYmT4Y9fAA0yYAAAADpfAOffk/gFJLXQvKdK6BV32Ok3q0uSAQAAAAAAAAAAAORLjNb1uvjdqhKEpKYjX1recBXsk+n4ySIG/34DT+D0zyYGZ80OAxfTexxH +AAAAAAAAAAAAAAAAAAAAAAAAAACVgbHHBXiMVqtGHdIADTpAAMBtM6v9dhHZVYhUGzbPkTYnxeBfyNnsfXwAAAAAAAAAAAAAQ3+Cc2ZGHx5eglPKNq5vs8W7iwI9m/to6vs5kde7PjlN6RdnKPECF3o5coo diff --git a/rskj-core/src/test/resources/checkpoints/12-byte-chainwork.production.checkpoints b/rskj-core/src/test/resources/checkpoints/12-byte-chainwork.production.checkpoints new file mode 100644 index 0000000000..0a372792ba --- /dev/null +++ b/rskj-core/src/test/resources/checkpoints/12-byte-chainwork.production.checkpoints @@ -0,0 +1,433 @@ +TXT CHECKPOINTS 1 +0 +430 +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 diff --git a/rskj-core/src/test/resources/checkpoints/32-byte-chainwork.production.checkpoints b/rskj-core/src/test/resources/checkpoints/32-byte-chainwork.production.checkpoints new file mode 100644 index 0000000000..69900d2d17 --- /dev/null +++ b/rskj-core/src/test/resources/checkpoints/32-byte-chainwork.production.checkpoints @@ -0,0 +1,433 @@ +TXT CHECKPOINTS 1 +0 +430 +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 From 6ce443a4bc78571208d6e39e55b7efd163657c52 Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Wed, 27 Nov 2024 11:55:10 -0400 Subject: [PATCH 3/5] - Reorganize tests - Put magical number into meaningful constant variable - Put assertion blocks into methods with meaningful names --- .../test/java/co/rsk/peg/BridgeSupportIT.java | 220 ++++++++++-------- 1 file changed, 118 insertions(+), 102 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java index cabdd6b5bd..b544072b15 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java @@ -74,7 +74,6 @@ import org.ethereum.TestUtils; import org.ethereum.config.Constants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.ethereum.config.blockchain.upgrades.ActivationConfig.ForBlock; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.core.*; import org.ethereum.crypto.ECKey; @@ -104,6 +103,15 @@ // to avoid Junit5 unnecessary stub error due to some setup generalizations @MockitoSettings(strictness = Strictness.LENIENT) public class BridgeSupportIT { + + private static final long dayInSeconds = 24 * 60 * 60; + private static final long weekInSeconds = 7 * dayInSeconds; + /** + * Time to use in CheckpointManager adjust checkpoint backwards by a week to account for possible clock drift in the block headers. + * For more detail please see {@link CheckpointManager#checkpoint(NetworkParameters, InputStream, co.rsk.bitcoinj.store.BtcBlockStore, long)} + */ + private static final long checkpointTimeAdjustmentForPossibleCLockDrift = weekInSeconds; + private static final co.rsk.core.Coin LIMIT_MONETARY_BASE = new co.rsk.core.Coin(new BigInteger("21000000000000000000000000")); private static final RskAddress BRIDGE_ADDRESS = PrecompiledContracts.BRIDGE_ADDR; private static final BlockDifficulty TEST_DIFFICULTY = new BlockDifficulty(BigInteger.ONE); @@ -125,6 +133,8 @@ public class BridgeSupportIT { private final BridgeSupportBuilder bridgeSupportBuilder = BridgeSupportBuilder.builder(); private final FederationSupportBuilder federationSupportBuilder = FederationSupportBuilder.builder(); + private static final BridgeConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); + private static final BridgeConstants bridgeRegTestConstants = new BridgeRegTestConstants(); private BridgeConstants bridgeConstants; private FederationConstants federationConstants; private NetworkParameters btcParams; @@ -136,10 +146,13 @@ public class BridgeSupportIT { private WhitelistSupport whitelistSupport; private WhitelistStorageProvider whitelistStorageProvider; private LockingCapSupport lockingCapSupport; + private Repository track; + + private BridgeSupport bridgeSupport; @BeforeEach void setUpOnEachTest() { - bridgeConstants = new BridgeRegTestConstants(); + bridgeConstants = bridgeRegTestConstants; federationConstants = bridgeConstants.getFederationConstants(); btcParams = bridgeConstants.getBtcParams(); activationsBeforeForks = ActivationConfigsForTest.genesis().forBlock(0); @@ -162,55 +175,41 @@ void setUpOnEachTest() { LockingCapMainNetConstants.getInstance(), signatureCache ); + + track = createRepository().startTracking(); } @Test - void testInitialChainHeadWithoutBtcCheckpoints() throws Exception { - Repository repository = createRepository(); - Repository track = repository.startTracking(); - - FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); - FederationSupport federationSupport = federationSupportBuilder - .withFederationConstants(federationConstants) - .withFederationStorageProvider(federationStorageProvider) - .withActivations(activationsBeforeForks) - .build(); - - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()); - BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); - - BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) - .withProvider(provider) - .withRepository(track) - .withBtcBlockStoreFactory(btcBlockStoreFactory) - .withFederationSupport(federationSupport) - .build(); + void initialChainHeadWithoutBtcCheckpoints() throws Exception { + // arrange + bridgeConstants = bridgeRegTestConstants; + activations = activationsBeforeForks; + arrangeBridgeSupport(); + // Act // Force instantiation of blockstore bridgeSupport.getBtcBlockchainBestChainHeight(); - StoredBlock chainHead = bridgeSupport.getBtcBlockStore().getChainHead(); - assertEquals(0, chainHead.getHeight()); - assertEquals(btcParams.getGenesisBlock(), chainHead.getHeader()); + // Assert + StoredBlock actualChainHead = bridgeSupport.getBtcBlockStore().getChainHead(); + int expectedChainHead = 0; + assertEquals(expectedChainHead, actualChainHead.getHeight()); + BtcBlock expectedHeader = btcParams.getGenesisBlock(); + assertEquals(expectedHeader, actualChainHead.getHeader()); } @Test - void testInitialChainHeadWithBtcCheckpoints() throws Exception { - BridgeConstants bridgeTestNetConstants = BridgeTestNetConstants.getInstance(); - - BridgeSupport bridgeSupport = arrangeBridgeSupport(bridgeTestNetConstants, - activationsBeforeForks); + void initialChainHeadWithBtcCheckpoints() throws Exception { + // arrange + bridgeConstants = bridgeMainNetConstants; + arrangeBridgeSupport(); + // act // Force instantiation of blockstore bridgeSupport.getBtcBlockchainBestChainHeight(); - InputStream checkpointsStream = bridgeSupport.getCheckPoints(); - CheckpointManager manager = new CheckpointManager(bridgeTestNetConstants.getBtcParams(), checkpointsStream); - long time = bridgeSupport.getActiveFederation().getCreationTime().toEpochMilli() - 604800L; // The magic number is a substraction CheckpointManager does when getting the checkpoints. - StoredBlock checkpoint = manager.getCheckpointBefore(time); - - assertEquals(checkpoint.getHeight(), bridgeSupport.getBtcBlockchainBestChainHeight()); + // assert + assertGenesisFedCreationTimeIsCheckpointBestChainHeight(); } @ParameterizedTest @@ -220,43 +219,41 @@ void testInitialChainHeadWithBtcCheckpoints() throws Exception { "12-byte-chainwork-mix-format.production.checkpoints" } ) - void testInitialChainHeadWithBtcCheckpoints_whenCheckpointsWith12BytesChainWork_before_RSKIP454_ok( + void initialChainHeadWithBtcCheckpoints_whenCheckpointsWith12BytesChainWork_before_RSKIP454_ok( String checkpointFileName) throws Exception { - var arrowhead631 = ActivationConfigsForTest.arrowhead631().forBlock(0); - BridgeConstants bridgeConstants = BridgeMainNetConstants.getInstance(); - String checkpointToCreate = "/rskbitcoincheckpoints/" + bridgeConstants.getBtcParams().getId() + ".checkpoints"; + // arrange + bridgeConstants = bridgeMainNetConstants; + activations = ActivationConfigsForTest.arrowhead631().forBlock(0); + arrangeCheckpointsSource(checkpointFileName); - Path target = Paths.get(getClass().getResource(checkpointToCreate).getPath()); - - Path source = Paths.get(getClass().getResource("/checkpoints/" + checkpointFileName).getPath()); - Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); - - BridgeSupport bridgeSupport = arrangeBridgeSupport(bridgeConstants, arrowhead631); + arrangeBridgeSupport(); + // act // Force instantiation of blockstore bridgeSupport.getBtcBlockchainBestChainHeight(); - - InputStream checkpointsStream = bridgeSupport.getCheckPoints(); - CheckpointManager manager = new CheckpointManager(bridgeConstants.getBtcParams(), checkpointsStream); - long time = bridgeSupport.getActiveFederation().getCreationTime().toEpochMilli() - 604800L; // The magic number is a substraction CheckpointManager does when getting the checkpoints. - StoredBlock checkpoint = manager.getCheckpointBefore(time); - - assertEquals(checkpoint.getHeight(), bridgeSupport.getBtcBlockchainBestChainHeight()); + assertGenesisFedCreationTimeIsCheckpointBestChainHeight(); } - @Test - void testInitialChainHeadWithBtcCheckpoints_whenCheckpointsWith32BytesChainWork_before_RSKIP454_shouldFail() throws Exception { - var arrowhead631 = ActivationConfigsForTest.arrowhead631().forBlock(0); - BridgeConstants bridgeConstants = BridgeMainNetConstants.getInstance(); + private void arrangeCheckpointsSource(String checkpointFileName) throws IOException { String checkpointToCreate = "/rskbitcoincheckpoints/" + bridgeConstants.getBtcParams().getId() + ".checkpoints"; Path target = Paths.get(getClass().getResource(checkpointToCreate).getPath()); - Path source = Paths.get(getClass().getResource("/checkpoints/32-byte-chainwork.production.checkpoints").getPath()); + Path source = Paths.get(getClass().getResource("/checkpoints/" + checkpointFileName).getPath()); Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); + } + + @Test + void initialChainHeadWithBtcCheckpoints_whenCheckpointsWith32BytesChainWork_before_RSKIP454_shouldFail() throws Exception { + // arrange + bridgeConstants = bridgeMainNetConstants; + activations = ActivationConfigsForTest.arrowhead631().forBlock(0); + arrangeCheckpointsSource("32-byte-chainwork.production.checkpoints"); - BridgeSupport bridgeSupport = arrangeBridgeSupport(bridgeConstants, arrowhead631); + // act + arrangeBridgeSupport(); + // assert Assertions.assertThrows(IllegalArgumentException.class, bridgeSupport::getBtcBlockchainBestChainHeight, "The given number does not fit in 12"); } @@ -265,59 +262,60 @@ void testInitialChainHeadWithBtcCheckpoints_whenCheckpointsWith32BytesChainWork_ { "12-byte-chainwork.production.checkpoints", "12-byte-chainwork.production.checkpoints", + "32-byte-chainwork.production.checkpoints", "12-byte-chainwork-mix-format.production.checkpoints" } ) - void testInitialChainHeadWithBtcCheckpoints_whenCheckpointsWith32BytesChainWork_after_RSKIP454_ok( + void initialChainHeadWithBtcCheckpoints_whenCheckpointsWith32BytesChainWork_after_RSKIP454_ok( String checkpointFileName) throws Exception { - var lovell = ActivationConfigsForTest.lovell700().forBlock(0); - BridgeConstants bridgeConstants = BridgeMainNetConstants.getInstance(); - String checkpointToCreate = "/rskbitcoincheckpoints/" + bridgeConstants.getBtcParams().getId() + ".checkpoints"; - - Path target = Paths.get(getClass().getResource(checkpointToCreate).getPath()); - - Path source = Paths.get(getClass().getResource("/checkpoints/" + checkpointFileName).getPath()); - Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); - - BridgeSupport bridgeSupport = arrangeBridgeSupport(bridgeConstants, lovell); + // arrange + bridgeConstants = bridgeMainNetConstants; + activations = ActivationConfigsForTest.lovell700().forBlock(0); + arrangeCheckpointsSource(checkpointFileName); + arrangeBridgeSupport(); + // act // Force instantiation of blockstore bridgeSupport.getBtcBlockchainBestChainHeight(); + // assert + assertGenesisFedCreationTimeIsCheckpointBestChainHeight(); + } + + private void assertGenesisFedCreationTimeIsCheckpointBestChainHeight() + throws BlockStoreException, IOException { InputStream checkpointsStream = bridgeSupport.getCheckPoints(); - CheckpointManager manager = new CheckpointManager(bridgeConstants.getBtcParams(), checkpointsStream); - long time = bridgeSupport.getActiveFederation().getCreationTime().toEpochMilli() - 604800L; // The magic number is a substraction CheckpointManager does when getting the checkpoints. - StoredBlock checkpoint = manager.getCheckpointBefore(time); + CheckpointManager manager = new CheckpointManager(bridgeConstants.getBtcParams(), + checkpointsStream); + long genesisFedCreationTimeAdjusted = bridgeSupport.getActiveFederation().getCreationTime().toEpochMilli() - checkpointTimeAdjustmentForPossibleCLockDrift; + StoredBlock checkpoint = manager.getCheckpointBefore(genesisFedCreationTimeAdjusted); assertEquals(checkpoint.getHeight(), bridgeSupport.getBtcBlockchainBestChainHeight()); } - private BridgeSupport arrangeBridgeSupport(BridgeConstants bridgeTestNetConstants, - ForBlock activations) { - Repository repository = createRepository(); - Repository track = repository.startTracking(); - + private void arrangeBridgeSupport() { + NetworkParameters btcNetworkParams = bridgeConstants.getBtcParams(); BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( - bridgeTestNetConstants.getBtcParams()); - BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeTestNetConstants.getBtcParams(), + btcNetworkParams); + BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, + btcNetworkParams, activations); FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); FederationSupport federationSupport = federationSupportBuilder - .withFederationConstants(federationConstants) + .withFederationConstants(bridgeConstants.getFederationConstants()) .withFederationStorageProvider(federationStorageProvider) .withActivations(activations) .build(); - BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeTestNetConstants) + this.bridgeSupport = bridgeSupportBuilder + .withBridgeConstants(bridgeConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(btcBlockStoreFactory) .withFederationSupport(federationSupport) .withActivations(activations) .build(); - return bridgeSupport; } @Test @@ -343,11 +341,16 @@ void feePerKbFromStorageProvider() { @Test void testGetBtcBlockchainBlockLocatorWithoutBtcCheckpoints() throws Exception { - BridgeSupport bridgeSupport = arrangeBridgeSupport(bridgeConstants, activationsBeforeForks); + // arrange + activations = activationsBeforeForks; + bridgeConstants = bridgeConstants; + arrangeBridgeSupport(); + // act // Force instantiation of blockstore bridgeSupport.getBtcBlockchainBestChainHeight(); + // assert StoredBlock chainHead = bridgeSupport.getBtcBlockStore().getChainHead(); assertEquals(0, chainHead.getHeight()); assertEquals(btcParams.getGenesisBlock(), chainHead.getHeader()); @@ -370,10 +373,9 @@ void testGetBtcBlockchainBlockLocatorWithoutBtcCheckpoints() throws Exception { @Test void testGetBtcBlockchainBlockLocatorWithBtcCheckpoints() throws Exception { - Repository repository = createRepository(); - Repository track = repository.startTracking(); - - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()); + // arrange + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( + bridgeConstants.getBtcParams()); BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); List checkpoints = createBtcBlocks(btcParams, btcParams.getGenesisBlock(), 10); @@ -407,9 +409,11 @@ InputStream getCheckPoints() { } }; + // act // Force instantiation of blockstore bridgeSupport.getBtcBlockchainBestChainHeight(); + // assert StoredBlock chainHead = bridgeSupport.getBtcBlockStore().getChainHead(); assertEquals(10, chainHead.getHeight()); assertEquals(checkpoints.get(9), chainHead.getHeader()); @@ -1107,8 +1111,10 @@ void sendOrphanBlockHeader() throws IOException, BlockStoreException { bridgeConstants.getBtcParams(), activationsBeforeForks ); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()); - BtcBlockStoreWithCache btcBlockStore = btcBlockStoreFactory.newInstance(track, bridgeConstants, provider, activations); + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( + bridgeConstants.getBtcParams()); + BtcBlockStoreWithCache btcBlockStore = btcBlockStoreFactory.newInstance(track, + bridgeConstants, provider, activations); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); @@ -1158,8 +1164,10 @@ void addBlockHeaderToBlockchain() throws IOException, BlockStoreException { bridgeConstants.getBtcParams(), activationsBeforeForks ); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()); - BtcBlockStoreWithCache btcBlockStore = btcBlockStoreFactory.newInstance(track, bridgeConstants, provider, activations); + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( + bridgeConstants.getBtcParams()); + BtcBlockStoreWithCache btcBlockStore = btcBlockStoreFactory.newInstance(track, + bridgeConstants, provider, activations); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); @@ -1364,7 +1372,8 @@ void registerBtcTransactionOfTransactionNotInMerkleTree() throws BlockStoreExcep Repository repository = createRepository(); Repository track = repository.startTracking(); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()); + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( + bridgeConstants.getBtcParams()); BtcTransaction tx = createTransaction(); BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); @@ -1402,7 +1411,8 @@ void registerBtcTransactionOfTransactionInMerkleTreeWithNegativeHeight() throws Repository repository = createRepository(); Repository track = repository.startTracking(); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()); + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( + bridgeConstants.getBtcParams()); BtcTransaction tx = createTransaction(); BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); @@ -1440,7 +1450,8 @@ void registerBtcTransactionOfTransactionInMerkleTreeWithNotEnoughtHeight() throw Repository repository = createRepository(); Repository track = repository.startTracking(); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()); + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( + bridgeConstants.getBtcParams()); BtcTransaction tx = createTransaction(); BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); @@ -1528,8 +1539,10 @@ void registerBtcTransactionTxNotLockNorReleaseTx() throws BlockStoreException, A bridgeConstants.getBtcParams(), activationsBeforeForks ); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()); - BtcBlockStoreWithCache btcBlockStore = btcBlockStoreFactory.newInstance(track, bridgeConstants, provider, activations); + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( + bridgeConstants.getBtcParams()); + BtcBlockStoreWithCache btcBlockStore = btcBlockStoreFactory.newInstance(track, + bridgeConstants, provider, activations); BtcBlockChain btcBlockChain = new SimpleBlockChain(btcContext, btcBlockStore); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); @@ -3557,7 +3570,8 @@ void getRetiringFederationWallet_nonEmpty() { @Test void getBtcBlockchainInitialBlockHeight() throws IOException { Repository repository = createRepository(); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()); + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( + bridgeConstants.getBtcParams()); BridgeSupport bridgeSupport = bridgeSupportBuilder .withBridgeConstants(bridgeConstants) .withProvider(null) @@ -3977,8 +3991,10 @@ void getBtcBlockchainBlockHashAtDepth() throws Exception { activationsBeforeForks ); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()); - BtcBlockStoreWithCache btcBlockStore = btcBlockStoreFactory.newInstance(track, bridgeConstants, provider, activations); + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( + bridgeConstants.getBtcParams()); + BtcBlockStoreWithCache btcBlockStore = btcBlockStoreFactory.newInstance(track, + bridgeConstants, provider, activations); BtcBlockStoreWithCache.Factory mockFactory = mock(RepositoryBtcBlockStoreWithCache.Factory.class); when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); From 26a435c5d613c24116de35da6240a3dccaa6b895 Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Thu, 28 Nov 2024 23:28:16 -0400 Subject: [PATCH 4/5] Reorganize tests --- .../test/java/co/rsk/peg/BridgeSupportIT.java | 430 ++++++++++-------- 1 file changed, 242 insertions(+), 188 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java index b544072b15..89911bc95e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportIT.java @@ -74,6 +74,7 @@ import org.ethereum.TestUtils; import org.ethereum.config.Constants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ActivationConfig.ForBlock; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.core.*; import org.ethereum.crypto.ECKey; @@ -103,15 +104,6 @@ // to avoid Junit5 unnecessary stub error due to some setup generalizations @MockitoSettings(strictness = Strictness.LENIENT) public class BridgeSupportIT { - - private static final long dayInSeconds = 24 * 60 * 60; - private static final long weekInSeconds = 7 * dayInSeconds; - /** - * Time to use in CheckpointManager adjust checkpoint backwards by a week to account for possible clock drift in the block headers. - * For more detail please see {@link CheckpointManager#checkpoint(NetworkParameters, InputStream, co.rsk.bitcoinj.store.BtcBlockStore, long)} - */ - private static final long checkpointTimeAdjustmentForPossibleCLockDrift = weekInSeconds; - private static final co.rsk.core.Coin LIMIT_MONETARY_BASE = new co.rsk.core.Coin(new BigInteger("21000000000000000000000000")); private static final RskAddress BRIDGE_ADDRESS = PrecompiledContracts.BRIDGE_ADDR; private static final BlockDifficulty TEST_DIFFICULTY = new BlockDifficulty(BigInteger.ONE); @@ -135,7 +127,6 @@ public class BridgeSupportIT { private static final BridgeConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); private static final BridgeConstants bridgeRegTestConstants = new BridgeRegTestConstants(); - private BridgeConstants bridgeConstants; private FederationConstants federationConstants; private NetworkParameters btcParams; private ActivationConfig.ForBlock activationsBeforeForks; @@ -152,9 +143,8 @@ public class BridgeSupportIT { @BeforeEach void setUpOnEachTest() { - bridgeConstants = bridgeRegTestConstants; - federationConstants = bridgeConstants.getFederationConstants(); - btcParams = bridgeConstants.getBtcParams(); + federationConstants = bridgeRegTestConstants.getFederationConstants(); + btcParams = bridgeRegTestConstants.getBtcParams(); activationsBeforeForks = ActivationConfigsForTest.genesis().forBlock(0); activations = mock(ActivationConfig.ForBlock.class); signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); @@ -177,15 +167,32 @@ void setUpOnEachTest() { ); track = createRepository().startTracking(); + + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( + btcParams); + BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, + btcParams, + activations); + + FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); + FederationSupport federationSupport = federationSupportBuilder + .withFederationConstants(bridgeRegTestConstants.getFederationConstants()) + .withFederationStorageProvider(federationStorageProvider) + .withActivations(activations) + .build(); + + this.bridgeSupport = bridgeSupportBuilder + .withBridgeConstants(bridgeRegTestConstants) + .withProvider(provider) + .withRepository(track) + .withBtcBlockStoreFactory(btcBlockStoreFactory) + .withFederationSupport(federationSupport) + .withActivations(activations) + .build(); } @Test void initialChainHeadWithoutBtcCheckpoints() throws Exception { - // arrange - bridgeConstants = bridgeRegTestConstants; - activations = activationsBeforeForks; - arrangeBridgeSupport(); - // Act // Force instantiation of blockstore bridgeSupport.getBtcBlockchainBestChainHeight(); @@ -201,15 +208,35 @@ void initialChainHeadWithoutBtcCheckpoints() throws Exception { @Test void initialChainHeadWithBtcCheckpoints() throws Exception { // arrange - bridgeConstants = bridgeMainNetConstants; - arrangeBridgeSupport(); + NetworkParameters btcNetworkParams = bridgeMainNetConstants.getBtcParams(); + BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, + btcNetworkParams, + activations); + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( + btcNetworkParams); + + FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); + FederationSupport federationSupport = federationSupportBuilder + .withFederationConstants(bridgeMainNetConstants.getFederationConstants()) + .withFederationStorageProvider(federationStorageProvider) + .withActivations(activations) + .build(); + + this.bridgeSupport = bridgeSupportBuilder + .withBridgeConstants(bridgeMainNetConstants) + .withBtcBlockStoreFactory(btcBlockStoreFactory) + .withProvider(provider) + .withFederationSupport(federationSupport) + .withRepository(track) + .withActivations(activations) + .build(); // act // Force instantiation of blockstore bridgeSupport.getBtcBlockchainBestChainHeight(); // assert - assertGenesisFedCreationTimeIsCheckpointBestChainHeight(); + assertGenesisFedCreationTimeIsCheckpointBestChainHeight(bridgeMainNetConstants); } @ParameterizedTest @@ -222,19 +249,37 @@ void initialChainHeadWithBtcCheckpoints() throws Exception { void initialChainHeadWithBtcCheckpoints_whenCheckpointsWith12BytesChainWork_before_RSKIP454_ok( String checkpointFileName) throws Exception { // arrange - bridgeConstants = bridgeMainNetConstants; - activations = ActivationConfigsForTest.arrowhead631().forBlock(0); - arrangeCheckpointsSource(checkpointFileName); + arrangeCheckpointsSource(checkpointFileName, bridgeMainNetConstants); + + activations = ActivationConfigsForTest.arrowhead631().forBlock(0); - arrangeBridgeSupport(); + NetworkParameters btcNetworkParams = bridgeMainNetConstants.getBtcParams(); + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( + btcNetworkParams); + + FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); + FederationSupport federationSupport = federationSupportBuilder + .withFederationConstants(bridgeMainNetConstants.getFederationConstants()) + .withFederationStorageProvider(federationStorageProvider) + .withActivations(activations) + .build(); + + this.bridgeSupport = bridgeSupportBuilder + .withBridgeConstants(bridgeMainNetConstants) + .withBtcBlockStoreFactory(btcBlockStoreFactory) + .withFederationSupport(federationSupport) + .withRepository(track) + .withActivations(activations) + .build(); // act // Force instantiation of blockstore bridgeSupport.getBtcBlockchainBestChainHeight(); - assertGenesisFedCreationTimeIsCheckpointBestChainHeight(); + assertGenesisFedCreationTimeIsCheckpointBestChainHeight(bridgeMainNetConstants); } - private void arrangeCheckpointsSource(String checkpointFileName) throws IOException { + private void arrangeCheckpointsSource(String checkpointFileName, + BridgeConstants bridgeConstants) throws IOException { String checkpointToCreate = "/rskbitcoincheckpoints/" + bridgeConstants.getBtcParams().getId() + ".checkpoints"; Path target = Paths.get(getClass().getResource(checkpointToCreate).getPath()); @@ -246,14 +291,29 @@ private void arrangeCheckpointsSource(String checkpointFileName) throws IOExcept @Test void initialChainHeadWithBtcCheckpoints_whenCheckpointsWith32BytesChainWork_before_RSKIP454_shouldFail() throws Exception { // arrange - bridgeConstants = bridgeMainNetConstants; - activations = ActivationConfigsForTest.arrowhead631().forBlock(0); - arrangeCheckpointsSource("32-byte-chainwork.production.checkpoints"); + arrangeCheckpointsSource("32-byte-chainwork.production.checkpoints", bridgeMainNetConstants); + activations = ActivationConfigsForTest.arrowhead631().forBlock(0); - // act - arrangeBridgeSupport(); + NetworkParameters btcNetworkParams = bridgeMainNetConstants.getBtcParams(); + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( + btcNetworkParams); - // assert + FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); + FederationSupport federationSupport = federationSupportBuilder + .withFederationConstants(bridgeMainNetConstants.getFederationConstants()) + .withFederationStorageProvider(federationStorageProvider) + .withActivations(activations) + .build(); + + this.bridgeSupport = bridgeSupportBuilder + .withBridgeConstants(bridgeMainNetConstants) + .withBtcBlockStoreFactory(btcBlockStoreFactory) + .withFederationSupport(federationSupport) + .withRepository(track) + .withActivations(activations) + .build(); + + // act and assert Assertions.assertThrows(IllegalArgumentException.class, bridgeSupport::getBtcBlockchainBestChainHeight, "The given number does not fit in 12"); } @@ -269,53 +329,52 @@ void initialChainHeadWithBtcCheckpoints_whenCheckpointsWith32BytesChainWork_befo void initialChainHeadWithBtcCheckpoints_whenCheckpointsWith32BytesChainWork_after_RSKIP454_ok( String checkpointFileName) throws Exception { // arrange - bridgeConstants = bridgeMainNetConstants; - activations = ActivationConfigsForTest.lovell700().forBlock(0); - arrangeCheckpointsSource(checkpointFileName); - arrangeBridgeSupport(); - - // act - // Force instantiation of blockstore - bridgeSupport.getBtcBlockchainBestChainHeight(); - - // assert - assertGenesisFedCreationTimeIsCheckpointBestChainHeight(); - } + arrangeCheckpointsSource(checkpointFileName, bridgeMainNetConstants); + activations = ActivationConfigsForTest.lovell700().forBlock(0); - private void assertGenesisFedCreationTimeIsCheckpointBestChainHeight() - throws BlockStoreException, IOException { - InputStream checkpointsStream = bridgeSupport.getCheckPoints(); - CheckpointManager manager = new CheckpointManager(bridgeConstants.getBtcParams(), - checkpointsStream); - long genesisFedCreationTimeAdjusted = bridgeSupport.getActiveFederation().getCreationTime().toEpochMilli() - checkpointTimeAdjustmentForPossibleCLockDrift; - StoredBlock checkpoint = manager.getCheckpointBefore(genesisFedCreationTimeAdjusted); - - assertEquals(checkpoint.getHeight(), bridgeSupport.getBtcBlockchainBestChainHeight()); - } - - private void arrangeBridgeSupport() { - NetworkParameters btcNetworkParams = bridgeConstants.getBtcParams(); + NetworkParameters btcNetworkParams = bridgeMainNetConstants.getBtcParams(); BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( btcNetworkParams); - BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, - btcNetworkParams, - activations); FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); FederationSupport federationSupport = federationSupportBuilder - .withFederationConstants(bridgeConstants.getFederationConstants()) + .withFederationConstants(bridgeMainNetConstants.getFederationConstants()) .withFederationStorageProvider(federationStorageProvider) .withActivations(activations) .build(); this.bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) - .withProvider(provider) - .withRepository(track) + .withBridgeConstants(bridgeMainNetConstants) .withBtcBlockStoreFactory(btcBlockStoreFactory) .withFederationSupport(federationSupport) + .withRepository(track) .withActivations(activations) .build(); + + // act + // Force instantiation of blockstore + bridgeSupport.getBtcBlockchainBestChainHeight(); + + // assert + assertGenesisFedCreationTimeIsCheckpointBestChainHeight(bridgeMainNetConstants); + } + + private void assertGenesisFedCreationTimeIsCheckpointBestChainHeight(BridgeConstants bridgeConstants) + throws BlockStoreException, IOException { + InputStream checkpointsStream = bridgeSupport.getCheckPoints(); + CheckpointManager manager = new CheckpointManager(bridgeConstants.getBtcParams(), + checkpointsStream); + + /** + * Time to use in CheckpointManager adjust checkpoint backwards by a week to account for possible clock drift in the block headers. + * For more detail please see {@link CheckpointManager#checkpoint(NetworkParameters, InputStream, co.rsk.bitcoinj.store.BtcBlockStore, long)} + */ + final long dayInSeconds = 24 * 60 * 60; + final long weekInSeconds = 7 * dayInSeconds; + long genesisFedCreationTimeAdjusted = bridgeSupport.getActiveFederation().getCreationTime().toEpochMilli() - weekInSeconds; + StoredBlock checkpoint = manager.getCheckpointBefore(genesisFedCreationTimeAdjusted); + + assertEquals(checkpoint.getHeight(), bridgeSupport.getBtcBlockchainBestChainHeight()); } @Test @@ -323,14 +382,14 @@ void feePerKbFromStorageProvider() { Repository repository = createRepository(); Repository track = repository.startTracking(); - BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); Coin expected = Coin.MILLICOIN; when(feePerKbSupport.getFeePerKb()).thenReturn(expected); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withFeePerKbSupport(feePerKbSupport) @@ -341,11 +400,6 @@ void feePerKbFromStorageProvider() { @Test void testGetBtcBlockchainBlockLocatorWithoutBtcCheckpoints() throws Exception { - // arrange - activations = activationsBeforeForks; - bridgeConstants = bridgeConstants; - arrangeBridgeSupport(); - // act // Force instantiation of blockstore bridgeSupport.getBtcBlockchainBestChainHeight(); @@ -375,8 +429,8 @@ void testGetBtcBlockchainBlockLocatorWithoutBtcCheckpoints() throws Exception { void testGetBtcBlockchainBlockLocatorWithBtcCheckpoints() throws Exception { // arrange BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( - bridgeConstants.getBtcParams()); - BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + bridgeRegTestConstants.getBtcParams()); + BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); List checkpoints = createBtcBlocks(btcParams, btcParams.getGenesisBlock(), 10); FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); @@ -387,7 +441,7 @@ void testGetBtcBlockchainBlockLocatorWithBtcCheckpoints() throws Exception { .build(); BridgeSupport bridgeSupport = new BridgeSupport( - bridgeConstants, + bridgeRegTestConstants, provider, mock(BridgeEventLogger.class), mock(BtcLockSenderProvider.class), @@ -497,7 +551,7 @@ void callUpdateCollectionsGenerateEventLog() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); @@ -509,7 +563,7 @@ void callUpdateCollectionsGenerateEventLog() throws IOException { .build(); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withEventLogger(eventLogger) @@ -542,7 +596,7 @@ void callUpdateCollectionsFundsEnoughForJustTheSmallerTx() throws IOException { Repository repository = createRepository(); Repository track = repository.startTracking(); - BridgeStorageProvider provider0 = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider0 = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); FederationStorageProvider federationStorageProvider = new FederationStorageProviderImpl(new BridgeStorageAccessorImpl(track)); provider0.getReleaseRequestQueue().add(new BtcECKey().toAddress(btcParams), Coin.valueOf(30, 0)); @@ -584,7 +638,7 @@ void callUpdateCollectionsFundsEnoughForJustTheSmallerTx() throws IOException { BridgeStorageProvider providerForSupport = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); federationStorageProvider = createFederationStorageProvider(track); @@ -596,7 +650,7 @@ void callUpdateCollectionsFundsEnoughForJustTheSmallerTx() throws IOException { .build(); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(providerForSupport) .withRepository(track) .withExecutionBlock(rskCurrentBlock) @@ -611,7 +665,7 @@ void callUpdateCollectionsFundsEnoughForJustTheSmallerTx() throws IOException { track.commit(); // reusing same bridge storage configuration as the height doesn't affect it for releases - BridgeStorageProvider provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); federationStorageProvider = createFederationStorageProvider(track); assertEquals(2, provider.getReleaseRequestQueue().getEntries().size()); @@ -631,7 +685,7 @@ void callUpdateCollectionsThrowsCouldNotAdjustDownwards() throws IOException { Repository repository = createRepository(); Repository track = repository.startTracking(); - BridgeStorageProvider provider0 = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider0 = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); provider0.getReleaseRequestQueue().add(new BtcECKey().toAddress(btcParams), Coin.valueOf(37500)); @@ -677,7 +731,7 @@ void callUpdateCollectionsThrowsCouldNotAdjustDownwards() throws IOException { BridgeStorageProvider providerForSupport = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); @@ -690,7 +744,7 @@ void callUpdateCollectionsThrowsCouldNotAdjustDownwards() throws IOException { .build(); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(providerForSupport) .withRepository(track) .withExecutionBlock(rskCurrentBlock) @@ -705,7 +759,7 @@ void callUpdateCollectionsThrowsCouldNotAdjustDownwards() throws IOException { track.commit(); // reusing same bridge storage configuration as it doesn't affect the release transactions - BridgeStorageProvider provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); federationStorageProvider = createFederationStorageProvider(track); assertEquals(1, provider.getReleaseRequestQueue().getEntries().size()); @@ -724,7 +778,7 @@ void callUpdateCollectionsThrowsExceededMaxTransactionSize() throws IOException Repository track = repository.startTracking(); FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); - BridgeStorageProvider provider0 = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider0 = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); provider0.getReleaseRequestQueue().add(new BtcECKey().toAddress(btcParams), Coin.COIN.multiply(7)); for (int i = 0; i < 2000; i++) { @@ -770,7 +824,7 @@ void callUpdateCollectionsThrowsExceededMaxTransactionSize() throws IOException BridgeStorageProvider providerForSupport = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); @@ -783,7 +837,7 @@ void callUpdateCollectionsThrowsExceededMaxTransactionSize() throws IOException .build(); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(providerForSupport) .withRepository(track) .withExecutionBlock(rskCurrentBlock) @@ -798,7 +852,7 @@ void callUpdateCollectionsThrowsExceededMaxTransactionSize() throws IOException track.commit(); // keeping same bridge storage configuration - BridgeStorageProvider provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); federationStorageProvider = createFederationStorageProvider(track); assertEquals(1, provider.getReleaseRequestQueue().getEntries().size()); @@ -817,7 +871,7 @@ void minimumProcessFundsMigrationValue() throws IOException { Collections.singletonList(member), Instant.EPOCH, 5L, - bridgeConstants.getBtcParams() + bridgeRegTestConstants.getBtcParams() ); Federation newFederation = FederationFactory.buildStandardMultiSigFederation( newFederationArgs @@ -855,7 +909,7 @@ void minimumProcessFundsMigrationValue() throws IOException { .build(); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withExecutionBlock(rskCurrentBlock) @@ -924,7 +978,7 @@ void callUpdateCollectionsChangeGetsOutOfDust() throws IOException { Repository repository = builder.getRepository(); Repository track = repository.startTracking(); - BridgeStorageProvider provider0 = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider0 = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); provider0.getReleaseRequestQueue().add(new BtcECKey().toAddress(btcParams), Coin.COIN); @@ -960,7 +1014,7 @@ void callUpdateCollectionsChangeGetsOutOfDust() throws IOException { BridgeStorageProvider providerForSupport = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); @@ -973,7 +1027,7 @@ void callUpdateCollectionsChangeGetsOutOfDust() throws IOException { .build(); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(providerForSupport) .withRepository(track) .withExecutionBlock(rskCurrentBlock) @@ -988,7 +1042,7 @@ void callUpdateCollectionsChangeGetsOutOfDust() throws IOException { track.commit(); // reusing same bridge storage configuration - BridgeStorageProvider provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); federationStorageProvider = createFederationStorageProvider(track); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); @@ -1018,7 +1072,7 @@ void callUpdateCollectionsWithTransactionsWaitingForConfirmationWithEnoughConfir BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); @@ -1046,7 +1100,7 @@ void callUpdateCollectionsWithTransactionsWaitingForConfirmationWithEnoughConfir track.commit(); track = repository.startTracking(); - BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); BlockGenerator blockGenerator = new BlockGenerator(); List blocks = blockGenerator.getSimpleBlockChain(blockGenerator.getGenesisBlock(), 10); @@ -1080,7 +1134,7 @@ void callUpdateCollectionsWithTransactionsWaitingForConfirmationWithEnoughConfir .build(); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withExecutionBlock(rskCurrentBlock) @@ -1092,7 +1146,7 @@ void callUpdateCollectionsWithTransactionsWaitingForConfirmationWithEnoughConfir track.commit(); - BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); assertEquals(0, provider2.getReleaseRequestQueue().getEntries().size()); assertEquals(2, provider2.getPegoutsWaitingForConfirmations().getEntries().size()); @@ -1108,22 +1162,22 @@ void sendOrphanBlockHeader() throws IOException, BlockStoreException { BridgeStorageProvider provider = new BridgeStorageProvider( track, BRIDGE_ADDRESS, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( - bridgeConstants.getBtcParams()); + bridgeRegTestConstants.getBtcParams()); BtcBlockStoreWithCache btcBlockStore = btcBlockStoreFactory.newInstance(track, - bridgeConstants, provider, activations); + bridgeRegTestConstants, provider, activations); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); - when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); + when(mockFactory.newInstance(track, bridgeRegTestConstants, provider, activations)).thenReturn(btcBlockStore); FederationSupport federationSupport = federationSupportBuilder .withFederationConstants(federationConstants) .build(); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) @@ -1161,22 +1215,22 @@ void addBlockHeaderToBlockchain() throws IOException, BlockStoreException { BridgeStorageProvider provider = new BridgeStorageProvider( track, BRIDGE_ADDRESS, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( - bridgeConstants.getBtcParams()); + bridgeRegTestConstants.getBtcParams()); BtcBlockStoreWithCache btcBlockStore = btcBlockStoreFactory.newInstance(track, - bridgeConstants, provider, activations); + bridgeRegTestConstants, provider, activations); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); - when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); + when(mockFactory.newInstance(track, bridgeRegTestConstants, provider, activations)).thenReturn(btcBlockStore); FederationSupport federationSupport = federationSupportBuilder .withFederationConstants(federationConstants) .build(); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) @@ -1244,9 +1298,9 @@ void releaseBtcWithDustOutput() throws AddressFormatException, IOException { tx.sign(new org.ethereum.crypto.ECKey().getPrivKeyBytes()); - BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .build(); @@ -1256,7 +1310,7 @@ void releaseBtcWithDustOutput() throws AddressFormatException, IOException { track.commit(); - BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); assertEquals(0, provider2.getReleaseRequestQueue().getEntries().size()); @@ -1281,9 +1335,9 @@ void releaseBtc() throws AddressFormatException, IOException { tx.sign(new org.ethereum.crypto.ECKey().getPrivKeyBytes()); - BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .build(); @@ -1293,7 +1347,7 @@ void releaseBtc() throws AddressFormatException, IOException { track.commit(); - BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); assertEquals(1, provider.getReleaseRequestQueue().getEntries().size()); assertEquals(1, provider2.getReleaseRequestQueue().getEntries().size()); @@ -1321,9 +1375,9 @@ void releaseBtcFromContract() throws AddressFormatException, IOException { ); track.saveCode(tx.getSender(), new byte[]{0x1}); - BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .build(); @@ -1342,12 +1396,12 @@ void registerBtcTransactionOfAlreadyProcessedTransaction() throws BlockStoreExce Repository track = repository.startTracking(); BtcTransaction tx = createTransaction(); - BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); provider.setHeightBtcTxhashAlreadyProcessed(tx.getHash(), 1L); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .build(); @@ -1357,7 +1411,7 @@ void registerBtcTransactionOfAlreadyProcessedTransaction() throws BlockStoreExce track.commit(); - BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); assertTrue(federationStorageProvider.getNewFederationBtcUTXOs(btcParams, activationsBeforeForks).isEmpty()); @@ -1373,12 +1427,12 @@ void registerBtcTransactionOfTransactionNotInMerkleTree() throws BlockStoreExcep Repository track = repository.startTracking(); BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( - bridgeConstants.getBtcParams()); + bridgeRegTestConstants.getBtcParams()); BtcTransaction tx = createTransaction(); - BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(btcBlockStoreFactory) @@ -1396,7 +1450,7 @@ void registerBtcTransactionOfTransactionNotInMerkleTree() throws BlockStoreExcep track.commit(); - BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); assertTrue(federationStorageProvider.getNewFederationBtcUTXOs(btcParams, activationsBeforeForks).isEmpty()); @@ -1412,12 +1466,12 @@ void registerBtcTransactionOfTransactionInMerkleTreeWithNegativeHeight() throws Repository track = repository.startTracking(); BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( - bridgeConstants.getBtcParams()); + bridgeRegTestConstants.getBtcParams()); BtcTransaction tx = createTransaction(); - BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(btcBlockStoreFactory) @@ -1435,7 +1489,7 @@ void registerBtcTransactionOfTransactionInMerkleTreeWithNegativeHeight() throws track.commit(); - BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); assertTrue(federationStorageProvider.getNewFederationBtcUTXOs(btcParams, activationsBeforeForks).isEmpty()); @@ -1451,12 +1505,12 @@ void registerBtcTransactionOfTransactionInMerkleTreeWithNotEnoughtHeight() throw Repository track = repository.startTracking(); BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( - bridgeConstants.getBtcParams()); + bridgeRegTestConstants.getBtcParams()); BtcTransaction tx = createTransaction(); - BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(btcBlockStoreFactory) @@ -1474,7 +1528,7 @@ void registerBtcTransactionOfTransactionInMerkleTreeWithNotEnoughtHeight() throw track.commit(); - BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); assertTrue(federationStorageProvider.getNewFederationBtcUTXOs(btcParams, activationsBeforeForks).isEmpty()); @@ -1536,19 +1590,19 @@ void registerBtcTransactionTxNotLockNorReleaseTx() throws BlockStoreException, A BridgeStorageProvider provider = new BridgeStorageProvider( track, BRIDGE_ADDRESS, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( - bridgeConstants.getBtcParams()); + bridgeRegTestConstants.getBtcParams()); BtcBlockStoreWithCache btcBlockStore = btcBlockStoreFactory.newInstance(track, - bridgeConstants, provider, activations); + bridgeRegTestConstants, provider, activations); BtcBlockChain btcBlockChain = new SimpleBlockChain(btcContext, btcBlockStore); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); - when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); + when(mockFactory.newInstance(track, bridgeRegTestConstants, provider, activations)).thenReturn(btcBlockStore); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) @@ -1585,7 +1639,7 @@ void registerBtcTransactionTxNotLockNorReleaseTx() throws BlockStoreException, A FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); assertEquals(0, federationStorageProvider.getNewFederationBtcUTXOs(btcParams, activationsBeforeForks).size()); - BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); assertEquals(0, provider2.getReleaseRequestQueue().getEntries().size()); assertEquals(0, provider2.getPegoutsWaitingForConfirmations().getEntries().size()); assertTrue(provider2.getPegoutsWaitingForSignatures().isEmpty()); @@ -1635,13 +1689,13 @@ void registerBtcTransactionReleaseTx() throws BlockStoreException, AddressFormat BridgeStorageProvider provider = new BridgeStorageProvider( track, BRIDGE_ADDRESS, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); - when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); + when(mockFactory.newInstance(track, bridgeRegTestConstants, provider, activations)).thenReturn(btcBlockStore); FederationSupport federationSupport = federationSupportBuilder .withFederationConstants(federationConstants) @@ -1649,7 +1703,7 @@ void registerBtcTransactionReleaseTx() throws BlockStoreException, AddressFormat .build(); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) @@ -1692,7 +1746,7 @@ void registerBtcTransactionReleaseTx() throws BlockStoreException, AddressFormat assertEquals(1, federationStorageProvider.getNewFederationBtcUTXOs(btcParams, activationsBeforeForks).size()); assertEquals(Coin.COIN, federationStorageProvider.getNewFederationBtcUTXOs(btcParams, activationsBeforeForks).get(0).getValue()); - BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); assertEquals(0, provider2.getReleaseRequestQueue().getEntries().size()); assertEquals(0, provider2.getPegoutsWaitingForConfirmations().getEntries().size()); assertTrue(provider2.getPegoutsWaitingForSignatures().isEmpty()); @@ -1701,7 +1755,7 @@ void registerBtcTransactionReleaseTx() throws BlockStoreException, AddressFormat @Test void registerBtcTransactionMigrationTx() throws BlockStoreException, AddressFormatException, IOException, BridgeIllegalArgumentException { - NetworkParameters parameters = bridgeConstants.getBtcParams(); + NetworkParameters parameters = bridgeRegTestConstants.getBtcParams(); List activeFederationKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fa01")), @@ -1769,7 +1823,7 @@ void registerBtcTransactionMigrationTx() throws BlockStoreException, AddressForm BridgeStorageProvider provider = new BridgeStorageProvider( track, BRIDGE_ADDRESS, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); FederationStorageProvider federationStorageProvider = createFederationStorageProvider(track); @@ -1778,7 +1832,7 @@ void registerBtcTransactionMigrationTx() throws BlockStoreException, AddressForm BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); - when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); + when(mockFactory.newInstance(track, bridgeRegTestConstants, provider, activations)).thenReturn(btcBlockStore); FederationSupport federationSupport = federationSupportBuilder .withFederationConstants(federationConstants) @@ -1787,7 +1841,7 @@ void registerBtcTransactionMigrationTx() throws BlockStoreException, AddressForm .build(); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) @@ -1832,7 +1886,7 @@ void registerBtcTransactionMigrationTx() throws BlockStoreException, AddressForm @Test void registerBtcTransactionWithCrossFederationsChange() throws Exception { - NetworkParameters params = bridgeConstants.getBtcParams(); + NetworkParameters params = bridgeRegTestConstants.getBtcParams(); List activeFederationKeys = Stream.of("fa01", "fa02") .map(Hex::decode) @@ -1857,7 +1911,7 @@ void registerBtcTransactionWithCrossFederationsChange() throws Exception { BtcECKey.fromPrivate(Hex.decode("e1b17fcd0ef1942465eee61b20561b16750191143d365e71de08b33dd84a9788")) ); - Federation retiringFederation = createFederation(bridgeConstants, retiringFedPrivateKeys); + Federation retiringFederation = createFederation(bridgeRegTestConstants, retiringFedPrivateKeys); List activeFederationUtxos = new ArrayList<>(); List retiringFederationUtxos = new ArrayList<>(); @@ -1921,7 +1975,7 @@ void registerBtcTransactionWithCrossFederationsChange() throws Exception { .build(); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withBtcBlockStoreFactory(mockFactory) .withExecutionBlock(rskCurrentBlock) .withFederationSupport(federationSupport) @@ -2015,7 +2069,7 @@ void registerBtcTransactionLockTxWhitelisted() throws Exception { BridgeStorageProvider provider = new BridgeStorageProvider( track, BRIDGE_ADDRESS, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); // Whitelist the addresses @@ -2028,10 +2082,10 @@ void registerBtcTransactionLockTxWhitelisted() throws Exception { whitelist.put(address3, new OneOffWhiteListEntry(address3, Coin.COIN.multiply(2).add(Coin.COIN.multiply(3)))); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); - when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); + when(mockFactory.newInstance(track, bridgeRegTestConstants, provider, activations)).thenReturn(btcBlockStore); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withBtcLockSenderProvider(new BtcLockSenderProvider()) .withRepository(track) @@ -2100,7 +2154,7 @@ void registerBtcTransactionLockTxWhitelisted() throws Exception { assertEquals(Coin.COIN.multiply(10), federationStorageProvider.getOldFederationBtcUTXOs().get(0).getValue()); assertEquals(Coin.COIN.multiply(3), federationStorageProvider.getOldFederationBtcUTXOs().get(1).getValue()); - BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants.getBtcParams(), activationsBeforeForks); + BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeRegTestConstants.getBtcParams(), activationsBeforeForks); assertEquals(0, provider2.getReleaseRequestQueue().getEntries().size()); assertEquals(0, provider2.getPegoutsWaitingForConfirmations().getEntries().size()); assertTrue(provider2.getPegoutsWaitingForSignatures().isEmpty()); @@ -2112,7 +2166,7 @@ void registerBtcTransactionLockTxWhitelisted() throws Exception { @Test void isBtcTxHashAlreadyProcessed() throws IOException { BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(getBridgeStorageProviderMockWithProcessedHashes()) .withRepository(null) .build(); @@ -2126,7 +2180,7 @@ void isBtcTxHashAlreadyProcessed() throws IOException { @Test void getBtcTxHashProcessedHeight() throws IOException { BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(getBridgeStorageProviderMockWithProcessedHashes()) .withRepository(null) .build(); @@ -3571,9 +3625,9 @@ void getRetiringFederationWallet_nonEmpty() { void getBtcBlockchainInitialBlockHeight() throws IOException { Repository repository = createRepository(); BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( - bridgeConstants.getBtcParams()); + bridgeRegTestConstants.getBtcParams()); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(null) .withRepository(repository) .withBtcBlockStoreFactory(btcBlockStoreFactory) @@ -3605,11 +3659,11 @@ void getBtcTransactionConfirmations_inexistentBlockHash() throws BlockStoreExcep BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) @@ -3643,17 +3697,17 @@ void getBtcTransactionConfirmations_blockNotInBestChain() throws BlockStoreExcep BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); - when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); + when(mockFactory.newInstance(track, bridgeRegTestConstants, provider, activations)).thenReturn(btcBlockStore); Sha256Hash btcTransactionHash = Sha256Hash.of(Hex.decode("112233")); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) @@ -3687,17 +3741,17 @@ void getBtcTransactionConfirmations_blockNotInBestChainBlockWithHeightNotFound() BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); - when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); + when(mockFactory.newInstance(track, bridgeRegTestConstants, provider, activations)).thenReturn(btcBlockStore); Sha256Hash btcTransactionHash = Sha256Hash.of(Hex.decode("112233")); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) @@ -3731,17 +3785,17 @@ void getBtcTransactionConfirmations_blockTooOld() throws BlockStoreException, IO BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); - when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); + when(mockFactory.newInstance(track, bridgeRegTestConstants, provider, activations)).thenReturn(btcBlockStore); Sha256Hash btcTransactionHash = Sha256Hash.of(Hex.decode("112233")); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) @@ -3775,17 +3829,17 @@ void getBtcTransactionConfirmations_heightInconsistency() throws BlockStoreExcep BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); - when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); + when(mockFactory.newInstance(track, bridgeRegTestConstants, provider, activations)).thenReturn(btcBlockStore); Sha256Hash btcTransactionHash = Sha256Hash.of(Hex.decode("112233")); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) @@ -3821,16 +3875,16 @@ void getBtcTransactionConfirmations_merkleBranchDoesNotProve() throws BlockStore BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); - when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); + when(mockFactory.newInstance(track, bridgeRegTestConstants, provider, activations)).thenReturn(btcBlockStore); Sha256Hash btcTransactionHash = Sha256Hash.of(Hex.decode("112233")); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) @@ -3864,16 +3918,16 @@ void getBtcTransactionConfirmationsGetCost_ok() throws BlockStoreException { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); - when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); + when(mockFactory.newInstance(track, bridgeRegTestConstants, provider, activations)).thenReturn(btcBlockStore); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) @@ -3898,14 +3952,14 @@ void getBtcTransactionConfirmationsGetCost_blockDoesNotExist() { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) @@ -3928,14 +3982,14 @@ void getBtcTransactionConfirmationsGetCost_getBestChainHeightError() { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) @@ -3959,14 +4013,14 @@ void getBtcTransactionConfirmationsGetCost_blockTooDeep() { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) @@ -3987,23 +4041,23 @@ void getBtcBlockchainBlockHashAtDepth() throws Exception { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants.getBtcParams(), + bridgeRegTestConstants.getBtcParams(), activationsBeforeForks ); BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( - bridgeConstants.getBtcParams()); + bridgeRegTestConstants.getBtcParams()); BtcBlockStoreWithCache btcBlockStore = btcBlockStoreFactory.newInstance(track, - bridgeConstants, provider, activations); + bridgeRegTestConstants, provider, activations); BtcBlockStoreWithCache.Factory mockFactory = mock(RepositoryBtcBlockStoreWithCache.Factory.class); - when(mockFactory.newInstance(track, bridgeConstants, provider, activations)).thenReturn(btcBlockStore); + when(mockFactory.newInstance(track, bridgeRegTestConstants, provider, activations)).thenReturn(btcBlockStore); FederationSupport federationSupport = federationSupportBuilder .withFederationConstants(federationConstants) .build(); BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(bridgeRegTestConstants) .withProvider(provider) .withRepository(track) .withBtcBlockStoreFactory(mockFactory) From 3f4cde541f2429afcbc97abc0b8ec38f45c3ad6c Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Tue, 3 Dec 2024 21:48:59 -0400 Subject: [PATCH 5/5] Bump version to 0.14.4-rsk-17-SNAPSHOT --- rskj-core/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rskj-core/build.gradle b/rskj-core/build.gradle index 2afc42feed..f7e0671567 100644 --- a/rskj-core/build.gradle +++ b/rskj-core/build.gradle @@ -273,7 +273,7 @@ ext { jaxwsRtVer : '2.3.5', picocliVer : '4.6.3', - bitcoinjThinVer: '0.14.4-rsk-16', + bitcoinjThinVer: '0.14.4-rsk-17-SNAPSHOT', rskjNativeVer: '1.3.0', ]