-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rework tx creation + implement Class C & missing transactions #13
Rework tx creation + implement Class C & missing transactions #13
Conversation
Note not spec related, code currently only supports up to two packets in Class B. As we improve Class B code to send multiple OP_CHECKMULTISIG outputs to support bigger payloads we can update these settings accordingly.
Reference outputs are added early on in the process, however if there is ever trouble identifying the reference address the highest vout will always be used as per spec, so we should make our reference vouts the highest (by adding them last).
Awesome. I'll take a look at this later. Given all the type checks, it might be worth the redo something mastercoin-MSC#167 (comment) and get some "parse-to-that-type-or-throw-json-exception" functions. But this would just serve readability, on the very first glimpse it looks like you covered the checks. Edit: in a seperate PR. I'd like to get this one in as soon as possible. |
Also, re: merge conflict. Didn't test it locally, nor really looked through, but IIRC you started with the 0.0.9.2-no-history branch, which might have caused some incompabilities? In the worst case the commits could be easily cherry-picked. |
Thanks bud :)
Yeah that looks good - at some point I really need to get to looking at all those outstanding PR's in the old repo!
Could very well be the case - but I had thought it was from omnicore-0.0.10 (exposing my lack of GitHub skills here lol):
Yep I noticed that too, now need to see what the issues are - hopefully be something small :) |
Conflicts: src/mastercore_rpc.cpp
Oh.. I pull it locally in a few minutes, but I fear this will ovewrite the history in an odd way, sort of like with similar problems I faced, when I tried to hack the history back into 0.0.10. But let's see. I have already a few ideas as follow up, including an idea how to tackle the
No need to. I'll resubmit them, here, when it's time. The upcoming ones are probably going to focus on moving some parts (say for example the send and sto logic, which is wrongly in mastercore.cpp right now), starting with the logger. Edit: if you have time to spare (which I doubt hehe), you could add a comment to each function though, and roughly give it a category. In particular this would be useful to locale "used by UI only" code blocks. |
@zathras-crypto: if you have some time, please resolve the merge conflicts. I'm going to add the creation methods to OmniJ, so it would be great, if this PR could be merged - at least in theory. To give you an overview of the tests, which are implemented:
I haven't touched it since the last update, because I'm sort of out of ideas. Please let me know, if you have something else in mind, which could or should be tested. @msgilligan: ping for additional input. :) |
…0.0.10-Z-ClassC Conflicts: src/mastercore.cpp
Done.
I just dropped in some code for the accept fee handling as per our discussion earlier on, but I'm questioning whether the automatic retrieval and application of the required fee might be a bad idea... Thoughts? |
Hmm.. well, let me say it this way: the DEx is very user unfriendly, and it's up the clever UI and wallet designers to deal with it. This isn't only the fee, but also the payment window.. I have an idea though: how about an extra flag, which defaults to If this flag is false, and it's an "unsafe" situation, a warning could be returned with information about the fee to pay and the payment window. "Power" users can always create transactions with enabled flag right from the beginning, so this wouldn't be very restrictive. |
That's not a bad idea. Also 3 blocks is a little on the low side IMO - IIRC Masterchest Wallet & OmniWallet both agreed to apply a minimum 10 block accept to wallet functions. This isn't per spec, but too many people were losing money to 'shady' offers with low payment windows (especially with the incorrect assumption of some users that an unconfirmed transaction will always be mined in the next block) so we felt it was the responsible thing to do as developers of those respective softwares. I would say being the reference client I don't like to enfore things that aren't in the spec, but if we as you note allow "power" users to bypass it then it's not a concern. I'd like to do same and probably change the sell RPC call respectively to restrict listing sell offers with shady payment windows, but again I don't like adding stuff to a reference client that isn't per spec. Hmm... Not sure which way to go, but thanks for bringing it up - we definitely want to do something. EDIT for clarity : Not sure which way to go re listing sells, your suggested flag is fine for accepts :) |
Well, then let's use 10 for accepting offers.
Imho there should be no restriction for creating offers, because buyers are already protected via the accepting flag. I would have suggested to provide sane default values though (like 10 or 20 blocks or so), but this requires to restructure the order of the parameters. |
if (senderBalance < amountForSale) throw JSONRPCError(RPC_TYPE_ERROR, "Sender has insufficient balance"); | ||
if (senderAvailableBalance < amountForSale) throw JSONRPCError(RPC_TYPE_ERROR, "Sender has insufficient balance (due to pending transactions)"); | ||
} | ||
if (minAcceptFee <= 0) throw JSONRPCError(RPC_TYPE_ERROR, "Mininmum accept mining fee invalid"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's wrong about no fee?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's wrong about no fee?
It's illegal per spec? The field is 'number of coins' which requires a positive value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not validated, as it seems (regtest mode):
> sendrawtx_MP "mz2kMTWoHnuvapPkHRgCPQt5tZJNFjNwj7" "00010014000000010000000008f0d180000000174876e8000a000000000000000001"
82a313b0de75058054307ff092175772352d2dcae3ad71f98b393a3a80ee65f7
> setgenerate true 1
[
"6eea2284a15a9d005a320405180c53325470c71e809525e0b7f9dad22acecc08"
]
> gettransaction_MP 82 a313b0de75058054307ff092175772352d2dcae3ad71f98b393a3a80ee65f7
{
"txid": "82a313b0de75058054307ff092175772352d2dcae3ad71f98b393a3a80ee65f7",
"sendingaddress": "mz2kMTWoHnuvapPkHRgCPQt5tZJNFjNwj7",
"ismine": true,
"confirmations": 1,
"fee": 0.00009999,
"blocktime": 1429930699,
"version": 0,
"type_int": 20,
"type": "DEx Sell Offer",
"propertyid": 1,
"divisible": true,
"amount": "1.50000000",
"feerequired": 0.00000000, <<<
"timelimit": 10,
"subaction": "New",
"bitcoindesired": 1000.00000000,
"valid": true <<<
}
So let's tackle it this way: do you think it would make sense, to enforce a minimum on the RPC layer? I'm not sure actually, and I'm wondering, what benefit it provides, if zero commitment fee are not disallowed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not validated, as it seems (regtest mode):
Right right... I don't know what the purpose of a non-zero commitment fee was (I kind of just mostly went off the spec when building those send rpc calls). Given that it's not enforced I think the safest thing is to say zero values are allowed and the info in the spec should be amended.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, sounds good.
Since it's a new call you can suggest changes mate, parameter order for those new calls is not set in stone until we release. |
Okay, here are a few ideas: Route 1:
Route 2:
Route 3:
... We could make it more user friendly this way, and provide sane default values, where the user safely can create and accept offers, without caring very much about all those "confusing" details. Most offers would end up with those default values, and if someone wants to use something else, he or she can do so of course. When accepting a shady offer, then buyer warning protection would be triggered. So the question really is: how far do we want to go here? I'm all in for easier interfaces, but at the same time one could argue, all this could be done on another layer, i.e. the UI or in some external wallet, such as Omni Wallet. |
I kind of like route 3 but then I think default parameters benefit end users, and how many end users are going to be making RPC calls to send transactions?
Yeah, I think you hit the nail on the head here. Making the API 'user friendly' should not receive as much attention as making say the UI user friendly. |
The class C part seems solid, also the data embedding and the raw transaction construction. What's missing are tests for the new creation commands via RPC. I completely agree re: consolidation, especially given that this is a rather large PR, and I would actually prefer to get this in as fast as possible. One of the reasons is to "use" the new code, in addition to the testing of some isolated parts, which, well, let's say, provides much more exposure and chances to spot defects, and it's sort of lost time, if it's unused, at least in my opinion. On the other hand, there is also the chance of introducing sneaky, and hard to spot issues, such as the almost-consensus-break related to the DEx commitment fee, as outlined in #13 (comment), and handling it too loose probably increases the chance of hidden issues due to the increased overall complexity of several new things mixed together. So let's evaluate the following options:
I favor 1, and as soon as possible, once you agree. 2 might be an option, but this creates additional work, and I wouldn't consider the RPC interface as critical enough to justify it, mostly because it doesn't have much impact on the rest. |
…0.0.10-Z-ClassC Conflicts: src/mastercore_sp.h
Perhaps we should open an issue and have a bunch of 'todo' on there?
This is true, and was a nice spot - thanks :) - but aren't we breaking consensus anyway the moment we live either Class C or MetaDEx? Obviously we need to stay in consensus for that period of 0.0.10 release to feature live while people upgrade, but I don't see that being an extended period of time.
Agreed,
IMO asap.
I don't think that's necessary - anyone can build busted up/incorrect transactions and broadcast them, if there is something wrong with the new RPC creation commands I don't see that as introducing any extra risk right now - but they have to be tested/solid before release.
Golden question :) |
Good idea, though I'd prefer to have one issue for each task, issue or todo point, which is easier to clear and focus on imho.
Yes, but there is a significant difference: the consensus breaks for class C and the meta DEx are scheduled and synchronized for all participants, whereby this bug would have been live right from the beginning, and 0.0.9 users could be fooled into a wrong (according to 0.0.10 logic) state.
Then we agree.
There is a small change required: diff --git a/src/mastercore_sp.h b/src/mastercore_sp.h
index 3c710ce..ed64ee9 100644
--- a/src/mastercore_sp.h
+++ b/src/mastercore_sp.h
@@ -7,6 +7,7 @@
class CBlockIndex;
+#include "base58.h"
#include "tinyformat.h"
#include "uint256.h"
#include "utiltime.h" I'm going to run mainnet consensus checks in a few minutes, on top of 28, as final confirmation for both. |
Ah, ok - that's interesting - I had a merge conflict and checked the current branch 0.0.10 (https://github.com/OmniLayer/omnicore/blob/omnicore-0.0.10/src/mastercore_sp.h) which didn't have the base58.h in it. EDIT: confirmed, sorry :) |
Looks fine on the first look. Build ongoing. |
bea3705 RPC: fix sendtrade_OMNI on @dexX7's recommendations (zathras-crypto) 544ee18 mastercore_sp.h: fix missing include for incomplete type CBitcoinAddress (zathras-crypto) bea8670 senddexsell : allow zero for minimum accept fee (zathras-crypto) 3d7459d Change unsafe trade detection and add override (zathras-crypto) c191053 RPC encoding : apply min accept fee for target sell in senddexaccept_OMNI (zathras-crypto) fd6cd48 Encoding: provide access to the Exodus address (dexX7) 7a62a01 Encoding: add encoding documentation and refine code consistency (dexX7) a9d6f67 Encoding: fix overflow in class C size check, refine includes (dexX7) 4d52ad1 Encoding: test class C embedding of empty payload via unit tests (dexX7) 38dbbaa Encoding: test existence of class C marker via unit tests (dexX7) 7e7bd5d Encoding: test payload creation of known references via unit tests (dexX7) 8409388 Script: test solver with several OP_RETURN sizes via unit tests (dexX7) 913522d Script: use independent solver for script identification (dexX7) 8aa1c10 Script: test getting dust threshold via unit tests (dexX7) a67ca3c Script: rename and move GetDustLimit to GetDustThreshold (dexX7) ecc50ec Script: test script extraction via unit tests (dexX7) 3d8ad43 Script: rename and move getOutputType to GetOutputType (dexX7) cd75837 Script: improve readability and documentation of GetScriptPushes (dexX7) e911488 Utils: test generation of obfuscated hashes via unit tests (dexX7) c80abd0 Utils: refine includes and dependencies, improve documentation (dexX7) 56fde5c mastercore.cpp : fix output total for mining fee calc (thanks @dexX7) (zathras-crypto) 9301eb9 Fix class selection size check (dexX7) a4d8540 Fix class selection on creation - credit @dexX7 (zathras-crypto) 9f3aa31 Fix backwards version/type (zathras-crypto) aeb2915 [CONSOLIDATE] Makefile changes (zathras-crypto) 0298fd1 [CONSOLIDATE] rpcclient.cpp/h changes (zathras-crypto) dedc077 [CONSOLIDATE] omnicore_encoding.cpp/h changes (zathras-crypto) 50c5098 [CONSOLIDATE] omnicore_rpctx.cpp/h (zathras-crypto) 369d495 [CONSOLIDATE] omnicore_createpayload.cpp/h (zathras-crypto) 5bb365f [CONSOLIDATE] rpcserver.cpp/h changes (zathras-crypto) daf5715 [CONSOLIDATE] mastercore.cpp/h changes (zathras-crypto) a0dfa0b [CONSOLIDATE] mastercore_rpc.cpp/h changes (zathras-crypto) 58a21f2 Fix: strip 2 instead of 4 bytes from OP_RETURN output for marker (zathras-crypto) fd881a3 Switch to a 2 byte marker (zathras-crypto) 28f8d66 [FIX] - Ensure reference output is added last Reference outputs are added early on in the process, however if there is ever trouble identifying the reference address the highest vout will always be used as per spec, so we should make our reference vouts the highest (by adding them last). (zathras-crypto) 0cbd9f1 [TX CREATION SIMPLIFICATION] - Makefile update (zathras-crypto) c4612f2 [TX CREATION SIMPLIFICATION] - Mastercore modifications (zathras-crypto) 070a9f2 [TX CREATION SIMPLIFICATION] - OmniCore utils (zathras-crypto) 90a2d55 [TX CREATION SIMPLIFICATION] - OmniCore Encoding (zathras-crypto) cbe5920 Make classAgnostic_Send return an error if the payload is too big (zathras-crypto) 6407370 Fix maximum OP_RETURN packet size (zathras-crypto) 3e2e6d4 Rename to MIN_PAYLOAD_SIZE and correct value (zathras-crypto) e56def0 cleanup - disable extra parser debugging (zathras-crypto) 4ae489b Cleanup - remove debugging include (zathras-crypto) f148cd7 ClassC-0.0.10 fix IsDust for unspendable outputs (zathras-crypto) c2d23ff ClassC-0.0.10 mastercore_tx (zathras-crypto) 7f49f5c ClassC-0.0.10 mastercore_rpc (zathras-crypto) a036633 ClassC-0.0.10 mastercore (zathras-crypto)
Peew.. :) Great work @zathras-crypto, one very significant milestone accomplished! :) |
Thanks dude, your help was invaluable as always :) :) :) |
fac04cb refactor: Add lock annotations to Active* methods (MacroFake) fac15ff Fix logical race in rest_getutxos (MacroFake) fa97a52 Fix UB/data-race in RPCNotifyBlockChange (MacroFake) fa530bc Add ChainstateManager::GetMutex(), an alias for ::cs_main (MacroFake) Pull request description: This fixes two issues: * A data race in `ActiveChain`, which returns a reference to the chain (a `std::vector`), which is not thread safe. See also below traceback. * A corrupt rest response, which returns a blockheight and blockhash, which are unrelated to each other and to the result, as the chain might advance between each call without cs_main held. The issues are fixed by taking cs_main and holding it for the required time. ``` ================== WARNING: ThreadSanitizer: data race (pid=32335) Write of size 8 at 0x7b3c000008f0 by thread T22 (mutexes: write M131626, write M151, write M131553): #0 std::__1::enable_if<(is_move_constructible<CBlockIndex**>::value) && (is_move_assignable<CBlockIndex**>::value), void>::type std::__1::swap<CBlockIndex**>(CBlockIndex**&, CBlockIndex**&) /usr/lib/llvm-13/bin/../include/c++/v1/__utility/swap.h:39:7 (bitcoind+0x501239) OmniLayer#1 std::__1::vector<CBlockIndex*, std::__1::allocator<CBlockIndex*> >::__swap_out_circular_buffer(std::__1::__split_buffer<CBlockIndex*, std::__1::allocator<CBlockIndex*>&>&) /usr/lib/llvm-13/bin/../include/c++/v1/vector:977:5 (bitcoind+0x501239) OmniLayer#2 std::__1::vector<CBlockIndex*, std::__1::allocator<CBlockIndex*> >::__append(unsigned long) /usr/lib/llvm-13/bin/../include/c++/v1/vector:1117:9 (bitcoind+0x501239) OmniLayer#3 std::__1::vector<CBlockIndex*, std::__1::allocator<CBlockIndex*> >::resize(unsigned long) /usr/lib/llvm-13/bin/../include/c++/v1/vector:2046:15 (bitcoind+0x4ffe29) OmniLayer#4 CChain::SetTip(CBlockIndex*) src/chain.cpp:19:12 (bitcoind+0x4ffe29) OmniLayer#5 CChainState::ConnectTip(BlockValidationState&, CBlockIndex*, std::__1::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) src/validation.cpp:2748:13 (bitcoind+0x475d00) OmniLayer#6 CChainState::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::__1::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) src/validation.cpp:2884:18 (bitcoind+0x47739e) OmniLayer#7 CChainState::ActivateBestChain(BlockValidationState&, std::__1::shared_ptr<CBlock const>) src/validation.cpp:3011:22 (bitcoind+0x477baf) OmniLayer#8 node::ThreadImport(ChainstateManager&, std::__1::vector<fs::path, std::__1::allocator<fs::path> >, ArgsManager const&) src/node/blockstorage.cpp:883:30 (bitcoind+0x23cd74) OmniLayer#9 AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7::operator()() const src/init.cpp:1657:9 (bitcoind+0x15863e) OmniLayer#10 decltype(static_cast<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(fp)()) std::__1::__invoke<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&) /usr/lib/llvm-13/bin/../include/c++/v1/type_traits:3918:1 (bitcoind+0x15863e) OmniLayer#11 void std::__1::__invoke_void_return_wrapper<void, true>::__call<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&) /usr/lib/llvm-13/bin/../include/c++/v1/__functional/invoke.h:61:9 (bitcoind+0x15863e) OmniLayer#12 std::__1::__function::__alloc_func<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, std::__1::allocator<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>, void ()>::operator()() /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:171:16 (bitcoind+0x15863e) OmniLayer#13 std::__1::__function::__func<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, std::__1::allocator<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>, void ()>::operator()() /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:345:12 (bitcoind+0x15863e) OmniLayer#14 std::__1::__function::__value_func<void ()>::operator()() const /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:498:16 (bitcoind+0x88891f) OmniLayer#15 std::__1::function<void ()>::operator()() const /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:1175:12 (bitcoind+0x88891f) OmniLayer#16 util::TraceThread(char const*, std::__1::function<void ()>) src/util/thread.cpp:18:9 (bitcoind+0x88891f) OmniLayer#17 decltype(static_cast<void (*>(fp)(static_cast<char const*>(fp0), static_cast<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>(fp0))) std::__1::__invoke<void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>(void (*&&)(char const*, std::__1::function<void ()>), char const*&&, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&&) /usr/lib/llvm-13/bin/../include/c++/v1/type_traits:3918:1 (bitcoind+0x157e6a) OmniLayer#18 void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, 2ul, 3ul>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>&, std::__1::__tuple_indices<2ul, 3ul>) /usr/lib/llvm-13/bin/../include/c++/v1/thread:280:5 (bitcoind+0x157e6a) OmniLayer#19 void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7> >(void*) /usr/lib/llvm-13/bin/../include/c++/v1/thread:291:5 (bitcoind+0x157e6a) Previous read of size 8 at 0x7b3c000008f0 by main thread: #0 std::__1::vector<CBlockIndex*, std::__1::allocator<CBlockIndex*> >::size() const /usr/lib/llvm-13/bin/../include/c++/v1/vector:680:61 (bitcoind+0x15179d) OmniLayer#1 CChain::Tip() const src/./chain.h:449:23 (bitcoind+0x15179d) OmniLayer#2 ChainstateManager::ActiveTip() const src/./validation.h:927:59 (bitcoind+0x15179d) OmniLayer#3 AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) src/init.cpp:1841:35 (bitcoind+0x15179d) OmniLayer#4 AppInit(node::NodeContext&, int, char**) src/bitcoind.cpp:231:43 (bitcoind+0x133fd2) OmniLayer#5 main src/bitcoind.cpp:275:13 (bitcoind+0x133fd2) Location is heap block of size 232 at 0x7b3c00000870 allocated by main thread: #0 operator new(unsigned long) <null> (bitcoind+0x132668) OmniLayer#1 ChainstateManager::InitializeChainstate(CTxMemPool*, std::__1::optional<uint256> const&) src/validation.cpp:4851:21 (bitcoind+0x48e26b) OmniLayer#2 node::LoadChainstate(bool, ChainstateManager&, CTxMemPool*, bool, Consensus::Params const&, bool, long, long, long, bool, bool, std::__1::function<bool ()>, std::__1::function<void ()>) src/node/chainstate.cpp:31:14 (bitcoind+0x24de07) OmniLayer#3 AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) src/init.cpp:1438:32 (bitcoind+0x14e994) OmniLayer#4 AppInit(node::NodeContext&, int, char**) src/bitcoind.cpp:231:43 (bitcoind+0x133fd2) OmniLayer#5 main src/bitcoind.cpp:275:13 (bitcoind+0x133fd2) Mutex M131626 (0x7b3c00000898) created at: #0 pthread_mutex_lock <null> (bitcoind+0xda898) OmniLayer#1 std::__1::mutex::lock() <null> (libc++.so.1+0x49f35) OmniLayer#2 node::ThreadImport(ChainstateManager&, std::__1::vector<fs::path, std::__1::allocator<fs::path> >, ArgsManager const&) src/node/blockstorage.cpp:883:30 (bitcoind+0x23cd74) OmniLayer#3 AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7::operator()() const src/init.cpp:1657:9 (bitcoind+0x15863e) OmniLayer#4 decltype(static_cast<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(fp)()) std::__1::__invoke<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&) /usr/lib/llvm-13/bin/../include/c++/v1/type_traits:3918:1 (bitcoind+0x15863e) OmniLayer#5 void std::__1::__invoke_void_return_wrapper<void, true>::__call<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&>(AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&) /usr/lib/llvm-13/bin/../include/c++/v1/__functional/invoke.h:61:9 (bitcoind+0x15863e) OmniLayer#6 std::__1::__function::__alloc_func<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, std::__1::allocator<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>, void ()>::operator()() /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:171:16 (bitcoind+0x15863e) OmniLayer#7 std::__1::__function::__func<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, std::__1::allocator<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>, void ()>::operator()() /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:345:12 (bitcoind+0x15863e) OmniLayer#8 std::__1::__function::__value_func<void ()>::operator()() const /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:498:16 (bitcoind+0x88891f) OmniLayer#9 std::__1::function<void ()>::operator()() const /usr/lib/llvm-13/bin/../include/c++/v1/__functional/function.h:1175:12 (bitcoind+0x88891f) OmniLayer#10 util::TraceThread(char const*, std::__1::function<void ()>) src/util/thread.cpp:18:9 (bitcoind+0x88891f) OmniLayer#11 decltype(static_cast<void (*>(fp)(static_cast<char const*>(fp0), static_cast<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>(fp0))) std::__1::__invoke<void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>(void (*&&)(char const*, std::__1::function<void ()>), char const*&&, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&&) /usr/lib/llvm-13/bin/../include/c++/v1/type_traits:3918:1 (bitcoind+0x157e6a) OmniLayer#12 void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, 2ul, 3ul>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7>&, std::__1::__tuple_indices<2ul, 3ul>) /usr/lib/llvm-13/bin/../include/c++/v1/thread:280:5 (bitcoind+0x157e6a) OmniLayer#13 void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(char const*, std::__1::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7> >(void*) /usr/lib/llvm-13/bin/../include/c++/v1/thread:291:5 (bitcoind+0x157e6a) Mutex M151 (0x55aacb8ea030) created at: #0 pthread_mutex_init <null> (bitcoind+0xbed2f) OmniLayer#1 std::__1::recursive_mutex::recursive_mutex() <null> (libc++.so.1+0x49fb3) OmniLayer#2 __libc_start_main <null> (libc.so.6+0x29eba) Mutex M131553 (0x7b4c000042e0) created at: #0 pthread_mutex_init <null> (bitcoind+0xbed2f) OmniLayer#1 std::__1::recursive_mutex::recursive_mutex() <null> (libc++.so.1+0x49fb3) OmniLayer#2 std::__1::__unique_if<CTxMemPool>::__unique_single std::__1::make_unique<CTxMemPool, CBlockPolicyEstimator*, int const&>(CBlockPolicyEstimator*&&, int const&) /usr/lib/llvm-13/bin/../include/c++/v1/__memory/unique_ptr.h:728:32 (bitcoind+0x15c81d) OmniLayer#3 AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) src/init.cpp:1426:24 (bitcoind+0x14e7b4) OmniLayer#4 AppInit(node::NodeContext&, int, char**) src/bitcoind.cpp:231:43 (bitcoind+0x133fd2) OmniLayer#5 main src/bitcoind.cpp:275:13 (bitcoind+0x133fd2) Thread T22 'b-loadblk' (tid=32370, running) created by main thread at: #0 pthread_create <null> (bitcoind+0xbd5bd) OmniLayer#1 std::__1::__libcpp_thread_create(unsigned long*, void* (*)(void*), void*) /usr/lib/llvm-13/bin/../include/c++/v1/__threading_support:443:10 (bitcoind+0x155e06) OmniLayer#2 std::__1::thread::thread<void (*)(char const*, std::__1::function<void ()>), char const (&) [8], AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7, void>(void (*&&)(char const*, std::__1::function<void ()>), char const (&) [8], AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_7&&) /usr/lib/llvm-13/bin/../include/c++/v1/thread:307:16 (bitcoind+0x155e06) OmniLayer#3 AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) src/init.cpp:1656:29 (bitcoind+0x150164) OmniLayer#4 AppInit(node::NodeContext&, int, char**) src/bitcoind.cpp:231:43 (bitcoind+0x133fd2) OmniLayer#5 main src/bitcoind.cpp:275:13 (bitcoind+0x133fd2) SUMMARY: ThreadSanitizer: data race /usr/lib/llvm-13/bin/../include/c++/v1/__utility/swap.h:39:7 in std::__1::enable_if<(is_move_constructible<CBlockIndex**>::value) && (is_move_assignable<CBlockIndex**>::value), void>::type std::__1::swap<CBlockIndex**>(CBlockIndex**&, CBlockIndex**&) ================== ``` From https://cirrus-ci.com/task/5612886578954240?logs=ci#L4868 ACKs for top commit: achow101: re-ACK fac04cb theStack: Code-review ACK fac04cb Tree-SHA512: 9d619f99ff6373874c7ffe1db20674575605646b4b54b692fb54515a4a49f110a770026d7320ed6dfeaa7976be4cd89e93f821acdbf22c7662bd1c5be0cedcd2
First off apologies for the size of this PR guys, these things kind of all link together. Thanks :)
Not final - will need a LOT of testing! This PR serves three main purposes:
1) Rework transaction creation
Transaction creation has been refactored with this PR. A number of old functions have been removed, including
classB_send
andsend_INTERNAL_1packet
to instead follow a method where the calling interface (eg RPC or UI) will evaluate parameters and perform the necessary checks before calling respectivecreatePayload_type
andClassAgnosticWalletTXBuilder
functions to create the transaction. This facilitates easier adding of new transactions types.In addition there is also a new raw transaction flag
autoCommit
(can be set via RPC commandsetautocommit_OMNI true|false
) - when set tofalse
(defaulttrue
) the RPC interface will ask the wallet to create transactions but will not commit them (or broadcast them), instead returning the raw transaction hex in the response instead of the txid. For testing use mainly & it seems there may some debate as to whether this should be included so unsure if will stay.2) Add support for Class C transactions
Class C transactions are supported with this PR. A Class C transaction moves both the payload and the Omni (Exodus) marker to an OP_RETURN output. Using a provably unspendable output reduces our impact on the blockchain and further reduces transaction cost. The client
nMaxDatacarrierBytes
setting will be used to determine when to send a Class C transaction, falling back to Class B when necessary (if the payload is too large).3) Add send support for all currently live transaction types
Also known as technical debt, there were numerous transaction types that are currently live but that OmniCore was unable to create/send. This PR adds support for all transactions that are currently live. A number of new RPC calls have been added (no UI support just yet) including:
Existing RPC commands
sendtoowners_MP
andsend_MP
have been aliased to the new_OMNI
calls to provide backwards compatibility. The original code for them has been removed.Test txids below (note you will need this branch to see them, as most of them were sent Class C - it was really nice to just be able to pump out transactions of any size and watch
ClassAgnostic
adapt!):