Пример #1
0
  @Test
  public void orphanBlock() {
    // CREATE EMPTY MEMORY DATABASE
    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 NEXT BLOCK
    BlockGenerator blockGenerator = new BlockGenerator();
    Block block = blockGenerator.generateNextBlock(databaseSet, generator, genesisBlock);

    // FORK
    DBSet fork = databaseSet.fork();

    // GENERATE PAYMENT 1
    Account recipient = new Account("XUi2oga2pnGNcZ9es6pBqxydtRZKWdkL2g");
    long timestamp = block.getTimestamp();
    byte[] signature =
        PaymentTransaction.generateSignature(
            databaseSet,
            generator,
            recipient,
            BigDecimal.valueOf(100).setScale(8),
            BigDecimal.valueOf(1).setScale(8),
            timestamp);
    Transaction payment1 =
        new PaymentTransaction(
            generator,
            recipient,
            BigDecimal.valueOf(100).setScale(8),
            BigDecimal.valueOf(1).setScale(8),
            timestamp,
            generator.getLastReference(databaseSet),
            signature);
    payment1.process(fork);
    block.addTransaction(payment1);

    // GENERATE PAYMENT 2
    Account recipient2 = new Account("XLPYYfxKEiDcybCkFA7jXcxSdePMMoyZLt");
    signature =
        PaymentTransaction.generateSignature(
            fork,
            generator,
            recipient2,
            BigDecimal.valueOf(100).setScale(8),
            BigDecimal.valueOf(1).setScale(8),
            timestamp);
    Transaction payment2 =
        new PaymentTransaction(
            generator,
            recipient2,
            BigDecimal.valueOf(100).setScale(8),
            BigDecimal.valueOf(1).setScale(8),
            timestamp,
            generator.getLastReference(fork),
            signature);
    block.addTransaction(payment2);

    // ADD TRANSACTION SIGNATURE
    byte[] transactionsSignature = blockGenerator.calculateTransactionsSignature(block, generator);
    block.setTransactionsSignature(transactionsSignature);

    // CHECK VALID
    assertEquals(true, block.isSignatureValid());
    assertEquals(true, block.isValid(databaseSet));

    // PROCESS BLOCK
    block.process(databaseSet);

    // ORPHAN BLOCK
    block.orphan(databaseSet);

    // CHECK BALANCE GENERATOR
    assertEquals(
        true, generator.getConfirmedBalance(databaseSet).compareTo(BigDecimal.valueOf(1000)) == 0);

    // CHECK LAST REFERENCE GENERATOR
    assertEquals(
        true, Arrays.equals(generator.getLastReference(databaseSet), transaction.getSignature()));

    // CHECK BALANCE RECIPIENT
    assertEquals(
        true, recipient.getConfirmedBalance(databaseSet).compareTo(BigDecimal.valueOf(1000)) == 0);

    // CHECK LAST REFERENCE RECIPIENT
    assertEquals(
        false, Arrays.equals(recipient.getLastReference(databaseSet), payment1.getSignature()));

    // CHECK BALANCE RECIPIENT2
    assertEquals(
        true, recipient2.getConfirmedBalance(databaseSet).compareTo(BigDecimal.valueOf(0)) == 0);

    // CHECK LAST REFERENCE RECIPIENT
    assertEquals(true, Arrays.equals(recipient2.getLastReference(databaseSet), new byte[0]));

    // CHECK LAST BLOCK
    assertEquals(
        true,
        Arrays.equals(
            genesisBlock.getSignature(), databaseSet.getBlockMap().getLastBlock().getSignature()));
  }
