From 20de5f9e2cb94c21bd368a53e71a9ecd44226b39 Mon Sep 17 00:00:00 2001
From: levoncrypto
Date: Fri, 20 Mar 2026 12:31:55 +0400
Subject: [PATCH 01/12] =?UTF-8?q?Lelantus=20strip=20=E2=80=93=20resolved?=
=?UTF-8?q?=20conflicts?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 4 +-
contrib/flathub/org.firo.firo-qt.metainfo.xml | 2 +-
qa/pull-tester/rpc-tests.py | 4 -
qa/rpc-tests/bip47-sendreceive.py | 60 -
qa/rpc-tests/lelantus_mint.py | 80 -
qa/rpc-tests/lelantus_mintspend.py | 137 --
.../lelantus_setmintstatus_validation.py | 66 -
qa/rpc-tests/lelantus_spend_gettransaction.py | 67 -
qa/rpc-tests/llmq-is-spark.py | 4 +-
qa/rpc-tests/wallet-dump.py | 8 +-
src/CMakeLists.txt | 17 -
src/batchproof_container.cpp | 220 --
src/batchproof_container.h | 39 -
src/bip47/account.cpp | 26 +-
src/bip47/secretpoint.cpp | 2 -
src/bloom.cpp | 1 -
src/chain.h | 2 +-
src/chainparams.cpp | 32 +-
src/coin_containers.cpp | 4 +-
src/coin_containers.h | 7 +-
src/evo/specialtx.cpp | 9 +-
src/evo/spork.cpp | 31 +-
src/evo/spork.h | 2 -
src/hdmint/hdmint.cpp | 52 -
src/hdmint/hdmint.h | 72 -
src/hdmint/mintpool.cpp | 62 -
src/hdmint/mintpool.h | 35 -
src/hdmint/test/lelantus_tests.cpp | 174 --
src/hdmint/tracker.cpp | 765 -------
src/hdmint/tracker.h | 54 -
src/hdmint/wallet.cpp | 858 --------
src/hdmint/wallet.h | 64 -
src/init.cpp | 25 +-
src/init.h | 1 -
src/lelantus.cpp | 1770 -----------------
src/lelantus.h | 311 ---
src/liblelantus/challenge_generator.h | 21 -
src/liblelantus/challenge_generator_impl.h | 79 -
src/liblelantus/coin.cpp | 182 --
src/liblelantus/coin.h | 183 --
src/liblelantus/innerproduct_proof.h | 36 -
.../innerproduct_proof_generator.cpp | 193 --
.../innerproduct_proof_generator.h | 78 -
.../innerproduct_proof_verifier.cpp | 128 --
src/liblelantus/innerproduct_proof_verifier.h | 43 -
src/liblelantus/joinsplit.cpp | 235 ---
src/liblelantus/joinsplit.h | 145 --
src/liblelantus/lelantus_primitives.cpp | 274 ---
src/liblelantus/lelantus_primitives.h | 123 --
src/liblelantus/lelantus_proof.h | 37 -
src/liblelantus/lelantus_prover.cpp | 282 ---
src/liblelantus/lelantus_prover.h | 51 -
src/liblelantus/lelantus_verifier.cpp | 294 ---
src/liblelantus/lelantus_verifier.h | 80 -
src/liblelantus/openssl_context.h | 38 -
src/liblelantus/params.cpp | 133 --
src/liblelantus/params.h | 53 -
src/liblelantus/range_proof.h | 54 -
src/liblelantus/range_prover.cpp | 199 --
src/liblelantus/range_prover.h | 40 -
src/liblelantus/range_verifier.cpp | 301 ---
src/liblelantus/range_verifier.h | 39 -
src/liblelantus/schnorr_proof.h | 29 -
src/liblelantus/schnorr_prover.cpp | 69 -
src/liblelantus/schnorr_prover.h | 25 -
src/liblelantus/schnorr_verifier.cpp | 80 -
src/liblelantus/schnorr_verifier.h | 25 -
src/liblelantus/sigmaextended_proof.h | 59 -
src/liblelantus/sigmaextended_prover.cpp | 212 --
src/liblelantus/sigmaextended_prover.h | 52 -
src/liblelantus/sigmaextended_verifier.cpp | 438 ----
src/liblelantus/sigmaextended_verifier.h | 86 -
src/liblelantus/spend_metadata.cpp | 16 -
src/liblelantus/spend_metadata.h | 32 -
.../test/challenge_generator_tests.cpp | 64 -
src/liblelantus/test/coin_tests.cpp | 168 --
src/liblelantus/test/inner_product_test.cpp | 168 --
src/liblelantus/test/joinsplit_tests.cpp | 107 -
.../test/lelantus_primitives_tests.cpp | 275 ---
src/liblelantus/test/lelantus_test.cpp | 235 ---
.../test/lelantus_test_fixture.cpp | 30 -
src/liblelantus/test/lelantus_test_fixture.h | 60 -
src/liblelantus/test/range_proof_test.cpp | 346 ----
src/liblelantus/test/schnorr_test.cpp | 100 -
src/liblelantus/test/serialize_test.cpp | 85 -
src/liblelantus/test/sigma_extended_test.cpp | 238 ---
src/liblelantus/threadpool.h | 139 --
src/libspark/coin.h | 131 ++
src/libspark/grootle.h | 4 +-
src/libspark/spend_transaction.h | 5 +
src/llmq/quorums_instantsend.cpp | 55 +-
src/miner.cpp | 39 -
src/primitives/mint_spend.cpp | 20 -
src/primitives/mint_spend.h | 80 +-
src/qt/bitcoin.qrc | 1 -
src/qt/bitcoingui.cpp | 12 -
src/qt/bitcoingui.h | 1 -
src/qt/coincontroldialog.cpp | 4 +-
src/qt/forms/optionsdialog.ui | 40 -
src/qt/locale/bitcoin_zh_CN.ts | 26 +-
src/qt/optionsdialog.cpp | 25 +-
src/qt/optionsmodel.cpp | 36 -
src/qt/optionsmodel.h | 5 -
src/qt/overviewpage.cpp | 248 +--
src/qt/overviewpage.h | 20 +-
src/qt/res/css/firo.css | 36 -
src/qt/sendcoinsdialog.cpp | 13 +-
src/qt/sparkmodel.cpp | 1 -
src/qt/transactiondesc.cpp | 24 +-
src/qt/transactionrecord.cpp | 15 +-
src/qt/walletmodel.cpp | 25 -
src/qt/walletmodel.h | 4 -
src/qt/walletmodeltransaction.cpp | 10 -
src/qt/walletmodeltransaction.h | 10 +-
src/rpc/client.cpp | 14 +-
src/rpc/misc.cpp | 253 +--
src/rpc/rawtransaction.cpp | 17 -
src/rpc/rpcevo.cpp | 2 -
src/spark/sparkwallet.cpp | 72 +-
src/spark/state.cpp | 71 +-
src/spark/state.h | 2 +-
src/test/CMakeLists.txt | 16 -
src/test/fixtures.cpp | 102 -
src/test/fixtures.h | 31 -
src/test/lelantus_mintspend_test.cpp | 164 --
src/test/lelantus_state_tests.cpp | 591 ------
src/test/lelantus_tests.cpp | 962 ---------
src/test/test_bitcoin.cpp | 5 -
src/txmempool.cpp | 34 -
src/txmempool.h | 6 +-
src/validation.cpp | 407 +---
src/validation.h | 6 +-
src/wallet/CMakeLists.txt | 6 -
src/wallet/crypter.cpp | 7 -
src/wallet/lelantusjoinsplitbuilder.cpp | 491 -----
src/wallet/lelantusjoinsplitbuilder.h | 47 -
src/wallet/rpcdump.cpp | 5 +-
src/wallet/rpcwallet.cpp | 762 +------
src/wallet/test/CMakeLists.txt | 1 -
src/wallet/test/lelantus_tests.cpp | 298 ---
src/wallet/txbuilder.cpp | 10 +-
src/wallet/wallet.cpp | 1393 +------------
src/wallet/wallet.h | 78 +-
src/wallet/walletdb.cpp | 232 ---
src/wallet/walletdb.h | 19 -
145 files changed, 439 insertions(+), 18081 deletions(-)
delete mode 100755 qa/rpc-tests/bip47-sendreceive.py
delete mode 100755 qa/rpc-tests/lelantus_mint.py
delete mode 100755 qa/rpc-tests/lelantus_mintspend.py
delete mode 100755 qa/rpc-tests/lelantus_setmintstatus_validation.py
delete mode 100755 qa/rpc-tests/lelantus_spend_gettransaction.py
delete mode 100644 src/hdmint/hdmint.cpp
delete mode 100644 src/hdmint/hdmint.h
delete mode 100644 src/hdmint/mintpool.cpp
delete mode 100644 src/hdmint/mintpool.h
delete mode 100644 src/hdmint/test/lelantus_tests.cpp
delete mode 100644 src/hdmint/tracker.cpp
delete mode 100644 src/hdmint/tracker.h
delete mode 100644 src/hdmint/wallet.cpp
delete mode 100644 src/hdmint/wallet.h
delete mode 100644 src/lelantus.cpp
delete mode 100644 src/lelantus.h
delete mode 100644 src/liblelantus/challenge_generator.h
delete mode 100644 src/liblelantus/challenge_generator_impl.h
delete mode 100644 src/liblelantus/coin.cpp
delete mode 100644 src/liblelantus/coin.h
delete mode 100755 src/liblelantus/innerproduct_proof.h
delete mode 100755 src/liblelantus/innerproduct_proof_generator.cpp
delete mode 100755 src/liblelantus/innerproduct_proof_generator.h
delete mode 100755 src/liblelantus/innerproduct_proof_verifier.cpp
delete mode 100755 src/liblelantus/innerproduct_proof_verifier.h
delete mode 100644 src/liblelantus/joinsplit.cpp
delete mode 100644 src/liblelantus/joinsplit.h
delete mode 100644 src/liblelantus/lelantus_primitives.cpp
delete mode 100644 src/liblelantus/lelantus_primitives.h
delete mode 100644 src/liblelantus/lelantus_proof.h
delete mode 100644 src/liblelantus/lelantus_prover.cpp
delete mode 100644 src/liblelantus/lelantus_prover.h
delete mode 100644 src/liblelantus/lelantus_verifier.cpp
delete mode 100644 src/liblelantus/lelantus_verifier.h
delete mode 100644 src/liblelantus/openssl_context.h
delete mode 100644 src/liblelantus/params.cpp
delete mode 100644 src/liblelantus/params.h
delete mode 100644 src/liblelantus/range_proof.h
delete mode 100644 src/liblelantus/range_prover.cpp
delete mode 100644 src/liblelantus/range_prover.h
delete mode 100644 src/liblelantus/range_verifier.cpp
delete mode 100644 src/liblelantus/range_verifier.h
delete mode 100644 src/liblelantus/schnorr_proof.h
delete mode 100644 src/liblelantus/schnorr_prover.cpp
delete mode 100644 src/liblelantus/schnorr_prover.h
delete mode 100644 src/liblelantus/schnorr_verifier.cpp
delete mode 100644 src/liblelantus/schnorr_verifier.h
delete mode 100644 src/liblelantus/sigmaextended_proof.h
delete mode 100644 src/liblelantus/sigmaextended_prover.cpp
delete mode 100644 src/liblelantus/sigmaextended_prover.h
delete mode 100644 src/liblelantus/sigmaextended_verifier.cpp
delete mode 100644 src/liblelantus/sigmaextended_verifier.h
delete mode 100644 src/liblelantus/spend_metadata.cpp
delete mode 100644 src/liblelantus/spend_metadata.h
delete mode 100644 src/liblelantus/test/challenge_generator_tests.cpp
delete mode 100644 src/liblelantus/test/coin_tests.cpp
delete mode 100755 src/liblelantus/test/inner_product_test.cpp
delete mode 100644 src/liblelantus/test/joinsplit_tests.cpp
delete mode 100644 src/liblelantus/test/lelantus_primitives_tests.cpp
delete mode 100644 src/liblelantus/test/lelantus_test.cpp
delete mode 100644 src/liblelantus/test/lelantus_test_fixture.cpp
delete mode 100644 src/liblelantus/test/lelantus_test_fixture.h
delete mode 100644 src/liblelantus/test/range_proof_test.cpp
delete mode 100644 src/liblelantus/test/schnorr_test.cpp
delete mode 100644 src/liblelantus/test/serialize_test.cpp
delete mode 100644 src/liblelantus/test/sigma_extended_test.cpp
delete mode 100644 src/liblelantus/threadpool.h
delete mode 100644 src/test/lelantus_mintspend_test.cpp
delete mode 100644 src/test/lelantus_state_tests.cpp
delete mode 100644 src/test/lelantus_tests.cpp
delete mode 100644 src/wallet/lelantusjoinsplitbuilder.cpp
delete mode 100644 src/wallet/lelantusjoinsplitbuilder.h
delete mode 100644 src/wallet/test/lelantus_tests.cpp
diff --git a/README.md b/README.md
index 2f4d6b185b..51c5228b69 100644
--- a/README.md
+++ b/README.md
@@ -8,9 +8,7 @@
[](https://github.com/firoorg/firo/commits/master)

-[Firo](https://firo.org) formerly known as Zcoin, is a privacy focused cryptocurrency that utilizes the [Lelantus Spark protocol](https://eprint.iacr.org/2021/1173) which supports high anonymity sets without requiring trusted setup and relying on standard cryptographic assumptions.
-
-The Lelantus Spark cryptographic library and implementation was audited by [HashCloak](https://firo.org/about/research/papers/lelantus_spark_code_audit_report.pdf). The Lelantus Spark cryptography paper has undergone two separate audits by [HashCloak](https://firo.org/about/research/papers/Lelantus_Spark_Audit_Report.pdf) and [Daniel (Linfeng) Zhao](https://firo.org/about/research/papers/LinfengSparkAudit.pdf).
+[Firo](https://firo.org) formerly known as Zcoin, is a privacy focused cryptocurrency that utilizes the [Spark protocol](https://eprint.iacr.org/2021/1173) which supports high anonymity sets without requiring trusted setup and relying on standard cryptographic assumptions.
Firo also utilises [Dandelion++](https://arxiv.org/abs/1805.11060) to obscure the originating IP of transactions without relying on any external services such as Tor/i2P.
diff --git a/contrib/flathub/org.firo.firo-qt.metainfo.xml b/contrib/flathub/org.firo.firo-qt.metainfo.xml
index d277784c0a..0a789f823c 100644
--- a/contrib/flathub/org.firo.firo-qt.metainfo.xml
+++ b/contrib/flathub/org.firo.firo-qt.metainfo.xml
@@ -24,7 +24,7 @@
Bitcoin was originally created as an answer to this by ensuring you can be self sovereign over your money and to serve as uncensorable and unseizable money that isn't controlled by any one entity.
Bitcoin's lack of privacy however has now made it much easier to seize or blacklist funds and due to ossification of the protocol, is unlikely to take serious steps to address this.
- Firo has dedicated itself to being a privacy preserving cryptocurrency and have designed and built trustless privacy protocols such as Lelantus and Lelantus Spark that have inspired and shaped the designs of other privacy protocols (for e.g. Triptych, Seraphis, Lelantus-MW).
+ Firo has dedicated itself to being a privacy preserving cryptocurrency and have designed and built trustless privacy protocols such as Spark that have inspired and shaped the designs of other privacy protocols (for e.g. Triptych, Seraphis, Lelantus-MW).
diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py
index abe9a539d5..f6cb7cd3c9 100755
--- a/qa/pull-tester/rpc-tests.py
+++ b/qa/pull-tester/rpc-tests.py
@@ -105,10 +105,6 @@
'spark_mintspend.py',
'spark_spend_gettransaction.py',
'spark_setmintstatus_validation.py',
- 'lelantus_mint.py',
- 'lelantus_setmintstatus_validation.py',
- 'lelantus_mintspend.py',
- 'lelantus_spend_gettransaction.py',
'mempool_doublesend_oneblock.py',
'mempool_reorg.py',
'mempool_spendcoinbase.py',
diff --git a/qa/rpc-tests/bip47-sendreceive.py b/qa/rpc-tests/bip47-sendreceive.py
deleted file mode 100755
index f3af936454..0000000000
--- a/qa/rpc-tests/bip47-sendreceive.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (c) 2017-2021 The Firo Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-"""dip47 sending receiving RPCs QA test.
-"""
-
-from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import *
-
-class Bip47SendReceive(BitcoinTestFramework):
-
- def __init__(self):
- super().__init__()
- self.setup_clean_chain = True
- self.num_nodes = 3
-
- def setup_network(self, split=False):
- self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
- connect_nodes_bi(self.nodes,0,1)
- connect_nodes_bi(self.nodes,1,2)
- connect_nodes_bi(self.nodes,0,2)
- self.is_network_split=False
- self.sync_all()
-
- def run_test(self):
-
- self.nodes[1].generate(210)
- node0_pcode = self.nodes[0].createrapaddress("node0-pcode0")
-
- try:
- self.nodes[1].setupchannel(node0_pcode)
- raise AssertionError('Lelantus balance should be zero')
- except JSONRPCException as e:
- assert(e.error['code']==-6)
-
- self.nodes[1].mintlelantus(1)
- self.nodes[1].mintlelantus(1)
- self.nodes[1].generate(10)
- self.nodes[1].setupchannel(node0_pcode)
- self.nodes[1].generate(1)
- sync_blocks(self.nodes)
- self.nodes[1].sendtorapaddress(node0_pcode, 10)
-
- self.nodes[1].generate(1)
- self.sync_all()
-
- assert_equal(self.nodes[0].getbalance(), Decimal("10.0001"))
-
- self.nodes[0].sendtoaddress(self.nodes[2].getaccountaddress(""), 9.99)
-
- self.sync_all()
- self.nodes[1].generate(1)
- sync_blocks(self.nodes)
-
- assert_equal(self.nodes[2].getbalance(), Decimal("9.99"))
-
-
-if __name__ == '__main__':
- Bip47SendReceive().main()
diff --git a/qa/rpc-tests/lelantus_mint.py b/qa/rpc-tests/lelantus_mint.py
deleted file mode 100755
index e52c12f07f..0000000000
--- a/qa/rpc-tests/lelantus_mint.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/env python3
-from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import assert_equal, assert_raises_message, JSONRPCException
-
-class LelantusMintTest(BitcoinTestFramework):
- def __init__(self):
- super().__init__()
- self.num_nodes = 1
- self.setup_clean_chain = False
-
- def run_test(self):
- # generate coins
- amounts = [1, 1.1, 2, 10]
-
- # 10 confirmations
- self.nodes[0].mintlelantus(amounts[0])
- self.nodes[0].mintlelantus(amounts[1])
- self.nodes[0].generate(5)
-
- # 5 confirmations
- self.nodes[0].mintlelantus(amounts[2])
- self.nodes[0].mintlelantus(amounts[3])
- self.nodes[0].generate(5)
-
- # get all mints and utxos
- mints = self.verify_listlelantusmints(amounts)
- self.verify_listunspentlelantusmints(amounts)
- self.verify_listunspentlelantusmints([], 1000) # [1000, 9999999]
- self.verify_listunspentlelantusmints([2, 10], 1, 5) # [1, 5]
- self.verify_listunspentlelantusmints([1, 1.1], 6, 10)
- self.verify_listunspentlelantusmints([1, 1.1, 2, 10], 5, 10)
- assert_equal([False, False, False, False], list(map(lambda m : m["isUsed"], mints)))
-
- # state modification test
- # mark two coins as used
- self.nodes[0].setlelantusmintstatus(mints[2]["serialNumber"], True)
- self.nodes[0].setlelantusmintstatus(mints[3]["serialNumber"], True)
-
- mints = self.verify_listlelantusmints(amounts)
- self.verify_listunspentlelantusmints([1, 1.1])
- self.verify_listunspentlelantusmints([], 1000)
- self.verify_listunspentlelantusmints([], 1, 5)
- self.verify_listunspentlelantusmints([1, 1.1], 6, 10)
- self.verify_listunspentlelantusmints([1, 1.1], 5, 10)
- assert_equal([False, False, True, True], list(map(lambda m : m["isUsed"], mints)))
-
- # set a coin as unused
- self.nodes[0].setlelantusmintstatus(mints[3]["serialNumber"], False)
- mints = self.verify_listlelantusmints(amounts)
- self.verify_listunspentlelantusmints([1, 1.1, 10])
- assert_equal([False, False, True, False], list(map(lambda m : m["isUsed"], mints)))
-
- # reset coins state
- self.nodes[0].resetlelantusmint()
- mints = self.verify_listlelantusmints(amounts)
- self.verify_listunspentlelantusmints(amounts)
- assert_equal([False, False, False, False], list(map(lambda m : m["isUsed"], mints)))
-
- def verify_listlelantusmints(self, expected_amounts, *args):
- mints = self.nodes[0].listlelantusmints(*args)
- mints = sorted(mints, key = lambda u: u['amount'])
-
- assert_equal(
- sorted(expected_amounts),
- list(map(lambda u: u['amount'] / 1e8, mints)))
-
- return mints
-
- def verify_listunspentlelantusmints(self, expected_amounts, *args):
- utxos = self.nodes[0].listunspentlelantusmints(*args)
- utxos = sorted(utxos, key = lambda u: float(u['amount']))
-
- assert_equal(
- sorted(expected_amounts),
- list(map(lambda u: float(u['amount']), utxos)))
-
- return utxos
-
-if __name__ == '__main__':
- LelantusMintTest().main()
\ No newline at end of file
diff --git a/qa/rpc-tests/lelantus_mintspend.py b/qa/rpc-tests/lelantus_mintspend.py
deleted file mode 100755
index 689c93cdc9..0000000000
--- a/qa/rpc-tests/lelantus_mintspend.py
+++ /dev/null
@@ -1,137 +0,0 @@
-#!/usr/bin/env python3
-from decimal import *
-
-from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import *
-
-
-class LelantusMintSpendTest(BitcoinTestFramework):
- def __init__(self):
- super().__init__()
- self.num_nodes = 4
- self.setup_clean_chain = False
-
- def run_test(self):
- # Decimal formating: 6 digits for balance will be enought 000.000
- getcontext().prec = 6
- self.nodes[0].generate(11)
- self.sync_all()
-
- start_bal = self.nodes[0].getbalance()
-
- mint_trans = list()
- mint_trans.append(self.nodes[0].mintlelantus(1))
- mint_trans.append(self.nodes[0].mintlelantus(2))
-
- # Get fees from both transactions (they may differ)
- info1 = self.nodes[0].gettransaction(mint_trans[0][0])
- info2 = self.nodes[0].gettransaction(mint_trans[1][0])
-
- # fee in transaction is negative, sum both actual fees
- fee = -(info1['fee'] + info2['fee'])
- cur_bal = self.nodes[0].getbalance()
- start_bal = float(start_bal) - float(fee) - 3
- start_bal = Decimal(format(start_bal, '.8f'))
-
- assert start_bal == cur_bal, \
- 'Unexpected current balance: {}, should be minus two mints and two fee, ' \
- 'but start was {}'.format(cur_bal, start_bal)
-
- for tr in mint_trans:
- info = self.nodes[0].gettransaction(tr[0])
- confrms = info['confirmations']
- assert confrms == 0, \
- 'Confirmations should be {}, ' \
- 'due to {} blocks was generated after transaction was created,' \
- 'but was {}'.format(0, 0, confrms)
-
- tr_type = info['details'][0]['category']
- assert tr_type == 'mint', 'Unexpected transaction type: {}'.format(tr_type)
-
- res = False
- args = {'THAYjKnnCsN5xspnEcb1Ztvw4mSPBuwxzU': 1}
- try:
- res = self.nodes[0].joinsplit(args)
- except JSONRPCException as ex:
- assert ex.error['message'] == 'Insufficient funds'
-
- assert not res, 'Did not raise spend exception, but should be.'
-
- self.nodes[0].generate(1)
- self.sync_all()
-
- # generate last confirmation block - now all transactions should be confimed
- self.nodes[0].generate(1)
- self.sync_all()
-
- for tr in mint_trans:
- info = self.nodes[0].gettransaction(tr[0])
- confrms = info['confirmations']
- assert confrms == 2, \
- 'Confirmations should be 2, ' \
- 'due to 2 blocks was generated after transaction was created,' \
- 'but was {}.'.format(confrms)
- tr_type = info['details'][0]['category']
- assert tr_type == 'mint', 'Unexpected transaction type'
-
- spend_trans = list()
- spend_total = Decimal(0)
-
- self.sync_all()
-
- start_bal = self.nodes[0].getbalance()
- print(start_bal)
- total_spend_fee = 0
-
- myaddr = self.nodes[0].listreceivedbyaddress(0, True)[0]['address']
- print(1)
- args = {myaddr: 1}
-
- spend_trans.append(self.nodes[0].joinsplit(args))
-
- info = self.nodes[0].gettransaction(spend_trans[-1])
- confrms = info['confirmations']
- tr_type = info['details'][0]['category']
- total_spend_fee += -info['fee']
- print(info['fee'])
- print(self.nodes[0].getbalance())
- spend_total = float(spend_total) + 1
- assert confrms == 0, \
- 'Confirmations should be 0, ' \
- 'due to 0 blocks was generated after transaction was created,' \
- 'but was {}.'.format(confrms)
- assert tr_type == 'spend', 'Unexpected transaction type'
- print(self.nodes[0].getbalance())
-
- before_new = self.nodes[0].getbalance()
- self.nodes[0].generate(2)
- after_new = self.nodes[0].getbalance()
- delta = after_new - before_new
- self.sync_all()
-
- # # Start balance increase on generated blocks to confirm
- start_bal += delta
- cur_bal = Decimal(format(self.nodes[0].getbalance(), '.1f'))
- spend_total = Decimal(format(spend_total, '.8f'))
-
- #TODO check why currently was not minused from total sum
- start_bal = start_bal + spend_total
-
- assert start_bal == cur_bal, \
- 'Unexpected current balance: {}, should increase on {}, ' \
- 'but start was {}'.format(cur_bal, spend_total, start_bal)
-
- for tr in spend_trans:
- info = self.nodes[0].gettransaction(tr)
-
- confrms = info['confirmations']
- tr_type = info['details'][0]['category']
- assert confrms >= 1, \
- 'Confirmations should be 1 or more, ' \
- 'due to 1 blocks was generated after transaction was created,' \
- 'but was {}.'.format(confrms)
- assert tr_type == 'spend', 'Unexpected transaction type'
-
-
-if __name__ == '__main__':
- LelantusMintSpendTest().main()
diff --git a/qa/rpc-tests/lelantus_setmintstatus_validation.py b/qa/rpc-tests/lelantus_setmintstatus_validation.py
deleted file mode 100755
index 61b4d6257e..0000000000
--- a/qa/rpc-tests/lelantus_setmintstatus_validation.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python3
-from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import *
-
-class SetLelantusMintSatusValidationWithFundsTest(BitcoinTestFramework):
- def __init__(self):
- super().__init__()
- self.num_nodes = 4
- self.setup_clean_chain = False
-
- def setup_nodes(self):
- # This test requires mocktime
- enable_mocktime()
- return start_nodes(self.num_nodes, self.options.tmpdir)
-
- def run_test(self):
- self.nodes[0].generate(100)
- self.sync_all()
-
- txid = self.nodes[0].mintlelantus(10)
-
- lelantus_mint = self.nodes[0].listlelantusmints()
-
- assert len(lelantus_mint) == len(txid), 'Should be same number.'
-
- mint_info = lelantus_mint[0]
-
- assert not mint_info['isUsed'], \
- 'This mint with txid: {} should not be Used.'.format(txid)
-
- print('Set mint status from False to True.')
-
- self.nodes[0].setlelantusmintstatus(mint_info['serialNumber'], True)
-
- lelantus_mint = self.nodes[0].listlelantusmints()
-
- assert len(lelantus_mint) == len(txid), 'Should be same number.'
-
- mint_info = lelantus_mint[0]
-
- assert mint_info['isUsed'], \
- 'This mint with txid: {} should be Used.'.format(txid)
-
- print('Set mint status from True to False back.')
-
- self.nodes[0].setlelantusmintstatus(mint_info['serialNumber'], False)
-
- lelantus_mint = self.nodes[0].listlelantusmints()
-
- assert len(lelantus_mint) == len(txid), 'Should be same number.'
-
- mint_info = lelantus_mint[0]
-
- assert not mint_info['isUsed'], \
- 'This mint with txid: {} should not be Used.'.format(txid)
-
-
- assert_raises(JSONRPCException, self.nodes[0].setlelantusmintstatus, [(mint_info['serialNumber'], "sometext")])
- assert_raises(JSONRPCException, self.nodes[0].setlelantusmintstatus, [mint_info['serialNumber']])
- assert_raises(JSONRPCException, self.nodes[0].setlelantusmintstatus, [])
- assert_raises(JSONRPCException, self.nodes[0].setlelantusmintstatus, ["sometext"])
- assert_raises(JSONRPCException, self.nodes[0].setlelantusmintstatus, [123])
-
-
-if __name__ == '__main__':
- SetLelantusMintSatusValidationWithFundsTest().main()
\ No newline at end of file
diff --git a/qa/rpc-tests/lelantus_spend_gettransaction.py b/qa/rpc-tests/lelantus_spend_gettransaction.py
deleted file mode 100755
index 73599a2890..0000000000
--- a/qa/rpc-tests/lelantus_spend_gettransaction.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env python3
-from decimal import *
-
-from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import *
-
-class JoinSplitGettransactionTest(BitcoinTestFramework):
- def __init__(self):
- super().__init__()
- self.num_nodes = 4
- self.setup_clean_chain = True
-
- def setup_nodes(self):
- # This test requires mocktime
- enable_mocktime()
- return start_nodes(self.num_nodes, self.options.tmpdir)
-
- def run_test(self):
- self.nodes[0].generate(101)
- self.sync_all()
-
- # get a watch only address
- watchonly_address = self.nodes[3].getnewaddress()
- watchonly_pubkey = self.nodes[3].validateaddress(watchonly_address)["pubkey"]
- self.nodes[0].importpubkey(watchonly_pubkey, "", True)
-
- valid_address = self.nodes[0].getnewaddress()
-
- for _ in range(10):
- self.nodes[0].mintlelantus(1)
-
- self.nodes[0].generate(10)
- self.sync_all()
-
- # case 1: Spend many with watchonly address
- spendto_wo_id = self.nodes[0].joinsplit({watchonly_address: 1})
- spendto_wo_tx = self.nodes[0].gettransaction(spendto_wo_id)
-
- assert spendto_wo_tx['amount'] == Decimal('-1')
- assert spendto_wo_tx['fee'] < Decimal('0')
- assert isinstance(spendto_wo_tx['details'], list)
- assert len(spendto_wo_tx['details']) == 1
- assert spendto_wo_tx['details'][0]['involvesWatchonly']
-
- # case 2: Spend many with watchonly address and valid address
- spendto_wo_and_valid_id = self.nodes[0].joinsplit({watchonly_address: 1, valid_address: 2})
- spendto_wo_and_valid_tx = self.nodes[0].gettransaction(spendto_wo_and_valid_id)
-
- assert spendto_wo_and_valid_tx['amount'] == Decimal('-1')
- assert spendto_wo_and_valid_tx['fee'] < Decimal('0')
- assert isinstance(spendto_wo_and_valid_tx['details'], list)
- assert len(spendto_wo_and_valid_tx['details']) == 3
-
- involves_watch_only_count = 0
- for detial in spendto_wo_and_valid_tx['details']:
- if 'involvesWatchonly' in detial and bool(detial['involvesWatchonly']):
- involves_watch_only_count += 1
-
- assert involves_watch_only_count == 1
-
- # case 3: spend many with watchonly address and invalid address
- assert_raises(JSONRPCException, self.nodes[0].joinsplit, [{watchonly_address: 1, 'invalidaddress': 2}])
-
-if __name__ == '__main__':
- JoinSplitGettransactionTest().main()
-
-
diff --git a/qa/rpc-tests/llmq-is-spark.py b/qa/rpc-tests/llmq-is-spark.py
index 2c70c5e81a..d59ac343c5 100755
--- a/qa/rpc-tests/llmq-is-spark.py
+++ b/qa/rpc-tests/llmq-is-spark.py
@@ -18,7 +18,7 @@
Testing Instantsend for Spark transactions
'''
-class LLMQ_IS_Lelantus(EvoZnodeTestFramework):
+class LLMQ_IS_Spark(EvoZnodeTestFramework):
def __init__(self):
super().__init__(6, 5, extra_args=[['-debug=instantsend']] * 6 )
self.sporkprivkey = "cW2YM2xaeCaebfpKguBahUAgEzLXgSserWRuD29kSyKHq1TTgwRQ"
@@ -55,4 +55,4 @@ def run_test(self):
assert(self.wait_for_instantlock(spendTxid, self.nodes[0]))
if __name__ == '__main__':
- LLMQ_IS_Lelantus().main()
+ LLMQ_IS_Spark().main()
diff --git a/qa/rpc-tests/wallet-dump.py b/qa/rpc-tests/wallet-dump.py
index c1fee55d1c..d495330d8f 100755
--- a/qa/rpc-tests/wallet-dump.py
+++ b/qa/rpc-tests/wallet-dump.py
@@ -81,8 +81,8 @@ def setup_network(self, split=False):
def run_test (self):
tmpdir = self.options.tmpdir
- # 21 hdmint keys generated initially (0-20)
- hdmint_key_count = 21
+ # hdmint/sigma mint keys no longer generated (Lelantus stripped)
+ hdmint_key_count = 0
# generate 20 addresses to compare against the dump
test_addr_count = 20
@@ -132,8 +132,8 @@ def run_test (self):
assert_equal(found_addr, test_addr_count)
assert_equal(found_addr_chg, 50) # 50 block were mined
- # Wallet encryption doesn't change master key anymore, therefore we just verify hdmint_key_count is the same as before.
- assert_equal(found_addr_sigma, hdmint_key_count) # hdmint keys
+ # Wallet encryption doesn't change master key anymore; sigma key count unchanged after Lelantus strip (0).
+ assert_equal(found_addr_sigma, hdmint_key_count)
assert_equal(found_addr_rsv, 90 + 1) # keypool size (TODO: fix off-by-one)
if __name__ == '__main__':
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index bf9e78a2d8..aa80161a0d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -200,7 +200,6 @@ add_library(bitcoin_common STATIC EXCLUDE_FROM_ALL
${CMAKE_CURRENT_SOURCE_DIR}/compressor.cpp
${CMAKE_CURRENT_SOURCE_DIR}/core_read.cpp
${CMAKE_CURRENT_SOURCE_DIR}/core_write.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/hdmint/hdmint.cpp
${CMAKE_CURRENT_SOURCE_DIR}/init.cpp
${CMAKE_CURRENT_SOURCE_DIR}/key.cpp
${CMAKE_CURRENT_SOURCE_DIR}/keystore.cpp
@@ -270,22 +269,6 @@ add_library(firo_node STATIC EXCLUDE_FROM_ALL
${CMAKE_CURRENT_SOURCE_DIR}/httprpc.cpp
${CMAKE_CURRENT_SOURCE_DIR}/httpserver.cpp
${CMAKE_CURRENT_SOURCE_DIR}/init.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/lelantus.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/liblelantus/coin.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/liblelantus/innerproduct_proof_generator.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/liblelantus/innerproduct_proof_verifier.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/liblelantus/joinsplit.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/liblelantus/lelantus_primitives.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/liblelantus/lelantus_prover.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/liblelantus/lelantus_verifier.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/liblelantus/params.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/liblelantus/range_prover.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/liblelantus/range_verifier.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/liblelantus/schnorr_prover.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/liblelantus/schnorr_verifier.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/liblelantus/sigmaextended_prover.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/liblelantus/sigmaextended_verifier.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/liblelantus/spend_metadata.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libspark/aead.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libspark/bech32.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libspark/bpplus.cpp
diff --git a/src/batchproof_container.cpp b/src/batchproof_container.cpp
index 98b760d89d..e2a2fe040e 100644
--- a/src/batchproof_container.cpp
+++ b/src/batchproof_container.cpp
@@ -1,8 +1,4 @@
#include "batchproof_container.h"
-#include "liblelantus/sigmaextended_verifier.h"
-#include "liblelantus/threadpool.h"
-#include "liblelantus/range_verifier.h"
-#include "lelantus.h"
#include "ui_interface.h"
#include "spark/state.h"
@@ -18,20 +14,11 @@ BatchProofContainer* BatchProofContainer::get_instance() {
}
void BatchProofContainer::init() {
- tempRangeProofs.clear();
tempSparkTransactions.clear();
}
void BatchProofContainer::finalize() {
if (fCollectProofs) {
- for (const auto& itr : tempLelantusSigmaProofs) {
- lelantusSigmaProofs[itr.first].insert(lelantusSigmaProofs[itr.first].begin(), itr.second.begin(), itr.second.end());
- }
-
- for (const auto& itr : tempRangeProofs) {
- rangeProofs[itr.first].insert(rangeProofs[itr.first].begin(), itr.second.begin(), itr.second.end());
- }
-
sparkTransactions.insert(sparkTransactions.end(), tempSparkTransactions.begin(), tempSparkTransactions.end());
}
fCollectProofs = false;
@@ -39,218 +26,11 @@ void BatchProofContainer::finalize() {
void BatchProofContainer::verify() {
if (!fCollectProofs) {
- batch_lelantus();
- batch_rangeProofs();
batch_spark();
}
fCollectProofs = false;
}
-void BatchProofContainer::add(lelantus::JoinSplit* joinSplit,
- const std::map& setSizes,
- const Scalar& challenge,
- bool fStartLelantusBlacklist) {
- const std::vector& sigma_proofs = joinSplit->getLelantusProof().sigma_proofs;
- const std::vector& serials = joinSplit->getCoinSerialNumbers();
- const std::vector& groupIds = joinSplit->getCoinGroupIds();
- if (joinSplit->isSigmaToLelantus())
- return;
-
- for (size_t i = 0; i < sigma_proofs.size(); i++) {
- // pair(pair(set id, fAfterFixes), isSigmaToLelantus)
- std::pair idAndFlag = std::make_pair(groupIds[i], fStartLelantusBlacklist);
- tempLelantusSigmaProofs[idAndFlag].push_back(LelantusSigmaProofData(sigma_proofs[i], serials[i], challenge, setSizes.at(groupIds[i])));
- }
-}
-
-
-void BatchProofContainer::add(lelantus::JoinSplit* joinSplit, const std::vector& Cout) {
- tempRangeProofs[joinSplit->getVersion()].push_back(std::make_pair(joinSplit->getLelantusProof().bulletproofs, Cout));
-}
-
-void BatchProofContainer::removeLelantus(std::unordered_map spentSerials) {
- for (auto& spendSerial : spentSerials) {
-
- int id = spendSerial.second;
-
- // afterFixes bool with the pair of set id is considered separate set identifiers, so try to find in one set, if not found try also in another
- std::pair key1 = std::make_pair(id, false);
- std::pair key2 = std::make_pair(id, true);
- std::vector* vProofs;
- if (lelantusSigmaProofs.count(key1) > 0) {
- vProofs = &lelantusSigmaProofs[key1];
- erase(vProofs, spendSerial.first);
- }
-
- if (lelantusSigmaProofs.count(key2) > 0) {
- vProofs = &lelantusSigmaProofs[key2];
- erase(vProofs, spendSerial.first);
- }
- }
-}
-
-void BatchProofContainer::remove(const std::vector& rangeProofsToRemove) {
- for (auto& itrRemove : rangeProofsToRemove) {
- for (auto itrVersions = rangeProofs.begin(); itrVersions != rangeProofs.end(); ++itrVersions) {
- bool found = false;
- for (auto itr = itrVersions->second.begin(); itr != itrVersions->second.end(); ++itr) {
- if (itr->first.T_x1 == itrRemove.T_x1 && itr->first.T_x2 == itrRemove.T_x2 && itr->first.u == itrRemove.u) {
- itrVersions->second.erase(itr);
- found = true;
- break;
- }
- }
- if (itrVersions->second.empty()) {
- rangeProofs.erase(itrVersions);
- itrVersions--;
- }
- if (found)
- break;
- }
- }
-}
-
-void BatchProofContainer::erase(std::vector* vProofs, const Scalar& serial) {
- vProofs->erase(std::remove_if(vProofs->begin(),
- vProofs->end(),
- [serial](LelantusSigmaProofData& proof){return proof.serialNumber == serial;}),
- vProofs->end());
-
-}
-
-void BatchProofContainer::batch_lelantus() {
- if (!lelantusSigmaProofs.empty()){
- LogPrintf("Lelantus batch verification started.\n");
- uiInterface.UpdateProgressBarLabel("Batch verifying Lelantus...");
- }
- else
- return;
-
- auto params = lelantus::Params::get_default();
-
- DoNotDisturb dnd;
- std::size_t threadsMaxCount = std::min((unsigned int)lelantusSigmaProofs.size(), boost::thread::hardware_concurrency());
- std::vector> parallelTasks;
- parallelTasks.reserve(threadsMaxCount);
- ParallelOpThreadPool threadPool(threadsMaxCount);
- auto itr = lelantusSigmaProofs.begin();
-
- lelantus::SigmaExtendedVerifier sigmaVerifier(params->get_g(), params->get_sigma_h(), params->get_sigma_n(),
- params->get_sigma_m());
- for (std::size_t j = 0; j < lelantusSigmaProofs.size(); j += threadsMaxCount) {
- for (std::size_t i = j; i < j + threadsMaxCount; ++i) {
- if (i < lelantusSigmaProofs.size()) {
- std::vector anonymity_set;
- lelantus::CLelantusState* state = lelantus::CLelantusState::GetState();
- std::vector coins;
- state->GetAnonymitySet(
- itr->first.first,
- itr->first.second,
- coins);
- anonymity_set.reserve(coins.size());
- for (auto& coin : coins)
- anonymity_set.emplace_back(coin.getValue());
-
- size_t m = itr->second.size();
- std::vector serials;
- serials.reserve(m);
- std::vector setSizes;
- setSizes.reserve(m);
- std::vector proofs;
- proofs.reserve(m);
- std::vector challenges;
- challenges.reserve(m);
-
- for (auto& proofData : itr->second) {
- serials.emplace_back(proofData.serialNumber);
- setSizes.emplace_back(proofData.anonymitySetSize);
- proofs.emplace_back(proofData.lelantusSigmaProof);
- challenges.emplace_back(proofData.challenge);
- }
-
-
-
- parallelTasks.emplace_back(threadPool.PostTask([=]() {
- try {
- if (!sigmaVerifier.batchverify(anonymity_set, challenges, serials, setSizes, proofs))
- return false;
- } catch (const std::exception &) {
- return false;
- }
- return true;
- }));
-
- ++itr;
- }
- }
- bool isFail = false;
- for (auto& th : parallelTasks) {
- if (!th.get())
- isFail = true;
- }
-
- if (isFail) {
- LogPrintf("Lelantus batch verification failed.");
- throw std::invalid_argument("Lelantus batch verification failed, please run Firo with -reindex -batching=0");
- }
-
- parallelTasks.clear();
- }
- if (!lelantusSigmaProofs.empty())
- LogPrintf("Lelantus batch verification finished successfully.\n");
- lelantusSigmaProofs.clear();
-}
-
-void BatchProofContainer::batch_rangeProofs() {
- if (!rangeProofs.empty()){
- LogPrintf("RangeProof batch verification started.\n");
- uiInterface.UpdateProgressBarLabel("Batch verifying Range Proofs...");
- }
-
- auto params = lelantus::Params::get_default();
- for (const auto& itr : rangeProofs) {
- lelantus::RangeVerifier rangeVerifier(params->get_h1(), params->get_h0(), params->get_g(), params->get_bulletproofs_g(), params->get_bulletproofs_h(), params->get_bulletproofs_n(), itr.first);
- std::vector> V;
- std::vector> commitments;
- size_t proofSize = itr.second.size();
- V.resize(proofSize); //size of batch
- commitments.resize(proofSize); // size of batch
- std::vector proofs;
- proofs.reserve(proofSize); // size of batch
- for (size_t i = 0; i < proofSize; ++i) {
- size_t coutSize = itr.second[i].second.size();
- std::size_t m = coutSize * 2;
-
- while (m & (m - 1))
- m++;
- proofs.emplace_back(itr.second[i].first);
- V[i].reserve(m); // aggregation size
- commitments[i].reserve(2 * coutSize);
- commitments[i].resize(coutSize); // prepend zero elements, to match the prover's behavior
- auto& Cout = itr.second[i].second;
- for (std::size_t j = 0; j < coutSize; ++j) {
- V[i].push_back(Cout[j].getValue());
- V[i].push_back(Cout[j].getValue() + params->get_h1_limit_range());
- commitments[i].emplace_back(Cout[j].getValue());
- }
-
- // Pad with zero elements
- for (std::size_t t = coutSize * 2; t < m; ++t)
- V[i].push_back(GroupElement());
- }
-
- if (!rangeVerifier.verify(V, commitments, proofs)) {
- LogPrintf("RangeProof batch verification failed.\n");
- throw std::invalid_argument("RangeProof batch verification failed, please run Firo with -reindex -batching=0");
- }
- }
-
- if (!rangeProofs.empty())
- LogPrintf("RangeProof batch verification finished successfully.\n");
-
- rangeProofs.clear();
-}
-
void BatchProofContainer::add(const spark::SpendTransaction& tx) {
tempSparkTransactions.push_back(tx);
}
diff --git a/src/batchproof_container.h b/src/batchproof_container.h
index 519c84074c..dc87dcfce2 100644
--- a/src/batchproof_container.h
+++ b/src/batchproof_container.h
@@ -3,7 +3,6 @@
#include
#include "chain.h"
-#include "liblelantus/joinsplit.h"
#include "libspark/spend_transaction.h"
extern CChain chainActive;
@@ -12,42 +11,12 @@ class BatchProofContainer {
public:
static BatchProofContainer* get_instance();
- struct LelantusSigmaProofData {
- LelantusSigmaProofData(const lelantus::SigmaExtendedProof& lelantusSigmaProof_,
- const Scalar& serialNumber_,
- const Scalar& challenge_,
- size_t anonymitySetSize_)
- : lelantusSigmaProof(lelantusSigmaProof_),
- serialNumber(serialNumber_),
- challenge(challenge_),
- anonymitySetSize(anonymitySetSize_) {}
-
- lelantus::SigmaExtendedProof lelantusSigmaProof;
- Scalar serialNumber;
- Scalar challenge;
- size_t anonymitySetSize;
- };
-
void init();
void finalize();
void verify();
- void add(lelantus::JoinSplit* joinSplit,
- const std::map& setSizes,
- const Scalar& challenge,
- bool fStartLelantusBlacklist);
-
- void add(lelantus::JoinSplit* joinSplit, const std::vector& Cout);
-
- void removeLelantus(std::unordered_map spentSerials);
- void remove(const std::vector& rangeProofsToRemove);
- void erase(std::vector* vProofs, const Scalar& serial);
-
- void batch_lelantus();
- void batch_rangeProofs();
-
void add(const spark::SpendTransaction& tx);
void remove(const spark::SpendTransaction& tx);
void batch_spark();
@@ -56,17 +25,9 @@ class BatchProofContainer {
private:
static std::unique_ptr instance;
- // temp containers, to forget in case block connection fails
- // map ((id, afterFixes), fIsSigmaToLelantus) to (sigma proof, serial, set size, challenge)
- std::map, std::vector> tempLelantusSigmaProofs;
- // map (version to (Range proof, Pubcoins))
- std::map>>> tempRangeProofs;
// temp spark transaction proofs
std::vector tempSparkTransactions;
- // containers to keep proofs for batching
- std::map, std::vector> lelantusSigmaProofs;
- std::map>>> rangeProofs;
// spark transaction proofs
std::vector sparkTransactions;
};
diff --git a/src/bip47/account.cpp b/src/bip47/account.cpp
index 6a0c1f9538..1d75f63c9b 100644
--- a/src/bip47/account.cpp
+++ b/src/bip47/account.cpp
@@ -6,7 +6,6 @@
#include "util.h"
#include "bip47/bip47utils.h"
#include "wallet/wallet.h"
-#include "lelantus.h"
namespace bip47 {
@@ -251,27 +250,10 @@ bool CAccountReceiver::acceptMaskedPayload(std::vector const & ma
bool CAccountReceiver::acceptMaskedPayload(std::vector const & maskedPayload, CTransaction const & tx)
{
- std::unique_ptr jsplit;
- try {
- jsplit = lelantus::ParseLelantusJoinSplit(tx);
- }catch (const std::exception &) {
- return false;
- }
- if (!jsplit)
- return false;
- std::unique_ptr pcode;
- CExtKey pcodePrivkey = utils::Derive(privkey, {0});
- try {
- CDataStream ds(SER_NETWORK, 0);
- ds << jsplit->getCoinSerialNumbers()[0];
- pcode = bip47::utils::PcodeFromMaskedPayload(maskedPayload, (unsigned char const *)ds.vch.data(), ds.vch.size(), pcodePrivkey.key, jsplit->GetEcdsaPubkeys()[0]);
- if (!pcode)
- return false;
- } catch (std::runtime_error const &) {
- return false;
- }
- acceptPcode(*pcode);
- return true;
+ // Lelantus was removed; BIP47 masked payload from Lelantus JoinSplit is no longer parsed.
+ (void)maskedPayload;
+ (void)tx;
+ return false;
}
CPaymentCode const & CAccountReceiver::lastPcode() const
diff --git a/src/bip47/secretpoint.cpp b/src/bip47/secretpoint.cpp
index 1c7b97ae9d..3f55039400 100644
--- a/src/bip47/secretpoint.cpp
+++ b/src/bip47/secretpoint.cpp
@@ -1,6 +1,4 @@
-#include "liblelantus/coin.h"
#include "bip47/secretpoint.h"
-#include "liblelantus/openssl_context.h"
#include "bip47/bip47utils.h"
#include "utilstrencodings.h"
diff --git a/src/bloom.cpp b/src/bloom.cpp
index 9b18b2468f..bf1c315c9d 100644
--- a/src/bloom.cpp
+++ b/src/bloom.cpp
@@ -224,7 +224,6 @@ bool CBloomFilter::CheckSpecialTransactionMatchesAndUpdate(const CTransaction &t
case(TRANSACTION_COINBASE):
case(TRANSACTION_QUORUM_COMMITMENT):
case (TRANSACTION_SPORK):
- case (TRANSACTION_LELANTUS):
// No aditional checks for this transaction types
return false;
}
diff --git a/src/chain.h b/src/chain.h
index f4629b72c8..1c043b36d9 100644
--- a/src/chain.h
+++ b/src/chain.h
@@ -14,7 +14,6 @@
#include "bitcoin_bignum/bignum.h"
#include
#include
-#include "liblelantus/coin.h"
#include "libspark/coin.h"
#include "evo/spork.h"
#include "firo_params.h"
@@ -23,6 +22,7 @@
#include "coin_containers.h"
#include "streams.h"
#include "sparkname.h"
+#include "libspark/coin.h"
#include
#include
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index d22e882c0e..fac4265e39 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -744,12 +744,11 @@ class CTestNetParams : public CChainParams {
consensus.nRestartSigmaWithBlacklistCheck = INT_MAX;
consensus.nOldSigmaBanBlock = 1;
- consensus.nLelantusStartBlock = ZC_LELANTUS_TESTNET_STARTING_BLOCK;
- consensus.nLelantusFixesStartBlock = ZC_LELANTUS_TESTNET_FIXES_START_BLOCK;
-
+ consensus.nLelantusStartBlock = 1;
+ consensus.nLelantusFixesStartBlock = 1;
consensus.nSparkStartBlock = SPARK_TESTNET_START_BLOCK;
- consensus.nLelantusGracefulPeriod = LELANTUS_TESTNET_GRACEFUL_PERIOD;
- consensus.nSigmaEndBlock = ZC_SIGMA_TESTNET_END_BLOCK;
+ consensus.nLelantusGracefulPeriod = 0;
+ consensus.nSigmaEndBlock = 1;
consensus.nZerocoinV2MintMempoolGracefulPeriod = ZC_V2_MINT_TESTNET_GRACEFUL_MEMPOOL_PERIOD;
consensus.nZerocoinV2MintGracefulPeriod = ZC_V2_MINT_TESTNET_GRACEFUL_PERIOD;
consensus.nZerocoinV2SpendMempoolGracefulPeriod = ZC_V2_SPEND_TESTNET_GRACEFUL_MEMPOOL_PERIOD;
@@ -802,9 +801,9 @@ class CTestNetParams : public CChainParams {
// Bip39
consensus.nMnemonicBlock = 1;
- // moving lelantus data to v3 payload
- consensus.nLelantusV3PayloadStartBlock = 35000;
-
+ // Lelantus strip
+ consensus.nLelantusV3PayloadStartBlock = 1;
+
// ProgPow
consensus.nPPSwitchTime = 1630069200; // August 27 2021, 13:00 UTC
consensus.nPPBlockNumber = 37305;
@@ -1021,7 +1020,7 @@ class CDevNetParams : public CChainParams {
consensus.nLelantusFixesStartBlock = 1;
consensus.nSparkStartBlock = 1500;
- consensus.nLelantusGracefulPeriod = 6000;
+ consensus.nLelantusGracefulPeriod = 0;
consensus.nSigmaEndBlock = 3600;
consensus.nMaxSigmaInputPerBlock = ZC_SIGMA_INPUT_LIMIT_PER_BLOCK;
consensus.nMaxValueSigmaSpendPerBlock = ZC_SIGMA_VALUE_SPEND_LIMIT_PER_BLOCK;
@@ -1271,11 +1270,12 @@ class CRegTestParams : public CChainParams {
consensus.nStartSigmaBlacklist = INT_MAX;
consensus.nRestartSigmaWithBlacklistCheck = INT_MAX;
consensus.nOldSigmaBanBlock = 1;
- consensus.nLelantusStartBlock = 100;
- consensus.nLelantusFixesStartBlock = 100;
- consensus.nSparkStartBlock = 400;
+ // Lelantus stripped (like Sigma): both "start" at 1, only Spark active (Sigma end=1, Lelantus grace=0)
+ consensus.nLelantusStartBlock = 1;
+ consensus.nLelantusFixesStartBlock = 1;
+ consensus.nSparkStartBlock = 100;
consensus.nExchangeAddressStartBlock = 1000;
- consensus.nLelantusGracefulPeriod = 600;
+ consensus.nLelantusGracefulPeriod = 0;
consensus.nSigmaEndBlock = 1;
consensus.nZerocoinV2MintMempoolGracefulPeriod = 1;
consensus.nZerocoinV2MintGracefulPeriod = 1;
@@ -1317,9 +1317,9 @@ class CRegTestParams : public CChainParams {
// Bip39
consensus.nMnemonicBlock = 0;
- // moving lelantus data to v3 payload
- consensus.nLelantusV3PayloadStartBlock = 800;
-
+ // Lelantus strip: no v3 payload boundary (same as testnet/devnet)
+ consensus.nLelantusV3PayloadStartBlock = 1;
+
// ProgPow
// this can be overridden with either -ppswitchtime or -ppswitchtimefromnow flags
consensus.nPPSwitchTime = INT_MAX;
diff --git a/src/coin_containers.cpp b/src/coin_containers.cpp
index d755ee5a49..2069ca4f05 100644
--- a/src/coin_containers.cpp
+++ b/src/coin_containers.cpp
@@ -4,7 +4,7 @@
#include
namespace lelantus {
-std::size_t CScalarHash::operator ()(const Scalar& bn) const noexcept {
+std::size_t CScalarHash::operator ()(const secp_primitives::Scalar& bn) const noexcept {
std::vector bnData(bn.memoryRequired());
bn.serialize(&bnData[0]);
@@ -18,7 +18,7 @@ std::size_t CScalarHash::operator ()(const Scalar& bn) const noexcept {
}
std::size_t CPublicCoinHash::operator ()(const lelantus::PublicCoin& coin) const noexcept {
- uint256 hash = coin.getValueHash();
+ ::uint256 hash = coin.getValueHash();
std::size_t result;
std::memcpy(&result, hash.begin(), sizeof(std::size_t));
diff --git a/src/coin_containers.h b/src/coin_containers.h
index 0e162c65b2..4f05d9bb0f 100644
--- a/src/coin_containers.h
+++ b/src/coin_containers.h
@@ -2,9 +2,14 @@
#define COIN_CONTAINERS_H
#include
-#include "liblelantus/coin.h"
+#include "uint256.h"
+#include "serialize.h"
#include
+#include
+
+// lelantus::PublicCoin and secp_primitives types
+#include "libspark/coin.h"
namespace lelantus {
diff --git a/src/evo/specialtx.cpp b/src/evo/specialtx.cpp
index dc9b261887..949a756d4e 100644
--- a/src/evo/specialtx.cpp
+++ b/src/evo/specialtx.cpp
@@ -42,11 +42,12 @@ bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CVali
return llmq::CheckLLMQCommitment(tx, pindexPrev, state);
case TRANSACTION_SPORK:
return CheckSporkTx(tx, pindexPrev, state);
+ case TRANSACTION_LELANTUS:
+ return true;
case TRANSACTION_SPARK:
// spark transaction checks are done in other places
return true;
- case TRANSACTION_LELANTUS:
- // lelantus transaction checks are done in other places
+ case TRANSACTION_ALIAS:
return true;
}
@@ -75,6 +76,8 @@ bool ProcessSpecialTx(const CTransaction& tx, const CBlockIndex* pindex, CValida
return true;
case TRANSACTION_SPARK:
return true;
+ case TRANSACTION_ALIAS:
+ return true;
}
return state.DoS(100, false, REJECT_INVALID, "bad-tx-type-proc");
@@ -102,6 +105,8 @@ bool UndoSpecialTx(const CTransaction& tx, const CBlockIndex* pindex)
return true;
case TRANSACTION_SPARK:
return true;
+ case TRANSACTION_ALIAS:
+ return true;
}
return false;
diff --git a/src/evo/spork.cpp b/src/evo/spork.cpp
index 9a0ccfb400..77e5f2080f 100644
--- a/src/evo/spork.cpp
+++ b/src/evo/spork.cpp
@@ -53,19 +53,7 @@ bool CheckSporkTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValida
static bool IsTransactionAllowed(const CTransaction &tx, const ActiveSporkMap &sporkMap, CValidationState &state)
{
- if (tx.IsLelantusTransaction()) {
- if (sporkMap.count(CSporkAction::featureLelantus) > 0)
- return state.DoS(100, false, REJECT_CONFLICT, "txn-lelantus-disabled", false, "Lelantus transactions are disabled at the moment");
-
- if (tx.IsLelantusJoinSplit()) {
- const auto &limitSpork = sporkMap.find(CSporkAction::featureLelantusTransparentLimit);
- if (limitSpork != sporkMap.cend()) {
- if (lelantus::GetSpendTransparentAmount(tx) > (CAmount)limitSpork->second.second)
- return state.DoS(100, false, REJECT_CONFLICT, "txn-lelantus-disabled", false, "Lelantus transaction is over the transparent limit");
- }
- }
- }
- else if (tx.IsSparkTransaction()) {
+ if (tx.IsSparkTransaction()) {
if (sporkMap.count(CSporkAction::featureSpark) > 0)
return state.DoS(100, false, REJECT_CONFLICT, "txn-spark-disabled", false, "Spark transactions are disabled at the moment");
@@ -176,24 +164,7 @@ bool CSporkManager::IsTransactionAllowed(const CTransaction &tx, const ActiveSpo
}
bool CSporkManager::IsBlockAllowed(const CBlock &block, const CBlockIndex *pindex, CValidationState &state) {
- if (pindex->activeDisablingSporks.count(CSporkAction::featureLelantusTransparentLimit) > 0) {
- // limit total transparent output of lelantus joinsplit
- int64_t limit = pindex->activeDisablingSporks.at(CSporkAction::featureLelantusTransparentLimit).second;
- CAmount totalTransparentOutput = 0;
-
- for (const auto &tx: block.vtx) {
- if (!tx->IsLelantusJoinSplit())
- continue;
-
- totalTransparentOutput += lelantus::GetSpendTransparentAmount(*tx);
- }
-
- if (totalTransparentOutput > CAmount(limit))
- return state.DoS(100, false, REJECT_CONFLICT, "txn-lelantus-disabled", false, "Block is over the transparent output limit because of existing spork");
- }
-
if (pindex->activeDisablingSporks.count(CSporkAction::featureSparkTransparentLimit) > 0) {
- // limit total transparent output of lelantus joinsplit
int64_t limit = pindex->activeDisablingSporks.at(CSporkAction::featureSparkTransparentLimit).second;
CAmount totalTransparentOutput = 0;
diff --git a/src/evo/spork.h b/src/evo/spork.h
index 4b4d67fc67..a750c46ebb 100644
--- a/src/evo/spork.h
+++ b/src/evo/spork.h
@@ -13,8 +13,6 @@ typedef std::map> ActiveSporkMap;
// one action to perform. Spork transaction can have multiple actions
struct CSporkAction
{
- static constexpr const char *featureLelantus = "lelantus";
- static constexpr const char *featureLelantusTransparentLimit = "lelantustransparentlimit";
static constexpr const char *featureChainlocks = "chainlocks";
static constexpr const char *featureInstantSend = "instantsend";
static constexpr const char *featureSpark = "spark";
diff --git a/src/hdmint/hdmint.cpp b/src/hdmint/hdmint.cpp
deleted file mode 100644
index 1a43351a28..0000000000
--- a/src/hdmint/hdmint.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2019 The Firo Core Developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#include
-#include "hdmint.h"
-
-/**
- * CHDMint empty constructor
- */
-CHDMint::CHDMint()
-{
- SetNull();
-}
-
-/**
- * CHDMint constructor from given values
- */
-CHDMint::CHDMint(const int32_t& nCount, const CKeyID& seedId, const uint256& hashSerial, const GroupElement& pubCoinValue)
-{
- SetNull();
- this->nCount = nCount;
- this->seedId = seedId;
- this->hashSerial = hashSerial;
- this->pubCoinValue = pubCoinValue;
-}
-
-/**
- * Set HDMint object null
- */
-void CHDMint::SetNull()
-{
- nCount = 0;
- seedId.SetNull();
- hashSerial.SetNull();
- txid.SetNull();
- nHeight = -1;
- nId = -1;
- amount = 0;
- isUsed = false;
-}
-
-/**
- * Convert CHDMint object to string
- *
- * @return CHDMint object as string
- */
-std::string CHDMint::ToString() const
-{
- return strprintf(" HDMint:\n count=%d\n seedId=%s\n hashSerial=%s\n hashPubCoinValue=%s\n txid=%s\n height=%d\n id=%d\n amount=%d\n isUsed=%d\n",
- nCount, seedId.ToString(), hashSerial.GetHex(), GetPubCoinHash().GetHex(), txid.GetHex(), nHeight, nId, amount, isUsed);
-}
diff --git a/src/hdmint/hdmint.h b/src/hdmint/hdmint.h
deleted file mode 100644
index 1831f198c9..0000000000
--- a/src/hdmint/hdmint.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2019 The Firo Core Developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#ifndef FIRO_HDMINT_H
-#define FIRO_HDMINT_H
-
-#include "primitives/mint_spend.h"
-
-/**
- * CHDMint object
- *
- * struct that is safe to store essential mint data, without holding any information that allows for actual spending
- * (ie. serial, randomness, private key)
- */
-class CHDMint
-{
-private:
- int32_t nCount;
- CKeyID seedId;
- uint256 hashSerial;
- GroupElement pubCoinValue;
- uint256 txid;
- int nHeight;
- int nId;
- int64_t amount;
- bool isUsed;
-
-public:
- CHDMint();
- CHDMint(const int32_t& nCount, const CKeyID& seedId, const uint256& hashSerial, const GroupElement& pubCoinValue);
-
- int64_t GetAmount() const {
- return amount;
- }
- int32_t GetCount() const { return nCount; }
- int GetHeight() const { return nHeight; }
- int GetId() const { return nId; }
- CKeyID GetSeedId() const { return seedId; }
- uint256 GetSerialHash() const { return hashSerial; }
- GroupElement GetPubcoinValue() const { return pubCoinValue; }
- uint256 GetPubCoinHash() const { return primitives::GetPubCoinValueHash(pubCoinValue); }
- uint256 GetTxHash() const { return txid; }
- bool IsUsed() const { return isUsed; }
- void SetAmount(int64_t amount) { this->amount = amount; }
- void SetHeight(int nHeight) { this->nHeight = nHeight; }
- void SetId(int nId) { this->nId = nId; }
- void SetNull();
- void SetTxHash(const uint256& txid) { this->txid = txid; }
- void SetUsed(const bool isUsed) { this->isUsed = isUsed; }
- void SetPubcoinValue(const GroupElement pubCoinValue) { this->pubCoinValue = pubCoinValue; }
- std::string ToString() const;
-
- ADD_SERIALIZE_METHODS;
-
- template
- inline void SerializationOp(Stream& s, Operation ser_action)
- {
- READWRITE(nCount);
- READWRITE(seedId);
- READWRITE(hashSerial);
- READWRITE(pubCoinValue);
- READWRITE(txid);
- READWRITE(nHeight);
- READWRITE(nId);
- READWRITE(amount);
- READWRITE(isUsed);
- };
-};
-
-#endif //FIRO_HDMINT_H
-
diff --git a/src/hdmint/mintpool.cpp b/src/hdmint/mintpool.cpp
deleted file mode 100644
index 1debd918a1..0000000000
--- a/src/hdmint/mintpool.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2019 The Firo Core Developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#include "hdmint/mintpool.h"
-#include "lelantus.h"
-CMintPool::CMintPool(){}
-
-/**
- * Add a mintpool entry
- */
-void CMintPool::Add(std::pair pMint, bool fVerbose)
-{
- insert(pMint);
-
- if (fVerbose)
- LogPrintf("%s : add %s count %d to mint pool\n", __func__, pMint.first.GetHex().substr(0, 6), std::get<2>(pMint.second));
-}
-
-/**
- * Sort mintpool entries in terms of the mint count.
- *
- * @return success
- */
-bool SortSmallest(const std::pair& a, const std::pair& b)
-{
- return std::get<2>(a.second) < std::get<2>(b.second);
-}
-
-/**
- * place the mintpool in listMints.
- */
-void CMintPool::List(std::list>& listMints)
-{
- for (auto pMint : *(this)) {
- listMints.emplace_back(pMint);
- }
-
- listMints.sort(SortSmallest);
-}
-
-/**
- * clear the current mintpool
- */
-void CMintPool::Reset()
-{
- clear();
-}
-
-bool CMintPool::Get(int32_t nCount, uint160 hashSeedMaster, std::pair& result){
- for (auto pMint : *(this)) {
- if(std::get<0>(pMint.second)==hashSeedMaster && std::get<2>(pMint.second)==nCount){
- result = pMint;
- return true;
- }
- }
-
- return false;
-
-}
-
-
diff --git a/src/hdmint/mintpool.h b/src/hdmint/mintpool.h
deleted file mode 100644
index ca11b546ce..0000000000
--- a/src/hdmint/mintpool.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2019 The Firo Core Developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#ifndef FIRO_MINTPOOL_H
-#define FIRO_MINTPOOL_H
-
-#include