3
0
mirror of https://github.com/Qortal/qortal.git synced 2025-02-12 02:05:50 +00:00

Blockchain replacement for launch.

These changes are for allowing devices to be shipped with an interim blockchain config & genesis block, running with "main-net" settings, prior to launch.
At launch, an "auto-update" will be broadcast to replace blockchain config & genesis block with the final, launch version.
When updated nodes restart (immediately after auto-update) they should notice their existing genesis blocks are invalid and hence wipe their blockchains,
effectively starting the final, launch blockchain.

To this end, genesis block signatures have been changed to better incorporate values that are likely to change at launch, e.g. block timestamp and transaction data.

Added Crypto.dupDigest(), which is effectively Bytes.concat(digest(msg), digest(msg)).

No need for HSQLDB repository to backup, or wipe, non-existent files for "in-memory" databases!

New interim blockchain config/genesis block.

**NOTE** These changes are being committed but require testing. However the auto-update suite requires a pushed commit in order to build an update file!
This commit is contained in:
catbref 2019-12-17 16:19:35 +00:00
parent 42bd68230b
commit 09ffd6fe6b
10 changed files with 294 additions and 88 deletions

View File

@ -7,7 +7,6 @@ import java.math.BigDecimal;
import java.math.MathContext; import java.math.MathContext;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -482,25 +481,20 @@ public class BlockChain {
rebuildBlockchain(); rebuildBlockchain();
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
Block parentBlock = GenesisBlock.getInstance(repository); BlockData detachedBlockData = repository.getBlockRepository().getDetachedBlockSignature();
BlockData parentBlockData = parentBlock.getBlockData();
while (true) { if (detachedBlockData != null) {
// No need to maintain transaction state while ploughing through the entire chain LOGGER.error(String.format("Block %d's reference does not match any block's signature", detachedBlockData.getHeight()));
repository.discardChanges();
BlockData childBlockData = parentBlock.getChild(); // Wait for blockchain lock (whereas orphan() only tries to get lock)
if (childBlockData == null) ReentrantLock blockchainLock = Controller.getInstance().getBlockchainLock();
break; blockchainLock.lock();
try {
if (!Arrays.equals(childBlockData.getReference(), parentBlock.getSignature())) { LOGGER.info(String.format("Orphaning back to block %d", detachedBlockData.getHeight() - 1));
LOGGER.error(String.format("Block %d's reference does not match block %d's signature", childBlockData.getHeight(), parentBlockData.getHeight())); orphan(detachedBlockData.getHeight() - 1);
rebuildBlockchain(); } finally {
return; blockchainLock.unlock();
} }
parentBlock = new Block(repository, childBlockData);
parentBlockData = childBlockData;
} }
} }
} }
@ -523,9 +517,9 @@ public class BlockChain {
private static void rebuildBlockchain() throws DataException { private static void rebuildBlockchain() throws DataException {
// (Re)build repository // (Re)build repository
try (final Repository repository = RepositoryManager.getRepository()) { RepositoryManager.rebuild();
repository.rebuild();
try (final Repository repository = RepositoryManager.getRepository()) {
GenesisBlock genesisBlock = GenesisBlock.getInstance(repository); GenesisBlock genesisBlock = GenesisBlock.getInstance(repository);
// Add Genesis Block to blockchain // Add Genesis Block to blockchain
@ -533,7 +527,7 @@ public class BlockChain {
repository.saveChanges(); repository.saveChanges();
// Give Network a change to install initial seed peers // Give Network a chance to install initial seed peers
Network.installInitialPeers(repository); Network.installInitialPeers(repository);
} }
} }

View File

@ -32,6 +32,7 @@ import org.qora.transform.TransformationException;
import org.qora.transform.transaction.TransactionTransformer; import org.qora.transform.transaction.TransactionTransformer;
import com.google.common.primitives.Bytes; import com.google.common.primitives.Bytes;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs; import com.google.common.primitives.Longs;
public class GenesisBlock extends Block { public class GenesisBlock extends Block {
@ -126,9 +127,9 @@ public class GenesisBlock extends Block {
int transactionCount = transactionsData.size(); int transactionCount = transactionsData.size();
BigDecimal totalFees = BigDecimal.ZERO.setScale(8); BigDecimal totalFees = BigDecimal.ZERO.setScale(8);
byte[] minterPublicKey = GenesisAccount.PUBLIC_KEY; byte[] minterPublicKey = GenesisAccount.PUBLIC_KEY;
byte[] bytesForSignature = getBytesForSignature(info.version, reference, minterPublicKey); byte[] bytesForSignature = getBytesForMinterSignature(info.timestamp, reference, minterPublicKey);
byte[] minterSignature = calcSignature(bytesForSignature); byte[] minterSignature = calcGenesisMinterSignature(bytesForSignature);
byte[] transactionsSignature = minterSignature; byte[] transactionsSignature = calcGenesisTransactionsSignature();
int height = 1; int height = 1;
int atCount = 0; int atCount = 0;
BigDecimal atFees = BigDecimal.ZERO.setScale(8); BigDecimal atFees = BigDecimal.ZERO.setScale(8);
@ -197,31 +198,29 @@ public class GenesisBlock extends Block {
} }
/** /**
* Generate genesis block minter/transactions signature. * Generate genesis block minter signature.
* <p> * <p>
* This is handled differently as there is no private key for the genesis account and so no way to sign data. * This is handled differently as there is no private key for the genesis account and so no way to sign data.
* <p>
* Instead we return the SHA-256 digest of the block, duplicated so that the returned byte[] is the same length as normal block signatures.
* *
* @return byte[] * @return byte[]
*/ */
private static byte[] calcSignature(byte[] bytes) { private static byte[] calcGenesisMinterSignature(byte[] bytes) {
byte[] digest = Crypto.digest(bytes); return Crypto.dupDigest(bytes);
return Bytes.concat(digest, digest);
} }
private static byte[] getBytesForSignature(int version, byte[] reference, byte[] minterPublicKey) { private static byte[] getBytesForMinterSignature(long timestamp, byte[] reference, byte[] minterPublicKey) {
try { try {
// Passing expected size to ByteArrayOutputStream avoids reallocation when adding more bytes than default 32. // Passing expected size to ByteArrayOutputStream avoids reallocation when adding more bytes than default 32.
// See below for explanation of some of the values used to calculated expected size. // See below for explanation of some of the values used to calculated expected size.
ByteArrayOutputStream bytes = new ByteArrayOutputStream(8 + 64 + 8 + 32); ByteArrayOutputStream bytes = new ByteArrayOutputStream(8 + 64 + 8 + 32);
/* /*
* NOTE: Historic code had genesis block using Longs.toByteArray() compared to standard block's Ints.toByteArray. The subsequent * NOTE: Historic code had genesis block using Longs.toByteArray(version) compared to standard block's Ints.toByteArray. The subsequent
* Bytes.ensureCapacity(versionBytes, 0, 4) did not truncate versionBytes back to 4 bytes either. This means 8 bytes were used even though * Bytes.ensureCapacity(versionBytes, 0, 4) did not truncate versionBytes back to 4 bytes either. This means 8 bytes were used even though
* VERSION_LENGTH is set to 4. Correcting this historic bug will break genesis block signatures! * VERSION_LENGTH is set to 4. Correcting this historic bug will break genesis block signatures!
*/ */
bytes.write(Longs.toByteArray(version)); // For Qortal, we use genesis timestamp instead
bytes.write(Longs.toByteArray(timestamp));
/* /*
* NOTE: Historic code had the reference expanded to only 64 bytes whereas standard block references are 128 bytes. Correcting this historic bug * NOTE: Historic code had the reference expanded to only 64 bytes whereas standard block references are 128 bytes. Correcting this historic bug
@ -238,22 +237,41 @@ public class GenesisBlock extends Block {
} }
} }
private static byte[] calcGenesisTransactionsSignature() {
// transaction index (int), transaction type (int), creator pubkey (32): so 40 bytes each
ByteArrayOutputStream bytes = new ByteArrayOutputStream(transactionsData.size() * (4 + 4 + 32));
try {
for (int ti = 0; ti < transactionsData.size(); ++ti) {
bytes.write(Ints.toByteArray(ti));
bytes.write(Ints.toByteArray(transactionsData.get(ti).getType().value));
bytes.write(transactionsData.get(ti).getCreatorPublicKey());
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return Crypto.dupDigest(bytes.toByteArray());
}
/** Convenience method for calculating genesis block signatures from block data */ /** Convenience method for calculating genesis block signatures from block data */
private static byte[] calcSignature(BlockData blockData) { private static byte[] calcSignature(BlockData blockData) {
byte[] bytes = getBytesForSignature(blockData.getVersion(), blockData.getReference(), blockData.getMinterPublicKey()); byte[] bytes = getBytesForMinterSignature(blockData.getTimestamp(), blockData.getReference(), blockData.getMinterPublicKey());
return calcSignature(bytes); return Bytes.concat(calcGenesisMinterSignature(bytes), calcGenesisTransactionsSignature());
} }
@Override @Override
public boolean isSignatureValid() { public boolean isSignatureValid() {
byte[] signature = calcSignature(this.blockData); byte[] signature = calcSignature(this.blockData);
// Validate block signature // Validate block minter's signature (first 64 bytes of block signature)
if (!Arrays.equals(signature, this.blockData.getMinterSignature())) if (!Arrays.equals(signature, 0, 64, this.blockData.getMinterSignature(), 0, 64))
return false; return false;
// Validate transactions signature // Validate transactions signature (last 64 bytes of block signature)
if (!Arrays.equals(signature, this.blockData.getTransactionsSignature())) if (!Arrays.equals(signature, 64, 128, this.blockData.getTransactionsSignature(), 0, 64))
return false; return false;
return true; return true;

View File

@ -8,6 +8,8 @@ import org.qora.account.Account;
import org.qora.block.BlockChain; import org.qora.block.BlockChain;
import org.qora.utils.Base58; import org.qora.utils.Base58;
import com.google.common.primitives.Bytes;
public class Crypto { public class Crypto {
public static final byte ADDRESS_VERSION = 58; public static final byte ADDRESS_VERSION = 58;
@ -44,6 +46,19 @@ public class Crypto {
return digest(digest(input)); return digest(digest(input));
} }
/**
* Returns 64-byte duplicated digest of message passed in input.
* <p>
* Effectively <tt>Bytes.concat(digest(input), digest(input)).
*
* @param addressVersion
* @param input
*/
public static byte[] dupDigest(byte[] input) {
final byte[] digest = digest(input);
return Bytes.concat(digest, digest);
}
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private static String toAddress(byte addressVersion, byte[] input) { private static String toAddress(byte addressVersion, byte[] input) {
// SHA2-256 input to create new data and of known size // SHA2-256 input to create new data and of known size

View File

@ -136,6 +136,13 @@ public interface BlockRepository {
*/ */
public int trimOldOnlineAccountsSignatures(long timestamp) throws DataException; public int trimOldOnlineAccountsSignatures(long timestamp) throws DataException;
/**
* Returns first (lowest height) block that doesn't link back to genesis block.
*
* @throws DataException
*/
public BlockData getDetachedBlockSignature() throws DataException;
/** /**
* Saves block into repository. * Saves block into repository.
* *

View File

@ -2,6 +2,8 @@ package org.qora.repository;
public interface RepositoryFactory { public interface RepositoryFactory {
public RepositoryFactory reopen() throws DataException;
public Repository getRepository() throws DataException; public Repository getRepository() throws DataException;
public Repository tryRepository() throws DataException; public Repository tryRepository() throws DataException;

View File

@ -35,4 +35,16 @@ public abstract class RepositoryManager {
} }
} }
public static void rebuild() throws DataException {
RepositoryFactory oldRepositoryFactory = repositoryFactory;
// Grab handle repository reference before we close
Repository oldRepository = oldRepositoryFactory.getRepository();
// Use old repository reference to perform rebuild
oldRepository.rebuild();
repositoryFactory = oldRepositoryFactory.reopen();
}
} }

View File

@ -339,6 +339,21 @@ public class HSQLDBBlockRepository implements BlockRepository {
} }
} }
@Override
public BlockData getDetachedBlockSignature() throws DataException {
String sql = "SELECT " + BLOCK_DB_COLUMNS + " FROM Blocks "
+ "LEFT OUTER JOIN Blocks AS ParentBlocks "
+ "ON ParentBlocks.signature = Blocks.reference "
+ "WHERE ParentBlocks.signature IS NULL AND Blocks.height > 1 "
+ "ORDER BY Blocks.height ASC LIMIT 1";
try (ResultSet resultSet = this.repository.checkedExecute(sql)) {
return getBlockFromResultSet(resultSet);
} catch (SQLException e) {
throw new DataException("Error fetching block by signature from repository", e);
}
}
@Override @Override
public void save(BlockData blockData) throws DataException { public void save(BlockData blockData) throws DataException {
HSQLDBSaver saveHelper = new HSQLDBSaver("Blocks"); HSQLDBSaver saveHelper = new HSQLDBSaver("Blocks");

View File

@ -38,6 +38,7 @@ import org.qora.repository.DataException;
import org.qora.repository.NameRepository; import org.qora.repository.NameRepository;
import org.qora.repository.NetworkRepository; import org.qora.repository.NetworkRepository;
import org.qora.repository.Repository; import org.qora.repository.Repository;
import org.qora.repository.RepositoryManager;
import org.qora.repository.TransactionRepository; import org.qora.repository.TransactionRepository;
import org.qora.repository.VotingRepository; import org.qora.repository.VotingRepository;
import org.qora.repository.hsqldb.transaction.HSQLDBTransactionRepository; import org.qora.repository.hsqldb.transaction.HSQLDBTransactionRepository;
@ -223,6 +224,37 @@ public class HSQLDBRepository implements Repository {
@Override @Override
public void rebuild() throws DataException { public void rebuild() throws DataException {
LOGGER.info("Rebuilding repository from scratch");
// Clean out any previous backup
try {
String connectionUrl = this.connection.getMetaData().getURL();
String dbPathname = getDbPathname(connectionUrl);
if (dbPathname == null)
throw new DataException("Unable to locate repository for rebuild?");
// Close repository reference so we can close repository factory cleanly
this.close();
// Close repository factory to prevent access
RepositoryManager.closeRepositoryFactory();
// No need to wipe files for in-memory database
if (!dbPathname.equals("mem")) {
Path oldRepoDirPath = Paths.get(dbPathname).getParent();
// Delete old repository files
Files.walk(oldRepoDirPath)
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.filter(file -> file.getPath().startsWith(dbPathname))
.forEach(File::delete);
}
} catch (NoSuchFileException e) {
// Nothing to remove
} catch (SQLException | IOException e) {
throw new DataException("Unable to remove previous repository");
}
} }
@Override @Override
@ -252,6 +284,12 @@ public class HSQLDBRepository implements Repository {
if (dbPathname == null) if (dbPathname == null)
throw new DataException("Unable to locate repository for backup?"); throw new DataException("Unable to locate repository for backup?");
// Doesn't really make sense to backup an in-memory database...
if (dbPathname.equals("mem")) {
LOGGER.debug("Ignoring request to backup in-memory repository!");
return;
}
String backupUrl = buildBackupUrl(dbPathname); String backupUrl = buildBackupUrl(dbPathname);
String backupPathname = getDbPathname(backupUrl); String backupPathname = getDbPathname(backupUrl);
if (backupPathname == null) if (backupPathname == null)
@ -279,15 +317,18 @@ public class HSQLDBRepository implements Repository {
} }
} }
/** Returns DB pathname from passed connection URL. */ /** Returns DB pathname from passed connection URL. If memory DB, returns "mem". */
private static String getDbPathname(String connectionUrl) { private static String getDbPathname(String connectionUrl) {
Pattern pattern = Pattern.compile("file:(.*?);"); Pattern pattern = Pattern.compile("hsqldb:(mem|file):(.*?)(;|$)");
Matcher matcher = pattern.matcher(connectionUrl); Matcher matcher = pattern.matcher(connectionUrl);
if (!matcher.find()) if (!matcher.find())
return null; return null;
return matcher.group(1); if (matcher.group(1).equals("mem"))
return "mem";
else
return matcher.group(2);
} }
private static String buildBackupUrl(String dbPathname) { private static String buildBackupUrl(String dbPathname) {

View File

@ -71,6 +71,11 @@ public class HSQLDBRepositoryFactory implements RepositoryFactory {
} }
} }
@Override
public RepositoryFactory reopen() throws DataException {
return new HSQLDBRepositoryFactory(this.connectionUrl);
}
@Override @Override
public Repository getRepository() throws DataException { public Repository getRepository() throws DataException {
try { try {

View File

@ -57,7 +57,7 @@
}, },
"genesisInfo": { "genesisInfo": {
"version": 4, "version": 4,
"timestamp": "1575300000000", "timestamp": "1576150000000",
"transactions": [ "transactions": [
{ "type": "ISSUE_ASSET", "owner": "QUwGVHPPxJNJ2dq95abQNe79EyBN2K26zM", "assetName": "QORT", "description": "QORTAL coin", "quantity": 0, "isDivisible": true, "reference": "28u54WRcMfGujtQMZ9dNKFXVqucY7XfPihXAqPFsnx853NPUwfDJy1sMH5boCkahFgjUNYqc5fkduxdBhQTKgUsC", "data": "{}" }, { "type": "ISSUE_ASSET", "owner": "QUwGVHPPxJNJ2dq95abQNe79EyBN2K26zM", "assetName": "QORT", "description": "QORTAL coin", "quantity": 0, "isDivisible": true, "reference": "28u54WRcMfGujtQMZ9dNKFXVqucY7XfPihXAqPFsnx853NPUwfDJy1sMH5boCkahFgjUNYqc5fkduxdBhQTKgUsC", "data": "{}" },
{ "type": "ISSUE_ASSET", "owner": "QUwGVHPPxJNJ2dq95abQNe79EyBN2K26zM", "assetName": "QORA", "description": "Representative legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true }, { "type": "ISSUE_ASSET", "owner": "QUwGVHPPxJNJ2dq95abQNe79EyBN2K26zM", "assetName": "QORA", "description": "Representative legacy QORA", "quantity": 0, "isDivisible": true, "data": "{}", "isUnspendable": true },
@ -71,8 +71,8 @@
{ "type": "CREATE_GROUP", "creatorPublicKey": "6rNn9b3pYRrG9UKqzMWYZ9qa8F3Zgv2mVWrULGHUusb", "owner": "QcatTpaU1UneBs3fVHo8QN6mUmuceRVzFY", "groupName": "dev-group", "description": "developer group", "isOpen": false, "approvalThreshold": "PCT60", "minimumBlockDelay": 0, "maximumBlockDelay": 1440 }, { "type": "CREATE_GROUP", "creatorPublicKey": "6rNn9b3pYRrG9UKqzMWYZ9qa8F3Zgv2mVWrULGHUusb", "owner": "QcatTpaU1UneBs3fVHo8QN6mUmuceRVzFY", "groupName": "dev-group", "description": "developer group", "isOpen": false, "approvalThreshold": "PCT60", "minimumBlockDelay": 0, "maximumBlockDelay": 1440 },
{ "type": "ACCOUNT_LEVEL", "target": "QcrnYL6yNwHKuEzYLXQ8LewG3m2B5k9K5f", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "Qe9VPzQp3h4Kg3DHSHBUQ3AM3AiRBfCDfX", "level": 5 }, { "type": "ACCOUNT_LEVEL", "target": "Qe9VPzQp3h4Kg3DHSHBUQ3AM3AiRBfCDfX", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QcrnYL6yNwHKuEzYLXQ8LewG3m2B5k9K5f", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QVLuvt9krmxXwQPAeAhxzhuMF5i8F4aNs8", "level": 5 }, { "type": "ACCOUNT_LEVEL", "target": "QVLuvt9krmxXwQPAeAhxzhuMF5i8F4aNs8", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QPYfRd1uhnAgqkZNmjNCjgPhkguMnHWuc4", "level": 5 }, { "type": "ACCOUNT_LEVEL", "target": "QPYfRd1uhnAgqkZNmjNCjgPhkguMnHWuc4", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QM9zVbXXnfrtQ1X7zPQ5zxPYPAWTaVMXqZ", "level": 5 }, { "type": "ACCOUNT_LEVEL", "target": "QM9zVbXXnfrtQ1X7zPQ5zxPYPAWTaVMXqZ", "level": 5 },
@ -83,104 +83,201 @@
{ "type": "ACCOUNT_LEVEL", "target": "QYgVi26jUqMzJo4ahZV9yekQNnYKHBaX8r", "level": 5 }, { "type": "ACCOUNT_LEVEL", "target": "QYgVi26jUqMzJo4ahZV9yekQNnYKHBaX8r", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QTTrv8SWR8huV8TFYUEQhfZ1j1JmtL5p8G", "level": 5 }, { "type": "ACCOUNT_LEVEL", "target": "QTTrv8SWR8huV8TFYUEQhfZ1j1JmtL5p8G", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QQa3MTgdnru5B7wSqPcq7qXcZcpbDQ7oyE", "level": 5 }, { "type": "ACCOUNT_LEVEL", "target": "QQa3MTgdnru5B7wSqPcq7qXcZcpbDQ7oyE", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QWe1iPDudLU189BggPykbH1DrAeaFEgX6W", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QUvoLFfkuVuRe1KGMLQS4nUHry6CBTuTYz", "level": 5 }, { "type": "ACCOUNT_LEVEL", "target": "QUvoLFfkuVuRe1KGMLQS4nUHry6CBTuTYz", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QTEE4ZJXv68ke4841HWjTLAAU8mfccxwbE", "level": 5 }, { "type": "ACCOUNT_LEVEL", "target": "QTEE4ZJXv68ke4841HWjTLAAU8mfccxwbE", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QQoHo1x4hvZcSFbj2uQAXQhq2ZXBUgPeNj", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QXan6JJ1WuRi7GigvFDjtTzJY1rfYEqEqv", "level": 5 }, { "type": "ACCOUNT_LEVEL", "target": "QXan6JJ1WuRi7GigvFDjtTzJY1rfYEqEqv", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QQoHo1x4hvZcSFbj2uQAXQhq2ZXBUgPeNj", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QVurebcEbe4USR4xcS3Mbk12mhxsjRX31u", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QfmM8dgfikTB2FYVuJ9owzQXVm8wP7T4QT", "level": 5 }, { "type": "ACCOUNT_LEVEL", "target": "QfmM8dgfikTB2FYVuJ9owzQXVm8wP7T4QT", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QPUMyJ59kkrp75tDzDPxSyw1GWCrbC2cS2", "level": 5 }, { "type": "ACCOUNT_LEVEL", "target": "QPUMyJ59kkrp75tDzDPxSyw1GWCrbC2cS2", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QVurebcEbe4USR4xcS3Mbk12mhxsjRX31u", "level": 4 }, { "type": "ACCOUNT_LEVEL", "target": "Qc9dZchoYfc1eRJhSLXR9rxSHcqNB47Dex", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "Qc9dZchoYfc1eRJhSLXR9rxSHcqNB47Dex", "level": 4 }, { "type": "ACCOUNT_LEVEL", "target": "QTMTFswUU83XVmk6T4Gez7qUJCccbAad7S", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QTMTFswUU83XVmk6T4Gez7qUJCccbAad7S", "level": 4 }, { "type": "ACCOUNT_LEVEL", "target": "QQEZEGWt3sAPwEWYD2RQ6tMwnpkayG81dY", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QQEZEGWt3sAPwEWYD2RQ6tMwnpkayG81dY", "level": 4 }, { "type": "ACCOUNT_LEVEL", "target": "QPcTWoAhYWmwjmWbQAS8muisrQVaLJMbg7", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QPcTWoAhYWmwjmWbQAS8muisrQVaLJMbg7", "level": 4 }, { "type": "ACCOUNT_LEVEL", "target": "QWpJxitn53ovwknQfrCaqivvoUNuPrX2sb", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QWpJxitn53ovwknQfrCaqivvoUNuPrX2sb", "level": 4 }, { "type": "ACCOUNT_LEVEL", "target": "QLpLY9o3X21q7q4L6u5JdDuMskYA838iYE", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QLpLY9o3X21q7q4L6u5JdDuMskYA838iYE", "level": 4 }, { "type": "ACCOUNT_LEVEL", "target": "QdGbhtkFHUqd9nK9UegxxGXD1eSRYSoKjt", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QdGbhtkFHUqd9nK9UegxxGXD1eSRYSoKjt", "level": 4 }, { "type": "ACCOUNT_LEVEL", "target": "QP8xG56L8b28h1mguSk9LuzNhxbHgAoL9b", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QP8xG56L8b28h1mguSk9LuzNhxbHgAoL9b", "level": 4 }, { "type": "ACCOUNT_LEVEL", "target": "QfjL32jLsxtumbfx6ufmfCFCBccVCQFkrh", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QfjL32jLsxtumbfx6ufmfCFCBccVCQFkrh", "level": 4 }, { "type": "ACCOUNT_LEVEL", "target": "QgpAW6uqwNR58gNYWRCVXNLm4F5TuckAw4", "level": 5 },
{ "type": "ACCOUNT_LEVEL", "target": "QgpAW6uqwNR58gNYWRCVXNLm4F5TuckAw4", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QbwgBD6LWdk1hZsb8EwdVVmDZdvpxMzyGT", "level": 4 }, { "type": "ACCOUNT_LEVEL", "target": "QbwgBD6LWdk1hZsb8EwdVVmDZdvpxMzyGT", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QawB5MesBratjs2d9EMnXnrN4EC7gw7LRw", "level": 4 }, { "type": "ACCOUNT_LEVEL", "target": "QawB5MesBratjs2d9EMnXnrN4EC7gw7LRw", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QXKmtkHHwaUQzGeHHG2dFiHUnKAp815Mzq", "level": 4 }, { "type": "ACCOUNT_LEVEL", "target": "QXKmtkHHwaUQzGeHHG2dFiHUnKAp815Mzq", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QdtAQm1EGNgM7QDSaC2qvV9WdpRHwpApUT", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QZkThgFfExognAbxLjYZGVHpL7X6g3EG4A", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QRFHr4jnVgvAsPTubeSrh8bPy1yzwzYaWD", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QdXe21sjY8smjVmiAUgZY8xWVzwgxMgK5A", "level": 4 }, { "type": "ACCOUNT_LEVEL", "target": "QdXe21sjY8smjVmiAUgZY8xWVzwgxMgK5A", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QbH8srDKeS5VcsQsgsaF3nqCzGT1NqfsTx", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QZkThgFfExognAbxLjYZGVHpL7X6g3EG4A", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QVkQTr8PzDTaNxhvrC47UUxUi6V987a5qL", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QdtAQm1EGNgM7QDSaC2qvV9WdpRHwpApUT", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QbqRyFw7Xu6Nsb4FraaUSe7nUPukuUpekG", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QbH8srDKeS5VcsQsgsaF3nqCzGT1NqfsTx", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QUzUCfoakDqBaL5zBgfvTKLHcuxbUfB38Q", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QRFHr4jnVgvAsPTubeSrh8bPy1yzwzYaWD", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QSBJuNoCAFUTcevuCTcMi3i5nzNPhC5R4b", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QVkQTr8PzDTaNxhvrC47UUxUi6V987a5qL", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QguNJ4evpN9i76dYHysTzLiKoWKFhE4B4U", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QguNJ4evpN9i76dYHysTzLiKoWKFhE4B4U", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QiBYApdEYRwsFYjt59UJqZV55wcwykvhsh", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QbqRyFw7Xu6Nsb4FraaUSe7nUPukuUpekG", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QhMEWhZCufhKLkfuNU2DAzj1mmWoAxX147", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QUzUCfoakDqBaL5zBgfvTKLHcuxbUfB38Q", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QNJ8jDx6Mni2GKLHEY1BMh9xDumT3vnJQM", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QSBJuNoCAFUTcevuCTcMi3i5nzNPhC5R4b", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QWe1iPDudLU189BggPykbH1DrAeaFEgX6W", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QiBYApdEYRwsFYjt59UJqZV55wcwykvhsh", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QZsygC1chppsJK1cnaHG4fEsNaDYfLF7ZJ", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QZvHW7amu5DNktsBgaMrR1brHZhhhVwKLW", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QaFN7DWcGF7keNACJpwCVnegePbfsAoFCw", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QNJ8jDx6Mni2GKLHEY1BMh9xDumT3vnJQM", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "Qgwb5SLVGAperXAMoVNBDvGpVAxTVY7f6F", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QhMEWhZCufhKLkfuNU2DAzj1mmWoAxX147", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QXv4WiqgryFPi8BgX7RU7gqtAgrVutmU4S", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "Qj5ncwncQY4KPYgKHD1eYpXHbR717PeLcJ", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QjEAs2or122weKppv5zALzoQzXxbsDjy3f", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QjrC8NXwR8gFkEauvRwCPxqHroPFqAJbhK", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QY1RFZTD2ogRohf3UrdT4g1Qo9D122AZDN", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QcU4VhU9ohDXU4k4AUMapgJRYSzEpizjLN", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QZsygC1chppsJK1cnaHG4fEsNaDYfLF7ZJ", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QaFN7DWcGF7keNACJpwCVnegePbfsAoFCw", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QYGNMWBmqWgVtMWGHypAsKhDVQw5mrFZww", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QRKRk5HVADsN1LHygK7q2pA7dWnYKnPpCT", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QSGB4Rd2xhd6UmA9LALTQ4f89Tfsz5VajU", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QNVKrjEq5bZdiDtgo64m5kz87rTHqCwvCP", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QNMDKE7XTujNQkuQorcHXw6hL7qRvyaTjr", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QY6ZGZdi8h5op2VrRXkG1W5Jp3feLwp7ZD", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "Qgwb5SLVGAperXAMoVNBDvGpVAxTVY7f6F", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QNHdGeFJmPcDdN8prPzPL4bk2dpnJ2ZZFr", "level": 4 },
{ "type": "ACCOUNT_LEVEL", "target": "QUXga5K8nzd9EqYtvEesZWEYuA688h6D3d", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QfbX8JJupEw5ckNtU4upQgET35oLTr5e6v", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QRaDef6H2zYfefqLwYGmUg7T6DAqo6DDqc", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QSkiGy3v3MwvGy3aACuyLDv3Xy2AWAYfPS", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QSkiGy3v3MwvGy3aACuyLDv3Xy2AWAYfPS", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QeUc5NfzubZD4eA4eJ7bfXAFraAWc7jVz5", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QibuD4c6gvXgS4iut7q3sXuVb23rgFJq2M", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QfPcwetW3BErP4ySTurxFJSHpNkNXPEhGk", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QTpYQqRyMekaEuECziirzy3HvCVofZS1wJ", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QU8XJyQEZxSHgrS1XyooWUo5MmruXg36Pe", "level": 3 }, { "type": "ACCOUNT_LEVEL", "target": "QXv4WiqgryFPi8BgX7RU7gqtAgrVutmU4S", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QeDhJRqTyeDmcgGJoms6FHK49ZGVpVahxg", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "QawSgZ7i2LLFTKyPxQptk9gN526ihy5yZi", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QMuWNAJ2tbeViHtBUN3yD2KARrrzcanLAd", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QUGo9SErgc6ceB5aBzcSJDNqBkQ9eaCKZS", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QdFZk74skMUu4rKMPEmcSVwR87LNDe6o3Y", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QScBgSw74MquesXmVJxerX3YgyhtShRr4q", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QRWEbzH4niUcu9dL3Yq42X4j89aqQk3qWw", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QYD3kXchZ86vUyJBXNCVQ4LUvTAd6PUZW3", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QhQdzLn36SDgrgoMfvdZAkoWtTUHpB3acJ", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QWL7kZp6Pdd1bhxZ6SXPhVf5g7GParG9CC", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QjgGeEkyiXa43pyqkXxZbvAChQpVYfUyKz", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QbxJvwrEHZs7MDE8rbqBwZAZkcywue5F3W", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QWwrtjBL4ah965XPXHYJhymreC9jyryNLZ", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QjEaMxcBKMsj91ytKe6GdTBJP8Mu1Ru3r4", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QPusqAVBVFGAAeE7RdospttA18AuyLP7sB", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "Qd1Px9vhWuEmF2SbLx3Ez7HhGtifGMa8TJ", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QWuW2YMygVtWieUo6a4yayD1xFDWdnmo5j", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QbYTowTHCr9WzfrR6b8uDfJKwL41nG1vyr", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QNw9xAm9TUerin9QsapCPL9mV6zmoXyJrh", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QSq8y4ZrSbF55ZddWNcw1ett2LDtjQEvNn", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QYuMATkLjz7YB6s4EG1aWCmmmrAPj3W9Ce", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QNiTnonHpXTeUrgNdyYWVDPP4ZdjkLpW72", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QjrCFCi6dqvka4UELg2SHhM2oWnQWepd1o", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QREtYDhP4HkpeCCZroemuGXMGVFoZHH3Lp", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QdXdUxnyKGGo7eEfTcx85oEikNe5nYnuwa", "level": 3 },
{ "type": "ACCOUNT_LEVEL", "target": "QWBFK5h61ZxGfqQpEkwwKTcLAo8t9VWe4K", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QjEAs2or122weKppv5zALzoQzXxbsDjy3f", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QgesuKa3zwx8VAseF1oHZAFHMf29k8ergq", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QUZQPWhrxpze32vGiux6wa85kg9iwuhCDx", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QWinRb65f2g3yBoaZvTrQKQk7CW7vfBgGX", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QQaKBSjAt9RK2bqJoSriR77X4ULstGzrFQ", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QdwSxr3t4hdGHjQFy6EVGR9yGMipefsTuo", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QZ2gi6BhUNpGmrErgJLFuY1WHy6xK1J7qX", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QXYk68x2tiUrDBv8eq6wd4KtBmLHYiC4zR", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QTyokTJrR4b2y76An3BFUEbqQy5vvg76iN", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QisSQZ7Et7Rfzx2SCC2o9UDSeRZWMyFKWc", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QPyx2bNiAnJEjitfeAh8jZXzQVKio2B7Mi", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QeUc5NfzubZD4eA4eJ7bfXAFraAWc7jVz5", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QU8XJyQEZxSHgrS1XyooWUo5MmruXg36Pe", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QfPcwetW3BErP4ySTurxFJSHpNkNXPEhGk", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QQHWFSJpzuDupPfcTvGMRNJp2UGz98Kb7j", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "QQHWFSJpzuDupPfcTvGMRNJp2UGz98Kb7j", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QeDhJRqTyeDmcgGJoms6FHK49ZGVpVahxg", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QdepeWWLMD3LiDRKkKBria29rDhZP9V5RJ", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "QdepeWWLMD3LiDRKkKBria29rDhZP9V5RJ", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QZvHW7amu5DNktsBgaMrR1brHZhhhVwKLW", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QjrC8NXwR8gFkEauvRwCPxqHroPFqAJbhK", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QWez1VBfYVJ8KFoZ6MhJDzYVLbn5mr38VT", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "QWez1VBfYVJ8KFoZ6MhJDzYVLbn5mr38VT", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QYsh2NB6TogqV1iXHmHXcVaWw25WEYA94o", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "QYsh2NB6TogqV1iXHmHXcVaWw25WEYA94o", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QfhJM5CpX5MhfjCcopwfw7pgS6w1hVJ49E", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QMMh94Pfs5LVE4xJee1yggViqP1YDdQHT4", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "QMMh94Pfs5LVE4xJee1yggViqP1YDdQHT4", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QU9dnN47Nc5KaH7JwNoCZ7TANwCW5VX9iG", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "QU9dnN47Nc5KaH7JwNoCZ7TANwCW5VX9iG", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QXoW5M113C3SDUeFdjVVs2m1RT9XtzXS3z", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "QXoW5M113C3SDUeFdjVVs2m1RT9XtzXS3z", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QjsD7pMh2LpmgYudaaRM8gmzhBC4c9uwyj", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QMozpRT9aUunfmPh7EtQ6LPoth2JFJWBXC", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QeSh3t1AnaRcRThkkUTvvdMEouixCADeVh", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QZxcntxfJimHus9pgfvVVPbpHs5yU7ZMhB", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "QZxcntxfJimHus9pgfvVVPbpHs5yU7ZMhB", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "Qc2eRuYXtpATrg87Pr1WDXkUBCsgNRYcQF", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "QTtXS6fZGThRLq4qgkwM4ngBYkLoFyZ3bK", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QbEJ5tfeskASVnmLFeKzspuZJJb6cJVPZ4", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "QRBVE5gHumH6RUgEUxJdQ5417NUvc14k3F", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QWvTdm9LU1GSX9q6Rrvgx7xjo2iuV2Gxn1", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "QPqfuZpmyA6cK6WUFwcGeKH2Te1aegkHBM", "level": 2 },
{ "type": "ACCOUNT_LEVEL", "target": "QWuW2YMygVtWieUo6a4yayD1xFDWdnmo5j", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "Qc2eRuYXtpATrg87Pr1WDXkUBCsgNRYcQF", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QbGwYRV3UDek4VNpzoAVVQWfoKjZmm4qPb", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "QbEJ5tfeskASVnmLFeKzspuZJJb6cJVPZ4", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QYM76r3tuf6FJWz2USqVjwXJrV9tLMz1cj", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "QZjCgcSVvSRsFZeLJz9C5dTa36s3cSKqvB", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QU9K6pWhkok9mokkPDoCwgSu3j62ECuKLD", "level": 2 }, { "type": "ACCOUNT_LEVEL", "target": "QWvTdm9LU1GSX9q6Rrvgx7xjo2iuV2Gxn1", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QZbKMgYBwWGyTDJzoDir2aNqXsFdDp6fS9", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QZw7tgMttSySNMKfcMrEbdtnqHVrQ9w9fT", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QbGwYRV3UDek4VNpzoAVVQWfoKjZmm4qPb", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QYM76r3tuf6FJWz2USqVjwXJrV9tLMz1cj", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QUdjqijDoyc83K4WcMW1sCn7zLd2t1WTqn", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QUdjqijDoyc83K4WcMW1sCn7zLd2t1WTqn", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QU9K6pWhkok9mokkPDoCwgSu3j62ECuKLD", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QZbKMgYBwWGyTDJzoDir2aNqXsFdDp6fS9", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QVEfMEeEHP768c9rEyi3WcH2JQwqheVDe3", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QVEfMEeEHP768c9rEyi3WcH2JQwqheVDe3", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QehM6hQZVkrYAst8WrBVdQiMFfTtDtbKQu", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QehM6hQZVkrYAst8WrBVdQiMFfTtDtbKQu", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QY7gQwZKiPYMHYjYASSDBhhAoyYaxmex17", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QY7gQwZKiPYMHYjYASSDBhhAoyYaxmex17", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QgmEtScSZWJmTUAidCZKj6gDr3LznZ6rr4", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QgmEtScSZWJmTUAidCZKj6gDr3LznZ6rr4", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "Qa9NXeLAvmaTsKackfDRmm1A9zy7JeEjgV", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QXqAtZJsLU6HFGTzuegjeUbmEW8cGEnYt6", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QXqAtZJsLU6HFGTzuegjeUbmEW8cGEnYt6", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QZJc1V32oFm8tufB4bk7fa3aepu4EdkeDU", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QVb7P596imucSwDqb5HHEjqpnAre615PbS", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QVb7P596imucSwDqb5HHEjqpnAre615PbS", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QNMtHRjEWPgZUVCpiC2qE2LyJsxq1BC1Yj", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QNMtHRjEWPgZUVCpiC2qE2LyJsxq1BC1Yj", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QUNTxxwr9f47RcwY48ZUP6FmmKnWCsxes5", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QUNTxxwr9f47RcwY48ZUP6FmmKnWCsxes5", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QSTDdguUfKe6TaQrik2zq4Xrbu6unxNa9o", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QSTDdguUfKe6TaQrik2zq4Xrbu6unxNa9o", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QgsxpySDm1qja6D2EyKuHPiUhyTM1RMk6c", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QgsxpySDm1qja6D2EyKuHPiUhyTM1RMk6c", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QaZs97g4Mbq9tXMoBWbhw3jFvBBVkWKS5F", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QWZwi5NUzHuJfg5fh9HzjWRpQc1fmMknAh", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QWZwi5NUzHuJfg5fh9HzjWRpQc1fmMknAh", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QMb2cAKb2BUxknneuoXQynJ7uzosJ57Top", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QMb2cAKb2BUxknneuoXQynJ7uzosJ57Top", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QQXgH4CnQCB76BbXhsApu6ShhohFfvoXv7", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QP9vU5yTsBjuTSFxH5Cb9VXYNRHKhMNAJ4", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QP9vU5yTsBjuTSFxH5Cb9VXYNRHKhMNAJ4", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QXm5e16Lq6dnYwpZJ8Rn2cME3ziHZfRRnp", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QXm5e16Lq6dnYwpZJ8Rn2cME3ziHZfRRnp", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "Qa9NXeLAvmaTsKackfDRmm1A9zy7JeEjgV", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QiQernJdiP4zCECB93v247FUtovkfJyTYm", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "QiQernJdiP4zCECB93v247FUtovkfJyTYm", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "Qa4KygekpW1Brr3D66K6rGtS5AY8qkhvD3", "level": 1 }, { "type": "ACCOUNT_LEVEL", "target": "Qa4KygekpW1Brr3D66K6rGtS5AY8qkhvD3", "level": 1 },
{ "type": "ACCOUNT_LEVEL", "target": "QSkicapNH35a3UebSxxSMCfntBhwwi6veW", "level": 1 },
{ "type": "GENESIS", "recipient": "QdoLZqB3pY4NgbSpvbsFzBDq2LcShjXsoq", "amount": "263574650.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QMtx2UmUuRZckCmRJRyxdzSAazHP8hU5rA", "amount": "160672815.43629771", "assetId": 1 }, { "type": "GENESIS", "recipient": "QMtx2UmUuRZckCmRJRyxdzSAazHP8hU5rA", "amount": "160672815.43629771", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QQKeokRiFCgAhBSdu1DUf5e1LCkgApvrxZ", "amount": "100000078.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QYoRWAxw6CVMeYeWHKJh3csmTVkVzjpdBo", "amount": "100000026.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QMkgf9Y6Ac2TUrynDvyhX69ekpC3P3GQmN", "amount": "99008835.47860426", "assetId": 1 }, { "type": "GENESIS", "recipient": "QMkgf9Y6Ac2TUrynDvyhX69ekpC3P3GQmN", "amount": "99008835.47860426", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QWZm17rRXeUehcM4TprVNNRSTHWQmG2bME", "amount": "62663714.00000000", "assetId": 1 }, { "type": "GENESIS", "recipient": "QWZm17rRXeUehcM4TprVNNRSTHWQmG2bME", "amount": "62663714.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "Qa95hURaNK4kPhDhbdmDFm2wMkkoWFZ4Zz", "amount": "40976709.97984710", "assetId": 1 }, { "type": "GENESIS", "recipient": "Qa95hURaNK4kPhDhbdmDFm2wMkkoWFZ4Zz", "amount": "40976709.97984710", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QZjDFrMrgeR9SGL8bprqyiXVtAZMVCXESZ", "amount": "37291276.42323117", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QaWReiLe5tAsTNoq7hMiSGNasJEXTX5bmn", "amount": "31465829.00562504", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QYsLsfwMRBPnunmuWmFkM4hvGsfooY8ssU", "amount": "25303386.66951814", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QgULJXk3qyLDr4EKkz48rxwwvWK7BDL8Ux", "amount": "22476856.86000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QNwedkYs6hToBRPZvBb6naKvDEgB7BeaKi", "amount": "21967101.30582773", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QgP7vQABSDJwuE8VTdVkiNnbkorqWWctQm", "amount": "20442665.63310002", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QLgBTDkt7t7WwbTd1RM8iGxu9FexPZcn7C", "amount": "19000025.40000000", "assetId": 1 }, { "type": "GENESIS", "recipient": "QLgBTDkt7t7WwbTd1RM8iGxu9FexPZcn7C", "amount": "19000025.40000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QQShonrAdJXg4CzhegtynzaBP7S631vKGq", "amount": "16577946.00000000", "assetId": 1 }, { "type": "GENESIS", "recipient": "QQShonrAdJXg4CzhegtynzaBP7S631vKGq", "amount": "16577946.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QcAVj3i3drVkiC9P8FtDgVdYz8Zeu61uNg", "amount": "13142764.62938834", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QLgewDr48AZxWbDbRZ12xEvCePwPj9bMBE", "amount": "12684967.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QPEoMF2dA7NHrHhsSG9zczCFwx9wFdWvzT", "amount": "10033147.61257500", "assetId": 1 }, { "type": "GENESIS", "recipient": "QPEoMF2dA7NHrHhsSG9zczCFwx9wFdWvzT", "amount": "10033147.61257500", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QWLhUT55hZHgdD7ayEqwHnF9h62dHV45G1", "amount": "9999999.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QjnHejJPyuyTRs7huzcqXtbM6sufWyLf9o", "amount": "9999999.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QjJjjBUJSZAMuYiwTyfJTFthH6SrofjG6d", "amount": "8871800.22712502", "assetId": 1 }, { "type": "GENESIS", "recipient": "QjJjjBUJSZAMuYiwTyfJTFthH6SrofjG6d", "amount": "8871800.22712502", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QRh9zNPmz5McxeWx3iCy2xnBRrBoYDZfMJ", "amount": "8739995.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QWGwGBzZG8UeNXJYZq9tjzN6ceriqTgMRd", "amount": "7825760.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QRj4VNEthakckhYpCJMEBhEFk12pa7GPJT", "amount": "7810001.00000000", "assetId": 1 }, { "type": "GENESIS", "recipient": "QRj4VNEthakckhYpCJMEBhEFk12pa7GPJT", "amount": "7810001.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QbdHzyw6q2hMAhg12JFbXSEcbrj43xNnYG", "amount": "7593814.00000000", "assetId": 1 }, { "type": "GENESIS", "recipient": "QbdHzyw6q2hMAhg12JFbXSEcbrj43xNnYG", "amount": "7593814.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QNFWWhmsun3HVUChjck8XqhsQW2tckNxxM", "amount": "7239123.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QeosmemBtE7aosv2QZhq1PTjqpKurKXKzy", "amount": "6185646.80750010", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QQM9B3ipQcSvATsxb4vgVuYs9kuxgnuBwG", "amount": "5032347.69657146", "assetId": 1 }, { "type": "GENESIS", "recipient": "QQM9B3ipQcSvATsxb4vgVuYs9kuxgnuBwG", "amount": "5032347.69657146", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QLu6X6CVhr6tovNR6k9pQijxN4DHiuLeJS", "amount": "4918400.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QPdkHcN8DBLuxaFf4Q4zXNn3rq2G78VgNt", "amount": "4128493.31116798", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QMNdPz11XubtvxXLGeiG3PHKaQW67LkZMp", "amount": "4056950.00000000", "assetId": 1 }, { "type": "GENESIS", "recipient": "QMNdPz11XubtvxXLGeiG3PHKaQW67LkZMp", "amount": "4056950.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QhUWSWWFt6vDy2qNFn68JPTPLjyDrzrh4D", "amount": "3220564.00000000", "assetId": 1 }, { "type": "GENESIS", "recipient": "QhUWSWWFt6vDy2qNFn68JPTPLjyDrzrh4D", "amount": "3220564.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QQ7wKkXyQtkwrgG6zeSHNrnDhXQ6fGUsYS", "amount": "3088411.29750001", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QcxXT317FQi3mq9hrQggw7xZujPX63XCq7", "amount": "2779141.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QMTcDA7v1dbRXHkryn4ppiM9Q7LGZFNkVT", "amount": "2752011.00000000", "assetId": 1 }, { "type": "GENESIS", "recipient": "QMTcDA7v1dbRXHkryn4ppiM9Q7LGZFNkVT", "amount": "2752011.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QTekAqCoXPy5R7NE78GXxjSaXBuekZge88", "amount": "2740816.93000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QVQErjTVBkPTphbyDhPvhHKGX2etNXZsgy", "amount": "1999999.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QNPfWoyuvYaScXuCdiCM2PEzvD7PWybBvh", "amount": "1749402.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QV96D15Y3qM1r55odiDf7j2TTYY8jCMJPs", "amount": "1572208.70562500", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QLsEy8syg8EXttzajE8AWGg3CxccNR6YML", "amount": "1300001.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QLeNqYjzid2oJFL2iVtcHeAkyunuTsHae4", "amount": "1185185.44326193", "assetId": 1 }, { "type": "GENESIS", "recipient": "QLeNqYjzid2oJFL2iVtcHeAkyunuTsHae4", "amount": "1185185.44326193", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QaUhQiyBZpZWSmFo56zRu2XXfZVL4D2xii", "amount": "1033451.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QMrECKgkohx6ZXEMdLzikqBmAkdyHeQDqL", "amount": "997498.00000000", "assetId": 1 }, { "type": "GENESIS", "recipient": "QMrECKgkohx6ZXEMdLzikqBmAkdyHeQDqL", "amount": "997498.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QR1GoYcR3iasGNWtJjeNcZFPf9BH4TjCeC", "amount": "858153.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QMFysMKXLubP21BCYeYiSNP3v5mLhp81Cd", "amount": "676881.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QMdfkckSTcCMKnRRve51SEfZQPVLZg9S7b", "amount": "333086.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QN2UFyKfUsJBHmM5hZrrD2wrwZ1SctSfwQ", "amount": "296438.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QQRUVwMGifreiLv3FuPTTcA1WbsvhH7Mux", "amount": "102825.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QMQAG28pyv2aZVjWbKoRn39Ytir6rLPnTK", "amount": "100745.00000000", "assetId": 1 }, { "type": "GENESIS", "recipient": "QMQAG28pyv2aZVjWbKoRn39Ytir6rLPnTK", "amount": "100745.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QgkNZyrj4zAEAwCDZHTLQ7RcbcCTwcNzPL", "amount": "99999.09400001", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QLnyXdhGDVEBmByTtjTZihVE3UnReghNyd", "amount": "78296.75000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QTHQ9pFMoraWTCS1tuFzuwWSXu7uVJ18VF", "amount": "40395.00000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QVZAQrQHPD8rePZ5hWKx4uj7Ty4GEBe15D", "amount": "2989.50000000", "assetId": 1 }, { "type": "GENESIS", "recipient": "QVZAQrQHPD8rePZ5hWKx4uj7Ty4GEBe15D", "amount": "2989.50000000", "assetId": 1 },
{ "type": "GENESIS", "recipient": "QPZTxWtCmH6Y6zwwntjnPDfKG6zNKRivqJ", "amount": "1282.61375000", "assetId": 1 } { "type": "GENESIS", "recipient": "QPZTxWtCmH6Y6zwwntjnPDfKG6zNKRivqJ", "amount": "1282.61375000", "assetId": 1 }