Пример #2
0
  @Test
  public void validateBlock() {
    // CREATE EMPTY MEMORY DATABASE
    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 NEXT BLOCK
    BlockGenerator blockGenerator = new BlockGenerator();
    Block newBlock = blockGenerator.generateNextBlock(databaseSet, generator, genesisBlock);

    // ADD TRANSACTION SIGNATURE
    byte[] transactionsSignature =
        Crypto.getInstance().sign(generator, newBlock.getGeneratorSignature());
    newBlock.setTransactionsSignature(transactionsSignature);

    // CHECK IF VALID
    assertEquals(true, newBlock.isValid(databaseSet));

    // CHANGE REFERENCE
    Block invalidBlock =
        BlockFactory.getInstance()
            .create(
                newBlock.getVersion(),
                new byte[128],
                newBlock.getTimestamp(),
                newBlock.getGeneratingBalance(),
                newBlock.getGenerator(),
                newBlock.getGeneratorSignature());

    // CHECK IF INVALID
    assertEquals(false, invalidBlock.isValid(databaseSet));

    // CHANGE TIMESTAMP
    invalidBlock =
        BlockFactory.getInstance()
            .create(
                newBlock.getVersion(),
                newBlock.getReference(),
                1L,
                newBlock.getGeneratingBalance(),
                newBlock.getGenerator(),
                newBlock.getGeneratorSignature());

    // CHECK IF INVALID
    assertEquals(false, invalidBlock.isValid(databaseSet));

    // CHANGE BASETARGET
    invalidBlock =
        BlockFactory.getInstance()
            .create(
                newBlock.getVersion(),
                newBlock.getReference(),
                newBlock.getTimestamp(),
                1L,
                newBlock.getGenerator(),
                newBlock.getGeneratorSignature());

    // CHECK IF INVALID
    assertEquals(false, invalidBlock.isValid(databaseSet));

    // ADD INVALID TRANSACTION
    invalidBlock = blockGenerator.generateNextBlock(databaseSet, generator, genesisBlock);
    Account recipient = new Account("XUi2oga2pnGNcZ9es6pBqxydtRZKWdkL2g");
    long timestamp = newBlock.getTimestamp();
    byte[] signature =
        PaymentTransaction.generateSignature(
            databaseSet,
            generator,
            recipient,
            BigDecimal.valueOf(-100).setScale(8),
            BigDecimal.valueOf(1).setScale(8),
            timestamp);
    Transaction payment =
        new PaymentTransaction(
            generator,
            recipient,
            BigDecimal.valueOf(-100).setScale(8),
            BigDecimal.valueOf(1).setScale(8),
            timestamp,
            generator.getLastReference(databaseSet),
            signature);
    invalidBlock.addTransaction(payment);

    // CHECK IF INVALID
    assertEquals(false, invalidBlock.isValid(databaseSet));

    // ADD GENESIS TRANSACTION
    invalidBlock = blockGenerator.generateNextBlock(databaseSet, generator, genesisBlock);
    transaction =
        new GenesisTransaction(
            generator, BigDecimal.valueOf(1000).setScale(8), newBlock.getTimestamp());
    invalidBlock.addTransaction(transaction);

    // CHECK IF INVALID
    assertEquals(false, invalidBlock.isValid(databaseSet));
  }
Пример #3
0
  @Test
  public void parseBlock() {
    // CREATE EMPTY MEMORY DATABASE
    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 NEXT BLOCK
    BlockGenerator blockGenerator = new BlockGenerator();
    Block block = blockGenerator.generateNextBlock(databaseSet, generator, genesisBlock);

    // FORK
    DBSet fork = databaseSet.fork();

    // GENERATE PAYMENT 1
    Account recipient = new Account("XUi2oga2pnGNcZ9es6pBqxydtRZKWdkL2g");
    long timestamp = block.getTimestamp();
    byte[] signature =
        PaymentTransaction.generateSignature(
            databaseSet,
            generator,
            recipient,
            BigDecimal.valueOf(100).setScale(8),
            BigDecimal.valueOf(1).setScale(8),
            timestamp);
    Transaction payment1 =
        new PaymentTransaction(
            generator,
            recipient,
            BigDecimal.valueOf(100).setScale(8),
            BigDecimal.valueOf(1).setScale(8),
            timestamp,
            generator.getLastReference(databaseSet),
            signature);
    payment1.process(fork);
    block.addTransaction(payment1);

    // GENERATE PAYMENT 2
    Account recipient2 = new Account("XLPYYfxKEiDcybCkFA7jXcxSdePMMoyZLt");
    signature =
        PaymentTransaction.generateSignature(
            fork,
            generator,
            recipient2,
            BigDecimal.valueOf(100).setScale(8),
            BigDecimal.valueOf(1).setScale(8),
            timestamp);
    Transaction payment2 =
        new PaymentTransaction(
            generator,
            recipient2,
            BigDecimal.valueOf(100).setScale(8),
            BigDecimal.valueOf(1).setScale(8),
            timestamp,
            generator.getLastReference(fork),
            signature);
    block.addTransaction(payment2);

    // ADD TRANSACTION SIGNATURE
    byte[] transactionsSignature =
        Crypto.getInstance().sign(generator, block.getGeneratorSignature());
    block.setTransactionsSignature(transactionsSignature);

    // CONVERT TO BYTES
    byte[] rawBlock = block.toBytes();

    try {
      // PARSE FROM BYTES
      Block parsedBlock = BlockFactory.getInstance().parse(rawBlock);

      // CHECK INSTANCE
      assertEquals(false, parsedBlock instanceof GenesisBlock);

      // CHECK SIGNATURE
      assertEquals(true, Arrays.equals(block.getSignature(), parsedBlock.getSignature()));

      // CHECK GENERATOR
      assertEquals(block.getGenerator().getAddress(), parsedBlock.getGenerator().getAddress());

      // CHECK BASE TARGET
      assertEquals(block.getGeneratingBalance(), parsedBlock.getGeneratingBalance());

      // CHECK FEE
      assertEquals(block.getTotalFee(), parsedBlock.getTotalFee());

      // CHECK REFERENCE
      assertEquals(true, Arrays.equals(block.getReference(), parsedBlock.getReference()));

      // CHECK TIMESTAMP
      assertEquals(block.getTimestamp(), parsedBlock.getTimestamp());

      // CHECK TRANSACTIONS COUNT
      assertEquals(block.getTransactionCount(), parsedBlock.getTransactionCount());
    } catch (Exception e) {
      fail("Exception while parsing transaction.");
    }

    // PARSE TRANSACTION FROM WRONG BYTES
    rawBlock = new byte[50];

    try {
      // PARSE FROM BYTES
      BlockFactory.getInstance().parse(rawBlock);

      // FAIL
      fail("this should throw an exception");
    } catch (Exception e) {
      // EXCEPTION IS THROWN OKE
    }
  }
