Search in sources :

Example 36 with Script

use of co.rsk.bitcoinj.script.Script in project rskj by rsksmart.

the class BridgeUtilsTest method testIsValidPegInTx_hasChangeUtxoFromFastBridgeRetiredFederation_afterRskip201_notPegin.

@Test
public void testIsValidPegInTx_hasChangeUtxoFromFastBridgeRetiredFederation_afterRskip201_notPegin() {
    Context btcContext = new Context(networkParameters);
    Federation activeFederation = bridgeConstantsRegtest.getGenesisFederation();
    when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true);
    List<BtcECKey> retiredFederationKeys = Arrays.asList(BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")));
    retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR);
    Federation retiredFederation = new Federation(FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters);
    // Create a tx from the retired fast bridge fed to the active fed
    BtcTransaction tx = new BtcTransaction(networkParameters);
    tx.addOutput(Coin.COIN, activeFederation.getAddress());
    TransactionInput txInput = new TransactionInput(networkParameters, tx, new byte[0], new TransactionOutPoint(networkParameters, 0, Sha256Hash.ZERO_HASH));
    tx.addInput(txInput);
    Script fastBridgeRedeemScript = FastBridgeRedeemScriptParser.createMultiSigFastBridgeRedeemScript(retiredFederation.getRedeemScript(), PegTestUtils.createHash(2));
    signWithNecessaryKeys(retiredFederation, fastBridgeRedeemScript, retiredFederationKeys, txInput, tx);
    assertFalse(BridgeUtils.isValidPegInTx(tx, Collections.singletonList(activeFederation), retiredFederation.getP2SHScript(), btcContext, bridgeConstantsRegtest, activations));
}
Also used : Context(co.rsk.bitcoinj.core.Context) Script(co.rsk.bitcoinj.script.Script) BtcTransaction(co.rsk.bitcoinj.core.BtcTransaction) BtcECKey(co.rsk.bitcoinj.core.BtcECKey) TransactionInput(co.rsk.bitcoinj.core.TransactionInput) TransactionOutPoint(co.rsk.bitcoinj.core.TransactionOutPoint) ActivationConfigsForTest(org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest) Test(org.junit.Test)

Example 37 with Script

use of co.rsk.bitcoinj.script.Script in project rskj by rsksmart.

the class BridgeSupportTest method getUTXOsForAddress_OK.

@Test
public void getUTXOsForAddress_OK() {
    ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class);
    when(activations.isActive(ConsensusRule.RSKIP176)).thenReturn(true);
    BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, mock(BridgeStorageProvider.class), mock(Repository.class), mock(BridgeEventLogger.class), null, mock(BtcBlockStoreWithCache.Factory.class), activations);
    Script fastBridgeRedeemScript = FastBridgeRedeemScriptParser.createMultiSigFastBridgeRedeemScript(bridgeConstants.getGenesisFederation().getRedeemScript(), Sha256Hash.of(new byte[1]));
    Script fastBridgeP2SH = ScriptBuilder.createP2SHOutputScript(fastBridgeRedeemScript);
    Address fastBridgeFedAddress = Address.fromP2SHScript(bridgeConstants.getBtcParams(), fastBridgeP2SH);
    BtcTransaction tx = createBtcTransactionWithOutputToAddress(Coin.COIN, fastBridgeFedAddress);
    List<UTXO> utxoList = new ArrayList<>();
    UTXO utxo = new UTXO(tx.getHash(), 0, Coin.COIN, 0, false, fastBridgeP2SH);
    utxoList.add(utxo);
    Assert.assertEquals(utxoList, bridgeSupport.getUTXOsForAddress(tx, fastBridgeFedAddress));
}
Also used : Script(co.rsk.bitcoinj.script.Script) RskAddress(co.rsk.core.RskAddress) ActivationConfig(org.ethereum.config.blockchain.upgrades.ActivationConfig) Repository(org.ethereum.core.Repository) MutableRepository(org.ethereum.db.MutableRepository) ActivationConfigsForTest(org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest) Test(org.junit.Test)

