diff --git a/C/bitcoin/bitcoinJets.c b/C/bitcoin/bitcoinJets.c index 850b20e1..0964f057 100644 --- a/C/bitcoin/bitcoinJets.c +++ b/C/bitcoin/bitcoinJets.c @@ -41,12 +41,26 @@ static uint_fast32_t lockTime(const bitcoinTransaction* tx) { return !tx->isFinal && 500000000U <= tx->lockTime ? tx->lockTime : 0; } -static uint_fast16_t lockDistance(const bitcoinTransaction* tx) { - return 2 <= tx->version ? tx->lockDistance : 0; +static uint_fast16_t lockDistance(const bitcoinTransaction* tx, uint_fast32_t ix) { + simplicity_assert(ix < tx->numInputs); + if (2 <= tx->version && + tx->input[ix].sequence < 0x80000000 && + !(tx->input[ix].sequence & ((uint_fast32_t)1 << 22))) { + return tx->input[ix].sequence & 0xffff; + } else { + return 0; + } } -static uint_fast16_t lockDuration(const bitcoinTransaction* tx) { - return 2 <= tx->version ? tx->lockDuration : 0; +static uint_fast16_t lockDuration(const bitcoinTransaction* tx, uint_fast32_t ix) { + simplicity_assert(ix < tx->numInputs); + if (2 <= tx->version && + tx->input[ix].sequence < 0x80000000 && + !!(tx->input[ix].sequence & ((uint_fast32_t)1 << 22))) { + return tx->input[ix].sequence & 0xffff; + } else { + return 0; + } } /* version : ONE |- TWO^32 */ @@ -312,14 +326,16 @@ bool simplicity_bitcoin_tx_lock_time(frameItem* dst, frameItem src, const txEnv* /* tx_lock_distance : ONE |- TWO^16 */ bool simplicity_bitcoin_tx_lock_distance(frameItem* dst, frameItem src, const txEnv* env) { (void) src; // src is unused; - simplicity_write16(dst, lockDistance(env->tx)); + if (env->tx->numInputs <= env->ix) return false; + simplicity_write16(dst, lockDistance(env->tx, env->ix)); return true; } /* tx_lock_duration : ONE |- TWO^16 */ bool simplicity_bitcoin_tx_lock_duration(frameItem* dst, frameItem src, const txEnv* env) { (void) src; // src is unused; - simplicity_write16(dst, lockDuration(env->tx)); + if (env->tx->numInputs <= env->ix) return false; + simplicity_write16(dst, lockDuration(env->tx, env->ix)); return true; } @@ -340,15 +356,17 @@ bool simplicity_bitcoin_check_lock_time(frameItem* dst, frameItem src, const txE /* check_lock_distance : TWO^16 |- ONE */ bool simplicity_bitcoin_check_lock_distance(frameItem* dst, frameItem src, const txEnv* env) { (void) dst; // dst is unused; + if (env->tx->numInputs <= env->ix) return false; uint_fast16_t x = simplicity_read16(&src); - return x <= lockDistance(env->tx); + return x <= lockDistance(env->tx, env->ix); } /* check_lock_duration : TWO^16 |- ONE */ bool simplicity_bitcoin_check_lock_duration(frameItem* dst, frameItem src, const txEnv* env) { (void) dst; // dst is unused; + if (env->tx->numInputs <= env->ix) return false; uint_fast16_t x = simplicity_read16(&src); - return x <= lockDuration(env->tx); + return x <= lockDuration(env->tx, env->ix); } /* build_tapleaf_simplicity : TWO^256 |- TWO^256 */ diff --git a/C/bitcoin/env.c b/C/bitcoin/env.c index 5d4bcd6b..85341aff 100644 --- a/C/bitcoin/env.c +++ b/C/bitcoin/env.c @@ -114,14 +114,6 @@ extern bitcoinTransaction* simplicity_bitcoin_mallocTransaction(const rawBitcoin copyInput(&input[i], &rawTx->input[i]); tx->totalInputValue += input[i].txo.value; if (input[i].sequence < 0xffffffff) { tx->isFinal = false; } - if (input[i].sequence < 0x80000000) { - const uint_fast16_t maskedSequence = input[i].sequence & 0xffff; - if (input[i].sequence & ((uint_fast32_t)1 << 22)) { - if (tx->lockDuration < maskedSequence) tx->lockDuration = maskedSequence; - } else { - if (tx->lockDistance < maskedSequence) tx->lockDistance = maskedSequence; - } - } sha256_hash(&ctx_inputOutpointsHash, &input[i].prevOutpoint.txid); sha256_u32be(&ctx_inputOutpointsHash, input[i].prevOutpoint.ix); sha256_u64be(&ctx_inputValuesHash, input[i].txo.value); diff --git a/C/bitcoin/primitiveJetNode.inc b/C/bitcoin/primitiveJetNode.inc index 95914222..b292250c 100644 --- a/C/bitcoin/primitiveJetNode.inc +++ b/C/bitcoin/primitiveJetNode.inc @@ -186,7 +186,7 @@ ,[CHECK_LOCK_DISTANCE] = { .tag = JET , .jet = simplicity_bitcoin_check_lock_distance -, .cmr = {{0xdbaa6fedu, 0xb73b2e31u, 0xa80ccbd1u, 0x4daaa5b8u, 0xce212cdeu, 0x0cbfd96du, 0x5db9715fu, 0xd19f8899u}} +, .cmr = {{0x38fdf7ddu, 0x28538670u, 0xfb34c1bfu, 0xe72f17e2u, 0xca5784f8u, 0x7fed88eau, 0xb584792bu, 0x3974bd18u}} , .sourceIx = ty_w16 , .targetIx = ty_u , .cost = 84 /* milli weight units */ @@ -194,7 +194,7 @@ ,[CHECK_LOCK_DURATION] = { .tag = JET , .jet = simplicity_bitcoin_check_lock_duration -, .cmr = {{0xdde93f33u, 0xf9b9d1d3u, 0xa3f2b3e8u, 0xb90f6d8bu, 0xeffccb45u, 0x81210eeau, 0xf06bd32fu, 0x6319df6eu}} +, .cmr = {{0x77503832u, 0x6eae25c7u, 0x209b2443u, 0x06eaa9f9u, 0x204c7eceu, 0x2dd63b45u, 0x2e10017fu, 0xa4ea53cfu}} , .sourceIx = ty_w16 , .targetIx = ty_u , .cost = 78 /* milli weight units */ @@ -3298,7 +3298,7 @@ ,[TX_LOCK_DISTANCE] = { .tag = JET , .jet = simplicity_bitcoin_tx_lock_distance -, .cmr = {{0x8c0b0c44u, 0x2bc20978u, 0xfa4c2b3du, 0x52a7fe7cu, 0x3f86e3d2u, 0x1b42130eu, 0xbb8dba45u, 0xe0f5e64bu}} +, .cmr = {{0xb6fbaac2u, 0x10a306beu, 0x8b58d0d7u, 0xb1563f62u, 0x2336d2aeu, 0xb56c393du, 0x276445a9u, 0xa22cc4a7u}} , .sourceIx = ty_u , .targetIx = ty_w16 , .cost = 72 /* milli weight units */ @@ -3306,7 +3306,7 @@ ,[TX_LOCK_DURATION] = { .tag = JET , .jet = simplicity_bitcoin_tx_lock_duration -, .cmr = {{0x09b18d5cu, 0x2f08402bu, 0xbcf8c31eu, 0xa43435efu, 0xffd9ea0eu, 0xf8758f76u, 0xbb27272bu, 0x4d60dc62u}} +, .cmr = {{0x53572818u, 0xe7e5b98fu, 0x968c9da7u, 0xdf5090d9u, 0x826f9bcfu, 0x84b63639u, 0x5eea321bu, 0x6909ece9u}} , .sourceIx = ty_u , .targetIx = ty_w16 , .cost = 66 /* milli weight units */ diff --git a/C/bitcoin/txEnv.h b/C/bitcoin/txEnv.h index 1095e05b..1eb773ea 100644 --- a/C/bitcoin/txEnv.h +++ b/C/bitcoin/txEnv.h @@ -60,11 +60,6 @@ typedef struct bitcoinTransaction { uint_fast32_t numOutputs; uint_fast32_t version; uint_fast32_t lockTime; - /* lockDuration and lockDistance values are set even when the version is 0 or 1. - * This is similar to lockTime whose value is also set, even when the transaction is final. - */ - uint_fast16_t lockDistance; - uint_fast16_t lockDuration; /* Units of 512 seconds */ bool isFinal; } bitcoinTransaction; diff --git a/C/elements/decodeElementsJets.inc b/C/elements/decodeElementsJets.inc index b2478e45..8420f64c 100644 --- a/C/elements/decodeElementsJets.inc +++ b/C/elements/decodeElementsJets.inc @@ -52,12 +52,12 @@ switch (code) { case 1: *result = CHECK_LOCK_HEIGHT; return SIMPLICITY_NO_ERROR; case 2: *result = CHECK_LOCK_TIME; return SIMPLICITY_NO_ERROR; - case 3: *result = CHECK_LOCK_DISTANCE; return SIMPLICITY_NO_ERROR; - case 4: *result = CHECK_LOCK_DURATION; return SIMPLICITY_NO_ERROR; + case 3: *result = BROKEN_DO_NOT_USE_CHECK_LOCK_DISTANCE; return SIMPLICITY_NO_ERROR; + case 4: *result = BROKEN_DO_NOT_USE_CHECK_LOCK_DURATION; return SIMPLICITY_NO_ERROR; case 5: *result = TX_LOCK_HEIGHT; return SIMPLICITY_NO_ERROR; case 6: *result = TX_LOCK_TIME; return SIMPLICITY_NO_ERROR; - case 7: *result = TX_LOCK_DISTANCE; return SIMPLICITY_NO_ERROR; - case 8: *result = TX_LOCK_DURATION; return SIMPLICITY_NO_ERROR; + case 7: *result = BROKEN_DO_NOT_USE_TX_LOCK_DISTANCE; return SIMPLICITY_NO_ERROR; + case 8: *result = BROKEN_DO_NOT_USE_TX_LOCK_DURATION; return SIMPLICITY_NO_ERROR; case 9: *result = TX_IS_FINAL; return SIMPLICITY_NO_ERROR; } break; diff --git a/C/elements/elementsJets.c b/C/elements/elementsJets.c index dfdf5be6..93b2c584 100644 --- a/C/elements/elementsJets.c +++ b/C/elements/elementsJets.c @@ -153,12 +153,12 @@ static uint_fast32_t lockTime(const elementsTransaction* tx) { return !tx->isFinal && 500000000U <= tx->lockTime ? tx->lockTime : 0; } -static uint_fast16_t lockDistance(const elementsTransaction* tx) { - return 2 <= tx->version ? tx->lockDistance : 0; +static uint_fast16_t obsolete_lockDistance(const elementsTransaction* tx) { + return 2 <= tx->version ? tx->obsolete_lockDistance : 0; } -static uint_fast16_t lockDuration(const elementsTransaction* tx) { - return 2 <= tx->version ? tx->lockDuration : 0; +static uint_fast16_t obsolete_lockDuration(const elementsTransaction* tx) { + return 2 <= tx->version ? tx->obsolete_lockDuration : 0; } static bool isFee(const sigOutput* output) { @@ -733,16 +733,16 @@ bool simplicity_tx_lock_time(frameItem* dst, frameItem src, const txEnv* env) { } /* tx_lock_distance : ONE |- TWO^16 */ -bool simplicity_tx_lock_distance(frameItem* dst, frameItem src, const txEnv* env) { +bool simplicity_broken_do_not_use_tx_lock_distance(frameItem* dst, frameItem src, const txEnv* env) { (void) src; // src is unused; - simplicity_write16(dst, lockDistance(env->tx)); + simplicity_write16(dst, obsolete_lockDistance(env->tx)); return true; } /* tx_lock_duration : ONE |- TWO^16 */ -bool simplicity_tx_lock_duration(frameItem* dst, frameItem src, const txEnv* env) { +bool simplicity_broken_do_not_use_tx_lock_duration(frameItem* dst, frameItem src, const txEnv* env) { (void) src; // src is unused; - simplicity_write16(dst, lockDuration(env->tx)); + simplicity_write16(dst, obsolete_lockDuration(env->tx)); return true; } @@ -761,17 +761,17 @@ bool simplicity_check_lock_time(frameItem* dst, frameItem src, const txEnv* env) } /* check_lock_distance : TWO^16 |- ONE */ -bool simplicity_check_lock_distance(frameItem* dst, frameItem src, const txEnv* env) { +bool simplicity_broken_do_not_use_check_lock_distance(frameItem* dst, frameItem src, const txEnv* env) { (void) dst; // dst is unused; uint_fast16_t x = simplicity_read16(&src); - return x <= lockDistance(env->tx); + return x <= obsolete_lockDistance(env->tx); } /* check_lock_duration : TWO^16 |- ONE */ -bool simplicity_check_lock_duration(frameItem* dst, frameItem src, const txEnv* env) { +bool simplicity_broken_do_not_use_check_lock_duration(frameItem* dst, frameItem src, const txEnv* env) { (void) dst; // dst is unused; uint_fast16_t x = simplicity_read16(&src); - return x <= lockDuration(env->tx); + return x <= obsolete_lockDuration(env->tx); } /* calculate_issuance_entropy : TWO^256 * TWO^32 * TWO^256 |- TWO^256 */ diff --git a/C/elements/elementsJets.h b/C/elements/elementsJets.h index d6412195..d6779e38 100644 --- a/C/elements/elementsJets.h +++ b/C/elements/elementsJets.h @@ -59,12 +59,12 @@ bool simplicity_num_outputs(frameItem* dst, frameItem src, const txEnv* env); bool simplicity_tx_is_final(frameItem* dst, frameItem src, const txEnv* env); bool simplicity_tx_lock_height(frameItem* dst, frameItem src, const txEnv* env); bool simplicity_tx_lock_time(frameItem* dst, frameItem src, const txEnv* env); -bool simplicity_tx_lock_distance(frameItem* dst, frameItem src, const txEnv* env); -bool simplicity_tx_lock_duration(frameItem* dst, frameItem src, const txEnv* env); +bool simplicity_broken_do_not_use_tx_lock_distance(frameItem* dst, frameItem src, const txEnv* env); +bool simplicity_broken_do_not_use_tx_lock_duration(frameItem* dst, frameItem src, const txEnv* env); bool simplicity_check_lock_height(frameItem* dst, frameItem src, const txEnv* env); bool simplicity_check_lock_time(frameItem* dst, frameItem src, const txEnv* env); -bool simplicity_check_lock_distance(frameItem* dst, frameItem src, const txEnv* env); -bool simplicity_check_lock_duration(frameItem* dst, frameItem src, const txEnv* env); +bool simplicity_broken_do_not_use_check_lock_distance(frameItem* dst, frameItem src, const txEnv* env); +bool simplicity_broken_do_not_use_check_lock_duration(frameItem* dst, frameItem src, const txEnv* env); bool simplicity_calculate_issuance_entropy(frameItem* dst, frameItem src, const txEnv* env); bool simplicity_calculate_asset(frameItem* dst, frameItem src, const txEnv* env); bool simplicity_calculate_explicit_token(frameItem* dst, frameItem src, const txEnv* env); diff --git a/C/elements/env.c b/C/elements/env.c index af39d522..e1af6e8f 100644 --- a/C/elements/env.c +++ b/C/elements/env.c @@ -408,12 +408,12 @@ extern elementsTransaction* simplicity_elements_mallocTransaction(const rawEleme copyInput(&input[i], &rawTx->input[i]); if (input[i].sequence < 0xffffffff) { tx->isFinal = false; } if (input[i].sequence < 0x80000000) { - const uint_fast16_t maskedSequence = input[i].sequence & 0xffff; - if (input[i].sequence & ((uint_fast32_t)1 << 22)) { - if (tx->lockDuration < maskedSequence) tx->lockDuration = maskedSequence; - } else { - if (tx->lockDistance < maskedSequence) tx->lockDistance = maskedSequence; - } + const uint_fast16_t maskedSequence = input[i].sequence & 0xffff; + if (input[i].sequence & ((uint_fast32_t)1 << 22)) { + if (tx->obsolete_lockDuration < maskedSequence) tx->obsolete_lockDuration = maskedSequence; + } else { + if (tx->obsolete_lockDistance < maskedSequence) tx->obsolete_lockDistance = maskedSequence; + } } if (input[i].isPegin) { sha256_uchar(&ctx_inputOutpointsHash, 1); diff --git a/C/elements/primitiveEnumJet.inc b/C/elements/primitiveEnumJet.inc index 5e6e6c89..57420913 100644 --- a/C/elements/primitiveEnumJet.inc +++ b/C/elements/primitiveEnumJet.inc @@ -15,6 +15,10 @@ AND_8, ANNEX_HASH, ASSET_AMOUNT_HASH, BIP_0340_VERIFY, +BROKEN_DO_NOT_USE_CHECK_LOCK_DISTANCE, +BROKEN_DO_NOT_USE_CHECK_LOCK_DURATION, +BROKEN_DO_NOT_USE_TX_LOCK_DISTANCE, +BROKEN_DO_NOT_USE_TX_LOCK_DURATION, BUILD_TAPBRANCH, BUILD_TAPLEAF_SIMPLICITY, BUILD_TAPTWEAK, @@ -27,8 +31,6 @@ CH_16, CH_32, CH_64, CH_8, -CHECK_LOCK_DISTANCE, -CHECK_LOCK_DURATION, CHECK_LOCK_HEIGHT, CHECK_LOCK_TIME, CHECK_SIG_VERIFY, @@ -454,8 +456,6 @@ TOTAL_FEE, TRANSACTION_ID, TX_HASH, TX_IS_FINAL, -TX_LOCK_DISTANCE, -TX_LOCK_DURATION, TX_LOCK_HEIGHT, TX_LOCK_TIME, VERIFY, diff --git a/C/elements/primitiveJetNode.inc b/C/elements/primitiveJetNode.inc index 12731bb7..683de898 100644 --- a/C/elements/primitiveJetNode.inc +++ b/C/elements/primitiveJetNode.inc @@ -127,6 +127,38 @@ , .targetIx = ty_u , .cost = 49087 /* milli weight units */ } +,[BROKEN_DO_NOT_USE_CHECK_LOCK_DISTANCE] = +{ .tag = JET +, .jet = simplicity_broken_do_not_use_check_lock_distance +, .cmr = {{0x7f78c7a7u, 0x7a25ada2u, 0x23267d23u, 0x9a5922f7u, 0x64b8ac0cu, 0x2fcef68eu, 0xb93c0d92u, 0xda4af515u}} +, .sourceIx = ty_w16 +, .targetIx = ty_u +, .cost = 105 /* milli weight units */ +} +,[BROKEN_DO_NOT_USE_CHECK_LOCK_DURATION] = +{ .tag = JET +, .jet = simplicity_broken_do_not_use_check_lock_duration +, .cmr = {{0x73dac8e2u, 0x5d87eaf3u, 0x82c2a772u, 0x06ad38b9u, 0x384361e7u, 0xd0dc87c0u, 0xfa7af7eau, 0x524597b7u}} +, .sourceIx = ty_w16 +, .targetIx = ty_u +, .cost = 102 /* milli weight units */ +} +,[BROKEN_DO_NOT_USE_TX_LOCK_DISTANCE] = +{ .tag = JET +, .jet = simplicity_broken_do_not_use_tx_lock_distance +, .cmr = {{0x4c7773b8u, 0x18cb7ee5u, 0xf54f925au, 0xad015677u, 0xa043a72fu, 0x316a187cu, 0xc28c696cu, 0xfcb90807u}} +, .sourceIx = ty_u +, .targetIx = ty_w16 +, .cost = 91 /* milli weight units */ +} +,[BROKEN_DO_NOT_USE_TX_LOCK_DURATION] = +{ .tag = JET +, .jet = simplicity_broken_do_not_use_tx_lock_duration +, .cmr = {{0xcc9c64c8u, 0xb6eb4bf0u, 0x9694af5au, 0x35d957a4u, 0x05e66c1bu, 0x35224ed6u, 0x75878918u, 0x452440b2u}} +, .sourceIx = ty_u +, .targetIx = ty_w16 +, .cost = 84 /* milli weight units */ +} ,[BUILD_TAPBRANCH] = { .tag = JET , .jet = simplicity_build_tapbranch @@ -223,22 +255,6 @@ , .targetIx = ty_w8 , .cost = 77 /* milli weight units */ } -,[CHECK_LOCK_DISTANCE] = -{ .tag = JET -, .jet = simplicity_check_lock_distance -, .cmr = {{0x7f78c7a7u, 0x7a25ada2u, 0x23267d23u, 0x9a5922f7u, 0x64b8ac0cu, 0x2fcef68eu, 0xb93c0d92u, 0xda4af515u}} -, .sourceIx = ty_w16 -, .targetIx = ty_u -, .cost = 105 /* milli weight units */ -} -,[CHECK_LOCK_DURATION] = -{ .tag = JET -, .jet = simplicity_check_lock_duration -, .cmr = {{0x73dac8e2u, 0x5d87eaf3u, 0x82c2a772u, 0x06ad38b9u, 0x384361e7u, 0xd0dc87c0u, 0xfa7af7eau, 0x524597b7u}} -, .sourceIx = ty_w16 -, .targetIx = ty_u -, .cost = 102 /* milli weight units */ -} ,[CHECK_LOCK_HEIGHT] = { .tag = JET , .jet = simplicity_check_lock_height @@ -3639,22 +3655,6 @@ , .targetIx = ty_b , .cost = 71 /* milli weight units */ } -,[TX_LOCK_DISTANCE] = -{ .tag = JET -, .jet = simplicity_tx_lock_distance -, .cmr = {{0x4c7773b8u, 0x18cb7ee5u, 0xf54f925au, 0xad015677u, 0xa043a72fu, 0x316a187cu, 0xc28c696cu, 0xfcb90807u}} -, .sourceIx = ty_u -, .targetIx = ty_w16 -, .cost = 91 /* milli weight units */ -} -,[TX_LOCK_DURATION] = -{ .tag = JET -, .jet = simplicity_tx_lock_duration -, .cmr = {{0xcc9c64c8u, 0xb6eb4bf0u, 0x9694af5au, 0x35d957a4u, 0x05e66c1bu, 0x35224ed6u, 0x75878918u, 0x452440b2u}} -, .sourceIx = ty_u -, .targetIx = ty_w16 -, .cost = 84 /* milli weight units */ -} ,[TX_LOCK_HEIGHT] = { .tag = JET , .jet = simplicity_tx_lock_height diff --git a/C/elements/txEnv.h b/C/elements/txEnv.h index f4493530..d9a89087 100644 --- a/C/elements/txEnv.h +++ b/C/elements/txEnv.h @@ -224,11 +224,9 @@ typedef struct elementsTransaction { uint_fast32_t numFees; uint_fast32_t version; uint_fast32_t lockTime; - /* lockDuration and lockDistance values are set even when the version is 0 or 1. - * This is similar to lockTime whose value is also set, even when the transaction is final. - */ - uint_fast16_t lockDistance; - uint_fast16_t lockDuration; /* Units of 512 seconds */ + /* These two fields are used to implement broken jets and only remain here for consensus purposes. */ + uint_fast16_t obsolete_lockDistance; + uint_fast16_t obsolete_lockDuration; bool isFinal; } elementsTransaction; diff --git a/Haskell/Bitcoin/Simplicity/Bitcoin/DataTypes.hs b/Haskell/Bitcoin/Simplicity/Bitcoin/DataTypes.hs index 8a2b1525..eec493fe 100644 --- a/Haskell/Bitcoin/Simplicity/Bitcoin/DataTypes.hs +++ b/Haskell/Bitcoin/Simplicity/Bitcoin/DataTypes.hs @@ -8,7 +8,7 @@ module Simplicity.Bitcoin.DataTypes , putNoWitnessTx, txid , TapEnv(..) , txTotalInputValue, txTotalOutputValue, txFee - , txIsFinal, txLockDistance, txLockDuration + , txIsFinal, txiLockDistance, txiLockDuration , outputValuesHash, outputScriptsHash , outputsHash, outputHash , inputOutpointsHash, inputValuesHash, inputScriptsHash, inputUtxosHash @@ -171,21 +171,17 @@ txIsFinal tx = all finalSequence (sigTxIn tx) where finalSequence sigin = sigTxiSequence sigin == maxBound -txLockDistance :: SigTx -> Word16 -txLockDistance tx | sigTxVersion tx < 2 = 0 - | otherwise = getMax . foldMap distance $ sigTxIn tx - where - distance sigin = case parseSequence (sigTxiSequence sigin) of - Just (Left x) -> Max x - _ -> mempty - -txLockDuration :: SigTx -> Word16 -txLockDuration tx | sigTxVersion tx < 2 = 0 - | otherwise = getMax . foldMap duration $ sigTxIn tx - where - duration sigin = case parseSequence (sigTxiSequence sigin) of - Just (Right x) -> Max x - _ -> mempty +txiLockDistance :: SigTxInput -> Word16 +txiLockDistance sigin = + case parseSequence (sigTxiSequence sigin) of + Just (Left x) -> x + _ -> 0 + +txiLockDuration :: SigTxInput -> Word16 +txiLockDuration sigin = + case parseSequence (sigTxiSequence sigin) of + Just (Right x) -> x + _ -> 0 -- | A hash of all 'txoValues's. outputValuesHash :: SigTx -> Hash256 diff --git a/Haskell/Elements/Simplicity/Elements/DataTypes.hs b/Haskell/Elements/Simplicity/Elements/DataTypes.hs index 13076e1a..f9867e14 100644 --- a/Haskell/Elements/Simplicity/Elements/DataTypes.hs +++ b/Haskell/Elements/Simplicity/Elements/DataTypes.hs @@ -23,7 +23,7 @@ module Simplicity.Elements.DataTypes , SigTx(SigTx), sigTxVersion, sigTxIn, sigTxOut, sigTxLock , putNoWitnessTx, txid , TapEnv(..) - , txIsFinal, txLockDistance, txLockDuration + , txIsFinal, txLockBrokenDistance, txLockBrokenDuration , calculateIssuanceEntropy, calculateAsset, calculateToken , outputAmountsHash, outputNoncesHash, outputScriptsHash , outputRangeProofsHash, outputSurjectionProofsHash, outputsHash, outputHash @@ -322,17 +322,19 @@ txIsFinal tx = all finalSequence (sigTxIn tx) where finalSequence sigin = sigTxiSequence sigin == maxBound -txLockDistance :: SigTx -> Word16 -txLockDistance tx | sigTxVersion tx < 2 = 0 +-- | This function is used in a specification of broken relative timelock jets and should not be used other than for previous consensus reasons. +txLockBrokenDistance :: SigTx -> Word16 +txLockBrokenDistance tx | sigTxVersion tx < 2 = 0 | otherwise = getMax . foldMap distance $ sigTxIn tx where distance sigin = case parseSequence (sigTxiSequence sigin) of Just (Left x) -> Max x _ -> mempty -txLockDuration :: SigTx -> Word16 -txLockDuration tx | sigTxVersion tx < 2 = 0 - | otherwise = getMax . foldMap duration $ sigTxIn tx +-- | This function is used in a specification of broken relative timelock jets and should not be used other than for previous consensus reasons. +txLockBrokenDuration :: SigTx -> Word16 +txLockBrokenDuration tx | sigTxVersion tx < 2 = 0 + | otherwise = getMax . foldMap duration $ sigTxIn tx where duration sigin = case parseSequence (sigTxiSequence sigin) of Just (Right x) -> Max x diff --git a/Haskell/Simplicity/Bitcoin/Jets.hs b/Haskell/Simplicity/Bitcoin/Jets.hs index aaf18894..98f87147 100644 --- a/Haskell/Simplicity/Bitcoin/Jets.hs +++ b/Haskell/Simplicity/Bitcoin/Jets.hs @@ -39,7 +39,7 @@ import qualified Simplicity.Bitcoin.Dag as Dag import Simplicity.Bitcoin.Term import Simplicity.Bitcoin.DataTypes import qualified Simplicity.Bitcoin.JetType -import Simplicity.Bitcoin.Primitive (PrimEnv, PubKey, primEnvHash, envTx, envTap) +import Simplicity.Bitcoin.Primitive (PrimEnv, PubKey, primEnvHash, envTx, envIx, envTap) import qualified Simplicity.Bitcoin.Primitive as Prim import qualified Simplicity.Bitcoin.Serialization.BitString as BitString import qualified Simplicity.Bitcoin.Semantics as Semantics @@ -295,10 +295,16 @@ implementationTimeLock CheckLockTime env x | txIsFinal (envTx env) = guard $ fro | otherwise = guard $ fromWord32 x <= 0 where lock = fromIntegral . sigTxLock . envTx $ env -implementationTimeLock CheckLockDistance env x | fromWord16 x <= fromIntegral (txLockDistance (envTx env)) = Just () - | otherwise = Nothing -implementationTimeLock CheckLockDuration env x | fromWord16 x <= fromIntegral (txLockDuration (envTx env)) = Just () - | otherwise = Nothing +implementationTimeLock CheckLockDistance env x | sigTxVersion (envTx env) < 2 = guard $ fromWord16 x <= 0 + | Just (Left l) <- parseSequence =<< sequence = guard $ fromWord16 x <= fromIntegral l + | otherwise = guard $ fromWord16 x <= 0 + where + sequence = sigTxiSequence <$> (sigTxIn (envTx env) !? (fromIntegral $ envIx env)) +implementationTimeLock CheckLockDuration env x | sigTxVersion (envTx env) < 2 = guard $ fromWord16 x <= 0 + | Just (Right l) <- parseSequence =<< sequence = guard $ fromWord16 x <= fromIntegral l + | otherwise = guard $ fromWord16 x <= 0 + where + sequence = sigTxiSequence <$> (sigTxIn (envTx env) !? (fromIntegral $ envIx env)) implementationTimeLock TxLockHeight env () | txIsFinal (envTx env) = Just (toWord32 0) | Left l <- parseLock lock = Just . toWord32 $ fromIntegral l | otherwise = Just (toWord32 0) @@ -309,8 +315,16 @@ implementationTimeLock TxLockTime env () | txIsFinal (envTx env) = Just (toWord3 | otherwise = Just (toWord32 0) where lock = fromIntegral . sigTxLock . envTx $ env -implementationTimeLock TxLockDistance env () = Just . toWord16 . fromIntegral $ txLockDistance (envTx env) -implementationTimeLock TxLockDuration env () = Just . toWord16 . fromIntegral $ txLockDuration (envTx env) +implementationTimeLock TxLockDistance env () | sigTxVersion (envTx env) < 2 = Just (toWord16 0) + | Just (Left l) <- parseSequence =<< sequence = Just . toWord16 $ fromIntegral l + | otherwise = Just (toWord16 0) + where + sequence = sigTxiSequence <$> (sigTxIn (envTx env) !? (fromIntegral $ envIx env)) +implementationTimeLock TxLockDuration env () | sigTxVersion (envTx env) < 2 = Just (toWord16 0) + | Just (Right l) <- parseSequence =<< sequence = Just . toWord16 $ fromIntegral l + | otherwise = Just (toWord16 0) + where + sequence = sigTxiSequence <$> (sigTxIn (envTx env) !? (fromIntegral $ envIx env)) implementationTimeLock TxIsFinal env () = Just $ toBit (txIsFinal (envTx env)) implementationTransaction :: TransactionJet a b -> PrimEnv -> a -> Maybe b diff --git a/Haskell/Simplicity/Bitcoin/Programs/TimeLock.hs b/Haskell/Simplicity/Bitcoin/Programs/TimeLock.hs index caf868d4..53128386 100644 --- a/Haskell/Simplicity/Bitcoin/Programs/TimeLock.hs +++ b/Haskell/Simplicity/Bitcoin/Programs/TimeLock.hs @@ -13,6 +13,7 @@ import Prelude hiding (Word, all, drop, max, not, take) import Simplicity.Bitcoin.Primitive import Simplicity.Bitcoin.Term +import Simplicity.Bitcoin.Programs.Transaction.Lib import Simplicity.Programs.Arith import Simplicity.Programs.Bit import Simplicity.Programs.Generic @@ -42,21 +43,19 @@ txLockTime = txIsFinal &&& primitive LockTime bip68VersionCheck :: (Core term, Primitive term) => term () Bit bip68VersionCheck = scribe (toWord32 2) &&& primitive Version >>> le word32 --- | Implements 'Simplicity.Bitcoin.DataTypes.txLockDistance'. -txLockDistance :: (Core term, Primitive term) => term () Distance -txLockDistance = bip68VersionCheck &&& zero word16 - >>> match ih (forWhile word32 body >>> copair iden iden) +-- | Computes the relative height timelock or 0 if there is no such timelock. +txLockDistance :: (Assert term, Primitive term) => term () Distance +txLockDistance = bip68VersionCheck &&& (currentSequence >>> parseSequence) + >>> cond (copair (unit >>> z) (copair iden (unit >>> z))) (unit >>> z) where - body = take (drop (primitive InputSequence)) &&& ih - >>> match (injl ih) (injr (take parseSequence &&& ih >>> match ih (match (max word16) ih))) + z = zero word16 --- | Implements 'Simplicity.Bitcoin.DataTypes.txLockDuration'. -txLockDuration :: (Core term, Primitive term) => term () Duration -txLockDuration = bip68VersionCheck &&& zero word16 - >>> match ih (forWhile word32 body >>> copair iden iden) +-- | Computes the relative time timelock or 0 if there is no such timelock. +txLockDuration :: (Assert term, Primitive term) => term () Distance +txLockDuration = bip68VersionCheck &&& (currentSequence >>> parseSequence) + >>> cond (copair (unit >>> z) (copair (unit >>> z) iden)) (unit >>> z) where - body = take (drop (primitive InputSequence)) &&& ih - >>> match (injl ih) (injr (take parseSequence &&& ih >>> match ih (match ih (max word16)))) + z = zero word16 -- | Asserts that the input is less than or equal to the value returned by 'txLockHeight'. checkLockHeight :: (Assert term, Primitive term) => term Height () diff --git a/Haskell/Simplicity/Elements/FFI/Jets.hs b/Haskell/Simplicity/Elements/FFI/Jets.hs index ce038d27..a97eed35 100644 --- a/Haskell/Simplicity/Elements/FFI/Jets.hs +++ b/Haskell/Simplicity/Elements/FFI/Jets.hs @@ -54,12 +54,12 @@ module Simplicity.Elements.FFI.Jets , tx_is_final , tx_lock_height , tx_lock_time - , tx_lock_distance - , tx_lock_duration + , broken_do_not_use_tx_lock_distance + , broken_do_not_use_tx_lock_duration , check_lock_height , check_lock_time - , check_lock_distance - , check_lock_duration + , broken_do_not_use_check_lock_distance + , broken_do_not_use_check_lock_duration , calculate_issuance_entropy , calculate_asset , calculate_explicit_token @@ -174,12 +174,12 @@ foreign import ccall unsafe "" c_num_outputs :: Ptr FrameItem -> Ptr FrameItem - foreign import ccall unsafe "" c_tx_is_final :: Ptr FrameItem -> Ptr FrameItem -> Ptr CTxEnv -> IO CBool foreign import ccall unsafe "" c_tx_lock_height :: Ptr FrameItem -> Ptr FrameItem -> Ptr CTxEnv -> IO CBool foreign import ccall unsafe "" c_tx_lock_time :: Ptr FrameItem -> Ptr FrameItem -> Ptr CTxEnv -> IO CBool -foreign import ccall unsafe "" c_tx_lock_distance :: Ptr FrameItem -> Ptr FrameItem -> Ptr CTxEnv -> IO CBool -foreign import ccall unsafe "" c_tx_lock_duration :: Ptr FrameItem -> Ptr FrameItem -> Ptr CTxEnv -> IO CBool +foreign import ccall unsafe "" c_broken_do_not_use_tx_lock_distance :: Ptr FrameItem -> Ptr FrameItem -> Ptr CTxEnv -> IO CBool +foreign import ccall unsafe "" c_broken_do_not_use_tx_lock_duration :: Ptr FrameItem -> Ptr FrameItem -> Ptr CTxEnv -> IO CBool foreign import ccall unsafe "" c_check_lock_height :: Ptr FrameItem -> Ptr FrameItem -> Ptr CTxEnv -> IO CBool foreign import ccall unsafe "" c_check_lock_time :: Ptr FrameItem -> Ptr FrameItem -> Ptr CTxEnv -> IO CBool -foreign import ccall unsafe "" c_check_lock_distance :: Ptr FrameItem -> Ptr FrameItem -> Ptr CTxEnv -> IO CBool -foreign import ccall unsafe "" c_check_lock_duration :: Ptr FrameItem -> Ptr FrameItem -> Ptr CTxEnv -> IO CBool +foreign import ccall unsafe "" c_broken_do_not_use_check_lock_distance :: Ptr FrameItem -> Ptr FrameItem -> Ptr CTxEnv -> IO CBool +foreign import ccall unsafe "" c_broken_do_not_use_check_lock_duration :: Ptr FrameItem -> Ptr FrameItem -> Ptr CTxEnv -> IO CBool foreign import ccall unsafe "" c_calculate_issuance_entropy :: Ptr FrameItem -> Ptr FrameItem -> IO CBool foreign import ccall unsafe "" c_calculate_asset :: Ptr FrameItem -> Ptr FrameItem -> IO CBool foreign import ccall unsafe "" c_calculate_explicit_token :: Ptr FrameItem -> Ptr FrameItem -> IO CBool @@ -384,11 +384,11 @@ tx_lock_height = unsafeLocalJet c_tx_lock_height tx_lock_time :: PrimEnv -> () -> Maybe Word32 tx_lock_time = unsafeLocalJet c_tx_lock_time -tx_lock_distance :: PrimEnv -> () -> Maybe Word16 -tx_lock_distance = unsafeLocalJet c_tx_lock_distance +broken_do_not_use_tx_lock_distance :: PrimEnv -> () -> Maybe Word16 +broken_do_not_use_tx_lock_distance = unsafeLocalJet c_broken_do_not_use_tx_lock_distance -tx_lock_duration :: PrimEnv -> () -> Maybe Word16 -tx_lock_duration = unsafeLocalJet c_tx_lock_duration +broken_do_not_use_tx_lock_duration :: PrimEnv -> () -> Maybe Word16 +broken_do_not_use_tx_lock_duration = unsafeLocalJet c_broken_do_not_use_tx_lock_duration check_lock_height :: PrimEnv -> Word32 -> Maybe () check_lock_height = unsafeLocalJet c_check_lock_height @@ -396,11 +396,11 @@ check_lock_height = unsafeLocalJet c_check_lock_height check_lock_time :: PrimEnv -> Word32 -> Maybe () check_lock_time = unsafeLocalJet c_check_lock_time -check_lock_distance :: PrimEnv -> Word16 -> Maybe () -check_lock_distance = unsafeLocalJet c_check_lock_distance +broken_do_not_use_check_lock_distance :: PrimEnv -> Word16 -> Maybe () +broken_do_not_use_check_lock_distance = unsafeLocalJet c_broken_do_not_use_check_lock_distance -check_lock_duration :: PrimEnv -> Word16 -> Maybe () -check_lock_duration = unsafeLocalJet c_check_lock_duration +broken_do_not_use_check_lock_duration :: PrimEnv -> Word16 -> Maybe () +broken_do_not_use_check_lock_duration = unsafeLocalJet c_broken_do_not_use_check_lock_duration calculate_issuance_entropy :: ((Word256, Word32), Word256) -> Maybe Word256 calculate_issuance_entropy = unsafeLocalCoreJet c_calculate_issuance_entropy diff --git a/Haskell/Simplicity/Elements/Jets.hs b/Haskell/Simplicity/Elements/Jets.hs index 5f6711d5..355d544a 100644 --- a/Haskell/Simplicity/Elements/Jets.hs +++ b/Haskell/Simplicity/Elements/Jets.hs @@ -126,12 +126,12 @@ deriving instance Show (SigHashJet a b) data TimeLockJet a b where CheckLockHeight :: TimeLockJet TimeLock.Height () CheckLockTime :: TimeLockJet TimeLock.Time () - CheckLockDistance :: TimeLockJet TimeLock.Distance () - CheckLockDuration :: TimeLockJet TimeLock.Duration () + BrokenDoNotUseCheckLockDistance :: TimeLockJet TimeLock.Distance () + BrokenDoNotUseCheckLockDuration :: TimeLockJet TimeLock.Duration () TxLockHeight :: TimeLockJet () TimeLock.Height TxLockTime :: TimeLockJet () TimeLock.Time - TxLockDistance :: TimeLockJet () TimeLock.Distance - TxLockDuration :: TimeLockJet () TimeLock.Duration + BrokenDoNotUseTxLockDistance :: TimeLockJet () TimeLock.Distance + BrokenDoNotUseTxLockDuration :: TimeLockJet () TimeLock.Duration TxIsFinal :: TimeLockJet () TimeLock.Bit deriving instance Eq (TimeLockJet a b) deriving instance Show (TimeLockJet a b) @@ -249,12 +249,12 @@ specificationSigHash BuildTaptweak = Prog.buildTaptweak specificationTimeLock :: (Assert term, Primitive term) => TimeLockJet a b -> term a b specificationTimeLock CheckLockHeight = TimeLock.checkLockHeight specificationTimeLock CheckLockTime = TimeLock.checkLockTime -specificationTimeLock CheckLockDistance = TimeLock.checkLockDistance -specificationTimeLock CheckLockDuration = TimeLock.checkLockDuration +specificationTimeLock BrokenDoNotUseCheckLockDistance = TimeLock.brokenCheckLockDistance +specificationTimeLock BrokenDoNotUseCheckLockDuration = TimeLock.brokenCheckLockDuration specificationTimeLock TxLockHeight = TimeLock.txLockHeight specificationTimeLock TxLockTime = TimeLock.txLockTime -specificationTimeLock TxLockDistance = TimeLock.txLockDistance -specificationTimeLock TxLockDuration = TimeLock.txLockDuration +specificationTimeLock BrokenDoNotUseTxLockDistance = TimeLock.brokenTxLockDistance +specificationTimeLock BrokenDoNotUseTxLockDuration = TimeLock.brokenTxLockDuration specificationTimeLock TxIsFinal = TimeLock.txIsFinal specificationIssuance :: (Assert term, Primitive term) => IssuanceJet a b -> term a b @@ -420,10 +420,10 @@ implementationTimeLock CheckLockTime env x | txIsFinal (envTx env) = guard $ fro | otherwise = guard $ fromWord32 x <= 0 where lock = fromIntegral . sigTxLock . envTx $ env -implementationTimeLock CheckLockDistance env x | fromWord16 x <= fromIntegral (txLockDistance (envTx env)) = Just () - | otherwise = Nothing -implementationTimeLock CheckLockDuration env x | fromWord16 x <= fromIntegral (txLockDuration (envTx env)) = Just () - | otherwise = Nothing +implementationTimeLock BrokenDoNotUseCheckLockDistance env x | fromWord16 x <= fromIntegral (txLockBrokenDistance (envTx env)) = Just () + | otherwise = Nothing +implementationTimeLock BrokenDoNotUseCheckLockDuration env x | fromWord16 x <= fromIntegral (txLockBrokenDuration (envTx env)) = Just () + | otherwise = Nothing implementationTimeLock TxLockHeight env () | txIsFinal (envTx env) = Just (toWord32 0) | Left l <- parseLock lock = Just . toWord32 $ fromIntegral l | otherwise = Just (toWord32 0) @@ -434,8 +434,8 @@ implementationTimeLock TxLockTime env () | txIsFinal (envTx env) = Just (toWord3 | otherwise = Just (toWord32 0) where lock = fromIntegral . sigTxLock . envTx $ env -implementationTimeLock TxLockDistance env () = Just . toWord16 . fromIntegral $ txLockDistance (envTx env) -implementationTimeLock TxLockDuration env () = Just . toWord16 . fromIntegral $ txLockDuration (envTx env) +implementationTimeLock BrokenDoNotUseTxLockDistance env () = Just . toWord16 . fromIntegral $ txLockBrokenDistance (envTx env) +implementationTimeLock BrokenDoNotUseTxLockDuration env () = Just . toWord16 . fromIntegral $ txLockBrokenDuration (envTx env) implementationTimeLock TxIsFinal env () = Just $ toBit (txIsFinal (envTx env)) implementationIssuance :: IssuanceJet a b -> PrimEnv -> a -> Maybe b @@ -553,12 +553,12 @@ sigHashCatalogue = book timeLockCatalogue = book [ SomeArrow CheckLockHeight , SomeArrow CheckLockTime - , SomeArrow CheckLockDistance - , SomeArrow CheckLockDuration + , SomeArrow BrokenDoNotUseCheckLockDistance + , SomeArrow BrokenDoNotUseCheckLockDuration , SomeArrow TxLockHeight , SomeArrow TxLockTime - , SomeArrow TxLockDistance - , SomeArrow TxLockDuration + , SomeArrow BrokenDoNotUseTxLockDistance + , SomeArrow BrokenDoNotUseTxLockDuration , SomeArrow TxIsFinal ] issuanceCatalogue = book @@ -671,12 +671,12 @@ putJetBitSigHash BuildTaptweak = putPositive 35 putJetBitTimeLock :: TimeLockJet a b -> DList Bool putJetBitTimeLock CheckLockHeight = putPositive 1 putJetBitTimeLock CheckLockTime = putPositive 2 -putJetBitTimeLock CheckLockDistance = putPositive 3 -putJetBitTimeLock CheckLockDuration = putPositive 4 +putJetBitTimeLock BrokenDoNotUseCheckLockDistance = putPositive 3 +putJetBitTimeLock BrokenDoNotUseCheckLockDuration = putPositive 4 putJetBitTimeLock TxLockHeight = putPositive 5 putJetBitTimeLock TxLockTime = putPositive 6 -putJetBitTimeLock TxLockDistance = putPositive 7 -putJetBitTimeLock TxLockDuration = putPositive 8 +putJetBitTimeLock BrokenDoNotUseTxLockDistance = putPositive 7 +putJetBitTimeLock BrokenDoNotUseTxLockDuration = putPositive 8 putJetBitTimeLock TxIsFinal = putPositive 9 putJetBitIssuance :: IssuanceJet a b -> DList Bool @@ -1294,12 +1294,12 @@ jetCostSigHash BuildTaptweak = cost "BuildTaptweak" jetCostTimeLock :: TimeLockJet a b -> Weight jetCostTimeLock CheckLockHeight = cost "CheckLockHeight" jetCostTimeLock CheckLockTime = cost "CheckLockTime" -jetCostTimeLock CheckLockDistance = cost "CheckLockDistance" -jetCostTimeLock CheckLockDuration = cost "CheckLockDuration" +jetCostTimeLock BrokenDoNotUseCheckLockDistance = cost "CheckLockDistance" +jetCostTimeLock BrokenDoNotUseCheckLockDuration = cost "CheckLockDuration" jetCostTimeLock TxLockHeight = cost "TxLockHeight" jetCostTimeLock TxLockTime = cost "TxLockTime" -jetCostTimeLock TxLockDistance = cost "TxLockDistance" -jetCostTimeLock TxLockDuration = cost "TxLockDuration" +jetCostTimeLock BrokenDoNotUseTxLockDistance = cost "TxLockDistance" +jetCostTimeLock BrokenDoNotUseTxLockDuration = cost "TxLockDuration" jetCostTimeLock TxIsFinal = cost "TxIsFinal" jetCostIssuance :: IssuanceJet a b -> Weight diff --git a/Haskell/Simplicity/Elements/Programs/TimeLock.hs b/Haskell/Simplicity/Elements/Programs/TimeLock.hs index 18d61727..8896b432 100644 --- a/Haskell/Simplicity/Elements/Programs/TimeLock.hs +++ b/Haskell/Simplicity/Elements/Programs/TimeLock.hs @@ -2,9 +2,9 @@ module Simplicity.Elements.Programs.TimeLock ( txIsFinal , txLockHeight, txLockTime - , txLockDistance, txLockDuration + , brokenTxLockDistance, brokenTxLockDuration , checkLockHeight, checkLockTime - , checkLockDistance, checkLockDuration + , brokenCheckLockDistance, brokenCheckLockDuration , module Simplicity.Programs.TimeLock , Bit ) where @@ -43,16 +43,16 @@ bip68VersionCheck :: (Core term, Primitive term) => term () Bit bip68VersionCheck = scribe (toWord32 2) &&& primitive Version >>> le word32 -- | Implements 'Simplicity.Elements.DataTypes.txLockDistance'. -txLockDistance :: (Core term, Primitive term) => term () Distance -txLockDistance = bip68VersionCheck &&& zero word16 +brokenTxLockDistance :: (Core term, Primitive term) => term () Distance +brokenTxLockDistance = bip68VersionCheck &&& zero word16 >>> match ih (forWhile word32 body >>> copair iden iden) where body = take (drop (primitive InputSequence)) &&& ih >>> match (injl ih) (injr (take parseSequence &&& ih >>> match ih (match (max word16) ih))) -- | Implements 'Simplicity.Elements.DataTypes.txLockDuration'. -txLockDuration :: (Core term, Primitive term) => term () Duration -txLockDuration = bip68VersionCheck &&& zero word16 +brokenTxLockDuration :: (Core term, Primitive term) => term () Duration +brokenTxLockDuration = bip68VersionCheck &&& zero word16 >>> match ih (forWhile word32 body >>> copair iden iden) where body = take (drop (primitive InputSequence)) &&& ih @@ -67,9 +67,9 @@ checkLockTime :: (Assert term, Primitive term) => term Time () checkLockTime = assert (iden &&& (unit >>> txLockTime) >>> le word32) -- | Asserts that the input is less than or equal to the value returned by 'txLockDistance'. -checkLockDistance :: (Assert term, Primitive term) => term Distance () -checkLockDistance = assert (iden &&& (unit >>> txLockDistance) >>> le word16) +brokenCheckLockDistance :: (Assert term, Primitive term) => term Distance () +brokenCheckLockDistance = assert (iden &&& (unit >>> brokenTxLockDistance) >>> le word16) -- | Asserts that the input is less than or equal to the value returned by 'txLockDuration'. -checkLockDuration :: (Assert term, Primitive term) => term Duration () -checkLockDuration = assert (iden &&& (unit >>> txLockDuration) >>> le word16) +brokenCheckLockDuration :: (Assert term, Primitive term) => term Duration () +brokenCheckLockDuration = assert (iden &&& (unit >>> brokenTxLockDuration) >>> le word16) diff --git a/Haskell/Tests/Simplicity/Bitcoin/Tests.hs b/Haskell/Tests/Simplicity/Bitcoin/Tests.hs index ee5cfbed..c8804d8b 100644 --- a/Haskell/Tests/Simplicity/Bitcoin/Tests.hs +++ b/Haskell/Tests/Simplicity/Bitcoin/Tests.hs @@ -4,7 +4,7 @@ import Control.Arrow ((***), (+++)) import qualified Data.ByteString.Char8 as BSC import qualified Data.ByteString.Lazy as BSL import qualified Data.Map as Map -import Data.Maybe (fromMaybe, isJust) +import Data.Maybe (fromMaybe, fromJust, isJust) import Data.Serialize (encode, put, putWord8, putWord32be, runPutLazy) import Data.Vector ((!), (!?), fromList) import Lens.Family2 (review, over, under, view) @@ -150,13 +150,17 @@ prop_check_lock_time = checkJet (BitcoinJet (TimeLockJet CheckLockTime)) prop_check_lock_distance :: Property prop_check_lock_distance = checkJet (BitcoinJet (TimeLockJet CheckLockDistance)) - $ \check -> forallPrimEnv $ \env -> forAll (genBoundaryCases . txLockDistance $ envTx env) + $ \check -> forallPrimEnv $ \env -> forAll (genBoundaryCases . txLockDistance $ env) $ \w -> check env (toW16 w) + where + txLockDistance env = fromIntegral . fromWord16 . fromJust $ implementation (BitcoinJet (TimeLockJet TxLockDistance)) env () :: Word.Word16 prop_check_lock_duration :: Property prop_check_lock_duration = checkJet (BitcoinJet (TimeLockJet CheckLockDuration)) - $ \check -> forallPrimEnv $ \env -> forAll (genBoundaryCases . txLockDuration $ envTx env) + $ \check -> forallPrimEnv $ \env -> forAll (genBoundaryCases . txLockDuration $ env) $ \w -> check env (toW16 w) + where + txLockDuration env = fromIntegral . fromWord16 . fromJust $ implementation (BitcoinJet (TimeLockJet TxLockDuration)) env () :: Word.Word16 prop_build_tapleaf_simplicity :: HashElement -> Bool prop_build_tapleaf_simplicity = \cmr -> diff --git a/Haskell/Tests/Simplicity/Elements/FFI/Tests.hs b/Haskell/Tests/Simplicity/Elements/FFI/Tests.hs index baa3ed58..d1ba9987 100644 --- a/Haskell/Tests/Simplicity/Elements/FFI/Tests.hs +++ b/Haskell/Tests/Simplicity/Elements/FFI/Tests.hs @@ -158,14 +158,14 @@ prop_tx_lock_time = forallPrimEnv $ \env -> fast_tx_lock_time env () == tx_lock_ fast_tx_lock_time = testEval (specification (ElementsJet (TimeLockJet TxLockTime))) prop_tx_lock_distance :: Property -prop_tx_lock_distance = forallPrimEnv $ \env -> fast_tx_lock_distance env () == tx_lock_distance env () +prop_tx_lock_distance = forallPrimEnv $ \env -> fast_tx_lock_distance env () == broken_do_not_use_tx_lock_distance env () where - fast_tx_lock_distance = testEval (specification (ElementsJet (TimeLockJet TxLockDistance))) + fast_tx_lock_distance = testEval (specification (ElementsJet (TimeLockJet BrokenDoNotUseTxLockDistance))) prop_tx_lock_duration :: Property -prop_tx_lock_duration = forallPrimEnv $ \env -> fast_tx_lock_duration env () == tx_lock_duration env () +prop_tx_lock_duration = forallPrimEnv $ \env -> fast_tx_lock_duration env () == broken_do_not_use_tx_lock_duration env () where - fast_tx_lock_duration = testEval (specification (ElementsJet (TimeLockJet TxLockDuration))) + fast_tx_lock_duration = testEval (specification (ElementsJet (TimeLockJet BrokenDoNotUseTxLockDuration))) prop_check_lock_height :: Word32 -> Property prop_check_lock_height = \w -> forallPrimEnv $ \env -> fast_check_lock_height env w == check_lock_height env w @@ -178,14 +178,14 @@ prop_check_lock_time = \w -> forallPrimEnv $ \env -> fast_check_lock_time env w fast_check_lock_time = testEval (specification (ElementsJet (TimeLockJet CheckLockTime))) prop_check_lock_distance :: Word16 -> Property -prop_check_lock_distance = \w -> forallPrimEnv $ \env -> fast_check_lock_distance env w == check_lock_distance env w +prop_check_lock_distance = \w -> forallPrimEnv $ \env -> fast_check_lock_distance env w == broken_do_not_use_check_lock_distance env w where - fast_check_lock_distance = testEval (specification (ElementsJet (TimeLockJet CheckLockDistance))) + fast_check_lock_distance = testEval (specification (ElementsJet (TimeLockJet BrokenDoNotUseCheckLockDistance))) prop_check_lock_duration :: Word16 -> Property -prop_check_lock_duration = \w -> forallPrimEnv $ \env -> fast_check_lock_duration env w == check_lock_duration env w +prop_check_lock_duration = \w -> forallPrimEnv $ \env -> fast_check_lock_duration env w == broken_do_not_use_check_lock_duration env w where - fast_check_lock_duration = testEval (specification (ElementsJet (TimeLockJet CheckLockDuration))) + fast_check_lock_duration = testEval (specification (ElementsJet (TimeLockJet BrokenDoNotUseCheckLockDuration))) prop_calculate_issuance_entropy :: ((Word256, Word32), Word256) -> Bool prop_calculate_issuance_entropy = \input -> diff --git a/Haskell/Tests/Simplicity/Elements/Regression.hs b/Haskell/Tests/Simplicity/Elements/Regression.hs index 7f4ac488..3fd02312 100644 --- a/Haskell/Tests/Simplicity/Elements/Regression.hs +++ b/Haskell/Tests/Simplicity/Elements/Regression.hs @@ -445,12 +445,12 @@ expected_cmr (ElementsJet (SigHashJet BuildTapbranch)) = 0xcbecf9bce172c50f58595 expected_cmr (ElementsJet (SigHashJet BuildTaptweak)) = 0x38741f80a2bf10f8f8723077c6741cbeae2dcac857901b813725806f21898ee3 expected_cmr (ElementsJet (TimeLockJet CheckLockHeight)) = 0x9e7898d037627134d2bd70c7fca9cba45eaf267d4d09ad50a9ef717a8f2749db expected_cmr (ElementsJet (TimeLockJet CheckLockTime)) = 0x68673d12e2732faa1d39e2136b1406afa098a84c96e8d60502a2dd61c59570bb -expected_cmr (ElementsJet (TimeLockJet CheckLockDistance)) = 0x7f78c7a77a25ada223267d239a5922f764b8ac0c2fcef68eb93c0d92da4af515 -expected_cmr (ElementsJet (TimeLockJet CheckLockDuration)) = 0x73dac8e25d87eaf382c2a77206ad38b9384361e7d0dc87c0fa7af7ea524597b7 +expected_cmr (ElementsJet (TimeLockJet BrokenDoNotUseCheckLockDistance)) = 0x7f78c7a77a25ada223267d239a5922f764b8ac0c2fcef68eb93c0d92da4af515 +expected_cmr (ElementsJet (TimeLockJet BrokenDoNotUseCheckLockDuration)) = 0x73dac8e25d87eaf382c2a77206ad38b9384361e7d0dc87c0fa7af7ea524597b7 expected_cmr (ElementsJet (TimeLockJet TxLockHeight)) = 0xc20257f8e76ecd0ae7ad634f5dfa68ae9a5eded0e2eebe4ee52cb47acfb0264c expected_cmr (ElementsJet (TimeLockJet TxLockTime)) = 0x3ee1900542d01efd4e9a01d4efb1f9dd992ced35b7a752f83da593381538dea4 -expected_cmr (ElementsJet (TimeLockJet TxLockDistance)) = 0x4c7773b818cb7ee5f54f925aad015677a043a72f316a187cc28c696cfcb90807 -expected_cmr (ElementsJet (TimeLockJet TxLockDuration)) = 0xcc9c64c8b6eb4bf09694af5a35d957a405e66c1b35224ed675878918452440b2 +expected_cmr (ElementsJet (TimeLockJet BrokenDoNotUseTxLockDistance)) = 0x4c7773b818cb7ee5f54f925aad015677a043a72f316a187cc28c696cfcb90807 +expected_cmr (ElementsJet (TimeLockJet BrokenDoNotUseTxLockDuration)) = 0xcc9c64c8b6eb4bf09694af5a35d957a405e66c1b35224ed675878918452440b2 expected_cmr (ElementsJet (TimeLockJet TxIsFinal)) = 0x8b3145722470a07de90a28ba89f3f8864261009654ce866cd8eaf76c5d8626eb expected_cmr (ElementsJet (IssuanceJet Issuance)) = 0x5c646312c169c68027979e1bc326c5dc95e5c5168d00d98e9d504a7cde21d768 expected_cmr (ElementsJet (IssuanceJet IssuanceAsset)) = 0x690bf918e1527756cfbbf51c831362143756d52d04e1294f1264950c6267e5c9 diff --git a/Haskell/Tests/Simplicity/Elements/Tests.hs b/Haskell/Tests/Simplicity/Elements/Tests.hs index 64be611e..e2bc15b7 100644 --- a/Haskell/Tests/Simplicity/Elements/Tests.hs +++ b/Haskell/Tests/Simplicity/Elements/Tests.hs @@ -188,11 +188,11 @@ prop_tx_lock_time = checkJet (ElementsJet (TimeLockJet TxLockTime)) $ \check -> forallPrimEnv $ \env -> check env () prop_tx_lock_distance :: Property -prop_tx_lock_distance = checkJet (ElementsJet (TimeLockJet TxLockDistance)) +prop_tx_lock_distance = checkJet (ElementsJet (TimeLockJet BrokenDoNotUseTxLockDistance)) $ \check -> forallPrimEnv $ \env -> check env () prop_tx_lock_duration :: Property -prop_tx_lock_duration = checkJet (ElementsJet (TimeLockJet TxLockDuration)) +prop_tx_lock_duration = checkJet (ElementsJet (TimeLockJet BrokenDoNotUseTxLockDuration)) $ \check -> forallPrimEnv $ \env -> check env () prop_check_lock_height :: Property @@ -206,13 +206,13 @@ prop_check_lock_time = checkJet (ElementsJet (TimeLockJet CheckLockTime)) $ \w -> check env (toW32 w) prop_check_lock_distance :: Property -prop_check_lock_distance = checkJet (ElementsJet (TimeLockJet CheckLockDistance)) - $ \check -> forallPrimEnv $ \env -> forAll (genBoundaryCases . txLockDistance $ envTx env) +prop_check_lock_distance = checkJet (ElementsJet (TimeLockJet BrokenDoNotUseCheckLockDistance)) + $ \check -> forallPrimEnv $ \env -> forAll (genBoundaryCases . txLockBrokenDistance $ envTx env) $ \w -> check env (toW16 w) prop_check_lock_duration :: Property -prop_check_lock_duration = checkJet (ElementsJet (TimeLockJet CheckLockDuration)) - $ \check -> forallPrimEnv $ \env -> forAll (genBoundaryCases . txLockDuration $ envTx env) +prop_check_lock_duration = checkJet (ElementsJet (TimeLockJet BrokenDoNotUseCheckLockDuration)) + $ \check -> forallPrimEnv $ \env -> forAll (genBoundaryCases . txLockBrokenDuration $ envTx env) $ \w -> check env (toW16 w) prop_calculate_issuance_entropy :: Outpoint -> HashElement -> Bool diff --git a/Haskell/cbits/elements/jets.c b/Haskell/cbits/elements/jets.c index 423c64fb..6d15bbff 100644 --- a/Haskell/cbits/elements/jets.c +++ b/Haskell/cbits/elements/jets.c @@ -54,12 +54,12 @@ WRAP_(num_outputs) WRAP_(tx_is_final) WRAP_(tx_lock_height) WRAP_(tx_lock_time) -WRAP_(tx_lock_distance) -WRAP_(tx_lock_duration) +WRAP_(broken_do_not_use_tx_lock_distance) +WRAP_(broken_do_not_use_tx_lock_duration) WRAP_(check_lock_height) WRAP_(check_lock_time) -WRAP_(check_lock_distance) -WRAP_(check_lock_duration) +WRAP_(broken_do_not_use_check_lock_distance) +WRAP_(broken_do_not_use_check_lock_duration) COREWRAP_(calculate_issuance_entropy) COREWRAP_(calculate_asset) COREWRAP_(calculate_explicit_token)