Search in sources :

Example 6 with RepositoryImpl

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

the class BridgeSupportTest method callUpdateCollectionsGenerateEventLog.

@Test
public void callUpdateCollectionsGenerateEventLog() throws IOException, BlockStoreException {
    Repository track = new RepositoryImpl(config).startTracking();
    BlockGenerator blockGenerator = new BlockGenerator();
    List<Block> blocks = blockGenerator.getSimpleBlockChain(blockGenerator.getGenesisBlock(), 10);
    org.ethereum.core.Block rskCurrentBlock = blocks.get(9);
    List<LogInfo> eventLogs = new LinkedList<>();
    BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeConstants, eventLogs);
    BridgeSupport bridgeSupport = new BridgeSupport(config, track, eventLogger, PrecompiledContracts.BRIDGE_ADDR, rskCurrentBlock);
    Transaction tx = Transaction.create(config, TO_ADDRESS, DUST_AMOUNT, NONCE, GAS_PRICE, GAS_LIMIT, DATA);
    ECKey key = new ECKey();
    tx.sign(key.getPrivKeyBytes());
    bridgeSupport.updateCollections(tx);
    Assert.assertEquals(1, eventLogs.size());
    // Assert address that made the log
    LogInfo result = eventLogs.get(0);
    Assert.assertArrayEquals(PrecompiledContracts.BRIDGE_ADDR.getBytes(), result.getAddress());
    // Assert log topics
    Assert.assertEquals(1, result.getTopics().size());
    Assert.assertEquals(Bridge.UPDATE_COLLECTIONS_TOPIC, result.getTopics().get(0));
    // Assert log data
    Assert.assertArrayEquals(key.getAddress(), RLP.decode2(result.getData()).get(0).getRLPData());
}
Also used : BridgeEventLoggerImpl(co.rsk.peg.utils.BridgeEventLoggerImpl) LogInfo(org.ethereum.vm.LogInfo) 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 7 with RepositoryImpl

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

the class BridgeSupportTest method callUpdateCollectionsThrowsExceededMaxTransactionSize.

@Test
public void callUpdateCollectionsThrowsExceededMaxTransactionSize() 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.COIN.multiply(7));
    for (int i = 0; i < 2000; i++) {
        provider0.getNewFederationBtcUTXOs().add(new UTXO(PegTestUtils.createHash(), 1, Coin.CENT, 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);
    BlockChainBuilder builder = new BlockChainBuilder();
    Blockchain blockchain = builder.setTesting(true).build();
    for (Block block : blocks) blockchain.getBlockStore().saveBlock(block, TEST_DIFFICULTY, true);
    org.ethereum.core.Block rskCurrentBlock = blocks.get(9);
    ReceiptStore rskReceiptStore = null;
    org.ethereum.db.BlockStore rskBlockStore = blockchain.getBlockStore();
    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(1, provider.getReleaseRequestQueue().getEntries().size());
    Assert.assertEquals(0, provider.getReleaseTransactionSet().getEntries().size());
    Assert.assertEquals(0, provider.getRskTxsWaitingForSignatures().size());
    // Check the wallet has not been emptied
    Assert.assertFalse(provider.getNewFederationBtcUTXOs().isEmpty());
}
Also used : ECKey(org.ethereum.crypto.ECKey) BlockGenerator(co.rsk.blockchain.utils.BlockGenerator) BlockChainBuilder(co.rsk.test.builders.BlockChainBuilder) 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) ReceiptStore(org.ethereum.db.ReceiptStore) BridgeEventLogger(co.rsk.peg.utils.BridgeEventLogger) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 8 with RepositoryImpl

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

the class BridgeSupportTest method addSignatureFromValidFederator.

/**
 * Helper method to test addSignature() with a valid federatorPublicKey parameter and both valid/invalid signatures
 * @param privateKeysToSignWith keys used to sign the tx. Federator key when we want to produce a valid signature, a random key when we want to produce an invalid signature
 * @param numberOfInputsToSign There is just 1 input. 1 when testing the happy case, other values to test attacks/bugs.
 * @param signatureCanonical Signature should be canonical. true when testing the happy case, false to test attacks/bugs.
 * @param signTwice Sign again with the same key
 * @param expectedResult "InvalidParameters", "PartiallySigned" or "FullySigned"
 */