Example 38 with Script

use of co.rsk.bitcoinj.script.Script in project rskj by rsksmart.

the class BridgeSupportTest method registerBtcTransaction_rejects_tx_with_witness_before_rskip_143_activation.

@Test(expected = VerificationException.EmptyInputsOrOutputs.class)
public void registerBtcTransaction_rejects_tx_with_witness_before_rskip_143_activation() throws BlockStoreException, IOException, BridgeIllegalArgumentException {
    ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class);
    when(activations.isActive(ConsensusRule.RSKIP143)).thenReturn(false);
    Repository repository = createRepository();
    BtcTransaction tx1 = new BtcTransaction(btcParams);
    tx1.addInput(Sha256Hash.ZERO_HASH, 0, new Script(new byte[] {}));
    TransactionWitness txWit = new TransactionWitness(1);
    txWit.setPush(0, new byte[] {});
    tx1.setWitness(0, txWit);
    tx1.addOutput(Coin.COIN, Address.fromBase58(BridgeRegTestConstants.getInstance().getBtcParams(), "mvbnrCX3bg1cDRUu8pkecrvP6vQkSLDSou"));
    byte[] bits = new byte[1];
    bits[0] = 0x3f;
    co.rsk.bitcoinj.core.BtcBlock registerHeader = new co.rsk.bitcoinj.core.BtcBlock(btcParams, 1, PegTestUtils.createHash(1), Sha256Hash.ZERO_HASH, 1, 1, 1, new ArrayList<>());
    List<Sha256Hash> hashes2 = new ArrayList<>();
    hashes2.add(tx1.getHash(true));
    PartialMerkleTree pmtWithWitness = new PartialMerkleTree(btcParams, bits, hashes2, 1);
    int height = 50;
    StoredBlock block = new StoredBlock(registerHeader, new BigInteger("0"), height);
    BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class);
    when(btcBlockStore.getFromCache(registerHeader.getHash())).thenReturn(block);
    co.rsk.bitcoinj.core.BtcBlock headBlock = new co.rsk.bitcoinj.core.BtcBlock(btcParams, 1, PegTestUtils.createHash(2), Sha256Hash.of(new byte[] { 1 }), 1, 1, 1, new ArrayList<>());
    StoredBlock chainHead = new StoredBlock(headBlock, new BigInteger("0"), 132);
    when(btcBlockStore.getChainHead()).thenReturn(chainHead);
    when(btcBlockStore.getStoredBlockAtMainChainHeight(block.getHeight())).thenReturn(block);
    BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class);
    when(mockFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore);
    BridgeStorageProvider provider = mock(BridgeStorageProvider.class);
    BridgeSupport bridgeSupport = getBridgeSupport(provider, repository, mockFactory);
    bridgeSupport.registerBtcTransaction(mock(Transaction.class), tx1.bitcoinSerialize(), height, pmtWithWitness.bitcoinSerialize());
    // When we send a segwit tx when the fork is not enabled, the tx is rejected because it does not have the
    // expected input format, therefore this method is never reached
    verify(btcBlockStore, never()).getStoredBlockAtMainChainHeight(height);
}
Also used : Script(co.rsk.bitcoinj.script.Script) ActivationConfig(org.ethereum.config.blockchain.upgrades.ActivationConfig) co.rsk.bitcoinj.core(co.rsk.bitcoinj.core) Repository(org.ethereum.core.Repository) MutableRepository(org.ethereum.db.MutableRepository) SimpleRskTransaction(co.rsk.peg.simples.SimpleRskTransaction) InternalTransaction(org.ethereum.vm.program.InternalTransaction) Transaction(org.ethereum.core.Transaction) BigInteger(java.math.BigInteger) ActivationConfigsForTest(org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest) Test(org.junit.Test)