Пример #4
0
  public static Block parse(byte[] data) throws Exception {
    // CHECK IF WE HAVE MINIMUM BLOCK LENGTH
    if (data.length < BASE_LENGTH) {
      throw new Exception("Data is less then minimum block length");
    }

    int position = 0;

    // READ VERSION
    byte[] versionBytes = Arrays.copyOfRange(data, position, position + VERSION_LENGTH);
    int version = Ints.fromByteArray(versionBytes);
    position += VERSION_LENGTH;

    // READ TIMESTAMP
    byte[] timestampBytes = Arrays.copyOfRange(data, position, position + TIMESTAMP_LENGTH);
    long timestamp = Longs.fromByteArray(timestampBytes);
    position += TIMESTAMP_LENGTH;

    // READ REFERENCE
    byte[] reference = Arrays.copyOfRange(data, position, position + REFERENCE_LENGTH);
    position += REFERENCE_LENGTH;

    // READ GENERATING BALANCE
    byte[] generatingBalanceBytes =
        Arrays.copyOfRange(data, position, position + GENERATING_BALANCE_LENGTH);
    long generatingBalance = Longs.fromByteArray(generatingBalanceBytes);
    position += GENERATING_BALANCE_LENGTH;

    // READ GENERATOR
    byte[] generatorBytes = Arrays.copyOfRange(data, position, position + GENERATOR_LENGTH);
    PublicKeyAccount generator = new PublicKeyAccount(generatorBytes);
    position += GENERATOR_LENGTH;

    // READ TRANSACTION SIGNATURE
    byte[] transactionsSignature =
        Arrays.copyOfRange(data, position, position + TRANSACTIONS_SIGNATURE_LENGTH);
    position += TRANSACTIONS_SIGNATURE_LENGTH;

    // READ GENERATOR SIGNATURE
    byte[] generatorSignature =
        Arrays.copyOfRange(data, position, position + GENERATOR_SIGNATURE_LENGTH);
    position += GENERATOR_SIGNATURE_LENGTH;

    // CREATE BLOCK
    Block block;
    if (version > 1) {
      // ADD ATs BYTES
      byte[] atBytesCountBytes = Arrays.copyOfRange(data, position, position + AT_BYTES_LENGTH);
      int atBytesCount = Ints.fromByteArray(atBytesCountBytes);
      position += AT_BYTES_LENGTH;

      byte[] atBytes = Arrays.copyOfRange(data, position, position + atBytesCount);
      position += atBytesCount;

      byte[] atFees = Arrays.copyOfRange(data, position, position + 8);
      position += 8;

      long atFeesL = Longs.fromByteArray(atFees);

      block =
          new Block(
              version,
              reference,
              timestamp,
              generatingBalance,
              generator,
              generatorSignature,
              atBytes,
              atFeesL);
    } else {
      block =
          new Block(
              version, reference, timestamp, generatingBalance, generator, generatorSignature);
    }

    // READ TRANSACTIONS COUNT
    byte[] transactionCountBytes =
        Arrays.copyOfRange(data, position, position + TRANSACTIONS_COUNT_LENGTH);
    int transactionCount = Ints.fromByteArray(transactionCountBytes);
    position += TRANSACTIONS_COUNT_LENGTH;

    // SET TRANSACTIONDATA
    byte[] rawTransactions = Arrays.copyOfRange(data, position, data.length);
    block.setTransactionData(transactionCount, rawTransactions);

    // SET TRANSACTIONS SIGNATURE
    block.setTransactionsSignature(transactionsSignature);

    return block;
  }