AccountStateServiceImpl implements AccountStateService { @Override public Fun.Tuple2<Block, Transaction> generateGenesisBlock(String initialAddress, BigInteger initialValue, AppState state, AppContext context) { logger.traceEntry("params: {} {} {} {}", initialAddress, initialValue, state, context); PrivateKey privateKey = context.getPrivateKey(); Util.check(!(initialAddress == null || initialAddress.isEmpty()), "initialAddress!=null"); Util.check(!(initialValue.compareTo(BigInteger.ZERO) < 0), "initialValue is less than zero"); Util.check(privateKey != null, "privateKey!=null"); if (initialValue.compareTo(Util.VALUE_MINTING) > 0) { initialValue = Util.VALUE_MINTING; } PrivateKey mintingPrivateKey = AppServiceProvider.getShardingService().getPrivateKeyForMinting(state.getShard()); PublicKey mintingPublicKey = AppServiceProvider.getShardingService().getPublicKeyForMinting(state.getShard()); logger.trace("Creating mint transaction..."); Transaction transactionMint = AppServiceProvider.getTransactionService().generateTransaction(mintingPublicKey, new PublicKey(Util.hexStringToByteArray(initialAddress)), initialValue, BigInteger.ZERO); logger.trace("Signing mint transaction..."); AppServiceProvider.getTransactionService().signTransaction(transactionMint, mintingPrivateKey.getValue(), mintingPublicKey.getValue()); logger.trace("Generating genesis block..."); Block genesisBlock = new Block(); genesisBlock.setShard(state.getShard()); genesisBlock.setNonce(BigInteger.ZERO); BlockUtil.addTransactionInBlock(genesisBlock, transactionMint); logger.trace("Setting timestamp and round..."); NTPClient ntpClient = state.getNtpClient(); genesisBlock.setTimestamp(AppServiceProvider.getChronologyService().getSynchronizedTime(ntpClient)); genesisBlock.setRoundIndex(0); List<String> nodeList = new ArrayList<>(); String self = state.getConnection().getPeer().peerID().toString(); nodeList.add(self); genesisBlock.setPeers(nodeList); logger.debug("done added {} peers to genesis block", genesisBlock.getPeers()); logger.trace("Computing state root hash..."); try { AccountsContext accountsContext = new AccountsContext(); accountsContext.setShard(state.getShard()); Accounts accountsTemp = new Accounts(accountsContext, new AccountsPersistenceUnit<>(accountsContext.getDatabasePath())); ExecutionService executionService = AppServiceProvider.getExecutionService(); ExecutionReport executionReport = executionService.processTransaction(transactionMint, accountsTemp); if (!executionReport.isOk()) { return logger.traceExit((Fun.Tuple2<Block, Transaction>) null); } genesisBlock.setAppStateHash(accountsTemp.getAccountsPersistenceUnit().getRootHash()); AppBlockManager.instance().signBlock(genesisBlock, privateKey); accountsTemp.getAccountsPersistenceUnit().close(); logger.trace("Genesis block created!"); } catch (Exception ex) { logger.catching(ex); logger.traceExit((Fun.Tuple2<Block, Transaction>) null); } return logger.traceExit(new Fun.Tuple2<>(genesisBlock, transactionMint)); }  @Override synchronized AccountState getOrCreateAccountState(AccountAddress address, Accounts accounts); @Override synchronized AccountState getAccountState(AccountAddress address, Accounts accounts); @Override synchronized void rollbackAccountStates(Accounts accounts); @Override synchronized void commitAccountStates(Accounts accounts); @Override synchronized void setAccountState(AccountAddress address, AccountState state, Accounts accounts); @Override byte[] convertAccountStateToRLP(AccountState accountState); @Override AccountState convertToAccountStateFromRLP(byte[] data); @Override void initialMintingToKnownAddress(Accounts accounts); @Override Fun.Tuple2<Block, Transaction> generateGenesisBlock(String initialAddress, BigInteger initialValue, AppState state, AppContext context);  }
@Test public void testGenerateGenesisBlock() throws IOException, ClassNotFoundException { AccountsContext accountsContext = new AccountsContext(); AppState appState = new AppState(); AppContext appContext = new AppContext(); appContext.setPort(4000); appContext.setMasterPeerPort(4000); appContext.setNodeName("node"); PrivateKey privateKey = new PrivateKey(); PublicKey publicKey = new PublicKey(new PrivateKey()); appContext.setPrivateKey(privateKey); Shard shard = AppServiceProvider.getShardingService().getShard(publicKey.getValue()); accountsContext.setShard(shard); appState.setShard(shard); appState.setConnection( AppServiceProvider.getP2PConnectionService().createConnection(appContext)); accounts = new Accounts(accountsContext, new AccountsPersistenceUnit<>("")); String initialAddress = Util.byteArrayToHexString(publicKey.getValue()); accountStateService.generateGenesisBlock(initialAddress, BigInteger.TEN, appState, appContext); AccountState state = accountStateService.getAccountState(AppServiceProvider.getShardingService().getAddressForMinting(accounts.getShard()), accounts); Assert.assertNotNull(state); Assert.assertTrue(state.getBalance().compareTo(Util.VALUE_MINTING) == 0); Assert.assertTrue(state.getBalance().compareTo(Util.VALUE_MINTING) == 0); }