Local sync commit
This commit is contained in:
parent
1ebcd999a6
commit
f48e9f8b46
18 changed files with 3319 additions and 194 deletions
18
.editorconfig
Normal file
18
.editorconfig
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
; This file is for unifying the coding style for different editors and IDEs.
|
||||||
|
; More information at http://editorconfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.bat]
|
||||||
|
end_of_line = crlf
|
||||||
|
|
||||||
|
[*.yml]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
42
.gitattributes
vendored
Normal file
42
.gitattributes
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
# Define the line ending behavior of the different file extensions
|
||||||
|
# Set default behaviour, in case users don't have core.autocrlf set.
|
||||||
|
* text=auto
|
||||||
|
* text eol=lf
|
||||||
|
|
||||||
|
# Explicitly declare text files we want to always be normalized and converted
|
||||||
|
# to native line endings on checkout.
|
||||||
|
*.php text
|
||||||
|
*.default text
|
||||||
|
*.ctp text
|
||||||
|
*.sql text
|
||||||
|
*.md text
|
||||||
|
*.po text
|
||||||
|
*.js text
|
||||||
|
*.css text
|
||||||
|
*.ini text
|
||||||
|
*.properties text
|
||||||
|
*.txt text
|
||||||
|
*.xml text
|
||||||
|
*.svg text
|
||||||
|
*.yml text
|
||||||
|
.htaccess text
|
||||||
|
|
||||||
|
# Declare files that will always have CRLF line endings on checkout.
|
||||||
|
*.bat eol=crlf
|
||||||
|
|
||||||
|
# Declare files that will always have LF line endings on checkout.
|
||||||
|
*.pem eol=lf
|
||||||
|
|
||||||
|
# Denote all files that are truly binary and should not be modified.
|
||||||
|
*.png binary
|
||||||
|
*.jpg binary
|
||||||
|
*.gif binary
|
||||||
|
*.ico binary
|
||||||
|
*.mo binary
|
||||||
|
*.pdf binary
|
||||||
|
*.phar binary
|
||||||
|
*.woff binary
|
||||||
|
*.woff2 binary
|
||||||
|
*.ttf binary
|
||||||
|
*.otf binary
|
||||||
|
*.eot binary
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -3,4 +3,5 @@
|
||||||
/tmp/*
|
/tmp/*
|
||||||
/logs/*
|
/logs/*
|
||||||
lbryexplorer.zip
|
lbryexplorer.zip
|
||||||
|
lbryexplorer.komodoproject
|
||||||
|
.komodotools
|
||||||
|
|
30
.travis.yml
Normal file
30
.travis.yml
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
language: php
|
||||||
|
|
||||||
|
dist: trusty
|
||||||
|
|
||||||
|
sudo: false
|
||||||
|
|
||||||
|
php:
|
||||||
|
- 5.6
|
||||||
|
- 7.0
|
||||||
|
- 7.1
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
fast_finish: true
|
||||||
|
|
||||||
|
include:
|
||||||
|
- php: 7.0
|
||||||
|
env: PHPCS=1
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- if [[ $PHPCS = 1 ]]; then composer require cakephp/cakephp-codesniffer:~2.1; fi
|
||||||
|
- if [[ $PHPCS != 1 ]]; then composer install; fi
|
||||||
|
- if [[ $PHPCS != 1 ]]; then composer require phpunit/phpunit:"^5.7|^6.0"; fi
|
||||||
|
- if [[ $PHPCS != 1 ]]; then composer run-script post-install-cmd --no-interaction; fi
|
||||||
|
|
||||||
|
script:
|
||||||
|
- if [[ $PHPCS != 1 ]]; then vendor/bin/phpunit; fi
|
||||||
|
- if [[ $PHPCS = 1 ]]; then vendor/bin/phpcs -p --extensions=php --standard=vendor/cakephp/cakephp-codesniffer/CakePHP ./src ./tests ./config ./webroot; fi
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
email: false
|
0
README.md
Normal file
0
README.md
Normal file
54
bin/cake.bat
54
bin/cake.bat
|
@ -1,27 +1,27 @@
|
||||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
::
|
::
|
||||||
:: Cake is a Windows batch script for invoking CakePHP shell commands
|
:: Cake is a Windows batch script for invoking CakePHP shell commands
|
||||||
::
|
::
|
||||||
:: CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
:: CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||||
:: Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
:: Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||||
::
|
::
|
||||||
:: Licensed under The MIT License
|
:: Licensed under The MIT License
|
||||||
:: Redistributions of files must retain the above copyright notice.
|
:: Redistributions of files must retain the above copyright notice.
|
||||||
::
|
::
|
||||||
:: @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
:: @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||||
:: @link http://cakephp.org CakePHP(tm) Project
|
:: @link http://cakephp.org CakePHP(tm) Project
|
||||||
:: @since 2.0.0
|
:: @since 2.0.0
|
||||||
:: @license http://www.opensource.org/licenses/mit-license.php MIT License
|
:: @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||||
::
|
::
|
||||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
@echo off
|
@echo off
|
||||||
|
|
||||||
SET app=%0
|
SET app=%0
|
||||||
SET lib=%~dp0
|
SET lib=%~dp0
|
||||||
|
|
||||||
php "%lib%cake.php" %*
|
php "%lib%cake.php" %*
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
exit /B %ERRORLEVEL%
|
exit /B %ERRORLEVEL%
|
||||||
|
|
53
composer.json
Normal file
53
composer.json
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
{
|
||||||
|
"name": "cakephp/app",
|
||||||
|
"description": "CakePHP skeleton app",
|
||||||
|
"homepage": "http://cakephp.org",
|
||||||
|
"type": "project",
|
||||||
|
"license": "MIT",
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.6",
|
||||||
|
"cakephp/cakephp": "3.4.*",
|
||||||
|
"mobiledetect/mobiledetectlib": "2.*",
|
||||||
|
"cakephp/migrations": "~1.0",
|
||||||
|
"cakephp/plugin-installer": "~1.0",
|
||||||
|
"mdanter/ecc": "^0.4.2",
|
||||||
|
"nesbot/carbon": "~1.18",
|
||||||
|
"endroid/qrcode": "^2.2.2",
|
||||||
|
"predis/predis": "^1.1.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"psy/psysh": "@stable",
|
||||||
|
"cakephp/debug_kit": "~3.2",
|
||||||
|
"cakephp/bake": "~1.1"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"markstory/asset_compress": "An asset compression plugin which provides file concatenation and a flexible filter system for preprocessing and minification.",
|
||||||
|
"dereuromark/cakephp-ide-helper": "After baking your code, this keeps your annotations in sync with the code evolving from there on for maximum IDE and PHPStan compatibility.",
|
||||||
|
"phpunit/phpunit": "Allows automated tests to be run without system-wide install.",
|
||||||
|
"cakephp/cakephp-codesniffer": "Allows to check the code against the coding standards used in CakePHP."
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"App\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"App\\Test\\": "tests",
|
||||||
|
"Cake\\Test\\": "./vendor/cakephp/cakephp/tests"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"post-install-cmd": "App\\Console\\Installer::postInstall",
|
||||||
|
"post-create-project-cmd": "App\\Console\\Installer::postInstall",
|
||||||
|
"post-autoload-dump": "Cake\\Composer\\Installer\\PluginInstaller::postAutoloadDump",
|
||||||
|
"check": [
|
||||||
|
"@test",
|
||||||
|
"@cs-check"
|
||||||
|
],
|
||||||
|
"cs-check": "phpcs --colors -p --standard=vendor/cakephp/cakephp-codesniffer/CakePHP ./src ./tests",
|
||||||
|
"cs-fix": "phpcbf --colors --standard=vendor/cakephp/cakephp-codesniffer/CakePHP ./src ./tests",
|
||||||
|
"test": "phpunit --colors=always"
|
||||||
|
},
|
||||||
|
"prefer-stable": true
|
||||||
|
}
|
2737
composer.lock
generated
Normal file
2737
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
40
phpunit.xml.dist
Normal file
40
phpunit.xml.dist
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit
|
||||||
|
colors="true"
|
||||||
|
processIsolation="false"
|
||||||
|
stopOnFailure="false"
|
||||||
|
syntaxCheck="false"
|
||||||
|
bootstrap="./tests/bootstrap.php"
|
||||||
|
>
|
||||||
|
<php>
|
||||||
|
<ini name="memory_limit" value="-1"/>
|
||||||
|
<ini name="apc.enable_cli" value="1"/>
|
||||||
|
</php>
|
||||||
|
|
||||||
|
<!-- Add any additional test suites you want to run here -->
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="App Test Suite">
|
||||||
|
<directory>./tests/TestCase</directory>
|
||||||
|
</testsuite>
|
||||||
|
<!-- Add plugin test suites here. -->
|
||||||
|
</testsuites>
|
||||||
|
|
||||||
|
<!-- Setup a listener for fixtures -->
|
||||||
|
<listeners>
|
||||||
|
<listener
|
||||||
|
class="\Cake\TestSuite\Fixture\FixtureInjector"
|
||||||
|
file="./vendor/cakephp/cakephp/src/TestSuite/Fixture/FixtureInjector.php">
|
||||||
|
<arguments>
|
||||||
|
<object class="\Cake\TestSuite\Fixture\FixtureManager" />
|
||||||
|
</arguments>
|
||||||
|
</listener>
|
||||||
|
</listeners>
|
||||||
|
|
||||||
|
<!-- Ignore vendor tests in code coverage reports -->
|
||||||
|
<filter>
|
||||||
|
<whitelist>
|
||||||
|
<directory suffix=".php">./src/</directory>
|
||||||
|
<directory suffix=".php">./plugins/*/src/</directory>
|
||||||
|
</whitelist>
|
||||||
|
</filter>
|
||||||
|
</phpunit>
|
18
sql/lbryexplorer.aux.sql
Normal file
18
sql/lbryexplorer.aux.sql
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
-- Address Tagging TX tracking
|
||||||
|
CREATE TABLE `TagAddressRequests`
|
||||||
|
(
|
||||||
|
`Id` SERIAL,
|
||||||
|
`Address` VARCHAR(35) NOT NULL,
|
||||||
|
`VerificationAmount` DECIMAL(18,8) NOT NULL,
|
||||||
|
`Tag` VARCHAR(30) NOT NULL,
|
||||||
|
`TagUrl` VARCHAR(200) NULL,
|
||||||
|
`IsVerified` TINYINT(1) DEFAULT 0 NOT NULL,
|
||||||
|
`Created` DATETIME NOT NULL,
|
||||||
|
`Modified` DATETIME NOT NULL,
|
||||||
|
PRIMARY KEY `PK_TagAddressRequest` (`Id`),
|
||||||
|
UNIQUE KEY `Idx_TagAddressRequestId` (`Address`, `VerificationAmount`),
|
||||||
|
INDEX `Idx_TagAddressRequestVerificationAmount` (`VerificationAmount`),
|
||||||
|
INDEX `Idx_TagAddressRequestAddress` (`Address`),
|
||||||
|
INDEX `Idx_TagAddressRequestCreated` (`Created`),
|
||||||
|
INDEX `Idx_TagAddressRequestModified` (`Modified`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
|
186
sql/lbryexplorer.ddl.sql
Normal file
186
sql/lbryexplorer.ddl.sql
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
--DROP DATABASE IF EXISTS lbry;
|
||||||
|
CREATE DATABASE lbry DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
USE lbry;
|
||||||
|
|
||||||
|
CREATE TABLE `Blocks`
|
||||||
|
(
|
||||||
|
`Id` SERIAL,
|
||||||
|
|
||||||
|
`Bits` VARCHAR(20) NOT NULL,
|
||||||
|
`Chainwork` VARCHAR(70) NOT NULL,
|
||||||
|
`Confirmations` INTEGER UNSIGNED NOT NULL,
|
||||||
|
`Difficulty` DECIMAL(18,8) NOT NULL,
|
||||||
|
`Hash` VARCHAR(70) NOT NULL,
|
||||||
|
`Height` BIGINT UNSIGNED NOT NULL,
|
||||||
|
`MedianTime` BIGINT UNSIGNED NOT NULL,
|
||||||
|
`MerkleRoot` VARCHAR(70) NOT NULL,
|
||||||
|
`NameClaimRoot` VARCHAR(70) NOT NULL,
|
||||||
|
`Nonce` BIGINT UNSIGNED NOT NULL,
|
||||||
|
`PreviousBlockHash` VARCHAR(70),
|
||||||
|
`NextBlockHash` VARCHAR(70),
|
||||||
|
`BlockSize` BIGINT UNSIGNED NOT NULL,
|
||||||
|
`Target` VARCHAR(70) NOT NULL,
|
||||||
|
`BlockTime` BIGINT UNSIGNED NOT NULL,
|
||||||
|
`Version` BIGINT UNSIGNED NOT NULL,
|
||||||
|
`VersionHex` VARCHAR(10) NOT NULL,
|
||||||
|
`TransactionHashes` TEXT,
|
||||||
|
`TransactionsProcessed` TINYINT(1) DEFAULT 0 NOT NULL,
|
||||||
|
|
||||||
|
`Created` DATETIME NOT NULL,
|
||||||
|
`Modified` DATETIME NOT NULL,
|
||||||
|
|
||||||
|
PRIMARY KEY `PK_Block` (`Id`),
|
||||||
|
UNIQUE KEY `Idx_BlockHash` (`Hash`),
|
||||||
|
CONSTRAINT `Cnt_TransactionHashesValidJson` CHECK(`TransactionHashes` IS NULL OR JSON_VALID(`TransactionHashes`)),
|
||||||
|
INDEX `Idx_BlockHeight` (`Height`),
|
||||||
|
INDEX `Idx_BlockTime` (`BlockTime`),
|
||||||
|
INDEX `Idx_MedianTime` (`MedianTime`),
|
||||||
|
INDEX `Idx_PreviousBlockHash` (`PreviousBlockHash`),
|
||||||
|
INDEX `Idx_BlockCreated` (`Created`),
|
||||||
|
INDEX `Idx_BlockModified` (`Modified`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
|
||||||
|
|
||||||
|
CREATE TABLE `Transactions`
|
||||||
|
(
|
||||||
|
`Id` SERIAL,
|
||||||
|
`BlockHash` VARCHAR(70),
|
||||||
|
`InputCount` INTEGER UNSIGNED NOT NULL,
|
||||||
|
`OutputCount` INTEGER UNSIGNED NOT NULL,
|
||||||
|
`Value` DECIMAL(18,8) NOT NULL,
|
||||||
|
`Fee` DECIMAL(18,8) DEFAULT 0 NOT NULL,
|
||||||
|
`TransactionTime` BIGINT UNSIGNED,
|
||||||
|
`TransactionSize` BIGINT UNSIGNED NOT NULL,
|
||||||
|
`Hash` VARCHAR(70) NOT NULL,
|
||||||
|
`Version` INTEGER NOT NULL,
|
||||||
|
`LockTime` INTEGER UNSIGNED NOT NULL,
|
||||||
|
`Raw` TEXT,
|
||||||
|
`Created` DATETIME NOT NULL,
|
||||||
|
`Modified` DATETIME NOT NULL,
|
||||||
|
`CreatedTime` INTEGER UNSIGNED DEFAULT UNIX_TIMESTAMP() NOT NULL,
|
||||||
|
PRIMARY KEY `PK_Transaction` (`Id`),
|
||||||
|
FOREIGN KEY `FK_TransactionBlockHash` (`BlockHash`) REFERENCES `Blocks` (`Hash`),
|
||||||
|
UNIQUE KEY `Idx_TransactionHash` (`Hash`),
|
||||||
|
INDEX `Idx_TransactionTime` (`TransactionTime`),
|
||||||
|
INDEX `Idx_TransactionCreatedTime` (`CreatedTime`),
|
||||||
|
INDEX `Idx_TransactionCreated` (`Created`),
|
||||||
|
INDEX `Idx_TransactionModified` (`Modified`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
|
||||||
|
|
||||||
|
CREATE TABLE `Addresses`
|
||||||
|
(
|
||||||
|
`Id` SERIAL,
|
||||||
|
`Address` VARCHAR(40) NOT NULL,
|
||||||
|
`FirstSeen` DATETIME,
|
||||||
|
`TotalReceived` DECIMAL(18,8) DEFAULT 0 NOT NULL,
|
||||||
|
`TotalSent` DECIMAL(18,8) DEFAULT 0 NOT NULL,
|
||||||
|
`Tag` VARCHAR(30) NOT NULL,
|
||||||
|
`TagUrl` VARCHAR(200),
|
||||||
|
`Created` DATETIME NOT NULL,
|
||||||
|
`Modified` DATETIME NOT NULL,
|
||||||
|
PRIMARY KEY `PK_Address` (`Id`),
|
||||||
|
UNIQUE KEY `Idx_AddressAddress` (`Address`),
|
||||||
|
UNIQUE KEY `Idx_AddressTag` (`Tag`),
|
||||||
|
INDEX `Idx_AddressTotalReceived` (`TotalReceived`),
|
||||||
|
INDEX `Idx_AddressTotalSent` (`TotalSent`),
|
||||||
|
INDEX `Idx_AddressCreated` (`Created`),
|
||||||
|
INDEX `Idx_AddressModified` (`Modified`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
|
||||||
|
|
||||||
|
CREATE TABLE `Inputs`
|
||||||
|
(
|
||||||
|
`Id` SERIAL,
|
||||||
|
`TransactionId` BIGINT UNSIGNED NOT NULL,
|
||||||
|
`TransactionHash` VARCHAR(70) NOT NULL,
|
||||||
|
`AddressId` BIGINT UNSIGNED,
|
||||||
|
`IsCoinbase` TINYINT(1) DEFAULT 0 NOT NULL,
|
||||||
|
`Coinbase` VARCHAR(70),
|
||||||
|
`PrevoutHash` VARCHAR(70),
|
||||||
|
`PrevoutN` INTEGER UNSIGNED,
|
||||||
|
`PrevoutSpendUpdated` TINYINT(1) DEFAULT 0 NOT NULL,
|
||||||
|
`Sequence` INTEGER UNSIGNED,
|
||||||
|
`Value` DECIMAL(18,8),
|
||||||
|
`ScriptSigAsm` TEXT,
|
||||||
|
`ScriptSigHex` TEXT,
|
||||||
|
`Created` DATETIME NOT NULL,
|
||||||
|
`Modified` DATETIME NOT NULL,
|
||||||
|
PRIMARY KEY `PK_Input` (`Id`),
|
||||||
|
FOREIGN KEY `FK_InputAddress` (`AddressId`) REFERENCES `Addresses` (`Id`),
|
||||||
|
FOREIGN KEY `FK_InputTransaction` (`TransactionId`) REFERENCES `Transactions` (`Id`),
|
||||||
|
INDEX `Idx_InputValue` (`Value`),
|
||||||
|
INDEX `Idx_PrevoutHash` (`PrevoutHash`),
|
||||||
|
INDEX `Idx_InputCreated` (`Created`),
|
||||||
|
INDEX `Idx_InputModified` (`Modified`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
|
||||||
|
|
||||||
|
CREATE TABLE `InputsAddresses`
|
||||||
|
(
|
||||||
|
`InputId` BIGINT UNSIGNED NOT NULL,
|
||||||
|
`AddressId` BIGINT UNSIGNED NOT NULL,
|
||||||
|
PRIMARY KEY `PK_InputAddress` (`InputId`, `AddressId`),
|
||||||
|
FOREIGN KEY `Idx_InputsAddressesInput` (`InputId`) REFERENCES `Inputs` (`Id`),
|
||||||
|
FOREIGN KEY `Idx_InputsAddressesAddress` (`AddressId`) REFERENCES `Addresses` (`Id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
|
||||||
|
|
||||||
|
CREATE TABLE `Outputs`
|
||||||
|
(
|
||||||
|
`Id` SERIAL,
|
||||||
|
`TransactionId` BIGINT UNSIGNED NOT NULL,
|
||||||
|
`Value` DECIMAL(18,8),
|
||||||
|
`Vout` INTEGER UNSIGNED,
|
||||||
|
`Type` VARCHAR(20),
|
||||||
|
`ScriptPubKeyAsm` TEXT,
|
||||||
|
`ScriptPubKeyHex` TEXT,
|
||||||
|
`RequiredSignatures` INTEGER UNSIGNED,
|
||||||
|
`Hash160` VARCHAR(50),
|
||||||
|
`Addresses` TEXT,
|
||||||
|
`IsSpent` TINYINT(1) DEFAULT 0 NOT NULL,
|
||||||
|
`SpentByInputId` BIGINT UNSIGNED,
|
||||||
|
`Created` DATETIME NOT NULL,
|
||||||
|
`Modified` DATETIME NOT NULL,
|
||||||
|
PRIMARY KEY `PK_Output` (`Id`),
|
||||||
|
FOREIGN KEY `FK_OutputTransaction` (`TransactionId`) REFERENCES `Transactions` (`Id`),
|
||||||
|
FOREIGN KEY `FK_OutputSpentByInput` (`SpentByInputId`) REFERENCES `Inputs` (`Id`),
|
||||||
|
CONSTRAINT `Cnt_AddressesValidJson` CHECK(`Addresses` IS NULL OR JSON_VALID(`Addresses`)),
|
||||||
|
INDEX `Idx_OutputValue` (`Value`),
|
||||||
|
INDEX `Idx_OuptutCreated` (`Created`),
|
||||||
|
INDEX `Idx_OutputModified` (`Modified`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
|
||||||
|
|
||||||
|
CREATE TABLE `OutputsAddresses`
|
||||||
|
(
|
||||||
|
`OutputId` BIGINT UNSIGNED NOT NULL,
|
||||||
|
`AddressId` BIGINT UNSIGNED NOT NULL,
|
||||||
|
PRIMARY KEY `PK_OutputAddress` (`OutputId`, `AddressId`),
|
||||||
|
FOREIGN KEY `Idx_OutputsAddressesOutput` (`OutputId`) REFERENCES `Outputs` (`Id`),
|
||||||
|
FOREIGN KEY `Idx_OutputsAddressesAddress` (`AddressId`) REFERENCES `Addresses` (`Id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
|
||||||
|
|
||||||
|
CREATE TABLE `TransactionsAddresses`
|
||||||
|
(
|
||||||
|
`TransactionId` BIGINT UNSIGNED NOT NULL,
|
||||||
|
`AddressId` BIGINT UNSIGNED NOT NULL,
|
||||||
|
`DebitAmount` DECIMAL(18,8) DEFAULT 0 NOT NULL COMMENT 'Sum of the inputs to this address for the tx',
|
||||||
|
`CreditAmount` DECIMAL(18,8) DEFAULT 0 NOT NULL COMMENT 'Sum of the outputs to this address for the tx',
|
||||||
|
`TransactionTime` DATETIME DEFAULT UTC_TIMESTAMP() NOT NULL,
|
||||||
|
PRIMARY KEY `PK_TransactionAddress` (`TransactionId`, `AddressId`),
|
||||||
|
FOREIGN KEY `Idx_TransactionsAddressesTransaction` (`TransactionId`) REFERENCES `Transactions` (`Id`),
|
||||||
|
FOREIGN KEY `Idx_TransactionsAddressesAddress` (`AddressId`) REFERENCES `Addresses` (`Id`),
|
||||||
|
INDEX `Idx_TransactionsAddressesLatestTransactionTime` (`LatestTransactionTime`),
|
||||||
|
INDEX `Idx_TransactionsAddressesDebit` (`DebitAmount`),
|
||||||
|
INDEX `Idx_TransactionsAddressesCredit` (`CreditAmount`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
|
||||||
|
|
||||||
|
ALTER TABLE TransactionsAddresses ADD COLUMN TransactionTime DATETIME DEFAULT UTC_TIMESTAMP() NOT NULL AFTER CreditAmount;
|
||||||
|
ALTER TABLE TransactionsAddresses ADD INDEX `Idx_TransactionsAddressesTransactionTime` (`TransactionTime`);
|
||||||
|
|
||||||
|
ALTER TABLE Addresses ADD COLUMN TotalReceived DECIMAL(18,8) DEFAULT 0 NOT NULL AFTER FirstSeen;
|
||||||
|
ALTER TABLE Addresses ADD COLUMN TotalSent DECIMAL(18,8) DEFAULT 0 NOT NULL AFTER TotalReceived;
|
||||||
|
ALTER TABLE Addresses ADD INDEX Idx_AddressTotalReceived (TotalReceived);
|
||||||
|
ALTER TABLE Addresses ADD INDEX Idx_AddressTotalSent (TotalSent);
|
||||||
|
|
||||||
|
ALTER TABLE Addresses ADD COLUMN `Tag` VARCHAR(30) AFTER TotalSent;
|
||||||
|
ALTER TABLE Addresses ADD COLUMN `TagUrl` VARCHAR(200) AFTER Tag;
|
||||||
|
ALTER TABLE Addresses ADD UNIQUE KEY `Idx_AddressTag` (`Tag`);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE Transactions ADD INDEX `Idx_TransactionSize` (`TransactionSize`);
|
|
@ -1,67 +1,67 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Model\Behavior;
|
namespace App\Model\Behavior;
|
||||||
|
|
||||||
use Cake\ORM\Behavior;
|
use Cake\ORM\Behavior;
|
||||||
use Cake\ORM\Entity;
|
use Cake\ORM\Entity;
|
||||||
use Cake\Event\Event;
|
use Cake\Event\Event;
|
||||||
use Cake\Routing\Router;
|
use Cake\Routing\Router;
|
||||||
|
|
||||||
class SimpleAuditBehavior extends Behavior {
|
class SimpleAuditBehavior extends Behavior {
|
||||||
private static $DefaultUser = '0';
|
private static $DefaultUser = '0';
|
||||||
|
|
||||||
private $_userField = 'Id';
|
private $_userField = 'Id';
|
||||||
|
|
||||||
protected $_defaultConfig = [
|
protected $_defaultConfig = [
|
||||||
'abortOnUserInvalid' => false,
|
'abortOnUserInvalid' => false,
|
||||||
'implementedMethods' => ['audit' => 'audit'],
|
'implementedMethods' => ['audit' => 'audit'],
|
||||||
'fieldMap' => [
|
'fieldMap' => [
|
||||||
'CreatedOn' => 'Created',
|
'CreatedOn' => 'Created',
|
||||||
'ModifiedOn' => 'Modified',
|
'ModifiedOn' => 'Modified',
|
||||||
'CreatedBy' => 'CreatedBy',
|
'CreatedBy' => 'CreatedBy',
|
||||||
'ModifiedBy' => 'ModifiedBy'
|
'ModifiedBy' => 'ModifiedBy'
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
public function audit(Entity $entity, $systemOperation = false) {
|
public function audit(Entity $entity, $systemOperation = false) {
|
||||||
$time = $this->_currentUtcTime()->format('Y-m-d H:i:s');
|
$time = $this->_currentUtcTime()->format('Y-m-d H:i:s');
|
||||||
$user = ($systemOperation) ? self::$DefaultUser : $this->_currentUser();
|
$user = ($systemOperation) ? self::$DefaultUser : $this->_currentUser();
|
||||||
|
|
||||||
if (!$systemOperation
|
if (!$systemOperation
|
||||||
&& $this->_config['abortOnUserInvalid']
|
&& $this->_config['abortOnUserInvalid']
|
||||||
&& $user == self::$DefaultUser)
|
&& $user == self::$DefaultUser)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$fieldMap = $this->_config['fieldMap'];
|
$fieldMap = $this->_config['fieldMap'];
|
||||||
|
|
||||||
if ($entity->isNew()) {
|
if ($entity->isNew()) {
|
||||||
$entity->set($fieldMap['CreatedOn'], $time);
|
$entity->set($fieldMap['CreatedOn'], $time);
|
||||||
$entity->set($fieldMap['CreatedBy'], $user);
|
$entity->set($fieldMap['CreatedBy'], $user);
|
||||||
}
|
}
|
||||||
|
|
||||||
$entity->set($fieldMap['ModifiedOn'], $time);
|
$entity->set($fieldMap['ModifiedOn'], $time);
|
||||||
$entity->set($fieldMap['ModifiedBy'], $user);
|
$entity->set($fieldMap['ModifiedBy'], $user);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function beforeSave(Event $event, Entity $entity) {
|
public function beforeSave(Event $event, Entity $entity) {
|
||||||
return $this->audit($entity);
|
return $this->audit($entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function _currentUtcTime() {
|
private function _currentUtcTime() {
|
||||||
return new \DateTime('now', new \DateTimeZone('UTC'));
|
return new \DateTime('now', new \DateTimeZone('UTC'));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function _currentUser() {
|
private function _currentUser() {
|
||||||
$request = Router::getRequest(true);
|
$request = Router::getRequest(true);
|
||||||
if ($request) {
|
if ($request) {
|
||||||
$session = $request->session();
|
$session = $request->session();
|
||||||
$fieldValue = $session->read(sprintf('Auth.User.' . $this->_userField));
|
$fieldValue = $session->read(sprintf('Auth.User.' . $this->_userField));
|
||||||
return (intval($fieldValue) > 0) ? $fieldValue : self::$DefaultUser;
|
return (intval($fieldValue) > 0) ? $fieldValue : self::$DefaultUser;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
|
@ -1,11 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Model\Entity;
|
namespace App\Model\Entity;
|
||||||
|
|
||||||
use Cake\ORM\Entity;
|
use Cake\ORM\Entity;
|
||||||
|
|
||||||
class Address extends Entity {
|
class Address extends Entity {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
|
@ -1,11 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Model\Entity;
|
namespace App\Model\Entity;
|
||||||
|
|
||||||
use Cake\ORM\Entity;
|
use Cake\ORM\Entity;
|
||||||
|
|
||||||
class Input extends Entity {
|
class Input extends Entity {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
|
@ -1,11 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Model\Entity;
|
namespace App\Model\Entity;
|
||||||
|
|
||||||
use Cake\ORM\Entity;
|
use Cake\ORM\Entity;
|
||||||
|
|
||||||
class Output extends Entity {
|
class Output extends Entity {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
|
@ -1,11 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Model\Entity;
|
namespace App\Model\Entity;
|
||||||
|
|
||||||
use Cake\ORM\Entity;
|
use Cake\ORM\Entity;
|
||||||
|
|
||||||
class Transaction extends Entity {
|
class Transaction extends Entity {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
|
@ -1,18 +1,18 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Model\Table;
|
namespace App\Model\Table;
|
||||||
|
|
||||||
use Cake\ORM\Table;
|
use Cake\ORM\Table;
|
||||||
|
|
||||||
class TagAddressRequestsTable extends Table {
|
class TagAddressRequestsTable extends Table {
|
||||||
public function initialize(array $config) {
|
public function initialize(array $config) {
|
||||||
parent::initialize($config);
|
parent::initialize($config);
|
||||||
|
|
||||||
$this->primaryKey('Id');
|
$this->primaryKey('Id');
|
||||||
$this->table('TagAddressRequests');
|
$this->table('TagAddressRequests');
|
||||||
|
|
||||||
$this->addBehavior('SimpleAudit');
|
$this->addBehavior('SimpleAudit');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
|
@ -1,44 +1,44 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\View\Helper;
|
namespace App\View\Helper;
|
||||||
|
|
||||||
use Cake\View\Helper;
|
use Cake\View\Helper;
|
||||||
|
|
||||||
class AmountHelper extends Helper {
|
class AmountHelper extends Helper {
|
||||||
public function format($value) {
|
public function format($value) {
|
||||||
$value = number_format($value, 8, '.', ',');
|
$value = number_format($value, 8, '.', ',');
|
||||||
$dotIdx = strpos($value, '.');
|
$dotIdx = strpos($value, '.');
|
||||||
if ($dotIdx !== false) {
|
if ($dotIdx !== false) {
|
||||||
$left = substr($value, 0, $dotIdx);
|
$left = substr($value, 0, $dotIdx);
|
||||||
$right = substr($value, $dotIdx + 1);
|
$right = substr($value, $dotIdx + 1);
|
||||||
|
|
||||||
$value = $left;
|
$value = $left;
|
||||||
if ((int) $right > 0) {
|
if ((int) $right > 0) {
|
||||||
$value .= '.' . rtrim($right, '0');
|
$value .= '.' . rtrim($right, '0');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function formatCurrency($value) {
|
public function formatCurrency($value) {
|
||||||
$dotIdx = strpos($value, '.');
|
$dotIdx = strpos($value, '.');
|
||||||
if ($dotIdx !== false) {
|
if ($dotIdx !== false) {
|
||||||
$left = substr($value, 0, $dotIdx);
|
$left = substr($value, 0, $dotIdx);
|
||||||
$right = substr($value, $dotIdx + 1);
|
$right = substr($value, $dotIdx + 1);
|
||||||
|
|
||||||
$value = number_format($left, 0, '', ',');
|
$value = number_format($left, 0, '', ',');
|
||||||
if ((int) $right > 0) {
|
if ((int) $right > 0) {
|
||||||
if (strlen($right) === 1) {
|
if (strlen($right) === 1) {
|
||||||
$value .= '.' . $right . '0';
|
$value .= '.' . $right . '0';
|
||||||
} else {
|
} else {
|
||||||
$value .= '.' . substr($right, 0, 2);
|
$value .= '.' . substr($right, 0, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
Loading…
Reference in a new issue