mirror of
https://github.com/ACINQ/eclair.git
synced 2025-02-22 14:22:39 +01:00
moved OldScripts into Scripts
This commit is contained in:
parent
b05f52b412
commit
1e97d4e0a6
17 changed files with 262 additions and 268 deletions
|
@ -3,7 +3,7 @@ package fr.acinq.eclair.blockchain
|
|||
import fr.acinq.bitcoin._
|
||||
import fr.acinq.eclair.blockchain.rpc.{BitcoinJsonRPCClient, JsonRPCError}
|
||||
import fr.acinq.eclair.{channel, transactions}
|
||||
import fr.acinq.eclair.transactions.OldScripts
|
||||
import fr.acinq.eclair.transactions.Common
|
||||
import org.bouncycastle.util.encoders.Hex
|
||||
import org.json4s.JsonAST._
|
||||
|
||||
|
@ -93,12 +93,12 @@ class ExtendedBitcoinClient(val client: BitcoinJsonRPCClient) {
|
|||
publishTransaction(tx2Hex(tx))
|
||||
|
||||
def makeAnchorTx(ourCommitPub: BinaryData, theirCommitPub: BinaryData, amount: Satoshi)(implicit ec: ExecutionContext): Future[(Transaction, Int)] = {
|
||||
val anchorOutputScript = transactions.OldScripts.anchorPubkeyScript(ourCommitPub, theirCommitPub)
|
||||
val anchorOutputScript = transactions.Common.anchorPubkeyScript(ourCommitPub, theirCommitPub)
|
||||
val tx = Transaction(version = 2, txIn = Seq.empty[TxIn], txOut = TxOut(amount, anchorOutputScript) :: Nil, lockTime = 0)
|
||||
val future = for {
|
||||
FundTransactionResponse(tx1, changepos, fee) <- fundTransaction(tx)
|
||||
SignTransactionResponse(anchorTx, true) <- signTransaction(tx1)
|
||||
Some(pos) = OldScripts.findPublicKeyScriptIndex(anchorTx, anchorOutputScript)
|
||||
Some(pos) = Common.findPublicKeyScriptIndex(anchorTx, anchorOutputScript)
|
||||
} yield (anchorTx, pos)
|
||||
|
||||
future
|
||||
|
@ -106,20 +106,20 @@ class ExtendedBitcoinClient(val client: BitcoinJsonRPCClient) {
|
|||
|
||||
def makeAnchorTx(fundingPriv: BinaryData, ourCommitPub: BinaryData, theirCommitPub: BinaryData, amount: Btc)(implicit ec: ExecutionContext): Future[(Transaction, Int)] = {
|
||||
val pub = Crypto.publicKeyFromPrivateKey(fundingPriv)
|
||||
val script = Script.write(OldScripts.pay2sh(OldScripts.pay2wpkh(pub)))
|
||||
val script = Script.write(Common.pay2sh(Common.pay2wpkh(pub)))
|
||||
val address = Base58Check.encode(Base58.Prefix.ScriptAddressTestnet, script)
|
||||
val future = for {
|
||||
id <- sendFromAccount("", address, amount.amount.toDouble)
|
||||
tx <- getTransaction(id)
|
||||
Some(pos) = OldScripts.findPublicKeyScriptIndex(tx, script)
|
||||
Some(pos) = Common.findPublicKeyScriptIndex(tx, script)
|
||||
output = tx.txOut(pos)
|
||||
anchorOutputScript = transactions.OldScripts.anchorPubkeyScript(ourCommitPub, theirCommitPub)
|
||||
anchorOutputScript = transactions.Common.anchorPubkeyScript(ourCommitPub, theirCommitPub)
|
||||
tx1 = Transaction(version = 2, txIn = TxIn(OutPoint(tx, pos), Nil, 0xffffffffL) :: Nil, txOut = TxOut(amount, anchorOutputScript) :: Nil, lockTime = 0)
|
||||
pubKeyScript = Script.write(OP_DUP :: OP_HASH160 :: OP_PUSHDATA(Crypto.hash160(pub)) :: OP_EQUALVERIFY :: OP_CHECKSIG :: Nil)
|
||||
sig = Transaction.signInput(tx1, 0, pubKeyScript, SIGHASH_ALL, output.amount, 1, fundingPriv)
|
||||
witness = ScriptWitness(Seq(sig, pub))
|
||||
tx2 = tx1.updateWitness(0, witness)
|
||||
Some(pos1) = OldScripts.findPublicKeyScriptIndex(tx2, anchorOutputScript)
|
||||
Some(pos1) = Common.findPublicKeyScriptIndex(tx2, anchorOutputScript)
|
||||
} yield (tx2, pos1)
|
||||
|
||||
future
|
||||
|
|
|
@ -5,7 +5,7 @@ import akka.pattern.pipe
|
|||
import fr.acinq.bitcoin._
|
||||
import fr.acinq.eclair.blockchain.peer.{BlockchainEvent, CurrentBlockCount, NewBlock, NewTransaction}
|
||||
import fr.acinq.eclair.channel.BITCOIN_FUNDING_SPENT
|
||||
import fr.acinq.eclair.transactions.OldScripts
|
||||
import fr.acinq.eclair.transactions.Common
|
||||
|
||||
import scala.collection.SortedMap
|
||||
import scala.concurrent.ExecutionContext
|
||||
|
@ -70,8 +70,8 @@ class PeerWatcher(client: ExtendedBitcoinClient, blockCount: Long)(implicit ec:
|
|||
}
|
||||
|
||||
case PublishAsap(tx) =>
|
||||
val cltvTimeout = OldScripts.cltvTimeout(tx)
|
||||
val csvTimeout = currentBlockCount + OldScripts.csvTimeout(tx)
|
||||
val cltvTimeout = Common.cltvTimeout(tx)
|
||||
val csvTimeout = currentBlockCount + Common.csvTimeout(tx)
|
||||
val timeout = Math.max(cltvTimeout, csvTimeout)
|
||||
val block2tx1 = block2tx.updated(timeout, tx +: block2tx.getOrElse(timeout, Seq.empty[Transaction]))
|
||||
context.become(watching(watches, block2tx1, currentBlockCount))
|
||||
|
|
|
@ -442,7 +442,7 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, paymentHandler: Acto
|
|||
sender ! "closing already in progress"
|
||||
stay
|
||||
} else {
|
||||
val defaultScriptPubkey: BinaryData = Script.write(OldScripts.pay2wpkh(d.params.localParams.finalPrivKey.point))
|
||||
val defaultScriptPubkey: BinaryData = Script.write(Common.pay2wpkh(d.params.localParams.finalPrivKey.point))
|
||||
val ourScriptPubKey = ourScriptPubKey_opt.getOrElse(defaultScriptPubkey)
|
||||
val ourShutdown = Shutdown(d.channelId, ourScriptPubKey)
|
||||
them ! ourShutdown
|
||||
|
@ -451,7 +451,7 @@ class Channel(val them: ActorRef, val blockchain: ActorRef, paymentHandler: Acto
|
|||
|
||||
case Event(theirShutdown@Shutdown(_, theirScriptPubKey), d@DATA_NORMAL(channelId, params, commitments, ourShutdownOpt, downstreams)) =>
|
||||
val ourShutdown: Shutdown = ourShutdownOpt.getOrElse {
|
||||
val defaultScriptPubkey: BinaryData = Script.write(OldScripts.pay2wpkh(params.localParams.finalPrivKey.point))
|
||||
val defaultScriptPubkey: BinaryData = Script.write(Common.pay2wpkh(params.localParams.finalPrivKey.point))
|
||||
val c = Shutdown(channelId, defaultScriptPubkey)
|
||||
them ! c
|
||||
c
|
||||
|
|
|
@ -2,7 +2,7 @@ package fr.acinq.eclair.channel
|
|||
|
||||
import fr.acinq.bitcoin.{OutPoint, _}
|
||||
import fr.acinq.eclair.crypto.Generators
|
||||
import fr.acinq.eclair.transactions.OldScripts._
|
||||
import fr.acinq.eclair.transactions.Common._
|
||||
import fr.acinq.eclair.transactions._
|
||||
import fr.acinq.eclair.wire.UpdateFulfillHtlc
|
||||
|
||||
|
@ -47,7 +47,7 @@ object Helpers {
|
|||
val remoteTx = CommitmentSpec.makeRemoteTxTemplate(params.localParams, params.remoteParams, commitmentInput :: Nil, remoteFirstPerCommitmentPoint, remoteSpec).makeTx
|
||||
|
||||
val localFundingPubkey = params.localParams.fundingPrivkey.point
|
||||
val fundingTxOutput = TxOut(Satoshi(params.fundingSatoshis), publicKeyScript = OldScripts.anchorPubkeyScript(localFundingPubkey, params.remoteParams.fundingPubkey))
|
||||
val fundingTxOutput = TxOut(Satoshi(params.fundingSatoshis), publicKeyScript = Common.anchorPubkeyScript(localFundingPubkey, params.remoteParams.fundingPubkey))
|
||||
|
||||
(localSpec, localTx, remoteSpec, remoteTx, fundingTxOutput)
|
||||
}
|
||||
|
@ -155,8 +155,8 @@ object Helpers {
|
|||
val index = tx.txOut.indexOf(htlcTemplate.txOut)
|
||||
|
||||
val tx1 = Transaction(version = 2,
|
||||
txIn = TxIn(OutPoint(tx, index), BinaryData.empty, sequence = OldScripts.toSelfDelay2csv(htlcTemplate.delay)) :: Nil,
|
||||
txOut = TxOut(htlcTemplate.amount, OldScripts.pay2pkh(Crypto.publicKeyFromPrivateKey(privateKey))) :: Nil,
|
||||
txIn = TxIn(OutPoint(tx, index), BinaryData.empty, sequence = Common.toSelfDelay2csv(htlcTemplate.delay)) :: Nil,
|
||||
txOut = TxOut(htlcTemplate.amount, Common.pay2pkh(Crypto.publicKeyFromPrivateKey(privateKey))) :: Nil,
|
||||
lockTime = ??? /*Scripts.locktime2long_cltv(htlcTemplate.htlc.add.expiry)*/)
|
||||
|
||||
val sig = Transaction.signInput(tx1, 0, htlcTemplate.redeemScript, SIGHASH_ALL, htlcTemplate.amount, 1, privateKey)
|
||||
|
@ -198,8 +198,8 @@ object Helpers {
|
|||
val index = tx.txOut.indexOf(htlcTemplate.txOut)
|
||||
val tx1 = Transaction(
|
||||
version = 2,
|
||||
txIn = TxIn(OutPoint(tx, index), Array.emptyByteArray, sequence = OldScripts.toSelfDelay2csv(htlcTemplate.delay)) :: Nil,
|
||||
txOut = TxOut(htlcTemplate.amount, OldScripts.pay2pkh(Crypto.publicKeyFromPrivateKey(privateKey))) :: Nil,
|
||||
txIn = TxIn(OutPoint(tx, index), Array.emptyByteArray, sequence = Common.toSelfDelay2csv(htlcTemplate.delay)) :: Nil,
|
||||
txOut = TxOut(htlcTemplate.amount, Common.pay2pkh(Crypto.publicKeyFromPrivateKey(privateKey))) :: Nil,
|
||||
lockTime = ??? /*Scripts.locktime2long_cltv(htlcTemplate.htlc.add.expiry)*/)
|
||||
|
||||
val sig = Transaction.signInput(tx1, 0, htlcTemplate.redeemScript, SIGHASH_ALL, htlcTemplate.amount, 1, privateKey)
|
||||
|
|
|
@ -5,7 +5,7 @@ import akka.util.Timeout
|
|||
import fr.acinq.bitcoin.{BinaryData, Crypto, DeterministicWallet, Satoshi, Script}
|
||||
import fr.acinq.eclair.Globals
|
||||
import fr.acinq.eclair.io.AuthHandler
|
||||
import fr.acinq.eclair.transactions.OldScripts
|
||||
import fr.acinq.eclair.transactions.Common
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
|
|
|
@ -1,230 +0,0 @@
|
|||
package fr.acinq.eclair.transactions
|
||||
|
||||
import fr.acinq.bitcoin.Crypto._
|
||||
import fr.acinq.bitcoin._
|
||||
import fr.acinq.eclair._
|
||||
|
||||
/**
|
||||
* Created by PM on 21/01/2016.
|
||||
*/
|
||||
object OldScripts {
|
||||
|
||||
def toSelfDelay2csv(in: Int): Long = ???
|
||||
|
||||
/*in match {
|
||||
case locktime(Blocks(blocks)) => blocks
|
||||
case locktime(Seconds(seconds)) => TxIn.SEQUENCE_LOCKTIME_TYPE_FLAG | (seconds >> TxIn.SEQUENCE_LOCKTIME_GRANULARITY)
|
||||
}*/
|
||||
|
||||
def expiry2cltv(in: Long): Long = ???
|
||||
|
||||
/*in match {
|
||||
case locktime(Blocks(blocks)) => blocks
|
||||
case locktime(Seconds(seconds)) => seconds
|
||||
}*/
|
||||
|
||||
def isLess(a: Seq[Byte], b: Seq[Byte]): Boolean = memcmp(a.dropWhile(_ == 0).toList, b.dropWhile(_ == 0).toList) < 0
|
||||
|
||||
def lessThan(output1: TxOut, output2: TxOut): Boolean = (output1, output2) match {
|
||||
case (TxOut(amount1, script1), TxOut(amount2, script2)) if amount1 == amount2 => memcmp(script1.toList, script2.toList) < 0
|
||||
case (TxOut(amount1, _), TxOut(amount2, _)) => amount1.toLong < amount2.toLong
|
||||
}
|
||||
|
||||
def permuteOutputs(tx: Transaction): Transaction = tx.copy(txOut = tx.txOut.sortWith(lessThan))
|
||||
|
||||
def multiSig2of2(pubkey1: BinaryData, pubkey2: BinaryData): BinaryData = if (isLess(pubkey1, pubkey2))
|
||||
Script.createMultiSigMofN(2, Seq(pubkey1, pubkey2))
|
||||
else
|
||||
Script.createMultiSigMofN(2, Seq(pubkey2, pubkey1))
|
||||
|
||||
|
||||
def sigScript2of2(sig1: BinaryData, sig2: BinaryData, pubkey1: BinaryData, pubkey2: BinaryData): BinaryData = if (isLess(pubkey1, pubkey2))
|
||||
Script.write(OP_0 :: OP_PUSHDATA(sig1) :: OP_PUSHDATA(sig2) :: OP_PUSHDATA(multiSig2of2(pubkey1, pubkey2)) :: Nil)
|
||||
else
|
||||
Script.write(OP_0 :: OP_PUSHDATA(sig2) :: OP_PUSHDATA(sig1) :: OP_PUSHDATA(multiSig2of2(pubkey1, pubkey2)) :: Nil)
|
||||
|
||||
/**
|
||||
*
|
||||
* @param sig1
|
||||
* @param sig2
|
||||
* @param pubkey1
|
||||
* @param pubkey2
|
||||
* @return a script witness that matches the msig 2-of-2 pubkey script for pubkey1 and pubkey2
|
||||
*/
|
||||
def witness2of2(sig1: BinaryData, sig2: BinaryData, pubkey1: BinaryData, pubkey2: BinaryData): ScriptWitness = {
|
||||
if (isLess(pubkey1, pubkey2))
|
||||
ScriptWitness(Seq(BinaryData.empty, sig1, sig2, multiSig2of2(pubkey1, pubkey2)))
|
||||
else
|
||||
ScriptWitness(Seq(BinaryData.empty, sig2, sig1, multiSig2of2(pubkey1, pubkey2)))
|
||||
|
||||
}
|
||||
|
||||
def pay2pkh(pubKey: BinaryData): Seq[ScriptElt] = OP_DUP :: OP_HASH160 :: OP_PUSHDATA(hash160(pubKey)) :: OP_EQUALVERIFY :: OP_CHECKSIG :: Nil
|
||||
|
||||
def pay2sh(script: Seq[ScriptElt]): Seq[ScriptElt] = pay2sh(Script.write(script))
|
||||
|
||||
def pay2sh(script: BinaryData): Seq[ScriptElt] = OP_HASH160 :: OP_PUSHDATA(hash160(script)) :: OP_EQUAL :: Nil
|
||||
|
||||
def pay2wsh(script: Seq[ScriptElt]): Seq[ScriptElt] = pay2wsh(Script.write(script))
|
||||
|
||||
def pay2wsh(script: BinaryData): Seq[ScriptElt] = OP_0 :: OP_PUSHDATA(sha256(script)) :: Nil
|
||||
|
||||
def pay2wpkh(pubKey: BinaryData): Seq[ScriptElt] = OP_0 :: OP_PUSHDATA(hash160(pubKey)) :: Nil
|
||||
|
||||
/**
|
||||
*
|
||||
* @param pubkey1 public key for A
|
||||
* @param pubkey2 public key for B
|
||||
* @param amount funding tx amount
|
||||
* @param previousTx tx that will fund the funding tx; it * must * be a P2PWPK embedded in a standard P2SH tx: the p2sh
|
||||
* script is just the P2WPK script for the public key that matches our "key" parameter
|
||||
* @param outputIndex index of the output in the funding tx
|
||||
* @param key private key that can redeem the funding tx
|
||||
* @return a signed funding tx
|
||||
*/
|
||||
def makeAnchorTx(pubkey1: BinaryData, pubkey2: BinaryData, amount: Long, previousTx: Transaction, outputIndex: Int, key: BinaryData): (Transaction, Int) = {
|
||||
val tx = Transaction(version = 2,
|
||||
txIn = TxIn(outPoint = OutPoint(previousTx, outputIndex), signatureScript = Array.emptyByteArray, sequence = 0xffffffffL) :: Nil,
|
||||
txOut = TxOut(Satoshi(amount), publicKeyScript = pay2wsh(multiSig2of2(pubkey1, pubkey2))) :: Nil,
|
||||
lockTime = 0)
|
||||
val pub: BinaryData = Crypto.publicKeyFromPrivateKey(key)
|
||||
val pkh = OP_0 :: OP_PUSHDATA(Crypto.hash160(pub)) :: Nil
|
||||
val p2sh: BinaryData = Script.write(pay2sh(pkh))
|
||||
|
||||
require(p2sh == previousTx.txOut(outputIndex).publicKeyScript)
|
||||
|
||||
val pubKeyScript = Script.write(OP_DUP :: OP_HASH160 :: OP_PUSHDATA(Crypto.hash160(pub)) :: OP_EQUALVERIFY :: OP_CHECKSIG :: Nil)
|
||||
val hash = Transaction.hashForSigning(tx, 0, pubKeyScript, SIGHASH_ALL, tx.txOut(0).amount, signatureVersion = 1)
|
||||
val sig = Crypto.encodeSignature(Crypto.sign(hash, key.take(32))) :+ SIGHASH_ALL.toByte
|
||||
val witness = ScriptWitness(Seq(sig, pub))
|
||||
val script = Script.write(OP_0 :: OP_PUSHDATA(Crypto.hash160(pub)) :: Nil)
|
||||
val signedTx = tx.updateSigScript(0, OP_PUSHDATA(script) :: Nil).updateWitness(0, witness)
|
||||
|
||||
// we don't permute outputs because by convention the multisig output has index = 0
|
||||
(signedTx, 0)
|
||||
}
|
||||
|
||||
def anchorPubkeyScript(pubkey1: BinaryData, pubkey2: BinaryData): BinaryData = Script.write(pay2wsh(multiSig2of2(pubkey1, pubkey2)))
|
||||
|
||||
def encodeNumber(n: Long): BinaryData = {
|
||||
// TODO: added for compatibility with lightningd => check (it's either a bug in lighningd or bitcoin-lib)
|
||||
if (n < 0xff) Protocol.writeUInt8(n.toInt) else Script.encodeNumber(n)
|
||||
}
|
||||
|
||||
def redeemSecretOrDelay(delayedKey: BinaryData, reltimeout: Long, keyIfSecretKnown: BinaryData, hashOfSecret: BinaryData): Seq[ScriptElt] = {
|
||||
// @formatter:off
|
||||
OP_HASH160 :: OP_PUSHDATA(ripemd160(hashOfSecret)) :: OP_EQUAL ::
|
||||
OP_IF ::
|
||||
OP_PUSHDATA(keyIfSecretKnown) ::
|
||||
OP_ELSE ::
|
||||
OP_PUSHDATA(encodeNumber(reltimeout)) :: OP_CHECKSEQUENCEVERIFY :: OP_DROP :: OP_PUSHDATA(delayedKey) ::
|
||||
OP_ENDIF ::
|
||||
OP_CHECKSIG :: Nil
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
def scriptPubKeyHtlcSend(ourkey: BinaryData, theirkey: BinaryData, abstimeout: Long, reltimeout: Long, rhash: BinaryData, commit_revoke: BinaryData): Seq[ScriptElt] = {
|
||||
// values lesser than 16 should be encoded using OP_0..OP_16 instead of OP_PUSHDATA
|
||||
assert(abstimeout > 16, s"abstimeout=$abstimeout must be greater than 16")
|
||||
// @formatter:off
|
||||
OP_SIZE :: OP_PUSHDATA(encodeNumber(32)) :: OP_EQUALVERIFY ::
|
||||
OP_HASH160 :: OP_DUP ::
|
||||
OP_PUSHDATA(ripemd160(rhash)) :: OP_EQUAL ::
|
||||
OP_SWAP :: OP_PUSHDATA(ripemd160(commit_revoke)) :: OP_EQUAL :: OP_ADD ::
|
||||
OP_IF ::
|
||||
OP_PUSHDATA(theirkey) ::
|
||||
OP_ELSE ::
|
||||
OP_PUSHDATA(encodeNumber(abstimeout)) :: OP_CHECKLOCKTIMEVERIFY :: OP_PUSHDATA(encodeNumber(reltimeout)) :: OP_CHECKSEQUENCEVERIFY :: OP_2DROP :: OP_PUSHDATA(ourkey) ::
|
||||
OP_ENDIF ::
|
||||
OP_CHECKSIG :: Nil
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
def scriptPubKeyHtlcReceive(ourkey: BinaryData, theirkey: BinaryData, abstimeout: Long, reltimeout: Long, rhash: BinaryData, commit_revoke: BinaryData): Seq[ScriptElt] = {
|
||||
// values lesser than 16 should be encoded using OP_0..OP_16 instead of OP_PUSHDATA
|
||||
assert(abstimeout > 16, s"abstimeout=$abstimeout must be greater than 16")
|
||||
// @formatter:off
|
||||
OP_SIZE :: OP_PUSHDATA(encodeNumber(32)) :: OP_EQUALVERIFY ::
|
||||
OP_HASH160 :: OP_DUP ::
|
||||
OP_PUSHDATA(ripemd160(rhash)) :: OP_EQUAL ::
|
||||
OP_IF ::
|
||||
OP_PUSHDATA(encodeNumber(reltimeout)) :: OP_CHECKSEQUENCEVERIFY :: OP_2DROP :: OP_PUSHDATA(ourkey) ::
|
||||
OP_ELSE ::
|
||||
OP_PUSHDATA(ripemd160(commit_revoke)) :: OP_EQUAL ::
|
||||
OP_NOTIF ::
|
||||
OP_PUSHDATA(encodeNumber(abstimeout)) :: OP_CHECKLOCKTIMEVERIFY :: OP_DROP ::
|
||||
OP_ENDIF ::
|
||||
OP_PUSHDATA(theirkey) ::
|
||||
OP_ENDIF ::
|
||||
OP_CHECKSIG :: Nil
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
def applyFees(amount_us: Satoshi, amount_them: Satoshi, fee: Satoshi) = {
|
||||
val (amount_us1: Satoshi, amount_them1: Satoshi) = (amount_us, amount_them) match {
|
||||
case (Satoshi(us), Satoshi(them)) if us >= fee.toLong / 2 && them >= fee.toLong / 2 => (Satoshi(us - fee.toLong / 2), Satoshi(them - fee.toLong / 2))
|
||||
case (Satoshi(us), Satoshi(them)) if us < fee.toLong / 2 => (Satoshi(0L), Satoshi(Math.max(0L, them - fee.toLong + us)))
|
||||
case (Satoshi(us), Satoshi(them)) if them < fee.toLong / 2 => (Satoshi(Math.max(us - fee.toLong + them, 0L)), Satoshi(0L))
|
||||
}
|
||||
(amount_us1, amount_them1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a "final" channel transaction that will be published when the channel is closed
|
||||
*
|
||||
* @param inputs inputs to include in the tx. In most cases, there's only one input that points to the output of
|
||||
* the funding tx
|
||||
* @param ourPubkeyScript our public key script
|
||||
* @param theirPubkeyScript their public key script
|
||||
* @param amount_us pay to us
|
||||
* @param amount_them pay to them
|
||||
* @return an unsigned "final" tx
|
||||
*/
|
||||
def makeFinalTx(inputs: Seq[TxIn], ourPubkeyScript: BinaryData, theirPubkeyScript: BinaryData, amount_us: Satoshi, amount_them: Satoshi, fee: Satoshi): Transaction = {
|
||||
val (amount_us1: Satoshi, amount_them1: Satoshi) = applyFees(amount_us, amount_them, fee)
|
||||
|
||||
permuteOutputs(Transaction(
|
||||
version = 2,
|
||||
txIn = inputs,
|
||||
txOut = Seq(
|
||||
TxOut(amount = amount_us1, publicKeyScript = ourPubkeyScript),
|
||||
TxOut(amount = amount_them1, publicKeyScript = theirPubkeyScript)
|
||||
),
|
||||
lockTime = 0))
|
||||
}
|
||||
|
||||
//def isFunder(o: open_channel): Boolean = o.anch == open_channel.anchor_offer.WILL_CREATE_FUNDING
|
||||
|
||||
def findPublicKeyScriptIndex(tx: Transaction, publicKeyScript: BinaryData): Option[Int] =
|
||||
tx.txOut.zipWithIndex.find {
|
||||
case (TxOut(_, script), _) => script == publicKeyScript
|
||||
} map (_._2)
|
||||
|
||||
/**
|
||||
*
|
||||
* @param tx
|
||||
* @return the block height before which this tx cannot be published
|
||||
*/
|
||||
def cltvTimeout(tx: Transaction): Long = {
|
||||
require(tx.lockTime <= LockTimeThreshold)
|
||||
tx.lockTime
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param tx
|
||||
* @return the number of confirmations of the tx parent before which it can be published
|
||||
*/
|
||||
def csvTimeout(tx: Transaction): Long = {
|
||||
def sequenceToBlockHeight(sequence: Long): Long = {
|
||||
if ((sequence & TxIn.SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0) 0
|
||||
else {
|
||||
require((sequence & TxIn.SEQUENCE_LOCKTIME_TYPE_FLAG) == 0, "CSV timeout must use block heights, not block times")
|
||||
sequence & TxIn.SEQUENCE_LOCKTIME_MASK
|
||||
}
|
||||
}
|
||||
|
||||
if (tx.version < 2) 0
|
||||
else tx.txIn.map(_.sequence).map(sequenceToBlockHeight).max
|
||||
}
|
||||
}
|
|
@ -1,10 +1,234 @@
|
|||
package fr.acinq.eclair.transactions
|
||||
|
||||
import fr.acinq.bitcoin.{BinaryData, OP_2, OP_CHECKLOCKTIMEVERIFY, OP_CHECKMULTISIG, OP_CHECKSEQUENCEVERIFY, OP_CHECKSIG, OP_DROP, OP_ELSE, OP_ENDIF, OP_EQUAL, OP_EQUALVERIFY, OP_HASH160, OP_IF, OP_NOTIF, OP_PUSHDATA, OP_SIZE, OP_SWAP, Script}
|
||||
import fr.acinq.bitcoin.Crypto.{hash160, ripemd160, sha256}
|
||||
import fr.acinq.bitcoin.{BinaryData, Crypto, LockTimeThreshold, OP_0, OP_2, OP_2DROP, OP_ADD, OP_CHECKLOCKTIMEVERIFY, OP_CHECKMULTISIG, OP_CHECKSEQUENCEVERIFY, OP_CHECKSIG, OP_DROP, OP_DUP, OP_ELSE, OP_ENDIF, OP_EQUAL, OP_EQUALVERIFY, OP_HASH160, OP_IF, OP_NOTIF, OP_PUSHDATA, OP_SIZE, OP_SWAP, OutPoint, Protocol, SIGHASH_ALL, Satoshi, Script, ScriptElt, ScriptWitness, Transaction, TxIn, TxOut}
|
||||
import fr.acinq.eclair.memcmp
|
||||
|
||||
/**
|
||||
* Created by PM on 02/12/2016.
|
||||
*/
|
||||
object Common {
|
||||
|
||||
def toSelfDelay2csv(in: Int): Long = ???
|
||||
|
||||
/*in match {
|
||||
case locktime(Blocks(blocks)) => blocks
|
||||
case locktime(Seconds(seconds)) => TxIn.SEQUENCE_LOCKTIME_TYPE_FLAG | (seconds >> TxIn.SEQUENCE_LOCKTIME_GRANULARITY)
|
||||
}*/
|
||||
|
||||
def expiry2cltv(in: Long): Long = ???
|
||||
|
||||
/*in match {
|
||||
case locktime(Blocks(blocks)) => blocks
|
||||
case locktime(Seconds(seconds)) => seconds
|
||||
}*/
|
||||
|
||||
def isLess(a: Seq[Byte], b: Seq[Byte]): Boolean = memcmp(a.dropWhile(_ == 0).toList, b.dropWhile(_ == 0).toList) < 0
|
||||
|
||||
def lessThan(output1: TxOut, output2: TxOut): Boolean = (output1, output2) match {
|
||||
case (TxOut(amount1, script1), TxOut(amount2, script2)) if amount1 == amount2 => memcmp(script1.toList, script2.toList) < 0
|
||||
case (TxOut(amount1, _), TxOut(amount2, _)) => amount1.toLong < amount2.toLong
|
||||
}
|
||||
|
||||
def permuteOutputs(tx: Transaction): Transaction = tx.copy(txOut = tx.txOut.sortWith(lessThan))
|
||||
|
||||
def multiSig2of2(pubkey1: BinaryData, pubkey2: BinaryData): BinaryData = if (isLess(pubkey1, pubkey2))
|
||||
Script.createMultiSigMofN(2, Seq(pubkey1, pubkey2))
|
||||
else
|
||||
Script.createMultiSigMofN(2, Seq(pubkey2, pubkey1))
|
||||
|
||||
|
||||
def sigScript2of2(sig1: BinaryData, sig2: BinaryData, pubkey1: BinaryData, pubkey2: BinaryData): BinaryData = if (isLess(pubkey1, pubkey2))
|
||||
Script.write(OP_0 :: OP_PUSHDATA(sig1) :: OP_PUSHDATA(sig2) :: OP_PUSHDATA(multiSig2of2(pubkey1, pubkey2)) :: Nil)
|
||||
else
|
||||
Script.write(OP_0 :: OP_PUSHDATA(sig2) :: OP_PUSHDATA(sig1) :: OP_PUSHDATA(multiSig2of2(pubkey1, pubkey2)) :: Nil)
|
||||
|
||||
/**
|
||||
*
|
||||
* @param sig1
|
||||
* @param sig2
|
||||
* @param pubkey1
|
||||
* @param pubkey2
|
||||
* @return a script witness that matches the msig 2-of-2 pubkey script for pubkey1 and pubkey2
|
||||
*/
|
||||
def witness2of2(sig1: BinaryData, sig2: BinaryData, pubkey1: BinaryData, pubkey2: BinaryData): ScriptWitness = {
|
||||
if (isLess(pubkey1, pubkey2))
|
||||
ScriptWitness(Seq(BinaryData.empty, sig1, sig2, multiSig2of2(pubkey1, pubkey2)))
|
||||
else
|
||||
ScriptWitness(Seq(BinaryData.empty, sig2, sig1, multiSig2of2(pubkey1, pubkey2)))
|
||||
|
||||
}
|
||||
|
||||
def pay2pkh(pubKey: BinaryData): Seq[ScriptElt] = OP_DUP :: OP_HASH160 :: OP_PUSHDATA(hash160(pubKey)) :: OP_EQUALVERIFY :: OP_CHECKSIG :: Nil
|
||||
|
||||
def pay2sh(script: Seq[ScriptElt]): Seq[ScriptElt] = pay2sh(Script.write(script))
|
||||
|
||||
def pay2sh(script: BinaryData): Seq[ScriptElt] = OP_HASH160 :: OP_PUSHDATA(hash160(script)) :: OP_EQUAL :: Nil
|
||||
|
||||
def pay2wsh(script: Seq[ScriptElt]): Seq[ScriptElt] = pay2wsh(Script.write(script))
|
||||
|
||||
def pay2wsh(script: BinaryData): Seq[ScriptElt] = OP_0 :: OP_PUSHDATA(sha256(script)) :: Nil
|
||||
|
||||
def pay2wpkh(pubKey: BinaryData): Seq[ScriptElt] = OP_0 :: OP_PUSHDATA(hash160(pubKey)) :: Nil
|
||||
|
||||
/**
|
||||
*
|
||||
* @param pubkey1 public key for A
|
||||
* @param pubkey2 public key for B
|
||||
* @param amount funding tx amount
|
||||
* @param previousTx tx that will fund the funding tx; it * must * be a P2PWPK embedded in a standard P2SH tx: the p2sh
|
||||
* script is just the P2WPK script for the public key that matches our "key" parameter
|
||||
* @param outputIndex index of the output in the funding tx
|
||||
* @param key private key that can redeem the funding tx
|
||||
* @return a signed funding tx
|
||||
*/
|
||||
def makeAnchorTx(pubkey1: BinaryData, pubkey2: BinaryData, amount: Long, previousTx: Transaction, outputIndex: Int, key: BinaryData): (Transaction, Int) = {
|
||||
val tx = Transaction(version = 2,
|
||||
txIn = TxIn(outPoint = OutPoint(previousTx, outputIndex), signatureScript = Array.emptyByteArray, sequence = 0xffffffffL) :: Nil,
|
||||
txOut = TxOut(Satoshi(amount), publicKeyScript = pay2wsh(multiSig2of2(pubkey1, pubkey2))) :: Nil,
|
||||
lockTime = 0)
|
||||
val pub: BinaryData = Crypto.publicKeyFromPrivateKey(key)
|
||||
val pkh = OP_0 :: OP_PUSHDATA(Crypto.hash160(pub)) :: Nil
|
||||
val p2sh: BinaryData = Script.write(pay2sh(pkh))
|
||||
|
||||
require(p2sh == previousTx.txOut(outputIndex).publicKeyScript)
|
||||
|
||||
val pubKeyScript = Script.write(OP_DUP :: OP_HASH160 :: OP_PUSHDATA(Crypto.hash160(pub)) :: OP_EQUALVERIFY :: OP_CHECKSIG :: Nil)
|
||||
val hash = Transaction.hashForSigning(tx, 0, pubKeyScript, SIGHASH_ALL, tx.txOut(0).amount, signatureVersion = 1)
|
||||
val sig = Crypto.encodeSignature(Crypto.sign(hash, key.take(32))) :+ SIGHASH_ALL.toByte
|
||||
val witness = ScriptWitness(Seq(sig, pub))
|
||||
val script = Script.write(OP_0 :: OP_PUSHDATA(Crypto.hash160(pub)) :: Nil)
|
||||
val signedTx = tx.updateSigScript(0, OP_PUSHDATA(script) :: Nil).updateWitness(0, witness)
|
||||
|
||||
// we don't permute outputs because by convention the multisig output has index = 0
|
||||
(signedTx, 0)
|
||||
}
|
||||
|
||||
def anchorPubkeyScript(pubkey1: BinaryData, pubkey2: BinaryData): BinaryData = Script.write(pay2wsh(multiSig2of2(pubkey1, pubkey2)))
|
||||
|
||||
def encodeNumber(n: Long): BinaryData = {
|
||||
// TODO: added for compatibility with lightningd => check (it's either a bug in lighningd or bitcoin-lib)
|
||||
if (n < 0xff) Protocol.writeUInt8(n.toInt) else Script.encodeNumber(n)
|
||||
}
|
||||
|
||||
def redeemSecretOrDelay(delayedKey: BinaryData, reltimeout: Long, keyIfSecretKnown: BinaryData, hashOfSecret: BinaryData): Seq[ScriptElt] = {
|
||||
// @formatter:off
|
||||
OP_HASH160 :: OP_PUSHDATA(ripemd160(hashOfSecret)) :: OP_EQUAL ::
|
||||
OP_IF ::
|
||||
OP_PUSHDATA(keyIfSecretKnown) ::
|
||||
OP_ELSE ::
|
||||
OP_PUSHDATA(encodeNumber(reltimeout)) :: OP_CHECKSEQUENCEVERIFY :: OP_DROP :: OP_PUSHDATA(delayedKey) ::
|
||||
OP_ENDIF ::
|
||||
OP_CHECKSIG :: Nil
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
def scriptPubKeyHtlcSend(ourkey: BinaryData, theirkey: BinaryData, abstimeout: Long, reltimeout: Long, rhash: BinaryData, commit_revoke: BinaryData): Seq[ScriptElt] = {
|
||||
// values lesser than 16 should be encoded using OP_0..OP_16 instead of OP_PUSHDATA
|
||||
assert(abstimeout > 16, s"abstimeout=$abstimeout must be greater than 16")
|
||||
// @formatter:off
|
||||
OP_SIZE :: OP_PUSHDATA(encodeNumber(32)) :: OP_EQUALVERIFY ::
|
||||
OP_HASH160 :: OP_DUP ::
|
||||
OP_PUSHDATA(ripemd160(rhash)) :: OP_EQUAL ::
|
||||
OP_SWAP :: OP_PUSHDATA(ripemd160(commit_revoke)) :: OP_EQUAL :: OP_ADD ::
|
||||
OP_IF ::
|
||||
OP_PUSHDATA(theirkey) ::
|
||||
OP_ELSE ::
|
||||
OP_PUSHDATA(encodeNumber(abstimeout)) :: OP_CHECKLOCKTIMEVERIFY :: OP_PUSHDATA(encodeNumber(reltimeout)) :: OP_CHECKSEQUENCEVERIFY :: OP_2DROP :: OP_PUSHDATA(ourkey) ::
|
||||
OP_ENDIF ::
|
||||
OP_CHECKSIG :: Nil
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
def scriptPubKeyHtlcReceive(ourkey: BinaryData, theirkey: BinaryData, abstimeout: Long, reltimeout: Long, rhash: BinaryData, commit_revoke: BinaryData): Seq[ScriptElt] = {
|
||||
// values lesser than 16 should be encoded using OP_0..OP_16 instead of OP_PUSHDATA
|
||||
assert(abstimeout > 16, s"abstimeout=$abstimeout must be greater than 16")
|
||||
// @formatter:off
|
||||
OP_SIZE :: OP_PUSHDATA(encodeNumber(32)) :: OP_EQUALVERIFY ::
|
||||
OP_HASH160 :: OP_DUP ::
|
||||
OP_PUSHDATA(ripemd160(rhash)) :: OP_EQUAL ::
|
||||
OP_IF ::
|
||||
OP_PUSHDATA(encodeNumber(reltimeout)) :: OP_CHECKSEQUENCEVERIFY :: OP_2DROP :: OP_PUSHDATA(ourkey) ::
|
||||
OP_ELSE ::
|
||||
OP_PUSHDATA(ripemd160(commit_revoke)) :: OP_EQUAL ::
|
||||
OP_NOTIF ::
|
||||
OP_PUSHDATA(encodeNumber(abstimeout)) :: OP_CHECKLOCKTIMEVERIFY :: OP_DROP ::
|
||||
OP_ENDIF ::
|
||||
OP_PUSHDATA(theirkey) ::
|
||||
OP_ENDIF ::
|
||||
OP_CHECKSIG :: Nil
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
def applyFees(amount_us: Satoshi, amount_them: Satoshi, fee: Satoshi) = {
|
||||
val (amount_us1: Satoshi, amount_them1: Satoshi) = (amount_us, amount_them) match {
|
||||
case (Satoshi(us), Satoshi(them)) if us >= fee.toLong / 2 && them >= fee.toLong / 2 => (Satoshi(us - fee.toLong / 2), Satoshi(them - fee.toLong / 2))
|
||||
case (Satoshi(us), Satoshi(them)) if us < fee.toLong / 2 => (Satoshi(0L), Satoshi(Math.max(0L, them - fee.toLong + us)))
|
||||
case (Satoshi(us), Satoshi(them)) if them < fee.toLong / 2 => (Satoshi(Math.max(us - fee.toLong + them, 0L)), Satoshi(0L))
|
||||
}
|
||||
(amount_us1, amount_them1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a "final" channel transaction that will be published when the channel is closed
|
||||
*
|
||||
* @param inputs inputs to include in the tx. In most cases, there's only one input that points to the output of
|
||||
* the funding tx
|
||||
* @param ourPubkeyScript our public key script
|
||||
* @param theirPubkeyScript their public key script
|
||||
* @param amount_us pay to us
|
||||
* @param amount_them pay to them
|
||||
* @return an unsigned "final" tx
|
||||
*/
|
||||
def makeFinalTx(inputs: Seq[TxIn], ourPubkeyScript: BinaryData, theirPubkeyScript: BinaryData, amount_us: Satoshi, amount_them: Satoshi, fee: Satoshi): Transaction = {
|
||||
val (amount_us1: Satoshi, amount_them1: Satoshi) = applyFees(amount_us, amount_them, fee)
|
||||
|
||||
permuteOutputs(Transaction(
|
||||
version = 2,
|
||||
txIn = inputs,
|
||||
txOut = Seq(
|
||||
TxOut(amount = amount_us1, publicKeyScript = ourPubkeyScript),
|
||||
TxOut(amount = amount_them1, publicKeyScript = theirPubkeyScript)
|
||||
),
|
||||
lockTime = 0))
|
||||
}
|
||||
|
||||
//def isFunder(o: open_channel): Boolean = o.anch == open_channel.anchor_offer.WILL_CREATE_FUNDING
|
||||
|
||||
def findPublicKeyScriptIndex(tx: Transaction, publicKeyScript: BinaryData): Option[Int] =
|
||||
tx.txOut.zipWithIndex.find {
|
||||
case (TxOut(_, script), _) => script == publicKeyScript
|
||||
} map (_._2)
|
||||
|
||||
/**
|
||||
*
|
||||
* @param tx
|
||||
* @return the block height before which this tx cannot be published
|
||||
*/
|
||||
def cltvTimeout(tx: Transaction): Long = {
|
||||
require(tx.lockTime <= LockTimeThreshold)
|
||||
tx.lockTime
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param tx
|
||||
* @return the number of confirmations of the tx parent before which it can be published
|
||||
*/
|
||||
def csvTimeout(tx: Transaction): Long = {
|
||||
def sequenceToBlockHeight(sequence: Long): Long = {
|
||||
if ((sequence & TxIn.SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0) 0
|
||||
else {
|
||||
require((sequence & TxIn.SEQUENCE_LOCKTIME_TYPE_FLAG) == 0, "CSV timeout must use block heights, not block times")
|
||||
sequence & TxIn.SEQUENCE_LOCKTIME_MASK
|
||||
}
|
||||
}
|
||||
|
||||
if (tx.version < 2) 0
|
||||
else tx.txIn.map(_.sequence).map(sequenceToBlockHeight).max
|
||||
}
|
||||
}
|
||||
|
||||
object OutputScripts {
|
||||
|
||||
def toLocal(revocationPubKey: BinaryData, toSelfDelay: Int, localDelayedKey: BinaryData) = {
|
||||
|
|
|
@ -14,11 +14,11 @@ object Signature {
|
|||
def sign(localParams: LocalParams, remoteParams: RemoteParams, fundingSatoshis: Satoshi, tx: Transaction): BinaryData = {
|
||||
// this is because by convention in bitcoin-core-speak 32B keys are 'uncompressed' and 33B keys (ending by 0x01) are 'compressed'
|
||||
val localCompressedFundingPrivkey: Seq[Byte] = localParams.fundingPrivkey.data.toSeq :+ 1.toByte
|
||||
Transaction.signInput(tx, 0, OldScripts.multiSig2of2(localParams.fundingPrivkey.point, remoteParams.fundingPubkey), SIGHASH_ALL, fundingSatoshis, 1, localCompressedFundingPrivkey)
|
||||
Transaction.signInput(tx, 0, Common.multiSig2of2(localParams.fundingPrivkey.point, remoteParams.fundingPubkey), SIGHASH_ALL, fundingSatoshis, 1, localCompressedFundingPrivkey)
|
||||
}
|
||||
|
||||
def addSigs(tx: Transaction, localFundingPubkey: Point, remoteFundingPubkey: Point, localSig: BinaryData, remoteSig: BinaryData): Transaction = {
|
||||
val witness = OldScripts.witness2of2(localSig, remoteSig, localFundingPubkey, remoteFundingPubkey)
|
||||
val witness = Common.witness2of2(localSig, remoteSig, localFundingPubkey, remoteFundingPubkey)
|
||||
tx.updateWitness(0, witness)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package fr.acinq.eclair.transactions
|
||||
|
||||
import fr.acinq.bitcoin.{BinaryData, Crypto, OP_CHECKSIG, OP_DUP, OP_EQUALVERIFY, OP_HASH160, OP_PUSHDATA, Satoshi, Script, ScriptElt, Transaction, TxIn, TxOut}
|
||||
import fr.acinq.eclair.transactions.OldScripts._
|
||||
import fr.acinq.eclair.transactions.Common._
|
||||
|
||||
/**
|
||||
* Created by PM on 06/12/2016.
|
||||
|
@ -101,8 +101,8 @@ case class HTLCTemplate(htlc: Htlc, ourKey: BinaryData, theirKey: BinaryData, de
|
|||
override def amount = Satoshi(htlc.add.amountMsat / 1000)
|
||||
|
||||
override def redeemScript = htlc.direction match {
|
||||
case IN => Script.write(OldScripts.scriptPubKeyHtlcReceive(ourKey, theirKey, expiry2cltv(htlc.add.expiry), toSelfDelay2csv(delay), htlc.add.paymentHash, revocationHash))
|
||||
case OUT => Script.write(OldScripts.scriptPubKeyHtlcSend(ourKey, theirKey, expiry2cltv(htlc.add.expiry), toSelfDelay2csv(delay), htlc.add.paymentHash, revocationHash))
|
||||
case IN => Script.write(Common.scriptPubKeyHtlcReceive(ourKey, theirKey, expiry2cltv(htlc.add.expiry), toSelfDelay2csv(delay), htlc.add.paymentHash, revocationHash))
|
||||
case OUT => Script.write(Common.scriptPubKeyHtlcSend(ourKey, theirKey, expiry2cltv(htlc.add.expiry), toSelfDelay2csv(delay), htlc.add.paymentHash, revocationHash))
|
||||
}
|
||||
|
||||
override def txOut = TxOut(amount, pay2wsh(redeemScript))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package fr.acinq.protos
|
||||
|
||||
import fr.acinq.bitcoin._
|
||||
import fr.acinq.eclair.transactions.OldScripts
|
||||
import fr.acinq.eclair.transactions.Common
|
||||
|
||||
object Bolt3 {
|
||||
// TODO: sort tx according to BIP69 (lexicographical ordering)
|
||||
|
@ -12,7 +12,7 @@ object Bolt3 {
|
|||
|
||||
def weight(tx: Transaction) = 3 * baseSize(tx) + totalSize(tx)
|
||||
|
||||
def fundingScript(pubKey1: BinaryData, pubKey2: BinaryData) = OldScripts.multiSig2of2(pubKey1, pubKey2)
|
||||
def fundingScript(pubKey1: BinaryData, pubKey2: BinaryData) = Common.multiSig2of2(pubKey1, pubKey2)
|
||||
|
||||
def toLocal(revocationPubKey: BinaryData, toSelfDelay: Long, localDelayedKey: BinaryData) = {
|
||||
// @formatter:off
|
||||
|
|
|
@ -5,7 +5,7 @@ import fr.acinq.bitcoin.{BinaryData, Satoshi, Transaction, TxIn, TxOut}
|
|||
import fr.acinq.eclair.blockchain.ExtendedBitcoinClient
|
||||
import fr.acinq.eclair.blockchain.peer.{NewBlock, NewTransaction}
|
||||
import fr.acinq.eclair.blockchain.rpc.BitcoinJsonRPCClient
|
||||
import fr.acinq.eclair.transactions.OldScripts
|
||||
import fr.acinq.eclair.transactions.Common
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
@ -24,7 +24,7 @@ class TestBitcoinClient()(implicit system: ActorSystem) extends ExtendedBitcoinC
|
|||
override def makeAnchorTx(ourCommitPub: BinaryData, theirCommitPub: BinaryData, amount: Satoshi)(implicit ec: ExecutionContext): Future[(Transaction, Int)] = {
|
||||
val anchorTx = Transaction(version = 1,
|
||||
txIn = Seq.empty[TxIn],
|
||||
txOut = TxOut(amount, OldScripts.anchorPubkeyScript(ourCommitPub, theirCommitPub)) :: Nil,
|
||||
txOut = TxOut(amount, Common.anchorPubkeyScript(ourCommitPub, theirCommitPub)) :: Nil,
|
||||
lockTime = 0
|
||||
)
|
||||
Future.successful((anchorTx, 0))
|
||||
|
|
|
@ -8,7 +8,7 @@ import fr.acinq.eclair.TestConstants.{Alice, Bob}
|
|||
import fr.acinq.eclair.blockchain._
|
||||
import fr.acinq.eclair.channel.states.{StateSpecBaseClass, StateTestsHelperMethods}
|
||||
import fr.acinq.eclair.channel.{BITCOIN_FUNDING_DEPTHOK, Data, State, _}
|
||||
import fr.acinq.eclair.transactions.{IN, OldScripts}
|
||||
import fr.acinq.eclair.transactions.{IN, Common}
|
||||
import fr.acinq.eclair.wire.{AcceptChannel, ClosingSigned, CommitSig, Error, FundingCreated, FundingLocked, FundingSigned, OpenChannel, RevokeAndAck, Shutdown, UpdateAddHtlc, UpdateFailHtlc, UpdateFulfillHtlc}
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
|
@ -697,7 +697,7 @@ class NormalStateSpec extends StateSpecBaseClass with StateTestsHelperMethods {
|
|||
// the punishment tx consumes all output but ours (which already goes to our final key)
|
||||
assert(punishTx.txIn.size == 5)
|
||||
// TODO: when changefee is implemented we should set fee = 0 and check against 304 000
|
||||
assert(punishTx.txOut == Seq(TxOut(Satoshi(301670), Script.write(OldScripts.pay2wpkh(Alice.channelParams.finalPrivKey.point)))))
|
||||
assert(punishTx.txOut == Seq(TxOut(Satoshi(301670), Script.write(Common.pay2wpkh(Alice.channelParams.finalPrivKey.point)))))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import fr.acinq.eclair.TestConstants.{Alice, Bob}
|
|||
import fr.acinq.eclair.blockchain._
|
||||
import fr.acinq.eclair.channel.states.{StateSpecBaseClass, StateTestsHelperMethods}
|
||||
import fr.acinq.eclair.channel.{BITCOIN_FUNDING_DEPTHOK, Data, State, _}
|
||||
import fr.acinq.eclair.transactions.OldScripts
|
||||
import fr.acinq.eclair.transactions.Common
|
||||
import fr.acinq.eclair.wire.{AcceptChannel, CommitSig, Error, FundingCreated, FundingLocked, FundingSigned, OpenChannel, RevokeAndAck, Shutdown, UpdateAddHtlc, UpdateFailHtlc, UpdateFulfillHtlc}
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
|
@ -424,7 +424,7 @@ class ShutdownStateSpec extends StateSpecBaseClass with StateTestsHelperMethods
|
|||
assert(revokedTx.txOut.size == 3)
|
||||
// the punishment tx consumes all output but ours (which already goes to our final key)
|
||||
assert(punishTx.txIn.size == 2)
|
||||
assert(punishTx.txOut == Seq(TxOut(Satoshi(500000), Script.write(OldScripts.pay2wpkh(Alice.channelParams.finalPrivKey.point)))))
|
||||
assert(punishTx.txOut == Seq(TxOut(Satoshi(500000), Script.write(Common.pay2wpkh(Alice.channelParams.finalPrivKey.point)))))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package fr.acinq.eclair.transactions
|
||||
|
||||
import fr.acinq.bitcoin._
|
||||
import fr.acinq.eclair.transactions.OldScripts._
|
||||
import fr.acinq.eclair.transactions.Common._
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.FunSuite
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package fr.acinq.eclair.transactions
|
||||
|
||||
import fr.acinq.bitcoin._
|
||||
import fr.acinq.eclair.transactions.OldScripts._
|
||||
import fr.acinq.eclair.transactions.Common._
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.FunSuite
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package fr.acinq.eclair.transactions
|
||||
|
||||
import fr.acinq.bitcoin._
|
||||
import fr.acinq.eclair.transactions.OldScripts._
|
||||
import fr.acinq.eclair.transactions.Common._
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.FlatSpec
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
|
|
|
@ -7,7 +7,7 @@ import fr.acinq.eclair.blockchain.ExtendedBitcoinClient
|
|||
import fr.acinq.eclair.blockchain.rpc.BitcoinJsonRPCClient
|
||||
import fr.acinq.eclair.crypto.Generators
|
||||
import fr.acinq.eclair.crypto.Generators.Scalar
|
||||
import fr.acinq.eclair.transactions.OldScripts
|
||||
import fr.acinq.eclair.transactions.Common
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.FunSuite
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
|
@ -87,7 +87,7 @@ class Bolt3Spec extends FunSuite {
|
|||
println(s"local sig size: ${localSig.length}")
|
||||
val remoteSig: BinaryData = Transaction.signInput(tx, 0, redeemScript, SIGHASH_ALL, fundingTx.txOut(fundingPos).amount, SigVersion.SIGVERSION_WITNESS_V0, remotePrivKey)
|
||||
println(s"remote sig size: ${remoteSig.length}")
|
||||
val witness = if (OldScripts.isLess(localPubKey, remotePubKey))
|
||||
val witness = if (Common.isLess(localPubKey, remotePubKey))
|
||||
ScriptWitness(BinaryData.empty :: localSig :: remoteSig :: redeemScript :: Nil)
|
||||
else
|
||||
ScriptWitness(BinaryData.empty :: remoteSig :: localSig :: redeemScript :: Nil)
|
||||
|
|
Loading…
Add table
Reference in a new issue