Example 39 with Script

use of co.rsk.bitcoinj.script.Script in project rskj by rsksmart.

the class BridgeSupportTest method processPegIn_errorParsingPeginInstructions_afterRskip170_refundSender.

@Test
public void processPegIn_errorParsingPeginInstructions_afterRskip170_refundSender() throws IOException, PeginInstructionsException {
    // Arrange
    ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class);
    when(activations.isActive(ConsensusRule.RSKIP170)).thenReturn(true);
    Repository repository = createRepository();
    BtcECKey srcKey1 = new BtcECKey();
    ECKey key = ECKey.fromPublicOnly(srcKey1.getPubKey());
    RskAddress rskAddress = new RskAddress(key.getAddress());
    Address btcSenderAddress = srcKey1.toAddress(btcParams);
    BtcTransaction btcTx = new BtcTransaction(btcParams);
    btcTx.addOutput(Coin.COIN.multiply(10), bridgeConstants.getGenesisFederation().getAddress());
    btcTx.addInput(PegTestUtils.createHash(1), 0, new Script(new byte[] {}));
    BridgeStorageProvider provider = mock(BridgeStorageProvider.class);
    ReleaseTransactionSet releaseTransactionSet = new ReleaseTransactionSet(new HashSet<>());
    when(provider.getReleaseTransactionSet()).thenReturn(releaseTransactionSet);
    BtcLockSenderProvider btcLockSenderProvider = getBtcLockSenderProvider(TxSenderAddressType.P2PKH, btcSenderAddress, rskAddress);
    PeginInstructionsProvider peginInstructionsProvider = mock(PeginInstructionsProvider.class);
    when(peginInstructionsProvider.buildPeginInstructions(btcTx)).thenThrow(PeginInstructionsException.class);
    BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, provider, repository, btcLockSenderProvider, peginInstructionsProvider, mock(Block.class), mock(BtcBlockStoreWithCache.Factory.class), activations);
    // Act
    try {
        bridgeSupport.processPegIn(btcTx, mock(Transaction.class), 0, mock(Sha256Hash.class));
        // Should have thrown a RegisterBtcTransactionException
        Assert.fail();
    } catch (Exception ex) {
        // Assert
        Assert.assertTrue(ex instanceof RegisterBtcTransactionException);
        Assert.assertEquals(1, releaseTransactionSet.getEntries().size());
        // Check rejection tx input was created from btc tx and sent to the btc refund address indicated by the user
        boolean successfulRejection = false;
        for (ReleaseTransactionSet.Entry e : releaseTransactionSet.getEntries()) {
            BtcTransaction refundTx = e.getTransaction();
            if (refundTx.getInput(0).getOutpoint().getHash() == btcTx.getHash() && refundTx.getOutput(0).getScriptPubKey().getToAddress(btcParams).equals(btcSenderAddress)) {
                successfulRejection = true;
                break;
            }
        }
        Assert.assertTrue(successfulRejection);
    }
}
Also used : Script(co.rsk.bitcoinj.script.Script) RskAddress(co.rsk.core.RskAddress) PeginInstructionsProvider(co.rsk.peg.pegininstructions.PeginInstructionsProvider) ECKey(org.ethereum.crypto.ECKey) VMException(org.ethereum.vm.exception.VMException) IOException(java.io.IOException) BlockStoreException(co.rsk.bitcoinj.store.BlockStoreException) PeginInstructionsException(co.rsk.peg.pegininstructions.PeginInstructionsException) ActivationConfig(org.ethereum.config.blockchain.upgrades.ActivationConfig) BtcLockSenderProvider(co.rsk.peg.btcLockSender.BtcLockSenderProvider) Repository(org.ethereum.core.Repository) MutableRepository(org.ethereum.db.MutableRepository) OneOffWhiteListEntry(co.rsk.peg.whitelist.OneOffWhiteListEntry) SimpleRskTransaction(co.rsk.peg.simples.SimpleRskTransaction) InternalTransaction(org.ethereum.vm.program.InternalTransaction) Transaction(org.ethereum.core.Transaction) RskAddress(co.rsk.core.RskAddress) Block(org.ethereum.core.Block) ActivationConfigsForTest(org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest) Test(org.junit.Test)

