|
23 | 23 | import co.rsk.bitcoinj.core.*; |
24 | 24 | import co.rsk.bitcoinj.script.Script; |
25 | 25 | import co.rsk.bitcoinj.store.BlockStoreException; |
26 | | -import co.rsk.core.types.bytes.Bytes; |
27 | | -import co.rsk.peg.constants.BridgeConstants; |
28 | 26 | import co.rsk.core.RskAddress; |
| 27 | +import co.rsk.core.types.bytes.Bytes; |
29 | 28 | import co.rsk.crypto.Keccak256; |
30 | 29 | import co.rsk.panic.PanicProcessor; |
| 30 | +import co.rsk.peg.BridgeMethods.AuthorizerProvider; |
31 | 31 | import co.rsk.peg.BridgeMethods.BridgeMethodExecutor; |
32 | | -import co.rsk.peg.feeperkb.FeePerKbResponseCode; |
33 | | -import co.rsk.peg.lockingcap.LockingCapIllegalArgumentException; |
34 | | -import co.rsk.peg.vote.ABICallSpec; |
35 | 32 | import co.rsk.peg.bitcoin.MerkleBranch; |
| 33 | +import co.rsk.peg.constants.BridgeConstants; |
36 | 34 | import co.rsk.peg.federation.Federation; |
37 | 35 | import co.rsk.peg.federation.FederationChangeResponseCode; |
38 | 36 | import co.rsk.peg.federation.FederationMember; |
| 37 | +import co.rsk.peg.feeperkb.FeePerKbResponseCode; |
39 | 38 | import co.rsk.peg.flyover.FlyoverTxResponseCodes; |
| 39 | +import co.rsk.peg.lockingcap.LockingCapIllegalArgumentException; |
40 | 40 | import co.rsk.peg.utils.BtcTransactionFormatUtils; |
| 41 | +import co.rsk.peg.vote.ABICallSpec; |
| 42 | +import co.rsk.peg.vote.AddressBasedAuthorizer; |
41 | 43 | import co.rsk.peg.whitelist.LockWhitelistEntry; |
42 | 44 | import co.rsk.peg.whitelist.OneOffWhiteListEntry; |
43 | 45 | import co.rsk.peg.whitelist.WhitelistResponseCode; |
44 | 46 | import co.rsk.rpc.modules.trace.ProgramSubtrace; |
45 | 47 | import com.google.common.annotations.VisibleForTesting; |
| 48 | +import java.io.IOException; |
| 49 | +import java.math.BigInteger; |
| 50 | +import java.time.Instant; |
| 51 | +import java.util.*; |
| 52 | +import java.util.function.BiFunction; |
| 53 | +import java.util.stream.Collectors; |
46 | 54 | import org.ethereum.config.Constants; |
47 | 55 | import org.ethereum.config.blockchain.upgrades.ActivationConfig; |
48 | 56 | import org.ethereum.config.blockchain.upgrades.ConsensusRule; |
49 | | -import org.ethereum.core.*; |
| 57 | +import org.ethereum.core.Block; |
| 58 | +import org.ethereum.core.CallTransaction; |
| 59 | +import org.ethereum.core.SignatureCache; |
50 | 60 | import org.ethereum.util.ByteUtil; |
51 | 61 | import org.ethereum.vm.DataWord; |
52 | 62 | import org.ethereum.vm.MessageCall.MsgType; |
|
57 | 67 | import org.slf4j.Logger; |
58 | 68 | import org.slf4j.LoggerFactory; |
59 | 69 |
|
60 | | -import java.io.IOException; |
61 | | -import java.math.BigInteger; |
62 | | -import java.time.Instant; |
63 | | -import java.util.ArrayList; |
64 | | -import java.util.Arrays; |
65 | | -import java.util.List; |
66 | | -import java.util.Optional; |
67 | | -import java.util.function.BiFunction; |
68 | | -import java.util.stream.Collectors; |
69 | | - |
70 | 70 | /** |
71 | 71 | * Precompiled contract that manages the 2 way peg between bitcoin and RSK. |
72 | 72 | * This class is just a wrapper, actual functionality is found in BridgeSupport. |
@@ -224,6 +224,15 @@ public class Bridge extends PrecompiledContracts.PrecompiledContract { |
224 | 224 |
|
225 | 225 | public static final CallTransaction.Function GET_ACTIVE_POWPEG_REDEEM_SCRIPT = BridgeMethods.GET_ACTIVE_POWPEG_REDEEM_SCRIPT.getFunction(); |
226 | 226 |
|
| 227 | + // Union Bridge Contract functions |
| 228 | + public static final CallTransaction.Function SET_UNION_BRIDGE_CONTRACT_ADDRESS_FOR_TESTNET = BridgeMethods.SET_UNION_BRIDGE_CONTRACT_ADDRESS_FOR_TESTNET.getFunction(); |
| 229 | + public static final CallTransaction.Function GET_UNION_BRIDGE_CONTRACT_ADDRESS = BridgeMethods.GET_UNION_BRIDGE_CONTRACT_ADDRESS.getFunction(); |
| 230 | + public static final CallTransaction.Function GET_UNION_BRIDGE_LOCKING_CAP = BridgeMethods.GET_UNION_BRIDGE_LOCKING_CAP.getFunction(); |
| 231 | + public static final CallTransaction.Function INCREASE_UNION_BRIDGE_LOCKING_CAP = BridgeMethods.INCREASE_UNION_BRIDGE_LOCKING_CAP.getFunction(); |
| 232 | + public static final CallTransaction.Function REQUEST_UNION_BRIDGE_RBTC = BridgeMethods.REQUEST_UNION_BRIDGE_RBTC.getFunction(); |
| 233 | + public static final CallTransaction.Function RELEASE_UNION_BRIDGE_RBTC = BridgeMethods.RELEASE_UNION_BRIDGE_RBTC.getFunction(); |
| 234 | + public static final CallTransaction.Function SET_UNION_BRIDGE_TRANSFER_PERMISSIONS = BridgeMethods.SET_UNION_BRIDGE_TRANSFER_PERMISSIONS.getFunction(); |
| 235 | + |
227 | 236 | // Log topics used by Bridge Contract pre RSKIP146 |
228 | 237 | public static final DataWord RELEASE_BTC_TOPIC = DataWord.fromString("release_btc_topic"); |
229 | 238 | public static final DataWord UPDATE_COLLECTIONS_TOPIC = DataWord.fromString("update_collections_topic"); |
@@ -1482,6 +1491,84 @@ public long getEstimatedFeesForNextPegOutEvent(Object[] args) throws IOException |
1482 | 1491 | return bridgeSupport.getEstimatedFeesForNextPegOutEvent().value; |
1483 | 1492 | } |
1484 | 1493 |
|
| 1494 | + public int setUnionBridgeContractAddressForTestnet(Object[] args) { |
| 1495 | + logger.trace("setUnionBridgeContractAddressForTestnet"); |
| 1496 | + // A DataWord cast is used because a SolidityType "address" is decoded using this specific type. |
| 1497 | + RskAddress unionBridgeContractAddress = new RskAddress((DataWord) args[0]); |
| 1498 | + return bridgeSupport.setUnionBridgeContractAddressForTestnet(unionBridgeContractAddress).getCode(); |
| 1499 | + } |
| 1500 | + |
| 1501 | + public String getUnionBridgeContractAddress(Object[] args) { |
| 1502 | + logger.trace("getUnionBridgeContractAddress"); |
| 1503 | + return bridgeSupport.getUnionBridgeContractAddress().toHexString(); |
| 1504 | + } |
| 1505 | + |
| 1506 | + public BigInteger getUnionBridgeLockingCap(Object[] args) { |
| 1507 | + logger.trace("getUnionBridgeLockingCap"); |
| 1508 | + return bridgeSupport.getUnionBridgeLockingCap().asBigInteger(); |
| 1509 | + } |
| 1510 | + |
| 1511 | + public int increaseUnionBridgeLockingCap(Object[] args) { |
| 1512 | + logger.trace("increaseUnionBridgeLockingCap"); |
| 1513 | + co.rsk.core.Coin newLockingCap = new co.rsk.core.Coin((BigInteger) args[0]); |
| 1514 | + return bridgeSupport.increaseUnionBridgeLockingCap(rskTx, newLockingCap).getCode(); |
| 1515 | + } |
| 1516 | + |
| 1517 | + public int requestUnionBridgeRbtc(Object[] args) { |
| 1518 | + logger.trace("requestUnionBridgeRbtc"); |
| 1519 | + co.rsk.core.Coin amountRequested = new co.rsk.core.Coin((BigInteger) args[0]); |
| 1520 | + return bridgeSupport.requestUnionBridgeRbtc(rskTx, amountRequested).getCode(); |
| 1521 | + } |
| 1522 | + |
| 1523 | + public int releaseUnionBridgeRbtc(Object[] args) { |
| 1524 | + logger.trace("releaseUnionBridgeRbtc"); |
| 1525 | + return bridgeSupport.releaseUnionBridgeRbtc(rskTx).getCode(); |
| 1526 | + } |
| 1527 | + |
| 1528 | + public int setUnionBridgeTransferPermissions(Object[] args) { |
| 1529 | + logger.trace("setUnionBridgeTransferPermissions"); |
| 1530 | + boolean requestEnabled = (boolean) args[0]; |
| 1531 | + boolean releaseEnabled = (boolean) args[1]; |
| 1532 | + return bridgeSupport.setUnionBridgeTransferPermissions(rskTx, requestEnabled, releaseEnabled).getCode(); |
| 1533 | + } |
| 1534 | + |
| 1535 | + protected static BridgeMethods.BridgeMethodExecutor executeIfAuthorized( |
| 1536 | + AuthorizerProvider authorizerProvider, |
| 1537 | + BridgeMethods.BridgeMethodExecutor decorate, |
| 1538 | + String functionName |
| 1539 | + ) { |
| 1540 | + return (self, args) -> { |
| 1541 | + AddressBasedAuthorizer addressBasedAuthorizer = authorizerProvider.provide(self.bridgeConstants); |
| 1542 | + if (!addressBasedAuthorizer.isAuthorized(self.rskTx, self.signatureCache)) { |
| 1543 | + String errorMessage = String.format( |
| 1544 | + "The sender is not authorized to call %s", |
| 1545 | + functionName |
| 1546 | + ); |
| 1547 | + throw new VMException(errorMessage); |
| 1548 | + } |
| 1549 | + return decorate.execute(self, args); |
| 1550 | + }; |
| 1551 | + } |
| 1552 | + |
| 1553 | + public static BridgeMethods.BridgeMethodExecutor executeIfTestnetAndAuthorized( |
| 1554 | + AuthorizerProvider authorizerProvider, |
| 1555 | + BridgeMethods.BridgeMethodExecutor decorate, |
| 1556 | + String functionName |
| 1557 | + ) { |
| 1558 | + return (self, args) -> { |
| 1559 | + boolean isMainnet = self.constants.getChainId() == Constants.MAINNET_CHAIN_ID; |
| 1560 | + if (isMainnet) { |
| 1561 | + String errorMessage = String.format( |
| 1562 | + "The %s function is disabled in Mainnet.", |
| 1563 | + functionName |
| 1564 | + ); |
| 1565 | + throw new VMException(errorMessage); |
| 1566 | + } |
| 1567 | + |
| 1568 | + return executeIfAuthorized(authorizerProvider, decorate, functionName).execute(self, args); |
| 1569 | + }; |
| 1570 | + } |
| 1571 | + |
1485 | 1572 | public static BridgeMethods.BridgeMethodExecutor activeAndRetiringFederationOnly(BridgeMethods.BridgeMethodExecutor decoratee, String funcName) { |
1486 | 1573 | return (self, args) -> { |
1487 | 1574 | boolean isFromActiveFed = BridgeUtils.isFromFederateMember(self.rskTx, self.bridgeSupport.getActiveFederation(), self.signatureCache); |
|
0 commit comments