From bfa2e1a82cf7b6ee88dbe25b1cfd0849117da294 Mon Sep 17 00:00:00 2001 From: oskal174 Date: Wed, 20 Mar 2024 12:14:20 +0500 Subject: [PATCH 1/7] liquid support --- .env.example | 23 ++ CONTRIBUTORS.md | 2 +- Modules/Common/UTXOLiquidAssetsModule.php | 295 ++++++++++++++++++++++ Modules/Common/UTXOMainModule.php | 103 +++++++- Modules/Common/UTXOTraits.php | 3 + Modules/LiquidAssetsModule.php | 30 +++ Modules/LiquidMainModule.php | 41 +++ 7 files changed, 489 insertions(+), 8 deletions(-) create mode 100644 Modules/Common/UTXOLiquidAssetsModule.php create mode 100644 Modules/LiquidAssetsModule.php create mode 100644 Modules/LiquidMainModule.php diff --git a/.env.example b/.env.example index 98102f8f..25d93947 100644 --- a/.env.example +++ b/.env.example @@ -875,6 +875,29 @@ MODULE_rootstock-erc-1155_NODES[]=http://login:password@127.0.0.1:1234/ MODULE_rootstock-erc-1155_REQUESTER_TIMEOUT=60 MODULE_rootstock-erc-1155_REQUESTER_THREADS=12 +###################### +## Main liquid Module +###################### + +MODULES[]=liquid-main +MODULE_liquid-main_CLASS=LiquidMainModule +MODULE_liquid-main_NODES[]=http://login:password@127.0.0.1:1234/ +MODULE_liquid-main_NODES[]=http://login:password@127.0.0.1:1234/ +MODULE_liquid-main_REQUESTER_TIMEOUT=60 +MODULE_liquid-main_REQUESTER_THREADS=12 + +###################### +## Assets liquid Module +###################### + +MODULES[]=liquid-assets +MODULE_liquid-assets_CLASS=LiquidAssetsModule +MODULE_liquid-assets_NODES[]=http://login:password@127.0.0.1:1234/ +MODULE_liquid-assets_NODES[]=http://login:password@127.0.0.1:1234/ +MODULE_liquid-assets_ASSETS_REGISTRY=http://login:password@127.0.0.1:12345/ +MODULE_liquid-assets_REQUESTER_TIMEOUT=60 +MODULE_liquid-assets_REQUESTER_THREADS=12 + ############################ # Titles, descriptions, etc. ############################ diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index f041e1f1..a8630df9 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -11,4 +11,4 @@ * [Oleg Makaussov](https://github.com/Lorgansar) - Cardano Tokens modules * [Kirill Kuzminykh](https://github.com/Oskal174) - - Rootstock modules + - Rootstock modules, Liquid modules diff --git a/Modules/Common/UTXOLiquidAssetsModule.php b/Modules/Common/UTXOLiquidAssetsModule.php new file mode 100644 index 00000000..4cff8c47 --- /dev/null +++ b/Modules/Common/UTXOLiquidAssetsModule.php @@ -0,0 +1,295 @@ +version = 1; + } + + final public function post_post_initialize() + { + if (is_null($this->native_asset)) + throw new DeveloperError("Native asset is not set"); + $this->asset_registry = envm( + $this->module, + 'ASSETS_REGISTRY', + new DeveloperError('ASSETS_REGISTRY not set in the env config') + ); + } + + final public function pre_process_block($block_id) + { + $block_hash = $this->block_hash; + $block = requester_single($this->select_node(), endpoint: "rest/block/{$block_hash}.json", timeout: $this->timeout); + $this->block_time = date('Y-m-d H:i:s', (int)$block['time']); + + $events = []; + $currencies = []; + + $currencies_to_process = []; + $currencies_sums = []; + + $previous_outputs_lib = []; + $populate_outputs_lib_with = []; + $GLOBALS['populate_outputs_lib_with_indexes'] = []; + $inputs_to_check = []; + $sort_in_block_lib = []; + + $block_n = 0; + + // Process outputs + + foreach ($block['tx'] as $transaction) + { + $previous_outputs_lib[($transaction['txid'])] = $transaction['vout']; + + foreach ($transaction['vout'] as $output) + { + $asset = $output['asset'] ?? $this->native_asset; + if ($asset === $this->native_asset) + continue; // Skip native assets + + if (isset($output['scriptPubKey']['address'])) + $address = $output['scriptPubKey']['address']; + else + $address = 'script-' . substr(hash('sha256', $output['scriptPubKey']['hex']), 0, 32); + + $effect = isset($output['value']) ? satoshi($output['value'], $this) : '+?'; + $events[] = [ + 'transaction' => $transaction['txid'], + 'currency' => $asset, + 'address' => $address, + 'effect' => $effect, + 'sort_in_transaction' => ((int)$output['n'] + 1) + ]; + + $currencies_to_process[] = $asset; + if (!array_key_exists($asset, $currencies_sums)) + $currencies_sums[$asset] = ['txid' => $transaction['txid'], 'sum' => $effect]; + else + $currencies_sums[$asset]['sum'] = bcadd($currencies_sums[$asset]['sum'], $effect); + } + + $sort_in_block_lib[($transaction['txid'])] = $block_n; + $block_n++; + } + + // Process inputs + + foreach ($block['tx'] as $transaction) + { + $this_n = 1; + foreach ($transaction['vin'] as $input) + { + if (isset($input['coinbase'])) + continue; + + $is_pegin = $input['is_pegin'] ?? false; + if ($is_pegin == true) + continue; + + if (!isset($previous_outputs_lib[($input['txid'])])) + { + $populate_outputs_lib_with[] = $input['txid']; + $GLOBALS['populate_outputs_lib_with_indexes'][$input['txid']][] = $input['vout']; + } + + $inputs_to_check[] = ['this_transaction' => $transaction['txid'], + 'previous_transaction' => $input['txid'], + 'previous_n' => $input['vout'], + 'this_n' => -$this_n, + ]; + + $this_n++; + } + } + + $multi_curl = []; + + $populate_outputs_lib_with = array_unique($populate_outputs_lib_with); + + // Get input data from the node + + foreach ($populate_outputs_lib_with as $tx_hash) + { + $multi_curl[] = requester_multi_prepare($this->select_node(), + params: ['method' => 'getrawtransaction', 'params' => [$tx_hash, 1]], + timeout: $this->timeout); + } + + $curl_results = requester_multi($multi_curl, + limit: envm($this->module, 'REQUESTER_THREADS'), + timeout: $this->timeout, post_process: function($output) { + $output = requester_multi_process($output, result_in: 'result'); + + foreach ($output['vout'] as $vok => $vov) + { + if (!in_array($vok, $GLOBALS['populate_outputs_lib_with_indexes'][$output['txid']])) + unset($output['vout'][$vok]); + } + + return ['txid' => $output['txid'], 'vout' => $output['vout']]; + }); + + foreach ($curl_results as $output) + { + $previous_outputs_lib[$output['txid']] = $output['vout']; + } + + foreach ($inputs_to_check as $input) + { + if (!isset($previous_outputs_lib[($input['previous_transaction'])])) + throw new ModuleError('Input is not in the library'); + + $previous_output = $previous_outputs_lib[($input['previous_transaction'])]; + + $asset = $previous_output[($input['previous_n'])]['asset'] ?? $this->native_asset; + if ($asset === $this->native_asset) + continue; // Skip native assets + + if (isset($previous_output[($input['previous_n'])]['scriptPubKey']['address'])) + $address = $previous_output[($input['previous_n'])]['scriptPubKey']['address']; + else + $address = 'script-' . substr(hash('sha256', $previous_output[($input['previous_n'])]['scriptPubKey']['hex']), 0, 32); + + $effect = isset($previous_output[($input['previous_n'])]['value']) ? satoshi($previous_output[($input['previous_n'])]['value'], $this) : '?'; + $events[] = [ + 'transaction' => $input['this_transaction'], + 'currency' => $asset, + 'address' => $address, + 'effect' => '-' . $effect, + 'sort_in_transaction' => (int)$input['this_n'], + ]; + + $currencies_to_process[] = $asset; + if (!array_key_exists($asset, $currencies_sums)) + throw new ModuleError("Currency {$asset} not found in outputs"); + else + $currencies_sums[$asset]['sum'] = bcsub($currencies_sums[$asset]['sum'], $effect); + } + + // Process currencies + + // Add mint events + foreach ($currencies_sums as $asset => $info) + { + if ($info['sum'][0] === '-') + throw new ModuleError("Unexpected minus for {$asset}"); + if ($info['sum'] === '0') + continue; + $events[] = [ + 'transaction' => $info['txid'], + 'currency' => $asset, + 'address' => 'the-void', + 'effect' => '-' . $info['sum'], + 'sort_in_transaction' => -1, + ]; + } + + $currencies_to_process = array_values(array_unique($currencies_to_process)); // Removing duplicates + $currencies_to_process = check_existing_currencies($currencies_to_process, $this->currency_format); // Removes already known currencies + + // Get metadata + foreach ($currencies_to_process as $currency) + { + try + { + $meta = requester_single($this->asset_registry, endpoint: $currency, timeout: $this->timeout, valid_codes: [200, 404]); + } + catch (RequesterException $e) + { + // For unknown assets returns HTML page with 404 code + if (str_contains($e->getMessage(), 'bad JSON')) + $meta = [ + 'name' => 'unknown', + 'ticker' => 'unknown', + 'precision' => 0, + ]; + else + throw $e; + } + + $currencies[] = [ + 'id' => $currency, + 'name' => $meta['name'] ?? '', + 'symbol' => $meta['ticker'] ?? '', + 'decimals' => $meta['precision'] ?? 0, + ]; + } + + foreach ($events as &$event) + { + $event['block'] = $block_id; + $event['sort_in_block'] = $sort_in_block_lib[($event['transaction'])]; + $event['time'] = date('Y-m-d H:i:s', (($this->block_id !== MEMPOOL) ? (int)$block['time'] : time())); + } + + // Resort + + usort($events, function($a, $b) { + return [$a['sort_in_block'], + !str_starts_with($a['effect'], '-'), + abs($a['sort_in_transaction']), + ] + <=> + [$b['sort_in_block'], + !str_starts_with($b['effect'], '-'), + abs($b['sort_in_transaction']), + ]; + }); + + $sort_key = 0; + foreach ($events as &$event) + { + $event['sort_key'] = $sort_key++; + + unset($event['sort_in_block']); + unset($event['sort_in_transaction']); + } + + $this->set_return_events($events); + $this->set_return_currencies($currencies); + } +} diff --git a/Modules/Common/UTXOMainModule.php b/Modules/Common/UTXOMainModule.php index c2f422e1..038de475 100644 --- a/Modules/Common/UTXOMainModule.php +++ b/Modules/Common/UTXOMainModule.php @@ -36,6 +36,10 @@ abstract class UTXOMainModule extends CoreModule public ?string $p2pk_prefix1 = null; public ?string $p2pk_prefix2 = null; + // Liquid-specific + + public ?string $native_asset = null; + // final public function pre_initialize() @@ -52,6 +56,15 @@ final public function post_post_initialize() $this->special_addresses[] = 'hogwarts'; if (in_array(UTXOSpecialFeatures::HasShieldedPools, $this->extra_features)) $this->special_addresses[] = '*-pool'; + + if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $this->extra_features)) + { + $this->special_addresses[] = 'bitcoin'; + if (is_null($this->native_asset)) + throw new DeveloperError("Native asset is not set for Liquid Bitcoin"); + if ($this->privacy_model !== PrivacyModel::Mixed) + throw new DeveloperError("Invalid privacy model for Liquid Bitcoin (need Mixed)"); + } } final public function pre_process_block($block_id) @@ -131,6 +144,12 @@ final public function pre_process_block($block_id) foreach ($transaction['vout'] as $output) { + if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $this->extra_features)) + { + $asset = $output['asset'] ?? $this->native_asset; + if ($asset !== $this->native_asset) + continue; // Skip not native assets + } if (in_array(UTXOSpecialFeatures::HasMWEB, $this->extra_features)) { if ($this->block_id === MEMPOOL && !isset($output['scriptPubKey']) && isset($transaction['vkern'])) @@ -179,11 +198,29 @@ final public function pre_process_block($block_id) if (in_array($output['scriptPubKey']['type'], ['witness_mweb_hogaddr', 'witness_mweb_pegin'])) $address = 'hogwarts'; - $events[] = ['transaction' => $transaction['txid'], - 'address' => $address, - 'effect' => satoshi($output['value'], $this), - 'sort_in_transaction' => ((int)$output['n'] + 1) - ]; + if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $this->extra_features)) + { + $effect = isset($output['value']) ? satoshi($output['value'], $this) : '+?'; + $type = $output['scriptPubKey']['type'] ?? ''; + if ($type !== 'fee') // Skip additional event for fee out + { + $events[] = [ + 'transaction' => $transaction['txid'], + 'address' => $address, + 'effect' => $effect, + 'sort_in_transaction' => ((int)$output['n'] + 1) + ]; + } + } + else + { + $events[] = [ + 'transaction' => $transaction['txid'], + 'address' => $address, + 'effect' => satoshi($output['value'], $this), + 'sort_in_transaction' => ((int)$output['n'] + 1) + ]; + } if ($this_is_coinbase) { @@ -191,7 +228,16 @@ final public function pre_process_block($block_id) } else { - $fees[($transaction['txid'])] = bcsub($fees[($transaction['txid'])], satoshi($output['value'], $this)); + if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $this->extra_features)) + { + $type = $output['scriptPubKey']['type'] ?? ''; + if ($type === 'fee') + $fees[($transaction['txid'])] = satoshi($output['value'], $this); + } + else + { + $fees[($transaction['txid'])] = bcsub($fees[($transaction['txid'])], satoshi($output['value'], $this)); + } } } @@ -283,6 +329,32 @@ final public function pre_process_block($block_id) } else { + // In LiquidBitcoin we cant get the previous tx vouts for pegin txs + if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $this->extra_features)) + { + $is_pegin = $input['is_pegin'] ?? false; + if ($is_pegin == true) + { + // Calculate exact amount from bitcoin + $value = '0'; + foreach ($transaction['vout'] as $out) + { + $type = $out['scriptPubKey']['type'] ?? ''; + if ($type !== 'fee') + $value = bcadd($value, satoshi($out['value'], $this)); + } + + // Set event for pegin and skip check for this input + $events[] = [ + 'transaction' => $transaction['txid'], + 'address' => 'bitcoin', + 'effect' => '-' . $value, + 'sort_in_transaction' => -1, + ]; + continue; + } + } + if (!isset($previous_outputs_lib[($input['txid'])])) { $populate_outputs_lib_with[] = $input['txid']; @@ -338,6 +410,13 @@ final public function pre_process_block($block_id) { $previous_output = $previous_outputs_lib[($input['previous_transaction'])]; + if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $this->extra_features)) + { + $asset = $output['asset'] ?? $this->native_asset; + if ($asset !== $this->native_asset) + continue; // Skip sends not native assets + } + if (!in_array(UTXOSpecialFeatures::OneAddressInScriptPubKey, $this->extra_features)) { if (isset($previous_output[($input['previous_n'])]['scriptPubKey']['addresses'][0]) && count($previous_output[($input['previous_n'])]['scriptPubKey']['addresses']) === 1) @@ -376,9 +455,19 @@ final public function pre_process_block($block_id) if (str_contains($address, ':')) $address = explode(':', $address)[1]; + if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $this->extra_features)) + { + $effect = isset($previous_output[($input['previous_n'])]['value']) ? satoshi($previous_output[($input['previous_n'])]['value'], $this) : '?'; + $previous_output[($input['previous_n'])]['value'] = $previous_output[($input['previous_n'])]['value'] ?? '0.00000000'; + } + else + { + $effect = satoshi($previous_output[($input['previous_n'])]['value'], $this); + } + $events[] = ['transaction' => $input['this_transaction'], 'address' => $address, - 'effect' => "-" . satoshi($previous_output[($input['previous_n'])]['value'], $this), + 'effect' => "-" . $effect, 'sort_in_transaction' => (int)$input['this_n'], ]; diff --git a/Modules/Common/UTXOTraits.php b/Modules/Common/UTXOTraits.php index ec12d3bf..c5734682 100644 --- a/Modules/Common/UTXOTraits.php +++ b/Modules/Common/UTXOTraits.php @@ -70,6 +70,7 @@ enum UTXOSpecialFeatures case HasShieldedPools; // Shielded pool processing in Zcash case Not8Decimals; // There's a "non-standard" number of decimals, i.e. not 8; e.g. Peercoin case OneAddressInScriptPubKey; // There's no "addresses" array in scriptPubKey + case LiquidBitcoin; // Liquid has anonymous amount/assets by default and pegin transactions case ManualCashAddress; // eCash doesn't output CashAddress format addresses for P2PK scripts } @@ -170,6 +171,8 @@ function satoshi(string $value, CoreModule|false $module = false): string { if ($module === false || !in_array(UTXOSpecialFeatures::Not8Decimals, $module->extra_features)) { + if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $module->extra_features) && $value === '?') + return $value; if ($value === '0.00000000') return '0'; if (strlen(explode('.', $value)[1]) !== 8) throw new ModuleError("satoshi(value: ({$value})): incorrect value"); return ltrim(str_replace('.', '', $value), '0'); diff --git a/Modules/LiquidAssetsModule.php b/Modules/LiquidAssetsModule.php new file mode 100644 index 00000000..2ea2f647 --- /dev/null +++ b/Modules/LiquidAssetsModule.php @@ -0,0 +1,30 @@ +blockchain = 'liquid'; + $this->module = 'liquid-assets'; + $this->is_main = false; + $this->first_block_date = '2018-09-27'; + + // Liquid-specific + $this->ignore_sum_of_all_effects = true; // Cause of PrivacyModel::Mixed + $this->native_asset = '6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d'; + + // Tests + $this->tests = [ + ['block' => 2774298, 'result' => 'a:2:{s:6:"events";a:2:{i:0;a:7:{s:11:"transaction";s:64:"97d3a20cb85209167de9ff354be7a6b7f10506db35a7ca5dfeae81cdfce73433";s:8:"currency";s:64:"71e30c59c03e78d064757befa459ae7a0e9c4b8a5ae16cc90b3d70fc73b40ce4";s:7:"address";s:8:"the-void";s:6:"effect";s:10:"-101899500";s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:0;}i:1;a:7:{s:11:"transaction";s:64:"97d3a20cb85209167de9ff354be7a6b7f10506db35a7ca5dfeae81cdfce73433";s:8:"currency";s:64:"71e30c59c03e78d064757befa459ae7a0e9c4b8a5ae16cc90b3d70fc73b40ce4";s:7:"address";s:42:"ex1qh59jvreqevgl2jwrx325zcp5lmdksaettgr62h";s:6:"effect";s:9:"101899500";s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:1;}}s:10:"currencies";a:1:{i:0;a:4:{s:2:"id";s:64:"71e30c59c03e78d064757befa459ae7a0e9c4b8a5ae16cc90b3d70fc73b40ce4";s:4:"name";s:26:"Taxkredit project 68cbc66a";s:6:"symbol";s:5:"tWaZe";s:8:"decimals";s:1:"2";}}}'], + ]; + } +} diff --git a/Modules/LiquidMainModule.php b/Modules/LiquidMainModule.php new file mode 100644 index 00000000..abadde7f --- /dev/null +++ b/Modules/LiquidMainModule.php @@ -0,0 +1,41 @@ +blockchain = 'liquid'; + $this->module = 'liquid-main'; + $this->is_main = true; + $this->currency = 'liquid'; // Static + $this->currency_details = ['name' => 'Liquid Bitcoin', 'symbol' => 'L-BTC', 'decimals' => 8, 'description' => null]; + $this->first_block_date = '2018-09-27'; + + // UTXOMainModule + $this->p2pk_prefix1 = ''; + $this->p2pk_prefix2 = ''; + + // Liquid-specific + $this->privacy_model = PrivacyModel::Mixed; + $this->ignore_sum_of_all_effects = true; // Cause of PrivacyModel::Mixed + $this->extra_features = [UTXOSpecialFeatures::LiquidBitcoin, UTXOSpecialFeatures::OneAddressInScriptPubKey]; + $this->native_asset = '6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d'; + + // Tests + $this->tests = [ + // Some block + ['block' => 2766919, 'result' => 'a:2:{s:6:"events";a:13:{i:0;a:6:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:7:"address";s:8:"the-void";s:6:"effect";s:4:"-446";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:0;}i:1;a:6:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:7:"address";s:39:"script-efcb3e8b994fe44d9b6dd0b55ab213a0";s:6:"effect";s:1:"0";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:1;}i:2;a:6:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:7:"address";s:34:"QLFdUboUPJnUzvsXKu83hUtrQ1DuxyggRg";s:6:"effect";s:3:"446";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:2;}i:3;a:6:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:7:"address";s:39:"script-287938b14253c57813474cb5eaf51d63";s:6:"effect";s:1:"0";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:3;}i:4;a:6:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:7:"address";s:42:"ex1qq2wh460mj56u5dunv8g9e4demrfa3sh723hums";s:6:"effect";s:2:"-?";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:4;}i:5;a:6:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:7:"address";s:42:"ex1qn84sc3540g7v8qr4j0tdsfa6qlshzsn47rz3yh";s:6:"effect";s:2:"-?";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:5;}i:6;a:6:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:7:"address";s:42:"ex1qwmyrwfm2fkcf82qmayhg22nh455ecyk4pqdp69";s:6:"effect";s:2:"-?";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:6;}i:7;a:6:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:7:"address";s:62:"ex1qemcjtseyldmga7axcv4sfq4dz3vap96snpe70huyalv84hxmn8wsty4yuv";s:6:"effect";s:2:"+?";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:7;}i:8;a:6:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:7:"address";s:42:"ex1qzhftnsrlr9x3vn9du9lgtqqllux2elpe2mva6w";s:6:"effect";s:2:"+?";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:8;}i:9;a:6:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"294";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:9;}i:10;a:6:{s:11:"transaction";s:64:"57b56f5b9ec72c95cf3431e1fe9e1ec528ebbbc4b59819fd701484fca5d43b88";s:7:"address";s:62:"ex1qemcjtseyldmga7axcv4sfq4dz3vap96snpe70huyalv84hxmn8wsty4yuv";s:6:"effect";s:2:"-?";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:10;}i:11;a:6:{s:11:"transaction";s:64:"57b56f5b9ec72c95cf3431e1fe9e1ec528ebbbc4b59819fd701484fca5d43b88";s:7:"address";s:34:"GteSSbj2k7EmNCXqnNnagGsTPVQ6S93N6n";s:6:"effect";s:2:"+?";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:11;}i:12;a:6:{s:11:"transaction";s:64:"57b56f5b9ec72c95cf3431e1fe9e1ec528ebbbc4b59819fd701484fca5d43b88";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"152";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:12;}}s:10:"currencies";N;}'], + // Block with pegin + ['block' => 2766423, 'result' => 'a:2:{s:6:"events";a:10:{i:0;a:6:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"-86";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:0;}i:1;a:6:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:7:"address";s:39:"script-14b005d6cde92956f8acef08cd554ebd";s:6:"effect";s:1:"0";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:1;}i:2;a:6:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:7:"address";s:34:"QLFdUboUPJnUzvsXKu83hUtrQ1DuxyggRg";s:6:"effect";s:2:"86";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:2;}i:3;a:6:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:7:"address";s:39:"script-08be25e98319c0bfe137f3102fbc496c";s:6:"effect";s:1:"0";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:3;}i:4;a:6:{s:11:"transaction";s:64:"9d9209113c3ded3a1a9a28be5b1227206d94b49df8f3adbbb343002d2d90fe00";s:7:"address";s:7:"bitcoin";s:6:"effect";s:8:"-2497468";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:4;}i:5;a:6:{s:11:"transaction";s:64:"9d9209113c3ded3a1a9a28be5b1227206d94b49df8f3adbbb343002d2d90fe00";s:7:"address";s:42:"ex1q4q240cjajpc2jy7kcs09zqsqh3xalfzeectgay";s:6:"effect";s:7:"2497468";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:5;}i:6;a:6:{s:11:"transaction";s:64:"9d9209113c3ded3a1a9a28be5b1227206d94b49df8f3adbbb343002d2d90fe00";s:7:"address";s:8:"the-void";s:6:"effect";s:2:"43";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:6;}i:7;a:6:{s:11:"transaction";s:64:"cf2e9f28f41e6a5ebdaee32c17123b36616283728d850842206b4204291717a5";s:7:"address";s:7:"bitcoin";s:6:"effect";s:8:"-1548364";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:7;}i:8;a:6:{s:11:"transaction";s:64:"cf2e9f28f41e6a5ebdaee32c17123b36616283728d850842206b4204291717a5";s:7:"address";s:42:"ex1qvtp03vtzeru6lff556xx7xssvm3a3mlzjtxdme";s:6:"effect";s:7:"1548364";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:8;}i:9;a:6:{s:11:"transaction";s:64:"cf2e9f28f41e6a5ebdaee32c17123b36616283728d850842206b4204291717a5";s:7:"address";s:8:"the-void";s:6:"effect";s:2:"43";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:9;}}s:10:"currencies";N;}'], + // Block with assets + ['block' => 2766264, 'result' => 'a:2:{s:6:"events";a:8:{i:0;a:6:{s:11:"transaction";s:64:"8285e7867e524659c5cb2850e2dbc8d5d658cef43a87582e43588d3dee9b8b5b";s:7:"address";s:8:"the-void";s:6:"effect";s:4:"-319";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:0;}i:1;a:6:{s:11:"transaction";s:64:"8285e7867e524659c5cb2850e2dbc8d5d658cef43a87582e43588d3dee9b8b5b";s:7:"address";s:39:"script-81f8057b579b326fedf8d76b33d87165";s:6:"effect";s:1:"0";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:1;}i:2;a:6:{s:11:"transaction";s:64:"8285e7867e524659c5cb2850e2dbc8d5d658cef43a87582e43588d3dee9b8b5b";s:7:"address";s:34:"QLFdUboUPJnUzvsXKu83hUtrQ1DuxyggRg";s:6:"effect";s:3:"319";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:2;}i:3;a:6:{s:11:"transaction";s:64:"8285e7867e524659c5cb2850e2dbc8d5d658cef43a87582e43588d3dee9b8b5b";s:7:"address";s:39:"script-616f900e387746e1e4b116ef73f6ccb3";s:6:"effect";s:1:"0";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:3;}i:4;a:6:{s:11:"transaction";s:64:"1fc472aaff27c643608be24f6b86f8f5230068db98f7e2ddd7c0a4fc7d1f6c86";s:7:"address";s:62:"ex1qlg7hpqluy7xccvgscw7qww0cdkr8lcccsjk0lc7ay6e3spze3ruqapqwlw";s:6:"effect";s:2:"-?";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:4;}i:5;a:6:{s:11:"transaction";s:64:"1fc472aaff27c643608be24f6b86f8f5230068db98f7e2ddd7c0a4fc7d1f6c86";s:7:"address";s:62:"ex1qvgn6f95j4kf84quk0w0ad0mayruv2guuph5rvl8jjq2u4spqu9pseyzl2w";s:6:"effect";s:2:"-?";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:5;}i:6;a:6:{s:11:"transaction";s:64:"1fc472aaff27c643608be24f6b86f8f5230068db98f7e2ddd7c0a4fc7d1f6c86";s:7:"address";s:62:"ex1qysz258hssf960jhljqmyaea9257qn3w7mc06272kf5y8gdx06d2qvm74k3";s:6:"effect";s:2:"+?";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:6;}i:7;a:6:{s:11:"transaction";s:64:"1fc472aaff27c643608be24f6b86f8f5230068db98f7e2ddd7c0a4fc7d1f6c86";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"319";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:7;}}s:10:"currencies";N;}'], + ]; + } +} From 00b880caf33af88154491fbb59f43ea1a38bac91 Mon Sep 17 00:00:00 2001 From: oskal174 Date: Wed, 27 Mar 2024 02:21:05 +0500 Subject: [PATCH 2/7] liquid in one module --- .env.example | 15 +- Modules/Common/UTXOLiquidAssetsModule.php | 295 --------------- Modules/Common/UTXOLiquidModule.php | 415 ++++++++++++++++++++++ Modules/Common/UTXOMainModule.php | 103 +----- Modules/Common/UTXOTraits.php | 3 - Modules/LiquidAssetsModule.php | 30 -- Modules/LiquidMainModule.php | 28 +- 7 files changed, 435 insertions(+), 454 deletions(-) delete mode 100644 Modules/Common/UTXOLiquidAssetsModule.php create mode 100644 Modules/Common/UTXOLiquidModule.php delete mode 100644 Modules/LiquidAssetsModule.php diff --git a/.env.example b/.env.example index 25d93947..4d62ca96 100644 --- a/.env.example +++ b/.env.example @@ -876,28 +876,17 @@ MODULE_rootstock-erc-1155_REQUESTER_TIMEOUT=60 MODULE_rootstock-erc-1155_REQUESTER_THREADS=12 ###################### -## Main liquid Module +## Main Liquid Module ###################### MODULES[]=liquid-main MODULE_liquid-main_CLASS=LiquidMainModule MODULE_liquid-main_NODES[]=http://login:password@127.0.0.1:1234/ MODULE_liquid-main_NODES[]=http://login:password@127.0.0.1:1234/ +MODULE_liquid-main_ASSETS_REGISTRY=http://login:password@127.0.0.1:12345/ MODULE_liquid-main_REQUESTER_TIMEOUT=60 MODULE_liquid-main_REQUESTER_THREADS=12 -###################### -## Assets liquid Module -###################### - -MODULES[]=liquid-assets -MODULE_liquid-assets_CLASS=LiquidAssetsModule -MODULE_liquid-assets_NODES[]=http://login:password@127.0.0.1:1234/ -MODULE_liquid-assets_NODES[]=http://login:password@127.0.0.1:1234/ -MODULE_liquid-assets_ASSETS_REGISTRY=http://login:password@127.0.0.1:12345/ -MODULE_liquid-assets_REQUESTER_TIMEOUT=60 -MODULE_liquid-assets_REQUESTER_THREADS=12 - ############################ # Titles, descriptions, etc. ############################ diff --git a/Modules/Common/UTXOLiquidAssetsModule.php b/Modules/Common/UTXOLiquidAssetsModule.php deleted file mode 100644 index 4cff8c47..00000000 --- a/Modules/Common/UTXOLiquidAssetsModule.php +++ /dev/null @@ -1,295 +0,0 @@ -version = 1; - } - - final public function post_post_initialize() - { - if (is_null($this->native_asset)) - throw new DeveloperError("Native asset is not set"); - $this->asset_registry = envm( - $this->module, - 'ASSETS_REGISTRY', - new DeveloperError('ASSETS_REGISTRY not set in the env config') - ); - } - - final public function pre_process_block($block_id) - { - $block_hash = $this->block_hash; - $block = requester_single($this->select_node(), endpoint: "rest/block/{$block_hash}.json", timeout: $this->timeout); - $this->block_time = date('Y-m-d H:i:s', (int)$block['time']); - - $events = []; - $currencies = []; - - $currencies_to_process = []; - $currencies_sums = []; - - $previous_outputs_lib = []; - $populate_outputs_lib_with = []; - $GLOBALS['populate_outputs_lib_with_indexes'] = []; - $inputs_to_check = []; - $sort_in_block_lib = []; - - $block_n = 0; - - // Process outputs - - foreach ($block['tx'] as $transaction) - { - $previous_outputs_lib[($transaction['txid'])] = $transaction['vout']; - - foreach ($transaction['vout'] as $output) - { - $asset = $output['asset'] ?? $this->native_asset; - if ($asset === $this->native_asset) - continue; // Skip native assets - - if (isset($output['scriptPubKey']['address'])) - $address = $output['scriptPubKey']['address']; - else - $address = 'script-' . substr(hash('sha256', $output['scriptPubKey']['hex']), 0, 32); - - $effect = isset($output['value']) ? satoshi($output['value'], $this) : '+?'; - $events[] = [ - 'transaction' => $transaction['txid'], - 'currency' => $asset, - 'address' => $address, - 'effect' => $effect, - 'sort_in_transaction' => ((int)$output['n'] + 1) - ]; - - $currencies_to_process[] = $asset; - if (!array_key_exists($asset, $currencies_sums)) - $currencies_sums[$asset] = ['txid' => $transaction['txid'], 'sum' => $effect]; - else - $currencies_sums[$asset]['sum'] = bcadd($currencies_sums[$asset]['sum'], $effect); - } - - $sort_in_block_lib[($transaction['txid'])] = $block_n; - $block_n++; - } - - // Process inputs - - foreach ($block['tx'] as $transaction) - { - $this_n = 1; - foreach ($transaction['vin'] as $input) - { - if (isset($input['coinbase'])) - continue; - - $is_pegin = $input['is_pegin'] ?? false; - if ($is_pegin == true) - continue; - - if (!isset($previous_outputs_lib[($input['txid'])])) - { - $populate_outputs_lib_with[] = $input['txid']; - $GLOBALS['populate_outputs_lib_with_indexes'][$input['txid']][] = $input['vout']; - } - - $inputs_to_check[] = ['this_transaction' => $transaction['txid'], - 'previous_transaction' => $input['txid'], - 'previous_n' => $input['vout'], - 'this_n' => -$this_n, - ]; - - $this_n++; - } - } - - $multi_curl = []; - - $populate_outputs_lib_with = array_unique($populate_outputs_lib_with); - - // Get input data from the node - - foreach ($populate_outputs_lib_with as $tx_hash) - { - $multi_curl[] = requester_multi_prepare($this->select_node(), - params: ['method' => 'getrawtransaction', 'params' => [$tx_hash, 1]], - timeout: $this->timeout); - } - - $curl_results = requester_multi($multi_curl, - limit: envm($this->module, 'REQUESTER_THREADS'), - timeout: $this->timeout, post_process: function($output) { - $output = requester_multi_process($output, result_in: 'result'); - - foreach ($output['vout'] as $vok => $vov) - { - if (!in_array($vok, $GLOBALS['populate_outputs_lib_with_indexes'][$output['txid']])) - unset($output['vout'][$vok]); - } - - return ['txid' => $output['txid'], 'vout' => $output['vout']]; - }); - - foreach ($curl_results as $output) - { - $previous_outputs_lib[$output['txid']] = $output['vout']; - } - - foreach ($inputs_to_check as $input) - { - if (!isset($previous_outputs_lib[($input['previous_transaction'])])) - throw new ModuleError('Input is not in the library'); - - $previous_output = $previous_outputs_lib[($input['previous_transaction'])]; - - $asset = $previous_output[($input['previous_n'])]['asset'] ?? $this->native_asset; - if ($asset === $this->native_asset) - continue; // Skip native assets - - if (isset($previous_output[($input['previous_n'])]['scriptPubKey']['address'])) - $address = $previous_output[($input['previous_n'])]['scriptPubKey']['address']; - else - $address = 'script-' . substr(hash('sha256', $previous_output[($input['previous_n'])]['scriptPubKey']['hex']), 0, 32); - - $effect = isset($previous_output[($input['previous_n'])]['value']) ? satoshi($previous_output[($input['previous_n'])]['value'], $this) : '?'; - $events[] = [ - 'transaction' => $input['this_transaction'], - 'currency' => $asset, - 'address' => $address, - 'effect' => '-' . $effect, - 'sort_in_transaction' => (int)$input['this_n'], - ]; - - $currencies_to_process[] = $asset; - if (!array_key_exists($asset, $currencies_sums)) - throw new ModuleError("Currency {$asset} not found in outputs"); - else - $currencies_sums[$asset]['sum'] = bcsub($currencies_sums[$asset]['sum'], $effect); - } - - // Process currencies - - // Add mint events - foreach ($currencies_sums as $asset => $info) - { - if ($info['sum'][0] === '-') - throw new ModuleError("Unexpected minus for {$asset}"); - if ($info['sum'] === '0') - continue; - $events[] = [ - 'transaction' => $info['txid'], - 'currency' => $asset, - 'address' => 'the-void', - 'effect' => '-' . $info['sum'], - 'sort_in_transaction' => -1, - ]; - } - - $currencies_to_process = array_values(array_unique($currencies_to_process)); // Removing duplicates - $currencies_to_process = check_existing_currencies($currencies_to_process, $this->currency_format); // Removes already known currencies - - // Get metadata - foreach ($currencies_to_process as $currency) - { - try - { - $meta = requester_single($this->asset_registry, endpoint: $currency, timeout: $this->timeout, valid_codes: [200, 404]); - } - catch (RequesterException $e) - { - // For unknown assets returns HTML page with 404 code - if (str_contains($e->getMessage(), 'bad JSON')) - $meta = [ - 'name' => 'unknown', - 'ticker' => 'unknown', - 'precision' => 0, - ]; - else - throw $e; - } - - $currencies[] = [ - 'id' => $currency, - 'name' => $meta['name'] ?? '', - 'symbol' => $meta['ticker'] ?? '', - 'decimals' => $meta['precision'] ?? 0, - ]; - } - - foreach ($events as &$event) - { - $event['block'] = $block_id; - $event['sort_in_block'] = $sort_in_block_lib[($event['transaction'])]; - $event['time'] = date('Y-m-d H:i:s', (($this->block_id !== MEMPOOL) ? (int)$block['time'] : time())); - } - - // Resort - - usort($events, function($a, $b) { - return [$a['sort_in_block'], - !str_starts_with($a['effect'], '-'), - abs($a['sort_in_transaction']), - ] - <=> - [$b['sort_in_block'], - !str_starts_with($b['effect'], '-'), - abs($b['sort_in_transaction']), - ]; - }); - - $sort_key = 0; - foreach ($events as &$event) - { - $event['sort_key'] = $sort_key++; - - unset($event['sort_in_block']); - unset($event['sort_in_transaction']); - } - - $this->set_return_events($events); - $this->set_return_currencies($currencies); - } -} diff --git a/Modules/Common/UTXOLiquidModule.php b/Modules/Common/UTXOLiquidModule.php new file mode 100644 index 00000000..3aad6d44 --- /dev/null +++ b/Modules/Common/UTXOLiquidModule.php @@ -0,0 +1,415 @@ + 'Peg-in transaction', + 'po' => 'Peg-out transaction', + ]; + + // For back compatibility with UTXO traits + public array $extra_features = []; + + // Liquid-specific + + public ?string $native_asset = null; + public ? array $native_asset_meta = null; + public ?string $asset_registry = null; + + // + + final public function pre_initialize() + { + $this->version = 1; + } + + final public function post_post_initialize() + { + if (is_null($this->native_asset)) + throw new DeveloperError("Native asset is not set"); + if (is_null($this->native_asset_meta)) + throw new DeveloperError("Native asset meta is not set"); + $this->asset_registry = envm( + $this->module, + 'ASSETS_REGISTRY', + new DeveloperError('ASSETS_REGISTRY not set in the env config') + ); + } + + final public function pre_process_block($block_id) + { + if ($block_id !== MEMPOOL) + { + $block_hash = $this->block_hash; + $block = requester_single($this->select_node(), endpoint: "rest/block/{$block_hash}.json", timeout: $this->timeout); + $this->block_time = date('Y-m-d H:i:s', (int)$block['time']); + } + else // Processing mempool + { + $block = []; + $block['tx'] = []; + $multi_curl = []; + + $mempool = requester_single($this->select_node(), params: ['method' => 'getrawmempool', 'params' => [false]], result_in: 'result', timeout: $this->timeout); + + $islice = 0; + + foreach ($mempool as $tx_hash) + { + if (!isset($this->processed_transactions[$tx_hash])) + { + $multi_curl[] = requester_multi_prepare($this->select_node(), + params: ['method' => 'getrawtransaction', 'params' => [$tx_hash, 1]], + timeout: $this->timeout); + + $islice++; + if ($islice >= 100) break; // For debug purposes, we limit the number of mempool transactions to process + } + } + + $curl_results = requester_multi($multi_curl, limit: envm($this->module, 'REQUESTER_THREADS'), timeout: $this->timeout); + + foreach ($curl_results as $v) + { + $block['tx'][] = requester_multi_process($v, result_in: 'result'); + } + } + + $events = []; + $currencies = []; + + $currencies_to_process = []; + + $previous_outputs_lib = []; + $populate_outputs_lib_with = []; + $GLOBALS['populate_outputs_lib_with_indexes'] = []; + $inputs_to_check = []; + $sort_in_block_lib = []; + $fees = []; + + $block_n = 0; + $coinbase_transaction_output = '0'; + + $this_is_coinbase = true; // Coinbase transaction is always the first one + if ($this->block_id === MEMPOOL) $this_is_coinbase = false; + + // Process outputs + + foreach ($block['tx'] as $transaction) + { + $previous_outputs_lib[($transaction['txid'])] = $transaction['vout']; + $fees[($transaction['txid'])] = ['amount' => '0', 'currency' => null]; + + foreach ($transaction['vout'] as $output) + { + if (isset($output['scriptPubKey']['address'])) + $address = $output['scriptPubKey']['address']; + else + $address = 'script-' . substr(hash('sha256', $output['scriptPubKey']['hex']), 0, 32); + + $extra = $extra_indexed = null; + if (isset($output['scriptPubKey']['pegout_address'])) + { + $extra = 'po'; + $extra_indexed = $output['scriptPubKey']['pegout_address']; + } + + $asset = $output['asset'] ?? null; + $effect = isset($output['value']) ? satoshi($output['value'], $this) : '+?'; + $type = $output['scriptPubKey']['type'] ?? ''; + + if ($type === 'fee') // Skip additional event for fee out + { + if (is_null($asset)) + throw new ModuleError("Null asset for fee output type"); + $fees[($transaction['txid'])]['amount'] = satoshi($output['value'], $this); + $fees[($transaction['txid'])]['currency'] = $asset; + } + else + { + $events[] = [ + 'transaction' => $transaction['txid'], + 'currency' => $asset, + 'address' => $address, + 'effect' => $effect, + 'sort_in_transaction' => ((int)$output['n'] + 1), + 'extra' => $extra, + 'extra_indexed' => $extra_indexed, + ]; + } + + if (!is_null($asset)) + $currencies_to_process[] = $asset; + + if ($this_is_coinbase) + $coinbase_transaction_output = bcsub($coinbase_transaction_output, satoshi($output['value'], $this)); + } + + $this_is_coinbase = false; + + $sort_in_block_lib[($transaction['txid'])] = $block_n; + $block_n++; + } + + // Process inputs + + foreach ($block['tx'] as $transaction) + { + $this_n = 1; + foreach ($transaction['vin'] as $input) + { + if (isset($input['coinbase'])) + { + if ($coinbase_transaction_output === '0') $coinbase_transaction_output = '-0'; // E.g. block #501726 in Bitcoin + + $events[] = [ + 'transaction' => $transaction['txid'], + 'currency' => $this->native_asset, + 'address' => 'the-void', + 'effect' => $coinbase_transaction_output, + 'sort_in_transaction' => -1, + 'extra' => null, + 'extra_indexed' => null, + ]; + } + else + { + // In LiquidBitcoin we cant get the previous tx vouts for pegin txs + $is_pegin = $input['is_pegin'] ?? false; + if ($is_pegin == true) + { + // Calculate exact amount from bitcoin + $value = '0'; + foreach ($transaction['vout'] as $out) + { + $type = $out['scriptPubKey']['type'] ?? ''; + if ($type !== 'fee') + $value = bcadd($value, satoshi($out['value'], $this)); + } + + // Set event for pegin and skip check for this input + $events[] = [ + 'transaction' => $transaction['txid'], + 'currency' => $this->native_asset, + 'address' => 'bitcoin', + 'effect' => '-' . $value, + 'sort_in_transaction' => -1, + 'extra' => 'pi', + 'extra_indexed' => $input['txid'], + ]; + $currencies_to_process[] = $this->native_asset; + continue; + } + + if (!isset($previous_outputs_lib[($input['txid'])])) + { + $populate_outputs_lib_with[] = $input['txid']; + $GLOBALS['populate_outputs_lib_with_indexes'][$input['txid']][] = $input['vout']; + } + + $inputs_to_check[] = [ + 'this_transaction' => $transaction['txid'], + 'previous_transaction' => $input['txid'], + 'previous_n' => $input['vout'], + 'this_n' => -$this_n, + ]; + + $this_n++; + } + } + } + + $multi_curl = []; + + $populate_outputs_lib_with = array_unique($populate_outputs_lib_with); + + // Get input data from the node + + foreach ($populate_outputs_lib_with as $tx_hash) + { + $multi_curl[] = requester_multi_prepare($this->select_node(), + params: ['method' => 'getrawtransaction', 'params' => [$tx_hash, 1]], + timeout: $this->timeout); + } + + $curl_results = requester_multi($multi_curl, + limit: envm($this->module, 'REQUESTER_THREADS'), + timeout: $this->timeout, post_process: function($output) { + $output = requester_multi_process($output, result_in: 'result'); + + foreach ($output['vout'] as $vok => $vov) + { + if (!in_array($vok, $GLOBALS['populate_outputs_lib_with_indexes'][$output['txid']])) + unset($output['vout'][$vok]); + } + + return ['txid' => $output['txid'], 'vout' => $output['vout']]; + }); + + foreach ($curl_results as $output) + { + $previous_outputs_lib[$output['txid']] = $output['vout']; + } + + foreach ($inputs_to_check as $input) + { + if (!isset($previous_outputs_lib[($input['previous_transaction'])])) + throw new ModuleError('Input is not in the library'); + + $previous_output = $previous_outputs_lib[($input['previous_transaction'])]; + + if (isset($previous_output[($input['previous_n'])]['scriptPubKey']['address'])) + $address = $previous_output[($input['previous_n'])]['scriptPubKey']['address']; + else + $address = 'script-' . substr(hash('sha256', $previous_output[($input['previous_n'])]['scriptPubKey']['hex']), 0, 32); + + $asset = $previous_output[($input['previous_n'])]['asset'] ?? $this->native_asset; + $effect = isset($previous_output[($input['previous_n'])]['value']) ? satoshi($previous_output[($input['previous_n'])]['value'], $this) : '?'; + $events[] = [ + 'transaction' => $input['this_transaction'], + 'currency' => $asset, + 'address' => $address, + 'effect' => '-' . $effect, + 'sort_in_transaction' => (int)$input['this_n'], + 'extra' => null, + 'extra_indexed' => null, + ]; + + $currencies_to_process[] = $asset; + } + + foreach ($fees as $txid => $fee_transfer) + { + if ($fee_transfer['amount'] !== '0') + { + $events[] = [ + 'transaction' => $txid, + 'currency' => $fee_transfer['currency'], + 'address' => 'the-void', + 'effect' => $fee_transfer['amount'], + 'sort_in_transaction' => PHP_INT_MAX, + 'extra' => null, + 'extra_indexed' => null, + ]; + } + } + + // Process currencies + + $currencies_to_process = array_values(array_unique($currencies_to_process)); // Removing duplicates + $currencies_to_process = check_existing_currencies($currencies_to_process, $this->currency_format); // Removes already known currencies + + // Get metadata + foreach ($currencies_to_process as $currency) + { + try + { + if ($currency === $this->native_asset) + $meta = $this->native_asset_meta; + else + $meta = requester_single($this->asset_registry, endpoint: $currency, timeout: $this->timeout, valid_codes: [200, 404]); + } + catch (RequesterException $e) + { + // For unknown assets returns HTML page with 404 code + if (str_contains($e->getMessage(), 'bad JSON')) + $meta = [ + 'name' => 'unknown', + 'ticker' => 'unknown', + 'precision' => 0, + ]; + else + throw $e; + } + + $currencies[] = [ + 'id' => $currency, + 'name' => $meta['name'] ?? '', + 'symbol' => $meta['ticker'] ?? '', + 'decimals' => $meta['precision'] ?? 0, + ]; + } + + foreach ($events as &$event) + { + $event['block'] = $block_id; + $event['sort_in_block'] = $sort_in_block_lib[($event['transaction'])]; + $event['time'] = date('Y-m-d H:i:s', (($this->block_id !== MEMPOOL) ? (int)$block['time'] : time())); + } + + // Resort + + usort($events, function($a, $b) { + return [$a['sort_in_block'], + !str_starts_with($a['effect'], '-'), + abs($a['sort_in_transaction']), + ] + <=> + [$b['sort_in_block'], + !str_starts_with($b['effect'], '-'), + abs($b['sort_in_transaction']), + ]; + }); + + $sort_key = 0; + $latest_tx_hash = ''; // This is for mempool + foreach ($events as &$event) + { + if ($this->block_id === MEMPOOL && $event['transaction'] !== $latest_tx_hash) + { + $latest_tx_hash = $event['transaction']; + $sort_key = 0; + } + + $event['sort_key'] = $sort_key++; + + unset($event['sort_in_block']); + unset($event['sort_in_transaction']); + } + + $this->set_return_events($events); + if ($this->block_id !== MEMPOOL) $this->set_return_currencies($currencies); + } +} diff --git a/Modules/Common/UTXOMainModule.php b/Modules/Common/UTXOMainModule.php index 038de475..c2f422e1 100644 --- a/Modules/Common/UTXOMainModule.php +++ b/Modules/Common/UTXOMainModule.php @@ -36,10 +36,6 @@ abstract class UTXOMainModule extends CoreModule public ?string $p2pk_prefix1 = null; public ?string $p2pk_prefix2 = null; - // Liquid-specific - - public ?string $native_asset = null; - // final public function pre_initialize() @@ -56,15 +52,6 @@ final public function post_post_initialize() $this->special_addresses[] = 'hogwarts'; if (in_array(UTXOSpecialFeatures::HasShieldedPools, $this->extra_features)) $this->special_addresses[] = '*-pool'; - - if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $this->extra_features)) - { - $this->special_addresses[] = 'bitcoin'; - if (is_null($this->native_asset)) - throw new DeveloperError("Native asset is not set for Liquid Bitcoin"); - if ($this->privacy_model !== PrivacyModel::Mixed) - throw new DeveloperError("Invalid privacy model for Liquid Bitcoin (need Mixed)"); - } } final public function pre_process_block($block_id) @@ -144,12 +131,6 @@ final public function pre_process_block($block_id) foreach ($transaction['vout'] as $output) { - if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $this->extra_features)) - { - $asset = $output['asset'] ?? $this->native_asset; - if ($asset !== $this->native_asset) - continue; // Skip not native assets - } if (in_array(UTXOSpecialFeatures::HasMWEB, $this->extra_features)) { if ($this->block_id === MEMPOOL && !isset($output['scriptPubKey']) && isset($transaction['vkern'])) @@ -198,29 +179,11 @@ final public function pre_process_block($block_id) if (in_array($output['scriptPubKey']['type'], ['witness_mweb_hogaddr', 'witness_mweb_pegin'])) $address = 'hogwarts'; - if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $this->extra_features)) - { - $effect = isset($output['value']) ? satoshi($output['value'], $this) : '+?'; - $type = $output['scriptPubKey']['type'] ?? ''; - if ($type !== 'fee') // Skip additional event for fee out - { - $events[] = [ - 'transaction' => $transaction['txid'], - 'address' => $address, - 'effect' => $effect, - 'sort_in_transaction' => ((int)$output['n'] + 1) - ]; - } - } - else - { - $events[] = [ - 'transaction' => $transaction['txid'], - 'address' => $address, - 'effect' => satoshi($output['value'], $this), - 'sort_in_transaction' => ((int)$output['n'] + 1) - ]; - } + $events[] = ['transaction' => $transaction['txid'], + 'address' => $address, + 'effect' => satoshi($output['value'], $this), + 'sort_in_transaction' => ((int)$output['n'] + 1) + ]; if ($this_is_coinbase) { @@ -228,16 +191,7 @@ final public function pre_process_block($block_id) } else { - if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $this->extra_features)) - { - $type = $output['scriptPubKey']['type'] ?? ''; - if ($type === 'fee') - $fees[($transaction['txid'])] = satoshi($output['value'], $this); - } - else - { - $fees[($transaction['txid'])] = bcsub($fees[($transaction['txid'])], satoshi($output['value'], $this)); - } + $fees[($transaction['txid'])] = bcsub($fees[($transaction['txid'])], satoshi($output['value'], $this)); } } @@ -329,32 +283,6 @@ final public function pre_process_block($block_id) } else { - // In LiquidBitcoin we cant get the previous tx vouts for pegin txs - if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $this->extra_features)) - { - $is_pegin = $input['is_pegin'] ?? false; - if ($is_pegin == true) - { - // Calculate exact amount from bitcoin - $value = '0'; - foreach ($transaction['vout'] as $out) - { - $type = $out['scriptPubKey']['type'] ?? ''; - if ($type !== 'fee') - $value = bcadd($value, satoshi($out['value'], $this)); - } - - // Set event for pegin and skip check for this input - $events[] = [ - 'transaction' => $transaction['txid'], - 'address' => 'bitcoin', - 'effect' => '-' . $value, - 'sort_in_transaction' => -1, - ]; - continue; - } - } - if (!isset($previous_outputs_lib[($input['txid'])])) { $populate_outputs_lib_with[] = $input['txid']; @@ -410,13 +338,6 @@ final public function pre_process_block($block_id) { $previous_output = $previous_outputs_lib[($input['previous_transaction'])]; - if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $this->extra_features)) - { - $asset = $output['asset'] ?? $this->native_asset; - if ($asset !== $this->native_asset) - continue; // Skip sends not native assets - } - if (!in_array(UTXOSpecialFeatures::OneAddressInScriptPubKey, $this->extra_features)) { if (isset($previous_output[($input['previous_n'])]['scriptPubKey']['addresses'][0]) && count($previous_output[($input['previous_n'])]['scriptPubKey']['addresses']) === 1) @@ -455,19 +376,9 @@ final public function pre_process_block($block_id) if (str_contains($address, ':')) $address = explode(':', $address)[1]; - if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $this->extra_features)) - { - $effect = isset($previous_output[($input['previous_n'])]['value']) ? satoshi($previous_output[($input['previous_n'])]['value'], $this) : '?'; - $previous_output[($input['previous_n'])]['value'] = $previous_output[($input['previous_n'])]['value'] ?? '0.00000000'; - } - else - { - $effect = satoshi($previous_output[($input['previous_n'])]['value'], $this); - } - $events[] = ['transaction' => $input['this_transaction'], 'address' => $address, - 'effect' => "-" . $effect, + 'effect' => "-" . satoshi($previous_output[($input['previous_n'])]['value'], $this), 'sort_in_transaction' => (int)$input['this_n'], ]; diff --git a/Modules/Common/UTXOTraits.php b/Modules/Common/UTXOTraits.php index c5734682..ec12d3bf 100644 --- a/Modules/Common/UTXOTraits.php +++ b/Modules/Common/UTXOTraits.php @@ -70,7 +70,6 @@ enum UTXOSpecialFeatures case HasShieldedPools; // Shielded pool processing in Zcash case Not8Decimals; // There's a "non-standard" number of decimals, i.e. not 8; e.g. Peercoin case OneAddressInScriptPubKey; // There's no "addresses" array in scriptPubKey - case LiquidBitcoin; // Liquid has anonymous amount/assets by default and pegin transactions case ManualCashAddress; // eCash doesn't output CashAddress format addresses for P2PK scripts } @@ -171,8 +170,6 @@ function satoshi(string $value, CoreModule|false $module = false): string { if ($module === false || !in_array(UTXOSpecialFeatures::Not8Decimals, $module->extra_features)) { - if (in_array(UTXOSpecialFeatures::LiquidBitcoin, $module->extra_features) && $value === '?') - return $value; if ($value === '0.00000000') return '0'; if (strlen(explode('.', $value)[1]) !== 8) throw new ModuleError("satoshi(value: ({$value})): incorrect value"); return ltrim(str_replace('.', '', $value), '0'); diff --git a/Modules/LiquidAssetsModule.php b/Modules/LiquidAssetsModule.php deleted file mode 100644 index 2ea2f647..00000000 --- a/Modules/LiquidAssetsModule.php +++ /dev/null @@ -1,30 +0,0 @@ -blockchain = 'liquid'; - $this->module = 'liquid-assets'; - $this->is_main = false; - $this->first_block_date = '2018-09-27'; - - // Liquid-specific - $this->ignore_sum_of_all_effects = true; // Cause of PrivacyModel::Mixed - $this->native_asset = '6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d'; - - // Tests - $this->tests = [ - ['block' => 2774298, 'result' => 'a:2:{s:6:"events";a:2:{i:0;a:7:{s:11:"transaction";s:64:"97d3a20cb85209167de9ff354be7a6b7f10506db35a7ca5dfeae81cdfce73433";s:8:"currency";s:64:"71e30c59c03e78d064757befa459ae7a0e9c4b8a5ae16cc90b3d70fc73b40ce4";s:7:"address";s:8:"the-void";s:6:"effect";s:10:"-101899500";s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:0;}i:1;a:7:{s:11:"transaction";s:64:"97d3a20cb85209167de9ff354be7a6b7f10506db35a7ca5dfeae81cdfce73433";s:8:"currency";s:64:"71e30c59c03e78d064757befa459ae7a0e9c4b8a5ae16cc90b3d70fc73b40ce4";s:7:"address";s:42:"ex1qh59jvreqevgl2jwrx325zcp5lmdksaettgr62h";s:6:"effect";s:9:"101899500";s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:1;}}s:10:"currencies";a:1:{i:0;a:4:{s:2:"id";s:64:"71e30c59c03e78d064757befa459ae7a0e9c4b8a5ae16cc90b3d70fc73b40ce4";s:4:"name";s:26:"Taxkredit project 68cbc66a";s:6:"symbol";s:5:"tWaZe";s:8:"decimals";s:1:"2";}}}'], - ]; - } -} diff --git a/Modules/LiquidMainModule.php b/Modules/LiquidMainModule.php index abadde7f..c2334a94 100644 --- a/Modules/LiquidMainModule.php +++ b/Modules/LiquidMainModule.php @@ -4,9 +4,11 @@ * Copyright (c) 2023 3xpl developers, 3@3xpl.com, see CONTRIBUTORS.md * Distributed under the MIT software license, see LICENSE.md */ -/* This is the main Liquid Bitcoin module. */ +/* This is the assets Liquid Bitcoin module. + * Using AssetRegistry: https://docs.liquid.net/docs/blockstream-liquid-asset-registry + * */ -final class LiquidMainModule extends UTXOMainModule implements Module +final class LiquidMainModule extends UTXOLiquidModule implements Module { function initialize() { @@ -14,28 +16,20 @@ function initialize() $this->blockchain = 'liquid'; $this->module = 'liquid-main'; $this->is_main = true; - $this->currency = 'liquid'; // Static - $this->currency_details = ['name' => 'Liquid Bitcoin', 'symbol' => 'L-BTC', 'decimals' => 8, 'description' => null]; $this->first_block_date = '2018-09-27'; - // UTXOMainModule - $this->p2pk_prefix1 = ''; - $this->p2pk_prefix2 = ''; - // Liquid-specific - $this->privacy_model = PrivacyModel::Mixed; - $this->ignore_sum_of_all_effects = true; // Cause of PrivacyModel::Mixed - $this->extra_features = [UTXOSpecialFeatures::LiquidBitcoin, UTXOSpecialFeatures::OneAddressInScriptPubKey]; $this->native_asset = '6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d'; + $this->native_asset_meta = ['name' => 'Liquid Bitcoin', 'ticker' => 'L-BTC', 'precision' => 8]; // Tests $this->tests = [ - // Some block - ['block' => 2766919, 'result' => 'a:2:{s:6:"events";a:13:{i:0;a:6:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:7:"address";s:8:"the-void";s:6:"effect";s:4:"-446";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:0;}i:1;a:6:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:7:"address";s:39:"script-efcb3e8b994fe44d9b6dd0b55ab213a0";s:6:"effect";s:1:"0";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:1;}i:2;a:6:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:7:"address";s:34:"QLFdUboUPJnUzvsXKu83hUtrQ1DuxyggRg";s:6:"effect";s:3:"446";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:2;}i:3;a:6:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:7:"address";s:39:"script-287938b14253c57813474cb5eaf51d63";s:6:"effect";s:1:"0";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:3;}i:4;a:6:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:7:"address";s:42:"ex1qq2wh460mj56u5dunv8g9e4demrfa3sh723hums";s:6:"effect";s:2:"-?";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:4;}i:5;a:6:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:7:"address";s:42:"ex1qn84sc3540g7v8qr4j0tdsfa6qlshzsn47rz3yh";s:6:"effect";s:2:"-?";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:5;}i:6;a:6:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:7:"address";s:42:"ex1qwmyrwfm2fkcf82qmayhg22nh455ecyk4pqdp69";s:6:"effect";s:2:"-?";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:6;}i:7;a:6:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:7:"address";s:62:"ex1qemcjtseyldmga7axcv4sfq4dz3vap96snpe70huyalv84hxmn8wsty4yuv";s:6:"effect";s:2:"+?";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:7;}i:8;a:6:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:7:"address";s:42:"ex1qzhftnsrlr9x3vn9du9lgtqqllux2elpe2mva6w";s:6:"effect";s:2:"+?";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:8;}i:9;a:6:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"294";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:9;}i:10;a:6:{s:11:"transaction";s:64:"57b56f5b9ec72c95cf3431e1fe9e1ec528ebbbc4b59819fd701484fca5d43b88";s:7:"address";s:62:"ex1qemcjtseyldmga7axcv4sfq4dz3vap96snpe70huyalv84hxmn8wsty4yuv";s:6:"effect";s:2:"-?";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:10;}i:11;a:6:{s:11:"transaction";s:64:"57b56f5b9ec72c95cf3431e1fe9e1ec528ebbbc4b59819fd701484fca5d43b88";s:7:"address";s:34:"GteSSbj2k7EmNCXqnNnagGsTPVQ6S93N6n";s:6:"effect";s:2:"+?";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:11;}i:12;a:6:{s:11:"transaction";s:64:"57b56f5b9ec72c95cf3431e1fe9e1ec528ebbbc4b59819fd701484fca5d43b88";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"152";s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:12;}}s:10:"currencies";N;}'], - // Block with pegin - ['block' => 2766423, 'result' => 'a:2:{s:6:"events";a:10:{i:0;a:6:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"-86";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:0;}i:1;a:6:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:7:"address";s:39:"script-14b005d6cde92956f8acef08cd554ebd";s:6:"effect";s:1:"0";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:1;}i:2;a:6:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:7:"address";s:34:"QLFdUboUPJnUzvsXKu83hUtrQ1DuxyggRg";s:6:"effect";s:2:"86";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:2;}i:3;a:6:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:7:"address";s:39:"script-08be25e98319c0bfe137f3102fbc496c";s:6:"effect";s:1:"0";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:3;}i:4;a:6:{s:11:"transaction";s:64:"9d9209113c3ded3a1a9a28be5b1227206d94b49df8f3adbbb343002d2d90fe00";s:7:"address";s:7:"bitcoin";s:6:"effect";s:8:"-2497468";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:4;}i:5;a:6:{s:11:"transaction";s:64:"9d9209113c3ded3a1a9a28be5b1227206d94b49df8f3adbbb343002d2d90fe00";s:7:"address";s:42:"ex1q4q240cjajpc2jy7kcs09zqsqh3xalfzeectgay";s:6:"effect";s:7:"2497468";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:5;}i:6;a:6:{s:11:"transaction";s:64:"9d9209113c3ded3a1a9a28be5b1227206d94b49df8f3adbbb343002d2d90fe00";s:7:"address";s:8:"the-void";s:6:"effect";s:2:"43";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:6;}i:7;a:6:{s:11:"transaction";s:64:"cf2e9f28f41e6a5ebdaee32c17123b36616283728d850842206b4204291717a5";s:7:"address";s:7:"bitcoin";s:6:"effect";s:8:"-1548364";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:7;}i:8;a:6:{s:11:"transaction";s:64:"cf2e9f28f41e6a5ebdaee32c17123b36616283728d850842206b4204291717a5";s:7:"address";s:42:"ex1qvtp03vtzeru6lff556xx7xssvm3a3mlzjtxdme";s:6:"effect";s:7:"1548364";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:8;}i:9;a:6:{s:11:"transaction";s:64:"cf2e9f28f41e6a5ebdaee32c17123b36616283728d850842206b4204291717a5";s:7:"address";s:8:"the-void";s:6:"effect";s:2:"43";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:9;}}s:10:"currencies";N;}'], - // Block with assets - ['block' => 2766264, 'result' => 'a:2:{s:6:"events";a:8:{i:0;a:6:{s:11:"transaction";s:64:"8285e7867e524659c5cb2850e2dbc8d5d658cef43a87582e43588d3dee9b8b5b";s:7:"address";s:8:"the-void";s:6:"effect";s:4:"-319";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:0;}i:1;a:6:{s:11:"transaction";s:64:"8285e7867e524659c5cb2850e2dbc8d5d658cef43a87582e43588d3dee9b8b5b";s:7:"address";s:39:"script-81f8057b579b326fedf8d76b33d87165";s:6:"effect";s:1:"0";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:1;}i:2;a:6:{s:11:"transaction";s:64:"8285e7867e524659c5cb2850e2dbc8d5d658cef43a87582e43588d3dee9b8b5b";s:7:"address";s:34:"QLFdUboUPJnUzvsXKu83hUtrQ1DuxyggRg";s:6:"effect";s:3:"319";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:2;}i:3;a:6:{s:11:"transaction";s:64:"8285e7867e524659c5cb2850e2dbc8d5d658cef43a87582e43588d3dee9b8b5b";s:7:"address";s:39:"script-616f900e387746e1e4b116ef73f6ccb3";s:6:"effect";s:1:"0";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:3;}i:4;a:6:{s:11:"transaction";s:64:"1fc472aaff27c643608be24f6b86f8f5230068db98f7e2ddd7c0a4fc7d1f6c86";s:7:"address";s:62:"ex1qlg7hpqluy7xccvgscw7qww0cdkr8lcccsjk0lc7ay6e3spze3ruqapqwlw";s:6:"effect";s:2:"-?";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:4;}i:5;a:6:{s:11:"transaction";s:64:"1fc472aaff27c643608be24f6b86f8f5230068db98f7e2ddd7c0a4fc7d1f6c86";s:7:"address";s:62:"ex1qvgn6f95j4kf84quk0w0ad0mayruv2guuph5rvl8jjq2u4spqu9pseyzl2w";s:6:"effect";s:2:"-?";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:5;}i:6;a:6:{s:11:"transaction";s:64:"1fc472aaff27c643608be24f6b86f8f5230068db98f7e2ddd7c0a4fc7d1f6c86";s:7:"address";s:62:"ex1qysz258hssf960jhljqmyaea9257qn3w7mc06272kf5y8gdx06d2qvm74k3";s:6:"effect";s:2:"+?";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:6;}i:7;a:6:{s:11:"transaction";s:64:"1fc472aaff27c643608be24f6b86f8f5230068db98f7e2ddd7c0a4fc7d1f6c86";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"319";s:5:"block";i:2766264;s:4:"time";s:19:"2024-03-13 03:50:08";s:8:"sort_key";i:7;}}s:10:"currencies";N;}'], + // With currency + ['block' => 2774298, 'result' => 'a:2:{s:6:"events";a:8:{i:0;a:9:{s:11:"transaction";s:64:"f318eda796f0dce947fb18a21fc4cfeeaee7dedc83989e3721aa09c82760b32f";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"-60";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:0;}i:1;a:9:{s:11:"transaction";s:64:"f318eda796f0dce947fb18a21fc4cfeeaee7dedc83989e3721aa09c82760b32f";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-58f7fda4425dd61e07568702c58b3fc2";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:1;}i:2;a:9:{s:11:"transaction";s:64:"f318eda796f0dce947fb18a21fc4cfeeaee7dedc83989e3721aa09c82760b32f";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:34:"QLFdUboUPJnUzvsXKu83hUtrQ1DuxyggRg";s:6:"effect";s:2:"60";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:2;}i:3;a:9:{s:11:"transaction";s:64:"f318eda796f0dce947fb18a21fc4cfeeaee7dedc83989e3721aa09c82760b32f";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-95baa1886566d84b5271a295d3a773b3";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:3;}i:4;a:9:{s:11:"transaction";s:64:"97d3a20cb85209167de9ff354be7a6b7f10506db35a7ca5dfeae81cdfce73433";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1qpwdf7qxr5tg0amtz8xwfha9wclmhkahyypc9gr";s:6:"effect";s:8:"-1134077";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:4;}i:5;a:9:{s:11:"transaction";s:64:"97d3a20cb85209167de9ff354be7a6b7f10506db35a7ca5dfeae81cdfce73433";s:8:"currency";s:64:"71e30c59c03e78d064757befa459ae7a0e9c4b8a5ae16cc90b3d70fc73b40ce4";s:7:"address";s:42:"ex1qh59jvreqevgl2jwrx325zcp5lmdksaettgr62h";s:6:"effect";s:9:"101899500";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:5;}i:6;a:9:{s:11:"transaction";s:64:"97d3a20cb85209167de9ff354be7a6b7f10506db35a7ca5dfeae81cdfce73433";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1qx7tzr5ztcex6f229z4pat96mpdvwadwf7r3stx";s:6:"effect";s:7:"1134017";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:6;}i:7;a:9:{s:11:"transaction";s:64:"97d3a20cb85209167de9ff354be7a6b7f10506db35a7ca5dfeae81cdfce73433";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:2:"60";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:7;}}s:10:"currencies";a:2:{i:0;a:4:{s:2:"id";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:4:"name";s:14:"Liquid Bitcoin";s:6:"symbol";s:5:"L-BTC";s:8:"decimals";i:8;}i:1;a:4:{s:2:"id";s:64:"71e30c59c03e78d064757befa459ae7a0e9c4b8a5ae16cc90b3d70fc73b40ce4";s:4:"name";s:26:"Taxkredit project 68cbc66a";s:6:"symbol";s:5:"tWaZe";s:8:"decimals";s:1:"2";}}}'], + // With L-BTC only + ['block' => 2766919, 'result' => 'a:2:{s:6:"events";a:13:{i:0;a:9:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:4:"-446";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:0;}i:1;a:9:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-efcb3e8b994fe44d9b6dd0b55ab213a0";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:1;}i:2;a:9:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:34:"QLFdUboUPJnUzvsXKu83hUtrQ1DuxyggRg";s:6:"effect";s:3:"446";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:2;}i:3;a:9:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-287938b14253c57813474cb5eaf51d63";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:3;}i:4;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1qq2wh460mj56u5dunv8g9e4demrfa3sh723hums";s:6:"effect";s:2:"-?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:4;}i:5;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1qn84sc3540g7v8qr4j0tdsfa6qlshzsn47rz3yh";s:6:"effect";s:2:"-?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:5;}i:6;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1qwmyrwfm2fkcf82qmayhg22nh455ecyk4pqdp69";s:6:"effect";s:2:"-?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:6;}i:7;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";N;s:7:"address";s:62:"ex1qemcjtseyldmga7axcv4sfq4dz3vap96snpe70huyalv84hxmn8wsty4yuv";s:6:"effect";s:2:"+?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:7;}i:8;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";N;s:7:"address";s:42:"ex1qzhftnsrlr9x3vn9du9lgtqqllux2elpe2mva6w";s:6:"effect";s:2:"+?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:8;}i:9;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"294";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:9;}i:10;a:9:{s:11:"transaction";s:64:"57b56f5b9ec72c95cf3431e1fe9e1ec528ebbbc4b59819fd701484fca5d43b88";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:62:"ex1qemcjtseyldmga7axcv4sfq4dz3vap96snpe70huyalv84hxmn8wsty4yuv";s:6:"effect";s:2:"-?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:10;}i:11;a:9:{s:11:"transaction";s:64:"57b56f5b9ec72c95cf3431e1fe9e1ec528ebbbc4b59819fd701484fca5d43b88";s:8:"currency";N;s:7:"address";s:34:"GteSSbj2k7EmNCXqnNnagGsTPVQ6S93N6n";s:6:"effect";s:2:"+?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:11;}i:12;a:9:{s:11:"transaction";s:64:"57b56f5b9ec72c95cf3431e1fe9e1ec528ebbbc4b59819fd701484fca5d43b88";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"152";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:12;}}s:10:"currencies";a:1:{i:0;a:4:{s:2:"id";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:4:"name";s:14:"Liquid Bitcoin";s:6:"symbol";s:5:"L-BTC";s:8:"decimals";i:8;}}}'], + // With pegin + ['block' => 2766423, 'result' => 'a:2:{s:6:"events";a:10:{i:0;a:9:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"-86";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:0;}i:1;a:9:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-14b005d6cde92956f8acef08cd554ebd";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:1;}i:2;a:9:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:34:"QLFdUboUPJnUzvsXKu83hUtrQ1DuxyggRg";s:6:"effect";s:2:"86";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:2;}i:3;a:9:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-08be25e98319c0bfe137f3102fbc496c";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:3;}i:4;a:9:{s:11:"transaction";s:64:"9d9209113c3ded3a1a9a28be5b1227206d94b49df8f3adbbb343002d2d90fe00";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:7:"bitcoin";s:6:"effect";s:8:"-2497468";s:5:"extra";s:2:"pi";s:13:"extra_indexed";s:64:"e1efb6717354c548c981ed266922e045a85a0fe489df84f301364532f3306c49";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:4;}i:5;a:9:{s:11:"transaction";s:64:"9d9209113c3ded3a1a9a28be5b1227206d94b49df8f3adbbb343002d2d90fe00";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1q4q240cjajpc2jy7kcs09zqsqh3xalfzeectgay";s:6:"effect";s:7:"2497468";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:5;}i:6;a:9:{s:11:"transaction";s:64:"9d9209113c3ded3a1a9a28be5b1227206d94b49df8f3adbbb343002d2d90fe00";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:2:"43";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:6;}i:7;a:9:{s:11:"transaction";s:64:"cf2e9f28f41e6a5ebdaee32c17123b36616283728d850842206b4204291717a5";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:7:"bitcoin";s:6:"effect";s:8:"-1548364";s:5:"extra";s:2:"pi";s:13:"extra_indexed";s:64:"82e2d8f6bbe7d252c18e96f931033075d5eb0b5c79e0ed346eae6c024f40973d";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:7;}i:8;a:9:{s:11:"transaction";s:64:"cf2e9f28f41e6a5ebdaee32c17123b36616283728d850842206b4204291717a5";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1qvtp03vtzeru6lff556xx7xssvm3a3mlzjtxdme";s:6:"effect";s:7:"1548364";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:8;}i:9;a:9:{s:11:"transaction";s:64:"cf2e9f28f41e6a5ebdaee32c17123b36616283728d850842206b4204291717a5";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:2:"43";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:9;}}s:10:"currencies";a:1:{i:0;a:4:{s:2:"id";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:4:"name";s:14:"Liquid Bitcoin";s:6:"symbol";s:5:"L-BTC";s:8:"decimals";i:8;}}}'], ]; } } From 904e9e1acc35a041c37aeb46bc458c80daafe6f0 Mon Sep 17 00:00:00 2001 From: Nikita Zhavoronkov Date: Thu, 28 Mar 2024 13:17:51 -0400 Subject: [PATCH 3/7] Multiple fixed --- Modules/Common/UTXOLiquidModule.php | 39 +++++++++++++++++------------ Modules/LiquidMainModule.php | 17 +++++++------ 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/Modules/Common/UTXOLiquidModule.php b/Modules/Common/UTXOLiquidModule.php index 3aad6d44..58145705 100644 --- a/Modules/Common/UTXOLiquidModule.php +++ b/Modules/Common/UTXOLiquidModule.php @@ -1,10 +1,10 @@ native_asset)) throw new DeveloperError("Native asset is not set"); + if (is_null($this->native_asset_meta)) throw new DeveloperError("Native asset meta is not set"); + $this->asset_registry = envm( $this->module, 'ASSETS_REGISTRY', @@ -150,6 +146,7 @@ final public function pre_process_block($block_id) $address = 'script-' . substr(hash('sha256', $output['scriptPubKey']['hex']), 0, 32); $extra = $extra_indexed = null; + if (isset($output['scriptPubKey']['pegout_address'])) { $extra = 'po'; @@ -163,12 +160,15 @@ final public function pre_process_block($block_id) if ($type === 'fee') // Skip additional event for fee out { if (is_null($asset)) - throw new ModuleError("Null asset for fee output type"); + throw new ModuleError('Null asset for fee output type'); + $fees[($transaction['txid'])]['amount'] = satoshi($output['value'], $this); $fees[($transaction['txid'])]['currency'] = $asset; } else { + $address = ($extra === 'po') ? 'the-bridge' : $address; + $events[] = [ 'transaction' => $transaction['txid'], 'currency' => $asset, @@ -198,6 +198,7 @@ final public function pre_process_block($block_id) foreach ($block['tx'] as $transaction) { $this_n = 1; + foreach ($transaction['vin'] as $input) { if (isset($input['coinbase'])) @@ -217,14 +218,15 @@ final public function pre_process_block($block_id) else { // In LiquidBitcoin we cant get the previous tx vouts for pegin txs - $is_pegin = $input['is_pegin'] ?? false; - if ($is_pegin == true) + if ($input['is_pegin']) { // Calculate exact amount from bitcoin $value = '0'; + foreach ($transaction['vout'] as $out) { $type = $out['scriptPubKey']['type'] ?? ''; + if ($type !== 'fee') $value = bcadd($value, satoshi($out['value'], $this)); } @@ -233,12 +235,13 @@ final public function pre_process_block($block_id) $events[] = [ 'transaction' => $transaction['txid'], 'currency' => $this->native_asset, - 'address' => 'bitcoin', + 'address' => 'the-bridge', 'effect' => '-' . $value, 'sort_in_transaction' => -1, 'extra' => 'pi', 'extra_indexed' => $input['txid'], ]; + $currencies_to_process[] = $this->native_asset; continue; } @@ -254,6 +257,7 @@ final public function pre_process_block($block_id) 'previous_transaction' => $input['txid'], 'previous_n' => $input['vout'], 'this_n' => -$this_n, + 'asset' => $input['asset'] ?? null, ]; $this_n++; @@ -305,8 +309,9 @@ final public function pre_process_block($block_id) else $address = 'script-' . substr(hash('sha256', $previous_output[($input['previous_n'])]['scriptPubKey']['hex']), 0, 32); - $asset = $previous_output[($input['previous_n'])]['asset'] ?? $this->native_asset; + $asset = $previous_output[($input['previous_n'])]['asset'] ?? null; $effect = isset($previous_output[($input['previous_n'])]['value']) ? satoshi($previous_output[($input['previous_n'])]['value'], $this) : '?'; + $events[] = [ 'transaction' => $input['this_transaction'], 'currency' => $asset, @@ -317,7 +322,8 @@ final public function pre_process_block($block_id) 'extra_indexed' => null, ]; - $currencies_to_process[] = $asset; + if (!is_null($asset)) + $currencies_to_process[] = $asset; } foreach ($fees as $txid => $fee_transfer) @@ -395,6 +401,7 @@ final public function pre_process_block($block_id) $sort_key = 0; $latest_tx_hash = ''; // This is for mempool + foreach ($events as &$event) { if ($this->block_id === MEMPOOL && $event['transaction'] !== $latest_tx_hash) diff --git a/Modules/LiquidMainModule.php b/Modules/LiquidMainModule.php index c2334a94..76af9b96 100644 --- a/Modules/LiquidMainModule.php +++ b/Modules/LiquidMainModule.php @@ -1,12 +1,11 @@ tests = [ - // With currency + // With a non-native asset ['block' => 2774298, 'result' => 'a:2:{s:6:"events";a:8:{i:0;a:9:{s:11:"transaction";s:64:"f318eda796f0dce947fb18a21fc4cfeeaee7dedc83989e3721aa09c82760b32f";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"-60";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:0;}i:1;a:9:{s:11:"transaction";s:64:"f318eda796f0dce947fb18a21fc4cfeeaee7dedc83989e3721aa09c82760b32f";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-58f7fda4425dd61e07568702c58b3fc2";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:1;}i:2;a:9:{s:11:"transaction";s:64:"f318eda796f0dce947fb18a21fc4cfeeaee7dedc83989e3721aa09c82760b32f";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:34:"QLFdUboUPJnUzvsXKu83hUtrQ1DuxyggRg";s:6:"effect";s:2:"60";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:2;}i:3;a:9:{s:11:"transaction";s:64:"f318eda796f0dce947fb18a21fc4cfeeaee7dedc83989e3721aa09c82760b32f";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-95baa1886566d84b5271a295d3a773b3";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:3;}i:4;a:9:{s:11:"transaction";s:64:"97d3a20cb85209167de9ff354be7a6b7f10506db35a7ca5dfeae81cdfce73433";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1qpwdf7qxr5tg0amtz8xwfha9wclmhkahyypc9gr";s:6:"effect";s:8:"-1134077";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:4;}i:5;a:9:{s:11:"transaction";s:64:"97d3a20cb85209167de9ff354be7a6b7f10506db35a7ca5dfeae81cdfce73433";s:8:"currency";s:64:"71e30c59c03e78d064757befa459ae7a0e9c4b8a5ae16cc90b3d70fc73b40ce4";s:7:"address";s:42:"ex1qh59jvreqevgl2jwrx325zcp5lmdksaettgr62h";s:6:"effect";s:9:"101899500";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:5;}i:6;a:9:{s:11:"transaction";s:64:"97d3a20cb85209167de9ff354be7a6b7f10506db35a7ca5dfeae81cdfce73433";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1qx7tzr5ztcex6f229z4pat96mpdvwadwf7r3stx";s:6:"effect";s:7:"1134017";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:6;}i:7;a:9:{s:11:"transaction";s:64:"97d3a20cb85209167de9ff354be7a6b7f10506db35a7ca5dfeae81cdfce73433";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:2:"60";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2774298;s:4:"time";s:19:"2024-03-18 20:38:08";s:8:"sort_key";i:7;}}s:10:"currencies";a:2:{i:0;a:4:{s:2:"id";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:4:"name";s:14:"Liquid Bitcoin";s:6:"symbol";s:5:"L-BTC";s:8:"decimals";i:8;}i:1;a:4:{s:2:"id";s:64:"71e30c59c03e78d064757befa459ae7a0e9c4b8a5ae16cc90b3d70fc73b40ce4";s:4:"name";s:26:"Taxkredit project 68cbc66a";s:6:"symbol";s:5:"tWaZe";s:8:"decimals";s:1:"2";}}}'], // With L-BTC only - ['block' => 2766919, 'result' => 'a:2:{s:6:"events";a:13:{i:0;a:9:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:4:"-446";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:0;}i:1;a:9:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-efcb3e8b994fe44d9b6dd0b55ab213a0";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:1;}i:2;a:9:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:34:"QLFdUboUPJnUzvsXKu83hUtrQ1DuxyggRg";s:6:"effect";s:3:"446";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:2;}i:3;a:9:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-287938b14253c57813474cb5eaf51d63";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:3;}i:4;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1qq2wh460mj56u5dunv8g9e4demrfa3sh723hums";s:6:"effect";s:2:"-?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:4;}i:5;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1qn84sc3540g7v8qr4j0tdsfa6qlshzsn47rz3yh";s:6:"effect";s:2:"-?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:5;}i:6;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1qwmyrwfm2fkcf82qmayhg22nh455ecyk4pqdp69";s:6:"effect";s:2:"-?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:6;}i:7;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";N;s:7:"address";s:62:"ex1qemcjtseyldmga7axcv4sfq4dz3vap96snpe70huyalv84hxmn8wsty4yuv";s:6:"effect";s:2:"+?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:7;}i:8;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";N;s:7:"address";s:42:"ex1qzhftnsrlr9x3vn9du9lgtqqllux2elpe2mva6w";s:6:"effect";s:2:"+?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:8;}i:9;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"294";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:9;}i:10;a:9:{s:11:"transaction";s:64:"57b56f5b9ec72c95cf3431e1fe9e1ec528ebbbc4b59819fd701484fca5d43b88";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:62:"ex1qemcjtseyldmga7axcv4sfq4dz3vap96snpe70huyalv84hxmn8wsty4yuv";s:6:"effect";s:2:"-?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:10;}i:11;a:9:{s:11:"transaction";s:64:"57b56f5b9ec72c95cf3431e1fe9e1ec528ebbbc4b59819fd701484fca5d43b88";s:8:"currency";N;s:7:"address";s:34:"GteSSbj2k7EmNCXqnNnagGsTPVQ6S93N6n";s:6:"effect";s:2:"+?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:11;}i:12;a:9:{s:11:"transaction";s:64:"57b56f5b9ec72c95cf3431e1fe9e1ec528ebbbc4b59819fd701484fca5d43b88";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"152";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:12;}}s:10:"currencies";a:1:{i:0;a:4:{s:2:"id";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:4:"name";s:14:"Liquid Bitcoin";s:6:"symbol";s:5:"L-BTC";s:8:"decimals";i:8;}}}'], - // With pegin - ['block' => 2766423, 'result' => 'a:2:{s:6:"events";a:10:{i:0;a:9:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"-86";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:0;}i:1;a:9:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-14b005d6cde92956f8acef08cd554ebd";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:1;}i:2;a:9:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:34:"QLFdUboUPJnUzvsXKu83hUtrQ1DuxyggRg";s:6:"effect";s:2:"86";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:2;}i:3;a:9:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-08be25e98319c0bfe137f3102fbc496c";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:3;}i:4;a:9:{s:11:"transaction";s:64:"9d9209113c3ded3a1a9a28be5b1227206d94b49df8f3adbbb343002d2d90fe00";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:7:"bitcoin";s:6:"effect";s:8:"-2497468";s:5:"extra";s:2:"pi";s:13:"extra_indexed";s:64:"e1efb6717354c548c981ed266922e045a85a0fe489df84f301364532f3306c49";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:4;}i:5;a:9:{s:11:"transaction";s:64:"9d9209113c3ded3a1a9a28be5b1227206d94b49df8f3adbbb343002d2d90fe00";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1q4q240cjajpc2jy7kcs09zqsqh3xalfzeectgay";s:6:"effect";s:7:"2497468";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:5;}i:6;a:9:{s:11:"transaction";s:64:"9d9209113c3ded3a1a9a28be5b1227206d94b49df8f3adbbb343002d2d90fe00";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:2:"43";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:6;}i:7;a:9:{s:11:"transaction";s:64:"cf2e9f28f41e6a5ebdaee32c17123b36616283728d850842206b4204291717a5";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:7:"bitcoin";s:6:"effect";s:8:"-1548364";s:5:"extra";s:2:"pi";s:13:"extra_indexed";s:64:"82e2d8f6bbe7d252c18e96f931033075d5eb0b5c79e0ed346eae6c024f40973d";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:7;}i:8;a:9:{s:11:"transaction";s:64:"cf2e9f28f41e6a5ebdaee32c17123b36616283728d850842206b4204291717a5";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1qvtp03vtzeru6lff556xx7xssvm3a3mlzjtxdme";s:6:"effect";s:7:"1548364";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:8;}i:9;a:9:{s:11:"transaction";s:64:"cf2e9f28f41e6a5ebdaee32c17123b36616283728d850842206b4204291717a5";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:2:"43";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:9;}}s:10:"currencies";a:1:{i:0;a:4:{s:2:"id";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:4:"name";s:14:"Liquid Bitcoin";s:6:"symbol";s:5:"L-BTC";s:8:"decimals";i:8;}}}'], + ['block' => 2766919, 'result' => 'a:2:{s:6:"events";a:13:{i:0;a:9:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:4:"-446";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:0;}i:1;a:9:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-efcb3e8b994fe44d9b6dd0b55ab213a0";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:1;}i:2;a:9:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:34:"QLFdUboUPJnUzvsXKu83hUtrQ1DuxyggRg";s:6:"effect";s:3:"446";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:2;}i:3;a:9:{s:11:"transaction";s:64:"4f6762c0a0c639b452fe5de2272cfa59348ca36580b83cc942838a580b55cbdc";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-287938b14253c57813474cb5eaf51d63";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:3;}i:4;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";N;s:7:"address";s:42:"ex1qq2wh460mj56u5dunv8g9e4demrfa3sh723hums";s:6:"effect";s:2:"-?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:4;}i:5;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";N;s:7:"address";s:42:"ex1qn84sc3540g7v8qr4j0tdsfa6qlshzsn47rz3yh";s:6:"effect";s:2:"-?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:5;}i:6;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";N;s:7:"address";s:42:"ex1qwmyrwfm2fkcf82qmayhg22nh455ecyk4pqdp69";s:6:"effect";s:2:"-?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:6;}i:7;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";N;s:7:"address";s:62:"ex1qemcjtseyldmga7axcv4sfq4dz3vap96snpe70huyalv84hxmn8wsty4yuv";s:6:"effect";s:2:"+?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:7;}i:8;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";N;s:7:"address";s:42:"ex1qzhftnsrlr9x3vn9du9lgtqqllux2elpe2mva6w";s:6:"effect";s:2:"+?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:8;}i:9;a:9:{s:11:"transaction";s:64:"7a731e79ae494ce4540322ea17a700eb050e1026009d49effea59b6b4985975c";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"294";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:9;}i:10;a:9:{s:11:"transaction";s:64:"57b56f5b9ec72c95cf3431e1fe9e1ec528ebbbc4b59819fd701484fca5d43b88";s:8:"currency";N;s:7:"address";s:62:"ex1qemcjtseyldmga7axcv4sfq4dz3vap96snpe70huyalv84hxmn8wsty4yuv";s:6:"effect";s:2:"-?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:10;}i:11;a:9:{s:11:"transaction";s:64:"57b56f5b9ec72c95cf3431e1fe9e1ec528ebbbc4b59819fd701484fca5d43b88";s:8:"currency";N;s:7:"address";s:34:"GteSSbj2k7EmNCXqnNnagGsTPVQ6S93N6n";s:6:"effect";s:2:"+?";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:11;}i:12;a:9:{s:11:"transaction";s:64:"57b56f5b9ec72c95cf3431e1fe9e1ec528ebbbc4b59819fd701484fca5d43b88";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"152";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766919;s:4:"time";s:19:"2024-03-13 14:45:08";s:8:"sort_key";i:12;}}s:10:"currencies";a:1:{i:0;a:4:{s:2:"id";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:4:"name";s:14:"Liquid Bitcoin";s:6:"symbol";s:5:"L-BTC";s:8:"decimals";i:8;}}}'], + // With a pegin + ['block' => 2766423, 'result' => 'a:2:{s:6:"events";a:10:{i:0;a:9:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"-86";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:0;}i:1;a:9:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-14b005d6cde92956f8acef08cd554ebd";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:1;}i:2;a:9:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:34:"QLFdUboUPJnUzvsXKu83hUtrQ1DuxyggRg";s:6:"effect";s:2:"86";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:2;}i:3;a:9:{s:11:"transaction";s:64:"eac7bddebcc5c76b9bc548115c7e3144d6c6654abb4ab76227374816436a15e6";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-08be25e98319c0bfe137f3102fbc496c";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:3;}i:4;a:9:{s:11:"transaction";s:64:"9d9209113c3ded3a1a9a28be5b1227206d94b49df8f3adbbb343002d2d90fe00";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:10:"the-bridge";s:6:"effect";s:8:"-2497468";s:5:"extra";s:2:"pi";s:13:"extra_indexed";s:64:"e1efb6717354c548c981ed266922e045a85a0fe489df84f301364532f3306c49";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:4;}i:5;a:9:{s:11:"transaction";s:64:"9d9209113c3ded3a1a9a28be5b1227206d94b49df8f3adbbb343002d2d90fe00";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1q4q240cjajpc2jy7kcs09zqsqh3xalfzeectgay";s:6:"effect";s:7:"2497468";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:5;}i:6;a:9:{s:11:"transaction";s:64:"9d9209113c3ded3a1a9a28be5b1227206d94b49df8f3adbbb343002d2d90fe00";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:2:"43";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:6;}i:7;a:9:{s:11:"transaction";s:64:"cf2e9f28f41e6a5ebdaee32c17123b36616283728d850842206b4204291717a5";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:10:"the-bridge";s:6:"effect";s:8:"-1548364";s:5:"extra";s:2:"pi";s:13:"extra_indexed";s:64:"82e2d8f6bbe7d252c18e96f931033075d5eb0b5c79e0ed346eae6c024f40973d";s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:7;}i:8;a:9:{s:11:"transaction";s:64:"cf2e9f28f41e6a5ebdaee32c17123b36616283728d850842206b4204291717a5";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1qvtp03vtzeru6lff556xx7xssvm3a3mlzjtxdme";s:6:"effect";s:7:"1548364";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:8;}i:9;a:9:{s:11:"transaction";s:64:"cf2e9f28f41e6a5ebdaee32c17123b36616283728d850842206b4204291717a5";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:2:"43";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2766423;s:4:"time";s:19:"2024-03-13 06:29:08";s:8:"sort_key";i:9;}}s:10:"currencies";a:1:{i:0;a:4:{s:2:"id";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:4:"name";s:14:"Liquid Bitcoin";s:6:"symbol";s:5:"L-BTC";s:8:"decimals";i:8;}}}'], + // With a pegout + ['block' => 2787954, 'result' => 'a:2:{s:6:"events";a:9:{i:0;a:9:{s:11:"transaction";s:64:"e42d0f3164d14c7cdc02cde92277509a68610d0bc1cd03c8187e6741da74b13d";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:4:"-210";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2787954;s:4:"time";s:19:"2024-03-28 09:01:08";s:8:"sort_key";i:0;}i:1;a:9:{s:11:"transaction";s:64:"e42d0f3164d14c7cdc02cde92277509a68610d0bc1cd03c8187e6741da74b13d";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-f06c5e8c739fe0c69173165dddd34ab3";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2787954;s:4:"time";s:19:"2024-03-28 09:01:08";s:8:"sort_key";i:1;}i:2;a:9:{s:11:"transaction";s:64:"e42d0f3164d14c7cdc02cde92277509a68610d0bc1cd03c8187e6741da74b13d";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:34:"QLFdUboUPJnUzvsXKu83hUtrQ1DuxyggRg";s:6:"effect";s:3:"210";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2787954;s:4:"time";s:19:"2024-03-28 09:01:08";s:8:"sort_key";i:2;}i:3;a:9:{s:11:"transaction";s:64:"e42d0f3164d14c7cdc02cde92277509a68610d0bc1cd03c8187e6741da74b13d";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:39:"script-15bc9143ad760bce10eb170125090af2";s:6:"effect";s:1:"0";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2787954;s:4:"time";s:19:"2024-03-28 09:01:08";s:8:"sort_key";i:3;}i:4;a:9:{s:11:"transaction";s:64:"0499e19709e4fe9b4c03fc6ae0b167d193fdd99f79c49dc757e4546d95823aef";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1q35lcg2rpl0jka4vdqs7dw34lcnqrp9sj9pl0ct";s:6:"effect";s:6:"-99955";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2787954;s:4:"time";s:19:"2024-03-28 09:01:08";s:8:"sort_key";i:4;}i:5;a:9:{s:11:"transaction";s:64:"0499e19709e4fe9b4c03fc6ae0b167d193fdd99f79c49dc757e4546d95823aef";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1qmuta6zj9hkzs4uzjghyhzuh5xre69cggculku6";s:6:"effect";s:8:"-1083380";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2787954;s:4:"time";s:19:"2024-03-28 09:01:08";s:8:"sort_key";i:5;}i:6;a:9:{s:11:"transaction";s:64:"0499e19709e4fe9b4c03fc6ae0b167d193fdd99f79c49dc757e4546d95823aef";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:42:"ex1qc7hnm2t8p3qhmtcdalak47hdyxafevqr2xlkd8";s:6:"effect";s:7:"1083125";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2787954;s:4:"time";s:19:"2024-03-28 09:01:08";s:8:"sort_key";i:6;}i:7;a:9:{s:11:"transaction";s:64:"0499e19709e4fe9b4c03fc6ae0b167d193fdd99f79c49dc757e4546d95823aef";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:10:"the-bridge";s:6:"effect";s:6:"100000";s:5:"extra";s:2:"po";s:13:"extra_indexed";s:34:"1PUNRRzJC667NvE2n5MqBi9uzhfQhh8KDV";s:5:"block";i:2787954;s:4:"time";s:19:"2024-03-28 09:01:08";s:8:"sort_key";i:7;}i:8;a:9:{s:11:"transaction";s:64:"0499e19709e4fe9b4c03fc6ae0b167d193fdd99f79c49dc757e4546d95823aef";s:8:"currency";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:7:"address";s:8:"the-void";s:6:"effect";s:3:"210";s:5:"extra";N;s:13:"extra_indexed";N;s:5:"block";i:2787954;s:4:"time";s:19:"2024-03-28 09:01:08";s:8:"sort_key";i:8;}}s:10:"currencies";a:1:{i:0;a:4:{s:2:"id";s:64:"6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d";s:4:"name";s:14:"Liquid Bitcoin";s:6:"symbol";s:5:"L-BTC";s:8:"decimals";i:8;}}}'], ]; } } From 34627b72be6abcae79980ad2ee7fa07c7c488c1c Mon Sep 17 00:00:00 2001 From: Nikita Zhavoronkov Date: Thu, 28 Mar 2024 13:27:52 -0400 Subject: [PATCH 4/7] Rename the blockchain into `liquid-network` --- Modules/LiquidMainModule.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/LiquidMainModule.php b/Modules/LiquidMainModule.php index 76af9b96..ca3f70e0 100644 --- a/Modules/LiquidMainModule.php +++ b/Modules/LiquidMainModule.php @@ -12,8 +12,8 @@ final class LiquidMainModule extends UTXOLiquidModule implements Module function initialize() { // CoreModule - $this->blockchain = 'liquid'; - $this->module = 'liquid-main'; + $this->blockchain = 'liquid-network'; + $this->module = 'liquid-network-main'; $this->is_main = true; $this->first_block_date = '2018-09-27'; From d69f55eddf9ab78a49ff53b954d55a34fb0f3196 Mon Sep 17 00:00:00 2001 From: Nikita Zhavoronkov Date: Thu, 28 Mar 2024 13:32:13 -0400 Subject: [PATCH 5/7] Rename the main Liquid module --- .env.example | 14 +++++++------- ...dMainModule.php => LiquidNetworkMainModule.php} | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) rename Modules/{LiquidMainModule.php => LiquidNetworkMainModule.php} (99%) diff --git a/.env.example b/.env.example index 4d62ca96..423ce7cd 100644 --- a/.env.example +++ b/.env.example @@ -879,13 +879,13 @@ MODULE_rootstock-erc-1155_REQUESTER_THREADS=12 ## Main Liquid Module ###################### -MODULES[]=liquid-main -MODULE_liquid-main_CLASS=LiquidMainModule -MODULE_liquid-main_NODES[]=http://login:password@127.0.0.1:1234/ -MODULE_liquid-main_NODES[]=http://login:password@127.0.0.1:1234/ -MODULE_liquid-main_ASSETS_REGISTRY=http://login:password@127.0.0.1:12345/ -MODULE_liquid-main_REQUESTER_TIMEOUT=60 -MODULE_liquid-main_REQUESTER_THREADS=12 +MODULES[]=liquid-network-main +MODULE_liquid-network-main_CLASS=LiquidNetworkMainModule +MODULE_liquid-network-main_NODES[]=http://login:password@127.0.0.1:1234/ +MODULE_liquid-network-main_NODES[]=http://login:password@127.0.0.1:1234/ +MODULE_liquid-network-main_ASSETS_REGISTRY=http://login:password@127.0.0.1:12345/ +MODULE_liquid-network-main_REQUESTER_TIMEOUT=60 +MODULE_liquid-network-main_REQUESTER_THREADS=12 ############################ # Titles, descriptions, etc. diff --git a/Modules/LiquidMainModule.php b/Modules/LiquidNetworkMainModule.php similarity index 99% rename from Modules/LiquidMainModule.php rename to Modules/LiquidNetworkMainModule.php index ca3f70e0..29845ed5 100644 --- a/Modules/LiquidMainModule.php +++ b/Modules/LiquidNetworkMainModule.php @@ -7,7 +7,7 @@ /* This is the Liquid Bitcoin module. * Using AssetRegistry: https://docs.liquid.net/docs/blockstream-liquid-asset-registry */ -final class LiquidMainModule extends UTXOLiquidModule implements Module +final class LiquidNetworkMainModule extends UTXOLiquidModule implements Module { function initialize() { From b625668269364df2d898c8357fdb69aef7993f4a Mon Sep 17 00:00:00 2001 From: Nikita Zhavoronkov Date: Thu, 28 Mar 2024 13:55:03 -0400 Subject: [PATCH 6/7] Small fixes --- Modules/Common/UTXOLiquidModule.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Modules/Common/UTXOLiquidModule.php b/Modules/Common/UTXOLiquidModule.php index 58145705..e1979cf3 100644 --- a/Modules/Common/UTXOLiquidModule.php +++ b/Modules/Common/UTXOLiquidModule.php @@ -24,7 +24,7 @@ abstract class UTXOLiquidModule extends CoreModule public ?array $events_table_nullable_fields = ['currency', 'extra', 'extra_indexed']; public ?array $currencies_table_fields = ['id', 'name', 'symbol', 'decimals']; - public ?array $currencies_table_nullable_fields = []; + public ?array $currencies_table_nullable_fields = ['name', 'symbol']; public ?bool $should_return_events = true; public ?bool $should_return_currencies = true; @@ -359,12 +359,12 @@ final public function pre_process_block($block_id) } catch (RequesterException $e) { - // For unknown assets returns HTML page with 404 code + // For unknown assets the registry returns an HTML page with 404 code if (str_contains($e->getMessage(), 'bad JSON')) $meta = [ - 'name' => 'unknown', - 'ticker' => 'unknown', - 'precision' => 0, + 'name' => null, + 'ticker' => null, + 'precision' => 0, ]; else throw $e; @@ -372,8 +372,8 @@ final public function pre_process_block($block_id) $currencies[] = [ 'id' => $currency, - 'name' => $meta['name'] ?? '', - 'symbol' => $meta['ticker'] ?? '', + 'name' => $meta['name'] ?? null, + 'symbol' => $meta['ticker'] ?? null, 'decimals' => $meta['precision'] ?? 0, ]; } From 4d329770e23317019f7aa88d8d3c59aef8a11c7a Mon Sep 17 00:00:00 2001 From: Nikita Zhavoronkov Date: Fri, 29 Mar 2024 13:23:53 -0400 Subject: [PATCH 7/7] Fix some kind of confidential transactions --- Modules/Common/UTXOLiquidModule.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Modules/Common/UTXOLiquidModule.php b/Modules/Common/UTXOLiquidModule.php index e1979cf3..a8bf338b 100644 --- a/Modules/Common/UTXOLiquidModule.php +++ b/Modules/Common/UTXOLiquidModule.php @@ -227,6 +227,9 @@ final public function pre_process_block($block_id) { $type = $out['scriptPubKey']['type'] ?? ''; + if (!isset($out['value'])) // Example: fd36f216be666d43ec861feb756b1c5f48fb54f98bfeed25e5367b05cccc96e8 + continue; + if ($type !== 'fee') $value = bcadd($value, satoshi($out['value'], $this)); }