private void addSignatureFromValidFederator(List<BtcECKey> privateKeysToSignWith, int numberOfInputsToSign, boolean signatureCanonical, boolean signTwice, String expectedResult) 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, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
    BtcTransaction prevTx = new BtcTransaction(btcParams);
    TransactionOutput prevOut = new TransactionOutput(btcParams, prevTx, Coin.FIFTY_COINS, federation.getAddress());
    prevTx.addOutput(prevOut);
    BtcTransaction t = new BtcTransaction(btcParams);
    TransactionOutput output = new TransactionOutput(btcParams, t, Coin.COIN, new BtcECKey().toAddress(btcParams));
    t.addOutput(output);
    t.addInput(prevOut).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);
    Script inputScript = t.getInputs().get(0).getScriptSig();
    List<ScriptChunk> chunks = inputScript.getChunks();
    byte[] program = chunks.get(chunks.size() - 1).data;
    Script redeemScript = new Script(program);
    Sha256Hash sighash = t.hashForSignature(0, redeemScript, BtcTransaction.SigHash.ALL, false);
    BtcECKey.ECDSASignature sig = privateKeysToSignWith.get(0).sign(sighash);
    if (!signatureCanonical) {
        sig = new BtcECKey.ECDSASignature(sig.r, BtcECKey.CURVE.getN().subtract(sig.s));
    }
    byte[] derEncodedSig = sig.encodeToDER();
    List derEncodedSigs = new ArrayList();
    for (int i = 0; i < numberOfInputsToSign; i++) {
        derEncodedSigs.add(derEncodedSig);
    }
    bridgeSupport.addSignature(1, findPublicKeySignedBy(federation.getPublicKeys(), privateKeysToSignWith.get(0)), derEncodedSigs, keccak256.getBytes());
    if (signTwice) {
        // Create another valid signature with the same private key
        ECDSASigner signer = new ECDSASigner();
        ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(privateKeysToSignWith.get(0).getPrivKey(), BtcECKey.CURVE);
        signer.init(true, privKey);
        BigInteger[] components = signer.generateSignature(sighash.getBytes());
        BtcECKey.ECDSASignature sig2 = new BtcECKey.ECDSASignature(components[0], components[1]).toCanonicalised();
        bridgeSupport.addSignature(1, findPublicKeySignedBy(federation.getPublicKeys(), privateKeysToSignWith.get(0)), Lists.newArrayList(sig2.encodeToDER()), keccak256.getBytes());
    }
    if (privateKeysToSignWith.size() > 1) {
        BtcECKey.ECDSASignature sig2 = privateKeysToSignWith.get(1).sign(sighash);
        byte[] derEncodedSig2 = sig2.encodeToDER();
        List derEncodedSigs2 = new ArrayList();
        for (int i = 0; i < numberOfInputsToSign; i++) {
            derEncodedSigs2.add(derEncodedSig2);
        }
        bridgeSupport.addSignature(1, findPublicKeySignedBy(federation.getPublicKeys(), privateKeysToSignWith.get(1)), derEncodedSigs2, keccak256.getBytes());
    }
    bridgeSupport.save();
    track.commit();
    provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
    if ("FullySigned".equals(expectedResult)) {
        Assert.assertTrue(provider.getRskTxsWaitingForSignatures().isEmpty());
        Assert.assertThat(logs, is(not(empty())));
        Assert.assertThat(logs, hasSize(3));
        LogInfo releaseTxEvent = logs.get(2);
        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());
        Script retrievedScriptSig = releaseTx.getInput(0).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);
    } else {
        Script retrievedScriptSig = provider.getRskTxsWaitingForSignatures().get(keccak256).getInput(0).getScriptSig();
        Assert.assertEquals(4, retrievedScriptSig.getChunks().size());
        // for "InvalidParameters"
        boolean expectSignatureToBePersisted = false;
        if ("PartiallySigned".equals(expectedResult)) {
            expectSignatureToBePersisted = true;
        }
        Assert.assertEquals(expectSignatureToBePersisted, retrievedScriptSig.getChunks().get(1).data.length > 0);
        Assert.assertEquals(false, retrievedScriptSig.getChunks().get(2).data.length > 0);
    }
}
Also used : RLPList(org.ethereum.util.RLPList) BridgeEventLogger(co.rsk.peg.utils.BridgeEventLogger) BridgeEventLoggerImpl(co.rsk.peg.utils.BridgeEventLoggerImpl) Script(co.rsk.bitcoinj.script.Script) LogInfo(org.ethereum.vm.LogInfo) ECDSASigner(org.spongycastle.crypto.signers.ECDSASigner) Keccak256(co.rsk.crypto.Keccak256) ScriptChunk(co.rsk.bitcoinj.script.ScriptChunk) RLPList(org.ethereum.util.RLPList) ECPrivateKeyParameters(org.spongycastle.crypto.params.ECPrivateKeyParameters) RepositoryImpl(co.rsk.db.RepositoryImpl) BigInteger(java.math.BigInteger)

Example 9 with RepositoryImpl

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

the class BridgeSupportTest method sendOrphanBlockHeader.

