Search in sources :

Example 36 with RepositoryImpl

use of co.rsk.db.RepositoryImpl in project rskj by rsksmart.

the class BridgeSupportTest method registerBtcTransactionTxNotLockNorReleaseTx.

@Test
public void registerBtcTransactionTxNotLockNorReleaseTx() throws BlockStoreException, AddressFormatException, IOException {
    Repository repository = new RepositoryImpl(config);
    Repository track = repository.startTracking();
    BridgeConstants bridgeConstants = config.getBlockchainConfig().getCommonConstants().getBridgeConstants();
    BtcTransaction tx = new BtcTransaction(this.btcParams);
    Address address = ScriptBuilder.createP2SHOutputScript(2, Lists.newArrayList(new BtcECKey(), new BtcECKey(), new BtcECKey())).getToAddress(bridgeConstants.getBtcParams());
    tx.addOutput(Coin.COIN, address);
    tx.addInput(PegTestUtils.createHash(), 0, ScriptBuilder.createInputScript(null, new BtcECKey()));
    Context btcContext = new Context(bridgeConstants.getBtcParams());
    BtcBlockStore btcBlockStore = new RepositoryBlockStore(config, track, PrecompiledContracts.BRIDGE_ADDR);
    BtcBlockChain btcBlockChain = new SimpleBlockChain(btcContext, btcBlockStore);
    BridgeStorageProvider provider = new BridgeStorageProvider(track, contractAddress, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
    BridgeSupport bridgeSupport = new BridgeSupport(config, track, null, config.getBlockchainConfig().getCommonConstants().getBridgeConstants(), provider, btcBlockStore, btcBlockChain);
    byte[] bits = new byte[1];
    bits[0] = 0x01;
    List<Sha256Hash> hashes = new ArrayList<>();
    hashes.add(tx.getHash());
    PartialMerkleTree pmt = new PartialMerkleTree(btcParams, bits, hashes, 1);
    List<Sha256Hash> hashlist = new ArrayList<>();
    Sha256Hash merkleRoot = pmt.getTxnHashAndMerkleRoot(hashlist);
    co.rsk.bitcoinj.core.BtcBlock block = new co.rsk.bitcoinj.core.BtcBlock(btcParams, 1, PegTestUtils.createHash(), merkleRoot, 1, 1, 1, new ArrayList<BtcTransaction>());
    btcBlockChain.add(block);
    bridgeSupport.registerBtcTransaction(mock(Transaction.class), tx, 1, pmt);
    bridgeSupport.save();
    track.commit();
    BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
    Assert.assertEquals(0, provider2.getNewFederationBtcUTXOs().size());
    Assert.assertEquals(0, provider2.getReleaseRequestQueue().getEntries().size());
    Assert.assertEquals(0, provider2.getReleaseTransactionSet().getEntries().size());
    Assert.assertTrue(provider2.getRskTxsWaitingForSignatures().isEmpty());
    Assert.assertTrue(provider2.getBtcTxHashesAlreadyProcessed().isEmpty());
}
Also used : RskAddress(co.rsk.core.RskAddress) SimpleBlockChain(co.rsk.peg.simples.SimpleBlockChain) BridgeConstants(co.rsk.config.BridgeConstants) BtcBlockStore(co.rsk.bitcoinj.store.BtcBlockStore) co.rsk.bitcoinj.core(co.rsk.bitcoinj.core) org.ethereum.core(org.ethereum.core) SimpleRskTransaction(co.rsk.peg.simples.SimpleRskTransaction) RepositoryImpl(co.rsk.db.RepositoryImpl) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 37 with RepositoryImpl

use of co.rsk.db.RepositoryImpl in project rskj by rsksmart.

the class BridgeSupportTest method callUpdateCollectionsFundsEnoughForJustTheSmallerTx.

@Test
public void callUpdateCollectionsFundsEnoughForJustTheSmallerTx() throws IOException, BlockStoreException {
    // Federation is the genesis federation ATM
    Federation federation = bridgeConstants.getGenesisFederation();
    Repository repository = new RepositoryImpl(config);
    Repository track = repository.startTracking();
    BridgeStorageProvider provider0 = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
    provider0.getReleaseRequestQueue().add(new BtcECKey().toAddress(btcParams), Coin.valueOf(30, 0));
    provider0.getReleaseRequestQueue().add(new BtcECKey().toAddress(btcParams), Coin.valueOf(20, 0));
    provider0.getReleaseRequestQueue().add(new BtcECKey().toAddress(btcParams), Coin.valueOf(10, 0));
    provider0.setFeePerKb(Coin.MILLICOIN);
    provider0.getNewFederationBtcUTXOs().add(new UTXO(PegTestUtils.createHash(), 1, Coin.valueOf(12, 0), 0, false, ScriptBuilder.createOutputScript(federation.getAddress())));
    provider0.save();
    track.commit();
    track = repository.startTracking();
    BlockGenerator blockGenerator = new BlockGenerator();
    List<Block> blocks = blockGenerator.getSimpleBlockChain(blockGenerator.getGenesisBlock(), 10);
    org.ethereum.core.Block rskCurrentBlock = blocks.get(9);
    Transaction tx = Transaction.create(config, TO_ADDRESS, DUST_AMOUNT, NONCE, GAS_PRICE, GAS_LIMIT, DATA);
    tx.sign(new ECKey().getPrivKeyBytes());
    BridgeSupport bridgeSupport = new BridgeSupport(config, track, mock(BridgeEventLogger.class), PrecompiledContracts.BRIDGE_ADDR, rskCurrentBlock);
    bridgeSupport.updateCollections(tx);
    bridgeSupport.save();
    track.commit();
    BridgeStorageProvider provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
    Assert.assertEquals(2, provider.getReleaseRequestQueue().getEntries().size());
    Assert.assertEquals(1, provider.getReleaseTransactionSet().getEntries().size());
    Assert.assertEquals(0, provider.getRskTxsWaitingForSignatures().size());
    // Check value sent to user is 10 BTC minus fee
    Assert.assertEquals(Coin.valueOf(999962800l), provider.getReleaseTransactionSet().getEntries().iterator().next().getTransaction().getOutput(0).getValue());
    // Check the wallet has been emptied
    Assert.assertTrue(provider.getNewFederationBtcUTXOs().isEmpty());
}
Also used : ECKey(org.ethereum.crypto.ECKey) BlockGenerator(co.rsk.blockchain.utils.BlockGenerator) co.rsk.bitcoinj.core(co.rsk.bitcoinj.core) org.ethereum.core(org.ethereum.core) SimpleRskTransaction(co.rsk.peg.simples.SimpleRskTransaction) RepositoryImpl(co.rsk.db.RepositoryImpl) BridgeEventLogger(co.rsk.peg.utils.BridgeEventLogger) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 38 with RepositoryImpl

use of co.rsk.db.RepositoryImpl in project rskj by rsksmart.

the class BridgeSupportTest method registerBtcTransactionMigrationTx.

@Test
public void registerBtcTransactionMigrationTx() throws BlockStoreException, AddressFormatException, IOException {
    BridgeConstants bridgeConstants = BridgeRegTestConstants.getInstance();
    NetworkParameters parameters = bridgeConstants.getBtcParams();
    List<BtcECKey> activeFederationKeys = Stream.of(BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02"))).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList());
    Federation activeFederation = new Federation(activeFederationKeys, Instant.ofEpochMilli(2000L), 2L, parameters);
    List<BtcECKey> retiringFederationKeys = Stream.of(BtcECKey.fromPrivate(Hex.decode("fb01")), BtcECKey.fromPrivate(Hex.decode("fb02"))).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList());
    Federation retiringFederation = new Federation(retiringFederationKeys, Instant.ofEpochMilli(1000L), 1L, parameters);
    Repository repository = new RepositoryImpl(config);
    repository.addBalance(PrecompiledContracts.BRIDGE_ADDR, LIMIT_MONETARY_BASE);
    Block executionBlock = Mockito.mock(Block.class);
    Mockito.when(executionBlock.getNumber()).thenReturn(15L);
    Repository track = repository.startTracking();
    BtcTransaction tx = new BtcTransaction(parameters);
    Address activeFederationAddress = activeFederation.getAddress();
    tx.addOutput(Coin.COIN, activeFederationAddress);
    // Create previous tx
    BtcTransaction prevTx = new BtcTransaction(btcParams);
    TransactionOutput prevOut = new TransactionOutput(btcParams, prevTx, Coin.FIFTY_COINS, retiringFederation.getAddress());
    prevTx.addOutput(prevOut);
    // Create tx input
    tx.addInput(prevOut);
    // Create tx input base script sig
    Script scriptSig = PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(retiringFederation);
    // Create sighash
    Script redeemScript = ScriptBuilder.createRedeemScript(retiringFederation.getNumberOfSignaturesRequired(), retiringFederation.getPublicKeys());
    Sha256Hash sighash = tx.hashForSignature(0, redeemScript, BtcTransaction.SigHash.ALL, false);
    // Sign by federator 0
    BtcECKey.ECDSASignature sig0 = retiringFederationKeys.get(0).sign(sighash);
    TransactionSignature txSig0 = new TransactionSignature(sig0, BtcTransaction.SigHash.ALL, false);
    int sigIndex0 = scriptSig.getSigInsertionIndex(sighash, retiringFederation.getPublicKeys().get(0));
    scriptSig = ScriptBuilder.updateScriptWithSignature(scriptSig, txSig0.encodeToBitcoin(), sigIndex0, 1, 1);
    // Sign by federator 1
    BtcECKey.ECDSASignature sig1 = retiringFederationKeys.get(1).sign(sighash);
    TransactionSignature txSig1 = new TransactionSignature(sig1, BtcTransaction.SigHash.ALL, false);
    int sigIndex1 = scriptSig.getSigInsertionIndex(sighash, retiringFederation.getPublicKeys().get(1));
    scriptSig = ScriptBuilder.updateScriptWithSignature(scriptSig, txSig1.encodeToBitcoin(), sigIndex1, 1, 1);
    // Set scipt sign to tx input
    tx.getInput(0).setScriptSig(scriptSig);
    Context btcContext = new Context(bridgeConstants.getBtcParams());
    BtcBlockStore btcBlockStore = new RepositoryBlockStore(config, track, PrecompiledContracts.BRIDGE_ADDR);
    BtcBlockChain btcBlockChain = new SimpleBlockChain(btcContext, btcBlockStore);
    BridgeStorageProvider provider = new BridgeStorageProvider(track, contractAddress, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
    provider.setNewFederation(activeFederation);
    provider.setOldFederation(retiringFederation);
    BridgeSupport bridgeSupport = new BridgeSupport(config, track, null, config.getBlockchainConfig().getCommonConstants().getBridgeConstants(), provider, btcBlockStore, btcBlockChain);
    Whitebox.setInternalState(bridgeSupport, "rskExecutionBlock", executionBlock);
    byte[] bits = new byte[1];
    bits[0] = 0x3f;
    List<Sha256Hash> hashes = new ArrayList<>();
    hashes.add(tx.getHash());
    PartialMerkleTree pmt = new PartialMerkleTree(btcParams, bits, hashes, 1);
    List<Sha256Hash> hashlist = new ArrayList<>();
    Sha256Hash merkleRoot = pmt.getTxnHashAndMerkleRoot(hashlist);
    co.rsk.bitcoinj.core.BtcBlock block = new co.rsk.bitcoinj.core.BtcBlock(btcParams, 1, PegTestUtils.createHash(), merkleRoot, 1, 1, 1, new ArrayList<BtcTransaction>());
    btcBlockChain.add(block);
    ((SimpleBlockChain) btcBlockChain).useHighBlock();
    bridgeSupport.registerBtcTransaction(mock(Transaction.class), tx, 1, pmt);
    bridgeSupport.save();
    ((SimpleBlockChain) btcBlockChain).useBlock();
    track.commit();
    List<UTXO> activeFederationBtcUTXOs = provider.getNewFederationBtcUTXOs();
    List<Coin> activeFederationBtcCoins = activeFederationBtcUTXOs.stream().map(UTXO::getValue).collect(Collectors.toList());
    assertThat(activeFederationBtcUTXOs, hasSize(1));
    assertThat(activeFederationBtcCoins, hasItem(Coin.COIN));
}
Also used : RskAddress(co.rsk.core.RskAddress) TransactionSignature(co.rsk.bitcoinj.crypto.TransactionSignature) SimpleBlockChain(co.rsk.peg.simples.SimpleBlockChain) BridgeConstants(co.rsk.config.BridgeConstants) Script(co.rsk.bitcoinj.script.Script) BtcBlockStore(co.rsk.bitcoinj.store.BtcBlockStore) co.rsk.bitcoinj.core(co.rsk.bitcoinj.core) org.ethereum.core(org.ethereum.core) SimpleRskTransaction(co.rsk.peg.simples.SimpleRskTransaction) RepositoryImpl(co.rsk.db.RepositoryImpl) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 39 with RepositoryImpl

use of co.rsk.db.RepositoryImpl in project rskj by rsksmart.

the class BridgeSupportTest method addSignatureMultipleInputsPartiallyValid.

@Test
public void addSignatureMultipleInputsPartiallyValid() throws Exception {
    // Federation is the genesis federation ATM
    Federation federation = bridgeConstants.getGenesisFederation();
    Repository repository = new RepositoryImpl(config);
    final Keccak256 keccak256 = PegTestUtils.createHash3();
    Repository track = repository.startTracking();
    BridgeStorageProvider provider = new BridgeStorageProvider(track, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants);
    BtcTransaction prevTx1 = new BtcTransaction(btcParams);
    TransactionOutput prevOut1 = new TransactionOutput(btcParams, prevTx1, Coin.FIFTY_COINS, federation.getAddress());
    prevTx1.addOutput(prevOut1);
    BtcTransaction prevTx2 = new BtcTransaction(btcParams);
    TransactionOutput prevOut2 = new TransactionOutput(btcParams, prevTx1, Coin.FIFTY_COINS, federation.getAddress());
    prevTx2.addOutput(prevOut2);
    BtcTransaction prevTx3 = new BtcTransaction(btcParams);
    TransactionOutput prevOut3 = new TransactionOutput(btcParams, prevTx1, Coin.FIFTY_COINS, federation.getAddress());
    prevTx3.addOutput(prevOut3);
    BtcTransaction t = new BtcTransaction(btcParams);
    TransactionOutput output = new TransactionOutput(btcParams, t, Coin.COIN, new BtcECKey().toAddress(btcParams));
    t.addOutput(output);
    t.addInput(prevOut1).setScriptSig(PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(federation));
    t.addInput(prevOut2).setScriptSig(PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(federation));
    t.addInput(prevOut3).setScriptSig(PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(federation));
    provider.getRskTxsWaitingForSignatures().put(keccak256, t);
    provider.save();
    track.commit();
    track = repository.startTracking();
    List<LogInfo> logs = new ArrayList<>();
    BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeConstants, logs);
    BridgeSupport bridgeSupport = new BridgeSupport(config, track, eventLogger, contractAddress, (Block) null);
    // Generate valid signatures for inputs
    List<byte[]> derEncodedSigsFirstFed = new ArrayList<>();
    List<byte[]> derEncodedSigsSecondFed = new ArrayList<>();
    BtcECKey privateKeyOfFirstFed = ((BridgeRegTestConstants) bridgeConstants).getFederatorPrivateKeys().get(0);
    BtcECKey privateKeyOfSecondFed = ((BridgeRegTestConstants) bridgeConstants).getFederatorPrivateKeys().get(1);
    BtcECKey.ECDSASignature lastSig = null;
    for (int i = 0; i < 3; i++) {
        Script inputScript = t.getInput(i).getScriptSig();
        List<ScriptChunk> chunks = inputScript.getChunks();
        byte[] program = chunks.get(chunks.size() - 1).data;
        Script redeemScript = new Script(program);
        Sha256Hash sighash = t.hashForSignature(i, redeemScript, BtcTransaction.SigHash.ALL, false);
        // Sign the last input with a random key
        // but keep the good signature for a subsequent call
        BtcECKey.ECDSASignature sig = privateKeyOfFirstFed.sign(sighash);
        if (i == 2) {
            lastSig = sig;
            sig = new BtcECKey().sign(sighash);
        }
        derEncodedSigsFirstFed.add(sig.encodeToDER());
        derEncodedSigsSecondFed.add(privateKeyOfSecondFed.sign(sighash).encodeToDER());
    }
    // Sign with two valid signatuers and one invalid signature
    bridgeSupport.addSignature(1, findPublicKeySignedBy(federation.getPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes());
    bridgeSupport.save();
    track.commit();
    // Sign with two valid signatuers and one malformed signature
    byte[] malformedSignature = new byte[lastSig.encodeToDER().length];
    for (int i = 0; i < malformedSignature.length; i++) {
        malformedSignature[i] = (byte) i;
    }
    derEncodedSigsFirstFed.set(2, malformedSignature);
    bridgeSupport.addSignature(1, findPublicKeySignedBy(federation.getPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes());
    bridgeSupport.save();
    track.commit();
    // Sign with fully valid signatures for same federator
    derEncodedSigsFirstFed.set(2, lastSig.encodeToDER());
    bridgeSupport.addSignature(1, findPublicKeySignedBy(federation.getPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes());
    bridgeSupport.save();
    track.commit();
    // Sign with second federation
    bridgeSupport.addSignature(1, findPublicKeySignedBy(federation.getPublicKeys(), privateKeyOfSecondFed), derEncodedSigsSecondFed, keccak256.getBytes());
    bridgeSupport.save();
    track.commit();
    provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants);
    Assert.assertTrue(provider.getRskTxsWaitingForSignatures().isEmpty());
    Assert.assertThat(logs, is(not(empty())));
    Assert.assertThat(logs, hasSize(5));
    LogInfo releaseTxEvent = logs.get(4);
    Assert.assertThat(releaseTxEvent.getTopics(), hasSize(1));
    Assert.assertThat(releaseTxEvent.getTopics(), hasItem(Bridge.RELEASE_BTC_TOPIC));
    BtcTransaction releaseTx = new BtcTransaction(bridgeConstants.getBtcParams(), ((RLPList) RLP.decode2(releaseTxEvent.getData()).get(0)).get(1).getRLPData());
    // Verify all inputs fully signed
    for (int i = 0; i < releaseTx.getInputs().size(); i++) {
        Script retrievedScriptSig = releaseTx.getInput(i).getScriptSig();
        Assert.assertEquals(4, retrievedScriptSig.getChunks().size());
        Assert.assertEquals(true, retrievedScriptSig.getChunks().get(1).data.length > 0);
        Assert.assertEquals(true, retrievedScriptSig.getChunks().get(2).data.length > 0);
    }
}
Also used : BridgeEventLoggerImpl(co.rsk.peg.utils.BridgeEventLoggerImpl) Script(co.rsk.bitcoinj.script.Script) LogInfo(org.ethereum.vm.LogInfo) Keccak256(co.rsk.crypto.Keccak256) ScriptChunk(co.rsk.bitcoinj.script.ScriptChunk) RLPList(org.ethereum.util.RLPList) RepositoryImpl(co.rsk.db.RepositoryImpl) BridgeEventLogger(co.rsk.peg.utils.BridgeEventLogger) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 40 with RepositoryImpl

use of co.rsk.db.RepositoryImpl in project rskj by rsksmart.

the class BridgeSupportTest method registerBtcTransactionLockTxNotWhitelisted.

@Test
public void registerBtcTransactionLockTxNotWhitelisted() throws BlockStoreException, AddressFormatException, IOException {
    BridgeConstants bridgeConstants = config.getBlockchainConfig().getCommonConstants().getBridgeConstants();
    NetworkParameters parameters = bridgeConstants.getBtcParams();
    List<BtcECKey> federation1Keys = Arrays.asList(new BtcECKey[] { BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) });
    federation1Keys.sort(BtcECKey.PUBKEY_COMPARATOR);
    Federation federation1 = new Federation(federation1Keys, Instant.ofEpochMilli(1000L), 0L, parameters);
    List<BtcECKey> federation2Keys = Arrays.asList(new BtcECKey[] { BtcECKey.fromPrivate(Hex.decode("fb01")), BtcECKey.fromPrivate(Hex.decode("fb02")), BtcECKey.fromPrivate(Hex.decode("fb03")) });
    federation2Keys.sort(BtcECKey.PUBKEY_COMPARATOR);
    Federation federation2 = new Federation(federation2Keys, Instant.ofEpochMilli(2000L), 0L, parameters);
    Repository repository = new RepositoryImpl(config);
    repository.addBalance(PrecompiledContracts.BRIDGE_ADDR, LIMIT_MONETARY_BASE);
    Block executionBlock = Mockito.mock(Block.class);
    Mockito.when(executionBlock.getNumber()).thenReturn(10L);
    Repository track = repository.startTracking();
    // First transaction goes only to the first federation
    BtcTransaction tx1 = new BtcTransaction(this.btcParams);
    tx1.addOutput(Coin.COIN.multiply(5), federation1.getAddress());
    BtcECKey srcKey1 = new BtcECKey();
    tx1.addInput(PegTestUtils.createHash(), 0, ScriptBuilder.createInputScript(null, srcKey1));
    // Second transaction goes only to the second federation
    BtcTransaction tx2 = new BtcTransaction(this.btcParams);
    tx2.addOutput(Coin.COIN.multiply(10), federation2.getAddress());
    BtcECKey srcKey2 = new BtcECKey();
    tx2.addInput(PegTestUtils.createHash(), 0, ScriptBuilder.createInputScript(null, srcKey2));
    // Third transaction has one output to each federation
    // Lock is expected to be done accordingly and utxos assigned accordingly as well
    BtcTransaction tx3 = new BtcTransaction(this.btcParams);
    tx3.addOutput(Coin.COIN.multiply(3), federation1.getAddress());
    tx3.addOutput(Coin.COIN.multiply(4), federation2.getAddress());
    BtcECKey srcKey3 = new BtcECKey();
    tx3.addInput(PegTestUtils.createHash(), 0, ScriptBuilder.createInputScript(null, srcKey3));
    Context btcContext = new Context(bridgeConstants.getBtcParams());
    BtcBlockStore btcBlockStore = new RepositoryBlockStore(config, track, PrecompiledContracts.BRIDGE_ADDR);
    BtcBlockChain btcBlockChain = new SimpleBlockChain(btcContext, btcBlockStore);
    BridgeStorageProvider provider = new BridgeStorageProvider(track, contractAddress, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
    provider.setNewFederation(federation1);
    provider.setOldFederation(federation2);
    BridgeSupport bridgeSupport = new BridgeSupport(config, track, null, config.getBlockchainConfig().getCommonConstants().getBridgeConstants(), provider, btcBlockStore, btcBlockChain);
    Whitebox.setInternalState(bridgeSupport, "rskExecutionBlock", executionBlock);
    byte[] bits = new byte[1];
    bits[0] = 0x3f;
    List<Sha256Hash> hashes = new ArrayList<>();
    hashes.add(tx1.getHash());
    hashes.add(tx2.getHash());
    hashes.add(tx3.getHash());
    PartialMerkleTree pmt = new PartialMerkleTree(btcParams, bits, hashes, 3);
    List<Sha256Hash> hashlist = new ArrayList<>();
    Sha256Hash merkleRoot = pmt.getTxnHashAndMerkleRoot(hashlist);
    co.rsk.bitcoinj.core.BtcBlock block = new co.rsk.bitcoinj.core.BtcBlock(btcParams, 1, PegTestUtils.createHash(), merkleRoot, 1, 1, 1, new ArrayList<BtcTransaction>());
    btcBlockChain.add(block);
    Transaction rskTx1 = getMockedRskTxWithHash("aa");
    Transaction rskTx2 = getMockedRskTxWithHash("bb");
    Transaction rskTx3 = getMockedRskTxWithHash("cc");
    ((SimpleBlockChain) btcBlockChain).useHighBlock();
    bridgeSupport.registerBtcTransaction(rskTx1, tx1, 1, pmt);
    bridgeSupport.registerBtcTransaction(rskTx2, tx2, 1, pmt);
    bridgeSupport.registerBtcTransaction(rskTx3, tx3, 1, pmt);
    bridgeSupport.save();
    ((SimpleBlockChain) btcBlockChain).useBlock();
    track.commit();
    RskAddress srcKey1RskAddress = new RskAddress(org.ethereum.crypto.ECKey.fromPrivate(srcKey1.getPrivKey()).getAddress());
    RskAddress srcKey2RskAddress = new RskAddress(org.ethereum.crypto.ECKey.fromPrivate(srcKey2.getPrivKey()).getAddress());
    RskAddress srcKey3RskAddress = new RskAddress(org.ethereum.crypto.ECKey.fromPrivate(srcKey3.getPrivKey()).getAddress());
    Assert.assertEquals(0, repository.getBalance(srcKey1RskAddress).asBigInteger().intValue());
    Assert.assertEquals(0, repository.getBalance(srcKey2RskAddress).asBigInteger().intValue());
    Assert.assertEquals(0, repository.getBalance(srcKey3RskAddress).asBigInteger().intValue());
    Assert.assertEquals(LIMIT_MONETARY_BASE, repository.getBalance(PrecompiledContracts.BRIDGE_ADDR));
    BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
    Assert.assertEquals(0, provider2.getNewFederationBtcUTXOs().size());
    Assert.assertEquals(0, provider2.getOldFederationBtcUTXOs().size());
    Assert.assertEquals(0, provider2.getReleaseRequestQueue().getEntries().size());
    Assert.assertEquals(3, provider2.getReleaseTransactionSet().getEntries().size());
    List<BtcTransaction> releaseTxs = provider2.getReleaseTransactionSet().getEntries().stream().map(e -> e.getTransaction()).sorted(Comparator.comparing(BtcTransaction::getOutputSum)).collect(Collectors.toList());
    // First release tx should correspond to the 5 BTC lock tx
    BtcTransaction releaseTx = releaseTxs.get(0);
    Assert.assertEquals(1, releaseTx.getOutputs().size());
    Assert.assertThat(Coin.COIN.multiply(5).subtract(releaseTx.getOutput(0).getValue()), is(lessThanOrEqualTo(Coin.MILLICOIN)));
    Assert.assertEquals(srcKey1.toAddress(parameters), releaseTx.getOutput(0).getAddressFromP2PKHScript(parameters));
    Assert.assertEquals(1, releaseTx.getInputs().size());
    Assert.assertEquals(tx1.getHash(), releaseTx.getInput(0).getOutpoint().getHash());
    Assert.assertEquals(0, releaseTx.getInput(0).getOutpoint().getIndex());
    // Second release tx should correspond to the 7 (3+4) BTC lock tx
    releaseTx = releaseTxs.get(1);
    Assert.assertEquals(1, releaseTx.getOutputs().size());
    Assert.assertThat(Coin.COIN.multiply(7).subtract(releaseTx.getOutput(0).getValue()), is(lessThanOrEqualTo(Coin.MILLICOIN)));
    Assert.assertEquals(srcKey3.toAddress(parameters), releaseTx.getOutput(0).getAddressFromP2PKHScript(parameters));
    Assert.assertEquals(2, releaseTx.getInputs().size());
    List<TransactionOutPoint> releaseOutpoints = releaseTx.getInputs().stream().map(i -> i.getOutpoint()).sorted(Comparator.comparing(TransactionOutPoint::getIndex)).collect(Collectors.toList());
    Assert.assertEquals(tx3.getHash(), releaseOutpoints.get(0).getHash());
    Assert.assertEquals(tx3.getHash(), releaseOutpoints.get(1).getHash());
    Assert.assertEquals(0, releaseOutpoints.get(0).getIndex());
    Assert.assertEquals(1, releaseOutpoints.get(1).getIndex());
    // Third release tx should correspond to the 10 BTC lock tx
    releaseTx = releaseTxs.get(2);
    Assert.assertEquals(1, releaseTx.getOutputs().size());
    Assert.assertThat(Coin.COIN.multiply(10).subtract(releaseTx.getOutput(0).getValue()), is(lessThanOrEqualTo(Coin.MILLICOIN)));
    Assert.assertEquals(srcKey2.toAddress(parameters), releaseTx.getOutput(0).getAddressFromP2PKHScript(parameters));
    Assert.assertEquals(1, releaseTx.getInputs().size());
    Assert.assertEquals(tx2.getHash(), releaseTx.getInput(0).getOutpoint().getHash());
    Assert.assertEquals(0, releaseTx.getInput(0).getOutpoint().getIndex());
    Assert.assertTrue(provider2.getRskTxsWaitingForSignatures().isEmpty());
    Assert.assertEquals(3, provider2.getBtcTxHashesAlreadyProcessed().size());
}
Also used : SimpleBlockChain(co.rsk.peg.simples.SimpleBlockChain) RskAddress(co.rsk.core.RskAddress) BridgeConstants(co.rsk.config.BridgeConstants) BtcBlockStore(co.rsk.bitcoinj.store.BtcBlockStore) co.rsk.bitcoinj.core(co.rsk.bitcoinj.core) org.ethereum.core(org.ethereum.core) SimpleRskTransaction(co.rsk.peg.simples.SimpleRskTransaction) RepositoryImpl(co.rsk.db.RepositoryImpl) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Aggregations

RepositoryImpl (co.rsk.db.RepositoryImpl)62 Test (org.junit.Test)54 Repository (org.ethereum.core.Repository)25 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)22 RskAddress (co.rsk.core.RskAddress)19 TrieStoreImpl (co.rsk.trie.TrieStoreImpl)16 HashMapDB (org.ethereum.datasource.HashMapDB)15 co.rsk.bitcoinj.core (co.rsk.bitcoinj.core)13 org.ethereum.core (org.ethereum.core)13 BlockGenerator (co.rsk.blockchain.utils.BlockGenerator)12 LogInfo (org.ethereum.vm.LogInfo)12 SimpleRskTransaction (co.rsk.peg.simples.SimpleRskTransaction)11 BridgeConstants (co.rsk.config.BridgeConstants)10 BridgeEventLogger (co.rsk.peg.utils.BridgeEventLogger)10 DataWord (org.ethereum.vm.DataWord)9 ArrayList (java.util.ArrayList)8 BtcBlockStore (co.rsk.bitcoinj.store.BtcBlockStore)7 ECKey (org.ethereum.crypto.ECKey)7 Keccak256 (co.rsk.crypto.Keccak256)6 SimpleBlockChain (co.rsk.peg.simples.SimpleBlockChain)6