package test; import static org.junit.Assert.*; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import ntp.NTP; import org.junit.Test; import qora.BlockGenerator; import qora.Synchronizer; import qora.account.PrivateKeyAccount; import qora.block.Block; import qora.block.GenesisBlock; import qora.crypto.Crypto; import qora.crypto.Ed25519; import qora.transaction.GenesisTransaction; import qora.transaction.Transaction; import database.DBSet; public class SynchronizerTests { @Test public void synchronizeNoCommonBlock() { Ed25519.load(); //GENERATE 5 BLOCKS FROM ACCOUNT 1 DBSet databaseSet = DBSet.createEmptyDatabaseSet(); //PROCESS GENESISBLOCK GenesisBlock genesisBlock = new GenesisBlock(); genesisBlock.process(databaseSet); //CREATE KNOWN ACCOUNT byte[] seed = Crypto.getInstance().digest("test".getBytes()); byte[] privateKey = Crypto.getInstance().createKeyPair(seed).getA(); PrivateKeyAccount generator = new PrivateKeyAccount(privateKey); //PROCESS GENESIS TRANSACTION TO MAKE SURE GENERATOR HAS FUNDS Transaction transaction = new GenesisTransaction(generator, BigDecimal.valueOf(1000).setScale(8), NTP.getTime()); transaction.process(databaseSet); //GENERATE 5 NEXT BLOCKS Block lastBlock = genesisBlock; BlockGenerator blockGenerator = new BlockGenerator(); List<Block> firstBlocks = new ArrayList<Block>(); for(int i=0; i<5; i++) { //GENERATE NEXT BLOCK Block newBlock = blockGenerator.generateNextBlock(databaseSet, generator, lastBlock); //ADD TRANSACTION SIGNATURE byte[] transactionsSignature = Crypto.getInstance().sign(generator, newBlock.getGeneratorSignature()); newBlock.setTransactionsSignature(transactionsSignature); //PROCESS NEW BLOCK newBlock.process(databaseSet); //ADD TO LIST firstBlocks.add(newBlock); //LAST BLOCK IS NEW BLOCK lastBlock = newBlock; } //GENERATE NEXT 5 BLOCK FROM ACCOUNT 2 ON FORK seed = Crypto.getInstance().digest("test2".getBytes()); privateKey = Crypto.getInstance().createKeyPair(seed).getA(); generator = new PrivateKeyAccount(privateKey); //PROCESS GENESIS TRANSACTION TO MAKE SURE GENERATOR HAS FUNDS transaction = new GenesisTransaction(generator, BigDecimal.valueOf(1000).setScale(8), NTP.getTime()); transaction.process(databaseSet); //FORK DBSet fork = databaseSet.fork(); //GENERATE NEXT 5 BLOCKS List<Block> newBlocks = new ArrayList<Block>(); for(int i=0; i<5; i++) { //GENERATE NEXT BLOCK Block newBlock = blockGenerator.generateNextBlock(fork, generator, lastBlock); //ADD TRANSACTION SIGNATURE byte[] transactionsSignature = Crypto.getInstance().sign(generator, newBlock.getGeneratorSignature()); newBlock.setTransactionsSignature(transactionsSignature); //PROCESS NEW BLOCK newBlock.process(fork); //ADD TO LIST newBlocks.add(newBlock); //LAST BLOCK IS NEW BLOCK lastBlock = newBlock; } //SYNCHRONIZE DB FROM ACCOUNT 1 WITH NEXT 5 BLOCKS OF ACCOUNT 2 Synchronizer synchronizer = new Synchronizer(); try { synchronizer.synchronize(databaseSet, null, newBlocks); //CHECK LAST 5 BLOCKS lastBlock = databaseSet.getBlockMap().getLastBlock(); for(int i=4; i>=0; i--) { //CHECK LAST BLOCK assertEquals(true, Arrays.equals(newBlocks.get(i).getSignature(), lastBlock.getSignature())); lastBlock = lastBlock.getParent(databaseSet); } //CHECK LAST 5 BLOCKS for(int i=4; i>=0; i--) { //CHECK LAST BLOCK assertEquals(true, Arrays.equals(firstBlocks.get(i).getSignature(), lastBlock.getSignature())); lastBlock = lastBlock.getParent(databaseSet); } //CHECK LAST BLOCK assertEquals(true, Arrays.equals(lastBlock.getSignature(), genesisBlock.getSignature())); //CHECK HEIGHT assertEquals(11, databaseSet.getBlockMap().getLastBlock().getHeight(databaseSet)); } catch(Exception e) { fail("Exception during synchronize"); } } @Test public void synchronizeCommonBlock() { Ed25519.load(); //GENERATE 5 BLOCKS FROM ACCOUNT 1 DBSet databaseSet = DBSet.createEmptyDatabaseSet(); DBSet databaseSet2 = DBSet.createEmptyDatabaseSet(); //PROCESS GENESISBLOCK GenesisBlock genesisBlock = new GenesisBlock(); genesisBlock.process(databaseSet); genesisBlock.process(databaseSet2); //CREATE KNOWN ACCOUNT byte[] seed = Crypto.getInstance().digest("test".getBytes()); byte[] privateKey = Crypto.getInstance().createKeyPair(seed).getA(); PrivateKeyAccount generator = new PrivateKeyAccount(privateKey); //PROCESS GENESIS TRANSACTION TO MAKE SURE GENERATOR HAS FUNDS Transaction transaction = new GenesisTransaction(generator, BigDecimal.valueOf(1000).setScale(8), NTP.getTime()); transaction.process(databaseSet); transaction.process(databaseSet2); //CREATE KNOWN ACCOUNT 2 byte[] seed2 = Crypto.getInstance().digest("test2".getBytes()); byte[] privateKey2 = Crypto.getInstance().createKeyPair(seed2).getA(); PrivateKeyAccount generator2 = new PrivateKeyAccount(privateKey2); //PROCESS GENESIS TRANSACTION TO MAKE SURE GENERATOR2 HAS FUNDS transaction = new GenesisTransaction(generator2, BigDecimal.valueOf(1000).setScale(8), NTP.getTime()); transaction.process(databaseSet); transaction.process(databaseSet2); //GENERATE 5 NEXT BLOCKS Block lastBlock = genesisBlock; BlockGenerator blockGenerator = new BlockGenerator(); for(int i=0; i<5; i++) { //GENERATE NEXT BLOCK Block newBlock = blockGenerator.generateNextBlock(databaseSet, generator, lastBlock); //ADD TRANSACTION SIGNATURE byte[] transactionsSignature = Crypto.getInstance().sign(generator, newBlock.getGeneratorSignature()); newBlock.setTransactionsSignature(transactionsSignature); //PROCESS NEW BLOCK newBlock.process(databaseSet); //LAST BLOCK IS NEW BLOCK lastBlock = newBlock; } //GENERATE NEXT 10 BLOCKS lastBlock = genesisBlock; List<Block> newBlocks = new ArrayList<Block>(); for(int i=0; i<10; i++) { //GENERATE NEXT BLOCK Block newBlock = blockGenerator.generateNextBlock(databaseSet2, generator2, lastBlock); //ADD TRANSACTION SIGNATURE byte[] transactionsSignature = Crypto.getInstance().sign(generator2, newBlock.getGeneratorSignature()); newBlock.setTransactionsSignature(transactionsSignature); //PROCESS NEW BLOCK newBlock.process(databaseSet2); //ADD TO LIST newBlocks.add(newBlock); //LAST BLOCK IS NEW BLOCK lastBlock = newBlock; } //SYNCHRONIZE DB FROM ACCOUNT 1 WITH NEXT 5 BLOCKS OF ACCOUNT 2 Synchronizer synchronizer = new Synchronizer(); try { synchronizer.synchronize(databaseSet, genesisBlock, newBlocks); //CHECK BLOCKS lastBlock = databaseSet.getBlockMap().getLastBlock(); for(int i=9; i>=0; i--) { //CHECK LAST BLOCK assertEquals(true, Arrays.equals(newBlocks.get(i).getSignature(), lastBlock.getSignature())); lastBlock = lastBlock.getParent(databaseSet); } //CHECK LAST BLOCK assertEquals(true, Arrays.equals(lastBlock.getSignature(), genesisBlock.getSignature())); //CHECK HEIGHT assertEquals(11, databaseSet.getBlockMap().getLastBlock().getHeight(databaseSet)); } catch(Exception e) { e.printStackTrace(); fail("Exception during synchronize"); } } }