Example 40 with Script

use of co.rsk.bitcoinj.script.Script in project rskj by rsksmart.

the class BridgeSupportTest method assertLockingCap.

private void assertLockingCap(boolean shouldLock, boolean isLockingCapEnabled, Coin lockingCap, Coin amountSentToNewFed, Coin amountSentToOldFed, Coin amountInNewFed, Coin amountInOldFed) throws BlockStoreException, IOException, BridgeIllegalArgumentException {
    // Configure if locking cap should be evaluated
    ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class);
    when(activations.isActive(ConsensusRule.RSKIP134)).thenReturn(isLockingCapEnabled);
    BridgeConstants bridgeConstants = mock(BridgeConstants.class);
    when(bridgeConstants.getLegacyMinimumPeginTxValueInSatoshis()).thenReturn(Coin.SATOSHI);
    when(bridgeConstants.getBtcParams()).thenReturn(BridgeRegTestConstants.getInstance().getBtcParams());
    when(bridgeConstants.getBtc2RskMinimumAcceptableConfirmations()).thenReturn(1);
    when(bridgeConstants.getGenesisFeePerKb()).thenReturn(BridgeRegTestConstants.getInstance().getGenesisFeePerKb());
    when(bridgeConstants.getMaxRbtc()).thenReturn(BridgeRegTestConstants.getInstance().getMaxRbtc());
    // Configure locking cap
    when(bridgeConstants.getInitialLockingCap()).thenReturn(lockingCap);
    Repository repository = createRepository();
    Federation oldFederation = this.getFederation(bridgeConstants);
    BridgeStorageProvider provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants, activations);
    // We need a random new fed
    provider.setNewFederation(this.getFederation(bridgeConstants, Arrays.asList(BtcECKey.fromPrivate(Hex.decode("fb01")), BtcECKey.fromPrivate(Hex.decode("fb02")), BtcECKey.fromPrivate(Hex.decode("fb03")))));
    // Use genesis fed as old
    provider.setOldFederation(oldFederation);
    Coin currentFunds = Coin.ZERO;
    // Configure existing utxos in both federations
    if (amountInOldFed != null) {
        UTXO utxo = new UTXO(Sha256Hash.wrap(HashUtil.randomHash()), 0, amountInOldFed, 1, false, new Script(new byte[] {}));
        provider.getOldFederationBtcUTXOs().add(utxo);
        currentFunds = currentFunds.add(amountInOldFed);
    }
    if (amountInNewFed != null) {
        UTXO utxo = new UTXO(Sha256Hash.wrap(HashUtil.randomHash()), 0, amountInNewFed, 1, false, new Script(new byte[] {}));
        provider.getNewFederationBtcUTXOs().add(utxo);
        currentFunds = currentFunds.add(amountInNewFed);
    }
    // Fund bridge in RBTC, substracting the funds that we are indicating were locked in the federations (which means a user locked)
    co.rsk.core.Coin bridgeBalance = LIMIT_MONETARY_BASE.subtract(co.rsk.core.Coin.fromBitcoin(currentFunds));
    repository.addBalance(PrecompiledContracts.BRIDGE_ADDR, bridgeBalance);
    // The locking cap shouldn't be surpassed by the initial configuration
    Assert.assertFalse(isLockingCapEnabled && currentFunds.isGreaterThan(lockingCap));
    Coin lockValue = Coin.ZERO;
    int newUtxos = 0;
    // Create transaction setting the outputs to the configured values
    BtcTransaction tx = new BtcTransaction(bridgeConstants.getBtcParams());
    if (amountSentToOldFed != null) {
        tx.addOutput(amountSentToOldFed, provider.getOldFederation().getAddress());
        lockValue = lockValue.add(amountSentToOldFed);
        newUtxos++;
    }
    if (amountSentToNewFed != null) {
        tx.addOutput(amountSentToNewFed, provider.getNewFederation().getAddress());
        lockValue = lockValue.add(amountSentToNewFed);
        newUtxos++;
    }
    BtcECKey srcKey = new BtcECKey();
    tx.addInput(PegTestUtils.createHash(1), 0, ScriptBuilder.createInputScript(null, srcKey));
    // Create header and PMT
    byte[] bits = new byte[1];
    bits[0] = 0x3f;
    List<Sha256Hash> hashes = new ArrayList<>();
    hashes.add(tx.getHash());
    PartialMerkleTree pmt = new PartialMerkleTree(bridgeConstants.getBtcParams(), bits, hashes, 1);
    Sha256Hash merkleRoot = pmt.getTxnHashAndMerkleRoot(new ArrayList<>());
    co.rsk.bitcoinj.core.BtcBlock registerHeader = new co.rsk.bitcoinj.core.BtcBlock(bridgeConstants.getBtcParams(), 1, PegTestUtils.createHash(1), merkleRoot, 1, 1, 1, new ArrayList<BtcTransaction>());
    BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class);
    BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class);
    when(mockFactory.newInstance(repository, bridgeConstants, provider, activations)).thenReturn(btcBlockStore);
    Block executionBlock = Mockito.mock(Block.class);
    when(executionBlock.getNumber()).thenReturn(10L);
    // Get the tx sender public key
    byte[] data = tx.getInput(0).getScriptSig().getChunks().get(1).data;
    BtcECKey senderBtcKey = BtcECKey.fromPublicOnly(data);
    // Whitelist the addresses
    LockWhitelist whitelist = provider.getLockWhitelist();
    Address address = senderBtcKey.toAddress(bridgeConstants.getBtcParams());
    whitelist.put(address, new OneOffWhiteListEntry(address, lockValue));
    // The address is whitelisted
    Assert.assertThat(whitelist.isWhitelisted(address), is(true));
    BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, provider, repository, new BtcLockSenderProvider(), new PeginInstructionsProvider(), executionBlock, mockFactory, activations);
    // Simulate blockchain
    int height = 1;
    mockChainOfStoredBlocks(btcBlockStore, registerHeader, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height);
    Transaction rskTx = mock(Transaction.class);
    Keccak256 hash = new Keccak256(HashUtil.keccak256(new byte[] {}));
    when(rskTx.getHash()).thenReturn(hash);
    // Try to register tx
    bridgeSupport.registerBtcTransaction(rskTx, tx.bitcoinSerialize(), height, pmt.bitcoinSerialize());
    bridgeSupport.save();
    // If the address is no longer whitelisted, it means it was consumed, whether the lock was rejected by lockingCap or not
    Assert.assertThat(whitelist.isWhitelisted(address), is(false));
    // The Btc transaction should have been processed
    assertTrue(bridgeSupport.isBtcTxHashAlreadyProcessed(tx.getHash()));
    co.rsk.core.Coin totalAmountExpectedToHaveBeenLocked = co.rsk.core.Coin.fromBitcoin(shouldLock ? lockValue : Coin.ZERO);
    RskAddress srcKeyRskAddress = new RskAddress(org.ethereum.crypto.ECKey.fromPrivate(srcKey.getPrivKey()).getAddress());
    // Verify amount was locked
    Assert.assertEquals(totalAmountExpectedToHaveBeenLocked, repository.getBalance(srcKeyRskAddress));
    Assert.assertEquals(bridgeBalance.subtract(totalAmountExpectedToHaveBeenLocked), repository.getBalance(PrecompiledContracts.BRIDGE_ADDR));
    if (!shouldLock) {
        // Release tx should have been created directly to the signatures stack
        BtcTransaction releaseTx = provider.getReleaseTransactionSet().getEntries().iterator().next().getTransaction();
        Assert.assertNotNull(releaseTx);
        // returns the funds to the sender
        Assert.assertEquals(1, releaseTx.getOutputs().size());
        Assert.assertEquals(address, releaseTx.getOutputs().get(0).getAddressFromP2PKHScript(bridgeConstants.getBtcParams()));
        Assert.assertEquals(lockValue, releaseTx.getOutputs().get(0).getValue().add(releaseTx.getFee()));
        // Uses the same UTXO(s)
        Assert.assertEquals(newUtxos, releaseTx.getInputs().size());
        for (int i = 0; i < newUtxos; i++) {
            TransactionInput input = releaseTx.getInput(i);
            Assert.assertEquals(tx.getHash(), input.getOutpoint().getHash());
            Assert.assertEquals(i, input.getOutpoint().getIndex());
        }
    }
}
Also used : RskAddress(co.rsk.core.RskAddress) BtcLockSenderProvider(co.rsk.peg.btcLockSender.BtcLockSenderProvider) LockWhitelist(co.rsk.peg.whitelist.LockWhitelist) PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(co.rsk.peg.PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation) PegTestUtils.createBaseRedeemScriptThatSpendsFromTheFederation(co.rsk.peg.PegTestUtils.createBaseRedeemScriptThatSpendsFromTheFederation) RskAddress(co.rsk.core.RskAddress) BridgeConstants(co.rsk.config.BridgeConstants) Script(co.rsk.bitcoinj.script.Script) PeginInstructionsProvider(co.rsk.peg.pegininstructions.PeginInstructionsProvider) Keccak256(co.rsk.crypto.Keccak256) ActivationConfig(org.ethereum.config.blockchain.upgrades.ActivationConfig) co.rsk.bitcoinj.core(co.rsk.bitcoinj.core) Repository(org.ethereum.core.Repository) MutableRepository(org.ethereum.db.MutableRepository) SimpleRskTransaction(co.rsk.peg.simples.SimpleRskTransaction) InternalTransaction(org.ethereum.vm.program.InternalTransaction) Transaction(org.ethereum.core.Transaction) Block(org.ethereum.core.Block) OneOffWhiteListEntry(co.rsk.peg.whitelist.OneOffWhiteListEntry)

