use of co.rsk.bitcoinj.script.RedeemScriptParser in project rskj by rsksmart.
the class BridgeUtils method countMissingSignatures.
/**
* Return the amount of missing signatures for a tx.
* @param btcContext Btc context
* @param btcTx The btc tx to check
* @return 0 if was signed by the required number of federators, amount of missing signatures otherwise
*/
public static int countMissingSignatures(Context btcContext, BtcTransaction btcTx) {
// Check missing signatures for only one input as it is not
// possible for a federator to leave unsigned inputs in a tx
Context.propagate(btcContext);
int unsigned = 0;
TransactionInput input = btcTx.getInput(0);
Script scriptSig = input.getScriptSig();
List<ScriptChunk> chunks = scriptSig.getChunks();
Script redeemScript = new Script(chunks.get(chunks.size() - 1).data);
RedeemScriptParser parser = RedeemScriptParserFactory.get(redeemScript.getChunks());
MultiSigType multiSigType;
int lastChunk;
multiSigType = parser.getMultiSigType();
if (multiSigType == MultiSigType.STANDARD_MULTISIG || multiSigType == MultiSigType.FAST_BRIDGE_MULTISIG) {
lastChunk = chunks.size() - 1;
} else {
lastChunk = chunks.size() - 2;
}
for (int i = 1; i < lastChunk; i++) {
ScriptChunk chunk = chunks.get(i);
if (!chunk.isOpCode() && chunk.data.length == 0) {
unsigned++;
}
}
return unsigned;
}
use of co.rsk.bitcoinj.script.RedeemScriptParser in project rskj by rsksmart.
the class BridgeUtils method isValidPegInTx.
/**
* It checks if the tx doesn't spend any of the federations' funds and if it sends more than
* the minimum ({@see BridgeConstants::getMinimumLockTxValue}) to any of the federations
* @param tx the BTC transaction to check
* @param activeFederations the active federations
* @param retiredFederationP2SHScript the retired federation P2SHScript. Could be {@code null}.
* @param btcContext the BTC Context
* @param bridgeConstants the Bridge constants
* @param activations the network HF activations configuration
* @return true if this is a valid peg-in transaction
*/
public static boolean isValidPegInTx(BtcTransaction tx, List<Federation> activeFederations, Script retiredFederationP2SHScript, Context btcContext, BridgeConstants bridgeConstants, ActivationConfig.ForBlock activations) {
// optionally sending some change to any of the federation addresses)
for (int i = 0; i < tx.getInputs().size(); i++) {
final int index = i;
if (activeFederations.stream().anyMatch(federation -> scriptCorrectlySpendsTx(tx, index, federation.getP2SHScript()))) {
return false;
}
if (retiredFederationP2SHScript != null && scriptCorrectlySpendsTx(tx, index, retiredFederationP2SHScript)) {
return false;
}
// erp federation, or even a retired fast bridge or erp federation
if (activations.isActive(ConsensusRule.RSKIP201)) {
RedeemScriptParser redeemScriptParser = RedeemScriptParserFactory.get(tx.getInput(index).getScriptSig().getChunks());
try {
Script inputStandardRedeemScript = redeemScriptParser.extractStandardRedeemScript();
if (activeFederations.stream().anyMatch(federation -> federation.getStandardRedeemScript().equals(inputStandardRedeemScript))) {
return false;
}
Script outputScript = ScriptBuilder.createP2SHOutputScript(inputStandardRedeemScript);
if (outputScript.equals(retiredFederationP2SHScript)) {
return false;
}
} catch (ScriptException e) {
// There is no redeem script, could be a peg-in from a P2PKH address
}
}
}
Wallet federationsWallet = BridgeUtils.getFederationsNoSpendWallet(btcContext, activeFederations, false, null);
Coin valueSentToMe = tx.getValueSentToMe(federationsWallet);
Coin minimumPegInTxValue = activations.isActive(ConsensusRule.RSKIP219) ? bridgeConstants.getMinimumPeginTxValueInSatoshis() : bridgeConstants.getLegacyMinimumPeginTxValueInSatoshis();
if (valueSentToMe.isLessThan(minimumPegInTxValue)) {
logger.warn("[btctx:{}] Someone sent to the federation less than {} satoshis", tx.getHash(), minimumPegInTxValue);
}
return valueSentToMe.isPositive() && !valueSentToMe.isLessThan(minimumPegInTxValue);
}
use of co.rsk.bitcoinj.script.RedeemScriptParser in project rskj by rsksmart.
the class FastBridgeCompatibleBtcWallet method findRedeemDataFromScriptHash.
@Nullable
@Override
public RedeemData findRedeemDataFromScriptHash(byte[] payToScriptHash) {
Optional<FastBridgeFederationInformation> fastBridgeFederationInformation = this.getFastBridgeFederationInformation(payToScriptHash);
if (fastBridgeFederationInformation.isPresent()) {
FastBridgeFederationInformation fastBridgeFederationInformationInstance = fastBridgeFederationInformation.get();
Optional<Federation> destinationFederation = getDestinationFederation(fastBridgeFederationInformationInstance.getFederationRedeemScriptHash());
if (!destinationFederation.isPresent()) {
return null;
}
Federation destinationFederationInstance = destinationFederation.get();
Script fedRedeemScript = destinationFederationInstance.getRedeemScript();
RedeemScriptParser parser = RedeemScriptParserFactory.get(fedRedeemScript.getChunks());
Script fastBridgeRedeemScript;
if (parser.getMultiSigType() == MultiSigType.ERP_FED) {
fastBridgeRedeemScript = FastBridgeErpRedeemScriptParser.createFastBridgeErpRedeemScript(fedRedeemScript, Sha256Hash.wrap(fastBridgeFederationInformationInstance.getDerivationHash().getBytes()));
} else {
fastBridgeRedeemScript = FastBridgeRedeemScriptParser.createMultiSigFastBridgeRedeemScript(fedRedeemScript, Sha256Hash.wrap(fastBridgeFederationInformationInstance.getDerivationHash().getBytes()));
}
return RedeemData.of(destinationFederationInstance.getBtcPublicKeys(), fastBridgeRedeemScript);
}
return super.findRedeemDataFromScriptHash(payToScriptHash);
}
use of co.rsk.bitcoinj.script.RedeemScriptParser in project rskj by rsksmart.
the class BridgeUtils method hasEnoughSignatures.
/**
* Checks whether a btc tx has been signed by the required number of federators.
* @param btcContext Btc context
* @param btcTx The btc tx to check
* @return True if was signed by the required number of federators, false otherwise
*/
public static boolean hasEnoughSignatures(Context btcContext, BtcTransaction btcTx) {
// When the tx is constructed OP_0 are placed where signature should go.
// Check all OP_0 have been replaced with actual signatures in all inputs
Context.propagate(btcContext);
Script scriptSig;
List<ScriptChunk> chunks;
Script redeemScript;
RedeemScriptParser parser;
MultiSigType multiSigType;
int lastChunk;
for (TransactionInput input : btcTx.getInputs()) {
scriptSig = input.getScriptSig();
chunks = scriptSig.getChunks();
redeemScript = new Script(chunks.get(chunks.size() - 1).data);
parser = RedeemScriptParserFactory.get(redeemScript.getChunks());
multiSigType = parser.getMultiSigType();
if (multiSigType == MultiSigType.STANDARD_MULTISIG || multiSigType == MultiSigType.FAST_BRIDGE_MULTISIG) {
lastChunk = chunks.size() - 1;
} else {
lastChunk = chunks.size() - 2;
}
for (int i = 1; i < lastChunk; i++) {
ScriptChunk chunk = chunks.get(i);
if (!chunk.isOpCode() && chunk.data.length == 0) {
return false;
}
}
}
return true;
}
use of co.rsk.bitcoinj.script.RedeemScriptParser in project rskj by rsksmart.
the class BridgeUtils method isPegOutTx.
public static boolean isPegOutTx(BtcTransaction tx, ActivationConfig.ForBlock activations, Script... p2shScript) {
int inputsSize = tx.getInputs().size();
for (int i = 0; i < inputsSize; i++) {
TransactionInput txInput = tx.getInput(i);
Optional<Script> redeemScriptOptional = extractRedeemScriptFromInput(tx.getInput(i));
if (!redeemScriptOptional.isPresent()) {
continue;
}
Script redeemScript = redeemScriptOptional.get();
if (activations.isActive(ConsensusRule.RSKIP201)) {
// Extract standard redeem script since the registered utxo could be from a fast bridge or erp federation
RedeemScriptParser redeemScriptParser = RedeemScriptParserFactory.get(txInput.getScriptSig().getChunks());
try {
redeemScript = redeemScriptParser.extractStandardRedeemScript();
} catch (ScriptException e) {
// There is no redeem script
continue;
}
}
Script outputScript = ScriptBuilder.createP2SHOutputScript(redeemScript);
if (Stream.of(p2shScript).anyMatch(federationPayScript -> federationPayScript.equals(outputScript))) {
return true;
}
}
return false;
}
Aggregations