@Test
public void sendOrphanBlockHeader() throws IOException, BlockStoreException {
    Repository repository = new RepositoryImpl(config);
    Repository track = repository.startTracking();
    BridgeConstants bridgeConstants = config.getBlockchainConfig().getCommonConstants().getBridgeConstants();
    Context btcContext = new Context(bridgeConstants.getBtcParams());
    BtcBlockStore btcBlockStore = new RepositoryBlockStore(config, track, PrecompiledContracts.BRIDGE_ADDR);
    BtcBlockChain btcBlockChain = new BtcBlockChain(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);
    co.rsk.bitcoinj.core.BtcBlock block = new co.rsk.bitcoinj.core.BtcBlock(btcParams, 1, PegTestUtils.createHash(), PegTestUtils.createHash(), 1, 1, 1, new ArrayList<BtcTransaction>());
    co.rsk.bitcoinj.core.BtcBlock[] headers = new co.rsk.bitcoinj.core.BtcBlock[1];
    headers[0] = block;
    bridgeSupport.receiveHeaders(headers);
    bridgeSupport.save();
    track.commit();
    Assert.assertNull(btcBlockStore.get(block.getHash()));
}
Also used : BtcBlockStore(co.rsk.bitcoinj.store.BtcBlockStore) co.rsk.bitcoinj.core(co.rsk.bitcoinj.core) org.ethereum.core(org.ethereum.core) RepositoryImpl(co.rsk.db.RepositoryImpl) BridgeConstants(co.rsk.config.BridgeConstants) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 10 with RepositoryImpl

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

the class BridgeSupportTest method registerBtcTransactionReleaseTx.

@Test
public void registerBtcTransactionReleaseTx() throws BlockStoreException, AddressFormatException, IOException {
    // Federation is the genesis federation ATM
    Federation federation = bridgeConstants.getGenesisFederation();
    Repository repository = new RepositoryImpl(config);
    repository.addBalance(PrecompiledContracts.BRIDGE_ADDR, LIMIT_MONETARY_BASE);
    Repository track = repository.startTracking();
    Block executionBlock = Mockito.mock(Block.class);
    Mockito.when(executionBlock.getNumber()).thenReturn(10L);
    BridgeRegTestConstants bridgeConstants = BridgeRegTestConstants.getInstance();
    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);
    Address address2 = federation.getAddress();
    tx.addOutput(Coin.COIN, address2);
    // Create previous tx
    BtcTransaction prevTx = new BtcTransaction(btcParams);
    TransactionOutput prevOut = new TransactionOutput(btcParams, prevTx, Coin.FIFTY_COINS, federation.getAddress());
    prevTx.addOutput(prevOut);
    // Create tx input
    tx.addInput(prevOut);
    // Create tx input base script sig
    Script scriptSig = PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(federation);
    // Create sighash
    Script redeemScript = ScriptBuilder.createRedeemScript(federation.getNumberOfSignaturesRequired(), federation.getPublicKeys());
    Sha256Hash sighash = tx.hashForSignature(0, redeemScript, BtcTransaction.SigHash.ALL, false);
    // Sign by federator 0
    BtcECKey.ECDSASignature sig0 = bridgeConstants.getFederatorPrivateKeys().get(0).sign(sighash);
    TransactionSignature txSig0 = new TransactionSignature(sig0, BtcTransaction.SigHash.ALL, false);
    int sigIndex0 = scriptSig.getSigInsertionIndex(sighash, federation.getPublicKeys().get(0));
    scriptSig = ScriptBuilder.updateScriptWithSignature(scriptSig, txSig0.encodeToBitcoin(), sigIndex0, 1, 1);
    // Sign by federator 1
    BtcECKey.ECDSASignature sig1 = bridgeConstants.getFederatorPrivateKeys().get(1).sign(sighash);
    TransactionSignature txSig1 = new TransactionSignature(sig1, BtcTransaction.SigHash.ALL, false);
    int sigIndex1 = scriptSig.getSigInsertionIndex(sighash, federation.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());
    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] = 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);
    ((SimpleBlockChain) btcBlockChain).useHighBlock();
    bridgeSupport.registerBtcTransaction(mock(Transaction.class), tx, 1, pmt);
    bridgeSupport.save();
    ((SimpleBlockChain) btcBlockChain).useBlock();
    track.commit();
    Assert.assertEquals(LIMIT_MONETARY_BASE, repository.getBalance(PrecompiledContracts.BRIDGE_ADDR));
    BridgeStorageProvider provider2 = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, config.getBlockchainConfig().getCommonConstants().getBridgeConstants());
    Assert.assertEquals(1, provider2.getNewFederationBtcUTXOs().size());
    Assert.assertEquals(Coin.COIN, provider2.getNewFederationBtcUTXOs().get(0).getValue());
    Assert.assertEquals(0, provider2.getReleaseRequestQueue().getEntries().size());
    Assert.assertEquals(0, provider2.getReleaseTransactionSet().getEntries().size());
    Assert.assertTrue(provider2.getRskTxsWaitingForSignatures().isEmpty());
    Assert.assertEquals(1, provider2.getBtcTxHashesAlreadyProcessed().size());
}
Also used : RskAddress(co.rsk.core.RskAddress) TransactionSignature(co.rsk.bitcoinj.crypto.TransactionSignature) SimpleBlockChain(co.rsk.peg.simples.SimpleBlockChain) BridgeRegTestConstants(co.rsk.config.BridgeRegTestConstants) 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)

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