From 301936a40b82e8a227b44ccfb3656cc258b1e554 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Wed, 17 Mar 2021 16:16:26 -0300 Subject: [PATCH 01/34] Bridge getBestBlockNumber method --- rskj-core/src/main/java/co/rsk/peg/Bridge.java | 11 +++++++++++ rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index c608c7ab74f..3927f9db380 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -1145,6 +1145,17 @@ public long registerFastBridgeBtcTransaction(Object[] args) { } } + public long getBestBlockNumber(Object[] args) { + logger.trace("getBestBlockNumber"); + + try { + return this.bridgeSupport.getBtcBlockchainBestChainHeight(); + } catch (Exception e) { + logger.warn("Exception in getBestBlockNumber", e); + return BridgeSupport.FAST_BRIDGE_GENERIC_ERROR; + } + } + public static BridgeMethods.BridgeMethodExecutor activeAndRetiringFederationOnly(BridgeMethods.BridgeMethodExecutor decoratee, String funcName) { return (self, args) -> { Federation retiringFederation = self.bridgeSupport.getRetiringFederation(); diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index fc0d2e7a801..a580b0fc381 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -613,6 +613,17 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::registerFastBridgeBtcTransaction, activations -> activations.isActive(RSKIP176), false + ), + GET_BEST_BLOCK_NUMBER( + CallTransaction.Function.fromSignature( + "getBestBlockNumber", + new String[0], + new String[]{"uint256"} + ), + fixedCost(10000L), // TODO: Define a cost + (BridgeMethodExecutorTyped) Bridge::getBestBlockNumber, + activations -> true, // TODO: Review activation + false ); private final CallTransaction.Function function; From ea190bedbe9080b0cc9ca22f774ab31c109f3bd9 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Wed, 17 Mar 2021 17:02:32 -0300 Subject: [PATCH 02/34] Bridge getBestBlockHeader method --- rskj-core/src/main/java/co/rsk/peg/Bridge.java | 11 +++++++++++ .../src/main/java/co/rsk/peg/BridgeMethods.java | 11 +++++++++++ .../src/main/java/co/rsk/peg/BridgeSupport.java | 14 ++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 3927f9db380..d1a0189baae 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -1145,6 +1145,17 @@ public long registerFastBridgeBtcTransaction(Object[] args) { } } + public byte[] getBestBlockHeader(Object[] args) { + logger.trace("getBestBlockHeader"); + + try { + return this.bridgeSupport.getBtcBlockchainSerializedBestBlockHeader(); + } catch (Exception e) { + logger.warn("Exception in getBestBlockHeader", e); + return null; + } + } + public long getBestBlockNumber(Object[] args) { logger.trace("getBestBlockNumber"); diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index a580b0fc381..0ca9a4429f3 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -614,6 +614,17 @@ public enum BridgeMethods { activations -> activations.isActive(RSKIP176), false ), + GET_BEST_BLOCK_HEADER( + CallTransaction.Function.fromSignature( + "getBestBlockHeader", + new String[0], + new String[]{"bytes"} + ), + fixedCost(10000L), // TODO: Define a cost + (BridgeMethodExecutorTyped) Bridge::getBestBlockHeader, + activations -> true, // TODO: Review activation + false + ), GET_BEST_BLOCK_NUMBER( CallTransaction.Function.fromSignature( "getBestBlockNumber", diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java index c2e27f042ec..9e50d16a89b 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1356,6 +1356,20 @@ public List getBtcBlockchainBlockLocator() throws IOException, Block return blockLocator; } + public byte[] getBtcBlockchainSerializedBestBlockHeader() throws BlockStoreException, IOException { + this.ensureBtcBlockStore(); + + StoredBlock head = btcBlockStore.getChainHead(); + + byte[] bytes = head.getHeader().unsafeBitcoinSerialize(); + + byte[] header = new byte[80]; + + System.arraycopy(bytes, 0, header, 0, 80); + + return header; + } + public Sha256Hash getBtcBlockchainBlockHashAtDepth(int depth) throws BlockStoreException, IOException { Context.propagate(btcContext); this.ensureBtcBlockStore(); From d7a787f03033d286304196d8dcf2e696ebf38249 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Wed, 17 Mar 2021 20:27:23 -0300 Subject: [PATCH 03/34] Bridge getBitcoinHeaderByHash --- .../src/main/java/co/rsk/peg/Bridge.java | 25 ++++++++++++++++++ .../main/java/co/rsk/peg/BridgeMethods.java | 22 ++++++++++++++++ .../main/java/co/rsk/peg/BridgeSupport.java | 26 +++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index d1a0189baae..a509df9ed8f 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -1167,6 +1167,31 @@ public long getBestBlockNumber(Object[] args) { } } + public byte[] getBestBlockHash(Object[] args) { + logger.trace("getBestBlockHash"); + + try { + return this.bridgeSupport.getBtcBlockchainBestBlockHash().getBytes(); + } catch (Exception e) { + logger.warn("Exception in getBestBlockHash", e); + return null; + } + } + + public byte[] getBitcoinHeaderByHash(Object[] args) { + logger.trace("getBitcoinHeaderByHash"); + + try { + byte[] hashBytes = (byte[])args[0]; + Sha256Hash hash = new Sha256Hash(hashBytes); + + return this.bridgeSupport.getBtcBlockHeaderByHash(hash); + } catch (Exception e) { + logger.warn("Exception in getBitcoinHeaderByHash", e); + return null; + } + } + public static BridgeMethods.BridgeMethodExecutor activeAndRetiringFederationOnly(BridgeMethods.BridgeMethodExecutor decoratee, String funcName) { return (self, args) -> { Federation retiringFederation = self.bridgeSupport.getRetiringFederation(); diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 0ca9a4429f3..981dc89f689 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -635,6 +635,28 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::getBestBlockNumber, activations -> true, // TODO: Review activation false + ), + GET_BEST_BLOCK_HASH( + CallTransaction.Function.fromSignature( + "getBestBlockHash", + new String[0], + new String[]{"bytes32"} + ), + fixedCost(10000L), // TODO: Define a cost + (BridgeMethodExecutorTyped) Bridge::getBestBlockHash, + activations -> true, // TODO: Review activation + false + ), + GET_BITCOIN_HEADER_BY_HASH( + CallTransaction.Function.fromSignature( + "getBitcoinHeaderByHash", + new String[]{"bytes32"}, + new String[]{"bytes"} + ), + fixedCost(10000L), // TODO: Define a cost + (BridgeMethodExecutorTyped) Bridge::getBitcoinHeaderByHash, + activations -> true, // TODO: Review activation + false ); private final CallTransaction.Function function; diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java index 9e50d16a89b..ee71e0139b1 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1356,6 +1356,24 @@ public List getBtcBlockchainBlockLocator() throws IOException, Block return blockLocator; } + public byte[] getBtcBlockHeaderByHash(Sha256Hash hash) throws IOException, BlockStoreException { + this.ensureBtcBlockStore(); + + StoredBlock block = btcBlockStore.get(hash); + + if (block == null) { + return null; + } + + byte[] bytes = block.getHeader().unsafeBitcoinSerialize(); + + byte[] header = new byte[80]; + + System.arraycopy(bytes, 0, header, 0, 80); + + return header; + } + public byte[] getBtcBlockchainSerializedBestBlockHeader() throws BlockStoreException, IOException { this.ensureBtcBlockStore(); @@ -1370,6 +1388,14 @@ public byte[] getBtcBlockchainSerializedBestBlockHeader() throws BlockStoreExcep return header; } + public Sha256Hash getBtcBlockchainBestBlockHash() throws BlockStoreException, IOException { + this.ensureBtcBlockStore(); + + StoredBlock head = btcBlockStore.getChainHead(); + + return head.getHeader().getHash(); + } + public Sha256Hash getBtcBlockchainBlockHashAtDepth(int depth) throws BlockStoreException, IOException { Context.propagate(btcContext); this.ensureBtcBlockStore(); From 5b5065539aa8fce8df7686cf75677f1fa4457342 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Wed, 17 Mar 2021 20:43:05 -0300 Subject: [PATCH 04/34] Bridge getBitcoinParentByHash --- .../src/main/java/co/rsk/peg/Bridge.java | 14 +++++++++++ .../main/java/co/rsk/peg/BridgeMethods.java | 11 +++++++++ .../main/java/co/rsk/peg/BridgeSupport.java | 24 +++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index a509df9ed8f..2cc4e600bb4 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -1192,6 +1192,20 @@ public byte[] getBitcoinHeaderByHash(Object[] args) { } } + public byte[] getBitcoinParentByHash(Object[] args) { + logger.trace("getBitcoinParentByHash"); + + try { + byte[] hashBytes = (byte[])args[0]; + Sha256Hash hash = new Sha256Hash(hashBytes); + + return this.bridgeSupport.getBtcParentBlockHeaderByHash(hash); + } catch (Exception e) { + logger.warn("Exception in getBitcoinHeaderByHash", e); + return null; + } + } + public static BridgeMethods.BridgeMethodExecutor activeAndRetiringFederationOnly(BridgeMethods.BridgeMethodExecutor decoratee, String funcName) { return (self, args) -> { Federation retiringFederation = self.bridgeSupport.getRetiringFederation(); diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 981dc89f689..b9a21db91cd 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -657,6 +657,17 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::getBitcoinHeaderByHash, activations -> true, // TODO: Review activation false + ), + GET_BITCOIN_PARENT_BY_HASH( + CallTransaction.Function.fromSignature( + "getBitcoinParentByHash", + new String[]{"bytes32"}, + new String[]{"bytes"} + ), + fixedCost(10000L), // TODO: Define a cost + (BridgeMethodExecutorTyped) Bridge::getBitcoinParentByHash, + activations -> true, // TODO: Review activation + false ); private final CallTransaction.Function function; diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java index ee71e0139b1..82b92f3ea5b 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1374,6 +1374,30 @@ public byte[] getBtcBlockHeaderByHash(Sha256Hash hash) throws IOException, Block return header; } + public byte[] getBtcParentBlockHeaderByHash(Sha256Hash hash) throws IOException, BlockStoreException { + this.ensureBtcBlockStore(); + + StoredBlock block = btcBlockStore.get(hash); + + if (block == null) { + return null; + } + + StoredBlock parent = btcBlockStore.get(block.getHeader().getPrevBlockHash()); + + if (parent == null) { + return null; + } + + byte[] bytes = parent.getHeader().unsafeBitcoinSerialize(); + + byte[] header = new byte[80]; + + System.arraycopy(bytes, 0, header, 0, 80); + + return header; + } + public byte[] getBtcBlockchainSerializedBestBlockHeader() throws BlockStoreException, IOException { this.ensureBtcBlockStore(); From 48453019962b503b350417dfabc6a7b6c6eb7669 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Mon, 22 Mar 2021 14:21:55 -0300 Subject: [PATCH 05/34] Bridge getBitcoinHeaderByHeight, first implementation --- .../src/main/java/co/rsk/peg/Bridge.java | 13 +++++++++ .../main/java/co/rsk/peg/BridgeMethods.java | 11 ++++++++ .../main/java/co/rsk/peg/BridgeSupport.java | 28 +++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 2cc4e600bb4..74db48660f4 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -1192,6 +1192,19 @@ public byte[] getBitcoinHeaderByHash(Object[] args) { } } + public byte[] getBitcoinHeaderByHeight(Object[] args) { + logger.trace("getBitcoinHeaderByHeight"); + + try { + int height = ((BigInteger) args[0]).intValue(); + + return this.bridgeSupport.getBtcBlockHeaderByHeight(height); + } catch (Exception e) { + logger.warn("Exception in getBitcoinHeaderByHeight", e); + return null; + } + } + public byte[] getBitcoinParentByHash(Object[] args) { logger.trace("getBitcoinParentByHash"); diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index b9a21db91cd..55d7873ea7b 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -668,6 +668,17 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::getBitcoinParentByHash, activations -> true, // TODO: Review activation false + ), + GET_BITCOIN_HEADER_BY_HEIGHT( + CallTransaction.Function.fromSignature( + "getBitcoinHeaderByHeight", + new String[]{"uint256"}, + new String[]{"bytes"} + ), + fixedCost(10000L), // TODO: Define a cost + (BridgeMethodExecutorTyped) Bridge::getBitcoinHeaderByHeight, + activations -> true, // TODO: Review activation + false ); private final CallTransaction.Function function; diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java index 82b92f3ea5b..9ba06dc9575 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1435,6 +1435,34 @@ public Sha256Hash getBtcBlockchainBlockHashAtDepth(int depth) throws BlockStoreE return blockAtDepth.getHeader().getHash(); } + public byte[] getBtcBlockHeaderByHeight(int height) throws BlockStoreException, IOException { + Context.propagate(btcContext); + this.ensureBtcBlockStore(); + + StoredBlock head = btcBlockStore.getChainHead(); + int highestHeight= head.getHeight(); + int lowestHeight = getLowestBlock().getHeight(); + int maxDepth = head.getHeight() - getLowestBlock().getHeight(); + + if (height < lowestHeight || height > highestHeight) { + throw new IndexOutOfBoundsException(String.format("Height must be between %d and %d", lowestHeight, highestHeight)); + } + + StoredBlock block = btcBlockStore.getStoredBlockAtMainChainDepth(highestHeight - height); + + if (block == null) { + return null; + } + + byte[] bytes = block.getHeader().unsafeBitcoinSerialize(); + + byte[] header = new byte[80]; + + System.arraycopy(bytes, 0, header, 0, 80); + + return header; + } + public Long getBtcTransactionConfirmationsGetCost(Object[] args) { final long BASIC_COST = 27_000; final long STEP_COST = 315; From db9560bad700fa7ea696d0e4077b2afc6251f198 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Mon, 22 Mar 2021 18:17:49 -0300 Subject: [PATCH 06/34] New Bridge method gas cost set to 20_000 --- .../src/main/java/co/rsk/peg/BridgeMethods.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 55d7873ea7b..d568d160d79 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -620,7 +620,7 @@ public enum BridgeMethods { new String[0], new String[]{"bytes"} ), - fixedCost(10000L), // TODO: Define a cost + fixedCost(20000L), (BridgeMethodExecutorTyped) Bridge::getBestBlockHeader, activations -> true, // TODO: Review activation false @@ -631,7 +631,7 @@ public enum BridgeMethods { new String[0], new String[]{"uint256"} ), - fixedCost(10000L), // TODO: Define a cost + fixedCost(20000L), (BridgeMethodExecutorTyped) Bridge::getBestBlockNumber, activations -> true, // TODO: Review activation false @@ -642,7 +642,7 @@ public enum BridgeMethods { new String[0], new String[]{"bytes32"} ), - fixedCost(10000L), // TODO: Define a cost + fixedCost(20000L), (BridgeMethodExecutorTyped) Bridge::getBestBlockHash, activations -> true, // TODO: Review activation false @@ -653,7 +653,7 @@ public enum BridgeMethods { new String[]{"bytes32"}, new String[]{"bytes"} ), - fixedCost(10000L), // TODO: Define a cost + fixedCost(20000L), (BridgeMethodExecutorTyped) Bridge::getBitcoinHeaderByHash, activations -> true, // TODO: Review activation false @@ -664,7 +664,7 @@ public enum BridgeMethods { new String[]{"bytes32"}, new String[]{"bytes"} ), - fixedCost(10000L), // TODO: Define a cost + fixedCost(20000L), (BridgeMethodExecutorTyped) Bridge::getBitcoinParentByHash, activations -> true, // TODO: Review activation false @@ -675,7 +675,7 @@ public enum BridgeMethods { new String[]{"uint256"}, new String[]{"bytes"} ), - fixedCost(10000L), // TODO: Define a cost + fixedCost(20000L), (BridgeMethodExecutorTyped) Bridge::getBitcoinHeaderByHeight, activations -> true, // TODO: Review activation false From 161654281e218f837064ec98c12ddf4ac7d7c491 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Mon, 22 Mar 2021 18:26:31 -0300 Subject: [PATCH 07/34] Serialize Block Header refactor in BridgeSupport; if no block is found, returns empty byte array --- .../main/java/co/rsk/peg/BridgeSupport.java | 68 ++++++------------- 1 file changed, 19 insertions(+), 49 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java index 9ba06dc9575..664e6493a97 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1359,19 +1359,7 @@ public List getBtcBlockchainBlockLocator() throws IOException, Block public byte[] getBtcBlockHeaderByHash(Sha256Hash hash) throws IOException, BlockStoreException { this.ensureBtcBlockStore(); - StoredBlock block = btcBlockStore.get(hash); - - if (block == null) { - return null; - } - - byte[] bytes = block.getHeader().unsafeBitcoinSerialize(); - - byte[] header = new byte[80]; - - System.arraycopy(bytes, 0, header, 0, 80); - - return header; + return serializeBlockHeader(btcBlockStore.get(hash)); } public byte[] getBtcParentBlockHeaderByHash(Sha256Hash hash) throws IOException, BlockStoreException { @@ -1380,36 +1368,16 @@ public byte[] getBtcParentBlockHeaderByHash(Sha256Hash hash) throws IOException, StoredBlock block = btcBlockStore.get(hash); if (block == null) { - return null; + return ByteUtil.EMPTY_BYTE_ARRAY; } - StoredBlock parent = btcBlockStore.get(block.getHeader().getPrevBlockHash()); - - if (parent == null) { - return null; - } - - byte[] bytes = parent.getHeader().unsafeBitcoinSerialize(); - - byte[] header = new byte[80]; - - System.arraycopy(bytes, 0, header, 0, 80); - - return header; + return serializeBlockHeader(btcBlockStore.get(block.getHeader().getPrevBlockHash())); } public byte[] getBtcBlockchainSerializedBestBlockHeader() throws BlockStoreException, IOException { this.ensureBtcBlockStore(); - StoredBlock head = btcBlockStore.getChainHead(); - - byte[] bytes = head.getHeader().unsafeBitcoinSerialize(); - - byte[] header = new byte[80]; - - System.arraycopy(bytes, 0, header, 0, 80); - - return header; + return serializeBlockHeader(btcBlockStore.getChainHead()); } public Sha256Hash getBtcBlockchainBestBlockHash() throws BlockStoreException, IOException { @@ -1448,19 +1416,7 @@ public byte[] getBtcBlockHeaderByHeight(int height) throws BlockStoreException, throw new IndexOutOfBoundsException(String.format("Height must be between %d and %d", lowestHeight, highestHeight)); } - StoredBlock block = btcBlockStore.getStoredBlockAtMainChainDepth(highestHeight - height); - - if (block == null) { - return null; - } - - byte[] bytes = block.getHeader().unsafeBitcoinSerialize(); - - byte[] header = new byte[80]; - - System.arraycopy(bytes, 0, header, 0, 80); - - return header; + return serializeBlockHeader(btcBlockStore.getStoredBlockAtMainChainDepth(highestHeight - height)); } public Long getBtcTransactionConfirmationsGetCost(Object[] args) { @@ -3054,4 +3010,18 @@ private Coin computeTotalAmountSent(BtcTransaction btcTx) throws IOException { } return amountToActive.add(amountToRetiring); } + + private static byte[] serializeBlockHeader(StoredBlock block) { + if (block == null) { + return ByteUtil.EMPTY_BYTE_ARRAY; + } + + byte[] bytes = block.getHeader().unsafeBitcoinSerialize(); + + byte[] header = new byte[80]; + + System.arraycopy(bytes, 0, header, 0, 80); + + return header; + } } From a20d505c97e5f5e9014640c4e5e4504e325ee2bf Mon Sep 17 00:00:00 2001 From: ajlopez Date: Tue, 23 Mar 2021 17:38:44 -0300 Subject: [PATCH 08/34] Bridge new method getBestBlockNumber simple test --- .../java/co/rsk/peg/BridgeNewMethodsTest.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java new file mode 100644 index 00000000000..665698569e3 --- /dev/null +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java @@ -0,0 +1,44 @@ +package co.rsk.peg; + +import co.rsk.bitcoinj.store.BlockStoreException; +import co.rsk.config.TestSystemProperties; +import org.ethereum.config.Constants; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; +import org.ethereum.core.Block; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; + +import static org.mockito.Mockito.*; + +public class BridgeNewMethodsTest { + @Test + public void getBestBlockNumber() throws IOException, BlockStoreException { + TestSystemProperties config = spy(new TestSystemProperties()); + Constants constants = Constants.regtest(); + when(config.getNetworkConstants()).thenReturn(constants); + ActivationConfig activationConfig = spy(ActivationConfigsForTest.genesis()); + when(config.getActivationConfig()).thenReturn(activationConfig); + BridgeSupport bridgeSupport = mock(BridgeSupport.class); + when(bridgeSupport.getBtcBlockchainBestChainHeight()).thenReturn(42); + BridgeSupportFactory bridgeSupportFactory = mock(BridgeSupportFactory.class); + when(bridgeSupportFactory.newInstance(any(), any(), any(), any())).thenReturn(bridgeSupport); + Block rskExecutionBlock = mock(Block.class); + when(rskExecutionBlock.getNumber()).thenReturn(42L); + + Bridge bridge = new Bridge( + null, + constants, + activationConfig, + bridgeSupportFactory + ); + + bridge.init(null, rskExecutionBlock, null, null, null, null); + + long result = bridge.getBestBlockNumber(new Object[0]); + + Assert.assertEquals(42, result); + } +} From 1542b97b34db59c964cdfdd9150661580796feef Mon Sep 17 00:00:00 2001 From: ajlopez Date: Tue, 23 Mar 2021 18:16:34 -0300 Subject: [PATCH 09/34] Bridge new method getBestBlockHeader simple test --- .../java/co/rsk/peg/BridgeNewMethodsTest.java | 54 ++++++++++++++----- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java index 665698569e3..8570f290b22 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java @@ -7,38 +7,64 @@ import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.core.Block; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; import java.io.IOException; +import java.util.Random; import static org.mockito.Mockito.*; public class BridgeNewMethodsTest { - @Test - public void getBestBlockNumber() throws IOException, BlockStoreException { - TestSystemProperties config = spy(new TestSystemProperties()); - Constants constants = Constants.regtest(); + private static Random random = new Random(); + + private TestSystemProperties config; + private Constants constants; + private ActivationConfig activationConfig; + private BridgeSupport bridgeSupport; + private BridgeSupportFactory bridgeSupportFactory; + private Block rskExecutionBlock; + private Bridge bridge; + + @Before + public void beforeEach() { + config = spy(new TestSystemProperties()); + constants = Constants.regtest(); when(config.getNetworkConstants()).thenReturn(constants); - ActivationConfig activationConfig = spy(ActivationConfigsForTest.genesis()); + activationConfig = spy(ActivationConfigsForTest.genesis()); when(config.getActivationConfig()).thenReturn(activationConfig); - BridgeSupport bridgeSupport = mock(BridgeSupport.class); - when(bridgeSupport.getBtcBlockchainBestChainHeight()).thenReturn(42); - BridgeSupportFactory bridgeSupportFactory = mock(BridgeSupportFactory.class); + bridgeSupport = mock(BridgeSupport.class); + bridgeSupportFactory = mock(BridgeSupportFactory.class); when(bridgeSupportFactory.newInstance(any(), any(), any(), any())).thenReturn(bridgeSupport); - Block rskExecutionBlock = mock(Block.class); + rskExecutionBlock = mock(Block.class); when(rskExecutionBlock.getNumber()).thenReturn(42L); - Bridge bridge = new Bridge( - null, - constants, - activationConfig, - bridgeSupportFactory + bridge = new Bridge( + null, + constants, + activationConfig, + bridgeSupportFactory ); bridge.init(null, rskExecutionBlock, null, null, null, null); + } + + @Test + public void getBestBlockNumber() throws IOException, BlockStoreException { + when(bridgeSupport.getBtcBlockchainBestChainHeight()).thenReturn(42); long result = bridge.getBestBlockNumber(new Object[0]); Assert.assertEquals(42, result); } + + @Test + public void getBestBlockHeader() throws IOException, BlockStoreException { + byte[] header = new byte[80]; + random.nextBytes(header); + when(bridgeSupport.getBtcBlockchainSerializedBestBlockHeader()).thenReturn(header); + byte[] result = bridge.getBestBlockHeader(new Object[0]); + + Assert.assertArrayEquals(header, result); + } } From 3482faacb8b2553fcf944353db0c118f3cb4df4f Mon Sep 17 00:00:00 2001 From: ajlopez Date: Tue, 23 Mar 2021 18:47:15 -0300 Subject: [PATCH 10/34] Bridge new method getBestBlockHash simple test --- .../test/java/co/rsk/peg/BridgeNewMethodsTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java index 8570f290b22..531d08ea735 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java @@ -1,5 +1,6 @@ package co.rsk.peg; +import co.rsk.bitcoinj.core.Sha256Hash; import co.rsk.bitcoinj.store.BlockStoreException; import co.rsk.config.TestSystemProperties; import org.ethereum.config.Constants; @@ -67,4 +68,15 @@ public void getBestBlockHeader() throws IOException, BlockStoreException { Assert.assertArrayEquals(header, result); } + + @Test + public void getBestBlockHash() throws IOException, BlockStoreException { + byte[] hashBytes = new byte[32]; + random.nextBytes(hashBytes); + Sha256Hash hash = new Sha256Hash(hashBytes); + when(bridgeSupport.getBtcBlockchainBestBlockHash()).thenReturn(hash); + byte[] result = bridge.getBestBlockHash(new Object[0]); + + Assert.assertArrayEquals(hashBytes, result); + } } From bb77d26a3abd0c0ca87e005640bb067548c725b9 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Tue, 23 Mar 2021 18:56:37 -0300 Subject: [PATCH 11/34] Bridge new method getBitcoinHeaderByHash simple test --- rskj-core/src/main/java/co/rsk/peg/Bridge.java | 2 +- .../java/co/rsk/peg/BridgeNewMethodsTest.java | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 74db48660f4..614094d43f2 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -1183,7 +1183,7 @@ public byte[] getBitcoinHeaderByHash(Object[] args) { try { byte[] hashBytes = (byte[])args[0]; - Sha256Hash hash = new Sha256Hash(hashBytes); + Sha256Hash hash = Sha256Hash.wrap(hashBytes); return this.bridgeSupport.getBtcBlockHeaderByHash(hash); } catch (Exception e) { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java index 531d08ea735..7264e231d20 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java @@ -73,10 +73,23 @@ public void getBestBlockHeader() throws IOException, BlockStoreException { public void getBestBlockHash() throws IOException, BlockStoreException { byte[] hashBytes = new byte[32]; random.nextBytes(hashBytes); - Sha256Hash hash = new Sha256Hash(hashBytes); + Sha256Hash hash = Sha256Hash.wrap(hashBytes); when(bridgeSupport.getBtcBlockchainBestBlockHash()).thenReturn(hash); byte[] result = bridge.getBestBlockHash(new Object[0]); Assert.assertArrayEquals(hashBytes, result); } + + @Test + public void getBitcoinHeaderByHash() throws IOException, BlockStoreException { + byte[] hashBytes = new byte[32]; + random.nextBytes(hashBytes); + byte[] header = new byte[80]; + random.nextBytes(header); + + when(bridgeSupport.getBtcBlockHeaderByHash(any())).thenReturn(header); + byte[] result = bridge.getBitcoinHeaderByHash(new Object[] { hashBytes }); + + Assert.assertArrayEquals(header, result); + } } From ccb93687ee9a5a71ac4008a6f85168d015f299e9 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Tue, 23 Mar 2021 19:01:40 -0300 Subject: [PATCH 12/34] Bridge new method getBitcoinHeaderByHeight simple test --- .../java/co/rsk/peg/BridgeNewMethodsTest.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java index 7264e231d20..c57596ec650 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java @@ -7,11 +7,13 @@ import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.core.Block; +import org.ethereum.vm.PrecompiledContracts; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.io.IOException; +import java.math.BigInteger; import java.util.Random; import static org.mockito.Mockito.*; @@ -87,9 +89,21 @@ public void getBitcoinHeaderByHash() throws IOException, BlockStoreException { byte[] header = new byte[80]; random.nextBytes(header); - when(bridgeSupport.getBtcBlockHeaderByHash(any())).thenReturn(header); + when(bridgeSupport.getBtcBlockHeaderByHash(Sha256Hash.wrap(hashBytes))).thenReturn(header); byte[] result = bridge.getBitcoinHeaderByHash(new Object[] { hashBytes }); Assert.assertArrayEquals(header, result); } + + @Test + public void getBitcoinHeaderByHeight() throws IOException, BlockStoreException { + byte[] header = new byte[80]; + random.nextBytes(header); + BigInteger height = BigInteger.TEN; + + when(bridgeSupport.getBtcBlockHeaderByHeight(10)).thenReturn(header); + byte[] result = bridge.getBitcoinHeaderByHeight(new Object[] { height }); + + Assert.assertArrayEquals(header, result); + } } From c854215c08a5439c86b250bf7dcf6bfa48f9fece Mon Sep 17 00:00:00 2001 From: ajlopez Date: Tue, 23 Mar 2021 19:05:20 -0300 Subject: [PATCH 13/34] Bridge new method getBitcoinParentByHeight simple test --- rskj-core/src/main/java/co/rsk/peg/Bridge.java | 2 +- .../test/java/co/rsk/peg/BridgeNewMethodsTest.java | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 614094d43f2..7436910faa3 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -1210,7 +1210,7 @@ public byte[] getBitcoinParentByHash(Object[] args) { try { byte[] hashBytes = (byte[])args[0]; - Sha256Hash hash = new Sha256Hash(hashBytes); + Sha256Hash hash = Sha256Hash.wrap(hashBytes); return this.bridgeSupport.getBtcParentBlockHeaderByHash(hash); } catch (Exception e) { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java index c57596ec650..8e05fda2e8a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java @@ -95,6 +95,19 @@ public void getBitcoinHeaderByHash() throws IOException, BlockStoreException { Assert.assertArrayEquals(header, result); } + @Test + public void getBitcoinParentByHash() throws IOException, BlockStoreException { + byte[] hashBytes = new byte[32]; + random.nextBytes(hashBytes); + byte[] header = new byte[80]; + random.nextBytes(header); + + when(bridgeSupport.getBtcParentBlockHeaderByHash(Sha256Hash.wrap(hashBytes))).thenReturn(header); + byte[] result = bridge.getBitcoinParentByHash(new Object[] { hashBytes }); + + Assert.assertArrayEquals(header, result); + } + @Test public void getBitcoinHeaderByHeight() throws IOException, BlockStoreException { byte[] header = new byte[80]; From 2a1038abae9470b71380ab0e04100f9d8a7fee8b Mon Sep 17 00:00:00 2001 From: ajlopez Date: Thu, 25 Mar 2021 14:16:33 -0300 Subject: [PATCH 14/34] BridgeSupport new method getBtcParentBlockHeaderByHash() first test --- .../rsk/peg/BridgeSupportNewMethodsTest.java | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java new file mode 100644 index 00000000000..511c3101335 --- /dev/null +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java @@ -0,0 +1,119 @@ +package co.rsk.peg; + +import co.rsk.bitcoinj.core.*; +import co.rsk.bitcoinj.store.BlockStoreException; +import co.rsk.config.BridgeConstants; +import co.rsk.config.BridgeRegTestConstants; +import co.rsk.peg.btcLockSender.BtcLockSender; +import co.rsk.peg.btcLockSender.BtcLockSenderProvider; +import co.rsk.peg.pegininstructions.PeginInstructionsProvider; +import co.rsk.peg.utils.BridgeEventLogger; +import org.bouncycastle.util.encoders.Hex; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; +import org.ethereum.core.Block; +import org.ethereum.core.Repository; +import org.ethereum.vm.PrecompiledContracts; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.Random; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doReturn; + +public class BridgeSupportNewMethodsTest { + private static Random random = new Random(); + + private BridgeConstants bridgeConstants; + private NetworkParameters btcParams; + private ActivationConfig.ForBlock activationsBeforeForks; + private ActivationConfig.ForBlock activationsAfterForks; + + @Before + public void setUpOnEachTest() { + bridgeConstants = BridgeRegTestConstants.getInstance(); + btcParams = bridgeConstants.getBtcParams(); + activationsBeforeForks = ActivationConfigsForTest.genesis().forBlock(0); + activationsAfterForks = ActivationConfigsForTest.all().forBlock(0); + } + + @Test + public void getBtcParentBlockHeaderByHash() throws BlockStoreException, IOException { + byte[] hashBytes = new byte[32]; + random.nextBytes(hashBytes); + Sha256Hash hash = Sha256Hash.wrap(hashBytes); + + byte[] header = new byte[80]; + random.nextBytes(header); + + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); + + BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); + when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); + StoredBlock storedBlock = mock(StoredBlock.class); + when(btcBlockStore.getChainHead()).thenReturn(storedBlock); + BtcBlock btcBlock = mock(BtcBlock.class); + when(btcBlock.unsafeBitcoinSerialize()).thenReturn(header); + when(storedBlock.getHeader()).thenReturn(btcBlock); + + BtcBlockStoreWithCache.Factory btcBlockStoreFactor = mock(BtcBlockStoreWithCache.Factory.class); + when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); + + when(btcBlock.getHash()).thenReturn(hash); + Assert.assertArrayEquals(header, btcBlock.unsafeBitcoinSerialize()); + Assert.assertArrayEquals(header, storedBlock.getHeader().unsafeBitcoinSerialize()); + + int height = 1; + + mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); + + BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); + + byte[] result = bridgeSupport.getBtcBlockchainSerializedBestBlockHeader(); + + Assert.assertArrayEquals(header, result); + } + + private BridgeSupport getBridgeSupport(BridgeConstants constants, + BtcBlockStoreWithCache.Factory blockStoreFactory, + ActivationConfig.ForBlock activations) { + BridgeStorageProvider provider = mock(BridgeStorageProvider.class); + Repository track = mock(Repository.class); + BridgeEventLogger eventLogger = mock(BridgeEventLogger.class); + BtcLockSenderProvider btcLockSenderProvider = mock(BtcLockSenderProvider.class); + Block executionBlock = mock(Block.class); + + return new BridgeSupport( + constants, + provider, + eventLogger, + btcLockSenderProvider, + new PeginInstructionsProvider(), + track, + executionBlock, + new Context(constants.getBtcParams()), + new FederationSupport(constants, provider, executionBlock), + blockStoreFactory, + activations + ); + } + + private void mockChainOfStoredBlocks(BtcBlockStoreWithCache btcBlockStore, BtcBlock targetHeader, int headHeight, int targetHeight) throws BlockStoreException { + // Simulate that the block is in there by mocking the getter by height, + // and then simulate that the txs have enough confirmations by setting a high head. + when(btcBlockStore.getStoredBlockAtMainChainHeight(targetHeight)).thenReturn(new StoredBlock(targetHeader, BigInteger.ONE, targetHeight)); + // Mock current pointer's header + StoredBlock currentStored = mock(StoredBlock.class); + BtcBlock currentBlock = mock(BtcBlock.class); + doReturn(Sha256Hash.of(Hex.decode("aa"))).when(currentBlock).getHash(); + doReturn(currentBlock).when(currentStored).getHeader(); + when(currentStored.getHeader()).thenReturn(currentBlock); + //when(btcBlockStore.getChainHead()).thenReturn(currentStored); + when(currentStored.getHeight()).thenReturn(headHeight); + } +} From 47518158e9002f87973f85d673c8cacabb2fa2e1 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Thu, 25 Mar 2021 16:14:14 -0300 Subject: [PATCH 15/34] BridgeSupport new method getBtcBlockHeaderByHash() tests --- .../src/main/java/co/rsk/peg/Bridge.java | 4 +- .../main/java/co/rsk/peg/BridgeSupport.java | 7 +- .../java/co/rsk/peg/BridgeNewMethodsTest.java | 5 +- .../rsk/peg/BridgeSupportNewMethodsTest.java | 169 +++++++++++++++++- 4 files changed, 172 insertions(+), 13 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 7436910faa3..5b4722ac78f 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -1149,7 +1149,7 @@ public byte[] getBestBlockHeader(Object[] args) { logger.trace("getBestBlockHeader"); try { - return this.bridgeSupport.getBtcBlockchainSerializedBestBlockHeader(); + return this.bridgeSupport.getBtcBlockchainBestBlockHeader(); } catch (Exception e) { logger.warn("Exception in getBestBlockHeader", e); return null; @@ -1198,7 +1198,7 @@ public byte[] getBitcoinHeaderByHeight(Object[] args) { try { int height = ((BigInteger) args[0]).intValue(); - return this.bridgeSupport.getBtcBlockHeaderByHeight(height); + return this.bridgeSupport.getBtcBlockchainBlockHeaderByHeight(height); } catch (Exception e) { logger.warn("Exception in getBitcoinHeaderByHeight", e); return null; diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java index 664e6493a97..7e5ed09292f 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1374,7 +1374,7 @@ public byte[] getBtcParentBlockHeaderByHash(Sha256Hash hash) throws IOException, return serializeBlockHeader(btcBlockStore.get(block.getHeader().getPrevBlockHash())); } - public byte[] getBtcBlockchainSerializedBestBlockHeader() throws BlockStoreException, IOException { + public byte[] getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOException { this.ensureBtcBlockStore(); return serializeBlockHeader(btcBlockStore.getChainHead()); @@ -1403,14 +1403,13 @@ public Sha256Hash getBtcBlockchainBlockHashAtDepth(int depth) throws BlockStoreE return blockAtDepth.getHeader().getHash(); } - public byte[] getBtcBlockHeaderByHeight(int height) throws BlockStoreException, IOException { + public byte[] getBtcBlockchainBlockHeaderByHeight(int height) throws BlockStoreException, IOException { Context.propagate(btcContext); this.ensureBtcBlockStore(); StoredBlock head = btcBlockStore.getChainHead(); - int highestHeight= head.getHeight(); + int highestHeight = head.getHeight(); int lowestHeight = getLowestBlock().getHeight(); - int maxDepth = head.getHeight() - getLowestBlock().getHeight(); if (height < lowestHeight || height > highestHeight) { throw new IndexOutOfBoundsException(String.format("Height must be between %d and %d", lowestHeight, highestHeight)); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java index 8e05fda2e8a..6ba879f74d2 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java @@ -7,7 +7,6 @@ import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.core.Block; -import org.ethereum.vm.PrecompiledContracts; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -65,7 +64,7 @@ public void getBestBlockNumber() throws IOException, BlockStoreException { public void getBestBlockHeader() throws IOException, BlockStoreException { byte[] header = new byte[80]; random.nextBytes(header); - when(bridgeSupport.getBtcBlockchainSerializedBestBlockHeader()).thenReturn(header); + when(bridgeSupport.getBtcBlockchainBestBlockHeader()).thenReturn(header); byte[] result = bridge.getBestBlockHeader(new Object[0]); Assert.assertArrayEquals(header, result); @@ -114,7 +113,7 @@ public void getBitcoinHeaderByHeight() throws IOException, BlockStoreException { random.nextBytes(header); BigInteger height = BigInteger.TEN; - when(bridgeSupport.getBtcBlockHeaderByHeight(10)).thenReturn(header); + when(bridgeSupport.getBtcBlockchainBlockHeaderByHeight(10)).thenReturn(header); byte[] result = bridge.getBitcoinHeaderByHeight(new Object[] { height }); Assert.assertArrayEquals(header, result); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java index 511c3101335..cebb3b77c68 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java @@ -4,7 +4,6 @@ import co.rsk.bitcoinj.store.BlockStoreException; import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeRegTestConstants; -import co.rsk.peg.btcLockSender.BtcLockSender; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.utils.BridgeEventLogger; @@ -13,7 +12,6 @@ import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.core.Block; import org.ethereum.core.Repository; -import org.ethereum.vm.PrecompiledContracts; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -43,7 +41,7 @@ public void setUpOnEachTest() { } @Test - public void getBtcParentBlockHeaderByHash() throws BlockStoreException, IOException { + public void getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOException { byte[] hashBytes = new byte[32]; random.nextBytes(hashBytes); Sha256Hash hash = Sha256Hash.wrap(hashBytes); @@ -74,11 +72,174 @@ public void getBtcParentBlockHeaderByHash() throws BlockStoreException, IOExcept BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); - byte[] result = bridgeSupport.getBtcBlockchainSerializedBestBlockHeader(); + byte[] result = bridgeSupport.getBtcBlockchainBestBlockHeader(); Assert.assertArrayEquals(header, result); } + @Test + public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IOException { + byte[] hashBytes = new byte[32]; + random.nextBytes(hashBytes); + Sha256Hash hash = Sha256Hash.wrap(hashBytes); + + byte[] header = new byte[80]; + random.nextBytes(header); + + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); + + BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); + when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); + StoredBlock storedBlock = mock(StoredBlock.class); + when(btcBlockStore.getChainHead()).thenReturn(storedBlock); + when(btcBlockStore.getStoredBlockAtMainChainDepth(10)).thenReturn(storedBlock); + BtcBlock btcBlock = mock(BtcBlock.class); + when(btcBlock.unsafeBitcoinSerialize()).thenReturn(header); + when(storedBlock.getHeader()).thenReturn(btcBlock); + when(storedBlock.getHeight()).thenReturn(30); + + BtcBlockStoreWithCache.Factory btcBlockStoreFactor = mock(BtcBlockStoreWithCache.Factory.class); + when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); + + when(btcBlock.getHash()).thenReturn(hash); + Assert.assertArrayEquals(header, btcBlock.unsafeBitcoinSerialize()); + Assert.assertArrayEquals(header, storedBlock.getHeader().unsafeBitcoinSerialize()); + + int height = 30; + + mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); + + BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); + + byte[] result = bridgeSupport.getBtcBlockchainBlockHeaderByHeight(20); + + Assert.assertArrayEquals(header, result); + } + + @Test + public void getBtcBlockHeaderByHash() throws BlockStoreException, IOException { + byte[] hashBytes = new byte[32]; + random.nextBytes(hashBytes); + Sha256Hash hash = Sha256Hash.wrap(hashBytes); + + byte[] header = new byte[80]; + random.nextBytes(header); + + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); + + BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); + when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); + StoredBlock storedBlock = mock(StoredBlock.class); + when(btcBlockStore.get(hash)).thenReturn(storedBlock); + when(btcBlockStore.getChainHead()).thenReturn(storedBlock); + when(btcBlockStore.getStoredBlockAtMainChainDepth(10)).thenReturn(storedBlock); + BtcBlock btcBlock = mock(BtcBlock.class); + when(btcBlock.unsafeBitcoinSerialize()).thenReturn(header); + when(storedBlock.getHeader()).thenReturn(btcBlock); + when(storedBlock.getHeight()).thenReturn(30); + + BtcBlockStoreWithCache.Factory btcBlockStoreFactor = mock(BtcBlockStoreWithCache.Factory.class); + when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); + + when(btcBlock.getHash()).thenReturn(hash); + Assert.assertArrayEquals(header, btcBlock.unsafeBitcoinSerialize()); + Assert.assertArrayEquals(header, storedBlock.getHeader().unsafeBitcoinSerialize()); + + int height = 30; + + mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); + + BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); + + byte[] result = bridgeSupport.getBtcBlockHeaderByHash(hash); + + Assert.assertArrayEquals(header, result); + } + + @Test + public void getBtcBlockHeaderByUnknownHash() throws BlockStoreException, IOException { + byte[] hashBytes = new byte[32]; + random.nextBytes(hashBytes); + Sha256Hash hash = Sha256Hash.wrap(hashBytes); + + byte[] header = new byte[80]; + random.nextBytes(header); + + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); + + BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); + when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); + StoredBlock storedBlock = mock(StoredBlock.class); + when(btcBlockStore.get(hash)).thenReturn(null); + when(btcBlockStore.getChainHead()).thenReturn(storedBlock); + when(btcBlockStore.getStoredBlockAtMainChainDepth(10)).thenReturn(storedBlock); + BtcBlock btcBlock = mock(BtcBlock.class); + when(btcBlock.unsafeBitcoinSerialize()).thenReturn(header); + when(storedBlock.getHeader()).thenReturn(btcBlock); + when(storedBlock.getHeight()).thenReturn(30); + + BtcBlockStoreWithCache.Factory btcBlockStoreFactor = mock(BtcBlockStoreWithCache.Factory.class); + when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); + + when(btcBlock.getHash()).thenReturn(hash); + Assert.assertArrayEquals(header, btcBlock.unsafeBitcoinSerialize()); + Assert.assertArrayEquals(header, storedBlock.getHeader().unsafeBitcoinSerialize()); + + int height = 30; + + mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); + + BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); + + byte[] result = bridgeSupport.getBtcBlockHeaderByHash(hash); + + Assert.assertNotNull(result); + Assert.assertEquals(0, result.length); + } + + @Test + public void getBtcBlockchainBlockHeaderByHeightTooHight() throws BlockStoreException, IOException { + byte[] hashBytes = new byte[32]; + random.nextBytes(hashBytes); + Sha256Hash hash = Sha256Hash.wrap(hashBytes); + + byte[] header = new byte[80]; + random.nextBytes(header); + + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); + + BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); + when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); + StoredBlock storedBlock = mock(StoredBlock.class); + when(btcBlockStore.getChainHead()).thenReturn(storedBlock); + when(btcBlockStore.getStoredBlockAtMainChainDepth(10)).thenReturn(storedBlock); + BtcBlock btcBlock = mock(BtcBlock.class); + when(btcBlock.unsafeBitcoinSerialize()).thenReturn(header); + when(storedBlock.getHeader()).thenReturn(btcBlock); + when(storedBlock.getHeight()).thenReturn(30); + + BtcBlockStoreWithCache.Factory btcBlockStoreFactor = mock(BtcBlockStoreWithCache.Factory.class); + when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); + + when(btcBlock.getHash()).thenReturn(hash); + Assert.assertArrayEquals(header, btcBlock.unsafeBitcoinSerialize()); + Assert.assertArrayEquals(header, storedBlock.getHeader().unsafeBitcoinSerialize()); + + int height = 30; + + mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); + + BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); + + try { + bridgeSupport.getBtcBlockchainBlockHeaderByHeight(40); + Assert.fail(); + } + catch (IndexOutOfBoundsException ex) { + Assert.assertEquals("Height must be between 0 and 30", ex.getMessage()); + } + } + private BridgeSupport getBridgeSupport(BridgeConstants constants, BtcBlockStoreWithCache.Factory blockStoreFactory, ActivationConfig.ForBlock activations) { From 1a15cfa815c58fb85434a39e4079f86522c817c1 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Thu, 25 Mar 2021 16:54:28 -0300 Subject: [PATCH 16/34] BridgeSupport new method getBtcParentBlockHeaderByHash() tests --- .../rsk/peg/BridgeSupportNewMethodsTest.java | 111 +++++++++++++++--- 1 file changed, 95 insertions(+), 16 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java index cebb3b77c68..e64b061d766 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java @@ -63,8 +63,6 @@ public void getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOExce when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); when(btcBlock.getHash()).thenReturn(hash); - Assert.assertArrayEquals(header, btcBlock.unsafeBitcoinSerialize()); - Assert.assertArrayEquals(header, storedBlock.getHeader().unsafeBitcoinSerialize()); int height = 1; @@ -78,7 +76,7 @@ public void getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOExce } @Test - public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IOException { + public void getBtcBlockHeaderByHash() throws BlockStoreException, IOException { byte[] hashBytes = new byte[32]; random.nextBytes(hashBytes); Sha256Hash hash = Sha256Hash.wrap(hashBytes); @@ -91,6 +89,7 @@ public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IO BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); StoredBlock storedBlock = mock(StoredBlock.class); + when(btcBlockStore.get(hash)).thenReturn(storedBlock); when(btcBlockStore.getChainHead()).thenReturn(storedBlock); when(btcBlockStore.getStoredBlockAtMainChainDepth(10)).thenReturn(storedBlock); BtcBlock btcBlock = mock(BtcBlock.class); @@ -102,8 +101,6 @@ public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IO when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); when(btcBlock.getHash()).thenReturn(hash); - Assert.assertArrayEquals(header, btcBlock.unsafeBitcoinSerialize()); - Assert.assertArrayEquals(header, storedBlock.getHeader().unsafeBitcoinSerialize()); int height = 30; @@ -111,13 +108,13 @@ public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IO BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); - byte[] result = bridgeSupport.getBtcBlockchainBlockHeaderByHeight(20); + byte[] result = bridgeSupport.getBtcBlockHeaderByHash(hash); Assert.assertArrayEquals(header, result); } @Test - public void getBtcBlockHeaderByHash() throws BlockStoreException, IOException { + public void getBtcBlockHeaderByUnknownHash() throws BlockStoreException, IOException { byte[] hashBytes = new byte[32]; random.nextBytes(hashBytes); Sha256Hash hash = Sha256Hash.wrap(hashBytes); @@ -130,7 +127,7 @@ public void getBtcBlockHeaderByHash() throws BlockStoreException, IOException { BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); StoredBlock storedBlock = mock(StoredBlock.class); - when(btcBlockStore.get(hash)).thenReturn(storedBlock); + when(btcBlockStore.get(hash)).thenReturn(null); when(btcBlockStore.getChainHead()).thenReturn(storedBlock); when(btcBlockStore.getStoredBlockAtMainChainDepth(10)).thenReturn(storedBlock); BtcBlock btcBlock = mock(BtcBlock.class); @@ -142,8 +139,6 @@ public void getBtcBlockHeaderByHash() throws BlockStoreException, IOException { when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); when(btcBlock.getHash()).thenReturn(hash); - Assert.assertArrayEquals(header, btcBlock.unsafeBitcoinSerialize()); - Assert.assertArrayEquals(header, storedBlock.getHeader().unsafeBitcoinSerialize()); int height = 30; @@ -153,15 +148,66 @@ public void getBtcBlockHeaderByHash() throws BlockStoreException, IOException { byte[] result = bridgeSupport.getBtcBlockHeaderByHash(hash); + Assert.assertNotNull(result); + Assert.assertEquals(0, result.length); + } + + @Test + public void getBtcParentBlockHeaderByHash() throws BlockStoreException, IOException { + byte[] hashBytes = new byte[32]; + random.nextBytes(hashBytes); + Sha256Hash hash = Sha256Hash.wrap(hashBytes); + + byte[] parentHashBytes = new byte[32]; + random.nextBytes(parentHashBytes); + Sha256Hash parentHash = Sha256Hash.wrap(parentHashBytes); + + byte[] header = new byte[80]; + random.nextBytes(header); + + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); + + BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); + when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); + StoredBlock storedBlock = mock(StoredBlock.class); + StoredBlock parentStoredBlock = mock(StoredBlock.class); + when(btcBlockStore.get(hash)).thenReturn(storedBlock); + when(btcBlockStore.get(parentHash)).thenReturn(parentStoredBlock); + when(btcBlockStore.getChainHead()).thenReturn(storedBlock); + BtcBlock btcBlock = mock(BtcBlock.class); + when(storedBlock.getHeader()).thenReturn(btcBlock); + when(storedBlock.getHeight()).thenReturn(30); + when(btcBlock.getPrevBlockHash()).thenReturn(parentHash); + BtcBlock parentBtcBlock = mock(BtcBlock.class); + when(parentBtcBlock.unsafeBitcoinSerialize()).thenReturn(header); + when(parentStoredBlock.getHeader()).thenReturn(parentBtcBlock); + + BtcBlockStoreWithCache.Factory btcBlockStoreFactor = mock(BtcBlockStoreWithCache.Factory.class); + when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); + + when(btcBlock.getHash()).thenReturn(hash); + + int height = 30; + + mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); + + BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); + + byte[] result = bridgeSupport.getBtcParentBlockHeaderByHash(hash); + Assert.assertArrayEquals(header, result); } @Test - public void getBtcBlockHeaderByUnknownHash() throws BlockStoreException, IOException { + public void getBtcParentBlockHeaderByUnknownHash() throws BlockStoreException, IOException { byte[] hashBytes = new byte[32]; random.nextBytes(hashBytes); Sha256Hash hash = Sha256Hash.wrap(hashBytes); + byte[] parentHashBytes = new byte[32]; + random.nextBytes(parentHashBytes); + Sha256Hash parentHash = Sha256Hash.wrap(parentHashBytes); + byte[] header = new byte[80]; random.nextBytes(header); @@ -172,6 +218,42 @@ public void getBtcBlockHeaderByUnknownHash() throws BlockStoreException, IOExcep StoredBlock storedBlock = mock(StoredBlock.class); when(btcBlockStore.get(hash)).thenReturn(null); when(btcBlockStore.getChainHead()).thenReturn(storedBlock); + BtcBlock btcBlock = mock(BtcBlock.class); + when(storedBlock.getHeader()).thenReturn(btcBlock); + when(storedBlock.getHeight()).thenReturn(30); + when(btcBlock.getPrevBlockHash()).thenReturn(parentHash); + + when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); + + when(btcBlock.getHash()).thenReturn(hash); + + int height = 30; + + mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); + + BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); + + byte[] result = bridgeSupport.getBtcParentBlockHeaderByHash(hash); + + Assert.assertNotNull(result); + Assert.assertEquals(0, result.length); + } + + @Test + public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IOException { + byte[] hashBytes = new byte[32]; + random.nextBytes(hashBytes); + Sha256Hash hash = Sha256Hash.wrap(hashBytes); + + byte[] header = new byte[80]; + random.nextBytes(header); + + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); + + BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); + when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); + StoredBlock storedBlock = mock(StoredBlock.class); + when(btcBlockStore.getChainHead()).thenReturn(storedBlock); when(btcBlockStore.getStoredBlockAtMainChainDepth(10)).thenReturn(storedBlock); BtcBlock btcBlock = mock(BtcBlock.class); when(btcBlock.unsafeBitcoinSerialize()).thenReturn(header); @@ -182,8 +264,6 @@ public void getBtcBlockHeaderByUnknownHash() throws BlockStoreException, IOExcep when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); when(btcBlock.getHash()).thenReturn(hash); - Assert.assertArrayEquals(header, btcBlock.unsafeBitcoinSerialize()); - Assert.assertArrayEquals(header, storedBlock.getHeader().unsafeBitcoinSerialize()); int height = 30; @@ -191,10 +271,9 @@ public void getBtcBlockHeaderByUnknownHash() throws BlockStoreException, IOExcep BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); - byte[] result = bridgeSupport.getBtcBlockHeaderByHash(hash); + byte[] result = bridgeSupport.getBtcBlockchainBlockHeaderByHeight(20); - Assert.assertNotNull(result); - Assert.assertEquals(0, result.length); + Assert.assertArrayEquals(header, result); } @Test From c5d436a3a263040c55bb0d7c5bfc9a3b6b672cde Mon Sep 17 00:00:00 2001 From: ajlopez Date: Thu, 25 Mar 2021 17:39:02 -0300 Subject: [PATCH 17/34] BridgeSupport new methods tests first refactor --- .../rsk/peg/BridgeSupportNewMethodsTest.java | 72 +++---------------- 1 file changed, 9 insertions(+), 63 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java index e64b061d766..99dc92ea69f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java @@ -7,7 +7,6 @@ import co.rsk.peg.btcLockSender.BtcLockSenderProvider; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.utils.BridgeEventLogger; -import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.core.Block; @@ -22,7 +21,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; -import static org.mockito.Mockito.doReturn; public class BridgeSupportNewMethodsTest { private static Random random = new Random(); @@ -31,6 +29,9 @@ public class BridgeSupportNewMethodsTest { private NetworkParameters btcParams; private ActivationConfig.ForBlock activationsBeforeForks; private ActivationConfig.ForBlock activationsAfterForks; + private byte[] hashBytes; + private Sha256Hash hash; + private byte[] header; @Before public void setUpOnEachTest() { @@ -38,17 +39,17 @@ public void setUpOnEachTest() { btcParams = bridgeConstants.getBtcParams(); activationsBeforeForks = ActivationConfigsForTest.genesis().forBlock(0); activationsAfterForks = ActivationConfigsForTest.all().forBlock(0); - } - @Test - public void getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOException { - byte[] hashBytes = new byte[32]; + hashBytes = new byte[32]; random.nextBytes(hashBytes); - Sha256Hash hash = Sha256Hash.wrap(hashBytes); + hash = Sha256Hash.wrap(hashBytes); - byte[] header = new byte[80]; + header = new byte[80]; random.nextBytes(header); + } + @Test + public void getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOException { BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); @@ -59,7 +60,6 @@ public void getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOExce when(btcBlock.unsafeBitcoinSerialize()).thenReturn(header); when(storedBlock.getHeader()).thenReturn(btcBlock); - BtcBlockStoreWithCache.Factory btcBlockStoreFactor = mock(BtcBlockStoreWithCache.Factory.class); when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); when(btcBlock.getHash()).thenReturn(hash); @@ -77,13 +77,6 @@ public void getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOExce @Test public void getBtcBlockHeaderByHash() throws BlockStoreException, IOException { - byte[] hashBytes = new byte[32]; - random.nextBytes(hashBytes); - Sha256Hash hash = Sha256Hash.wrap(hashBytes); - - byte[] header = new byte[80]; - random.nextBytes(header); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); @@ -115,13 +108,6 @@ public void getBtcBlockHeaderByHash() throws BlockStoreException, IOException { @Test public void getBtcBlockHeaderByUnknownHash() throws BlockStoreException, IOException { - byte[] hashBytes = new byte[32]; - random.nextBytes(hashBytes); - Sha256Hash hash = Sha256Hash.wrap(hashBytes); - - byte[] header = new byte[80]; - random.nextBytes(header); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); @@ -154,17 +140,10 @@ public void getBtcBlockHeaderByUnknownHash() throws BlockStoreException, IOExcep @Test public void getBtcParentBlockHeaderByHash() throws BlockStoreException, IOException { - byte[] hashBytes = new byte[32]; - random.nextBytes(hashBytes); - Sha256Hash hash = Sha256Hash.wrap(hashBytes); - byte[] parentHashBytes = new byte[32]; random.nextBytes(parentHashBytes); Sha256Hash parentHash = Sha256Hash.wrap(parentHashBytes); - byte[] header = new byte[80]; - random.nextBytes(header); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); @@ -182,7 +161,6 @@ public void getBtcParentBlockHeaderByHash() throws BlockStoreException, IOExcept when(parentBtcBlock.unsafeBitcoinSerialize()).thenReturn(header); when(parentStoredBlock.getHeader()).thenReturn(parentBtcBlock); - BtcBlockStoreWithCache.Factory btcBlockStoreFactor = mock(BtcBlockStoreWithCache.Factory.class); when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); when(btcBlock.getHash()).thenReturn(hash); @@ -200,17 +178,10 @@ public void getBtcParentBlockHeaderByHash() throws BlockStoreException, IOExcept @Test public void getBtcParentBlockHeaderByUnknownHash() throws BlockStoreException, IOException { - byte[] hashBytes = new byte[32]; - random.nextBytes(hashBytes); - Sha256Hash hash = Sha256Hash.wrap(hashBytes); - byte[] parentHashBytes = new byte[32]; random.nextBytes(parentHashBytes); Sha256Hash parentHash = Sha256Hash.wrap(parentHashBytes); - byte[] header = new byte[80]; - random.nextBytes(header); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); @@ -241,13 +212,6 @@ public void getBtcParentBlockHeaderByUnknownHash() throws BlockStoreException, I @Test public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IOException { - byte[] hashBytes = new byte[32]; - random.nextBytes(hashBytes); - Sha256Hash hash = Sha256Hash.wrap(hashBytes); - - byte[] header = new byte[80]; - random.nextBytes(header); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); @@ -260,7 +224,6 @@ public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IO when(storedBlock.getHeader()).thenReturn(btcBlock); when(storedBlock.getHeight()).thenReturn(30); - BtcBlockStoreWithCache.Factory btcBlockStoreFactor = mock(BtcBlockStoreWithCache.Factory.class); when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); when(btcBlock.getHash()).thenReturn(hash); @@ -278,13 +241,6 @@ public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IO @Test public void getBtcBlockchainBlockHeaderByHeightTooHight() throws BlockStoreException, IOException { - byte[] hashBytes = new byte[32]; - random.nextBytes(hashBytes); - Sha256Hash hash = Sha256Hash.wrap(hashBytes); - - byte[] header = new byte[80]; - random.nextBytes(header); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); @@ -301,8 +257,6 @@ public void getBtcBlockchainBlockHeaderByHeightTooHight() throws BlockStoreExcep when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); when(btcBlock.getHash()).thenReturn(hash); - Assert.assertArrayEquals(header, btcBlock.unsafeBitcoinSerialize()); - Assert.assertArrayEquals(header, storedBlock.getHeader().unsafeBitcoinSerialize()); int height = 30; @@ -347,13 +301,5 @@ private void mockChainOfStoredBlocks(BtcBlockStoreWithCache btcBlockStore, BtcBl // Simulate that the block is in there by mocking the getter by height, // and then simulate that the txs have enough confirmations by setting a high head. when(btcBlockStore.getStoredBlockAtMainChainHeight(targetHeight)).thenReturn(new StoredBlock(targetHeader, BigInteger.ONE, targetHeight)); - // Mock current pointer's header - StoredBlock currentStored = mock(StoredBlock.class); - BtcBlock currentBlock = mock(BtcBlock.class); - doReturn(Sha256Hash.of(Hex.decode("aa"))).when(currentBlock).getHash(); - doReturn(currentBlock).when(currentStored).getHeader(); - when(currentStored.getHeader()).thenReturn(currentBlock); - //when(btcBlockStore.getChainHead()).thenReturn(currentStored); - when(currentStored.getHeight()).thenReturn(headHeight); } } From 1fb170658ec6f1e2699d81943c4992d8ef47bdd7 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Thu, 25 Mar 2021 17:59:03 -0300 Subject: [PATCH 18/34] BridgeSupport new method tests refactor --- .../rsk/peg/BridgeSupportNewMethodsTest.java | 154 +++--------------- 1 file changed, 21 insertions(+), 133 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java index 99dc92ea69f..04967afb972 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java @@ -32,9 +32,13 @@ public class BridgeSupportNewMethodsTest { private byte[] hashBytes; private Sha256Hash hash; private byte[] header; + private BtcBlockStoreWithCache.Factory btcBlockStoreFactory; + private BtcBlockStoreWithCache btcBlockStore; + private StoredBlock storedBlock; + private BtcBlock btcBlock; @Before - public void setUpOnEachTest() { + public void setUpOnEachTest() throws BlockStoreException { bridgeConstants = BridgeRegTestConstants.getInstance(); btcParams = bridgeConstants.getBtcParams(); activationsBeforeForks = ActivationConfigsForTest.genesis().forBlock(0); @@ -46,28 +50,27 @@ public void setUpOnEachTest() { header = new byte[80]; random.nextBytes(header); - } - - @Test - public void getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOException { - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); - BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); + btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); + btcBlockStore = mock(BtcBlockStoreWithCache.class); when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); - StoredBlock storedBlock = mock(StoredBlock.class); + + storedBlock = mock(StoredBlock.class); when(btcBlockStore.getChainHead()).thenReturn(storedBlock); - BtcBlock btcBlock = mock(BtcBlock.class); + when(btcBlockStore.get(hash)).thenReturn(storedBlock); + btcBlock = mock(BtcBlock.class); when(btcBlock.unsafeBitcoinSerialize()).thenReturn(header); when(storedBlock.getHeader()).thenReturn(btcBlock); - - when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); - when(btcBlock.getHash()).thenReturn(hash); + when(storedBlock.getHeight()).thenReturn(30); - int height = 1; + int height = 30; mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); + } + @Test + public void getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOException { BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); byte[] result = bridgeSupport.getBtcBlockchainBestBlockHeader(); @@ -77,28 +80,6 @@ public void getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOExce @Test public void getBtcBlockHeaderByHash() throws BlockStoreException, IOException { - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); - - BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); - when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); - StoredBlock storedBlock = mock(StoredBlock.class); - when(btcBlockStore.get(hash)).thenReturn(storedBlock); - when(btcBlockStore.getChainHead()).thenReturn(storedBlock); - when(btcBlockStore.getStoredBlockAtMainChainDepth(10)).thenReturn(storedBlock); - BtcBlock btcBlock = mock(BtcBlock.class); - when(btcBlock.unsafeBitcoinSerialize()).thenReturn(header); - when(storedBlock.getHeader()).thenReturn(btcBlock); - when(storedBlock.getHeight()).thenReturn(30); - - BtcBlockStoreWithCache.Factory btcBlockStoreFactor = mock(BtcBlockStoreWithCache.Factory.class); - when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); - - when(btcBlock.getHash()).thenReturn(hash); - - int height = 30; - - mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); - BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); byte[] result = bridgeSupport.getBtcBlockHeaderByHash(hash); @@ -108,31 +89,15 @@ public void getBtcBlockHeaderByHash() throws BlockStoreException, IOException { @Test public void getBtcBlockHeaderByUnknownHash() throws BlockStoreException, IOException { - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); + byte[] unknownHashBytes = new byte[32]; + random.nextBytes(unknownHashBytes); + Sha256Hash unknownHash = Sha256Hash.wrap(unknownHashBytes); - BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); - when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); - StoredBlock storedBlock = mock(StoredBlock.class); - when(btcBlockStore.get(hash)).thenReturn(null); - when(btcBlockStore.getChainHead()).thenReturn(storedBlock); - when(btcBlockStore.getStoredBlockAtMainChainDepth(10)).thenReturn(storedBlock); - BtcBlock btcBlock = mock(BtcBlock.class); - when(btcBlock.unsafeBitcoinSerialize()).thenReturn(header); - when(storedBlock.getHeader()).thenReturn(btcBlock); - when(storedBlock.getHeight()).thenReturn(30); - - BtcBlockStoreWithCache.Factory btcBlockStoreFactor = mock(BtcBlockStoreWithCache.Factory.class); - when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); - - when(btcBlock.getHash()).thenReturn(hash); - - int height = 30; - - mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); + when(btcBlockStore.get(unknownHash)).thenReturn(null); BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); - byte[] result = bridgeSupport.getBtcBlockHeaderByHash(hash); + byte[] result = bridgeSupport.getBtcBlockHeaderByHash(unknownHash); Assert.assertNotNull(result); Assert.assertEquals(0, result.length); @@ -144,31 +109,13 @@ public void getBtcParentBlockHeaderByHash() throws BlockStoreException, IOExcept random.nextBytes(parentHashBytes); Sha256Hash parentHash = Sha256Hash.wrap(parentHashBytes); - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); - - BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); - when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); - StoredBlock storedBlock = mock(StoredBlock.class); StoredBlock parentStoredBlock = mock(StoredBlock.class); - when(btcBlockStore.get(hash)).thenReturn(storedBlock); when(btcBlockStore.get(parentHash)).thenReturn(parentStoredBlock); - when(btcBlockStore.getChainHead()).thenReturn(storedBlock); - BtcBlock btcBlock = mock(BtcBlock.class); - when(storedBlock.getHeader()).thenReturn(btcBlock); - when(storedBlock.getHeight()).thenReturn(30); when(btcBlock.getPrevBlockHash()).thenReturn(parentHash); BtcBlock parentBtcBlock = mock(BtcBlock.class); when(parentBtcBlock.unsafeBitcoinSerialize()).thenReturn(header); when(parentStoredBlock.getHeader()).thenReturn(parentBtcBlock); - when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); - - when(btcBlock.getHash()).thenReturn(hash); - - int height = 30; - - mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); - BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); byte[] result = bridgeSupport.getBtcParentBlockHeaderByHash(hash); @@ -178,29 +125,7 @@ public void getBtcParentBlockHeaderByHash() throws BlockStoreException, IOExcept @Test public void getBtcParentBlockHeaderByUnknownHash() throws BlockStoreException, IOException { - byte[] parentHashBytes = new byte[32]; - random.nextBytes(parentHashBytes); - Sha256Hash parentHash = Sha256Hash.wrap(parentHashBytes); - - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); - - BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); - when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); - StoredBlock storedBlock = mock(StoredBlock.class); when(btcBlockStore.get(hash)).thenReturn(null); - when(btcBlockStore.getChainHead()).thenReturn(storedBlock); - BtcBlock btcBlock = mock(BtcBlock.class); - when(storedBlock.getHeader()).thenReturn(btcBlock); - when(storedBlock.getHeight()).thenReturn(30); - when(btcBlock.getPrevBlockHash()).thenReturn(parentHash); - - when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); - - when(btcBlock.getHash()).thenReturn(hash); - - int height = 30; - - mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); @@ -212,25 +137,7 @@ public void getBtcParentBlockHeaderByUnknownHash() throws BlockStoreException, I @Test public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IOException { - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); - - BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); - when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); - StoredBlock storedBlock = mock(StoredBlock.class); - when(btcBlockStore.getChainHead()).thenReturn(storedBlock); when(btcBlockStore.getStoredBlockAtMainChainDepth(10)).thenReturn(storedBlock); - BtcBlock btcBlock = mock(BtcBlock.class); - when(btcBlock.unsafeBitcoinSerialize()).thenReturn(header); - when(storedBlock.getHeader()).thenReturn(btcBlock); - when(storedBlock.getHeight()).thenReturn(30); - - when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); - - when(btcBlock.getHash()).thenReturn(hash); - - int height = 30; - - mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); @@ -241,26 +148,7 @@ public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IO @Test public void getBtcBlockchainBlockHeaderByHeightTooHight() throws BlockStoreException, IOException { - BtcBlockStoreWithCache.Factory btcBlockStoreFactory = mock(BtcBlockStoreWithCache.Factory.class); - - BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); - when(btcBlockStoreFactory.newInstance(any(Repository.class), any(), any(), any())).thenReturn(btcBlockStore); - StoredBlock storedBlock = mock(StoredBlock.class); - when(btcBlockStore.getChainHead()).thenReturn(storedBlock); when(btcBlockStore.getStoredBlockAtMainChainDepth(10)).thenReturn(storedBlock); - BtcBlock btcBlock = mock(BtcBlock.class); - when(btcBlock.unsafeBitcoinSerialize()).thenReturn(header); - when(storedBlock.getHeader()).thenReturn(btcBlock); - when(storedBlock.getHeight()).thenReturn(30); - - BtcBlockStoreWithCache.Factory btcBlockStoreFactor = mock(BtcBlockStoreWithCache.Factory.class); - when(btcBlockStoreFactory.newInstance(any(), any(), any(), any())).thenReturn(btcBlockStore); - - when(btcBlock.getHash()).thenReturn(hash); - - int height = 30; - - mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); From f9b83ea02d5a64b78fe0882eef022027d1d223a2 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Thu, 25 Mar 2021 18:10:29 -0300 Subject: [PATCH 19/34] BridgeSupport new methods tests refactor --- .../co/rsk/peg/BridgeSupportNewMethodsTest.java | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java index 04967afb972..613bc1fe4a4 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java @@ -36,6 +36,7 @@ public class BridgeSupportNewMethodsTest { private BtcBlockStoreWithCache btcBlockStore; private StoredBlock storedBlock; private BtcBlock btcBlock; + private BridgeSupport bridgeSupport; @Before public void setUpOnEachTest() throws BlockStoreException { @@ -67,12 +68,12 @@ public void setUpOnEachTest() throws BlockStoreException { int height = 30; mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); + + bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); } @Test public void getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOException { - BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); - byte[] result = bridgeSupport.getBtcBlockchainBestBlockHeader(); Assert.assertArrayEquals(header, result); @@ -80,8 +81,6 @@ public void getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOExce @Test public void getBtcBlockHeaderByHash() throws BlockStoreException, IOException { - BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); - byte[] result = bridgeSupport.getBtcBlockHeaderByHash(hash); Assert.assertArrayEquals(header, result); @@ -95,8 +94,6 @@ public void getBtcBlockHeaderByUnknownHash() throws BlockStoreException, IOExcep when(btcBlockStore.get(unknownHash)).thenReturn(null); - BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); - byte[] result = bridgeSupport.getBtcBlockHeaderByHash(unknownHash); Assert.assertNotNull(result); @@ -116,8 +113,6 @@ public void getBtcParentBlockHeaderByHash() throws BlockStoreException, IOExcept when(parentBtcBlock.unsafeBitcoinSerialize()).thenReturn(header); when(parentStoredBlock.getHeader()).thenReturn(parentBtcBlock); - BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); - byte[] result = bridgeSupport.getBtcParentBlockHeaderByHash(hash); Assert.assertArrayEquals(header, result); @@ -127,8 +122,6 @@ public void getBtcParentBlockHeaderByHash() throws BlockStoreException, IOExcept public void getBtcParentBlockHeaderByUnknownHash() throws BlockStoreException, IOException { when(btcBlockStore.get(hash)).thenReturn(null); - BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); - byte[] result = bridgeSupport.getBtcParentBlockHeaderByHash(hash); Assert.assertNotNull(result); @@ -139,8 +132,6 @@ public void getBtcParentBlockHeaderByUnknownHash() throws BlockStoreException, I public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IOException { when(btcBlockStore.getStoredBlockAtMainChainDepth(10)).thenReturn(storedBlock); - BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); - byte[] result = bridgeSupport.getBtcBlockchainBlockHeaderByHeight(20); Assert.assertArrayEquals(header, result); @@ -150,8 +141,6 @@ public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IO public void getBtcBlockchainBlockHeaderByHeightTooHight() throws BlockStoreException, IOException { when(btcBlockStore.getStoredBlockAtMainChainDepth(10)).thenReturn(storedBlock); - BridgeSupport bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); - try { bridgeSupport.getBtcBlockchainBlockHeaderByHeight(40); Assert.fail(); From 9dd6d4de7a0497c06ef65fd2c4ecf3db9682722e Mon Sep 17 00:00:00 2001 From: ajlopez Date: Fri, 26 Mar 2021 09:22:03 -0300 Subject: [PATCH 20/34] Removing muletto method get block header hash --- rskj-core/src/main/java/co/rsk/peg/Bridge.java | 11 ----------- rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java | 11 ----------- rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java | 8 -------- .../test/java/co/rsk/peg/BridgeNewMethodsTest.java | 11 ----------- .../java/co/rsk/peg/BridgeSupportNewMethodsTest.java | 8 +------- 5 files changed, 1 insertion(+), 48 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 5b4722ac78f..ddeead86395 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -1167,17 +1167,6 @@ public long getBestBlockNumber(Object[] args) { } } - public byte[] getBestBlockHash(Object[] args) { - logger.trace("getBestBlockHash"); - - try { - return this.bridgeSupport.getBtcBlockchainBestBlockHash().getBytes(); - } catch (Exception e) { - logger.warn("Exception in getBestBlockHash", e); - return null; - } - } - public byte[] getBitcoinHeaderByHash(Object[] args) { logger.trace("getBitcoinHeaderByHash"); diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index d568d160d79..7fddb006b57 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -636,17 +636,6 @@ public enum BridgeMethods { activations -> true, // TODO: Review activation false ), - GET_BEST_BLOCK_HASH( - CallTransaction.Function.fromSignature( - "getBestBlockHash", - new String[0], - new String[]{"bytes32"} - ), - fixedCost(20000L), - (BridgeMethodExecutorTyped) Bridge::getBestBlockHash, - activations -> true, // TODO: Review activation - false - ), GET_BITCOIN_HEADER_BY_HASH( CallTransaction.Function.fromSignature( "getBitcoinHeaderByHash", diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java index 7e5ed09292f..5d201b422fc 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1380,14 +1380,6 @@ public byte[] getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOEx return serializeBlockHeader(btcBlockStore.getChainHead()); } - public Sha256Hash getBtcBlockchainBestBlockHash() throws BlockStoreException, IOException { - this.ensureBtcBlockStore(); - - StoredBlock head = btcBlockStore.getChainHead(); - - return head.getHeader().getHash(); - } - public Sha256Hash getBtcBlockchainBlockHashAtDepth(int depth) throws BlockStoreException, IOException { Context.propagate(btcContext); this.ensureBtcBlockStore(); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java index 6ba879f74d2..5aa1a6622c9 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java @@ -70,17 +70,6 @@ public void getBestBlockHeader() throws IOException, BlockStoreException { Assert.assertArrayEquals(header, result); } - @Test - public void getBestBlockHash() throws IOException, BlockStoreException { - byte[] hashBytes = new byte[32]; - random.nextBytes(hashBytes); - Sha256Hash hash = Sha256Hash.wrap(hashBytes); - when(bridgeSupport.getBtcBlockchainBestBlockHash()).thenReturn(hash); - byte[] result = bridge.getBestBlockHash(new Object[0]); - - Assert.assertArrayEquals(hashBytes, result); - } - @Test public void getBitcoinHeaderByHash() throws IOException, BlockStoreException { byte[] hashBytes = new byte[32]; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java index 613bc1fe4a4..5c2fa8d2a38 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java @@ -67,7 +67,7 @@ public void setUpOnEachTest() throws BlockStoreException { int height = 30; - mockChainOfStoredBlocks(btcBlockStore, btcBlock, height + bridgeConstants.getBtc2RskMinimumAcceptableConfirmations(), height); + when(btcBlockStore.getStoredBlockAtMainChainHeight(height)).thenReturn(new StoredBlock(btcBlock, BigInteger.ONE, height)); bridgeSupport = getBridgeSupport(bridgeConstants, btcBlockStoreFactory, activationsAfterForks); } @@ -173,10 +173,4 @@ private BridgeSupport getBridgeSupport(BridgeConstants constants, activations ); } - - private void mockChainOfStoredBlocks(BtcBlockStoreWithCache btcBlockStore, BtcBlock targetHeader, int headHeight, int targetHeight) throws BlockStoreException { - // Simulate that the block is in there by mocking the getter by height, - // and then simulate that the txs have enough confirmations by setting a high head. - when(btcBlockStore.getStoredBlockAtMainChainHeight(targetHeight)).thenReturn(new StoredBlock(targetHeader, BigInteger.ONE, targetHeight)); - } } From ae60e8e9fd9bf993a46672842724e593558e4540 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Fri, 26 Mar 2021 10:18:10 -0300 Subject: [PATCH 21/34] Returning empty byte array instead of null when exception in Bridge new methods --- rskj-core/src/main/java/co/rsk/peg/Bridge.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index ddeead86395..ac81df8dc35 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -1152,7 +1152,7 @@ public byte[] getBestBlockHeader(Object[] args) { return this.bridgeSupport.getBtcBlockchainBestBlockHeader(); } catch (Exception e) { logger.warn("Exception in getBestBlockHeader", e); - return null; + return ByteUtil.EMPTY_BYTE_ARRAY; } } @@ -1177,7 +1177,7 @@ public byte[] getBitcoinHeaderByHash(Object[] args) { return this.bridgeSupport.getBtcBlockHeaderByHash(hash); } catch (Exception e) { logger.warn("Exception in getBitcoinHeaderByHash", e); - return null; + return ByteUtil.EMPTY_BYTE_ARRAY; } } @@ -1190,7 +1190,7 @@ public byte[] getBitcoinHeaderByHeight(Object[] args) { return this.bridgeSupport.getBtcBlockchainBlockHeaderByHeight(height); } catch (Exception e) { logger.warn("Exception in getBitcoinHeaderByHeight", e); - return null; + return ByteUtil.EMPTY_BYTE_ARRAY; } } @@ -1204,7 +1204,7 @@ public byte[] getBitcoinParentByHash(Object[] args) { return this.bridgeSupport.getBtcParentBlockHeaderByHash(hash); } catch (Exception e) { logger.warn("Exception in getBitcoinHeaderByHash", e); - return null; + return ByteUtil.EMPTY_BYTE_ARRAY; } } From b5c7fc15c43318d7d64a1597a27a90dc2d444d93 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Mon, 29 Mar 2021 15:25:15 -0300 Subject: [PATCH 22/34] Adding RSKIP220 references --- rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java | 10 +++++----- .../config/blockchain/upgrades/ConsensusRule.java | 3 ++- rskj-core/src/main/resources/expected.conf | 1 + rskj-core/src/main/resources/reference.conf | 1 + ...hodsTest.java => BridgeRSKIP220NewMethodsTest.java} | 2 +- ...t.java => BridgeSupportRSKIP220NewMethodsTest.java} | 2 +- 6 files changed, 11 insertions(+), 8 deletions(-) rename rskj-core/src/test/java/co/rsk/peg/{BridgeNewMethodsTest.java => BridgeRSKIP220NewMethodsTest.java} (98%) rename rskj-core/src/test/java/co/rsk/peg/{BridgeSupportNewMethodsTest.java => BridgeSupportRSKIP220NewMethodsTest.java} (99%) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 7fddb006b57..28241f26fc8 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -622,7 +622,7 @@ public enum BridgeMethods { ), fixedCost(20000L), (BridgeMethodExecutorTyped) Bridge::getBestBlockHeader, - activations -> true, // TODO: Review activation + activations -> activations.isActive(RSKIP220), false ), GET_BEST_BLOCK_NUMBER( @@ -633,7 +633,7 @@ public enum BridgeMethods { ), fixedCost(20000L), (BridgeMethodExecutorTyped) Bridge::getBestBlockNumber, - activations -> true, // TODO: Review activation + activations -> activations.isActive(RSKIP220), false ), GET_BITCOIN_HEADER_BY_HASH( @@ -644,7 +644,7 @@ public enum BridgeMethods { ), fixedCost(20000L), (BridgeMethodExecutorTyped) Bridge::getBitcoinHeaderByHash, - activations -> true, // TODO: Review activation + activations -> activations.isActive(RSKIP220), false ), GET_BITCOIN_PARENT_BY_HASH( @@ -655,7 +655,7 @@ public enum BridgeMethods { ), fixedCost(20000L), (BridgeMethodExecutorTyped) Bridge::getBitcoinParentByHash, - activations -> true, // TODO: Review activation + activations -> activations.isActive(RSKIP220), false ), GET_BITCOIN_HEADER_BY_HEIGHT( @@ -666,7 +666,7 @@ public enum BridgeMethods { ), fixedCost(20000L), (BridgeMethodExecutorTyped) Bridge::getBitcoinHeaderByHeight, - activations -> true, // TODO: Review activation + activations -> activations.isActive(RSKIP220), false ); diff --git a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java index 84ec17422e7..bda488925b0 100644 --- a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java +++ b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java @@ -67,7 +67,8 @@ public enum ConsensusRule { RSKIP199("rskip199"), RSKIP200("rskip200"), RSKIP201("rskip201"), - RSKIP218("rskip218"); // New rewards fee adddress + RSKIP218("rskip218"), // New rewards fee adddress + RSKIP220("rskip220"); private String configKey; diff --git a/rskj-core/src/main/resources/expected.conf b/rskj-core/src/main/resources/expected.conf index 333a284e45d..c639bb6473c 100644 --- a/rskj-core/src/main/resources/expected.conf +++ b/rskj-core/src/main/resources/expected.conf @@ -63,6 +63,7 @@ blockchain = { rskip200 = rskip201 = rskip218 = + rskip220 = } } gc = { diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index b05e1e621fd..f63e4f1ab4e 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -54,6 +54,7 @@ blockchain = { rskip200 = iris300 rskip201 = iris300 rskip218 = iris300 + rskip220 = iris300 } } gc = { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeRSKIP220NewMethodsTest.java similarity index 98% rename from rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java rename to rskj-core/src/test/java/co/rsk/peg/BridgeRSKIP220NewMethodsTest.java index 5aa1a6622c9..0baf99a017a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeNewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeRSKIP220NewMethodsTest.java @@ -17,7 +17,7 @@ import static org.mockito.Mockito.*; -public class BridgeNewMethodsTest { +public class BridgeRSKIP220NewMethodsTest { private static Random random = new Random(); private TestSystemProperties config; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRSKIP220NewMethodsTest.java similarity index 99% rename from rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java rename to rskj-core/src/test/java/co/rsk/peg/BridgeSupportRSKIP220NewMethodsTest.java index 5c2fa8d2a38..b92b5890ef0 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportNewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRSKIP220NewMethodsTest.java @@ -22,7 +22,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; -public class BridgeSupportNewMethodsTest { +public class BridgeSupportRSKIP220NewMethodsTest { private static Random random = new Random(); private BridgeConstants bridgeConstants; From db749cb60f6b105b914890dfd3c547a3f302264d Mon Sep 17 00:00:00 2001 From: ajlopez Date: Mon, 29 Mar 2021 16:40:49 -0300 Subject: [PATCH 23/34] Using height to hash map --- .../src/main/java/co/rsk/peg/BridgeSupport.java | 10 ++++------ .../peg/BridgeSupportRSKIP220NewMethodsTest.java | 15 +-------------- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java index 5d201b422fc..c80a61807b1 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1399,15 +1399,13 @@ public byte[] getBtcBlockchainBlockHeaderByHeight(int height) throws BlockStoreE Context.propagate(btcContext); this.ensureBtcBlockStore(); - StoredBlock head = btcBlockStore.getChainHead(); - int highestHeight = head.getHeight(); - int lowestHeight = getLowestBlock().getHeight(); + StoredBlock block = btcBlockStore.getStoredBlockAtMainChainHeight(height); - if (height < lowestHeight || height > highestHeight) { - throw new IndexOutOfBoundsException(String.format("Height must be between %d and %d", lowestHeight, highestHeight)); + if (block == null) { + return ByteUtil.EMPTY_BYTE_ARRAY; } - return serializeBlockHeader(btcBlockStore.getStoredBlockAtMainChainDepth(highestHeight - height)); + return serializeBlockHeader(block); } public Long getBtcTransactionConfirmationsGetCost(Object[] args) { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRSKIP220NewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRSKIP220NewMethodsTest.java index b92b5890ef0..e71b6b7dbbf 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRSKIP220NewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRSKIP220NewMethodsTest.java @@ -130,26 +130,13 @@ public void getBtcParentBlockHeaderByUnknownHash() throws BlockStoreException, I @Test public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IOException { - when(btcBlockStore.getStoredBlockAtMainChainDepth(10)).thenReturn(storedBlock); + when(btcBlockStore.getStoredBlockAtMainChainHeight(20)).thenReturn(storedBlock); byte[] result = bridgeSupport.getBtcBlockchainBlockHeaderByHeight(20); Assert.assertArrayEquals(header, result); } - @Test - public void getBtcBlockchainBlockHeaderByHeightTooHight() throws BlockStoreException, IOException { - when(btcBlockStore.getStoredBlockAtMainChainDepth(10)).thenReturn(storedBlock); - - try { - bridgeSupport.getBtcBlockchainBlockHeaderByHeight(40); - Assert.fail(); - } - catch (IndexOutOfBoundsException ex) { - Assert.assertEquals("Height must be between 0 and 30", ex.getMessage()); - } - } - private BridgeSupport getBridgeSupport(BridgeConstants constants, BtcBlockStoreWithCache.Factory blockStoreFactory, ActivationConfig.ForBlock activations) { From c5a787d09bd920c2d240c103929875a17da54b6d Mon Sep 17 00:00:00 2001 From: ajlopez Date: Mon, 5 Apr 2021 10:29:02 -0300 Subject: [PATCH 24/34] Adding TODO comments for gas calculation; change only local calls flag --- .../main/java/co/rsk/peg/BridgeMethods.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 28241f26fc8..7c925a5d9a3 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -620,10 +620,10 @@ public enum BridgeMethods { new String[0], new String[]{"bytes"} ), - fixedCost(20000L), + fixedCost(20000L), // TODO: calculate gas cost (BridgeMethodExecutorTyped) Bridge::getBestBlockHeader, activations -> activations.isActive(RSKIP220), - false + true ), GET_BEST_BLOCK_NUMBER( CallTransaction.Function.fromSignature( @@ -631,10 +631,10 @@ public enum BridgeMethods { new String[0], new String[]{"uint256"} ), - fixedCost(20000L), + fixedCost(20000L), // TODO: calculate gas cost (BridgeMethodExecutorTyped) Bridge::getBestBlockNumber, activations -> activations.isActive(RSKIP220), - false + true ), GET_BITCOIN_HEADER_BY_HASH( CallTransaction.Function.fromSignature( @@ -642,10 +642,10 @@ public enum BridgeMethods { new String[]{"bytes32"}, new String[]{"bytes"} ), - fixedCost(20000L), + fixedCost(20000L), // TODO: calculate gas cost (BridgeMethodExecutorTyped) Bridge::getBitcoinHeaderByHash, activations -> activations.isActive(RSKIP220), - false + true ), GET_BITCOIN_PARENT_BY_HASH( CallTransaction.Function.fromSignature( @@ -653,10 +653,10 @@ public enum BridgeMethods { new String[]{"bytes32"}, new String[]{"bytes"} ), - fixedCost(20000L), + fixedCost(20000L), // TODO: calculate gas cost (BridgeMethodExecutorTyped) Bridge::getBitcoinParentByHash, activations -> activations.isActive(RSKIP220), - false + true ), GET_BITCOIN_HEADER_BY_HEIGHT( CallTransaction.Function.fromSignature( @@ -664,10 +664,10 @@ public enum BridgeMethods { new String[]{"uint256"}, new String[]{"bytes"} ), - fixedCost(20000L), + fixedCost(20000L), // TODO: calculate gas cost (BridgeMethodExecutorTyped) Bridge::getBitcoinHeaderByHeight, activations -> activations.isActive(RSKIP220), - false + true ); private final CallTransaction.Function function; From 28ab538cc0392b377317bc50a0c3d952d4f2af95 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Mon, 5 Apr 2021 15:43:08 -0300 Subject: [PATCH 25/34] Reusing existing method in BridgeSupport.getBtcBlockchainBestBlockHeader --- rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java | 10 +++++----- rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java | 4 +--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 7c925a5d9a3..d968847b291 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -623,7 +623,7 @@ public enum BridgeMethods { fixedCost(20000L), // TODO: calculate gas cost (BridgeMethodExecutorTyped) Bridge::getBestBlockHeader, activations -> activations.isActive(RSKIP220), - true + false ), GET_BEST_BLOCK_NUMBER( CallTransaction.Function.fromSignature( @@ -634,7 +634,7 @@ public enum BridgeMethods { fixedCost(20000L), // TODO: calculate gas cost (BridgeMethodExecutorTyped) Bridge::getBestBlockNumber, activations -> activations.isActive(RSKIP220), - true + false ), GET_BITCOIN_HEADER_BY_HASH( CallTransaction.Function.fromSignature( @@ -645,7 +645,7 @@ public enum BridgeMethods { fixedCost(20000L), // TODO: calculate gas cost (BridgeMethodExecutorTyped) Bridge::getBitcoinHeaderByHash, activations -> activations.isActive(RSKIP220), - true + false ), GET_BITCOIN_PARENT_BY_HASH( CallTransaction.Function.fromSignature( @@ -656,7 +656,7 @@ public enum BridgeMethods { fixedCost(20000L), // TODO: calculate gas cost (BridgeMethodExecutorTyped) Bridge::getBitcoinParentByHash, activations -> activations.isActive(RSKIP220), - true + false ), GET_BITCOIN_HEADER_BY_HEIGHT( CallTransaction.Function.fromSignature( @@ -667,7 +667,7 @@ public enum BridgeMethods { fixedCost(20000L), // TODO: calculate gas cost (BridgeMethodExecutorTyped) Bridge::getBitcoinHeaderByHeight, activations -> activations.isActive(RSKIP220), - true + false ); private final CallTransaction.Function function; diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java index c80a61807b1..2fdf3d98f74 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1375,9 +1375,7 @@ public byte[] getBtcParentBlockHeaderByHash(Sha256Hash hash) throws IOException, } public byte[] getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOException { - this.ensureBtcBlockStore(); - - return serializeBlockHeader(btcBlockStore.getChainHead()); + return serializeBlockHeader(getBtcBlockchainChainHead()); } public Sha256Hash getBtcBlockchainBlockHashAtDepth(int depth) throws BlockStoreException, IOException { From ae37a43fca144b81ab7b3ce399f09a448499f93a Mon Sep 17 00:00:00 2001 From: ajlopez Date: Mon, 5 Apr 2021 16:04:52 -0300 Subject: [PATCH 26/34] Bridge new code method renaming --- .../src/main/java/co/rsk/peg/Bridge.java | 35 +++++++------------ .../main/java/co/rsk/peg/BridgeMethods.java | 10 +++--- .../rsk/peg/BridgeRSKIP220NewMethodsTest.java | 21 +++++------ 3 files changed, 28 insertions(+), 38 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index ac81df8dc35..4b652308d6d 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -1145,30 +1145,19 @@ public long registerFastBridgeBtcTransaction(Object[] args) { } } - public byte[] getBestBlockHeader(Object[] args) { - logger.trace("getBestBlockHeader"); + public byte[] getBtcBlockchainBestBlockHeader(Object[] args) { + logger.trace("getBtcBlockchainBestBlockHeader"); try { return this.bridgeSupport.getBtcBlockchainBestBlockHeader(); } catch (Exception e) { - logger.warn("Exception in getBestBlockHeader", e); + logger.warn("Exception in getBtcBlockchainBestBlockHeader", e); return ByteUtil.EMPTY_BYTE_ARRAY; } } - public long getBestBlockNumber(Object[] args) { - logger.trace("getBestBlockNumber"); - - try { - return this.bridgeSupport.getBtcBlockchainBestChainHeight(); - } catch (Exception e) { - logger.warn("Exception in getBestBlockNumber", e); - return BridgeSupport.FAST_BRIDGE_GENERIC_ERROR; - } - } - - public byte[] getBitcoinHeaderByHash(Object[] args) { - logger.trace("getBitcoinHeaderByHash"); + public byte[] getBtcBlockHeaderByHash(Object[] args) { + logger.trace("getBtcBlockHeaderByHash"); try { byte[] hashBytes = (byte[])args[0]; @@ -1176,26 +1165,26 @@ public byte[] getBitcoinHeaderByHash(Object[] args) { return this.bridgeSupport.getBtcBlockHeaderByHash(hash); } catch (Exception e) { - logger.warn("Exception in getBitcoinHeaderByHash", e); + logger.warn("Exception in getBtcBlockHeaderByHash", e); return ByteUtil.EMPTY_BYTE_ARRAY; } } - public byte[] getBitcoinHeaderByHeight(Object[] args) { - logger.trace("getBitcoinHeaderByHeight"); + public byte[] getBtcBlockchainBlockHeaderByHeight(Object[] args) { + logger.trace("getBtcBlockchainBlockHeaderByHeight"); try { int height = ((BigInteger) args[0]).intValue(); return this.bridgeSupport.getBtcBlockchainBlockHeaderByHeight(height); } catch (Exception e) { - logger.warn("Exception in getBitcoinHeaderByHeight", e); + logger.warn("Exception in getBtcBlockchainBlockHeaderByHeight", e); return ByteUtil.EMPTY_BYTE_ARRAY; } } - public byte[] getBitcoinParentByHash(Object[] args) { - logger.trace("getBitcoinParentByHash"); + public byte[] getBtcParentBlockHeaderByHash(Object[] args) { + logger.trace("getBtcParentBlockHeaderByHash"); try { byte[] hashBytes = (byte[])args[0]; @@ -1203,7 +1192,7 @@ public byte[] getBitcoinParentByHash(Object[] args) { return this.bridgeSupport.getBtcParentBlockHeaderByHash(hash); } catch (Exception e) { - logger.warn("Exception in getBitcoinHeaderByHash", e); + logger.warn("Exception in getBtcParentBlockHeaderByHash", e); return ByteUtil.EMPTY_BYTE_ARRAY; } } diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index d968847b291..5227b6839ca 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -621,7 +621,7 @@ public enum BridgeMethods { new String[]{"bytes"} ), fixedCost(20000L), // TODO: calculate gas cost - (BridgeMethodExecutorTyped) Bridge::getBestBlockHeader, + (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBestBlockHeader, activations -> activations.isActive(RSKIP220), false ), @@ -632,7 +632,7 @@ public enum BridgeMethods { new String[]{"uint256"} ), fixedCost(20000L), // TODO: calculate gas cost - (BridgeMethodExecutorTyped) Bridge::getBestBlockNumber, + (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBestChainHeight, activations -> activations.isActive(RSKIP220), false ), @@ -643,7 +643,7 @@ public enum BridgeMethods { new String[]{"bytes"} ), fixedCost(20000L), // TODO: calculate gas cost - (BridgeMethodExecutorTyped) Bridge::getBitcoinHeaderByHash, + (BridgeMethodExecutorTyped) Bridge::getBtcBlockHeaderByHash, activations -> activations.isActive(RSKIP220), false ), @@ -654,7 +654,7 @@ public enum BridgeMethods { new String[]{"bytes"} ), fixedCost(20000L), // TODO: calculate gas cost - (BridgeMethodExecutorTyped) Bridge::getBitcoinParentByHash, + (BridgeMethodExecutorTyped) Bridge::getBtcParentBlockHeaderByHash, activations -> activations.isActive(RSKIP220), false ), @@ -665,7 +665,7 @@ public enum BridgeMethods { new String[]{"bytes"} ), fixedCost(20000L), // TODO: calculate gas cost - (BridgeMethodExecutorTyped) Bridge::getBitcoinHeaderByHeight, + (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHeaderByHeight, activations -> activations.isActive(RSKIP220), false ); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeRSKIP220NewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeRSKIP220NewMethodsTest.java index 0baf99a017a..015ffa3f998 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeRSKIP220NewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeRSKIP220NewMethodsTest.java @@ -7,6 +7,7 @@ import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.core.Block; +import org.ethereum.vm.exception.VMException; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -52,58 +53,58 @@ public void beforeEach() { } @Test - public void getBestBlockNumber() throws IOException, BlockStoreException { + public void getBtcBlockchainBestChainHeight() throws IOException, BlockStoreException, VMException { when(bridgeSupport.getBtcBlockchainBestChainHeight()).thenReturn(42); - long result = bridge.getBestBlockNumber(new Object[0]); + int result = bridge.getBtcBlockchainBestChainHeight(new Object[0]); Assert.assertEquals(42, result); } @Test - public void getBestBlockHeader() throws IOException, BlockStoreException { + public void getBtcBlockchainBestBlockHeader() throws IOException, BlockStoreException { byte[] header = new byte[80]; random.nextBytes(header); when(bridgeSupport.getBtcBlockchainBestBlockHeader()).thenReturn(header); - byte[] result = bridge.getBestBlockHeader(new Object[0]); + byte[] result = bridge.getBtcBlockchainBestBlockHeader(new Object[0]); Assert.assertArrayEquals(header, result); } @Test - public void getBitcoinHeaderByHash() throws IOException, BlockStoreException { + public void getBtcBlockHeaderByHash() throws IOException, BlockStoreException { byte[] hashBytes = new byte[32]; random.nextBytes(hashBytes); byte[] header = new byte[80]; random.nextBytes(header); when(bridgeSupport.getBtcBlockHeaderByHash(Sha256Hash.wrap(hashBytes))).thenReturn(header); - byte[] result = bridge.getBitcoinHeaderByHash(new Object[] { hashBytes }); + byte[] result = bridge.getBtcBlockHeaderByHash(new Object[] { hashBytes }); Assert.assertArrayEquals(header, result); } @Test - public void getBitcoinParentByHash() throws IOException, BlockStoreException { + public void getBtcParentBlockHeaderByHash() throws IOException, BlockStoreException { byte[] hashBytes = new byte[32]; random.nextBytes(hashBytes); byte[] header = new byte[80]; random.nextBytes(header); when(bridgeSupport.getBtcParentBlockHeaderByHash(Sha256Hash.wrap(hashBytes))).thenReturn(header); - byte[] result = bridge.getBitcoinParentByHash(new Object[] { hashBytes }); + byte[] result = bridge.getBtcParentBlockHeaderByHash(new Object[] { hashBytes }); Assert.assertArrayEquals(header, result); } @Test - public void getBitcoinHeaderByHeight() throws IOException, BlockStoreException { + public void getBtcBlockchainBlockHeaderByHeight() throws IOException, BlockStoreException { byte[] header = new byte[80]; random.nextBytes(header); BigInteger height = BigInteger.TEN; when(bridgeSupport.getBtcBlockchainBlockHeaderByHeight(10)).thenReturn(header); - byte[] result = bridge.getBitcoinHeaderByHeight(new Object[] { height }); + byte[] result = bridge.getBtcBlockchainBlockHeaderByHeight(new Object[] { height }); Assert.assertArrayEquals(header, result); } From c464557f5981ce5ee94cd5327eb123c2d9f723dd Mon Sep 17 00:00:00 2001 From: ajlopez Date: Mon, 5 Apr 2021 16:07:38 -0300 Subject: [PATCH 27/34] Removing unneeded null check --- rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java index 2fdf3d98f74..761c0c4a8d7 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1399,10 +1399,6 @@ public byte[] getBtcBlockchainBlockHeaderByHeight(int height) throws BlockStoreE StoredBlock block = btcBlockStore.getStoredBlockAtMainChainHeight(height); - if (block == null) { - return ByteUtil.EMPTY_BYTE_ARRAY; - } - return serializeBlockHeader(block); } From bbd5de9768c4dabe23a678ee2b1531d8fe1d64c8 Mon Sep 17 00:00:00 2001 From: ajlopez Date: Mon, 5 Apr 2021 16:10:13 -0300 Subject: [PATCH 28/34] Adding RSKIP220 reference to ActivationConfigTest --- .../config/blockchain/upgrades/ActivationConfigTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java index f3b13977263..8209f0a8386 100644 --- a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java +++ b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java @@ -89,6 +89,7 @@ public class ActivationConfigTest { " rskip200: iris300", " rskip201: iris300", " rskip218: iris300", + " rskip220: iris300", "}" )); From 43398ba4b7c1ffb121f34ad8f21187391f56ac5e Mon Sep 17 00:00:00 2001 From: ajlopez Date: Thu, 8 Apr 2021 10:09:00 -0300 Subject: [PATCH 29/34] Change new Bridge method external names --- rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 5227b6839ca..bbbbc5f1f0b 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -614,9 +614,9 @@ public enum BridgeMethods { activations -> activations.isActive(RSKIP176), false ), - GET_BEST_BLOCK_HEADER( + GET_BTC_BLOCKCHAIN_BEST_BLOCK_HEADER( CallTransaction.Function.fromSignature( - "getBestBlockHeader", + "getBtcBlockchainBestBlockHeader", new String[0], new String[]{"bytes"} ), @@ -625,9 +625,9 @@ public enum BridgeMethods { activations -> activations.isActive(RSKIP220), false ), - GET_BEST_BLOCK_NUMBER( + GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT_2( CallTransaction.Function.fromSignature( - "getBestBlockNumber", + "getBtcBlockchainBestChainHeight2", new String[0], new String[]{"uint256"} ), @@ -636,7 +636,7 @@ public enum BridgeMethods { activations -> activations.isActive(RSKIP220), false ), - GET_BITCOIN_HEADER_BY_HASH( + GET_BTC_BLOCK_HEADER_BY_HASH( CallTransaction.Function.fromSignature( "getBitcoinHeaderByHash", new String[]{"bytes32"}, From 415a3bdf0e405be0324fe08f8a234d261d1162b5 Mon Sep 17 00:00:00 2001 From: Marcos Date: Thu, 8 Apr 2021 13:32:06 -0300 Subject: [PATCH 30/34] Rename and reorder methods for consistency --- .../src/main/java/co/rsk/peg/Bridge.java | 16 ++++---- .../main/java/co/rsk/peg/BridgeMethods.java | 36 ++++++++--------- .../main/java/co/rsk/peg/BridgeSupport.java | 30 +++++++------- .../rsk/peg/BridgeRSKIP220NewMethodsTest.java | 40 +++++++++---------- .../BridgeSupportRSKIP220NewMethodsTest.java | 34 ++++++++-------- 5 files changed, 78 insertions(+), 78 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 4b652308d6d..916ea82fb26 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -1156,16 +1156,16 @@ public byte[] getBtcBlockchainBestBlockHeader(Object[] args) { } } - public byte[] getBtcBlockHeaderByHash(Object[] args) { - logger.trace("getBtcBlockHeaderByHash"); + public byte[] getBtcBlockchainBlockHeaderByHash(Object[] args) { + logger.trace("getBtcBlockchainBlockHeaderByHash"); try { byte[] hashBytes = (byte[])args[0]; Sha256Hash hash = Sha256Hash.wrap(hashBytes); - return this.bridgeSupport.getBtcBlockHeaderByHash(hash); + return this.bridgeSupport.getBtcBlockchainBlockHeaderByHash(hash); } catch (Exception e) { - logger.warn("Exception in getBtcBlockHeaderByHash", e); + logger.warn("Exception in getBtcBlockchainBlockHeaderByHash", e); return ByteUtil.EMPTY_BYTE_ARRAY; } } @@ -1183,16 +1183,16 @@ public byte[] getBtcBlockchainBlockHeaderByHeight(Object[] args) { } } - public byte[] getBtcParentBlockHeaderByHash(Object[] args) { - logger.trace("getBtcParentBlockHeaderByHash"); + public byte[] getBtcBlockchainParentBlockHeaderByHash(Object[] args) { + logger.trace("getBtcBlockchainParentBlockHeaderByHash"); try { byte[] hashBytes = (byte[])args[0]; Sha256Hash hash = Sha256Hash.wrap(hashBytes); - return this.bridgeSupport.getBtcParentBlockHeaderByHash(hash); + return this.bridgeSupport.getBtcBlockchainParentBlockHeaderByHash(hash); } catch (Exception e) { - logger.warn("Exception in getBtcParentBlockHeaderByHash", e); + logger.warn("Exception in getBtcBlockchainParentBlockHeaderByHash", e); return ByteUtil.EMPTY_BYTE_ARRAY; } } diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index bbbbc5f1f0b..defa8eded4b 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -636,36 +636,36 @@ public enum BridgeMethods { activations -> activations.isActive(RSKIP220), false ), - GET_BTC_BLOCK_HEADER_BY_HASH( + GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HASH( CallTransaction.Function.fromSignature( - "getBitcoinHeaderByHash", + "getBtcBlockchainBlockHeaderByHash", new String[]{"bytes32"}, new String[]{"bytes"} ), fixedCost(20000L), // TODO: calculate gas cost - (BridgeMethodExecutorTyped) Bridge::getBtcBlockHeaderByHash, + (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHeaderByHash, activations -> activations.isActive(RSKIP220), false ), - GET_BITCOIN_PARENT_BY_HASH( - CallTransaction.Function.fromSignature( - "getBitcoinParentByHash", - new String[]{"bytes32"}, - new String[]{"bytes"} - ), - fixedCost(20000L), // TODO: calculate gas cost - (BridgeMethodExecutorTyped) Bridge::getBtcParentBlockHeaderByHash, - activations -> activations.isActive(RSKIP220), - false + GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HEIGHT( + CallTransaction.Function.fromSignature( + "getBtcBlockchainBlockHeaderByHeight", + new String[]{"uint256"}, + new String[]{"bytes"} + ), + fixedCost(20000L), // TODO: calculate gas cost + (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHeaderByHeight, + activations -> activations.isActive(RSKIP220), + false ), - GET_BITCOIN_HEADER_BY_HEIGHT( + GET_BTC_BLOCKCHAIN_PARENT_BLOCK_HEADER_BY_HASH( CallTransaction.Function.fromSignature( - "getBitcoinHeaderByHeight", - new String[]{"uint256"}, + "getBtcBlockchainParentBlockHeaderByHash", + new String[]{"bytes32"}, new String[]{"bytes"} ), fixedCost(20000L), // TODO: calculate gas cost - (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHeaderByHeight, + (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainParentBlockHeaderByHash, activations -> activations.isActive(RSKIP220), false ); @@ -753,7 +753,7 @@ private static CostProvider fixedCost(long cost) { private static CostProvider fromMethod(BridgeCostProvider bridgeCostProvider) { return (Bridge bridge, ActivationConfig.ForBlock config, Object[] args) -> bridgeCostProvider.getCost(bridge, args); } - + private static final Map SIGNATURES = Stream.of(BridgeMethods.values()) .collect(Collectors.toMap( m -> new ByteArrayWrapper(m.getFunction().encodeSignature()), diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java index 761c0c4a8d7..adeee0c5cd4 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1356,13 +1356,26 @@ public List getBtcBlockchainBlockLocator() throws IOException, Block return blockLocator; } - public byte[] getBtcBlockHeaderByHash(Sha256Hash hash) throws IOException, BlockStoreException { + public byte[] getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOException { + return serializeBlockHeader(getBtcBlockchainChainHead()); + } + + public byte[] getBtcBlockchainBlockHeaderByHash(Sha256Hash hash) throws IOException, BlockStoreException { this.ensureBtcBlockStore(); return serializeBlockHeader(btcBlockStore.get(hash)); } - public byte[] getBtcParentBlockHeaderByHash(Sha256Hash hash) throws IOException, BlockStoreException { + public byte[] getBtcBlockchainBlockHeaderByHeight(int height) throws BlockStoreException, IOException { + Context.propagate(btcContext); + this.ensureBtcBlockStore(); + + StoredBlock block = btcBlockStore.getStoredBlockAtMainChainHeight(height); + + return serializeBlockHeader(block); + } + + public byte[] getBtcBlockchainParentBlockHeaderByHash(Sha256Hash hash) throws IOException, BlockStoreException { this.ensureBtcBlockStore(); StoredBlock block = btcBlockStore.get(hash); @@ -1374,10 +1387,6 @@ public byte[] getBtcParentBlockHeaderByHash(Sha256Hash hash) throws IOException, return serializeBlockHeader(btcBlockStore.get(block.getHeader().getPrevBlockHash())); } - public byte[] getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOException { - return serializeBlockHeader(getBtcBlockchainChainHead()); - } - public Sha256Hash getBtcBlockchainBlockHashAtDepth(int depth) throws BlockStoreException, IOException { Context.propagate(btcContext); this.ensureBtcBlockStore(); @@ -1393,15 +1402,6 @@ public Sha256Hash getBtcBlockchainBlockHashAtDepth(int depth) throws BlockStoreE return blockAtDepth.getHeader().getHash(); } - public byte[] getBtcBlockchainBlockHeaderByHeight(int height) throws BlockStoreException, IOException { - Context.propagate(btcContext); - this.ensureBtcBlockStore(); - - StoredBlock block = btcBlockStore.getStoredBlockAtMainChainHeight(height); - - return serializeBlockHeader(block); - } - public Long getBtcTransactionConfirmationsGetCost(Object[] args) { final long BASIC_COST = 27_000; final long STEP_COST = 315; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeRSKIP220NewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeRSKIP220NewMethodsTest.java index 015ffa3f998..7858954bdbd 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeRSKIP220NewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeRSKIP220NewMethodsTest.java @@ -52,15 +52,6 @@ public void beforeEach() { bridge.init(null, rskExecutionBlock, null, null, null, null); } - @Test - public void getBtcBlockchainBestChainHeight() throws IOException, BlockStoreException, VMException { - when(bridgeSupport.getBtcBlockchainBestChainHeight()).thenReturn(42); - - int result = bridge.getBtcBlockchainBestChainHeight(new Object[0]); - - Assert.assertEquals(42, result); - } - @Test public void getBtcBlockchainBestBlockHeader() throws IOException, BlockStoreException { byte[] header = new byte[80]; @@ -72,27 +63,23 @@ public void getBtcBlockchainBestBlockHeader() throws IOException, BlockStoreExce } @Test - public void getBtcBlockHeaderByHash() throws IOException, BlockStoreException { - byte[] hashBytes = new byte[32]; - random.nextBytes(hashBytes); - byte[] header = new byte[80]; - random.nextBytes(header); + public void getBtcBlockchainBestChainHeight() throws IOException, BlockStoreException, VMException { + when(bridgeSupport.getBtcBlockchainBestChainHeight()).thenReturn(42); - when(bridgeSupport.getBtcBlockHeaderByHash(Sha256Hash.wrap(hashBytes))).thenReturn(header); - byte[] result = bridge.getBtcBlockHeaderByHash(new Object[] { hashBytes }); + int result = bridge.getBtcBlockchainBestChainHeight(new Object[0]); - Assert.assertArrayEquals(header, result); + Assert.assertEquals(42, result); } @Test - public void getBtcParentBlockHeaderByHash() throws IOException, BlockStoreException { + public void getBtcBlockchainBlockHeaderByHash() throws IOException, BlockStoreException { byte[] hashBytes = new byte[32]; random.nextBytes(hashBytes); byte[] header = new byte[80]; random.nextBytes(header); - when(bridgeSupport.getBtcParentBlockHeaderByHash(Sha256Hash.wrap(hashBytes))).thenReturn(header); - byte[] result = bridge.getBtcParentBlockHeaderByHash(new Object[] { hashBytes }); + when(bridgeSupport.getBtcBlockchainBlockHeaderByHash(Sha256Hash.wrap(hashBytes))).thenReturn(header); + byte[] result = bridge.getBtcBlockchainBlockHeaderByHash(new Object[] { hashBytes }); Assert.assertArrayEquals(header, result); } @@ -108,4 +95,17 @@ public void getBtcBlockchainBlockHeaderByHeight() throws IOException, BlockStore Assert.assertArrayEquals(header, result); } + + @Test + public void getBtcBlockchainParentBlockHeaderByHash() throws IOException, BlockStoreException { + byte[] hashBytes = new byte[32]; + random.nextBytes(hashBytes); + byte[] header = new byte[80]; + random.nextBytes(header); + + when(bridgeSupport.getBtcBlockchainParentBlockHeaderByHash(Sha256Hash.wrap(hashBytes))).thenReturn(header); + byte[] result = bridge.getBtcBlockchainParentBlockHeaderByHash(new Object[] { hashBytes }); + + Assert.assertArrayEquals(header, result); + } } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRSKIP220NewMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRSKIP220NewMethodsTest.java index e71b6b7dbbf..e8ae5ebc948 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRSKIP220NewMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRSKIP220NewMethodsTest.java @@ -80,28 +80,37 @@ public void getBtcBlockchainBestBlockHeader() throws BlockStoreException, IOExce } @Test - public void getBtcBlockHeaderByHash() throws BlockStoreException, IOException { - byte[] result = bridgeSupport.getBtcBlockHeaderByHash(hash); + public void getBtcBlockchainBlockHeaderByHash() throws BlockStoreException, IOException { + byte[] result = bridgeSupport.getBtcBlockchainBlockHeaderByHash(hash); Assert.assertArrayEquals(header, result); } @Test - public void getBtcBlockHeaderByUnknownHash() throws BlockStoreException, IOException { + public void getBtcBlockchainBlockHeaderByUnknownHash() throws BlockStoreException, IOException { byte[] unknownHashBytes = new byte[32]; random.nextBytes(unknownHashBytes); Sha256Hash unknownHash = Sha256Hash.wrap(unknownHashBytes); when(btcBlockStore.get(unknownHash)).thenReturn(null); - byte[] result = bridgeSupport.getBtcBlockHeaderByHash(unknownHash); + byte[] result = bridgeSupport.getBtcBlockchainBlockHeaderByHash(unknownHash); Assert.assertNotNull(result); Assert.assertEquals(0, result.length); } @Test - public void getBtcParentBlockHeaderByHash() throws BlockStoreException, IOException { + public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IOException { + when(btcBlockStore.getStoredBlockAtMainChainHeight(20)).thenReturn(storedBlock); + + byte[] result = bridgeSupport.getBtcBlockchainBlockHeaderByHeight(20); + + Assert.assertArrayEquals(header, result); + } + + @Test + public void getBtcBlockchainParentBlockHeaderByHash() throws BlockStoreException, IOException { byte[] parentHashBytes = new byte[32]; random.nextBytes(parentHashBytes); Sha256Hash parentHash = Sha256Hash.wrap(parentHashBytes); @@ -113,30 +122,21 @@ public void getBtcParentBlockHeaderByHash() throws BlockStoreException, IOExcept when(parentBtcBlock.unsafeBitcoinSerialize()).thenReturn(header); when(parentStoredBlock.getHeader()).thenReturn(parentBtcBlock); - byte[] result = bridgeSupport.getBtcParentBlockHeaderByHash(hash); + byte[] result = bridgeSupport.getBtcBlockchainParentBlockHeaderByHash(hash); Assert.assertArrayEquals(header, result); } @Test - public void getBtcParentBlockHeaderByUnknownHash() throws BlockStoreException, IOException { + public void getBtcBlockchainParentBlockHeaderByUnknownHash() throws BlockStoreException, IOException { when(btcBlockStore.get(hash)).thenReturn(null); - byte[] result = bridgeSupport.getBtcParentBlockHeaderByHash(hash); + byte[] result = bridgeSupport.getBtcBlockchainParentBlockHeaderByHash(hash); Assert.assertNotNull(result); Assert.assertEquals(0, result.length); } - @Test - public void getBtcBlockchainBlockHeaderByHeight() throws BlockStoreException, IOException { - when(btcBlockStore.getStoredBlockAtMainChainHeight(20)).thenReturn(storedBlock); - - byte[] result = bridgeSupport.getBtcBlockchainBlockHeaderByHeight(20); - - Assert.assertArrayEquals(header, result); - } - private BridgeSupport getBridgeSupport(BridgeConstants constants, BtcBlockStoreWithCache.Factory blockStoreFactory, ActivationConfig.ForBlock activations) { From f783ee9c8831645220513d3da678d7278bf42271 Mon Sep 17 00:00:00 2001 From: Marcos Date: Thu, 8 Apr 2021 15:44:20 -0300 Subject: [PATCH 31/34] Create CallPermissionProvider interface --- .../main/java/co/rsk/peg/BridgeMethods.java | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index defa8eded4b..79f7bf9609e 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -676,11 +676,22 @@ public enum BridgeMethods { private final BridgeMethodExecutor executor; private final boolean onlyAllowsLocalCalls; - BridgeMethods(CallTransaction.Function function, CostProvider costProvider, BridgeMethodExecutor executor, boolean onlyAllowsLocalCalls) { + BridgeMethods( + CallTransaction.Function function, + CostProvider costProvider, + BridgeMethodExecutor executor, + boolean onlyAllowsLocalCalls) { + this(function, costProvider, executor, activations -> Boolean.TRUE, onlyAllowsLocalCalls); } - BridgeMethods(CallTransaction.Function function, CostProvider costProvider, BridgeMethodExecutor executor, Function isEnabled, boolean onlyAllowsLocalCalls) { + BridgeMethods( + CallTransaction.Function function, + CostProvider costProvider, + BridgeMethodExecutor executor, + Function isEnabled, + boolean onlyAllowsLocalCalls) { + this.function = function; this.costProvider = costProvider; this.executor = executor; @@ -753,7 +764,23 @@ private static CostProvider fixedCost(long cost) { private static CostProvider fromMethod(BridgeCostProvider bridgeCostProvider) { return (Bridge bridge, ActivationConfig.ForBlock config, Object[] args) -> bridgeCostProvider.getCost(bridge, args); } - + + private interface CallPermissionProvider { + boolean getOnlyAllowLocalCallsPermission(Bridge bridge, ActivationConfig.ForBlock config, Object[] args); + } + + private interface BridgeCallPermissionProvider { + boolean getOnlyAllowLocalCallsPermission(Bridge bridge, Object[] args); + } + + private static CallPermissionProvider fixedPermission(boolean onlyAllowsLocalCalls) { + return (Bridge bridge, ActivationConfig.ForBlock config, Object[] args) -> onlyAllowsLocalCalls; + } + + private static CallPermissionProvider fromMethod(BridgeCallPermissionProvider bridgeCallPermissionProvider) { + return (Bridge bridge, ActivationConfig.ForBlock config, Object[] args) -> bridgeCallPermissionProvider.getOnlyAllowLocalCallsPermission(bridge, args); + } + private static final Map SIGNATURES = Stream.of(BridgeMethods.values()) .collect(Collectors.toMap( m -> new ByteArrayWrapper(m.getFunction().encodeSignature()), From 2d3747a332876a8aa2252599b619c6508dd0b257 Mon Sep 17 00:00:00 2001 From: Marcos Date: Thu, 8 Apr 2021 17:41:31 -0300 Subject: [PATCH 32/34] Update BridgeMethods to use CallPermissionProvider --- .../src/main/java/co/rsk/peg/Bridge.java | 5 +- .../main/java/co/rsk/peg/BridgeMethods.java | 135 +++++++++--------- 2 files changed, 72 insertions(+), 68 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 916ea82fb26..17e141b4ffd 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -335,7 +335,10 @@ public byte[] execute(byte[] data) throws VMException { // If this is not a local call, then first check whether the function // allows for non-local calls - if (activations.isActive(ConsensusRule.RSKIP88) && !isLocalCall() && bridgeParsedData.bridgeMethod.onlyAllowsLocalCalls()) { + if (activations.isActive(ConsensusRule.RSKIP88) && + !isLocalCall() && + bridgeParsedData.bridgeMethod.onlyAllowsLocalCalls(this, activations, bridgeParsedData.args)) { + String errorMessage = String.format("Non-local-call to %s. Returning without execution.", bridgeParsedData.bridgeMethod.getFunction().name); logger.info(errorMessage); throw new BridgeIllegalArgumentException(errorMessage); diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 79f7bf9609e..99686a71d66 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -42,7 +42,7 @@ public enum BridgeMethods { fixedCost(13000L), (BridgeMethodExecutorTyped) Bridge::addFederatorPublicKey, activations -> !activations.isActive(RSKIP123), - false + fixedPermission(false) ), ADD_FEDERATOR_PUBLIC_KEY_MULTIKEY( CallTransaction.Function.fromSignature( @@ -53,7 +53,7 @@ public enum BridgeMethods { fixedCost(13000L), (BridgeMethodExecutorTyped) Bridge::addFederatorPublicKeyMultikey, activations -> activations.isActive(RSKIP123), - false + fixedPermission(false) ), ADD_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( @@ -64,7 +64,7 @@ public enum BridgeMethods { fixedCost(25000L), (BridgeMethodExecutorTyped) Bridge::addOneOffLockWhitelistAddress, activations -> !activations.isActive(RSKIP87), - false + fixedPermission(false) ), ADD_ONE_OFF_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( @@ -75,7 +75,7 @@ public enum BridgeMethods { fixedCost(25000L), // using same gas estimation as ADD_LOCK_WHITELIST_ADDRESS (BridgeMethodExecutorTyped) Bridge::addOneOffLockWhitelistAddress, activations -> activations.isActive(RSKIP87), - false + fixedPermission(false) ), ADD_UNLIMITED_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( @@ -86,7 +86,7 @@ public enum BridgeMethods { fixedCost(25000L), // using same gas estimation as ADD_LOCK_WHITELIST_ADDRESS (BridgeMethodExecutorTyped) Bridge::addUnlimitedLockWhitelistAddress, activations -> activations.isActive(RSKIP87), - false + fixedPermission(false) ), ADD_SIGNATURE( CallTransaction.Function.fromSignature( @@ -96,7 +96,7 @@ public enum BridgeMethods { ), fixedCost(70000L), Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::addSignature, "addSignature"), - false + fixedPermission(false) ), COMMIT_FEDERATION( CallTransaction.Function.fromSignature( @@ -106,7 +106,7 @@ public enum BridgeMethods { ), fixedCost(38000L), (BridgeMethodExecutorTyped) Bridge::commitFederation, - false + fixedPermission(false) ), CREATE_FEDERATION( CallTransaction.Function.fromSignature( @@ -116,7 +116,7 @@ public enum BridgeMethods { ), fixedCost(11000L), (BridgeMethodExecutorTyped) Bridge::createFederation, - false + fixedPermission(false) ), GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT( CallTransaction.Function.fromSignature( @@ -126,7 +126,7 @@ public enum BridgeMethods { ), fixedCost(19000L), (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBestChainHeight, - true + fixedPermission(true) ), GET_BTC_BLOCKCHAIN_INITIAL_BLOCK_HEIGHT( CallTransaction.Function.fromSignature( @@ -137,7 +137,7 @@ public enum BridgeMethods { fixedCost(20000L), (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainInitialBlockHeight, activations -> activations.isActive(RSKIP89), - true + fixedPermission(true) ), GET_BTC_BLOCKCHAIN_BLOCK_LOCATOR( CallTransaction.Function.fromSignature( @@ -148,7 +148,7 @@ public enum BridgeMethods { fixedCost(76000L), (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockLocator, activations -> !activations.isActive(RSKIP89), - true + fixedPermission(true) ), GET_BTC_BLOCKCHAIN_BLOCK_HASH_AT_DEPTH( CallTransaction.Function.fromSignature( @@ -159,7 +159,7 @@ public enum BridgeMethods { fixedCost(20000L), (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHashAtDepth, activations -> activations.isActive(RSKIP89), - true + fixedPermission(true) ), GET_BTC_TRANSACTION_CONFIRMATIONS( CallTransaction.Function.fromSignature( @@ -170,7 +170,7 @@ public enum BridgeMethods { fromMethod(Bridge::getBtcTransactionConfirmationsGetCost), (BridgeMethodExecutorTyped) Bridge::getBtcTransactionConfirmations, activations -> activations.isActive(RSKIP122), - false + fixedPermission(false) ), GET_BTC_TX_HASH_PROCESSED_HEIGHT( CallTransaction.Function.fromSignature( @@ -180,7 +180,7 @@ public enum BridgeMethods { ), fixedCost(22000L), (BridgeMethodExecutorTyped) Bridge::getBtcTxHashProcessedHeight, - true + fixedPermission(true) ), GET_FEDERATION_ADDRESS( CallTransaction.Function.fromSignature( @@ -190,7 +190,7 @@ public enum BridgeMethods { ), fixedCost(11000L), (BridgeMethodExecutorTyped) Bridge::getFederationAddress, - true + fixedPermission(true) ), GET_FEDERATION_CREATION_BLOCK_NUMBER( CallTransaction.Function.fromSignature( @@ -200,7 +200,7 @@ public enum BridgeMethods { ), fixedCost(10000L), (BridgeMethodExecutorTyped) Bridge::getFederationCreationBlockNumber, - true + fixedPermission(true) ), GET_FEDERATION_CREATION_TIME( CallTransaction.Function.fromSignature( @@ -210,7 +210,7 @@ public enum BridgeMethods { ), fixedCost(10000L), (BridgeMethodExecutorTyped) Bridge::getFederationCreationTime, - true + fixedPermission(true) ), GET_FEDERATION_SIZE( CallTransaction.Function.fromSignature( @@ -220,7 +220,7 @@ public enum BridgeMethods { ), fixedCost(10000L), (BridgeMethodExecutorTyped) Bridge::getFederationSize, - true + fixedPermission(true) ), GET_FEDERATION_THRESHOLD( CallTransaction.Function.fromSignature( @@ -230,7 +230,7 @@ public enum BridgeMethods { ), fixedCost(11000L), (BridgeMethodExecutorTyped) Bridge::getFederationThreshold, - true + fixedPermission(true) ), GET_FEDERATOR_PUBLIC_KEY( CallTransaction.Function.fromSignature( @@ -241,7 +241,7 @@ public enum BridgeMethods { fixedCost(10000L), (BridgeMethodExecutorTyped) Bridge::getFederatorPublicKey, activations -> !activations.isActive(RSKIP123), - true + fixedPermission(true) ), GET_FEDERATOR_PUBLIC_KEY_OF_TYPE( CallTransaction.Function.fromSignature( @@ -252,7 +252,7 @@ public enum BridgeMethods { fixedCost(10000L), (BridgeMethodExecutorTyped) Bridge::getFederatorPublicKeyOfType, activations -> activations.isActive(RSKIP123), - true + fixedPermission(true) ), GET_FEE_PER_KB( CallTransaction.Function.fromSignature( @@ -262,7 +262,7 @@ public enum BridgeMethods { ), fixedCost(2000L), (BridgeMethodExecutorTyped) Bridge::getFeePerKb, - true + fixedPermission(true) ), GET_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( @@ -272,7 +272,7 @@ public enum BridgeMethods { ), fixedCost(16000L), (BridgeMethodExecutorTyped) Bridge::getLockWhitelistAddress, - true + fixedPermission(true) ), GET_LOCK_WHITELIST_ENTRY_BY_ADDRESS( CallTransaction.Function.fromSignature( @@ -283,7 +283,7 @@ public enum BridgeMethods { fixedCost(16000L), (BridgeMethodExecutorTyped) Bridge::getLockWhitelistEntryByAddress, activations -> activations.isActive(RSKIP87), - true + fixedPermission(true) ), GET_LOCK_WHITELIST_SIZE( CallTransaction.Function.fromSignature( @@ -293,7 +293,7 @@ public enum BridgeMethods { ), fixedCost(16000L), (BridgeMethodExecutorTyped) Bridge::getLockWhitelistSize, - true + fixedPermission(true) ), GET_MINIMUM_LOCK_TX_VALUE( CallTransaction.Function.fromSignature( @@ -303,7 +303,7 @@ public enum BridgeMethods { ), fixedCost(2000L), (BridgeMethodExecutorTyped) Bridge::getMinimumLockTxValue, - true + fixedPermission(true) ), GET_PENDING_FEDERATION_HASH( CallTransaction.Function.fromSignature( @@ -313,7 +313,7 @@ public enum BridgeMethods { ), fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getPendingFederationHash, - true + fixedPermission(true) ), GET_PENDING_FEDERATION_SIZE( CallTransaction.Function.fromSignature( @@ -323,7 +323,7 @@ public enum BridgeMethods { ), fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getPendingFederationSize, - true + fixedPermission(true) ), GET_PENDING_FEDERATOR_PUBLIC_KEY( CallTransaction.Function.fromSignature( @@ -334,7 +334,7 @@ public enum BridgeMethods { fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getPendingFederatorPublicKey, activations -> !activations.isActive(RSKIP123), - true + fixedPermission(true) ), GET_PENDING_FEDERATOR_PUBLIC_KEY_OF_TYPE( CallTransaction.Function.fromSignature( @@ -345,7 +345,7 @@ public enum BridgeMethods { fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getPendingFederatorPublicKeyOfType, activations -> activations.isActive(RSKIP123), - true + fixedPermission(true) ), GET_RETIRING_FEDERATION_ADDRESS( CallTransaction.Function.fromSignature( @@ -355,7 +355,7 @@ public enum BridgeMethods { ), fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getRetiringFederationAddress, - true + fixedPermission(true) ), GET_RETIRING_FEDERATION_CREATION_BLOCK_NUMBER( CallTransaction.Function.fromSignature( @@ -365,7 +365,7 @@ public enum BridgeMethods { ), fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getRetiringFederationCreationBlockNumber, - true + fixedPermission(true) ), GET_RETIRING_FEDERATION_CREATION_TIME( CallTransaction.Function.fromSignature( @@ -375,7 +375,7 @@ public enum BridgeMethods { ), fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getRetiringFederationCreationTime, - true + fixedPermission(true) ), GET_RETIRING_FEDERATION_SIZE( CallTransaction.Function.fromSignature( @@ -385,7 +385,7 @@ public enum BridgeMethods { ), fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getRetiringFederationSize, - true + fixedPermission(true) ), GET_RETIRING_FEDERATION_THRESHOLD( CallTransaction.Function.fromSignature( @@ -395,7 +395,7 @@ public enum BridgeMethods { ), fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getRetiringFederationThreshold, - true + fixedPermission(true) ), GET_RETIRING_FEDERATOR_PUBLIC_KEY( CallTransaction.Function.fromSignature( @@ -406,7 +406,7 @@ public enum BridgeMethods { fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getRetiringFederatorPublicKey, activations -> !activations.isActive(RSKIP123), - true + fixedPermission(true) ), GET_RETIRING_FEDERATOR_PUBLIC_KEY_OF_TYPE( CallTransaction.Function.fromSignature( @@ -417,7 +417,7 @@ public enum BridgeMethods { fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getRetiringFederatorPublicKeyOfType, activations -> activations.isActive(RSKIP123), - true + fixedPermission(true) ), GET_STATE_FOR_BTC_RELEASE_CLIENT( CallTransaction.Function.fromSignature( @@ -427,7 +427,7 @@ public enum BridgeMethods { ), fixedCost(4000L), (BridgeMethodExecutorTyped) Bridge::getStateForBtcReleaseClient, - true + fixedPermission(true) ), GET_STATE_FOR_DEBUGGING( CallTransaction.Function.fromSignature( @@ -437,7 +437,7 @@ public enum BridgeMethods { ), fixedCost(3_000_000L), (BridgeMethodExecutorTyped) Bridge::getStateForDebugging, - true + fixedPermission(true) ), GET_LOCKING_CAP( CallTransaction.Function.fromSignature( @@ -448,7 +448,7 @@ public enum BridgeMethods { fixedCost(3_000L), (BridgeMethodExecutorTyped) Bridge::getLockingCap, activations -> activations.isActive(RSKIP134), - true + fixedPermission(true) ), GET_ACTIVE_FEDERATION_CREATION_BLOCK_HEIGHT( CallTransaction.Function.fromSignature( @@ -459,7 +459,7 @@ public enum BridgeMethods { fixedCost(3_000L), (BridgeMethodExecutorTyped) Bridge::getActiveFederationCreationBlockHeight, activations -> activations.isActive(RSKIP186), - false + fixedPermission(false) ), INCREASE_LOCKING_CAP( CallTransaction.Function.fromSignature( @@ -470,7 +470,7 @@ public enum BridgeMethods { fixedCost(8_000L), (BridgeMethodExecutorTyped) Bridge::increaseLockingCap, activations -> activations.isActive(RSKIP134), - false + fixedPermission(false) ), IS_BTC_TX_HASH_ALREADY_PROCESSED( CallTransaction.Function.fromSignature( @@ -480,7 +480,7 @@ public enum BridgeMethods { ), fixedCost(23000L), (BridgeMethodExecutorTyped) Bridge::isBtcTxHashAlreadyProcessed, - true + fixedPermission(true) ), RECEIVE_HEADERS( CallTransaction.Function.fromSignature( @@ -494,7 +494,7 @@ public enum BridgeMethods { (BridgeMethodExecutorVoid) Bridge::receiveHeaders, Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::receiveHeaders, "receiveHeaders") ), - false + fixedPermission(false) ), RECEIVE_HEADER( CallTransaction.Function.fromSignature( @@ -505,7 +505,7 @@ public enum BridgeMethods { fixedCost(22_000L), // TODO: calculate gas cost. (BridgeMethodExecutorTyped) Bridge::receiveHeader, activations -> activations.isActive(RSKIP200), - false + fixedPermission(false) ), REGISTER_BTC_TRANSACTION( CallTransaction.Function.fromSignature( @@ -519,7 +519,7 @@ public enum BridgeMethods { (BridgeMethodExecutorVoid) Bridge::registerBtcTransaction, Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::registerBtcTransaction, "registerBtcTransaction") ), - false + fixedPermission(false) ), RELEASE_BTC( CallTransaction.Function.fromSignature( @@ -529,7 +529,7 @@ public enum BridgeMethods { ), fixedCost(23000L), (BridgeMethodExecutorVoid) Bridge::releaseBtc, - false + fixedPermission(false) ), REMOVE_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( @@ -539,7 +539,7 @@ public enum BridgeMethods { ), fixedCost(24000L), (BridgeMethodExecutorTyped) Bridge::removeLockWhitelistAddress, - false + fixedPermission(false) ), ROLLBACK_FEDERATION( CallTransaction.Function.fromSignature( @@ -549,7 +549,7 @@ public enum BridgeMethods { ), fixedCost(12000L), (BridgeMethodExecutorTyped) Bridge::rollbackFederation, - false + fixedPermission(false) ), SET_LOCK_WHITELIST_DISABLE_BLOCK_DELAY( CallTransaction.Function.fromSignature( @@ -559,7 +559,7 @@ public enum BridgeMethods { ), fixedCost(24000L), (BridgeMethodExecutorTyped) Bridge::setLockWhitelistDisableBlockDelay, - false + fixedPermission(false) ), UPDATE_COLLECTIONS( CallTransaction.Function.fromSignature( @@ -569,7 +569,7 @@ public enum BridgeMethods { ), fixedCost(48000L), Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::updateCollections, "updateCollections"), - false + fixedPermission(false) ), VOTE_FEE_PER_KB( CallTransaction.Function.fromSignature( @@ -579,7 +579,7 @@ public enum BridgeMethods { ), fixedCost(10000L), (BridgeMethodExecutorTyped) Bridge::voteFeePerKbChange, - false + fixedPermission(false) ), REGISTER_BTC_COINBASE_TRANSACTION( CallTransaction.Function.fromSignature( @@ -590,7 +590,7 @@ public enum BridgeMethods { fixedCost(10000L), (BridgeMethodExecutorVoid) Bridge::registerBtcCoinbaseTransaction, activations -> activations.isActive(RSKIP143), - false + fixedPermission(false) ), HAS_BTC_BLOCK_COINBASE_TRANSACTION_INFORMATION( CallTransaction.Function.fromSignature( @@ -601,7 +601,7 @@ public enum BridgeMethods { fixedCost(5000L), (BridgeMethodExecutorTyped) Bridge::hasBtcBlockCoinbaseTransactionInformation, activations -> activations.isActive(RSKIP143), - false + fixedPermission(false) ), REGISTER_FAST_BRIDGE_BTC_TRANSACTION( CallTransaction.Function.fromSignature( @@ -612,7 +612,7 @@ public enum BridgeMethods { fixedCost(10000L), // TODO: Define a cost (BridgeMethodExecutorTyped) Bridge::registerFastBridgeBtcTransaction, activations -> activations.isActive(RSKIP176), - false + fixedPermission(false) ), GET_BTC_BLOCKCHAIN_BEST_BLOCK_HEADER( CallTransaction.Function.fromSignature( @@ -623,7 +623,7 @@ public enum BridgeMethods { fixedCost(20000L), // TODO: calculate gas cost (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBestBlockHeader, activations -> activations.isActive(RSKIP220), - false + fixedPermission(false) ), GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT_2( CallTransaction.Function.fromSignature( @@ -634,7 +634,7 @@ public enum BridgeMethods { fixedCost(20000L), // TODO: calculate gas cost (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBestChainHeight, activations -> activations.isActive(RSKIP220), - false + fixedPermission(false) ), GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HASH( CallTransaction.Function.fromSignature( @@ -645,7 +645,7 @@ public enum BridgeMethods { fixedCost(20000L), // TODO: calculate gas cost (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHeaderByHash, activations -> activations.isActive(RSKIP220), - false + fixedPermission(false) ), GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HEIGHT( CallTransaction.Function.fromSignature( @@ -656,7 +656,7 @@ public enum BridgeMethods { fixedCost(20000L), // TODO: calculate gas cost (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHeaderByHeight, activations -> activations.isActive(RSKIP220), - false + fixedPermission(false) ), GET_BTC_BLOCKCHAIN_PARENT_BLOCK_HEADER_BY_HASH( CallTransaction.Function.fromSignature( @@ -667,22 +667,22 @@ public enum BridgeMethods { fixedCost(20000L), // TODO: calculate gas cost (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainParentBlockHeaderByHash, activations -> activations.isActive(RSKIP220), - false + fixedPermission(false) ); private final CallTransaction.Function function; private final CostProvider costProvider; private final Function isEnabledFunction; private final BridgeMethodExecutor executor; - private final boolean onlyAllowsLocalCalls; + private final CallPermissionProvider callPermissionProvider; BridgeMethods( CallTransaction.Function function, CostProvider costProvider, BridgeMethodExecutor executor, - boolean onlyAllowsLocalCalls) { + CallPermissionProvider callPermissionProvider) { - this(function, costProvider, executor, activations -> Boolean.TRUE, onlyAllowsLocalCalls); + this(function, costProvider, executor, activations -> Boolean.TRUE, callPermissionProvider); } BridgeMethods( @@ -690,13 +690,13 @@ public enum BridgeMethods { CostProvider costProvider, BridgeMethodExecutor executor, Function isEnabled, - boolean onlyAllowsLocalCalls) { + CallPermissionProvider callPermissionProvider) { this.function = function; this.costProvider = costProvider; this.executor = executor; this.isEnabledFunction = isEnabled; - this.onlyAllowsLocalCalls = onlyAllowsLocalCalls; + this.callPermissionProvider = callPermissionProvider; } public static Optional findBySignature(byte[] encoding) { @@ -706,6 +706,7 @@ public static Optional findBySignature(byte[] encoding) { public CallTransaction.Function getFunction() { return function; } + public Boolean isEnabled(ActivationConfig.ForBlock activations) { return this.isEnabledFunction.apply(activations); } @@ -718,8 +719,8 @@ public BridgeMethodExecutor getExecutor() { return executor; } - public boolean onlyAllowsLocalCalls() { - return onlyAllowsLocalCalls; + public boolean onlyAllowsLocalCalls(Bridge bridge, ActivationConfig.ForBlock config, Object[] args) { + return callPermissionProvider.getOnlyAllowLocalCallsPermission(bridge, config, args); } public interface BridgeCondition { From d85c8e0d181e2ee6d0a627894e0cd734d5398455 Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 9 Apr 2021 11:02:04 -0300 Subject: [PATCH 33/34] Modify getBtcBlockchainBestChainHeight to allow only local calls depending on RSKIP220 activation --- .../src/main/java/co/rsk/peg/Bridge.java | 71 ++- .../main/java/co/rsk/peg/BridgeMethods.java | 13 +- .../src/test/java/co/rsk/peg/BridgeTest.java | 20 + .../java/co/rsk/peg/BridgeTestPowerMock.java | 440 ++++++++++-------- 4 files changed, 287 insertions(+), 257 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 17e141b4ffd..e924c80ad76 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -32,6 +32,7 @@ import com.google.common.annotations.VisibleForTesting; import org.ethereum.config.Constants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ActivationConfig.ForBlock; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.Block; import org.ethereum.core.CallTransaction; @@ -568,6 +569,10 @@ public Integer getBtcBlockchainBestChainHeight(Object[] args) throws VMException } } + public boolean getBtcBlockchainBestChainHeightOnlyAllowsLocalCalls(Object[] args) { + return !activations.isActive(ConsensusRule.RSKIP220); + } + public Integer getBtcBlockchainInitialBlockHeight(Object[] args) throws VMException { logger.trace("getBtcBlockchainInitialBlockHeight"); @@ -643,8 +648,7 @@ public int getBtcTransactionConfirmations(Object[] args) throws VMException { } } - public Long getMinimumLockTxValue(Object[] args) - { + public Long getMinimumLockTxValue(Object[] args) { logger.trace("getMinimumLockTxValue"); return bridgeSupport.getMinimumLockTxValue().getValue(); } @@ -673,29 +677,25 @@ public Long getBtcTxHashProcessedHeight(Object[] args) throws VMException { } } - public String getFederationAddress(Object[] args) - { + public String getFederationAddress(Object[] args) { logger.trace("getFederationAddress"); return bridgeSupport.getFederationAddress().toBase58(); } - public Integer getFederationSize(Object[] args) - { + public Integer getFederationSize(Object[] args) { logger.trace("getFederationSize"); return bridgeSupport.getFederationSize(); } - public Integer getFederationThreshold(Object[] args) - { + public Integer getFederationThreshold(Object[] args) { logger.trace("getFederationThreshold"); return bridgeSupport.getFederationThreshold(); } - public byte[] getFederatorPublicKey(Object[] args) - { + public byte[] getFederatorPublicKey(Object[] args) { logger.trace("getFederatorPublicKey"); int index = ((BigInteger) args[0]).intValue(); @@ -718,8 +718,7 @@ public byte[] getFederatorPublicKeyOfType(Object[] args) throws VMException { return bridgeSupport.getFederatorPublicKeyOfType(index, keyType); } - public Long getFederationCreationTime(Object[] args) - { + public Long getFederationCreationTime(Object[] args) { logger.trace("getFederationCreationTime"); // Return the creation time in milliseconds from the epoch @@ -731,8 +730,7 @@ public long getFederationCreationBlockNumber(Object[] args) { return bridgeSupport.getFederationCreationBlockNumber(); } - public String getRetiringFederationAddress(Object[] args) - { + public String getRetiringFederationAddress(Object[] args) { logger.trace("getRetiringFederationAddress"); Address address = bridgeSupport.getRetiringFederationAddress(); @@ -745,22 +743,19 @@ public String getRetiringFederationAddress(Object[] args) return address.toBase58(); } - public Integer getRetiringFederationSize(Object[] args) - { + public Integer getRetiringFederationSize(Object[] args) { logger.trace("getRetiringFederationSize"); return bridgeSupport.getRetiringFederationSize(); } - public Integer getRetiringFederationThreshold(Object[] args) - { + public Integer getRetiringFederationThreshold(Object[] args) { logger.trace("getRetiringFederationThreshold"); return bridgeSupport.getRetiringFederationThreshold(); } - public byte[] getRetiringFederatorPublicKey(Object[] args) - { + public byte[] getRetiringFederatorPublicKey(Object[] args) { logger.trace("getRetiringFederatorPublicKey"); int index = ((BigInteger) args[0]).intValue(); @@ -797,8 +792,7 @@ public byte[] getRetiringFederatorPublicKeyOfType(Object[] args) throws VMExcept return publicKey; } - public Long getRetiringFederationCreationTime(Object[] args) - { + public Long getRetiringFederationCreationTime(Object[] args) { logger.trace("getRetiringFederationCreationTime"); Instant creationTime = bridgeSupport.getRetiringFederationCreationTime(); @@ -882,8 +876,7 @@ public Integer rollbackFederation(Object[] args) throws BridgeIllegalArgumentExc ); } - public byte[] getPendingFederationHash(Object[] args) - { + public byte[] getPendingFederationHash(Object[] args) { logger.trace("getPendingFederationHash"); byte[] hash = bridgeSupport.getPendingFederationHash(); @@ -896,15 +889,13 @@ public byte[] getPendingFederationHash(Object[] args) return hash; } - public Integer getPendingFederationSize(Object[] args) - { + public Integer getPendingFederationSize(Object[] args) { logger.trace("getPendingFederationSize"); return bridgeSupport.getPendingFederationSize(); } - public byte[] getPendingFederatorPublicKey(Object[] args) - { + public byte[] getPendingFederatorPublicKey(Object[] args) { logger.trace("getPendingFederatorPublicKey"); int index = ((BigInteger) args[0]).intValue(); @@ -941,15 +932,13 @@ public byte[] getPendingFederatorPublicKeyOfType(Object[] args) throws VMExcepti return publicKey; } - public Integer getLockWhitelistSize(Object[] args) - { + public Integer getLockWhitelistSize(Object[] args) { logger.trace("getLockWhitelistSize"); return bridgeSupport.getLockWhitelistSize(); } - public String getLockWhitelistAddress(Object[] args) - { + public String getLockWhitelistAddress(Object[] args) { logger.trace("getLockWhitelistAddress"); int index = ((BigInteger) args[0]).intValue(); @@ -963,8 +952,7 @@ public String getLockWhitelistAddress(Object[] args) return entry.address().toBase58(); } - public long getLockWhitelistEntryByAddress(Object[] args) - { + public long getLockWhitelistEntryByAddress(Object[] args) { logger.trace("getLockWhitelistEntryByAddress"); String addressBase58; @@ -987,8 +975,7 @@ public long getLockWhitelistEntryByAddress(Object[] args) LOCK_WHITELIST_UNLIMITED_MODE_CODE; } - public Integer addOneOffLockWhitelistAddress(Object[] args) - { + public Integer addOneOffLockWhitelistAddress(Object[] args) { logger.trace("addOneOffLockWhitelistAddress"); String addressBase58; @@ -1004,8 +991,7 @@ public Integer addOneOffLockWhitelistAddress(Object[] args) return bridgeSupport.addOneOffLockWhitelistAddress(rskTx, addressBase58, maxTransferValue); } - public Integer addUnlimitedLockWhitelistAddress(Object[] args) - { + public Integer addUnlimitedLockWhitelistAddress(Object[] args) { logger.trace("addUnlimitedLockWhitelistAddress"); String addressBase58; @@ -1019,8 +1005,7 @@ public Integer addUnlimitedLockWhitelistAddress(Object[] args) return bridgeSupport.addUnlimitedLockWhitelistAddress(rskTx, addressBase58); } - public Integer removeLockWhitelistAddress(Object[] args) - { + public Integer removeLockWhitelistAddress(Object[] args) { logger.trace("removeLockWhitelistAddress"); String addressBase58; @@ -1040,8 +1025,7 @@ public Integer setLockWhitelistDisableBlockDelay(Object[] args) throws IOExcepti return bridgeSupport.setLockWhitelistDisableBlockDelay(rskTx, lockWhitelistDisableBlockDelay); } - public Integer voteFeePerKbChange(Object[] args) - { + public Integer voteFeePerKbChange(Object[] args) { logger.trace("voteFeePerKbChange"); Coin feePerKb; @@ -1055,8 +1039,7 @@ public Integer voteFeePerKbChange(Object[] args) return bridgeSupport.voteFeePerKbChange(rskTx, feePerKb); } - public long getFeePerKb(Object[] args) - { + public long getFeePerKb(Object[] args) { logger.trace("getFeePerKb"); return bridgeSupport.getFeePerKb().getValue(); diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 99686a71d66..0340492b480 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -126,7 +126,7 @@ public enum BridgeMethods { ), fixedCost(19000L), (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBestChainHeight, - fixedPermission(true) + fromMethod(Bridge::getBtcBlockchainBestChainHeightOnlyAllowsLocalCalls) ), GET_BTC_BLOCKCHAIN_INITIAL_BLOCK_HEIGHT( CallTransaction.Function.fromSignature( @@ -625,17 +625,6 @@ public enum BridgeMethods { activations -> activations.isActive(RSKIP220), fixedPermission(false) ), - GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT_2( - CallTransaction.Function.fromSignature( - "getBtcBlockchainBestChainHeight2", - new String[0], - new String[]{"uint256"} - ), - fixedCost(20000L), // TODO: calculate gas cost - (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBestChainHeight, - activations -> activations.isActive(RSKIP220), - fixedPermission(false) - ), GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HASH( CallTransaction.Function.fromSignature( "getBtcBlockchainBlockHeaderByHash", diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index e44e1e257b3..71c63c03817 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -620,6 +620,26 @@ public void receiveHeaders_after_RSKIP200_header_wrong_size() throws VMException Assert.assertEquals(BigInteger.valueOf(-20), Bridge.RECEIVE_HEADER.decodeResult(result)[0]); } + @Test + public void getBtcBlockchainBestChainHeightOnlyAllowsLocalCalls_afterRskip220() { + ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); + doReturn(true).when(activations).isActive(eq(RSKIP220), anyLong()); + + Bridge bridge = getBridgeInstance(mock(BridgeSupport.class), activations); + + Assert.assertFalse(bridge.getBtcBlockchainBestChainHeightOnlyAllowsLocalCalls(new Object[0])); + } + + @Test + public void getBtcBlockchainBestChainHeightOnlyAllowsLocalCalls_beforeRskip220() { + ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); + doReturn(false).when(activations).isActive(eq(RSKIP220), anyLong()); + + Bridge bridge = getBridgeInstance(mock(BridgeSupport.class), activations); + + Assert.assertTrue(bridge.getBtcBlockchainBestChainHeightOnlyAllowsLocalCalls(new Object[0])); + } + /** * Gets a bride instance mocking the transaction and BridgeSupportFactory * @param bridgeSupportInstance Provide the bridgeSupport to be used diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTestPowerMock.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTestPowerMock.java index de10f6884a1..c136fc1ee1e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTestPowerMock.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTestPowerMock.java @@ -412,9 +412,14 @@ public void executeWithFunctionSignatureLengthTooShortAfterRskip88() { BridgeSupportFactory bridgeSupportFactory = new BridgeSupportFactory( new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()), bridgeConstants, - activationConfig); - Bridge bridge = new Bridge(PrecompiledContracts.BRIDGE_ADDR, constants, activationConfig, - bridgeSupportFactory); + activationConfig + ); + Bridge bridge = new Bridge( + PrecompiledContracts.BRIDGE_ADDR, + constants, + activationConfig, + bridgeSupportFactory + ); Transaction mockedTx = mock(Transaction.class); try { @@ -426,7 +431,6 @@ public void executeWithFunctionSignatureLengthTooShortAfterRskip88() { } } - @Test public void executeWithInexistentFunctionBeforeRskip88() throws VMException { BridgeSupportFactory bridgeSupportFactory = new BridgeSupportFactory( @@ -776,7 +780,6 @@ public byte[] bitcoinSerialize() { } - @Test public void registerBtcTransactionWithNonParseableTx() throws VMException { Repository repository = createRepository(); @@ -836,94 +839,6 @@ public void registerBtcTransactionWithHugeDeclaredWitnessPushSize() throws VMExc registerBtcTransactionWithHugeDeclaredSize(tx); } - private void registerBtcTransactionWithHugeDeclaredSize(BtcTransaction tx) throws VMException { - Repository repository = createRepository(); - Repository track = repository.startTracking(); - - Transaction rskTx = Transaction - .builder() - .nonce(NONCE) - .gasPrice(GAS_PRICE) - .gasLimit(GAS_LIMIT) - .destination(Hex.decode(PrecompiledContracts.BRIDGE_ADDR_STR)) - .data(Hex.decode(DATA)) - .chainId(Constants.REGTEST_CHAIN_ID) - .value(AMOUNT) - .build(); - rskTx.sign(fedECPrivateKey.getPrivKeyBytes()); - - BridgeSupportFactory bridgeSupportFactory = new BridgeSupportFactory( - new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()), - bridgeConstants, - activationConfig); - Bridge bridge = new Bridge(PrecompiledContracts.BRIDGE_ADDR, constants, activationConfig, - bridgeSupportFactory); - bridge.init(rskTx, getGenesisBlock(), track, null, null, null); - - byte[] serializedTx = tx.bitcoinSerialize(); - - byte[] data = Bridge.REGISTER_BTC_TRANSACTION.encode(serializedTx, 1, new byte[30]); - - Assert.assertNull(bridge.execute(data)); - } - - private static class HugeDeclaredSizeBtcTransaction extends BtcTransaction { - - private boolean hackInputsSize; - private boolean hackOutputsSize; - private boolean hackWitnessPushCountSize; - private boolean hackWitnessPushSize; - - public HugeDeclaredSizeBtcTransaction(NetworkParameters params, boolean hackInputsSize, boolean hackOutputsSize, boolean hackWitnessPushCountSize, boolean hackWitnessPushSize) { - super(params); - BtcTransaction inputTx = new BtcTransaction(params); - inputTx.addOutput(Coin.FIFTY_COINS, BtcECKey.fromPrivate(BigInteger.valueOf(123456)).toAddress(params)); - Address to = BtcECKey.fromPrivate(BigInteger.valueOf(1000)).toAddress(params); - this.addInput(inputTx.getOutput(0)); - this.getInput(0).disconnect(); - TransactionWitness witness = new TransactionWitness(1); - witness.setPush(0, new byte[] {0}); - this.setWitness(0, witness); - this.addOutput(Coin.COIN, to); - - this.hackInputsSize = hackInputsSize; - this.hackOutputsSize = hackOutputsSize; - this.hackWitnessPushCountSize = hackWitnessPushCountSize; - this.hackWitnessPushSize = hackWitnessPushSize; - } - - protected void bitcoinSerializeToStream(OutputStream stream, boolean serializeWitRequested) throws IOException { - boolean serializeWit = serializeWitRequested && hasWitness(); - uint32ToByteStreamLE(getVersion(), stream); - if (serializeWit) { - stream.write(new byte[]{0, 1}); - } - - long inputsSize = hackInputsSize ? Integer.MAX_VALUE : getInputs().size(); - stream.write(new VarInt(inputsSize).encode()); - for (TransactionInput in : getInputs()) - in.bitcoinSerialize(stream); - long outputsSize = hackOutputsSize ? Integer.MAX_VALUE : getOutputs().size(); - stream.write(new VarInt(outputsSize).encode()); - for (TransactionOutput out : getOutputs()) - out.bitcoinSerialize(stream); - if (serializeWit) { - for (int i = 0; i < getInputs().size(); i++) { - TransactionWitness witness = getWitness(i); - long pushCount = hackWitnessPushCountSize ? Integer.MAX_VALUE : witness.getPushCount(); - stream.write(new VarInt(pushCount).encode()); - for (int y = 0; y < witness.getPushCount(); y++) { - byte[] push = witness.getPush(y); - long pushLength = hackWitnessPushSize ? Integer.MAX_VALUE : push.length; - stream.write(new VarInt(pushLength).encode()); - stream.write(push); - } - } - } - uint32ToByteStreamLE(getLockTime(), stream); - } - }; - @Test public void registerBtcTransactionWithNonParseableMerkleeProof1() throws Exception{ Repository repository = createRepository(); @@ -1394,10 +1309,6 @@ public void getBtcBlockchainBlockLocatorAfterRskip88And89Fork() { } } - private BtcTransaction createTransaction() { - return new SimpleBtcTransaction(networkParameters, PegTestUtils.createHash()); - } - @Test public void getGasForDataFreeTx() { activationConfig = ActivationConfigsForTest.bridgeUnitTest(); @@ -1457,6 +1368,7 @@ public void getGasForDataReleaseBtc() { public void getGasForDataAddSignature() { getGasForDataPaidTx(70000 + 548*2, Bridge.ADD_SIGNATURE, new byte[3], new byte[3][2], new byte[3]); } + @Test public void getGasForDataGSFBRC() { getGasForDataPaidTx(4000 + 8, Bridge.GET_STATE_FOR_BTC_RELEASE_CLIENT); @@ -1487,54 +1399,6 @@ public void getGasForDataGetMinimumLockTxValue() { getGasForDataPaidTx(2000 + 8, Bridge.GET_MINIMUM_LOCK_TX_VALUE); } - private void getGasForDataPaidTx(int expected, CallTransaction.Function function, Object... funcArgs) { - activationConfig = ActivationConfigsForTest.bridgeUnitTest(); - - BridgeSupportFactory bridgeSupportFactory = new BridgeSupportFactory( - new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()), - bridgeConstants, - activationConfig); - Bridge bridge = new Bridge(PrecompiledContracts.BRIDGE_ADDR, constants, activationConfig, - bridgeSupportFactory); - org.ethereum.core.Transaction rskTx; - if (function==null) { - rskTx = CallTransaction.createRawTransaction( - 0, - 1, - 1, - PrecompiledContracts.BRIDGE_ADDR, - 0, - new byte[]{1,2,3}, - Constants.REGTEST_CHAIN_ID - ); - } else { - rskTx = CallTransaction.createCallTransaction( - 0, - 1, - 1, - PrecompiledContracts.BRIDGE_ADDR, - 0, - function, - Constants.REGTEST_CHAIN_ID, - funcArgs - ); - } - - rskTx.sign(BridgeRegTestConstants.REGTEST_FEDERATION_PRIVATE_KEYS.get(0).getPrivKeyBytes()); - - BlockGenerator blockGenerator = new BlockGenerator(); - Block rskExecutionBlock = blockGenerator.createChildBlock(getGenesisInstance(config)); - for (int i = 0; i < 20; i++) { - rskExecutionBlock = blockGenerator.createChildBlock(rskExecutionBlock); - } - - Repository mockRepository = mock(Repository.class); - when(mockRepository.getCode(any(RskAddress.class))).thenReturn(null); - - bridge.init(rskTx, rskExecutionBlock, mockRepository, null, null, null); - Assert.assertEquals(expected, bridge.getGasForData(rskTx.getData())); - } - @Test public void isBtcTxHashAlreadyProcessed_normalFlow() throws IOException, VMException { BridgeSupportFactory bridgeSupportFactory = new BridgeSupportFactory( @@ -1678,7 +1542,7 @@ public void getFederationCreationTime() { } @Test - public void getFederationCreationBlockNumber() throws IOException { + public void getFederationCreationBlockNumber() { Bridge bridge = new Bridge(PrecompiledContracts.BRIDGE_ADDR, constants, activationConfig, null); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Whitebox.setInternalState(bridge, "bridgeSupport", bridgeSupportMock); @@ -2074,7 +1938,7 @@ public void getPendingFederatorPublicKeyOfType_afterMultikey() throws Exception } @Test - public void createFederation() throws IOException, BridgeIllegalArgumentException { + public void createFederation() throws BridgeIllegalArgumentException { Transaction txMock = mock(Transaction.class); BridgeSupportFactory bridgeSupportFactory = new BridgeSupportFactory( new RepositoryBtcBlockStoreWithCache.Factory(constants.getBridgeConstants().getBtcParams()), @@ -2354,7 +2218,7 @@ public void getLockWhitelistEntryByAddressAfterRskip87Fork() throws Exception { } @Test - public void addLockWhitelistAddressBeforeRskip87Fork() throws IOException, VMException { + public void addLockWhitelistAddressBeforeRskip87Fork() throws VMException { doReturn(false).when(activationConfig).isActive(eq(RSKIP87), anyLong()); doReturn(false).when(activationConfig).isActive(eq(RSKIP88), anyLong()); @@ -2412,7 +2276,7 @@ public void addLockWhitelistAddressAfterRskip87And88Fork() { } @Test - public void addOneOffLockWhitelistAddressBeforeRskip87And88Fork() throws IOException, VMException { + public void addOneOffLockWhitelistAddressBeforeRskip87And88Fork() throws VMException { doReturn(false).when(activationConfig).isActive(eq(RSKIP87), anyLong()); doReturn(false).when(activationConfig).isActive(eq(RSKIP88), anyLong()); @@ -2546,7 +2410,7 @@ public void getFeePerKb() { } @Test - public void voteFeePerKb_ok() throws IOException { + public void voteFeePerKb_ok() { Transaction txMock = mock(Transaction.class); BridgeSupportFactory bridgeSupportFactory = new BridgeSupportFactory( new RepositoryBtcBlockStoreWithCache.Factory(constants.getBridgeConstants().getBtcParams()), @@ -2681,7 +2545,7 @@ public void executeMethodWithOnlyLocalCallsAllowed_nonLocalCallTx_beforeOrchid() } @Test - public void executeMethodWithOnlyLocalCallsAllowed_nonLocalCallTx() throws Exception { + public void executeMethodWithOnlyLocalCallsAllowed_nonLocalCallTx() { doReturn(false).when(activationConfig).isActive(eq(RSKIP87), anyLong()); doReturn(true).when(activationConfig).isActive(eq(RSKIP88), anyLong()); @@ -2716,48 +2580,6 @@ public void executeMethodWithAnyCallsAllowed_nonLocalCallTx() throws Exception { executeAndCheckMethodWithAnyCallsAllowed(false); } - private void executeAndCheckMethodWithAnyCallsAllowed(boolean localCall) throws Exception { - Transaction tx = mock(Transaction.class); - when(tx.isLocalCallTransaction()).thenReturn(localCall); - - BridgeSupportFactory bridgeSupportFactoryMock = mock(BridgeSupportFactory.class); - - Bridge bridge = new Bridge(PrecompiledContracts.BRIDGE_ADDR, constants, activationConfig, - bridgeSupportFactoryMock); - - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - when(bridgeSupportFactoryMock.newInstance(any(), any(), any(), any())).thenReturn(bridgeSupportMock); - when(bridgeSupportMock.voteFeePerKbChange(tx, Coin.CENT)).thenReturn(1); - - bridge.init(tx, getGenesisBlock(), null, null, null, null); - - byte[] data = BridgeMethods.VOTE_FEE_PER_KB.getFunction().encode(new Object[]{ Coin.CENT.longValue() }); - bridge.execute(data); - - verify(bridgeSupportMock, times(1)).voteFeePerKbChange(tx, Coin.CENT); - } - - // We need reflection to mock static final fields - private void setFinalStatic(Field field, Object newValue) throws Exception { - field.setAccessible(true); - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); - field.set(null, newValue); - } - - public void getBtcBlockchainInitialBlockHeight() throws IOException, VMException { - Bridge bridge = new Bridge(PrecompiledContracts.BRIDGE_ADDR, constants, activationConfig, - null); - bridge.init(null, getGenesisBlock(), null, null, null, null); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Whitebox.setInternalState(bridge, "bridgeSupport", bridgeSupportMock); - when(bridgeSupportMock.getBtcBlockchainInitialBlockHeight()).thenReturn(1234); - - Assert.assertEquals(1234, bridge.getBtcBlockchainInitialBlockHeight(new Object[]{}).intValue()); - } - @Test public void getBtcTransactionConfirmationsBeforeWasabi() throws Exception { doReturn(false).when(activationConfig).isActive(eq(RSKIP122), anyLong()); @@ -3016,10 +2838,6 @@ public void getBtcBlockchainBlockHashAtDepth() throws BlockStoreException, IOExc Assert.assertEquals(mockedResult, Sha256Hash.wrap(bridge.getBtcBlockchainBlockHashAtDepth(new Object[]{BigInteger.valueOf(555)}))); } - private Block getGenesisBlock() { - return new BlockGenerator().getGenesisBlock(); - } - @Test public void testCallFromContract_beforeOrchid() { // GenesisConfig mockedConfig = spy(new GenesisConfig()); @@ -3113,12 +2931,13 @@ public void testCallFromContract_afterOrchid() { @Test public void localCallOnlyMethodsDefinition() { + Bridge bridge = new Bridge(PrecompiledContracts.BRIDGE_ADDR, constants, activationConfig, null); + // To force initialization String foo = Bridge.UPDATE_COLLECTIONS.name; // Actual tests Arrays.asList( - BridgeMethods.GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT, BridgeMethods.GET_BTC_BLOCKCHAIN_INITIAL_BLOCK_HEIGHT, BridgeMethods.GET_BTC_BLOCKCHAIN_BLOCK_LOCATOR, BridgeMethods.GET_BTC_BLOCKCHAIN_BLOCK_HASH_AT_DEPTH, @@ -3147,12 +2966,14 @@ public void localCallOnlyMethodsDefinition() { BridgeMethods.GET_STATE_FOR_DEBUGGING, BridgeMethods.IS_BTC_TX_HASH_ALREADY_PROCESSED ).stream().forEach(m -> { - Assert.assertTrue(m.onlyAllowsLocalCalls()); + Assert.assertTrue(m.onlyAllowsLocalCalls(bridge, activationConfigAll, new Object[0])); }); } @Test public void mineableMethodsDefinition() { + Bridge bridge = new Bridge(PrecompiledContracts.BRIDGE_ADDR, constants, activationConfig, null); + // To force initialization String foo = Bridge.UPDATE_COLLECTIONS.name; @@ -3175,10 +2996,30 @@ public void mineableMethodsDefinition() { BridgeMethods.VOTE_FEE_PER_KB, BridgeMethods.GET_ACTIVE_FEDERATION_CREATION_BLOCK_HEIGHT ).stream().forEach(m -> { - Assert.assertFalse(m.onlyAllowsLocalCalls()); + Assert.assertFalse(m.onlyAllowsLocalCalls(bridge, activationConfigAll, new Object[0])); }); } + @Test + public void getBtcBlockchainBestChainHeight_beforeRskip220_isMineable() { + ActivationConfig.ForBlock activationsMock = mock(ActivationConfig.ForBlock.class); + when(activationsMock.isActive(RSKIP220)).thenReturn(true); + + Bridge bridge = getBridgeInstance(activationsMock); + + Assert.assertFalse(BridgeMethods.GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT.onlyAllowsLocalCalls(bridge, activationsMock, new Object[0])); + } + + @Test + public void getBtcBlockchainBestChainHeight_afterRskip220_onlyAllowsLocalCalls() { + ActivationConfig.ForBlock activationsMock = mock(ActivationConfig.ForBlock.class); + when(activationsMock.isActive(RSKIP220)).thenReturn(false); + + Bridge bridge = getBridgeInstance(activationsMock); + + Assert.assertTrue(BridgeMethods.GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT.onlyAllowsLocalCalls(bridge, activationsMock, new Object[0])); + } + @Test public void receiveHeadersGasCost_beforeDynamicCost() { doReturn(false).when(activationConfig).isActive(eq(RSKIP124), anyLong()); @@ -3200,7 +3041,7 @@ public void receiveHeadersGasCost_beforeDynamicCost() { } @Test - public void receiveHeadersGasCost_afterDynamicCost() throws Exception { + public void receiveHeadersGasCost_afterDynamicCost() { doReturn(true).when(activationConfig).isActive(eq(RSKIP124), anyLong()); Transaction txMock = mock(Transaction.class); @@ -3346,4 +3187,201 @@ public static Genesis getGenesisInstance(RskSystemProperties config) { TrieStore trieStore = new TrieStoreImpl(new HashMapDB()); return new TestGenesisLoader(trieStore, config.genesisInfo(), config.getNetworkConstants().getInitialNonce(), false, false, false).load(); } + + private void executeAndCheckMethodWithAnyCallsAllowed(boolean localCall) throws Exception { + Transaction tx = mock(Transaction.class); + when(tx.isLocalCallTransaction()).thenReturn(localCall); + + BridgeSupportFactory bridgeSupportFactoryMock = mock(BridgeSupportFactory.class); + + Bridge bridge = new Bridge(PrecompiledContracts.BRIDGE_ADDR, constants, activationConfig, + bridgeSupportFactoryMock); + + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportFactoryMock.newInstance(any(), any(), any(), any())).thenReturn(bridgeSupportMock); + when(bridgeSupportMock.voteFeePerKbChange(tx, Coin.CENT)).thenReturn(1); + + bridge.init(tx, getGenesisBlock(), null, null, null, null); + + byte[] data = BridgeMethods.VOTE_FEE_PER_KB.getFunction().encode(new Object[]{ Coin.CENT.longValue() }); + bridge.execute(data); + + verify(bridgeSupportMock, times(1)).voteFeePerKbChange(tx, Coin.CENT); + } + + // We need reflection to mock static final fields + private void setFinalStatic(Field field, Object newValue) throws Exception { + field.setAccessible(true); + Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); + field.set(null, newValue); + } + + public void getBtcBlockchainInitialBlockHeight() throws IOException, VMException { + Bridge bridge = new Bridge(PrecompiledContracts.BRIDGE_ADDR, constants, activationConfig, + null); + bridge.init(null, getGenesisBlock(), null, null, null, null); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Whitebox.setInternalState(bridge, "bridgeSupport", bridgeSupportMock); + when(bridgeSupportMock.getBtcBlockchainInitialBlockHeight()).thenReturn(1234); + + Assert.assertEquals(1234, bridge.getBtcBlockchainInitialBlockHeight(new Object[]{}).intValue()); + } + + private BtcTransaction createTransaction() { + return new SimpleBtcTransaction(networkParameters, PegTestUtils.createHash()); + } + + private Block getGenesisBlock() { + return new BlockGenerator().getGenesisBlock(); + } + + private void getGasForDataPaidTx(int expected, CallTransaction.Function function, Object... funcArgs) { + activationConfig = ActivationConfigsForTest.bridgeUnitTest(); + + BridgeSupportFactory bridgeSupportFactory = new BridgeSupportFactory( + new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()), + bridgeConstants, + activationConfig); + Bridge bridge = new Bridge(PrecompiledContracts.BRIDGE_ADDR, constants, activationConfig, + bridgeSupportFactory); + org.ethereum.core.Transaction rskTx; + if (function==null) { + rskTx = CallTransaction.createRawTransaction( + 0, + 1, + 1, + PrecompiledContracts.BRIDGE_ADDR, + 0, + new byte[]{1,2,3}, + Constants.REGTEST_CHAIN_ID + ); + } else { + rskTx = CallTransaction.createCallTransaction( + 0, + 1, + 1, + PrecompiledContracts.BRIDGE_ADDR, + 0, + function, + Constants.REGTEST_CHAIN_ID, + funcArgs + ); + } + + rskTx.sign(BridgeRegTestConstants.REGTEST_FEDERATION_PRIVATE_KEYS.get(0).getPrivKeyBytes()); + + BlockGenerator blockGenerator = new BlockGenerator(); + Block rskExecutionBlock = blockGenerator.createChildBlock(getGenesisInstance(config)); + for (int i = 0; i < 20; i++) { + rskExecutionBlock = blockGenerator.createChildBlock(rskExecutionBlock); + } + + Repository mockRepository = mock(Repository.class); + when(mockRepository.getCode(any(RskAddress.class))).thenReturn(null); + + bridge.init(rskTx, rskExecutionBlock, mockRepository, null, null, null); + Assert.assertEquals(expected, bridge.getGasForData(rskTx.getData())); + } + + private void registerBtcTransactionWithHugeDeclaredSize(BtcTransaction tx) throws VMException { + Repository repository = createRepository(); + Repository track = repository.startTracking(); + + Transaction rskTx = Transaction + .builder() + .nonce(NONCE) + .gasPrice(GAS_PRICE) + .gasLimit(GAS_LIMIT) + .destination(Hex.decode(PrecompiledContracts.BRIDGE_ADDR_STR)) + .data(Hex.decode(DATA)) + .chainId(Constants.REGTEST_CHAIN_ID) + .value(AMOUNT) + .build(); + rskTx.sign(fedECPrivateKey.getPrivKeyBytes()); + + BridgeSupportFactory bridgeSupportFactory = new BridgeSupportFactory( + new RepositoryBtcBlockStoreWithCache.Factory(bridgeConstants.getBtcParams()), + bridgeConstants, + activationConfig); + Bridge bridge = new Bridge(PrecompiledContracts.BRIDGE_ADDR, constants, activationConfig, + bridgeSupportFactory); + bridge.init(rskTx, getGenesisBlock(), track, null, null, null); + + byte[] serializedTx = tx.bitcoinSerialize(); + + byte[] data = Bridge.REGISTER_BTC_TRANSACTION.encode(serializedTx, 1, new byte[30]); + + Assert.assertNull(bridge.execute(data)); + } + + private Bridge getBridgeInstance(ActivationConfig.ForBlock activations) { + BridgeSupportFactory bridgeSupportFactoryMock = mock(BridgeSupportFactory.class); + when(bridgeSupportFactoryMock.newInstance(any(), any(), any(), any())).thenReturn(mock(BridgeSupport.class)); + + when(activationConfig.forBlock(anyLong())).thenReturn(activations); + Bridge bridge = new Bridge(PrecompiledContracts.BRIDGE_ADDR, constants, activationConfig, bridgeSupportFactoryMock); + bridge.init(mock(Transaction.class), getGenesisBlock(), null, null, null, null); + + return bridge; + } + + private static class HugeDeclaredSizeBtcTransaction extends BtcTransaction { + + private boolean hackInputsSize; + private boolean hackOutputsSize; + private boolean hackWitnessPushCountSize; + private boolean hackWitnessPushSize; + + public HugeDeclaredSizeBtcTransaction(NetworkParameters params, boolean hackInputsSize, boolean hackOutputsSize, boolean hackWitnessPushCountSize, boolean hackWitnessPushSize) { + super(params); + BtcTransaction inputTx = new BtcTransaction(params); + inputTx.addOutput(Coin.FIFTY_COINS, BtcECKey.fromPrivate(BigInteger.valueOf(123456)).toAddress(params)); + Address to = BtcECKey.fromPrivate(BigInteger.valueOf(1000)).toAddress(params); + this.addInput(inputTx.getOutput(0)); + this.getInput(0).disconnect(); + TransactionWitness witness = new TransactionWitness(1); + witness.setPush(0, new byte[] {0}); + this.setWitness(0, witness); + this.addOutput(Coin.COIN, to); + + this.hackInputsSize = hackInputsSize; + this.hackOutputsSize = hackOutputsSize; + this.hackWitnessPushCountSize = hackWitnessPushCountSize; + this.hackWitnessPushSize = hackWitnessPushSize; + } + + protected void bitcoinSerializeToStream(OutputStream stream, boolean serializeWitRequested) throws IOException { + boolean serializeWit = serializeWitRequested && hasWitness(); + uint32ToByteStreamLE(getVersion(), stream); + if (serializeWit) { + stream.write(new byte[]{0, 1}); + } + + long inputsSize = hackInputsSize ? Integer.MAX_VALUE : getInputs().size(); + stream.write(new VarInt(inputsSize).encode()); + for (TransactionInput in : getInputs()) + in.bitcoinSerialize(stream); + long outputsSize = hackOutputsSize ? Integer.MAX_VALUE : getOutputs().size(); + stream.write(new VarInt(outputsSize).encode()); + for (TransactionOutput out : getOutputs()) + out.bitcoinSerialize(stream); + if (serializeWit) { + for (int i = 0; i < getInputs().size(); i++) { + TransactionWitness witness = getWitness(i); + long pushCount = hackWitnessPushCountSize ? Integer.MAX_VALUE : witness.getPushCount(); + stream.write(new VarInt(pushCount).encode()); + for (int y = 0; y < witness.getPushCount(); y++) { + byte[] push = witness.getPush(y); + long pushLength = hackWitnessPushSize ? Integer.MAX_VALUE : push.length; + stream.write(new VarInt(pushLength).encode()); + stream.write(push); + } + } + } + uint32ToByteStreamLE(getLockTime(), stream); + } + }; } \ No newline at end of file From 397b91c42f53ae5b0f86a39a818f86b52e016244 Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 9 Apr 2021 12:08:20 -0300 Subject: [PATCH 34/34] Remove unnecessary interface --- .../src/main/java/co/rsk/peg/Bridge.java | 3 +-- .../main/java/co/rsk/peg/BridgeMethods.java | 22 ++++++++----------- .../java/co/rsk/peg/BridgeTestPowerMock.java | 8 +++---- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index e924c80ad76..6eaac8637b0 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -32,7 +32,6 @@ import com.google.common.annotations.VisibleForTesting; import org.ethereum.config.Constants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.ethereum.config.blockchain.upgrades.ActivationConfig.ForBlock; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.Block; import org.ethereum.core.CallTransaction; @@ -338,7 +337,7 @@ public byte[] execute(byte[] data) throws VMException { // allows for non-local calls if (activations.isActive(ConsensusRule.RSKIP88) && !isLocalCall() && - bridgeParsedData.bridgeMethod.onlyAllowsLocalCalls(this, activations, bridgeParsedData.args)) { + bridgeParsedData.bridgeMethod.onlyAllowsLocalCalls(this, bridgeParsedData.args)) { String errorMessage = String.format("Non-local-call to %s. Returning without execution.", bridgeParsedData.bridgeMethod.getFunction().name); logger.info(errorMessage); diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 0340492b480..ce7fbd80a3c 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -663,13 +663,13 @@ public enum BridgeMethods { private final CostProvider costProvider; private final Function isEnabledFunction; private final BridgeMethodExecutor executor; - private final CallPermissionProvider callPermissionProvider; + private final BridgeCallPermissionProvider callPermissionProvider; BridgeMethods( CallTransaction.Function function, CostProvider costProvider, BridgeMethodExecutor executor, - CallPermissionProvider callPermissionProvider) { + BridgeCallPermissionProvider callPermissionProvider) { this(function, costProvider, executor, activations -> Boolean.TRUE, callPermissionProvider); } @@ -679,7 +679,7 @@ public enum BridgeMethods { CostProvider costProvider, BridgeMethodExecutor executor, Function isEnabled, - CallPermissionProvider callPermissionProvider) { + BridgeCallPermissionProvider callPermissionProvider) { this.function = function; this.costProvider = costProvider; @@ -708,8 +708,8 @@ public BridgeMethodExecutor getExecutor() { return executor; } - public boolean onlyAllowsLocalCalls(Bridge bridge, ActivationConfig.ForBlock config, Object[] args) { - return callPermissionProvider.getOnlyAllowLocalCallsPermission(bridge, config, args); + public boolean onlyAllowsLocalCalls(Bridge bridge, Object[] args) { + return callPermissionProvider.getOnlyAllowLocalCallsPermission(bridge, args); } public interface BridgeCondition { @@ -755,20 +755,16 @@ private static CostProvider fromMethod(BridgeCostProvider bridgeCostProvider) { return (Bridge bridge, ActivationConfig.ForBlock config, Object[] args) -> bridgeCostProvider.getCost(bridge, args); } - private interface CallPermissionProvider { - boolean getOnlyAllowLocalCallsPermission(Bridge bridge, ActivationConfig.ForBlock config, Object[] args); - } - private interface BridgeCallPermissionProvider { boolean getOnlyAllowLocalCallsPermission(Bridge bridge, Object[] args); } - private static CallPermissionProvider fixedPermission(boolean onlyAllowsLocalCalls) { - return (Bridge bridge, ActivationConfig.ForBlock config, Object[] args) -> onlyAllowsLocalCalls; + private static BridgeCallPermissionProvider fixedPermission(boolean onlyAllowsLocalCalls) { + return (Bridge bridge, Object[] args) -> onlyAllowsLocalCalls; } - private static CallPermissionProvider fromMethod(BridgeCallPermissionProvider bridgeCallPermissionProvider) { - return (Bridge bridge, ActivationConfig.ForBlock config, Object[] args) -> bridgeCallPermissionProvider.getOnlyAllowLocalCallsPermission(bridge, args); + private static BridgeCallPermissionProvider fromMethod(BridgeCallPermissionProvider bridgeCallPermissionProvider) { + return (Bridge bridge, Object[] args) -> bridgeCallPermissionProvider.getOnlyAllowLocalCallsPermission(bridge, args); } private static final Map SIGNATURES = Stream.of(BridgeMethods.values()) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTestPowerMock.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTestPowerMock.java index c136fc1ee1e..3cf1f1c140d 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTestPowerMock.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTestPowerMock.java @@ -2966,7 +2966,7 @@ public void localCallOnlyMethodsDefinition() { BridgeMethods.GET_STATE_FOR_DEBUGGING, BridgeMethods.IS_BTC_TX_HASH_ALREADY_PROCESSED ).stream().forEach(m -> { - Assert.assertTrue(m.onlyAllowsLocalCalls(bridge, activationConfigAll, new Object[0])); + Assert.assertTrue(m.onlyAllowsLocalCalls(bridge, new Object[0])); }); } @@ -2996,7 +2996,7 @@ public void mineableMethodsDefinition() { BridgeMethods.VOTE_FEE_PER_KB, BridgeMethods.GET_ACTIVE_FEDERATION_CREATION_BLOCK_HEIGHT ).stream().forEach(m -> { - Assert.assertFalse(m.onlyAllowsLocalCalls(bridge, activationConfigAll, new Object[0])); + Assert.assertFalse(m.onlyAllowsLocalCalls(bridge, new Object[0])); }); } @@ -3007,7 +3007,7 @@ public void getBtcBlockchainBestChainHeight_beforeRskip220_isMineable() { Bridge bridge = getBridgeInstance(activationsMock); - Assert.assertFalse(BridgeMethods.GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT.onlyAllowsLocalCalls(bridge, activationsMock, new Object[0])); + Assert.assertFalse(BridgeMethods.GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT.onlyAllowsLocalCalls(bridge, new Object[0])); } @Test @@ -3017,7 +3017,7 @@ public void getBtcBlockchainBestChainHeight_afterRskip220_onlyAllowsLocalCalls() Bridge bridge = getBridgeInstance(activationsMock); - Assert.assertTrue(BridgeMethods.GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT.onlyAllowsLocalCalls(bridge, activationsMock, new Object[0])); + Assert.assertTrue(BridgeMethods.GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT.onlyAllowsLocalCalls(bridge, new Object[0])); } @Test