Aggregations

Script (co.rsk.bitcoinj.script.Script)123 Test (org.junit.Test)91 ActivationConfigsForTest (org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest)60 RskAddress (co.rsk.core.RskAddress)47 BtcTransaction (co.rsk.bitcoinj.core.BtcTransaction)40 Repository (org.ethereum.core.Repository)34 MutableRepository (org.ethereum.db.MutableRepository)33 ActivationConfig (org.ethereum.config.blockchain.upgrades.ActivationConfig)29 BtcECKey (co.rsk.bitcoinj.core.BtcECKey)26 Block (org.ethereum.core.Block)24 Context (co.rsk.bitcoinj.core.Context)21 co.rsk.bitcoinj.core (co.rsk.bitcoinj.core)20 PeginInstructionsProvider (co.rsk.peg.pegininstructions.PeginInstructionsProvider)20 Address (co.rsk.bitcoinj.core.Address)17 TransactionOutPoint (co.rsk.bitcoinj.core.TransactionOutPoint)17 PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation (co.rsk.peg.PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation)17 PegTestUtils.createBaseRedeemScriptThatSpendsFromTheFederation (co.rsk.peg.PegTestUtils.createBaseRedeemScriptThatSpendsFromTheFederation)17 BtcLockSenderProvider (co.rsk.peg.btcLockSender.BtcLockSenderProvider)17 SimpleRskTransaction (co.rsk.peg.simples.SimpleRskTransaction)17 InternalTransaction (org.ethereum.vm.program.InternalTransaction)17