Compare commits

...

735 Commits

Author SHA1 Message Date
msutton
20f16cf729 Update checkpoint to new side-chain 2022-03-06 01:03:44 +02:00
Ori Newman
4d3f504b73 Check checkpoint only if highestSharedBlockFound 2022-03-02 21:17:46 +02:00
Ori Newman
b5eda33488 remove count 2022-03-02 13:11:32 +02:00
Ori Newman
ef1a3c0dce remove debug log 2022-03-02 13:09:34 +02:00
Ori Newman
1cedc720ac patch 2022-03-02 12:31:14 +02:00
Ori Newman
6449b03034 Ignore transaction invs on IBD (#1960)
* Ignore transaction invs on IBD

* Add IsIBDRunning mock to TestHandleRelayedTransactionsNotFound

Co-authored-by: Ori Newman <>
2022-02-26 22:20:08 +02:00
Ori Newman
9f02a24e8b Add merge set and IsChainBlock to the RPC (#1961)
* Add merge set and IsChainBlock to the RPC

* Fix BlockInfo.Clone()
2022-02-25 16:22:00 +02:00
Isaac Cook
9b23bbcdb5 kaspactl: string slice deser for GetUtxosByAddresses (#1955)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2022-02-24 00:40:01 +02:00
stasatdaglabs
b30f7309a2 Implement a parse sub command in the walllet (#1953)
* Add boilerplate for the `parse` sub command.

* Deserialize the given transaction hax.

* Implement the rest of the wallet parse command.

* Hide transaction inputs behind a `verbose` flag.

* Indicate that we aren't able to extract an address out of a nonstandard transaction.

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2022-02-20 22:12:23 +02:00
Ori Newman
1c18a49992 Add cache to block window (#1948)
* Add cache to block window

* Copy the window heap slice with the right capacity

* Use WindowHeapSliceStore

* Use the selected parent window as a basis (and some comments and variable renames)

* Clone slice on newSizedUpHeapFromSlice

* Rename isNotFoundError->currentIsNonTrustedBlock

* Increase windowHeapSliceStore cache size to 2000 and some cosmetic changes
2022-02-20 16:52:36 +02:00
stasatdaglabs
28d0f1ea2e Set MaxBlockLevels for non-mainnet networks to 250 (#1952)
* Make MaxBlockLevel a DAG params instead of a constant.

* Change the testnet network name to 9.

* Fix TestBlockWindow.

* Set MaxBlockLevels for non-mainnet networks to 250.

* Revert "Fix TestBlockWindow."

This reverts commit 30a7892f53.

* Fix TestPruning.
2022-02-20 13:43:42 +02:00
Ori Newman
3f7e482291 Add progress indication for virtual resolution (#1949)
* Add progress indication for virtual resolution

* Avoid division by zero
2022-02-20 00:32:41 +02:00
Ori Newman
ce4f5fcc33 Remove BlockWithTrustedData method (#1950)
* Remove BlockWithTrustedData method

* Remove unused methods
2022-02-20 00:04:47 +02:00
Svarog
be3a6604d7 Make kaspawallet store the utxos sorted by amount (#1947)
* Make kaspawallet store the utxos sorted by amount, so that the bigger utxos are spent first - making it less likely a compound will be required

* Start refactor addEntryToUTXOSet

* Add GetUTXOsByBalances command to rpc

* Store list of addresses, updated with the collectAddresses methods
(replacing collectUTXOs methods)

* Fix wrong commands in GetBalanceByAddress

* Rename: refreshExistingUTXOs -> refreshUTXOs

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2022-02-18 15:08:08 +02:00
Svarog
f452531df0 Fix bookkeeping of chained transactions in mempool (#1946)
* Fix bookkeeping of chained transactions in mempool

* Fix golint error
2022-02-18 13:21:45 +02:00
Ori Newman
13a09da848 Bump version to v0.11.12 (#1941)
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2022-02-17 18:27:25 +02:00
Michael Sutton
f58aeb4f9f In profile dump file - use a time format supporting all file systems (#1945)
* Use a time format without ":" to support all file systems

* go fmt
2022-02-12 22:00:46 +02:00
Ori Newman
82f0a4d74f Drop support for p2p v3 (#1942)
* Drop support for p2p v3

* Remove redundant aliases

* Remove redundant condition
2022-02-06 17:28:06 +02:00
Ori Newman
69d90fe827 Remove duplicate median time calculation on tx validation (#1943)
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2022-02-06 16:34:05 +02:00
Ori Newman
c85b5d70fd Add AllowConnectionToDifferentVersions flag to kaspactl (#1940) 2022-02-06 15:43:09 +02:00
Ori Newman
1cd712a63e Increase headers proof timeout and add more progress logs (#1939)
* Increase timeout for pruning proof and add some logs

* Show resolving virtual progress as whole percents
2022-02-06 12:42:28 +02:00
stasatdaglabs
27ba9d0374 Split ApplyPruningPointProof to multiple small database transactions (#1937)
* Split ApplyPruningPointProof to multiple small database transactions.

* Increase the timeout duration in TestIBDWithPruning.

* Increase the timeout duration in simple-sync.

* Explain that if ApplyPruningPointProof fails, the database must be discarded.
2022-02-06 10:36:27 +02:00
stasatdaglabs
b1229f7908 Display progress of IBD process in Kaspad logs (#1938)
* Report progress percentage when downloading headers in IBD.

* Extract reporting logic to a separate type.

* Report progress for IBD missing block bodies.
2022-02-02 21:24:45 +02:00
Michael Sutton
4a560f25a6 Update changelog and version number for v0.11.11 (#1935) 2022-01-27 21:53:05 +02:00
Michael Sutton
dab1a881fe Fix for rare consensus bug regarding daa window order (#1934)
* Fix for rare consensus bug: daa window min-time-block was not deterministic when timestamps are equal

* Something is missing

* Extract compare logic to a function with better performance

* typo
2022-01-27 20:29:44 +02:00
Ori Newman
598392d0cf Update changelog to v0.11.10 (#1933)
Co-authored-by: Ori Newman <>
2022-01-27 12:56:26 +02:00
Michael Sutton
6d27637055 Add monitoring of heap and save heap profile if size is over some limit (#1932)
* Add monitoring of heap and save heap profile if size is over some limit

* Exported function

* Extract dump logic to a function (for defer close)

* Change trackHeapSize ticker interval to 10 seconds

* Add timestamp to dump file name

Co-authored-by: Ori Newman <>
2022-01-27 11:57:28 +02:00
Michael Sutton
4855d845b3 Extract IBD management from invs relay flow to a new separated flow (#1930)
* Separate IBD to a new flow (so now invs are handled concurrently and no route capacity errors)

* Invs messages should be queued while waiting for BlockLocator msg

* Close IBD channel so that HandleIBDFlow exits too

* Apply flow separation to p2p protocol v4

* Manage the IBDRequestChannel through the Peer struct

* Some IBDs take a little longer
2022-01-24 09:30:41 +02:00
stasatdaglabs
b1b179c105 Add --transaction-file options to the sign and broadcast wallet subcommands (#1927)
* Add --transaction-file to the sign wallet subcommand.

* Fix bad short sign config option.

* Trim whitespace around the hex file.

* Add --transaction-file to the broadcast subcommand.
2022-01-16 14:59:54 +02:00
Ori Newman
dadacdc0f4 Filter redundant blocks from daa window (#1925)
* Copy blockrelay flows to v4

* Remove duplicate sending of the same DAA blocks

* Advance testnet version

* Renames and add comments

* Add IBD test between v3 and v4

* Fix syncee v4 p2p version

* Check if netsync finished with selected tip
2022-01-09 16:58:51 +02:00
Ori Newman
d2379608ad P2P upgrade mechanism (#1921)
* Implement upgrade mechanism for p2p

* Remove dependencies from flowcontext to v3

* Add p2p v4

* Add Ready flow

* Remove copy paste code of v3

* Register SendAddresses flow at the top level

* Add option to set protocol version from CLI and add TestAddressExchangeV3V4

* Send ready message on minimal net adapter

* Rename defaultMaxProtocolVersion->maxAcceptableProtocolVersion
2022-01-09 09:59:45 +02:00
Michael Sutton
14b2bcbd81 Update to version v0.11.9 plus changelog update (#1919) 2021-12-30 18:37:51 +02:00
Michael Sutton
71b284f4d5 Address manager randomization weighted by connection failures (#1916)
* Address manager refactor stage 1

* Use a simpler weightedRand function which makes it easier parameterize to the process

* Switch back to connectionFailedCount

* Simplify selected entry deletion

* Fix function comment

Co-authored-by: Constantine Bitensky <cbitensky1@gmail.com>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-12-30 12:05:53 +02:00
Michael Sutton
0e1d247915 Fix stability test mining (allow submission of non DAA blocks too) (#1917)
* Fix stability test mining (allow submission of non DAA blocks too)

* Comments for go fmt

* Use SubmitBlockAlsoIfNonDAA for all tests

Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
2021-12-30 11:04:56 +02:00
Michael Sutton
504ec36612 Remove DNS seeder managed by Elichai Turkel (its offline) (#1918) 2021-12-30 10:10:57 +02:00
Ori Newman
c80b113319 Fix two pruning proof bugs (#1913)
* Don't assume pruning point is at specific level

* Reverse pruning points order in ArePruningPointsViolatingFinality

Co-authored-by: Michael Sutton <mikisiton2@gmail.com>
2021-12-29 21:24:29 +02:00
stasatdaglabs
0bdd19136f Implement the new monetary policy (#1892)
* Remove unused functions, constants, and variables.

* Rename maxSubsidy to baseSubsidy.

* Remove unused parameters from CalcBlockSubsidy.

* Remove link to old monetary policy.

* If a block's DAA score is smaller than half a year, it should have a base subsidy.

* Fix merge errors.

* Fix more merge errors.

* Add DeflationaryPhaseBaseSubsidy to the params.

* Implement TestCalcDeflationaryPeriodBlockSubsidy.

* Implement calcDeflationaryPeriodBlockSubsidy naively.

* Implement calcDeflationaryPeriodBlockSubsidy not naively.

* Adjust the subsidy based on target block rate.

* Fix deflationaryPhaseDaaScore in TestCalcDeflationaryPeriodBlockSubsidy.

* Explain how secondsPerMonth is calculated.

* Don't adjust the subsidy based on the target block rate.

* Update defaultDeflationaryPhaseDaaScore and add an explanation.

* Use a pre-calculated table for subsidy per month

* Make the generation function fail if base subsidy is changed

* go fmt

* Use test logger for printing + simplify print loop

Co-authored-by: msutton <mikisiton2@gmail.com>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-12-29 20:49:20 +02:00
Svarog
7c1cddff11 Address Manager: Don't seed if we have enough Addresses + Remove Address that failed connection too many times (#1899)
* Seed from DNS only if we ran out of addresses to connect to

* Remove address if it has failed 10 connections

* Change connectionFailedCountForRemove to 3
2021-12-29 20:34:32 +02:00
Michael Sutton
064b0454e8 Reject out of date blocks submitted via RPC (#1914)
* Disallow by default RPC submission of out of date blocks (blocks which are out of virtual DAA window)

* go fmt

* Better condition test

* Make allowNonDAABlocks an RPC field and not a command line flag

* go fmt

* one more go fmt
2021-12-29 20:07:45 +02:00
Michael Sutton
8282fb486e Fix protobuf generation for PR #1885 (#1915) 2021-12-29 15:30:07 +02:00
Constantine Bytensky
428449bb7d Wallet: show balance by addresses (#1904)
Co-authored-by: Constantine Bitensky <cbitensky1@gmail.com>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-12-25 14:25:15 +02:00
Aleoami
f54659ead0 Add kaspadns.kaspacalc.net to seeder list (#1910)
* Update to version v0.11.8

* bugfix: addresses issue #1903, raised kaspawallet bruteforce core limit to 256

* fix contributing.md text

* added dns seeder kaspadns.kaspacalc.net

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-12-25 13:22:44 +02:00
Aleoami
99f82eb80f fix CONTRIBUTING.md text (#1908)
* Update to version v0.11.8

* bugfix: addresses issue #1903, raised kaspawallet bruteforce core limit to 256

* fix contributing.md text

* Update cmd/kaspawallet/keys/keys.go

Co-authored-by: Ori Newman <orinewman1@gmail.com>

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-12-25 12:47:04 +02:00
georges-kuenzli
aa43c14fc5 Added seeder[1-4].kaspad.net to seeder list (#1901)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-12-23 00:42:17 +02:00
FestinaLente666
129e9119d2 Add request balance by address to kaspactl (#1885)
* Added new RPC command for getting balance of wallet address

* small details

* Regenerate protobuffs

* fixes

* routing fix

* Add 'Message' suffix to GetBalanceByAddressRequest and GetBalanceByAddressResponse

* Add Message

* linting

* linting

* fixed name

Co-authored-by: Mike Zak <feanorr@gmail.com>
Co-authored-by: Ori Newman <>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
Co-authored-by: Michael Sutton <mikisiton2@gmail.com>
2021-12-22 22:21:33 +02:00
Constantine Bytensky
cae7faced2 Added dnsseed.cbytensky.org to seeder list (#1897)
Co-authored-by: Constantine Bitensky <cbitensky1@gmail.com>
2021-12-20 08:42:02 +02:00
Elichai Turkel
f036b18f9e Add a profile option to kaspawallet daemon (#1854)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-12-19 09:36:43 +02:00
Ori Newman
1d740e1eab UTXO index fix (#1891)
* Update to version v0.11.8

* Call OnPruningPointUTXOSetOverride after committing the staging consensus

* use domain.Consensus() in utxo index so it'll always check the right consensus
2021-12-19 08:56:18 +02:00
Ori Newman
011871cda2 Update reindex root for each block level (#1881)
Co-authored-by: Ori Newman <>
2021-12-13 00:06:33 +02:00
Michael Sutton
7b4f761fb9 Update readme (#1848)
Update readme to reflect that project is no longer at pre-Alpha state

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-12-12 17:07:59 +02:00
Ori Newman
5806fef35f Lower devnet's initial difficulty (#1869)
* Lower devnet's initial difficulty

* Increase simple-sync timeToPropagate to 10 seconds

* Check expectedAveragePropagationTime

Co-authored-by: Ori Newman <>
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-12-12 16:24:43 +02:00
Ori Newman
227ef392ba Update version 2021-12-11 20:55:25 +02:00
Ori Newman
f3d76d6565 Ignore header mass in devnet and testnet (#1879) 2021-12-11 20:36:58 +02:00
Ori Newman
df573bba63 Remove unused args from CalcSubsidy (#1877) 2021-12-11 20:16:23 +02:00
Ori Newman
2a97b7c9bb ExpectedHeaderPruningPoint fix (#1876)
* ExpectedHeaderPruningPoint fix

* Fix off by one error when iterating lowHash's selected chain
2021-12-11 19:26:35 +02:00
Svarog
70900c571b Changes to libkaspawallet to support Kaspaper (#1878)
* Add NewFileFromMnemonics

* Export InternalKeychain and ExternalKeychain

* Rename NewFileFromMnemonics -> NewFileFromMnemonic

* NewFileFromMnemonic: change also argument name

* Use libkaspawallet.ExternalKeychain instead of externalKeychain
2021-12-11 17:52:21 +02:00
Constantine Bytensky
7292438e4a kaspawallet: show-address →new-address + show-addresses (#1870)
* Rename show-address to new-address

* New proto: ShowAdresses

* kaspawallet: added show-addresses command

Co-authored-by: Constantine Bitensky <cbitensky1@gmail.com>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-12-07 00:49:06 +02:00
Ori Newman
dced1a9376 Fix numThreads using getAEAD instead of decryptMnemonic (#1859)
* Fix num threads using getAEAD instead of decryptMnemonic

* Use d.NumThread to init bruteforce for num threads in getAEAD

Co-authored-by: Ori Newman <>
2021-12-06 23:56:00 +02:00
Ori Newman
32e8e539ac Apply ResolveVirtual diffs to the UTXO index (#1868)
* Apply ResolveVirtual diffs to the UTXO index

* Add comments

Co-authored-by: Ori Newman <>
2021-12-05 13:22:48 +02:00
Ori Newman
11103a36d3 Get rid of genesis's UTXO dump (#1867)
* Get rid of genesis's UTXO dump

* Allow known orphans when AllowSubmitBlockWhenNotSynced=true

* gofmt

* Avoid IBD without changing the pruning point when only genesis is available

* Add DisallowDirectBlocksOnTopOfGenesis=true for mainnet

* Remove any mention to nobanning to let stability tests run

* Rename ifGenesisSetUtxoSet to loadUTXODataForGenesis

Co-authored-by: Ori Newman <>
2021-12-05 12:46:41 +02:00
Elichai Turkel
606b781ca0 Fix bug in RequiredDifficulty and release another version 2021-11-25 21:49:15 +02:00
Elichai Turkel
dbf18d8052 Hard fork - new genesis with the utxo set of the last block (#1856)
* UTXO dump of block 0fca37ca667c2d550a6c4416dad9717e50927128c424fa4edbebc436ab13aeef

* Activate HF immediately and change reward to 1000

* Change protocol version and datadir location

* Delete comments

* Fix zero hash to muhash zero hash in genesis utxo dump check

* Don't omit genesis as direct parent

* Fix tests

* Change subsidy to 500

* Dont assume genesis multiset is empty

* Fix BlockReward test

* Fix TestValidateAndInsertImportedPruningPoint test

* Fix pruning point genesis utxo set

* Fix tests related to mainnet utxo set

* Dont change the difficulty before you have a full window

* Fix TestBlockWindow tests

* Remove global utxo set variable, and persist mainnetnet utxo deserialization between runs

* Fix last tests

* Make peer banning opt-in

* small fix for a test

* Fix go lint

* Fix Ori's review comments

* Change DAA score of genesis to checkpoint DAA score and fix all tests

* Fix the BlockLevel bits counting

* Fix some tests and make them run a little faster

* Change datadir name back to kaspa-mainnet and change db path from /data to /datadir

* Last changes for the release and change the version to 0.11.5

Co-authored-by: Ori Newman <orinewman1@gmail.com>
Co-authored-by: Ori Newman <>
Co-authored-by: msutton <mikisiton2@gmail.com>
2021-11-25 20:18:43 +02:00
Michael Sutton
2a1b38ce7a Fix mergeset limit violation bug (#1855)
* Added a test which reproduces a bug where virtual's mergeset exceeds the mergeset limit -- this test currently fails

* Added a simple condition to fix the mergeset limit bug

* Format issue
2021-11-24 19:34:59 +02:00
Ori Newman
29c410d123 Change HF time 2021-11-22 11:27:17 +02:00
Ori Newman
6e6fabf956 Change HF time 2021-11-22 11:24:55 +02:00
Ori Newman
b04292c97a Don't server parallel PruningPointAndItsAnticoneRequests 2021-11-22 09:56:30 +02:00
Ori Newman
765dd170e4 Optimizations and header size reduce hardfork (#1853)
* Modify DefaultTimeout to 120 seconds

A temporary workaround for nodes having trouble to sync (currently the download of pruning point related data during IBD takes more than 30 seconds)

* Cache existence in reachability store

* Cache block level in the header

* Fix IBD indication on submit block

* Add hardForkOmitGenesisFromParentsDAAScore logic

* Fix NumThreads bug in the wallet

* Get rid of ParentsAtLevel header method

* Fix a bug in BuildPruningPointProof

* Increase race detector timeout

* Add cache to BuildPruningPointProof

* Add comments and temp comment out go vet

* Fix ParentsAtLevel

* Dont fill empty parents

* Change HardForkOmitGenesisFromParentsDAAScore in fast netsync test

* Add --allow-submit-block-when-not-synced in stability tests

* Fix TestPruning

* Return fast tests

* Fix off by one error on kaspawallet

* Fetch only one block with trusted data at a time

* Update fork DAA score

* Don't ban for unexpected message type

* Fix tests

Co-authored-by: Michael Sutton <mikisiton2@gmail.com>
Co-authored-by: Ori Newman <>
2021-11-22 09:00:39 +02:00
Ori Newman
8e362845b3 Update to version 0.11.4 2021-11-21 01:52:56 +02:00
Ori Newman
5c1ba9170e Don't set blocks from the pruning point anticone as the header select tip (#1850)
* Decrease the dial timeout to 1 second

* Don't set blocks from the pruning point anticone as the header selected tip.

Co-authored-by: Kaspa Profiler <>
2021-11-13 18:59:20 +02:00
Elichai Turkel
9d8c555bdf Fix a bug in the matrix ranking algorithm (#1849)
* Fix a bug in the matrix ranking algorithm

* Add tests and benchmarks for matrix generation and ranking

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-11-13 17:51:11 +02:00
Ori Newman
a2f574eab8 Update to version 0.11.3 2021-11-13 17:18:40 +02:00
Kaspa Profiler
7bed86dc1b Update changelog.txt 2021-11-11 09:30:12 +02:00
Ori Newman
9b81f5145e Increase p2p msg size and reset utxo after ibd (#1847)
* Don't build unnecessary binaries

* Reset UTXO index after IBD

* Enlarge max msg size to 1gb

* Fix UTXO chunks logic

* Revert UTXO set override change

* Fix sendPruningPointUTXOSet

* Increase tests timeout to 20 minutes

Co-authored-by: Kaspa Profiler <>
2021-11-11 09:27:07 +02:00
Kaspa Profiler
cd8341ef57 Update to version 0.11.2 2021-11-10 23:19:25 +02:00
Ori Newman
ad8bdbed21 Update changelog (#1845)
Co-authored-by: Kaspa Profiler <>
2021-11-09 00:32:56 +02:00
Elichai Turkel
7cdceb6df0 Cache the miner state (#1844)
* Implement a MinerState to cache the matrix and friends

* Modify the miner and related code to use the new MinerCache

* Change MinerState to State

* Make go lint happy

Co-authored-by: Ori Newman <orinewman1@gmail.com>
Co-authored-by: Kaspa Profiler <>
2021-11-09 00:12:30 +02:00
stasatdaglabs
cc5248106e Update to version 0.11.1 2021-11-08 09:01:52 +02:00
Elichai Turkel
e3463b7268 Replace Keccak256 in oPoW with CSHAKE256 with domain seperation (#1842)
* Replace keccak with CSHAKE256 in oPoW

* Add benchmarks to hash writers to compare blake2b to the CSHAKE

* Update genesis blocks

* Update tests

* Define genesis's block level to be the maximal one

* Add message to genesis coinbase

* Add comments to genesis coinbase

* Fix tests

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-11-07 18:36:30 +02:00
Ori Newman
a2173ef80a Switch PoW to a keccak heavyhash variant (#1841)
* Add another hash domain for HeavyHash

* Add a xoShiRo256PlusPlus implementation

* Add a HeavyHash implementation

* Replace our current PoW algorithm with oPoW

* Change to pow hash to keccak256

* Fix genesis

* Fix tests

Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
2021-11-07 11:17:15 +02:00
stasatdaglabs
aeb4500b61 Add the daglabs-dev mainnet dnsseeder. (#1840) 2021-11-07 10:39:54 +02:00
Ori Newman
0a1daae319 Allow mainnet flag and raise wallet fee (#1838)
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-11-07 10:04:27 +02:00
stasatdaglabs
131cd3357e Rename FixedSubsidySwitchHashRateDifference to FixedSubsidySwitchHashRateThreshold and set its value to 150GH/s. (#1837) 2021-11-07 09:33:39 +02:00
Ori Newman
ff72568d6b Fix pruning point anticone order (#1836)
* Send pruning point anticone in topological order
Fix a UTXO pagination bug
Lengthen the stabilization time for the last DAA test

* Extend "sudden hash rate drop" test length to 45 minutes

Co-authored-by: Kaspa Profiler <>
2021-11-07 08:21:34 +02:00
stasatdaglabs
2dddb650b9 Switch to a fixed block subsidy after a certain work threshold (#1831)
* Implement isBlockRewardFixed.

* Fix factory.go.

* Call isBlockRewardFixed from calcBlockSubsidy.

* Fix bad call to ghostdagDataStore.Get.

* Extract blue score and blue work from the header instead of from the ghostdagDataStore.

* Fix coinbasemanager constructor arguments order

* Format consensus_defaults.go

* Check the mainnet switch from the block's point of view rather than the virtual's.

* Don't call newBlockPruningPoint twice in buildBlock.

* Properly handle new pruning point blocks in isBlockRewardFixed.

* Use the correct variable.

* Add a comment explaining what we do when the pruning point is not found in isBlockRewardFixed.

* Implement TestBlockRewardSwitch.

* Add missing error handling.

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-10-31 15:04:51 +02:00
Ori Newman
99aaacd649 Check blue score before requesting a pruning proof (#1835)
* Check blue score before requesting a pruning proof

* BuildPruningPointProof should return empty proof if the pruning point is genesis

* Don't fail many-tips if kaspad exits ungracefully
2021-10-31 12:48:18 +02:00
stasatdaglabs
77a344cc29 In IBD, validate the timestamps of the headers of the pruning point and selected tip (#1829)
* Implement validatePruningPointFutureHeaderTimestamps.

* Fix TestIBDWithPruning.

* Fix wrong logic.

* Add a comment.

* Fix a comment.

* Fix a variable name.

* Add a commment

* Fix TestIBDWithPruning.

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-10-30 20:32:49 +03:00
stasatdaglabs
3dbc42b4f7 Implement the new block subsidy function (#1830)
* Replace the old blockSubsidy parameters with the new ones.

* Return subsidyGenesisReward if blockHash is the genesis hash.

* Traverse a block's past for the subsidy calculation.

* Partially implement SubsidyStore.

* Refer to SubsidyStore from CoinbaseManager.

* Wrap calcBlockSubsidy in getBlockSubsidy, which first checks the database.

* Fix finalityStore not calling GenerateShardingID.

* Implement calculateAveragePastSubsidy.

* Implement calculateMergeSetSubsidySum.

* Implement calculateSubsidyRandomVariable.

* Implement calcBlockSubsidy.

* Add a TODO about floats.

* Update the calcBlockSubsidy TODO.

* Use binary.LittleEndian in calculateSubsidyRandomVariable.

* Fix bad range in calculateSubsidyRandomVariable.

* Replace float64 with big.Rat everywhere except for subsidyRandomVariable.

* Fix a nil dereference.

* Use a random walk to approximate the normal distribution.

* In order to avoid unsupported fractional results from powInt64, flip the numerator and the denominator manually.

* Set standardDeviation to 0.25, MaxSompi to 10_000_000_000 * SompiPerKaspa and defaultSubsidyGenesisReward to 1_000.

* Set the standard deviation to 0.2.

* Use a binomial distribution instead of trying to estimate the normal distribution.

* Change some values around.

* Clamp the block subsidy.

* Remove the fake duplicate constants in the util package.

* Reduce MaxSompi to only 100m Kaspa to avoid hitting the uint64 ceiling.

* Lower MaxSompi further to avoid new and exciting ways for the uint64 ceiling to be hit.

* Remove debug logs.

* Fix a couple of failing tests.

* Fix TestBlockWindow.

* Fix limitTransactionCount sometimes crashing on index-out-of-bounds.

* In TrustedDataDataDAABlock, replace BlockHeader with DomainBlock

* In calculateAveragePastSubsidy, use blockWindow instead of doing a BFS manually.

* Remove the reference to DAGTopologyManager in coinbaseManager.

* Add subsidy to the coinbase payload.

* Get rid of the subsidy store and extract subsidies out of coinbase transactions.

* Keep a blockWindow amount of blocks under the virtual for IBD purposes.

* Manually remove the virtual genesis from the merge set.

* Fix simnet genesis.

* Fix TestPruning.

* Fix TestCheckBlockIsNotPruned.

* Fix TestBlockWindow.

* Fix TestCalculateSignatureHashSchnorr.

* Fix TestCalculateSignatureHashECDSA.

* Fix serializing the wrong value into the coinbase payload.

* Rename coinbaseOutputForBlueBlock to coinbaseOutputAndSubsidyForBlueBlock.

* Add a TODO about optimizing trusted data DAA window blocks.

* Expand on a comment in TestCheckBlockIsNotPruned.

* In calcBlockSubsidy, divide the big.Int numerator by the big.Int denominator instead of converting to float64.

* Clarify a comment.

* Rename SubsidyMinGenesisReward to MinSubsidy.

* Properly handle trusted data blocks in calculateMergeSetSubsidySum.

* Use the first two bytes of the selected parent's hash for randomness instead of math/rand.

* Restore maxSompi to what it used to be.

* Fix TestPruning.

* Fix TestAmountCreation.

* Fix TestBlockWindow.

* Fix TestAmountUnitConversions.

* Increase the timeout in many-tips to 30 minutes.

* Check coinbase subsidy for every block

* Re-rename functions

* Use shift instead of powInt64 to determine subsidyRandom

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-10-30 10:16:47 +03:00
Ori Newman
1b9be28613 Improve ExpectedHeaderPruningPoint performance (#1833)
* Improve ExpectedHeaderPruningPoint perf

* Add suggestedLowHash to nextPruningPointAndCandidateByBlockHash
2021-10-26 11:01:26 +03:00
Ori Newman
5dbb1da84b Implement pruning point proof (#1832)
* Calculate GHOSTDAG, reachability etc for each level

* Don't preallocate cache for dag stores except level 0 and reduce the number of connections in the integration test to 32

* Reduce the number of connections in the integration test to 16

* Increase page file

* BuildPruningPointProof

* BuildPruningPointProof

* Add PruningProofManager

* Implement ApplyPruningPointProof

* Add prefix and fix blockAtDepth and fill headersByLevel

* Some bug fixes

* Include all relevant blocks for each level in the proof

* Fix syncAndValidatePruningPointProof to return the right block hash

* Fix block window

* Fix isAncestorOfPruningPoint

* Ban for rule errors on pruning proof

* Find common ancestor for blockAtDepthMAtNextLevel

* Use pruning proof in TestValidateAndInsertImportedPruningPoint

* stage status and finality point for proof blocks

* Uncomment golint

* Change test timeouts

* Calculate merge set for ApplyPruningPointProof

* Increase test timeout

* Add better caching for daa window store

* Return to default timeout

* Add ErrPruningProofMissesBlocksBelowPruningPoint

* Add errDAAWindowBlockNotFound

* Force connection loop next iteration on connection manager stop

* Revert to Test64IncomingConnections

* Remove BlockAtDepth from DAGTraversalManager

* numBullies->16

* Set page file size to 8gb

* Increase p2p max message size

* Test64IncomingConnections->Test16IncomingConnections

* Add comment for PruningProofM

* Add comment in `func (c *ConnectionManager) Stop()`

* Rename isAncestorOfPruningPoint->isAncestorOfSelectedTip

* Revert page file to 16gb

* Improve ExpectedHeaderPruningPoint perf

* Fix comment

* Revert "Improve ExpectedHeaderPruningPoint perf"

This reverts commit bca1080e71.

* Don't test windows
2021-10-26 09:48:27 +03:00
Ori Newman
afaac28da1 Validate each level parents (#1827)
* Create BlockParentBuilder.

* Implement BuildParents.

* Explictly set level 0 blocks to be the same as direct parents.

* Add checkIndirectParents to validateBlockHeaderInContext.

* Fix test_block_builder.go and BlockLevelParents::Equal.

* Don't check indirect parents for blocks with trusted data.

* Handle pruned blocks when building block level parents.

* Fix bad deletions from unprocessedXxxParents.

* Fix merge errors.

* Fix bad pruning point parent replaces.

* Fix duplicates in newBlockLevelParents.

* Skip checkIndirectParents

* Get rid of staging constant IDs

* Fix BuildParents

* Fix tests

* Add comments

* Change order of directParentHashes

* Get rid of maybeAddDirectParentParents

* Add comments

* Add blockToReferences type

* Use ParentsAtLevel

Co-authored-by: stasatdaglabs <stas@daglabs.com>
2021-09-13 14:22:00 +03:00
stasatdaglabs
0053ee788d Use the BlueWork declared in an orphan block's header instead of requesting it explicitly from the peer that sent us the orphan (#1828) 2021-09-13 13:13:03 +03:00
stasatdaglabs
af7e7de247 Add PruningPointProof to the P2P protocol (#1825)
* Add PruningPointProof to externalapi.

* Add BuildPruningPointProof and ValidatePruningPointProof to Consensus.

* Add the pruning point proof to the protocol.

* Add the pruning point proof to the wire package.

* Add PruningPointBlueWork.

* Make go vet happy.

* Properly initialize PruningPointProof in consensus.go.

* Validate pruning point blue work.

* Populate PruningPointBlueWork with the actual blue work of the pruning point.

* Revert "Populate PruningPointBlueWork with the actual blue work of the pruning point."

This reverts commit f2a9829998.

* Revert "Validate pruning point blue work."

This reverts commit c6a90c5d2c.

* Revert "Properly initialize PruningPointProof in consensus.go."

This reverts commit 9391574bbf.

* Revert "Add PruningPointBlueWork."

This reverts commit 48182f652a.

* Fix PruningPointProof and MsgPruningPointProof to be two-dimensional.

* Fix wire PruningPointProof to be two-dimensional.
2021-09-05 17:20:15 +03:00
Ori Newman
02a08902a7 Fix current pruning point index cache (#1824)
* Fix ps.currentPruningPointIndexCache

* Remove redundant dependency from block builder

* Fix typo
2021-09-05 07:37:25 +03:00
Ori Newman
d9bc94a2a8 Replace header finality point with pruning point and enforce finality rules on IBD with headers proof (#1823)
* Replace header finality point with pruning point

* Fix TestTransactionAcceptance

* Fix pruning candidate

* Store all past pruning points

* Pass pruning points on IBD

* Add blue score to block header

* Simplify ArePruningPointsInValidChain

* Fix static check errors

* Fix genesis

* Renames and text fixing

* Use ExpectedHeaderPruningPoint in block builder

* Fix TestCheckPruningPointViolation
2021-08-31 08:01:48 +03:00
stasatdaglabs
837dac68b5 Update block headers to include multiple levels of parent blocks (#1822)
* Replace the old parents in the block header with BlockLevelParents.

* Begin fixing compilation errors.

* Implement database serialization for block level parents.

* Implement p2p serialization for block level parents.

* Implement rpc serialization for block level parents.

* Add DirectParents() to the block header interface.

* Use DirectParents() instead of Parents() in some places.

* Revert test_block_builder.go.

* Add block level parents to hash serialization.

* Use the zero hash for genesis finality points.

* Fix failing tests.

* Fix a variable name.

* Update headerEstimatedSerializedSize.

* Add comments in blocklevelparents.go.

* Fix the rpc-stability stability test.

* Change the field number for `parents` fields in p2p.proto and rpc.proto.

* Remove MsgBlockHeader::NumParentBlocks.
2021-08-24 12:06:39 +03:00
Ori Newman
ba5880fab1 Fix pruning candidate (#1821) 2021-08-23 07:26:43 +03:00
stasatdaglabs
7b5720a155 Implement GHOST (#1819)
* Implement GHOST.

* Implement TestGHOST.

* Make GHOST() take arbitrary subDAGs.

* Hold RootHashes in SubDAG rather than one GenesisHash.

* Select which root the GHOST chain starts with instead of passing a lowHash.

* If two child hashes have the same future size, decide which one is larger using the block hash.

* Extract blockHashWithLargestFutureSize to a separate function.

* Calculate future size for each block individually.

* Make TestGHOST deterministic.

* Increase the timeout for connecting 128 connections in TestRPCMaxInboundConnections.

* Implement BenchmarkGHOST.

* Fix an infinite loop.

* Use much larger benchmark data.

* Optimize `futureSizes` using reverse merge sets.

* Temporarily make the benchmark data smaller while GHOST is being optimized.

* Fix a bug in futureSizes.

* Fix a bug in populateReverseMergeSet.

* Choose a selectedChild at random instead of the one with the largest reverse merge set size.

* Rename populateReverseMergeSet to calculateReverseMergeSet.

* Use reachability to resolve isDescendantOf.

* Extract heightMaps to a separate object.

* Iterate using height maps in futureSizes.

* Don't store reverse merge sets in memory.

* Change calculateReverseMergeSet to calculateReverseMergeSetSize.

* Fix bad initial reverseMergeSetSize.

* Optimize calculateReverseMergeSetSize.

* Enlarge the benchmark data to 86k blocks.
2021-08-19 13:59:43 +03:00
stasatdaglabs
65b5a080e4 Fix the RPCClient leaking connections (#1820)
* Fix the RPCClient leaking connections.

* Wrap the error return from GetInfo.
2021-08-16 15:59:35 +03:00
stasatdaglabs
ce17348175 Limit the amount of inbound RPC connections (#1818)
* Limit the amount of inbound RPC connections.

* Increment/decrement the right variable.

* Implement TestRPCMaxInboundConnections.

* Make go vet happy.

* Increase RPCMaxInboundConnections to 128.

* Set NUM_CLIENTS=128 in the rpc-idle-clients stability test.

* Explain why the P2P server has unlimited inbound connections.
2021-08-12 14:40:49 +03:00
stasatdaglabs
d922ee1be2 Add header commitments for DAA score, blue work, and finality points (#1817)
* Add DAAScore, BlueWork, and FinalityPoint to externalapi.BlockHeader.

* Add DAAScore, BlueWork, and FinalityPoint to NewImmutableBlockHeader and fix compilation errors.

* Add DAAScore, BlueWork, and FinalityPoint to protowire header types and fix failing tests.

* Check for header DAA score in validateDifficulty.

* Add DAA score to buildBlock.

* Fix failing tests.

* Add a blue work check in validateDifficultyDAAAndBlueWork.

* Add blue work to buildBlock and fix failing tests.

* Add finality point validation to ValidateHeaderInContext.

* Fix genesis blocks' finality points.

* Add finalityPoint to blockBuilder.

* Fix tests that failed due to missing reachability data.

* Make blockBuilder use VirtualFinalityPoint instead of directly calling FinalityPoint with the virtual hash.

* Don't validate the finality point for blocks with trusted data.

* Add debug logs.

* Skip finality point validation for block whose finality points are the virtual genesis.

* Revert "Add debug logs."

This reverts commit 3c18f519cc.

* Move checkDAAScore and checkBlueWork to validateBlockHeaderInContext.

* Add checkCoinbaseBlueScore to validateBodyInContext.

* Fix failing tests.

* Add DAAScore, blueWork, and finalityPoint to blocks' hashes.

* Generate new genesis blocks.

* Fix failing tests.

* In BuildUTXOInvalidBlock, get the bits from StageDAADataAndReturnRequiredDifficulty instead of calling RequiredDifficulty separately.
2021-08-12 13:25:00 +03:00
stasatdaglabs
4132891ac9 In calculateDiffBetweenPreviousAndCurrentPruningPoints, collect diffChild hashes instead of UTXODiffs to give the GC a chance to clean up UTXODiffs. (#1815)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-08-08 12:46:21 +03:00
stasatdaglabs
2094f4facf Decrease the size of the small chains in many-small-chains-and-one-big-chain.json, since the merge set size limit was reduced to k*10. (#1816) 2021-08-08 11:22:27 +03:00
stasatdaglabs
2de68f43f0 Use blockStatusStore instead of blockStore in missingBlockBodyHashes. (#1814) 2021-08-05 09:45:09 +03:00
Ori Newman
d748089a14 Update the virtual after overriding the virtual UTXO set (#1811)
* Update the virtual after overriding the virtual utxo set

* Put the updateVirtual inside importVirtualUTXOSetAndPruningPointUTXOSet

* Add pruningPoint to importVirtualUTXOSetAndPruningPointUTXOSet

* Remove sanity check
2021-08-02 17:02:15 +03:00
stasatdaglabs
7d1071a9b1 Update testnet version to testnet-6 (#1808)
* Update testnet version to testnet-6.

* Fix failing test.
2021-07-29 10:12:23 +03:00
Ori Newman
f26a7fdedf Return headers first (#1806)
* Return headers first

* Delete TestHandleRelayInvs

* resolve virtual only after IBD

* Fix ResolveVirtual

* Fix comments and variable names
2021-07-27 17:07:29 +03:00
Ori Newman
d207888b67 Implement pruned headers node (#1787)
* Pruning headers p2p basic structure

* Remove headers-first

* Fix consensus tests except TestValidateAndInsertPruningPointWithSideBlocks and TestValidateAndInsertImportedPruningPoint

* Add virtual genesis

* Implement PruningPointAndItsAnticoneWithMetaData

* Start fixing TestValidateAndInsertImportedPruningPoint

* Fix TestValidateAndInsertImportedPruningPoint

* Fix BlockWindow

* Update p2p and gRPC

* Fix all tests except TestHandleRelayInvs

* Delete TestHandleRelayInvs parts that cover the old IBD flow

* Fix lint errors

* Add p2p_request_ibd_blocks.go

* Clean code

* Make MsgBlockWithMetaData implement its own representation

* Remove redundant check if highest share block is below the pruning point

* Fix TestCheckLockTimeVerifyConditionedByAbsoluteTimeWithWrongLockTime

* Fix comments, errors ane names

* Fix window size to the real value

* Check reindex root after each block at TestUpdateReindexRoot

* Remove irrelevant check

* Renames and comments

* Remove redundant argument from sendGetBlockLocator

* Don't delete staging on non-recoverable errors

* Renames and comments

* Remove redundant code

* Commit changes inside ResolveVirtual

* Add comment to IsRecoverableError

* Remove blocksWithMetaDataGHOSTDAGDataStore

* Increase windows pagefile

* Move DeleteStagingConsensus outside of defer

* Get rid of mustAccepted in receiveBlockWithMetaData

* Ban on invalid pruning point

* Rename interface_datastructures_daawindowstore.go to interface_datastructures_blocks_with_meta_data_daa_window_store.go

* * Change GetVirtualSelectedParentChainFromBlockResponseMessage and VirtualSelectedParentChainChangedNotificationMessage to show only added block hashes
*  Remove ResolveVirtual
* Use externalapi.ConsensusWrapper inside MiningManager
* Fix pruningmanager.blockwithmetadata

* Set pruning point selected child when importing the pruning point UTXO set

* Change virtual genesis hash

* replace the selected parent with virtual genesis on removePrunedBlocksFromGHOSTDAGData

* Get rid of low hash in block locators

* Remove +1 from everywhere we use difficultyAdjustmentWindowSize and increase the default value by one

* Add comments about consensus wrapper

* Don't use separate staging area when resolving resolveBlockStatus

* Fix netsync stability test

* Fix checkResolveVirtual

* Rename ConsensusWrapper->ConsensusReference

* Get rid of blockHeapNode

* Add comment to defaultDifficultyAdjustmentWindowSize

* Add SelectedChild to DAGTraversalManager

* Remove redundant copy

* Rename blockWindowHeap->calculateBlockWindowHeap

* Move isVirtualGenesisOnlyParent to utils

* Change BlockWithMetaData->BlockWithTrustedData

* Get rid of maxReasonLength

* Split IBD to 100 blocks each time

* Fix a bug in calculateBlockWindowHeap

* Switch to trusted data when encountering virtual genesis in blockWithTrustedData

* Move ConsensusReference to domain

* Update ConsensusReference comment

* Add comment

* Rename shouldNotAddGenesis->skipAddingGenesis
2021-07-26 12:24:07 +03:00
stasatdaglabs
38e2ee1b43 Change the log level of the transaction propagation log from Info to Debug. (#1804) 2021-07-19 10:30:29 +03:00
talelbaz
aba44e7bfb Disable relative time lock by time (#1800)
* ignore type flag

* Ignore type flag of relative time lock - interpret as DAA score

* Split verifyLockTime to functions with and without threshold.relative lockTimes dont need threshold check

* Change function name and order of the functions calls

Co-authored-by: tal <tal@daglabs.com>
2021-07-18 17:52:16 +03:00
Constantine Bitensky
c731d74bc0 Replace queue by stack in GetRedeemer (#1802) 2021-07-15 15:02:06 +03:00
Svarog
60e7a8ebed Make transaction propagation much more frequent (#1799)
* Make transaction propagation much more frequent

* Update f.transactionIDsToPropagate after brodacasting
2021-07-14 16:06:24 +03:00
Svarog
369a3bac09 Limit block mass instead of merge set limit + Introduce SigOpCount to TransactionInput (#1790)
* Update constants

* Add to transaction SigOpCount

* Update mass calculation, and move it from InContext to InIsolation

* Update block validation accordingly

* Add SigOpCount validation during TransactionInContext

* Remove checking of mass vs maxMassAcceptedByBlock from consensusStateManager

* Update mining manager with latest changes

* Add SigOpCount to MsgTx.Copy()

* Fix initTestTransactionAcceptanceDataForClone

* Fix all tests in transaction_equal_clone_test.go

* Fix TestBlockMass

* Fix tests in transactionvalidator package

* Add SigOpCount to sighash

* Fix TestPruningDepth

* Fix problems in libkaspawalelt

* Fix integration tests

* Fix CalculateSignatureHash tests

* Remove remaining places talking about block size

* Add sanity check to checkBlockMass to make sure all transactions have their mass filled

* always add own sigOpCount to sigHash

* Update protowire/rpc.md

* Start working on removing any remaining reference to block/tx size

* Update rpc transaction verbose data to include mass rather then size

* Convert verboseData and block size check to mass

* Remove remaining usages of tx size in mempool

* Move transactionEstimatedSerializedSize to transactionvalidator

* Add PopulateMass to fakeRelayInvsContext

* Move PopulateMass to beggining of ValidateAndInsertTransaction + fix in it

* Assign mass a new number for backward-compatibility
2021-07-14 14:21:57 +03:00
talelbaz
8022e4cbea Validate locktime when admitted into mempool and when building a block. (#1794)
* Validate locktime when admitted into mempool and when build a block. Also, fix isFinalized to use DAAscore instead of blue score.

* Change the function name:ValidateTransactionInContextIgnoringUTXO

Co-authored-by: tal <tal@daglabs.com>
2021-07-14 11:00:03 +03:00
talelbaz
28ac77b202 Tests for timelock - check lock time verify (CLTV) (#1751)
* Create a file

* Add tests for lockTime - CLTV scripts conditioned by time and block height

* Add a handle for an unhandled error.

* Renamed the test file

* Fix typo

* Add a counter for current block height.

* Change variable name

* Adds a test for wrong lock time, removed fundingTransaction variable

* Fix LockTimeThreshold constant, fix opcodeCheckLockTimeVerify and opcodeCheckSequenceVerify(padding in the end), add support for sequence and lock time number in the script builder, add more checks to the CLTV test.

* Call AddData instead of addData. Rename fixedSize to unpaddedSize

* Creating wrapper functions to lockTime&sequence numbers that call to a shared function in script builder.

Co-authored-by: tal <tal@daglabs.com>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-07-08 18:09:45 +03:00
Constantine Bitensky
28af7eb596 Add stability-fast action to pull requests (#1791)
* Add stability-fast action to pull requests

* Add stability-fast action to pull requests

* Add stability-fast action to pull requests

* Add stability-fast action to pull requests

* Add stability-fast action to pull requests

* Add stability-fast action to pull requests

* Add stability-fast action to pull requests

* Add stability-fast action to pull requests

* Add stability-fast action to pull requests
2021-07-08 16:08:21 +03:00
stasatdaglabs
a4d241c30a Batch transaction inv messages (#1788)
* Implement EnqueueTransactionIDsForPropagation.

* Fix tests.

* Fix TxRelayTest.

* Add a log for transaction propagation.

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-07-07 17:54:57 +03:00
stasatdaglabs
487fab0e2b Implement a stability test to stress test the DAA algorithm (#1767)
* Copy over boilerplate and begin implementing TestDAA.

* Implement a fairly reliable method of hashing at a certain hashrate.

* Convert the DAA test to an application.

* Start kaspad and make sure that hashrate throttling works with that as well.

* Finish implementing testConstantHashRate.

* Tidied up a bit.

* Convert TestDAA back into a go test.

* Reorganize TestDAA to be more like a traditional test.

* Add sudden hashrate drop/jump tests.

* Simplify targetHashNanosecondsFunction.

* Improve progress logs.

* Add more tests.

* Remove the no-longer relevant `hashes` part of targetHashNanosecondsFunction.

* Implement a constant hashrate increase test.

* Implement a constant hashrate decrease test.

* Give the correct run duration to the constant hashrate decrease test.

* Add cooldowns to exponential functions.

* Add run.sh to the DAA test.

* Add a README.

* Add `daa` to run-slow.sh.

* Make go lint happy.

* Fix the README's title.

* Keep running tests even if one of them failed on high block rate deviation.

* Fix hashrate peak/valley tests.

* Preallocate arrays for hash and mining durations.

* Add more statistics to the "mined block" log.

* Make sure runDAATest stops when it's suppposed to.

* Add a newline after "5 minute cooldown."

* Fix variable names.

* Rename totalElapsedTime to tatalElapsedDuration.

* In measureMachineHashNanoseconds, generate a random nonce only once.

* In runDAATest, add "DAA" to the start/finish log.

* Remove --logdir from kaspadRunCommand.

* In runDAATest, enlarge the nonce range to the entirety of uint64.

* Explain what targetHashNanosecondsFunction is.

* Move RunKaspadForTesting into common.

* Rename runForDuration to loopForDuration.

* Make go lint happy.

* Extract fetchBlockForMining to a separate function.

* Extract waitUntilTargetHashDurationHadElapsed to a separate function.

* Extract pushHashDuration and pushMiningDuration to separate functions.

* Extract logMinedBlockStatsAndUpdateStatFields to a separate function.

* Extract submitMinedBlock to a separate function.

* Extract tryNonceForMiningAndIncrementNonce to a separate function.

* Add comments.

* Use a rolling average instead of appending to an array for performance/accuracy.

* Change a word in a comment.

* Explain why we wait for five minutes at the end of the exponential increase/decrease tests.

Co-authored-by: Svarog <feanorr@gmail.com>
2021-07-07 16:14:22 +03:00
stasatdaglabs
2f272cd517 Expire old transactions when both an amount of DAA and an amount of time had passed. (#1784)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-07-06 15:23:53 +03:00
Constantine Bitensky
e3a6d9e49a Added RPC connection server version checking, fixes https://github.com/kaspanet/kaspad/issues/1047 (#1783)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-07-06 15:10:35 +03:00
Svarog
069ee26e84 Adds name to route, and writes it in every error message (#1777)
* Adds name to route, and writes it in every error message

* Update all calls with route name

* Fixed a few missed points

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-07-04 14:40:27 +03:00
Svarog
61aa15fd61 Update lastRebroadcastTime when we are rebroadcasting + Add some logs to mempool (#1776)
* Update lastRebroadcastTime when we are rebroadcasting

* Add some logs to mempool

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-07-04 12:08:44 +03:00
Svarog
f7cce5cb39 Cache virtual past median time (#1775)
* Add cache for virtual pastMedianTime

* Implement InvalidateVirtualPastMedianTimeCache for mocPastMedianTimeManager
2021-07-04 11:47:43 +03:00
cbitensky
2f7a1395e7 Make use of maxBlocks instead of maxBlueScoreDifference in antiPastHashesBetween (#1772)
* Make use of maxBlocks instead of maxBlueScoreDifference in antiPastHashesBetween

* Make use of maxBlocks instead of maxBlueScoreDifference in antiPastHashesBetween

* Make use of maxBlocks instead of maxBlueScoreDifference in antiPastHashesBetween

* Make use of maxBlocks instead of maxBlueScoreDifference in antiPastHashesBetween

* Make use of maxBlocks instead of maxBlueScoreDifference in antiPastHashesBetween

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-06-30 17:21:22 +03:00
Svarog
8b1ac86532 Modify locktime thresholds to accomodate 64 bits and millisecond timestamps (#1770)
* Change SequenceLockTimeDisabled to 1 << 63

* Move LockTimeThreshold to constants

* Update locktime constants according to new proposal

* Fix opcodeCheckSequenceVerify and failed tests

* Disallow numbers above 8 bytes in makeScriptNum

* Use littleEndian.Uint64 for sequence instead of ScriptNum

* Update comments on constants

* Update some more comments
2021-06-30 10:57:09 +03:00
Svarog
ab721f3ad6 All orphans inputs should be added to op.orphansByPreviousOutpoint even if outpoint is not missing (#1766)
* All orphans inputs should be added to op.orphansByPreviousOutpoint even if outpoint is not missing

* Remove redundant log

* processOrphansAfterAcceptedTransaction: wqCheck that UTXOEntry is empty before filling it

* Don't remove redeemers in expireOrphanTransactions
2021-06-24 17:09:16 +03:00
Svarog
798c5fab7d Add allowOrphans to rpcclient.SubmitTransaction (#1765) 2021-06-24 15:23:10 +03:00
Svarog
c13a4d90ed Mempool redesign (#1752)
* Added model and stubs for all main methods

* Add constructors to all main objects

* Implement BlockCandidateTransactions

* implement expireOldTransactions and expireOrphanTransactions

* Rename isHighPriority to neverExpires

* Add stub for checkDoubleSpends

* Revert "Rename isHighPriority to neverExpires"

This reverts commit b2da9a4a00.

* Imeplement transactionsOrderedByFeeRate

* Orphan maps should be idToOrphan

* Add error.go to mempool

* Invert the condition for banning when mempool rejects a transaction

* Move all model objects to model package

* Implement getParentsInPool

* Implemented mempoolUTXOSet.addTransaction

* Implement removeTransaction, remove sanity checks

* Implemented mempoolUTXOSet.checkDoubleSpends

* Implemented removeOrphan

* Implement removeOrphan

* Implement maybeAddOrphan and AddOrphan

* Implemented processOrphansAfterAcceptedTransaction

* Implement transactionsPool.addTransaction

* Implement RemoveTransaction

* If a transaction was removed from the mempool - update it's redeemers in orphan pool as well

* Use maximumOrphanTransactionCount

* Add allowOrphans to ValidateAndInsertTransaction stub

* Implement validateTransaction functions

* Implement fillInputs

* Implement ValidateAndInsertTransaction

* Implement HandleNewBlockTransactions

* Implement missing mempool interface methods

* Add comments to exported functions

* Call ValidateTransactionInIsolation where needed

* Implement RevalidateHighPriorityTransactions

* Rewire kaspad to use new mempool, and fix compilation errors

* Update rebroadcast logic to use new structure

* Handle non-standard transaction errors properly

* Add mutex to mempool

* bugfix: GetTransaction panics when ok is false

* properly calculate targetBlocksPerSecond in config.go

* Fix various lint errors and tests

* Fix expected text in test for duplicate transactions

* Skip the coinbase transaction in HandleNewBlockTransactions

* Unorphan the correct transactions

* Call ValidateTransactionAndPopulateWithConsensusData on unorphanTransaction

* Re-apply policy_test as check_transactions_standard_test

* removeTransaction: Remove redeemers in orphan pool as well

* Remove redundant check for uint64 < 0

* Export and rename isDust -> IsTransactionOutputDust to allow usage by rothschild

* Add allowOrphan to SubmitTransaction RPC request

* Remove all implementation from mempool.go

* tidy go mod

* Don't pass acceptedOrphans to handleNewBlockTransactions

* Use t.Errorf in stead of t.Fatalf

* Remove minimum relay fee from TestDust, as it's no longer configurable

* Add separate VirtualDAASCore method for faster retrieval where it's repeated multiple times

* Broadcast all transactions that were accepted

* Don't re-use GetVirtualDAAScore in GetVirtualInfo - this causes a deadlock

* Use real transaction count, and not Orphan

* Get mempool config from outside, incorporating values received from cli

* Use MinRelayFee and MaxOrphanTxs from global kaspad config

* Add explanation for the seemingly redundant check for transaction version in checkTransactionStandard

* Update some comment

* Convert creation of acceptedTransactions to a single line

* Move mempoolUTXOSet out of checkDoubleSpends

* Add test for attempt to insert double spend into mempool

* fillInputs: Skip check for coinbase - it's always false in mempool

* Clarify comment about removeRedeemers when removing random orphan

* Don't remove high-priority transactions in limitTransactionCount

* Use mempool.removeTransaction in limitTransactionCount

* Add mutex comment to handleNewBlockTransactions

* Return error from limitTransactionCount

* Pluralize the map types

* mempoolUTXOSet.removeTransaction: Don't restore utxo if it was not created in mempool

* Don't evacuate from orphanPool high-priority transactions

* Disallow double-spends in orphan pool

* Don't use exported (and locking) methods from inside mempool

* Check for double spends in mempool during revalidateTransaction

* Add checkOrphanDuplicate

* Add orphan to acceptedOrphans, not current

* Add TestHighPriorityTransactions

* Fix off-by-one error in limitTransactionCount

* Add TestRevalidateHighPriorityTransactions

* Remove checkDoubleSpends from revalidateTransaction

* Fix TestRevalidateHighPriorityTransactions

* Move check for MaximumOrphanCount to beggining of maybeAddOrphan

* Rename all map type to singulateToSingularMap

* limitOrphanPool only after the orphan was added

* TestDoubleSpendInMempool: use createChildTxWhenParentTxWasAddedByConsensus instead of createTransactionWithUTXOEntry

* Fix some comments

* Have separate min/max transaction versions for mempool

* Add comment on defaultMaximumOrphanTransactionCount to keep it small as long as we have recursion

* Fix comment

* Rename: createChildTxWhenParentTxWasAddedByConsensus -> createChildTxWhereParentTxWasAddedByConsensus

* Handle error from createChildTxWhereParentTxWasAddedByConsensus

* Rename createChildTxWhereParentTxWasAddedByConsensus -> createChildAndParentTxsAndAddParentToConsensus

* Convert all MaximumXXX constants to uint64

* Add comment

* remove mutex comments
2021-06-23 15:49:20 +03:00
Constantine Bitensky
4ba8b14675 Make GetVirtualSelectedParentBlueScore work properly (#1764) 2021-06-21 15:56:37 +03:00
Constantine Bitensky
319cbce768 Friendly error messages for ban and unban with ip with brackets (#1762) 2021-06-21 11:42:45 +03:00
Constantine Bitensky
bdd42903b4 Remove NOP1..10 (#1761) 2021-06-20 16:52:12 +03:00
Svarog
9bedf84740 kaspawallet: Add timeout to connect to daemon, and print friendly error (#1756)
message if it's not available
2021-06-16 15:05:19 +03:00
Svarog
f317f51cdd Change IBD finished log to specify if completed succesfully or not (#1754)
* Change IBD finished log to specify if complete succesfully or not

* Move log to outside UnsetIBDRunning

* Style inhancement of IBD finished string
2021-06-16 11:13:29 +03:00
Ori Newman
4207c82f5a Add database prefix (#1750)
* Add prefix to stores

* Add prefix to forgotten stores

* Add a special type for prefix

* Rename transaction->dbTx

* Change error message

* Use countKeyName

* Rename Temporary Consesnsus to Staging

* Add DeleteStagingConsensus to Domain interface

* Add lock to staging consensus

* Make prefix type-safer

* Use ioutil.TempDir instead of t.TempDir
2021-06-15 17:47:17 +03:00
Constantine Bitensky
70399dae2a Added a friendly error message when genesis hash is not relevant to database (#1745)
Co-authored-by: Constantine Bitensky <constantinebitensky@gmail.com>
Co-authored-by: Svarog <feanorr@gmail.com>
2021-06-13 11:36:47 +03:00
Constantine Bitensky
2ae1b7853f Added comment to database lock error (#1746)
More readable database lock error string

Co-authored-by: Constantine Bitensky <constantinebitensky@gmail.com>
Co-authored-by: Svarog <feanorr@gmail.com>
2021-06-10 19:49:08 +03:00
Constantine Bitensky
d53d040bee Add .github/workflows/stability-fast.yml to run stability test (#1744)
* Added .github/stability-fast.yml

Co-authored-by: Constantine Bitensky <constantine@daglabs.com>
Co-authored-by: Svarog <feanorr@gmail.com>
2021-06-09 15:11:56 +03:00
Constantine Bitensky
79c74c482b Get connections from Seeder when no connections left (#1742)
Co-authored-by: Constantine Bitensky <constantinebitensky@gmail.com>
2021-06-08 17:42:13 +03:00
Ori Newman
3b0394eefe Skip solving the block if SkipProofOfWork (#1741) 2021-06-08 15:44:27 +03:00
tal
43e6467ff1 Fix merge errors 2021-06-06 17:00:29 +03:00
stasatdaglabs
363494ef7a Implement NotifyVirtualDaaScoreChanged (#1737)
* Add notifyVirtualDaaScoreChanged to protowire.

* Add notifyVirtualDaaScoreChanged to the rest of kaspad.

* Add notifyVirtualDaaScoreChanged to the rest of kaspad.

* Test the DAA score notification in TestVirtualSelectedParentBlueScore.

* Rename TestVirtualSelectedParentBlueScore to TestVirtualSelectedParentBlueScoreAndVirtualDAAScore.

(cherry picked from commit 83e631548f)
2021-06-06 16:46:02 +03:00
cbitensky
d1df97c4c5 added --password and --yes cmdline parameters (#1735)
* added --password and --yes cmdline parameters

* Renamed:
confPassword -> cmdLinePassword
yes -> forceOverride

Added password in ImportMnemonics

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-06-01 15:36:18 +03:00
Svarog
4f52a6de51 Check if err != nil returned from ConnectionManager.Ban() (#1736) 2021-05-31 10:50:12 +03:00
Svarog
4f4a8934e7 Add option to specify blockHash in EstimateNetworkHashesPerSecond (#1731)
* Add BlockHash optional parameter to EstimateNetworkBlockHashesPerSecond

* Allow to pass '-' for optional values in kaspactl

* Solve a division-by-zero in estimateNetworkHashesPerSecond

* Add BlockHash to toAppMessage/fromAppMessage functions

* Rename: topHash -> StartHash

* Return proper error message if provided startHash doesn't deserialize into a hash
2021-05-27 14:59:29 +03:00
Svarog
16ba2bd312 Export DefaultPath + Add logging to kaspawallet daemon (#1730)
* Export DefaultPath + Add logging to kaspawallet daemon

* Export purpose and CoinType instead of defaultPath

* Move TODO to correct place
2021-05-26 18:51:11 +03:00
Svarog
6613faee2d Invert coin-type and purpose in default derivation path (#1728) 2021-05-20 17:43:07 +03:00
Ori Newman
edc459ae1b Improve pickVirtualParents performance and add many-tips to the stability tests suite (#1725)
* First limit the candidates size to 3*csm.maxBlockParents before taking the bottom csm.maxBlockParents/2

* Change log level of printing all tips to Tracef

* Add many-tips to run-fast.sh and run-slow.sh

* Fix preallocation size

* Assign intermediate variables
2021-05-19 16:06:52 +03:00
talelbaz
d7f2cf81c0 Change merge set order to topological order (#1654)
* Change mergeSet to be ordered topologically.

* Add special condition for genesis.

* Add check that the coinbase is validated.

* Change names of variables(old: chainHash, blueHash).

* Fix the DAG diagram in the comment above the function.

* Fix variables names.

Co-authored-by: tal <tal@daglabs.com>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-05-19 14:40:55 +03:00
Ori Newman
4658f9d05c Implement BIP 39 and HD wallet features (#1705)
* Naive bip39 with address reuse

* Avoid address reuse in libkaspawallet

* Add wallet daemon

* Use daemon everywhere

* Add forceOverride

* Make CreateUnsignedTransaction endpoint receive amount in sompis

* Collect close UTXOs

* Filter out non-spendable UTXOs from selectUTXOs

* Use different paths for multisig and non multisig

* Fix tests to use non zero path

* Fix multisig cosigner index detection

* Add comments

* Fix dump_unencrypted_data.go according to bip39 and bip32

* Fix wrong derivation path for multisig on wallet creation

* Remove IsSynced endpoint and add validation if wallet is synced for the relevant endpoints

* Rename server address to daemon address

* Fix capacity for extendedPublicKeys

* Use ReadBytes instead of ReadLine

* Add validation when importing

* Increment before using index value, and use it as is

* Save keys file exactly where needed

* Use %+v printErrorAndExit

* Remove redundant consts

* Rnemae collectCloseUTXOs and collectFarUTXOs

* Move typedefs around

* Add comment to addressesToQuery

* Update collectUTXOsFromRecentAddresses comment about locks

* Split collectUTXOs to small functions

* Add sanity check

* Add addEntryToUTXOSet function

* Change validateIsSynced to isSynced

* Simplify createKeyPairsFromFunction logic

* Rename .Sync() to .Save()

* Fix typo

* Create bip39BitSize const

* Add consts to purposes

* Add multisig check for 'send'

* Rename updatedPSTxBytes to partiallySignedTransaction

* Change collectUTXOsFromFarAddresses's comment

* Use setters for last used indexes

* Don't use the pstx acronym

* Fix SetPath

* Remove spaces when reading lines

* Fix walletserver to daemonaddress

* Fix isUTXOSpendable to use DAA score

Co-authored-by: Svarog <feanorr@gmail.com>
2021-05-19 10:03:23 +03:00
Ori Newman
010df3b0d3 Rename IncludeTransactionVerboseData flag to IncludeTransactions (#1717)
* Rename IncludeTransactionVerboseData flag to IncludeTransactions

* Regenerate auto-generated files
2021-05-18 17:40:06 +03:00
stasatdaglabs
346598e67f Fix merge errors. 2021-05-18 17:09:11 +03:00
Ori Newman
268906a7ce Add VirtualDaaScore to GetBlockDagInfo (#1719)
Co-authored-by: Svarog <feanorr@gmail.com>

(cherry picked from commit 36c56f73bf)
2021-05-18 17:07:07 +03:00
stasatdaglabs
befc60b185 Update changelog.txt for v0.10.2.
(cherry picked from commit 91866dd61c)
2021-05-18 16:37:10 +03:00
Ori Newman
dd3e04e671 Fix overflow when checking coinbase maturity and don't ban peers that send transactions with immature spend (#1722)
* Fix overflow when checking coinbase maturity and don't ban peers that send transactions with immature spend

* Fix tests

Co-authored-by: Svarog <feanorr@gmail.com>
(cherry picked from commit a18f2f8802)
2021-05-18 16:33:29 +03:00
stasatdaglabs
9c743db4d6 Fix merge errors. 2021-05-18 16:33:01 +03:00
Ori Newman
eb3dba5c88 Fix calcTxSequenceLockFromReferencedUTXOEntries for loop break condition (#1723)
Co-authored-by: Svarog <feanorr@gmail.com>
(cherry picked from commit 04dc1947ff)
2021-05-18 16:30:26 +03:00
stasatdaglabs
e46e2580b1 Add VirtualDaaScore to GetBlockDagInfo (#1719)
Co-authored-by: Svarog <feanorr@gmail.com>
(cherry picked from commit 36c56f73bf)

# Conflicts:
#	infrastructure/network/netadapter/server/grpcserver/protowire/rpc.pb.go
2021-05-18 16:28:57 +03:00
Ori Newman
414f58fb90 serializeAddress should always serialize as IPv6, since it assumes the IP size is 16 bytes (#1720)
(cherry picked from commit b76ca41109)
2021-05-18 16:05:36 +03:00
Ori Newman
9df80957b1 Fix getBlock and getBlocks RPC commands to return blocks and transactions properly (#1716)
* Fix getBlock RPC command to return transactions

* Fix getBlocks RPC command to return transactions and blocks

* Add GetBlockEvenIfHeaderOnly and use it for getBlock and getBlocks

* Implement GetBlockEvenIfHeaderOnly for fakeRelayInvsContext

* Use less nested code

(cherry picked from commit 50fd86e287)
2021-05-13 16:00:42 +03:00
stasatdaglabs
268c9fa83c Update changelog for v0.10.1.
(cherry picked from commit 9e0b50c0dd)
2021-05-11 12:14:04 +03:00
Ori Newman
2e3592e351 Calculate virtual's acceptance data and multiset after importing a new pruning point (#1700)
(cherry picked from commit b405ea50e5)
2021-05-11 12:14:00 +03:00
talelbaz
19718ac102 Change removeTransactionAndItsChainedTransactions to be non-recursive (#1696)
* Change removeTransactionAndItsChainedTransactions to be non-recursive

* Split the variables assigning.

* Change names of function and variables.

* Append the correct queue.

Co-authored-by: tal <tal@daglabs.com>
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-05-10 15:21:48 +03:00
talelbaz
28a8e96e65 New stability test - many tips (#1694)
* Unfinished code.

* Update the testnet version to testnet-5. (#1683)

* Generalize stability-tests/docker/Dockerfile. (#1685)

* Committed for rebasing.

* Adds stability-test many-tips, which tests kaspad handling with many tips in the DAG.

* Delete manytips_test.go.

* Add timeout to the test and create only one RPC client.

* Place the spawn before the for loop and remove a redundant condition.

Co-authored-by: tal <tal@daglabs.com>
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-05-10 15:03:20 +03:00
Ori Newman
4df283934a Add a link to the kaspanet github project in the README (#1698)
* Add link to project

* Fix README.md
2021-05-04 11:56:51 +03:00
talelbaz
ab89efe3dc Update relayTransactions unit tests. (#1623)
* [NOD-1344] relaytransactions: simple unit tests

* [NOD-1344]  Add mid-complexity unit tests for relaytransactions
* Improve TestHandleRelayedTransactionssub tests
* Improve TestHandleRequestedTransactions sub tests

* [NOD-1344]  Fix Simple call test

* [NOD-1344]  Fix tests after redesign

* Divide transactionrelay_test.go to 2 separated tests and updates the tests.

* Changes due to review:change the test files name and the test function names, adds new comments and fix typo.

* Delete an unnecessary comparison to True in the if statement condition.

* Update the branch to v0.11.0-dev.

Co-authored-by: karim1king <karimkaspersky@yahoo.com>
Co-authored-by: tal <tal@daglabs.com>
Co-authored-by: Svarog <feanorr@gmail.com>
2021-05-02 16:16:57 +03:00
Ori Newman
fa16c30cf3 Implement bip32 (#1676)
* Implement bip32

* Unite private and public extended keys

* Change variable names

* Change test name and add comment

* Rename var name

* Rename ckd.go to child_key_derivation.go

* Rename ser32 -> serializeUint32

* Add PrivateKey method

* Rename Path -> DeriveFromPath

* Add comment to validateChecksum

* Remove redundant condition from parsePath

* Rename Fingerprint->ParentFingerprint

* Merge hardened and non-hardened paths in calcI

* Change fingerPrintFromPoint to method

* Move hash160 to hash.go

* Fix a bug in calcI

* Simplify doubleSha256

* Remove slice end bound

* Split long line

* Change KaspaMainnetPrivate/public to represent kprv/kpub

* Add comments

* Fix comment

* Copy base58 library to kaspad

* Add versions for all networks

* Change versions to hex

* Add comments

Co-authored-by: Svarog <feanorr@gmail.com>
Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
2021-04-28 15:27:16 +03:00
stasatdaglabs
c28366eb50 Add v0.10.0 to the changelog. (#1692)
(cherry picked from commit 9dd8136e4b)
2021-04-26 15:12:50 +03:00
stasatdaglabs
dc0bf56bf3 Fix the mempool-limits stability test (#1690)
* Add -v to the `go test` command.

* Generate a new keypair for mempool-limits.

* Set mempool-limits to time out only after 24 hours.

(cherry picked from commit eb1703b948)
2021-04-26 15:12:46 +03:00
stasatdaglabs
91de1807ad Generalize stability-tests/docker/Dockerfile. (#1685)
(cherry picked from commit a6da3251d0)
2021-04-26 15:12:44 +03:00
stasatdaglabs
830684167c Update the testnet version to testnet-5. (#1683)
(cherry picked from commit bf198948c4)
2021-04-26 15:12:41 +03:00
stasatdaglabs
1f56a68a28 Add an RPC command: EstimateNetworkHashesPerSecond (#1686)
* Implement EstimateNetworkHashesPerSecond.

* Fix failing tests.

* Add request/response messages to the .proto files.

* Add the EstimateNetworkHashesPerSecond RPC command.

* Add the EstimateNetworkHashesPerSecond RPC client function.

* Add the EstimateNetworkHashesPerSecond RPC command to kaspactl.

* Disallow windowSize lesser than 2.

* Fix wrong scale (milliseconds instead of seconds).

* Handle windowHashes being 0.
2021-04-22 15:18:21 +03:00
stasatdaglabs
13a6b4cc51 Update to version 0.11.0 2021-04-20 13:40:11 +03:00
Svarog
dfd8b3423d Implement new mechanism for updating UTXO Diffs (#1671)
* Use selectedParent instead of selectedTip for non-selectedTip blocks in restoreSingleBlockStatus

* Cache the selectedParent for re-use in a resolveSingleBlockStatus chain

* Implement and use reverseUTXOSet

* Reverse blocks in correct order

* Support resolveBlockStatus without separate stagingAreas for usage of testConsensus

* Handle the case where the tip of the resolved block is not the next selectedTip

* Unify isResolveTip

* Some minor fixes and cleanup

* Add full finality window re-org test to stability-slow

* rename: useSeparateStagingAreasPerBlock -> useSeparateStagingAreaPerBlock

* Better logs in resolveSingleBlockStatus

* A few retouches to reverseUTXODiffs

* TEMPORARY COMMIT: EXTRAT ALL DIFFFROMS TO SEPARATE METHODS

* TEMPORARY COMMIT: REMOVE DIFFICULTY CHECKS IN DEVNET

* Don't pre-allocate in utxo-algebra, since the numbers are not known ahead-of-time

* Add some logs to reverseUTXODiffs

* Revert "TEMPORARY COMMIT: REMOVE DIFFICULTY CHECKS IN DEVNET"

This reverts commit c0af9dc6ad.

* Revert "TEMPORARY COMMIT: EXTRAT ALL DIFFFROMS TO SEPARATE METHODS"

This reverts commit 4fcca1b48c.

* Remove redundant paranthesis

* Revise some logs messages

* Rename:oneBlockBeforeCurrentUTXOSet -> lastResolvedBlockUTXOSet

* Don't break if the block was resolved as invalid

* rename unverifiedBlocks to recentlyVerifiedBlcks in reverseUTXODiffs

* Add errors.New to the panic, for a stack trace

* Reverse the UTXODiffs after the main block has been commited

* Use the correct value for previousUTXODiff

* Add test for ReverseUTXODiff

* Fix some names and comments

* Update TestReverseUTXODiffs to use consensus.Config

* Fix comments mentioning 'oneBlockBeforeTip'
2021-04-20 10:26:55 +03:00
Svarog
28bfc0fb9c Move pow package from model to utils (#1681) 2021-04-19 15:35:36 +03:00
Elichai Turkel
83beae4463 Add consensus.Config as a wrapper for dagParams (#1680)
* Add a new consensus.Config wrapper to dagParams

* Update all tests to use consensus.Config
2021-04-19 09:07:34 +03:00
Elichai Turkel
a6ebe83198 Disable validate commitment unless explictly requested (#1679)
* Add a flag for sanity check pruning point utxo set and do the sanity check only if it's enabled

* add description to EnableSanityCheckPruningUTXOSet

* review fix

Co-authored-by: Svarog <feanorr@gmail.com>
2021-04-18 17:55:17 +03:00
Svarog
acdc59b565 Add version file to database (#1678)
* Add version file to database

* Remove redundant code

* Check for version before opening the database, create version file after

* Create version file before opening the database
2021-04-14 12:35:39 +03:00
stasatdaglabs
15811b0bcb Fix missing VerboseData in BlockAddedNotifications. (#1675)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
Co-authored-by: Svarog <feanorr@gmail.com>
2021-04-13 11:35:06 +03:00
Svarog
a8a7e3dd9b Add windows to the CI + fix errors when testing on Windows (#1674)
* Add windows to the CI

* Cast syscall.Stdin into an integer

* DataDir -> AppDir in service_windows.go

* Rename mempool-limits package to something non-main

* Close database after re-assigining to it

* Up rpcTimout to 10 seconds
2021-04-12 14:53:34 +03:00
Svarog
3f193e9219 Use a separate folder for every network under ~/.kaspawallet (#1673) 2021-04-11 18:07:21 +03:00
stasatdaglabs
dfa24d8353 Implement a stability test for mempool limits (#1647)
* Copy some boilerplate from the other stability tests.

* Fix a copy+paste error in run.sh.

* Copy over some stability test boilerplate go code.

* Run kaspad in the background.

* Catch panics and initialize the RPC client.

* Mine enough blocks to fund filling up the mempool.

* Extract coinbase transactions out of the generated blocks.

* Tidy up a bit.

* Implement submitting transactions.

* Lower the amount of outputs in each transaction.

* Verify that the mempool size has the expected amount of transactions.

* Pregenerate enough funds before submitting the first transaction so that block creation doesn't interfere with the test.

* Empty mempool out by continuously adding blocks to the DAG.

* Handle orphan transactions when overfilling the mempool.

* Increase mempoolSizeLimit to 1m.

* Fix a comment.

* Fix a comment.

* Add mempool-limits to run-slow.sh.

* Rename generateTransactionsWithLotsOfOutputs to generateTransactionsWithMultipleOutputs.

* Rename generateCoinbaseTransaction to mineBlockAndGetCoinbaseTransaction.

* Make generateFundingCoinbaseTransactions return an object instead of store a global variable.

* Convert mempool-limits into a Go test.

* Convert panics to t.Fatalfs.

* Fix a comment.

* Increase mempoolSizeLimit to 1m.

* Run TestMempoolLimits only if RUN_STABILITY_TESTS is set.

* Move the run of mempool-limits in run-slow.sh.

* Add a comment above fundingCoinbaseTransactions.

* Make a couple of stylistic changes.

* Use transactionhelper.CoinbaseTransactionIndex instead of hardcoding 0.

* Make uninteresting errors print %+v instead of %s.

Co-authored-by: Svarog <feanorr@gmail.com>
2021-04-11 16:59:11 +03:00
Elichai Turkel
3c3ad1425d Make moving the pruning point faster (#1660)
* Add oldPruningPoint to pruningStore

* Make the pruning store work with utxo diff and return an iterator over pruning point utxoset

* Redesign pruning point utxo storage by creating a diff and modifying the old pruning utxo set

* Fix review comments

* Rename updatePruningPointUTXOSet
2021-04-11 11:17:13 +03:00
Svarog
9bb8123391 Don't include selectedParentHash in block verbose data if it's nil + Fix test vectors in rpc-stability (#1668)
* Fix submitBlockRequest in rpc-stability/commands.json

* Don't include selectedParentHash in block verbose data if it's nil (a.k.a. genesis)
2021-04-08 15:34:10 +03:00
Svarog
347dd8fc4b Support resolveBlockStatus without separate stagingAreas for usage of testConsensus (#1666) 2021-04-08 11:26:17 +03:00
Ori Newman
d2cccd2829 Add ECDSA support to the wallet (#1664)
* Add ECDSA support to the wallet

* Fix genkeypair

* Fix typo and rename var
2021-04-06 17:25:09 +03:00
Ori Newman
7186f83095 Add OpCheckMultiSigECDSA (#1663)
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-04-06 16:29:16 +03:00
Ori Newman
5c394c2951 Add PubKeyECDSATy (#1662) 2021-04-06 15:56:31 +03:00
Ori Newman
a786cdc15e Add ECDSA support (#1657)
* Add ECDSA support

* Add domain separation to ECDSA sighash

* Use InfallibleWrite instead of Write

* Rename funcs

* Fix wrong use if vm.sigCache

* Add TestCalculateSignatureHashECDSA

* Add consts

* Fix comment and test name

* Move consts to the top

* Fix comment
2021-04-06 14:27:18 +03:00
Ori Newman
6dd3d4a9e7 Add dump unencrypted data sub command to the wallet (#1661) 2021-04-06 12:29:13 +03:00
stasatdaglabs
73b36f12f0 Implement importing private keys into the wallet (#1655)
* Implement importing private keys into the wallet.

* Fix bad --import default.

* Fix typo in --import annotation.

* Make go lint happy.

* Make go lint happier.

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-04-05 18:10:33 +03:00
stasatdaglabs
a795a9e619 Add a size limit to the address manager (#1652)
* Remove a random address from the address manager if it's full.

* Implement TestOverfillAddressManager.

* Add connectionFailedCount to addresses.

* Mark connection failures.

* Mark connection successes.

* Implement removing by most connection failures.

* Expand TestOverfillAddressManager.

* Add comments.

* Use a better method for finding the address with the greatest connectionFailedCount.

* Fix a comment.

* Compare addresses by IP in TestOverfillAddressManager.

* Add a comment for updateNotBanned.

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-04-05 17:56:13 +03:00
Ori Newman
0be1bba408 Fix TestAddresses (#1656) 2021-04-05 16:24:22 +03:00
Ori Newman
6afc06ce58 Replace p2pkh with p2pk (#1650)
* Replace p2pkh with p2pk

* Fix tests

* Fix comments and variable names

* Add README.md for genkeypair

* Rename pubkey->publicKey

* Rename p2pkh to p2pk

* Use util.PublicKeySize where needed

* Remove redundant pointer

* Fix comment

* Rename pubKey->publicKey
2021-04-05 14:35:34 +03:00
stasatdaglabs
d01a213f3d Add a show-address subcommand to kaspawallet (#1653)
* Add a show-address subcommand to kaspawallet.

* Update the description of the key-file command line parameter.
2021-04-05 14:22:03 +03:00
stasatdaglabs
7ad8ce521c Implement reconnection logic within the RPC client (#1643)
* Add a reconnect mechanism to RPCClient.

* Fix Reconnect().

* Connect the internal reconnection logic to the miner reconnection logic.

* Rename shouldReconnect to isClosed.

* Move safe reconnection logic from the miner to rpcclient.

* Remove sleep from HandleSubmitBlock.

* Properly handle client errors and only disconnect if we're already connected.

* Make go lint happy.

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-04-05 13:57:28 +03:00
Ori Newman
86ba80a091 Improve wallet functionality (#1636)
* Add basic wallet library

* Add CLI

* Add multisig support

* Add persistence to wallet

* Add tests

* go mod tidy

* Fix lint errors

* Fix wallet send command

* Always use the password as byte slice

* Remove redundant empty string

* Use different salt per private key

* Don't sign a signed transaction

* Add comment

* Remove old wallet

* Change directory permissions

* Use NormalizeRPCServerAddress

* Fix compilation errors
2021-03-31 15:58:22 +03:00
Ori Newman
088e2114c2 Disconnect from RPC client after finishing the simple sync test (#1641) 2021-03-31 13:44:42 +03:00
stasatdaglabs
2854d91688 Add missing call to broadcastTransactionsAfterBlockAdded (#1639)
* Add missing call to broadcastTransactionsAfterBlockAdded.

* Fix a comment.

* Fix a comment some more.

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-03-31 10:28:02 +03:00
Ori Newman
af10b59181 Use go-secp256k1 v0.0.5 (#1640) 2021-03-30 18:01:56 +03:00
stasatdaglabs
c5b0394bbc In RPC, use RPCTransactions and RPCBlocks instead of TransactionMessages and BlockMessages (#1609)
* Replace BlockMessage with RpcBlock in rpc.proto.

* Convert everything in kaspad to use RPCBlocks and fix tests.

* Fix compilation errors in stability tests and the miner.

* Update TransactionVerboseData in rpc.proto.

* Update TransactionVerboseData in the rest of kaspad.

* Make golint happy.

* Include RpcTransactionVerboseData in RpcTransaction instead of the other way around.

* Regenerate rpc.pb.go after merge.

* Update appmessage types.

* Update appmessage request and response types.

* Reimplement conversion functions between appmessage.RPCTransaction and protowire.RpcTransaction.

* Extract RpcBlockHeader toAppMessage/fromAppMessage out of RpcBlock.

* Fix compilation errors in getBlock, getBlocks, and submitBlock.

* Fix compilation errors in getMempoolEntry.

* Fix compilation errors in notifyBlockAdded.

* Update verbosedata.go.

* Fix compilation errors in getBlock and getBlocks.

* Fix compilation errors in getBlocks tests.

* Fix conversions between getBlocks message types.

* Fix integration tests.

* Fix a comment.

* Add selectedParent to the verbose block response.
2021-03-30 17:43:02 +03:00
Ori Newman
9266d179a9 Add a test with two signed inputs (#1628)
* Add TestSigningTwoInputs

* Rename fundingBlockHash to block1Hash

* Fix error message

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-03-30 16:54:54 +03:00
Ori Newman
321792778e Add mass limit to mempool (#1627)
* Add mass limit to mempool

* Pass only params instead of multiple configuration options

* Remove acceptNonStd from mempool constructor

* Remove acceptNonStd from mempool constructor

* Fix test compilation
2021-03-30 15:37:56 +03:00
talelbaz
70f3fa9893 Update miningManager test (#1593)
* [NOD-1429] add mining manager unit tests

* [NOD-1429] Add additional test

* found a bug, so stopped working on this test until the bug will be fix.

* Update miningmanager_test.go test.

* Delete payloadHash field - not used anymore in the current version.

* Change the condition for comparing slices instead of pointers.

* Fix due to review notes - change names, use testutils.CreateTransaction function and adds comments.

* Changes after fetch&merge to v0.10.0-dev

* Create a new function createChildTxWhenParentTxWasAddedByConsensus and add a comment

* Add an argument to create_transaction function and fix review notes

* Optimization

* Change to blockID(instead of the all transaction) in the error messages and fix review notes

* Change to blockID(instead of the all transaction) in the error messages and fix review notes

* Change format of error messages.

* Change name ofa variable

* Use go:embed to embed sample-kaspad.conf (only on go1.16)

* Revert "Use go:embed to embed sample-kaspad.conf (only on go1.16)"

This reverts commit bd28052b92.

Co-authored-by: karim1king <karimkaspersky@yahoo.com>
Co-authored-by: tal <tal@daglabs.com>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-03-30 13:52:40 +03:00
Svarog
4e18031483 Resolve each block status in it's own staging area (#1634) 2021-03-30 11:04:43 +03:00
Svarog
2abc284e3b Make sure the ghostdagDataStore cache is at least DifficultyAdjustmentBlockWindow sized (#1635) 2021-03-29 14:38:19 +03:00
Svarog
f1451406f7 Add support for multiple staging areas (#1633)
* Add StagingArea struct

* Implemented staging areas in blockStore

* Move blockStagingShard to separate folder

* Apply staging shard to acceptanceDataStore

* Update blockHeaderStore with StagingArea

* Add StagingArea to BlockRelationStore

* Add StagingArea to blockStatusStore

* Add StagingArea to consensusStateStore

* Add StagingArea to daaBlocksStore

* Add StagingArea to finalityStore

* Add StagingArea to ghostdagDataStore

* Add StagingArea to headersSelectedChainStore and headersSelectedTipStore

* Add StagingArea to multisetStore

* Add StagingArea to pruningStore

* Add StagingArea to reachabilityDataStore

* Add StagingArea to utxoDiffStore

* Fix forgotten compilation error

* Update reachability manager and some more things with StagingArea

* Add StagingArea to dagTopologyManager, and some more

* Add StagingArea to GHOSTDAGManager, and some more

* Add StagingArea to difficultyManager, and some more

* Add StagingArea to dagTraversalManager, and some more

* Add StagingArea to headerTipsManager, and some more

* Add StagingArea to constnsusStateManager, pastMedianTimeManager

* Add StagingArea to transactionValidator

* Add StagingArea to finalityManager

* Add StagingArea to mergeDepthManager

* Add StagingArea to pruningManager

* Add StagingArea to rest of ValidateAndInsertBlock

* Add StagingArea to blockValidator

* Add StagingArea to coinbaseManager

* Add StagingArea to syncManager

* Add StagingArea to blockBuilder

* Update consensus with StagingArea

* Add StagingArea to ghostdag2

* Fix remaining compilation errors

* Update names of stagingShards

* Fix forgotten stagingArea passing

* Mark stagingShard.isCommited = true once commited

* Move isStaged to stagingShard, so that it's available without going through store

* Make blockHeaderStore count be avilable from stagingShard

* Fix remaining forgotten stagingArea passing

* commitAllChanges should call dbTx.Commit in the end

* Fix all tests tests in blockValidator

* Fix all tests in consensusStateManager and some more

* Fix all tests in pruningManager

* Add many missing stagingAreas in tests

* Fix many tests

* Fix most of all other tests

* Fix ghostdag_test.go

* Add comment to StagingArea

* Make list of StagingShards an array

* Add comment to StagingShardID

* Make sure all staging shards are pointer-receiver

* Undo bucket rename in block_store

* Typo: isCommited -> isCommitted

* Add comment explaining why stagingArea.shards is an array
2021-03-29 10:34:11 +03:00
talelbaz
c12e180873 Use go:embed to embed sample-kaspad.conf (only on go1.16) (#1631)
* Use go:embed to embed sample-kaspad.conf (only on go1.16)

* Add a comment to justify the blank import.

* Change a variable name to sampleKaspad (instead configurationSampleKaspadString)

Co-authored-by: tal <tal@daglabs.com>
Co-authored-by: Svarog <feanorr@gmail.com>
2021-03-25 15:56:01 +02:00
Svarog
3959bc1e7c Fixes to stability tests: Move orphans test to simnet + Change fakePublicKeyHash size to 32 bytes (#1630)
* Move orphans test to simnet

* Change fakePublicKeyHash size to correct one
2021-03-25 12:04:41 +02:00
Elichai Turkel
6ec0a8a559 Replace ECMH with Muhash (#1624)
* Replace ECMH with MuHash

* Update genesis hash

* Update tests for new genesis
2021-03-22 18:15:16 +02:00
Svarog
6824be9216 Remove support for ServiceFlags out of DNSSeeder (#1622) 2021-03-18 18:02:57 +02:00
Ori Newman
d0511c1636 Use BLAKE2B instead of HASH160, and get rid of any usage of RIPEMD160 and SHA1 (#1618)
* Use BLAKE2B instead of HASH160, and get rid of any usage of RIPEMD160

* Change genesis coinbase payload script to OP_FALSE

* Fix tests after conflict

* Remove duplicate tests

* Change file name

* Change atomic swap to use proper hash size
2021-03-18 10:20:12 +02:00
Svarog
7d69b66c7c Change --datadir to --appdir and remove symmetrical connection in stability tests (#1617)
* Don't do simetric connects in netsync stability test

* Convert --datadir to --appdir everywhere

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-03-17 17:34:03 +02:00
Svarog
cebcab7f5c Implement BIP-143-like sighash (#1598)
* Move CalculateSignatureHash to consensushashing

* Added CalcSignatureHash_BIP143 with all parameters except the re-used hashes

* Add handling of outputHash

* Add sequencesHash to the mix

* Add previousOutputsHash to the mix

* Replace legacy CalculateSigHash with new one, and re-wire to all non-test code

* Add missing types to WriteElement

* Fix tests in txscript

* Fix tests in rest of code

* Add missing comments

* Add SubnetworkID and Gas to sigHash

* Add TestCalculateSignatureHash

* Invert condition in SigHashSingle getOutputsHash

* Explicitly define that payloadHash for native transactions is 0

* added benchmark to CalculateSignatureHash

* Reformat call for signAndCheck

* Change SigHashes to be true bit-fields

* Add check for transaction version

* Write length of byte array in WriteElement

* hashOutpoint should get outpoint, not txIn

* Use inputIndex instead of i to determine SigHashType

* Use correct transaction version + fix some typos

* Fix hashes in test

* Reformat an overly-long line

* Replace checkHashTypeEncoding with caalls to hashType.IsStandardSigHashType

* Convert hashType to uint8

* Add comment
2021-03-17 15:17:38 +02:00
Elichai Turkel
caf251b7a8 Replace the HomeDir flag with a AppDir flag (#1615) 2021-03-17 12:48:38 +02:00
Svarog
1a4161ffc0 Restructure the default ~/.kaspad directory layout (#1613) 2021-03-16 17:36:36 +02:00
Ori Newman
b84080f3d9 Fix getBlocks to not add the anticone when some blocks were filtered by GetHashesBetween (#1611)
* Fix getBlocks to not add the anticone when some blocks were filtered by GetHashesBetween

* Fix TestSyncManager_GetHashesBetween
2021-03-16 14:43:02 +02:00
stasatdaglabs
cbd0bb6d14 Remove the Services field from NetAddress. (#1610) 2021-03-16 14:22:52 +02:00
Ori Newman
d9449a32b8 Use DAA score where needed (#1602)
* Replace blue score with DAA score in UTXO entries

* Use DAA score for coinbase maturity

* Use DAA score for sequence lock

* Fix calcBlockSubsidy to use DAA score

* Don't pay to blocks that are not included in the DAA added blocks, and bestow red blocks reward to the merging block

* Fix TestGetPruningPointUTXOs

* Fix TestTransactionAcceptance

* Fix TestChainedTransactions

* Fix TestVirtualDiff

* Fix TestBlockWindow

* Fix TestPruning

* Use NewFromSlice instead of manually creating the hash set

* Add assert

* Add comment

* Remove redundant call to UpdateDAADataAndReturnDifficultyBits

* Add RequiredDifficulty, rename UpdateDAADataAndReturnDifficultyBits to StageDAADataAndReturnRequiredDifficulty and add comments

* Make buildUTXOInvalidHeader get bits as an argument

* Fix comments
2021-03-15 13:48:40 +02:00
Ori Newman
0ee8f2b631 Convert appmessage nil mempool entry to gRPC nil mempool entry (#1608) 2021-03-15 11:48:55 +02:00
Ori Newman
ff1c96c149 Wait for flows to finish before shutting down (#1605)
* Wait for flows to finish before shutting down

* Use CompareAndSwap

* Add comment

* Fix error message

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-03-14 20:18:40 +02:00
Elichai Turkel
5e335be5ab Update README.md (#1607) 2021-03-14 16:24:22 +02:00
Svarog
032eda4604 Update go-deploy workflow to upload all executables (#1604) 2021-03-14 13:48:36 +02:00
stasatdaglabs
e4e3541a30 Increase the route capacity of InvTransaction messages. (#1603) 2021-03-14 13:02:55 +02:00
talelbaz
b5933bc4fe Update general unit tests for Reachability (#1597)
* [NOD-1424] Write general unit-tests for Reachability

* Update the tests of reachabilityManager.

* Add a diagram for the created DAG in the test.

* Change tabs to spaces in the diagram.

Co-authored-by: karim1king <karimkaspersky@yahoo.com>
Co-authored-by: tal <tal@daglabs.com>
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-03-14 11:42:56 +02:00
Ori Newman
ec446ac511 Adding DAA score (#1596)
* Save DAA score and DAA added blocks for each block

* Add test

* Add pruning support

* Replace 8 with uint64Length

* Separate DAABlocksStore cache size to DAA score and daaAddedBlocks
2021-03-14 09:44:44 +02:00
Elichai Turkel
3d668cc1bd Remove old constants and print actual grpc server address (#1595)
* Remove unneeded old constants in the p2p

* Print the actual address of the grpc server

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-03-10 16:33:51 +02:00
Elichai Turkel
1486a6312c Adjust the difficulty in the first difficultyAdjustmentWindowSize blocks (#1592)
* Move timesorter to its own package and remove unused functions

* Remove padding+genesis from BlockWindow

* Adjust the difficulty even when there's less than difficultyAdjustmentWindowSize blocks

* Remove unnecessary check from checkBlockTransactionsFinalized

* Update tests with new pastMedianTime and Difficulty

* Review nit
2021-03-10 16:11:46 +02:00
Elichai Turkel
cd27f2850e Delete the stability tests when doing code coverage (#1594) 2021-03-10 15:00:54 +02:00
Ori Newman
14cf7f81f3 Change the difficulty to be calculated based on the same block instead of its selected parent (#1591) 2021-03-09 17:07:16 +02:00
Ori Newman
74539f8f0b Fix TestDifficulty to better check red blocks (#1590)
* Write better tests for red blocks and DAA

* Fix comments

* Fix blue chain size

* Remove high timestamps from blue chain

Co-authored-by: Svarog <feanorr@gmail.com>
2021-03-09 16:38:17 +02:00
Svarog
a7299c1b87 Add stability tests (#1587)
* Add stability-tests

* Fix requires

* Fix golint errors

* Update README.md

* Remove payloadHash from everywhere

* don't run vet on kaspad in stability-tests/install_and_test
2021-03-09 15:01:08 +02:00
Elichai Turkel
27c1e4611e Add a github action deploy script to build and publish releases (#1585)
Co-authored-by: Svarog <feanorr@gmail.com>
2021-03-09 13:00:57 +02:00
Ori Newman
b8413fcecb Add the mempool size to getInfo RPC command (#1584)
* Add the mempool size to getInfo RPC command

* Add mempool.Len()

* Rename mempool.Len() to mempool.TransactionCount()

Co-authored-by: Svarog <feanorr@gmail.com>
2021-03-09 12:48:33 +02:00
Ori Newman
c084c69771 Don't swallow orphan errors (#1581)
Co-authored-by: Svarog <feanorr@gmail.com>
2021-03-09 12:30:35 +02:00
Ori Newman
53781eed4d Remove payload hash (#1583)
* Remove payload hash

* Fix tests
2021-03-08 15:15:03 +02:00
Elichai Turkel
837fa65735 kaspaminer: User tickers and regulate each block individually (#1580)
* User tickers and regulate each block individually

* Add comments, logs and rename variables

* Fix review comments
2021-03-08 10:51:35 +02:00
Elichai Turkel
dd3b2cf7d1 Fix data race in GetBlockChildren (#1579) 2021-03-07 16:33:47 +02:00
Mike Zak
3fd324ca28 Update to version 0.10.0 2021-03-03 16:34:45 +02:00
Ori Newman
0271858f25 Readd BlockHashes to getBlocks response (#1575) 2021-03-03 16:27:51 +02:00
Elichai Turkel
7909480757 Merge big subdags in pick virtual parents (#1574)
* Refactor mergeSetIncrease to return the current BFS block to allow easier merging

* Remove unneeded Heap/HashSet usages

* Add new IsAnyAncestorOf to DagTopolyManager

* Check if the new candidate is in the future of any existing candidate

* Add comments and fix off-by-one in the mergeSetIncrease queue

* Fixed DAGToplogy test mock

* Fix review comments
2021-03-03 16:17:16 +02:00
Ori Newman
18274c236b Write in the reject message the tx rejection reason (#1573)
Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
2021-03-02 20:11:31 +02:00
Elichai Turkel
7829a9fd76 Add nil checks for protowire (#1570)
* Handle errors in p2p handshake better

* Add a new errNil in protowire

* Add nil checks for all protowire.toAppMessage() functions for the p2p

* Add nil checks for all protowire.toAppMessage() functions for the RPC

* Add nil check for protwire KaspadMessage

Co-authored-by: Svarog <feanorr@gmail.com>
2021-03-02 19:14:31 +02:00
Ori Newman
1548ed9629 Increase getBlocks limit to 1000 (#1572) 2021-03-02 18:24:37 +02:00
Svarog
32cd643e8b Clone transactions before returning them out of mempool (#1571)
Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
2021-03-02 17:28:53 +02:00
Ori Newman
05df6e3e4e Return RPC error if getBlock's lowHash doesn't exist (#1569)
Co-authored-by: Svarog <feanorr@gmail.com>
2021-03-02 16:21:55 +02:00
Svarog
ce326b3c7d Add default dns-seeder to testnet (#1568) 2021-03-02 12:57:16 +02:00
Svarog
a4ae263ed5 Don't print stack trace on disconnected (#1567) 2021-03-02 12:25:33 +02:00
Elichai Turkel
79be1edaa5 Fix utxoindex deserialization (#1566)
* Fix broken deserialization in utxoindex

* Add Tests for hashes serialization in utxo index
2021-03-01 19:06:19 +02:00
Svarog
c1ef5f0c56 Add pruning point hash to GetBlockDagInfo response (#1565)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-03-01 18:46:45 +02:00
Elichai Turkel
458e409654 Rename handleRequestBlocksFlow to handleRequestHeadersFlow (#1563) 2021-03-01 15:01:59 +02:00
Svarog
df19bdfaf3 Use EmitUnpopulated so that kaspactl prints all fields, even the default ones (#1561)
Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
2021-03-01 14:47:34 +02:00
Elichai Turkel
103edf97d0 Stop logging an error whenever an RPC/P2P connection is canceled (#1562)
* Don't log error when connectionLoop is canceled

* Print new line after Exiting...

* Add stacktrace to the unknown error from connectionLoops
2021-03-01 14:37:42 +02:00
Elichai Turkel
1f69f9eed9 Cleanup the logger and make it asynchronous (#1524)
* Remove Subsystems map and replace with RegisterSubSystem

* Clean up the logger

* Fix LOGFLAGS and make LongFile work correctly

* Parallelize the logger backend

* More logger cleanup

* Initialize and close the logger backend wherever it's needed

* Move the location where the backend is closed, also print the log if it panics while writing

* Add TestMain to reachability manager tests to preserve the same log level

* Fix review comments

Co-authored-by: Svarog <feanorr@gmail.com>
2021-03-01 14:04:40 +02:00
Elichai Turkel
6a12428504 Close iterators (#1542)
* Add Close() function to all the iterators

* Add defer iterator.Close() whenever we open an iterator

* Add isClosed to all iterators and panic/return error if used after closing

Co-authored-by: Svarog <feanorr@gmail.com>
2021-03-01 11:15:59 +02:00
Svarog
63b1d2a05a Add childrenHashes to GetBlock/s RPC commands (#1560)
* Add childrenHashes to GetBlock/s RPC commands

* Fix missed error + implement GetBlockChildren in fakeRelayInvsContext
2021-02-28 18:28:29 +02:00
Svarog
089115c389 Add ScriptPublicKey.Version to RPC (#1559)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-02-25 17:43:06 +02:00
Elichai Turkel
24a12cf2a1 Fix subnetworks FromString and disable reversal (#1557)
* Remove DomainSubnetworkID reversal

* Fix DomaiNSubnetworkID FromString implementation

* Change RPC conversation logic to use Stringer/FromString

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-02-25 16:35:31 +02:00
Mike Zak
6597f24bab Add changelog for v0.8.10 2021-02-25 14:56:05 +02:00
Svarog
dc84913214 Convert ProtocolError to value-type, so that it can be used withh errors.As + fix SubmitBlock ProtocolError condition (#1555)
* Fix condition from || to &&

* Convert ProtocolError to value-type, so that it can be used wihth errors.As

* Simplify condition further
2021-02-24 17:13:59 +02:00
Ori Newman
201646282b Fix the target block rate to create less bursty mining (#1554)
Co-authored-by: Svarog <feanorr@gmail.com>
2021-02-24 16:35:38 +02:00
Svarog
3f08bf87a8 Fix mempool.RemoveTransactions (#1551)
* Fix mempool.RemoveTransactions

* Don't crash if mempool.RemoveTransactions returns an error. log.Critical instead
2021-02-24 12:47:21 +02:00
Ori Newman
581a12db96 Add RPC reconnection to the miner (#1552)
* Add RPC reconnection to the miner

* Fix wrapf

* Change logs
2021-02-24 10:25:13 +02:00
Svarog
fb6c9c8f21 Remove virtual diff parents (#1550)
* resolveSingleBlockStatus: If the block being resolved is not going to be the next selectedTip - set it's diffParent to be the old selectedTip

* resolveSingleBlockStatus: If the block being resolved is going to be the next selectedTip - set it as old selectedTip's diffChild

* Remove any mentions of virtualDiffParents

* If block is genesis - don't do all the mumbo-jumbo with oldSelectedTip

* Check an unchecked error

* Write a better log message
2021-02-23 17:19:35 +02:00
Ori Newman
2adb4f5d0f Fix UTXO index (#1548)
* Add VirtualUTXODiff and VirtualParents to block insertion result

* Add GetVirtualUTXOs

* Add OnPruningPointUTXOSetOverrideHandler

* Add recovery to UTXO index

* Add UTXO set override notification

* Fix compilation error

* Fix iterators in UTXO index and fix TestUTXOIndex

* Change Dialing to DEBUG

* Change LogBlock location

* Rename StopNotify to StopNotifying

* Add sanity check

* Add comment

* Remove receiver from serialization functions

Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
2021-02-23 16:51:51 +02:00
Ori Newman
9ffda2b1da Change disconnect log level to INFO (#1549)
* Change disconnect log level to INFO

* Add disconnected log and change log levels
2021-02-23 13:52:47 +02:00
Svarog
bee0893660 Renamed BlueBlockWindow to just BlockWindow (#1547)
* Renamed BlueBlockWindow to just BlockWindow

* Update comment
2021-02-22 11:33:39 +02:00
talelbaz
a7bb1853f9 Adds tests for transaction validator and block validators (#1531)
* [NOD-1453] cover failing block validation

* [NOD-1453] Complete covering test for invalid block

* [NOD-1453] Fix validator tests after rebase

* [NOD-1453] Cover tests for valid blocks

* [NOD-1453] Implement unit tests for ValidateTransactionInIsolation

* [NOD-1453] Add tests for ValidateTransactionInContextAndPopulateMassAndFee

* [NOD-1453] Cover ValidateHeaderInContext test

* [NOD-1453] Fix after rebase

* not finish

* commited for update the branch.

* Adds new tests to block_body_in_isolation_test.go according to (and instead of ) blockvalisator_test.go

* Adds a comment to type MEDIAN.

* Fixes according to the review notes: add notes and change variables name.

* Fix comment.

* Remove an unused test( all the tests in this file were passed to other test files).

* Change a variable name(txWithAnEmptyInvalidScript to txWithInvalidSignature).

* adds missing '}'.

* Change spaces to tab

Co-authored-by: karim1king <karimkaspersky@yahoo.com>
Co-authored-by: Karim A <karim.a@it-dimension.com>
Co-authored-by: tal <tal@daglabs.com>
2021-02-21 17:46:22 +02:00
talelbaz
35e555e959 Tests validateDifficulty ( ValidatePruningPointViolationAndProofOfWorkAndDifficulty) (#1532)
* Adds tests for validateDifficulty

* fixes according to the review notes: adding the test's goal and fix an unmatch test name on the NewTestConsensus.

* Fixes according to the review notes:delete the function genesisBits - No usages.

* Fix according to review - fix comments.

Co-authored-by: tal <tal@daglabs.com>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-02-21 17:00:34 +02:00
Elichai Turkel
a250f697ee Prevent fast failing (#1545) 2021-02-21 16:09:19 +02:00
Elichai Turkel
f66708b3c6 Make the CI more verbose and cache kaspad dependencies in the dockerfile (#1541)
* Make the CI more verbose

* Improve the docker caching of kaspad dependencies

Co-authored-by: Svarog <feanorr@gmail.com>
2021-02-21 12:15:32 +02:00
Svarog
8fbea5d239 Increase the sleep time in kaspaminer when the node is not synced (#1544)
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-02-21 11:46:06 +02:00
Svarog
5fa06fe7d7 Upgrade everything to go1.16 (#1539)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-02-21 09:17:21 +02:00
Ori Newman
06fd6f1b95 Parallelize tests on Dockerfile (#1540)
Co-authored-by: Svarog <feanorr@gmail.com>
2021-02-18 11:38:44 +02:00
Ori Newman
d2f4ed660c Disallow header only blocks on RPC, relay and when requesting IBD full blocks (#1537) 2021-02-18 10:39:12 +02:00
Elichai Turkel
19878aa062 Make templateManager hold a DomainBlock and isSynced bool instead of a GetBlockTemplateResponseMessage (#1538) 2021-02-18 00:59:11 +02:00
Elichai Turkel
6415e525c3 go test race detector in github actions at cron job (#1534)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-02-17 18:59:42 +02:00
Svarog
995e526dae Make antiPastHashesBetween return blocks sorted in ghostdag-order (#1536)
* Make antiPastHashesBetween return blocks sorted in ghostdag-order

* Return sortedMergeSet instead of blueMergeSet

* Invert the order of parameters of IsAncestorOf

* Add RenderDAGToDot to TestConsensus

* Add HighHash explicitly, unless lowHash == highHash

* Use Equal instead of == when comparing hashes

* Fixed TestSyncManager_GetHashesBetween

* Fix tests

* findHighHashAccordingToMaxBlueScoreDifference: don't start looking if the whole thing fits

* Handle a missed error

* Remove redundant call to RenderToDot

* Fix bug in findHighHashAccordingToMaxBlueScoreDifference
2021-02-17 18:22:08 +02:00
Elichai Turkel
00a023620d Fix a data race in the block logger (#1533) 2021-02-17 17:05:25 +02:00
Ori Newman
2908a46441 Don't ban when sending pruned blocks (#1530) 2021-02-15 16:43:35 +02:00
Ori Newman
e78cdff3d0 Don't mark block that got rejected because of ruleerrors.ErrPrunedBlock as invalid (#1529)
* Don't mark block that got rejected because of ruleerrors.ErrPrunedBlock as invalid

* Update comment
2021-02-15 15:34:21 +02:00
Ori Newman
2a31074fc4 Make getBlock return an error for invalid blocks (#1528) 2021-02-15 14:39:25 +02:00
stasatdaglabs
d835f72e74 Make AddressManager persistent (#1525)
* Move existing address/bannedAddress functionality to a new addressStore object.

* Implement TestAddressManager.

* Implement serializeAddressKey and deserializeAddressKey.

* Implement serializeNetAddress and deserializeNetAddress.

* Store addresses and banned addresses to disk.

* Implement restoreNotBannedAddresses.

* Fix bannedDatabaseKey.

* Implement restoreBannedAddresses.

* Implement TestRestoreAddressManager.

* Defer closing the database in TestRestoreAddressManager.

* Defer closing the database in TestRestoreAddressManager.

* Add a log.

* Return errors where appropriate.

Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
2021-02-14 19:08:06 +02:00
Elichai Turkel
a581dea127 Remove unused utils and structures (#1526)
* Remove unused utils

* Remove unneeded randomness from tests

* Remove more unused functions

* Remove unused protobuf structures

* Fix small errors
2021-02-14 18:13:20 +02:00
stasatdaglabs
7b4b5668e2 Enhance UTXOsChanged notifications (#1522)
* In PropagateUTXOsChangedNotifications, add the given addresses to the address list instead of replacing them.

* Add StopNotifyingUtxosChangedRequestMessage to rpc.proto.

* Implement StopNotifyingUTXOsChanged.

* Optimize convertUTXOChangesToUTXOsChangedNotification.
2021-02-14 12:58:29 +02:00
Elichai Turkel
0e2061d838 Make RPC command GetBlocks prepend lowHash to return value and fix error when lowHash=highHash (#1520)
* Don't error out if antiPastHashesBetween have 2 blocks with the same blue score

* Prepend lowHash to RPC GetBlocks request

* Add a test for GetHashesBetween

* Add a test for GetBlocks RPC call

* Update antipast.go

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-02-11 18:13:46 +02:00
Svarog
0a579e7f78 DownloadHeaders: Instead of using doneChan - close blockHeadersMessageChan. (#1523) 2021-02-11 17:01:15 +02:00
hashdag
1ed6c4c086 Update README.md 2021-02-11 15:04:15 +02:00
Svarog
fea83e5c6c Change Testnet name to kaspad-testnet-2 (#1521)
* Change Testnet name to kaspad-testnet-2

* Fix tests that hardcoded network names
2021-02-11 15:02:25 +02:00
Elichai Turkel
7c3beb526e Limit stdout log level to info (#1518)
* Rename debuglevel to loglevel

* Limit stdout level to info by default

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
Co-authored-by: Svarog <feanorr@gmail.com>
2021-02-10 18:35:13 +02:00
Svarog
171deded4e Implement GetBlocks RPC command (#1514)
* Remove BlockHexes from GetBlocks request and response

* Add GetBlocks RPC

* Include the selectedTip's anticone in GetBlocks

* Add Anticone to fakeRelayInvsContext

* Include verbose data only if it was requested + Add comments to HandleGetBlocks

* Allow antiPastHashesBetween to receive unrelated low and high hashes

* Convert to/from protowire GetBlocksResponse with no verbose data correctly

* Removed NextLowHash

* Update GetBlocks in rpc_client

* Validate in consensus.Anticone that blockHash exists

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-02-10 18:27:04 +02:00
stasatdaglabs
94cdc77481 Send peers the hash of the virtual selected parent once connection is established (#1519)
* Send peers the hash of the virtual selected parent once connection is established.

* Add a log to SendVirtualSelectedParentInv.

* Fix TestIBDWithPruning.

* Fix TestIBDWithPruning better and signal from the IBD syncer to the IBD syncee that the DAG is split amongst them.

* Fix TestVirtualSelectedParentChain.

* Add comments.
2021-02-10 18:09:25 +02:00
Svarog
1222a555f2 Prune blocks below pruning point when moving pruning point during IBD (#1513)
* Split deletePastBlocks into sub-routines

* Remove SelectedParentIterator, and refactor SelectedChildIterator to support First and Error

* Implement PruneAllBlocks

* Prune all blocks in the store

* Prune only blocks that are below the pruning point

* Defer call onEnd of LogAndMeasureExecutionTime

* Handle a forgotten error

* Minor style fixes
2021-02-10 16:39:36 +02:00
talelbaz
f13fc35b9e Adds new tests for "BlockAtDepth" function and validate the old tests on DAGTraversal. (#1500)
* Adds tests for the "blockAtDepth" function and verify old other tests.

* Optimization on create the Dag chain.

* Changes according to the review - more detailed error messages, added constants, changed to 3 independent graphs (instead of extending), and changes all the abbreviations.

* Changes according to the review - divide the test into three separate tests and change names to variables.

* Changes according to the review - the order of the function has changed.

* delete double lines

Co-authored-by: tal <tal@daglabs.com>
Co-authored-by: Svarog <feanorr@gmail.com>
2021-02-09 15:28:37 +02:00
Elichai Turkel
2d61a67592 Change some logs (#1511) 2021-02-09 14:00:02 +02:00
stasatdaglabs
3a4fa6e0e1 Add blockVerboseData to blockAddedNotifications (#1508)
* Add blockVerboseData to blockAddedNotifications.

* Run the documentation generator.
2021-02-09 10:30:16 +02:00
Elichai Turkel
2edf6bfd07 Minimize memory usage in tests (#1495)
* Make leveldb cache configurable

* Fix leveldb tests

* Add a preallocate option to all caches and disable in tests

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-02-08 18:37:02 +02:00
Ori Newman
8225f7fb3c Add GetInfo RPC command (#1504)
* Add GetInfo RPC command

* Rename ID to p2p ID
2021-02-08 16:33:21 +02:00
Elichai Turkel
3d0a2a47b2 Move testGHOSTDagSorter to testutils, and build a boilerplate for overriding specific managers (#1486)
* Move testGHOSTDagSorter to testutils

* Allow overriding managers in consensus, starting with ghostdag

* Add test prefix to SetDataDir and SetGHOSTDAGManager

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-02-08 15:24:26 +02:00
Ori Newman
4a354cd538 Validate transactions on BuildBlock (#1491)
* Validate transactions on BuildBlock

* Rename tx -> transactions

* Add transaction validator to block builder constructor and fix TestValidateAndInsertErrors

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-02-08 14:59:43 +02:00
Ori Newman
1a3b16aaa3 Don't change the new reindex root if the blue score of the selected tip is lower than the current reindex root (#1501) 2021-02-08 14:00:53 +02:00
Ori Newman
5b5a7e60af Add aggregated headers processing logs (#1487)
* Add aggregated headers processing logs

* Unite headers and blocks log

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-02-08 10:45:13 +02:00
Ori Newman
d30f05b250 Remove IsPushOnlyScript from mempool validation (#1492)
* Remove IsPushOnlyScript from mempool validation

* Fix TestCheckTransactionStandard
2021-02-08 10:04:19 +02:00
Svarog
6bc7a4eb85 Allow GetMissingBlockBodyHashes return an empty list if the missing blocks were requested before IBD start (#1498)
* Allow GetMissingBlockBodyHashes return an empty list if the missing blocks were requested before IBD start

* Add link to issue in comment about error to be fixed
2021-02-07 16:12:15 +02:00
Ori Newman
608d1f8ef9 Add TestBlueWork (#1488)
* Add TestBlueWork

* Add comments and blue score check

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-02-04 17:12:33 +02:00
stasatdaglabs
a792d4a19e Don't fsync immediately after all writes (#1490) 2021-02-04 16:36:46 +02:00
stasatdaglabs
8941c518fc Remove the no-longer relevant highHashReceived mechanism in syncHeaders. (#1489) 2021-02-04 16:06:20 +02:00
Ori Newman
6f53da18b1 Increase stores cache (#1485)
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-02-04 10:06:02 +02:00
stasatdaglabs
44280b9006 Require the --miningaddr parameter in kaspaminer. (#1482)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-02-04 09:42:02 +02:00
Ori Newman
dbababb978 Limit mempool size to million transactions and remove the least profitable transactions (#1483)
* Limit mempool size to million transactions and remove the least profitable transactions

* Simplify insert

* Fix typo

* Improve findTxIndexInOrderedTransactionsByFeeRate readability
2021-02-03 19:45:39 +02:00
Ori Newman
238950cb98 Add logs (#1484)
* Add logs

* Fix log name
2021-02-03 17:47:59 +02:00
Ori Newman
ee8fa32ff8 Refactor miner and mine when waiting for block to validate (#1481)
* Refactor miner and mine when waiting for block to validate

* Fix -n to work after the refactor.
Change foundBlockChan capacity.
Use lock instead of atomic in the template manager.

* Fix self assignment

* Fix lock

* Fix Dockerfile

* Add comment
2021-02-03 11:53:55 +02:00
Elichai Turkel
e7f9606683 Add dummy go files for test only package, to mitigate golang/go#27333 (#1480)
* Add dummy go files for test only package, to mitigate golang/go#27333

* Stop ignoring errors when producing the coverage

* Add comments explaining the dummy go files

* Make the coverage output non-json
2021-02-02 18:20:15 +02:00
stasatdaglabs
97be133cee Add logs to help debug long virtual parent selection. (#1470)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-02-01 19:15:50 +02:00
Ori Newman
aeb8e9d2cd Unban address after one day (#1479)
* Unban address after one day

* Unban addresses one by one

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-02-01 18:52:49 +02:00
Ori Newman
b636ae234e Add ban and unban RPC commands (#1478)
* Add ban and unban RPC commands

* Fix names

* Fix commands strings

* Update RPC documentation

* Rename functions

* Simplify return

* Use IP strings in app messages

* Add parse IP error

* Fix wrong condition
2021-02-01 17:34:43 +02:00
Elichai Turkel
a3913dbf80 Update to version 0.9.0 2021-02-01 15:39:39 +02:00
Elichai Turkel
2871a6a527 Update to version 0.8.7 2021-02-01 15:38:40 +02:00
Svarog
d5a3a96bde Use hard-coded sample config instead of assumed path (#1466)
* Use hard-coded sample config instead of assumed path

* Fix bad path to sample-kaspad.conf in TestCreateDefaultConfigFile

Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
2021-02-01 15:15:37 +02:00
Elichai Turkel
12c438d389 Fix data races in ConnectionManager and flow tests (#1474)
* Reuse the ticker in ConnectionManager.waitTillNextIteration

* Fix a data race in ConnectionManager by locking the mutex

* Add a mutex to fakeRelayInvsContext in block relay flow test

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-02-01 15:03:31 +02:00
Elichai Turkel
280fa3de46 Prevent infinite ticker leaks in kaspaminer (#1476)
* Prevent infinite tickers leaks in kaspaminer

* Reset ticker in ConnectionManager instead of allocating a new one

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-02-01 14:52:17 +02:00
Elichai Turkel
d281dabdb4 Bump Go version to 1.15 (#1477) 2021-02-01 14:35:11 +02:00
Ori Newman
331042edf1 Add defaultTargetBlocksPerSecond (#1473)
* Add defaultTargetBlocksPerSecond

* Use different default per network
2021-02-01 14:26:45 +02:00
Ori Newman
669a9ab4c3 Ban by IP (#1471)
* Ban by IP

* Fix panic

* Fix error format

* Remove failed addresses

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-02-01 10:51:18 +02:00
stasatdaglabs
65e149b2bb In kaspaminer, don't crash on submitBlock timeout (#1462)
* In kaspaminer, don't crash on submitBlock timeout.

* Make timeout messages have a log level of Warn.

* Wait for a second after receiving a reject for IBD.

Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
2021-01-29 09:10:21 +02:00
stasatdaglabs
7c1495ba65 Force stop gRPC servers after a short timeout (#1463)
* Force stop gRPC servers after a short timeout.

* Use spawn instead of go.
2021-01-28 19:43:04 +02:00
Ori Newman
13ffa5093c Increase the waiting for error timeout (#1465) 2021-01-28 13:33:37 +02:00
Ori Newman
a9a810a2b2 Add block type to MineJSON (#1464) 2021-01-28 13:22:20 +02:00
Michael Sutton
c9b591f2d3 Final reindex algorithm (#1430)
* Mine JSON

* [Reindex tests] add test_params and validate_mining flag to test_consensus

* Rename file and extend tests

* Ignore local test datasets

* Use spaces over tabs

* Reindex algorithm - full algorithm, initial commit, some tests fail

* Reindex algorithm - a few critical fixes

* Reindex algorithm - move reindex struct and all related operations to new file

* Reindex algorithm - added a validateIntervals method and modified tests to use it (instead of exact comparisons)

* Reindex algorithm - modified reindexIntervals to receive the new child as argument and fixed an important related bug

* Reindex attack tests - move logic to helper function and add stretch test

* Reindex algorithm - variable names and some comments

* Reindex algorithm - minor changes

* Reindex algorithm - minor changes 2

* Reindex algorithm - extended stretch test

* Reindex algorithm - small fix to validate function

* Reindex tests - move tests and add DAG files

* go format fixes

* TestParams doc comment

* Reindex tests - exact comparisons are not needed

* Update to version 0.8.6

* Remove TestParams and use AddUTXOInvalidHeader instead

* Use gzipeed test files

* This unintended change somehow slipped in through branch merges

* Rename test

* Move interval increase/decrease methods to reachability interval file

* Addressing a bunch of minor review comments

* Addressed a few more minor review comments

* Make code of offsetSiblingsBefore and offsetSiblingsAfter symmetric

* Optimize reindex logic in cases where reorg occurs + reorg test

* Do not change reindex root too fast (on reorg)

* Some comments

* A few more comments

* Addressing review comments

* Remove TestNoAttackAlternateReorg and assert chain attack

* Minor

Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
Co-authored-by: Mike Zak <feanorr@gmail.com>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-01-27 17:09:20 +02:00
Ori Newman
8d6e71d490 Add IBD test cases and check for MsgUnexpectedPruningPoint on receivePruningPointBlock as well (#1459)
* Check for MsgUnexpectedPruningPoint on receivePruningPointBlock as well

* Add IBD test cases

* Revert "Check for MsgUnexpectedPruningPoint on receivePruningPointBlock as well"

This reverts commit 6a6d1ea180.

* Change log level for two logs

* Remove "testing a situation where the pruning point moved during IBD (before sending the pruning point block)"
2021-01-27 16:42:42 +02:00
Elichai Turkel
2823461fe2 Change AddressKey from string to port+ipv6 address (#1458) 2021-01-27 16:09:32 +02:00
Elichai Turkel
2075c585da Fix race condition in kaspaminer (#1455)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-01-27 13:08:35 +02:00
Elichai Turkel
01aee62cb0 Add log and measure to pruning points (#1457) 2021-01-27 11:40:51 +02:00
Ori Newman
a6ee871f7e Increase maxSelectedParentTimeDiffToAllowMiningInMilliSeconds to one hour (#1456) 2021-01-27 11:04:58 +02:00
Mike Zak
6393a8186a Update to version 0.9.0 2021-01-27 09:22:56 +02:00
stasatdaglabs
3916534a7e In kaspactl, prettify responses before printing them (#1453)
* In kaspactl, prettify responses before printing them.

* Indent with four spaces instead of a tab.

* Unwrap the response.

* Simplify unwrapping the response.

* Don't unwrap responses.

* Use protojson.MarshalOptions for prettification.
2021-01-27 09:13:48 +02:00
Elichai Turkel
0561347ff1 Remove default dns/grpc seeders (#1454) 2021-01-26 17:40:54 +02:00
Svarog
fb11981da1 Make kaspactl usable by human beings (#1452)
* Add request_types and their help

* Added command parser

* Updated main to use command if it's specified

* Some progress in making everything work

* Fix command parser for pointers to structs

* Cleanup code

* Enhance usage text

* Fixed typo

* Some minor style fixing, and remove temporary code

* Correctly fallthrough in stringToValue unsupported types

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-01-26 14:22:35 +02:00
Ori Newman
1742e76af7 Add TestHandleRelayInvsErrors (#1450) 2021-01-26 13:31:28 +02:00
Svarog
ddfe376388 Don't ban peers that sent a requested duplicate block (#1440)
* Ignore ErrDuplicateBlock for any blocks that were requested

* Don't check for DuplicateBlockErr in processHeaders + improve logs

* Return the check for ErrDuplicateBlock in processHeader

* Fix log message
2021-01-26 08:42:04 +02:00
Elichai Turkel
52da65077a codecov: Ignore protobuf autogenerated files (#1449) 2021-01-25 16:58:11 +02:00
Elichai Turkel
ed85f09742 Add P2P/RPC name to the gRPC logs (#1448)
* Add P2P/RPC name to the gRPC logs

* Add p2p/rpc name in more logs
2021-01-25 16:41:43 +02:00
stasatdaglabs
819ec9f2a7 Pass fromOutpoint into GetPruningPointUTXOs instead of offset, so it could Seek over the cursor (#1447)
* Implement TestGetPruningPointUTXOs.

* Fix a bad error message.

* Fix TestGetPruningPointUTXOs for testnet.

* Make sure all the UTXOs are returned in TestGetPruningPointUTXOs.

* Implement BenchmarkGetPruningPointUTXOs.

* Pass fromOutpoint into GetPruningPointUTXOs instead of offset, so it could Seek over the cursor.

* Fix weird benchmark timer calls.

* Remove unnecessary collection of outpointAndUTXOEntryPairs from BenchmarkGetPruningPointUTXOs.

* Fix a comment.
2021-01-25 13:38:59 +02:00
Ori Newman
7ea8a72a9e Add TestReceiveAddressesErrors (#1446)
* Add TestReceiveAddressesErrors

* Change errors to be more descriptive

* Fix checkFlowError
2021-01-24 17:35:20 +02:00
stasatdaglabs
ca04c049ab When the pruning point moves, update its UTXO set outside of a database transaction (#1444)
* Remove pruningPointUTXOSetStaging and implement UpdatePruningPointUTXOSet.

* Implement StageStartSavingNewPruningPointUTXOSet, HadStartedSavingNewPruningPointUTXOSet, and FinishSavingNewPruningPointUTXOSet.

* Fix a bad return.

* Implement UpdatePruningPointUTXOSetIfRequired.

* Call UpdatePruningPointUTXOSetIfRequired on consensus creation.

* Rename savingNewPruningPointUTXOSetKey to updatingPruningPointUTXOSet.

* Add a log.

* Add calls to runtime.GC() at its start and end.

* Rename a variable.

* Replace calls to runtime.GC to calls to LogMemoryStats.

* Wrap the contents of LogMemoryStats in a log closure.
2021-01-24 14:48:11 +02:00
Ori Newman
9a17198e7d Remove redundant type check (#1445) 2021-01-24 14:14:03 +02:00
stasatdaglabs
756f40c59a Sync pruning point UTXO sets incrementally instead of all at once (#1431)
* Replaced the content of MsgIBDRootUTXOSetChunk with pairs of outpoint-utxo entry pairs.

* Rename utxoIter to utxoIterator.

* Add a big stinky TODO on an assert.

* Replace pruningStore staging with a UTXO set iterator.

* Reimplement receiveAndInsertIBDRootUTXOSet.

* Extract OutpointAndUTXOEntryPairsToDomainOutpointAndUTXOEntryPairs into domainconverters.go.

* Pass the outpoint and utxy entry pairs to the pruning store.

* Implement InsertCandidatePruningPointUTXOs.

* Implement ClearCandidatePruningPointUTXOs.

* Implement UpdateCandidatePruningPointMultiset.

* Use the candidate pruning point multiset in updatePruningPoint.

* Implement CandidatePruningPointUTXOIterator.

* Use the pruning point utxo set iterator for StageVirtualUTXOSet.

* Defer ClearCandidatePruningPointUTXOs.

* Implement OverwriteVirtualUTXOSet.

* Implement CommitCandidatePruningPointUTXOSet.

* Implement BeginOverwritingVirtualUTXOSet and FinishOverwritingVirtualUTXOSet.

* Implement overwriteVirtualUTXOSetAndCommitPruningPointUTXOSet.

* Rename ClearCandidatePruningPointUTXOs to ClearCandidatePruningPointData.

* Add missing methods to dbManager.

* Implement PruningPointUTXOs.

* Implement RecoverUTXOIfRequired.

* Delete the utxoserialization package.

* Fix compilation errors in TestValidateAndInsertPruningPoint.

* Switch order of operations in the if statements in PruningPointUTXOs so that Next() wouldn't be unnecessarily called.

* Fix missing pruning point utxo set staging and bad slice length.

* Fix no default multiset in InsertCandidatePruningPointUTXOs.

* Make go vet happy.

* Rename candidateXXX to importedXXX.

* Do some more renaming.

* Rename some more.

* Fix bad MsgIBDRootNotFound logic.

* Fix an error message.

* Simplify receiveIBDRootBlock.

* Fix error message in receiveAndInsertIBDRootUTXOSet.

* Do some more renaming.

* Fix merge errors.

* Fix a bug caused by calling iterator.First() unnecessarily.

* Remove databaseContext from stores and don't use a transaction in ClearXXX functions.

* Simplify receiveAndInsertIBDRootUTXOSet.

* Fix offset count in PruningPointUTXOs().

* Fix readOnlyUTXOIteratorWithDiff.First().

* Split handleRequestIBDRootUTXOSetAndBlockFlow into smaller methods.

* Rename IbdRootNotFound to UnexpectedPruningPoint.

* Rename requestIBDRootHash to requestPruningPointHash.

* Rename IBDRootHash to PruningPointHash.

* Rename RequestIBDRootUTXOSetAndBlock to RequestPruningPointUTXOSetAndBlock.

* Rename IBDRootUTXOSetChunk to PruningPointUTXOSetChunk.

* Rename RequestNextIBDRootUTXOSetChunk to RequestNextPruningPointUTXOSetChunk.

* Rename DoneIBDRootUTXOSetChunks to DonePruningPointUTXOSetChunks.

* Rename remaining references to IBD root.

* Fix an error message.

* Add a check for HadStartedImportingPruningPointUTXOSet in commitVirtualUTXODiff.

* Add a check for HadStartedImportingPruningPointUTXOSet in ImportPruningPointUTXOSetIntoVirtualUTXOSet.

* Move FinishImportingPruningPointUTXOSet closer to HadStartedImportingPruningPointUTXOSet.

* Remove reference to pruningStore in utxoSetIterator.

* Pointerify utxoSetIterator receivers.

* Fix bad insert in CommitImportedPruningPointUTXOSet.

* Rename commitImportedPruningPointUTXOSetAll to applyImportedPruningPointUTXOSet.

* Simplify PruningPointUTXOs.

* Add populateTransactionWithUTXOEntriesFromUTXOSet.

* Fix a TODO comment.

* Rename InsertImportedPruningPointUTXOs to AppendImportedPruningPointUTXOs.

* Extract handleRequestPruningPointUTXOSetAndBlockMessage to a separate method.

* Rename stuff in readOnlyUTXOIteratorWithDiff.First().

* Address toAddIterator in readOnlyUTXOIteratorWithDiff.First().

* Call First() before any full iteration on ReadOnlyUTXOSetIterator.

* Call First() before any full iteration on a database Cursor.

* Put StartImportingPruningPointUTXOSet inside the pruning point transaction.

* Make serializeOutpoint and serializeUTXOEntry free functions in pruningStore.

* Fix readOnlyUTXOIteratorWithDiff.First().

* Fix bad validations in importPruningPoint.

* Remove superfluous call to validateBlockTransactionsAgainstPastUTXO.
2021-01-21 17:24:52 +02:00
Elichai Turkel
6a03d31f98 Remove accidental pointer indirection in dbKey (#1441) 2021-01-21 12:14:52 +02:00
Ori Newman
319ab6cfcd Always request orphan roots, even when you get an inv of a known orphan (#1436)
Co-authored-by: Svarog <feanorr@gmail.com>
2021-01-20 10:58:45 +02:00
Ori Newman
abef96e3de Add TestIBDWithPruning (#1425)
* Add TestIBDWithPruning

* Test block count

* Fix a typo

Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
Co-authored-by: Mike Zak <feanorr@gmail.com>
2021-01-20 10:07:32 +02:00
stasatdaglabs
2e0bc0f8c4 Increase P2P connections' dial timeouts to 5 seconds (#1437)
Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
2021-01-20 09:48:48 +02:00
Ori Newman
acf5423c63 Remove docker test parallelism (#1434)
* Remove docker parallelism

* Remove redundant dash
2021-01-19 17:30:24 +02:00
Ori Newman
effb545d20 Fix wrong condition and add logs (#1435) 2021-01-19 17:20:25 +02:00
Svarog
ad9c213a06 Restructure database to prevent double-slashes in keys, causing bugs in cursors (#1432)
* Add TestValidateAndInsertPruningPointWithSideBlocks

* Optimize infrastracture bucket paths

* Update infrastracture tests

* Refactor the consensus/database layer

* Remove utils/dbkeys

* Use consensus/database in consensus instead of infrastructure

* Fix a bug in dbBucketToDatabaseBucket and MakeBucket combination

Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-01-19 14:19:08 +02:00
Svarog
a4adbabf96 TestBuildBlockErrorCases and remove redundant check of coinbase script length (#1427)
* Write structure of TestBlockBuilderErrorCases

* Remove double verification of script length in serializeCoinbasePayload

* Remove redundant code in TestBuildBlockErrorCases

* Rename povTransactionHash -> povBlockHash

* Convert coinbasePayloadScriptPublicKeyMaxLength to uint8

* Re-use consensus in TestBuildBlockErrorCases
2021-01-19 10:37:51 +02:00
Ori Newman
799eb7515c Test validateAndInsertPruningPoint (#1420)
* Add TestValidateAndInsertPruningPoint

* Check fake UTXO set and validate that the pruning point changed
2021-01-18 18:17:13 +02:00
Mike Zak
0769705b37 Update to version 0.8.6 2021-01-18 15:17:15 +02:00
Svarog
189e3b6be9 Fix missing utxo notifications (#1428)
* fix missing UTXO notifications (#1426)

* Remove redundant semicolon

Co-authored-by: aspect <anton.yemelyanov@gmail.com>
2021-01-18 13:08:16 +02:00
Mike Zak
e8dfbc8367 Merge remote-tracking branch 'origin/master' into v0.8.5-dev 2021-01-18 11:36:25 +02:00
Ori Newman
d70740331a Remove hashesQueueSet (#1424)
Co-authored-by: Svarog <feanorr@gmail.com>
2021-01-18 09:10:26 +02:00
Svarog
9a81b1328a Add the Address of node to whom connected in log of send/receiveVersion (#1423)
* Add the Address of node to whom connected in log of send/receiveVersion

* Don't call functions before LogAndMeasureExecutionTime

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-01-17 16:31:48 +02:00
Ori Newman
d4f3a252ff Add TestIsFinalizedTransaction (#1422)
Co-authored-by: Svarog <feanorr@gmail.com>
2021-01-17 15:47:49 +02:00
Ori Newman
f14527de4c Give different limit to the RPC server (#1421) 2021-01-17 13:58:42 +02:00
Ori Newman
dd57e6abe6 Fix checkParentHeadersExist and cover pruning_violation_proof_of_work_and_difficulty.go with tests (#1418)
* Fix checkParentHeadersExist and cover pruning_violation_proof_of_work_and_difficulty.go with tests

* Remove unused variable

* Change consensus violation

* Change condition order

* Get rid of irrelevant error codes in extractRejectCode

* Fix wrong test db names

* Fix checkParentHeadersExist
2021-01-17 11:27:04 +02:00
Ori Newman
67be4d82bf Don't mark bad merkle root as invalid (#1419)
* Don't mark bad merkle root as invalid

* Fix TestBlockStatus

* Move discardAllChanges inside the inner if
2021-01-17 10:40:05 +02:00
Ori Newman
a1381d6768 Add TestCheckParentBlockBodiesExist (#1405)
* Add TestCheckParentBlockBodiesExist

* Use block in pruning point's anticone for the test

* Fix test db name
2021-01-14 13:31:17 +02:00
Ori Newman
10b519a3e2 Add tests to ValidateHeaderInIsolation (#1415)
* Add tests to ValidateHeaderInIsolation

* Fix tests db names

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-01-14 11:06:08 +02:00
Ori Newman
a35f8269ea Add checkBlockIsNotPruned (#1413)
* Add checkBlockIsNotPruned

* Fix test name and comment

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-01-14 10:56:22 +02:00
stasatdaglabs
15af6641fc Send the IBD root UTXO set in chunks instead of a massive monolythic message (#1412)
* Extract syncPruningPointUTXOSet to a separate method.

* Implement logic to send pruning point utxo set chunks in a loop.

* Replace IBDRootUTXOSetAndBlockMessage with IbdRootUtxoSetChunkMessage.

* Add a new message: RequestNextIBDRootUTXOSetChunk.

* Add a new message: DoneIBDRootUTXOSetChunks.

* Protect HandleRequestIBDRootUTXOSetAndBlock from rogue messages.

* Reimplement receiveIBDRootUTXOSetAndBlock.

* Add CmdDoneIBDRootUTXOSetChunks to the HandleRelayInvs flow.

* Decrease the max message size to 10mb.

* Fix bad step.

* Fix confusion between outgoing/incoming routes.

* Measure how long it takes to send/receive the UTXO set.

* Use LogAndMeasure in handleRequestIBDRootUTXOSetAndBlockFlow.
2021-01-13 18:03:07 +02:00
Svarog
1b97cfb302 Prevent a race condition in findHighestSharedBlockHash where we get headersSelectedTip and then pass it as highHash to GetBlockLocator, without locking consensus (#1410)
* Prevent a race condition in findHighestSharedBlockHash where we get headersSelectedTip and then pass it as highHash to GetBlockLocator, without locking consensus

* Restart findHighestSharedBlockHash if lowHash or highHash are no longer in selectedParentChain

* Test for specifically ErrBlockNotInSelectedParentChain instead of database NotFound error

* Fix TestCreateHeadersSelectedChainBlockLocator

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-01-13 17:55:37 +02:00
Ori Newman
61be80a60c Add TestCheckMergeSizeLimit (#1408)
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-01-13 16:19:52 +02:00
Elichai Turkel
83134cc2b5 Add a codecov yml, disable patch checks and make status checks always pass (#1414) 2021-01-13 15:57:57 +02:00
Svarog
4988817da1 Reject SubmitBlock if the node is in IBD (#1409)
* Reject SubmitBlock if the node is in IBD

* Add comments

* Don't use iota for RejectReason constants, since in .proto those are hard-coded
2021-01-13 15:04:55 +02:00
Elichai Turkel
68bd8330ac Log the networks hashrate (#1406)
* Log the hashrate of each block

* Add a test for GetHashrateString

* Move difficulty related functions to its own package

* Convert the validated log in validateAndInsertBlock to a log function

* Add tests for max/min int
2021-01-13 12:51:23 +02:00
Elichai Turkel
192dd2ba8f Add codecov to github (#1358) 2021-01-13 10:35:12 +02:00
Ori Newman
cc49b1826a Reset windowExpectedEndTime after each window (#1407) 2021-01-12 21:34:26 +02:00
Svarog
ce348373c6 Delete existing UTXOSet when commiting VirtualUTXOSet. (#1403) 2021-01-12 16:51:56 +02:00
talelbaz
8ad5725421 Adding a test for the error cases on the function 'checkBlockStatus()' (#1398)
* Adds test for error cases on the function checkBlockStatus.

* Fix review's comments.

* Move test to validateandinsertblock_test.go

Co-authored-by: tal <tal@daglabs.com>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-01-12 15:55:02 +02:00
Ori Newman
23a2fbf401 Remove erroneous finality optimization from LowestChainBlockAboveOrEqualToBlueScore (#1402)
* Remove finality erroneous optimization from LowestChainBlockAboveOrEqualToBlueScore

* Add TestLowestChainBlockAboveOrEqualToBlueScore

* Remove unnecessary fields from dagTraversalManager
2021-01-12 15:27:08 +02:00
Elichai Turkel
c1361e5b3e Change log sizes and add some new features to logger (#1400)
* Increase default log sizes, and increase kaspad log sizes

* Add an option to not print logs to stdout

* Allow logs to be printed in the current working directory

* Add more pruning related logs

* Add comment and increase log rotations to save last 64 logs
2021-01-12 13:26:29 +02:00
Ori Newman
53744ceb45 Compare transaction IDs with Equal (#1401) 2021-01-12 12:53:33 +02:00
Ori Newman
bcf2302460 Add high hash to block locator, and add block locator tests (#1397)
* Include high hash in the block locator

* Add tests for block locator

* Remove redundant function

* Remove redundant assignments
2021-01-12 11:16:25 +02:00
Ori Newman
6101e6bdb6 Fix UTXO serialization, its test, and the static check that missed it (#1396)
* Fix UTXO serialization, its test, and the static check that missed it

* Remove duplicate case

* Use one line for static check

Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
2021-01-11 17:45:17 +02:00
stasatdaglabs
d9b97afb92 Don't swallow errors in HandleNewBlockTransactions. (#1390)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-01-11 17:16:15 +02:00
Ori Newman
b8ca33d91d Add selected chain store and optimize block locator with it (#1394)
* Add selected chain store and optimize block locator with it

* Fix build error

* Fix comments

* Fix IsStaged

* Rename CalculateSelectedParentChainChanges to CalculateChainPath and SelectedParentChainChanges->SelectedChainPath

* Use binary.LittleEndian directly to allow compiler optimizations

* Remove boolean from HeadersSelectedChainStore interface

* Prevent endless loop in block locator
2021-01-11 15:51:45 +02:00
Svarog
c7deda41c6 Fix deserialization of script version in UTXOSet deserialization (#1395)
* Initalize protoUTXOSetIterator with index = -1

* Handle error when failed to deserialize Script version

* Add support for (de)serialization of (u)int16

* Log the error when converting it into ErrMalformedUTXO
2021-01-11 15:23:27 +02:00
talelbaz
434cf45112 Adds a new test to validate POW, and Fix Main-net and Test-net genesis block data. (#1389)
* commit for do fetch&merge

* Adds a new test to validate POW, and Fix Main-net and Testnet genesis block data.

* Fix window's test for testnet and change the expected pruning point for mainnet and testnet.

* Delete function "solveBlock" on proof_of_work_test.go and call the function mining.SolvaBlock instead. Also, remove using of random in "solveBlockWithWrongPOW" function.

* Replace 0xFFFFFFFFFFFFFFFF to math.MaxUint64 in "solveBlockWithWrongPOW" function and change the function's comment of "TestPOW"

* Replace 0xFFFFFFFFFFFFFFFF to math.MaxUint64 in "solveBlockWithWrongPOW" function and change the function's comment of "TestPOW"

* Change from <= to < in the for statement in "solveBlockWithWrongPOW" function

* Adds one arg to the function call "NewTestConsensus" (the function sig has changed).

Co-authored-by: tal <tal@daglabs.com>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-01-11 13:15:26 +02:00
Elichai Turkel
2cc0bf1639 Optimize block locator using finality store (#1386)
* Make sure block locator doesn't include a hash lower than the lowHash in
the block locator

* Use finalityStore to optimize LowestChainBlockAboveOrEqualToBlueScore
2021-01-10 13:36:02 +02:00
Ori Newman
0f2d0d45b5 Add TargetBlocksPerSecond for kaspaminer (#1385)
Co-authored-by: Svarog <feanorr@gmail.com>
2021-01-10 12:44:24 +02:00
Svarog
09e1a73340 Added some logs to block-relay and IBD flows (#1384)
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-01-10 12:05:34 +02:00
Svarog
c6d20c1f6f Start IBDBlockLocator from PruningPoint instead of Genesis (#1383) 2021-01-10 11:06:06 +02:00
Svarog
49e0a2a2e7 Add basic support for archival node (#1370)
* Add archival cli flag

* If --archival was activated - don't delete anything

* Fix tests

* Still change block status to StatusHeaderOnly even in archival nodes
2021-01-10 10:25:15 +02:00
Ori Newman
285ae5cd40 Update READMEs and add CONTRIBUTING.md (#1381)
* Update READMEs and add CONTRIBUTING.md

* Update go version

* Update READMEs and CONTRIBUTING.md

* Update README.md

* Update README.md

* Update README.md
2021-01-10 09:13:00 +02:00
stasatdaglabs
541205904e Add RPC documentation (#1379)
* Split messages.proto to p2p and rpc.

* Split messages.proto to p2p and rpc.

* Write a short intro to the RPC docs.

* Start documenting RPC calls.

* Use a custom protoc-gen-doc.

* Continue writing RPC documentation.

* Finish writing RPC documentation.

* Fix a formatting error.

* Fix merge errors.

* Fix formatting into protowire/README.md.

* Rerun go generate ..

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-01-07 16:55:47 +02:00
Ori Newman
256b7f25f1 Decrease grpc client dial timeout to one second (#1378) 2021-01-07 16:26:37 +02:00
Elichai Turkel
82d95c59a3 Increase log files sizes (#1374) 2021-01-07 11:17:13 +02:00
Ori Newman
79c5d4595e Remove gencerts (#1371) 2021-01-07 10:00:13 +02:00
stasatdaglabs
b195301a99 Add IsIBDPeer to GetConnectedPeerInfoResponse. (#1367)
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-01-06 17:33:51 +02:00
Ori Newman
4ad89056c2 Implement getMempoolEntries (#1369)
* Implement getMempoolEntries

* Fix comment

* Fix comment
2021-01-06 17:26:21 +02:00
Elichai Turkel
64f6cd2178 Merge pull request #1368 from kaspanet/v0.8.4-dev
Upgrade master to 0.8.4rc0
2021-01-06 14:43:39 +02:00
Mike Zak
26368cd674 Update to version 0.8.5 2021-01-06 14:04:46 +02:00
Svarog
9ea4c0fa38 Add sanity check that makes sure that the utxoset that we save fits the pruningPoints's commitment. (#1366)
Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
2021-01-06 13:27:02 +02:00
Elichai Turkel
a04a5462ae Update devnet genesis with older timestamp (#1364)
* Update devnet genesis with older timestamp

* Update BlueWindow test for new genesis
2021-01-06 12:50:27 +02:00
Elichai Turkel
4577023e44 Add script pubkey version to signature hash (#1360)
* Replace 0xffff with math.MaxUint16 on version checks

* Add script version to the signature hash

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2021-01-06 11:51:12 +02:00
Ori Newman
d8293ef635 Revert "Add recoverability for UTXO index (#1342)" (#1353)
This reverts commit 778375c4
2021-01-06 11:41:52 +02:00
Ori Newman
2059d6ba56 Delete sync rate mechanism (#1356)
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-01-06 10:43:44 +02:00
Ori Newman
3ec1cbe236 Add TestBlockStatus (#1361)
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-01-06 10:37:10 +02:00
Ori Newman
741e0962be Remove diffs from restoreUTXO logs (#1354)
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-01-06 10:31:42 +02:00
Elichai Turkel
6279db2bf1 Reverse ghostdag tie break direction (#1359)
* Remove hash reversal in ghostdag

* Update tests after chaning ghostdag hash direction

Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
2021-01-05 19:10:59 +02:00
stasatdaglabs
e24bc527f3 Update the max block size and mass constants to reasonable values (#1344)
Co-authored-by: Elichai Turkel <elichai.turkel@gmail.com>
2021-01-05 18:36:08 +02:00
talelbaz
8a309a7d2a Upgradability mechanisms script version (#1313)
* ''

* ''

* ''

* Changes genesis block version to 0.

* a

* a

* All tests are done.

* All tests passed for changed block version from int32 to uint16

* Adds validation of rejecting blocks with unknown versions.

* Changes txn version from int32 to uint16.

* .

* Adds comments to exported functions.

* Change functions name from ConvertFromRpcScriptPubKeyToRPCScriptPubKey to ConvertFromAppMsgRPCScriptPubKeyToRPCScriptPubKey and from ConvertFromRPCScriptPubKeyToRpcScriptPubKey to ConvertFromRPCScriptPubKeyToAppMsgRPCScriptPubKey

* change comment to "ScriptPublicKey represents a Kaspad ScriptPublicKey"

* delete part (tx.Version < 0) that cannot be exist on the if statement.

* Revert protobuf version.

* Fix a comment.

* Fix a comment.

* Rename a variable.

* Rename a variable.

* Remove a const.

* Rename a type.

* Rename a field.

* Rename a field.

* Remove commented-out code.

* Remove dangerous nil case in DomainTransactionOutput.Clone().

* Remove a constant.

* Fix a string.

* Fix wrong totalScriptPubKeySize in transactionMassStandalonePart.

* Remove a constant.

* Remove an unused error.

* Fix a serialization error.

* Specify version types to be uint16 explicitly.

* Use constants.ScriptPublicKeyVersion.

* Fix a bad test.

* Remove some whitespace.

* Add a case to utxoEntry.Equal().

* Rename scriptPubKey to scriptPublicKey.

* Remove a TODO.

* Rename constants.

* Rename a variable.

* Add version to parseShortForm.

Co-authored-by: tal <tal@daglabs.com>
Co-authored-by: stasatdaglabs <stas@daglabs.com>
2021-01-05 17:50:09 +02:00
Elichai Turkel
70d515a5a9 PruningManager: Delete tips that are in pruningPoint.Anticone from the tips list (#1351) 2021-01-05 14:14:40 +02:00
Elichai Turkel
72a7ca53e6 Save and expose the database in TestConsensus (#1349) 2021-01-05 14:13:33 +02:00
Svarog
119e7374e1 Move common log message to trace (#1348) 2021-01-05 12:51:48 +02:00
Elichai Turkel
e509cb1597 Smal performance improvements to BlueWindow (#1343)
* Convert BlockGHOSTDAGData from an interface to a public struct with getters

* Move hashes.Less to externalapi so it can access the hashes directly without copying

* Reduce calls to ghostdagstore.Get in blueWindow

* Simplify the logic in RequiredDifficulty and reuse big.Int

* Remove bigintpool as its no longer used

* Use ChooseSelectedParent in RequiredDifficulty instead of looping over the parents

* Remove comment
2021-01-05 12:13:02 +02:00
Ori Newman
0fb97a4f37 Add logs (#1346)
* Add logs

* Fix logInterval to const
2021-01-04 17:04:13 +02:00
Svarog
789a7379bd Require only inputs not be prefilled (#1345)
* bug invalidateAndInsertPruningPoint: if ValidateAndInsertBlock returned a non-RuleError error - the error was ignored

* Convert checkNoPrefilledFields into checkNoPrefilledInputs

* Add log line

* clone pruning point when passing to validateBlockTransactionsAgainstPastUTXO
2021-01-04 15:55:08 +02:00
Ori Newman
778375c4af Add recoverability for UTXO index (#1342)
* Add recoverability for UTXO index

* Add comment

* Rename UTXOOutpointPair->OutpointUTXOPair

* Get rid of the db transaction on resetStore and collect all keys before deleting

* Use VirtualSelectedParent instead of selected tip

* Fix error
2021-01-04 14:15:51 +02:00
stasatdaglabs
acef311fb4 Improve the performance of downloading headers (#1340)
* Add a new message: BlockHeadersMessage.

* Add a new message: BlockHeadersMessage.

* Send a lot of headers as a single message instead of many small messages.

* Keep a short queue of blockHeadersMessages so that there's never a moment when the node is not validating and inserting headers

* Add a missing return statement.

* Remove MsgBlockHeader from payloads.
2021-01-03 17:57:14 +02:00
stasatdaglabs
e8cad2b2f3 Send headers continuously without needing to run the BlockLocator protocol after every ~maxBlueScoreDifference blocks (#1339)
* Send headers continuously without needing to run the BlockLocator protocol after ever ~maxBlueScoreDifference blocks

* Add logging.

* Make logs more descriptive.
2021-01-03 15:50:21 +02:00
Ori Newman
97fddeff4b Don't mine when node is not connected (#1338) 2021-01-03 14:57:09 +02:00
Svarog
d6fe9a3017 Filter headers-only blocks out of parentChildren when selecting virtualSelectedParent (#1337) 2021-01-03 14:35:03 +02:00
Ori Newman
1abffd472c Add lock to mempool.GetTransaction (#1336) 2021-01-03 13:06:46 +02:00
Svarog
8c8da3b01f Convert all log messages in pick_virtual_parents.go to Debugf (#1335) 2021-01-03 10:20:37 +02:00
Elichai Turkel
51625e7967 Remove LevelDBSnapshot from LevelDBTransaction (#1334)
* Remove leveldb snapshot from LevelDBTransaction

* Update transactions_test.go to represent the new Transaction logic
2020-12-31 17:58:01 +02:00
Svarog
6fa3aa1dca Change SyncRateWindow to 15 minutes + update sync times on block headers as well (#1331)
* Change SyncRateWindow to 15 minutes + update sync times on block headers as well

* Rename result to isSyncRateTooLow

* Fix formula for expected blocks
2020-12-31 16:45:56 +02:00
Ori Newman
23304a4977 Add UTXO set cache (#1333)
* Add UTXO set cache

* Add clear method to cache
2020-12-31 16:34:46 +02:00
stasatdaglabs
b473a09111 Fix a crash in the UTXO index (#1332)
* Add a field to TransactionAcceptanceData: TransactionInputUTXOEntries.

* Fix failing tests.

* Add transactionInputUtxoEntries to the database.

* Populate transactionInputUTXOEntries in applyMergeSetBlocks and use them in the UTXO index.

* Remove UTXOEntry.Clone().

* Add an additional equality test.
2020-12-31 14:50:14 +02:00
Ori Newman
dd35669861 Check that there are no prefilled fields when validating a block (#1329)
* Check that there are no prefilled fields when validating a block

* Use cleanBlockPrefilledFields in AddBlock

* Move cleanBlockPrefilledFields to BuildBlockWithParents

* Move cleanBlockPrefilledFields to func (bb *testBlockBuilder) BuildBlockWithParents
2020-12-30 18:31:17 +02:00
stasatdaglabs
9401b77a4f Improve the performance of GetBlock and GetBlockHeader. (#1328) 2020-12-30 18:13:12 +02:00
Elichai Turkel
e87368157d Update go.yml (#1330) 2020-12-30 17:46:17 +02:00
stasatdaglabs
7dd0188838 Move the heavy lifting in BlockLocator from the syncer to the syncee (#1324)
* Add a new message: BlockLocatorHighestHash.

* Add a new message: IBDBlockLocator.

* Implement HandleIBDBlockLocator.

* Reimplement findHighestSharedBlockHash.

* Make HandleIBDBlockLocator only return hashes that are in the selected parent chain of the target hash.

* Increase the cache sizes of blockRelationStore, reachabilityDataStore, and ghostdagDataStore.

* Fix wrong initial highHash in findHighestSharedBlockHash.

* Make go vet happy.

* Protect against receiving wrong messages when expecting MsgIBDBlockLocatorHighestHash.
2020-12-30 15:44:14 +02:00
Ori Newman
6172e48adc Don't ban when capacity has been reached (#1326) 2020-12-30 15:15:41 +02:00
Elichai Turkel
739cffd918 Remove half the ghostdag store calls in LowestChainBlockAboveOrEqualToBlueScore (#1323) 2020-12-30 13:53:46 +02:00
Elichai Turkel
bd89ca2125 Log only tips length, and inspect ReachabilityData error instead of calling HasReachabilityData (#1321)
* Print the amount of tips instead of the tips themselves

* Inspect ReachabilityData error instead of calling HasReachabilityData
2020-12-30 13:02:34 +02:00
Svarog
d917a1fc1e Remove the block delay from kaspaminer (#1320) 2020-12-30 12:37:23 +02:00
Svarog
9b12b9c58a Make ReachabilityData a read-only interface with a writable variant, to prevent cloning (#1316)
* Rename reachabilityManager.data to dataForInsertion, and use it only during insertions

* Make reachabilityData an interface

* Fix db serialization of reachability data

* Fix reachabilityDataStore

* Fix all tests

* Cleanup debugging code

* Fix insertToFutureCoveringSet

* Add comments

* Rename to ReachabilityData and MutableReachabilityData
2020-12-30 09:48:38 +02:00
Elichai Turkel
533fa8c00e Change sirtual parents selection to allow faster branch merges in the network (#1315)
* if more candidates then max, choose half with highest blueWork and half with lowest

* Add a Test GhostDAG sorter

* Add a test for pick virtual parents

* Fix review nits
2020-12-29 21:42:31 +02:00
Svarog
0f93189c16 Don't print the whole UTXODiff to log, it might be quite huge (#1318) 2020-12-29 17:16:38 +02:00
Elichai Turkel
52427cb953 Reduce the amount of calls to FinalityPoint() (#1317) 2020-12-29 17:08:06 +02:00
talelbaz
d72f70fabe Adds new dags for GHOSTDAG tests (formatted as json files). (#1187)
* Adds new dags for ghostdag tests.

* Change the error msg for the number of tests (6 instead of 3).

Co-authored-by: tal <tal@daglabs.com>
2020-12-29 14:10:38 +02:00
Ori Newman
49b6cc6038 Add mutable and immutable header interfaces (#1305)
* Add mutable and immutable header interfaces

* Fix ShouldMine()

* Remove false comment

* Fix Equal signature

* Fix Equal implementation
2020-12-29 13:55:17 +02:00
Elichai Turkel
c10a087696 Remove virtualDiffParents that aren't in V.Past or in P.Future (#1310) 2020-12-29 12:07:45 +02:00
Ori Newman
02d5fb29cf Fix notifyVirtualSelectedParentBlueScoreChanged to show the selected tip blue score instead of the virtual's (#1309)
* Fix notifyVirtualSelectedParentBlueScoreChanged to show the selected tip blue score instead of the virtual's

* Fix ShouldMine() to fetch selected tip header
2020-12-29 12:07:05 +02:00
stasatdaglabs
48278bd1c0 Slightly improve the performance of antiPastHashesBetween. (#1312) 2020-12-29 10:36:18 +02:00
Ori Newman
d91afbfe3b Change most Tracef to Debugf (#1302)
* Change most Tracef to Debugf

* Remove diff from log
2020-12-29 10:32:28 +02:00
Ori Newman
5f22632836 Use sync rate for getBlockTemplate's isSynced (#1311)
* Use sync rate for getBlockTemplate's isSynced

* Fix a typo

Co-authored-by: Mike Zak <feanorr@gmail.com>
2020-12-29 09:28:02 +02:00
stasatdaglabs
4aafe8a630 Fix a crashed caused by orphans whose validation failed. (#1297) 2020-12-29 09:02:28 +02:00
Elichai Turkel
7e379028f3 Log the time it takes to delete blocks and save the utxo set for pruning point (#1307) 2020-12-28 16:22:00 +02:00
Elichai Turkel
af1b8c8490 Move version initializiation to init function to prevent race conditions (#1299) 2020-12-28 16:04:00 +02:00
Ori Newman
c7c8b25c09 Set stream max message size and increase the max message size to 1GB (#1300) 2020-12-28 12:53:11 +02:00
stasatdaglabs
b0251fe1a6 Add missing lock to IsValidPruningPoint. (#1296) 2020-12-28 10:08:36 +02:00
Ori Newman
cfe013eca7 Add IsHeaderOnly field to BlockVerboseData (#1295) 2020-12-27 18:23:51 +02:00
stasatdaglabs
50e74bf412 Add BlueScore to BlockVerboseData. (#1294) 2020-12-27 17:57:43 +02:00
stasatdaglabs
12f1c3dfab Fix a crash in GetMissingBlockBodyHashes (#1289)
* Remove the limit on the amount of hashes returned from antiPastHashesBetween.

* Guard against requests with a non-existing block hash.

* Move missing-block-hash guards to consensus.go.

* Ban a peer that doesn't send us all the requested headers during IBD.

* Extract blockHeap.ToSlice.

* Re-request headers in requestHeaders if we didn't receive the highHash.
2020-12-27 17:03:21 +02:00
Ori Newman
a231ec7214 Make only one transaction in validateAndInsertBlock (#1292) 2020-12-27 16:37:09 +02:00
Ori Newman
8aecf961bc Red inclusion (#1275)
* Accept red blocks transactions

* Add comments to TestTransactionAcceptance

* Fix tests

* Remove fetchUTXOSetIfMissing

* Remove redundant dependency

* Fix comments
2020-12-24 18:12:46 +02:00
stasatdaglabs
0dea766373 Fix the stopOldTemplateSolving channel in the miner getting closed twice (#1286)
* Fix the stopOldTemplateSolving channel in the miner getting closed twice.

* Remove a unused variable.
2020-12-24 17:58:28 +02:00
Ori Newman
830ddf4735 Fill testConsensus's dagParams (#1283) 2020-12-24 17:47:03 +02:00
stasatdaglabs
9d0f513e49 Implement a simple mechanism to stop a miner from mining while kaspad is not synced (#1284)
* Reintroduce isSynced into the GetBlockTemplate response.

* Add a warning for when kaspad is not synced.

* Rephrase a log.
2020-12-24 17:15:44 +02:00
stasatdaglabs
bd97075e07 Remove the limit to the returned headers from buildMsgBlockHeaders (#1281)
* Remove the limit to the returned header hashes from buildMsgBlockHeaders.

* Build msgBlockHeaders in batches rather than all at once.
2020-12-24 16:53:26 +02:00
Svarog
05941a76e7 Make DomainHash and TransactionID read-only structs (#1282)
* Increase size of reachability cache

* Change DomainHash to struct with unexported hashArray

* Fixing compilation errors stemming from new DomainHash structure

* Remove obsolete Read/WriteElement methods in appmessage

* Fix all tests

* Fix all tests

* Add comments

* A few renamings

* go mod tidy
2020-12-24 16:15:23 +02:00
stasatdaglabs
7cbda3b018 Fix RPC requests with unknown payloads crashing kaspad (#1203)
* [NOD-1596] Return an error on an unknown field.

* [NOD-1596] Don't use unknownFields to check whether a message is invalid.
2020-12-24 15:17:34 +02:00
Ori Newman
a0b93e1230 Fix deletePastBlocks (#1280) 2020-12-24 13:53:16 +02:00
stasatdaglabs
b749b2db0b Fix transaction relay not working (#1279)
* Implement HandleGetMempoolEntry.

* Fix equality bug in handleRelayedTransactionsFlow.
2020-12-24 10:40:56 +02:00
Svarog
717914319a Increase size of reachability and block-relations cache (#1272)
* Increase size of reachability cache

* Increase cache size for BlockRelationStore
2020-12-24 10:27:05 +02:00
stasatdaglabs
6ef8eaf133 Fix AddBlock not returning validation failure errors (#1268)
* Fix AddBlock not returning validation failure errors.

* Elevate a log from Info to Warning.

* Elevate a log from Info to Warning.
2020-12-23 15:08:02 +02:00
Elichai Turkel
273c271771 Remove hash reversal (#1270)
* Remove hash reversing

* Move toBig to pow.go

* Update some tests
2020-12-23 12:42:37 +02:00
Ori Newman
729e3db145 Pruning calculation changes (#1250)
* 1) Calculate pruning point incrementally
2) Add IsValidPruningPoint to pruning manager and consensus
3) Use reachability children for selected child iterator

* Add request IBD root hash flow

* Fix UpdatePruningPointByVirtual and IsValidPruningPoint

* Regenerate messages.pb.go

* Make the pruning point the earliest chain block with finality interval higher than the previous pruning point

* Fix merge errors
2020-12-23 11:37:39 +02:00
Elichai Turkel
43c00f5e7f Remove the sorting requirement from BlueWindow (#1266)
* Remove the requirement for sorting in BlueWindow

* Sort the BlueWindow in window_test
2020-12-23 10:00:14 +02:00
stasatdaglabs
90d4dbcba1 Implement a simple CLI wallet (#1261)
* Copy over the CLI wallet from Kasparov.

* Fix trivial compilation errors.

* Reimplement the balance command.

* Extract isUTXOSpendable to a separate function.

* Reimplement the send command.

* Fix bad transaction ID parsing.

* Add a missing newline in a log.

* Don't use msgTx in send().

* Fix isUTXOSpendable not checking whether a UTXO is of a coinbase transaction.

* Add --devnet, --testnet, etc. to command line flags.

* In `create`, only print the public key of the active network.

* Use coinbase maturity in isUTXOSpendable.

* Add a readme.

* Fix formatting in readme.
2020-12-23 09:41:48 +02:00
Ori Newman
cb9d7e313d Implement Clone and Equal for all model types (#1155)
* [NOD-1575] Implement Clone and Equal for all model types

* [NOD-1575] Add assertion for transaction ID equality

* [NOD-1575] Use DomainTransaction.Equal to compare to expected coinbase transaction

* [NOD-1575] Add TestDomainBlockHeader_Clone

* [NOD-1575] Don't clone nil values

* [NOD-1575] Add type assertions

* [NOD-1575] Don't clone nil values

* [NOD-1575] Add missing Equals

* [NOD-1575] Add length checks

* [NOD-1575] Update comment

* [NOD-1575] Check length for TransactionAcceptanceData

* [NOD-1575] Explicitly clone nils where needed

* [NOD-1575] Clone tx id

* [NOD-1575] Flip condition

* Nod 1576 make coverage tests for equal clone inside model externalapi (#1177)

* [NOD-1576] Make coverage tests for equal and clone inside model and externalapi

* Some formatting and naming fixes

* Made transactionToCompare type exported

* Added some tests and made some changes to the tests code

* No changes made

* Some formatting and naming changes made

* Made better test coverage for externalapi clone and equal functions

* Changed expected result for two cases

* Added equal and clone functions tests for ghostdag and utxodiff

* Added tests

* [NOD-1576] Implement reachabilitydata equal/clone unit tests

* [NOD-1576]  Full coverage of reachabilitydata equal/clone unit tests

* Made changes and handling panic to transaction_equal_clone_test.go and formating of utxodiff_equal_clone_test.go

* Added recoverForEqual2 for handling panic to transaction_equal_clone_test.go

* [NOD-1576]  Full coverage of transaction equal unit test

* [NOD-1576] Add expects panic

* [NOD-1576] Allow composites in go vet

* [NOD-1576] Code review fixes (#1223)

* [NOD-1576] Code review fixes

* [NOD-1576] Code review fixes part 2

* [NOD-1576] Fix wrong name

Co-authored-by: karim1king <karimkaspersky@yahoo.com>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
Co-authored-by: Karim <karim1king@users.noreply.github.com>

* Fix merge errors

* Use Equal where possible

* Use Equal where possible

* Use Equal where possible

Co-authored-by: andrey-hash <74914043+andrey-hash@users.noreply.github.com>
Co-authored-by: karim1king <karimkaspersky@yahoo.com>
Co-authored-by: Karim <karim1king@users.noreply.github.com>
2020-12-22 17:38:54 +02:00
stasatdaglabs
c2cec2f170 Fix the Sequence field in transaction inputs always getting deserialized to MaxUint64. (#1258) 2020-12-22 16:29:38 +02:00
Svarog
e7edfaceb7 Remove redundant rule errors (#1256)
* Remove ErrTimeTooNew and rename ErrBlockIsTooMuchInTheFuture to ErrTimeTooMuchInTheFuture

* Remove ErrBlockMassTooHigh

* Remove ErrHighHash

* Remove ErrInvalidSubnetwork + some cleanup around subnetwork validation

* Remove ErrTxMassTooHigh

* Remove ErrBadTxInput

* Remove ErrOverwriteTx

* Remove ErrTooManySigOps

* Remove ErrParentBlockUnknown

* Remove ErrParentBlockIsNotCurrentTips

* Remove ErrWithDiff

* Remove ErrFinality

* Remove ErrDelayedBlockIsNotAllowed + ErrOrphanBlockIsNotAllowed

* Remove ErrSelectedParentDisqualifiedFromChain

* Remove ErrBuildInTransactionHasGas

* Remove ErrBadFees
2020-12-22 14:05:21 +02:00
FestinaLente666
5632bee49d comments on default constants (#1253)
* comments on default constants

* more comments on default constants

* more comments on default constants

* more comments on default constants

* gofmt

* small typos
2020-12-22 11:44:32 +02:00
stasatdaglabs
21a459c0f4 Implement virtual selected parent chain RPC methods (#1249)
* [NOD-1579] Rename AcceptedTxIDs to AcceptedTransactionIDs.

* [NOD-1579] Add InsertBlockResult to ValidateAndInsertBlock results.

* [NOD-1593] Rename InsertBlockResult to BlockInsertionResult.

* [NOD-1593] Add SelectedParentChainChanges to AddBlockToVirtual's result.

* [NOD-1593] Implement findSelectedParentChainChanges.

* [NOD-1593] Implement TestFindSelectedParentChainChanges.

* [NOD-1593] Fix a string.

* [NOD-1593] Finish implementing TestFindSelectedParentChainChanges.

* [NOD-1593] Fix merge errors.

* [NOD-1597] Begin implementing UTXOIndex.

* [NOD-1597] Connect UTXOIndex to RPC.

* [NOD-1597] Connect Consensus to UTXOIndex.

* [NOD-1597] Add AcceptanceData to BlockInfo.

* [NOD-1597] Implement UTXOIndex.Update().

* [NOD-1597] Implement add(), remove(), and discard() in utxoIndexStore.

* [NOD-1597] Add error cases to add() and remove().

* [NOD-1597] Add special cases to add() and remove().

* [NOD-1597] Implement commit.

* [NOD-1597] Add a mutex around UTXOIndex.Update().

* [NOD-1597] Return changes to the UTXO from Update().

* [NOD-1597] Add NotifyUTXOsChangedRequestMessage and related structs.

* [NOD-1597] Implement HandleNotifyUTXOsChanged.

* [NOD-1597] Begin implementing TestUTXOIndex.

* [NOD-1597] Implement RegisterForUTXOsChangedNotifications.

* [NOD-1597] Fix bad transaction.ID usage.

* [NOD-1597] Implement convertUTXOChangesToUTXOsChangedNotification.

* [NOD-1597] Make UTXOsChangedNotificationMessage.Removed UTXOsByAddressesEntry instead of just RPCOutpoint so that the client can discern which address was the UTXO removed for.

* [NOD-1597] Collect outpoints in TestUTXOIndex.

* [NOD-1597] Rename RPC stuff.

* [NOD-1597] Add messages for GetUTXOsByAddresses.

* [NOD-1597] Implement HandleGetUTXOsByAddresses.

* [NOD-1597] Implement GetUTXOsByAddresses.

* [NOD-1597] Implement UTXOs().

* [NOD-1597] Implement getUTXOOutpointEntryPairs().

* [NOD-1597] Expand TestUTXOIndex.

* [NOD-1597] Convert SubmitTransaction to use RPCTransaction instead of MsgTx.

* [NOD-1597] Finish implementing TestUTXOIndex.

* [NOD-1597] Add messages for GetVirtualSelectedParentBlueScore.

* [NOD-1597] Implement HandleGetVirtualSelectedParentBlueScore and GetVirtualSelectedParentBlueScore.

* [NOD-1597] Implement TestVirtualSelectedParentBlueScore.

* [NOD-1597] Implement NotifyVirtualSelectedParentBlueScoreChanged.

* [NOD-1597] Expand TestVirtualSelectedParentBlueScore.

* [NOD-1597] Implement notifyVirtualSelectedParentBlueScoreChanged.

* [NOD-1597] Make go lint happy.

* [NOD-1593] Fix merge errors.

* [NOD-1593] Rename findSelectedParentChainChanges to calculateSelectedParentChainChanges.

* [NOD-1593] Expand TestCalculateSelectedParentChainChanges.

* [NOD-1597] Add logs to utxoindex.go.

* [NOD-1597] Add logs to utxoindex/store.go.

* [NOD-1597] Add logs to RPCManager.NotifyXXX functions.

* Implement notifySelectedParentChainChanged.

* Implement TestSelectedParentChain.

* Rename NotifyChainChanged to NotifyVirtualSelectedParentChainChanged.

* Rename GetChainFromBlock to GetVirtualSelectedParentChainFromBlock.

* Remove AcceptanceIndex from the config.

* Implement HandleGetVirtualSelectedParentChainFromBlock.

* Expand TestVirtualSelectedParentChain.

* Fix merge errors.

* Add a comment.

* Move a comment.
2020-12-21 14:43:32 +02:00
Elichai Turkel
45edacfbfa Replace Double-SHA256 with blake2b and implement domain seperation (#1245)
* Replace default hasher (Double-SHA256) with domain seperated blake2b

* Replace all hashes with domain seperated blake2b

* Update the genesis blocks

* Replace OP_HASH256 with OP_BLAKE2B

* Fix the merkle tree by appending zeros instead of duplicating the hash when there is 1 branch left

* Update tests

* Add a payloadHash function

* Update gitignore to ignore binaries

* Fix a bug in the blake2b opcode
2020-12-21 12:51:45 +02:00
Svarog
9f8f0fd747 Added safeguard against running TestDifficulty with a fresh genesis block (#1251) 2020-12-21 11:30:43 +02:00
stasatdaglabs
053bb351b5 [NOD-1597] Implement a UTXO index (#1221)
* [NOD-1579] Rename AcceptedTxIDs to AcceptedTransactionIDs.

* [NOD-1579] Add InsertBlockResult to ValidateAndInsertBlock results.

* [NOD-1593] Rename InsertBlockResult to BlockInsertionResult.

* [NOD-1593] Add SelectedParentChainChanges to AddBlockToVirtual's result.

* [NOD-1593] Implement findSelectedParentChainChanges.

* [NOD-1593] Implement TestFindSelectedParentChainChanges.

* [NOD-1593] Fix a string.

* [NOD-1593] Finish implementing TestFindSelectedParentChainChanges.

* [NOD-1593] Fix merge errors.

* [NOD-1597] Begin implementing UTXOIndex.

* [NOD-1597] Connect UTXOIndex to RPC.

* [NOD-1597] Connect Consensus to UTXOIndex.

* [NOD-1597] Add AcceptanceData to BlockInfo.

* [NOD-1597] Implement UTXOIndex.Update().

* [NOD-1597] Implement add(), remove(), and discard() in utxoIndexStore.

* [NOD-1597] Add error cases to add() and remove().

* [NOD-1597] Add special cases to add() and remove().

* [NOD-1597] Implement commit.

* [NOD-1597] Add a mutex around UTXOIndex.Update().

* [NOD-1597] Return changes to the UTXO from Update().

* [NOD-1597] Add NotifyUTXOsChangedRequestMessage and related structs.

* [NOD-1597] Implement HandleNotifyUTXOsChanged.

* [NOD-1597] Begin implementing TestUTXOIndex.

* [NOD-1597] Implement RegisterForUTXOsChangedNotifications.

* [NOD-1597] Fix bad transaction.ID usage.

* [NOD-1597] Implement convertUTXOChangesToUTXOsChangedNotification.

* [NOD-1597] Make UTXOsChangedNotificationMessage.Removed UTXOsByAddressesEntry instead of just RPCOutpoint so that the client can discern which address was the UTXO removed for.

* [NOD-1597] Collect outpoints in TestUTXOIndex.

* [NOD-1597] Rename RPC stuff.

* [NOD-1597] Add messages for GetUTXOsByAddresses.

* [NOD-1597] Implement HandleGetUTXOsByAddresses.

* [NOD-1597] Implement GetUTXOsByAddresses.

* [NOD-1597] Implement UTXOs().

* [NOD-1597] Implement getUTXOOutpointEntryPairs().

* [NOD-1597] Expand TestUTXOIndex.

* [NOD-1597] Convert SubmitTransaction to use RPCTransaction instead of MsgTx.

* [NOD-1597] Finish implementing TestUTXOIndex.

* [NOD-1597] Add messages for GetVirtualSelectedParentBlueScore.

* [NOD-1597] Implement HandleGetVirtualSelectedParentBlueScore and GetVirtualSelectedParentBlueScore.

* [NOD-1597] Implement TestVirtualSelectedParentBlueScore.

* [NOD-1597] Implement NotifyVirtualSelectedParentBlueScoreChanged.

* [NOD-1597] Expand TestVirtualSelectedParentBlueScore.

* [NOD-1597] Implement notifyVirtualSelectedParentBlueScoreChanged.

* [NOD-1597] Make go lint happy.

* [NOD-1593] Fix merge errors.

* [NOD-1593] Rename findSelectedParentChainChanges to calculateSelectedParentChainChanges.

* [NOD-1593] Expand TestCalculateSelectedParentChainChanges.

* [NOD-1597] Add logs to utxoindex.go.

* [NOD-1597] Add logs to utxoindex/store.go.

* [NOD-1597] Add logs to RPCManager.NotifyXXX functions.

* [NOD-1597] Ignore transactions that aren't accepted.

* [NOD-1597] Use GetBlockAcceptanceData instead of GetBlockInfo.

* [NOD-1597] Convert scriptPublicKey to string directly, instead of using hex.

* [NOD-1597] Add a comment.

* [NOD-1597] Guard against calling utxoindex methods when utxoindex is turned off.

* [NOD-1597] Add lock to UTXOs.

* [NOD-1597] Guard against calls to getUTXOOutpointEntryPairs when staging isn't empty.
2020-12-20 17:24:56 +02:00
stasatdaglabs
843edc4ba5 Limit the orphan collection (#1238)
* Limit the orphan collection.

* Fix grammar in a comment.

* Fix a bad log.
2020-12-20 11:20:51 +02:00
Ori Newman
bd5f4e8c6a Pruning fixes (#1243)
* Pruning related fixes

* Rename setBlockStatus->setBlockStatusAfterBlockValidation

* Rename StatusValid->StatusUTXOValid

* Add comment

* Fix typo

* Rename hasValidatedOnlyHeader->hasValidatedHeader

* Rename checkBlockBodiesExist->checkParentBlockBodiesExist

* Add comments and logs

* Adding logs

* Add logs and assert

* Add comment

* Fix typo

* Fix log
2020-12-20 09:38:34 +02:00
Elichai Turkel
6b1e691a57 Add GitHub actions in preperation for deprecating Jenkins (#1164)
* Add a test script

* add gh action for build and test

* added all the test

* Change github workflow to use the new test script

* Change the docker file to use the new test script

* Add doc comment for ProtocolError.Unwrap()

* Use another github action to increase windows page size

* Run the action after any edit to the PR metadata/base

* Change go version from 1.15 to 1.14

* Rename test.sh to build_and_test.sh

Co-authored-by: Isabella Liu <isabellaliu77@gmail.com>
2020-12-17 15:48:55 +02:00
Ori Newman
bf67c6351e Add TestPruning (#1222)
* Add TestPruning

* Add missing argument to teardown

* Add missing return value to AddBlock
2020-12-16 14:49:55 +02:00
Mike Zak
99a14c5999 Update to version 0.8.4 2020-12-16 14:00:09 +02:00
Ori Newman
b510fc08a7 Change PoW error (#1234)
* Use proper error for invalid PoW

* Add comment
2020-12-16 13:33:10 +02:00
Ori Newman
dc3ae4d3ac Use pointer receivers when needed (#1237) 2020-12-16 12:50:17 +02:00
Svarog
1ebda36b17 Remove IsAwaitingUTXOSet from validateAndInsertBlock log, to prevent long operation (#1235) 2020-12-16 11:33:48 +02:00
Ori Newman
12379bedb6 Fix UTXO serialization errors (#1233) 2020-12-16 11:27:43 +02:00
stasatdaglabs
f90d7d796a [NOD-1593] Return SelectedParentChainChanged from ValidateAndInsertBlock (#1202)
* [NOD-1579] Rename AcceptedTxIDs to AcceptedTransactionIDs.

* [NOD-1579] Add InsertBlockResult to ValidateAndInsertBlock results.

* [NOD-1593] Rename InsertBlockResult to BlockInsertionResult.

* [NOD-1593] Add SelectedParentChainChanges to AddBlockToVirtual's result.

* [NOD-1593] Implement findSelectedParentChainChanges.

* [NOD-1593] Implement TestFindSelectedParentChainChanges.

* [NOD-1593] Fix a string.

* [NOD-1593] Finish implementing TestFindSelectedParentChainChanges.

* [NOD-1593] Fix merge errors.

* [NOD-1593] Fix merge errors.

* [NOD-1593] Rename findSelectedParentChainChanges to calculateSelectedParentChainChanges.

* [NOD-1593] Expand TestCalculateSelectedParentChainChanges.
2020-12-15 11:37:52 +02:00
Ori Newman
fddda46d4f Fix infinite loop on antiPastHashesBetween (#1226)
* Fix infinite loop on antiPastHashesBetween

* Get rid of highBlockBlueScore and lowBlockBlueScore
2020-12-15 10:37:35 +02:00
Svarog
77adb6c99f Make consensus.databaseContext a DBManager and allow keeping data dir in TestConsensus
* Make consensus.databaseContext a DBManager

* Allow keeping data dir in TestConsensus
2020-12-15 10:11:14 +02:00
Ori Newman
48e1a2c396 New headers first flow (#1211)
* Get rid of insertMode

* Rename AddBlockToVirtual->AddBlock

* When F is not in the future of P, enforce finality with P and not with F.

* Don't allow blocks with invalid parents or with missing block body

* Check finality violation before checking block status

* Implement CalculateIndependentPruningPoint

* Move checkBlockStatus to validateBlock

* Add ValidateBlock to block processor interface

* Adjust SetPruningPoint to the new IBD flow

* Add pruning store to CSM's constructor

* Flip wrong condition on AddHeaderTip

* Fix func (hts *headerSelectedTipStore) Has

* Fix block stage order

* Call to ValidateBodyInContext from validatePostProofOfWork

* Enable overrideDAGParams

* Update log

* Rename SetPruningPoint to ValidateAndInsertPruningPoint and move most of its logic inside block processor

* Rename hasValidatedHeader->hasValidatedOnlyHeader

* Fix typo

* Name return values for fetchMissingUTXOSet

* Add comment

* Return ErrMissingParents when block body is missing

* Add logs and comments

* Fix merge error

* Fix pruning point calculation to be by virtual selected parent

* Replace CalculateIndependentPruningPoint to CalculatePruningPointByHeaderSelectedTip

* Fix isAwaitingUTXOSet to check pruning point by headers

* Change isAwaitingUTXOSet indication

* Remove IsBlockInHeaderPruningPointFuture from BlockInfo

* Fix LowestChainBlockAboveOrEqualToBlueScore

* Add validateNewPruningPointTransactions

* Add validateNewPruningAgainstPastUTXO

* Rename set_pruning_utxo_set.go to update_pruning_utxo_set.go

* Check missing block body hashes by missing block instead of status

* Validate pruning point against past UTXO with the pruning point as block hash

* Remove virtualHeaderHash

* Fix comment

* Fix imports
2020-12-14 17:53:08 +02:00
oudeis
6926a7ab81 Update to version 0.8.3 2020-12-14 12:38:03 +00:00
Svarog
a9e0c33e5c Lower minimum difficulty for mainnet and testnet (#1220) 2020-12-14 12:39:54 +02:00
Svarog
2c1688909d Move TestNet to use GRPCSeeds by default (#1217) 2020-12-14 09:09:18 +02:00
Svarog
6714e084e9 Small fix in proof-of-work log (#1205) 2020-12-09 18:31:36 +02:00
Elichai Turkel
3354ac67c8 Parallelize all the tests in ForAllNets (#1199) 2020-12-09 17:43:36 +02:00
Svarog
0d8f7bba40 [NOD-1595] Implement all fields of GetBlockDAGInfo (#1200)
* [NOD-1595] Implement all fields of GetBlockDAGInfo

* [NOD-1595]

* [NOD-1595] Don't swallow errors in GetDifficultyRatio

* [NOD-1595] Change roundingPrecision in GetDifficultyRatio to 2 decimal places
2020-12-09 12:14:15 +02:00
Svarog
e04f76b800 [NOD-1594] Add HeaderCount to GetBlockCount rpc call (#1197) 2020-12-08 19:11:35 +02:00
Elichai Turkel
82fa8e6831 Abstract CheckProofOfWork as a public function and change PoW structure (#1198)
* Expose CheckProofOfWork from model/pow

* Update blockvalidator to call the new CheckProofOfWork

* Update genesis blocks

* Update tools to use the new CheckProofOfWork

* Update tests with new PoW
2020-12-08 17:17:30 +02:00
Svarog
b7ca3f4461 [NOD-1590] Implement optimized finalityPoint calculation mechanism (#1190)
* [NOD-1590] Moved all finality logic to FinalityManager

* [NOD-1590] Add finality store

* [NOD-1590] Implement optimized finalityPoint calculation mechanism

* [NOD-1590] Add comments

* [NOD-1590] Add finalityStore to consensus object, and TestConsensus

* [NOD-1590] Added logs to finalityPoint calculation
2020-12-08 10:26:39 +02:00
Svarog
37bf261da1 [NOD-1581] Enable fsync in database writes (#1168) 2020-12-07 14:18:33 +02:00
Ori Newman
d90e18ec51 Fix v0.8.2-dev build (#1189) 2020-12-07 12:39:40 +02:00
Elichai Turkel
9962527793 Replace BlueWindow implementation to accomadate a better DAA scheme (#1179)
* Change DifficultyAdjustmentWindowSize and TimestampDeviationTolerance from uint64 to int

* refactor block_heap for readability and usage

* Add a new SizedUpHeap

* Refactor BlueWindow with the new DAA

* Update TestBlueBlockWindow with the new DAA window

* Fix review requested changes
2020-12-06 18:42:49 +02:00
talelbaz
78550d3639 Adds "checkDelayedBlock" - checks if the block timeStamp is in the future. (#1183)
* [#1056] Adds "checkDelayedBlock" - check if the block timeStamp is in future.
Adds 2 new fields to blockValidator struct.
Adds new Rule Error "ErrDelayedBlock" .

* [#1056] Replace "ErrDelayedBlock" to "ErrBlockIsTooMuchInTheFuture".

* [#1056] Replace "checkDelayedBlock" to "checkBlockTimeStampInIsolation".

* [#1056] Cosmetics changes: timeStamp -> timestamp .

* Merge remote-tracking branch 'origin/v0.8.2-dev' into droppedDelayedBlock

# Conflicts:
#	domain/consensus/factory.go
#	domain/consensus/processes/blockvalidator/block_header_in_isolation.go
#	domain/consensus/processes/blockvalidator/blockvalidator.go

Co-authored-by: tal <tal@daglabs.com>
2020-12-06 18:41:07 +02:00
stasatdaglabs
7f899b0d09 [NOD-1579] Improve the IBD mechanism (#1174)
* [NOD-1579] Remove selected tip hash messages.

* [NOD-1579] Start moving IBD stuff into blockrelay.

* [NOD-1579] Rename relaytransactions to transactionrelay.

* [NOD-1579] Move IBD files into blockrelay.

* [NOD-1579] Remove flow stuff from ibd.go.

* [NOD-1579] Bring back IsInIBD().

* [NOD-1579] Simplify block relay flow.

* [NOD-1579] Check orphan pool for missing parents to avoid unnecessary processing.

* [NOD-1579] Implement processOrphan.

* [NOD-1579] Implement addToOrphanSetAndRequestMissingParents.

* [NOD-1579] Fix TestIBD.

* [NOD-1579] Implement isBlockInOrphanResolutionRange.

* [NOD-1579] Implement limited block locators.

* [NOD-1579] Add some comments.

* [NOD-1579] Specifically check for StatusHeaderOnly in blockrelay.

* [NOD-1579] Simplify runIBDIfNotRunning.

* [NOD-1579] Don't run IBD if it is already running.

* [NOD-1579] Fix a comment.

* [NOD-1579] Rename mode to syncInfo.

* [NOD-1579] Simplify validateAndInsertBlock.

* [NOD-1579] Fix bad SyncStateSynced condition.

* [NOD-1579] Implement validateAgainstSyncStateAndResolveInsertMode.

* [NOD-1579] Use insertModeHeader.

* [NOD-1579] Add logs to TrySetIBDRunning and UnsetIBDRunning.

* [NOD-1579] Implement and use dequeueIncomingMessageAndSkipInvs.

* [NOD-1579] Fix a log.

* [NOD-1579] Fix a bug in createBlockLocator.

* [NOD-1579] Rename a variable.

* [NOD-1579] Fix a slew of bugs in missingBlockBodyHashes and selectedChildIterator.

* [NOD-1579] Fix bad chunk size in syncMissingBlockBodies.

* [NOD-1579] Remove maxOrphanBlueScoreDiff.

* [NOD-1579] Fix merge errors.

* [NOD-1579] Remove a debug log.

* [NOD-1579] Add logs.

* [NOD-1579] Make various go quality tools happy.

* [NOD-1579] Fix a typo in a variable name.

* [NOD-1579] Fix full blocks over header-only blocks not failing the missing-parents validation.

* [NOD-1579] Add an error log about a condition that should never happen.

* [NOD-1579] Check all antiPast hashes instead of just the lowHash's anticone to filter for header-only blocks.

* [NOD-1579] Remove the nil stuff from GetBlockLocator.

* [NOD-1579] Remove superfluous condition in handleRelayInvsFlow.start().

* [NOD-1579] Return a boolean from requestBlock instead of comparing to nil.

* [NOD-1579] Fix a bad log.Debugf.

* [NOD-1579] Remove a redundant check.

* [NOD-1579] Change an info log to a warning log.

* [NOD-1579] Move OnNewBlock out of relayBlock.

* [NOD-1579] Remove redundant exists check from runIBDIfNotRunning.

* [NOD-1579] Fix bad call to OnNewBlock.

* [NOD-1579] Remove an impossible check.

* [NOD-1579] Added a log.

* [NOD-1579] Rename insertModeBlockWithoutUpdatingVirtual to insertModeBlockBody.

* [NOD-1579] Add a check for duplicate headers.

* [NOD-1579] Added a comment.

* [NOD-1579] Tighten a stop condition.

* [NOD-1579] Simplify a log.

* [NOD-1579] Clarify a log.

* [NOD-1579] Move a log.
2020-12-06 16:23:56 +02:00
Svarog
4886425caf [NOD-1589] Re-enable DisableDifficultyAdjustment (#1182)
* [NOD-1589] Re-enable DisableDifficultyAdjustment

* [NOD-1589] Remove simnet from TestDifficulty

* [NOD-1589] Update comment
2020-12-06 16:02:48 +02:00
Elichai Turkel
c3902ed7a8 Replace blue score with blue work in ghostdag (#1172)
* Replace blueScore with blueWork in ghostDAG SelectedParent selection

* Add blueWork to protopuf ghostdag data

* Auto generate protobuf go code

* Serialize/Deserialize blueWork when converting to protobuf

* pass block header store to ghostdagmanager

* Convert tal's ghostdag2 implementation to blueWork

* Change finality test to check the blueWork instead of blueScore

* Update ghostdag_test to pass blockHeaderStore to ghostdag, and test all networks genesis headers

* Add sanity blueWork check to ghostdag_test
2020-12-06 14:45:21 +02:00
Svarog
33eaf9edac [NOD-1548] Re-add test difficulty + Make GHOSTDAGData immutable + don't clone in store (#1178)
* [NOD-1548] Readd TestDifficulty

* [NOD-1548] Make GHOSTDAGData immutable + don't clone in store

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2020-12-06 12:35:14 +02:00
Svarog
f97b8f7580 [NOD-1587] Add DAGParams to TestConsensus (#1181) 2020-12-06 10:57:57 +02:00
Ori Newman
05979de705 [NOD-1586] Return routes.Disconnect (#1180) 2020-12-06 10:54:34 +02:00
Ori Newman
32a04d1811 Allow to configure consensus (closes #1067)
* Allow to configure consensus with a JSON file

* Define everywhere maxBlockParents as KType

* Move consensus default to consensus_defaults.go
2020-12-03 18:30:01 +02:00
Svarog
a585f32763 [NOD-1551] Make UTXODiff immutable + skip cloning it in datastore (#1167)
* [NOD-1551] Make UTXO-Diff implemented fully in utils/utxo

* [NOD-1551] Fixes everywhere except database

* [NOD-1551] Fix database

* [NOD-1551] Add comments

* [NOD-1551] Partial commit

* [NOD-1551] Comlete making UTXOEntry immutable + don't clone it in UTXOCollectionClone

* [NOD-1551] Rename ToUnmutable -> ToImmutable

* [NOD-1551] Track immutable references generated from mutable UTXODiff, and invalidate them if the mutable one changed

* [NOD-1551] Clone scriptPubKey in NewUTXOEntry

* [NOD-1551] Remove redundant code

* [NOD-1551] Remove redundant call for .CloneMutable and then .ToImmutable

* [NOD-1551] Make utxoEntry pointert-receiver + clone ScriptPubKey in getter
2020-12-03 13:24:24 +02:00
Mike Zak
9866abb75a [NOD-1583] Split consensusserialization to consensushashing and serialization 2020-12-02 13:18:50 +02:00
Mike Zak
ab3c81c552 [NOD-1583] Move all TestXXX interfaces to testapi 2020-12-02 13:18:50 +02:00
Ori Newman
9756d64f28 [NOD-1582] Fix orphan resolution (#1169)
* [NOD-1582] Fix multiple request per missing ancestor

* [NOD-1582] Don't remove peer on routerpkg.ErrRouteClosed from RPC

* [NOD-1582] Use LogAndMeasureExecutionTime where possible
2020-12-02 13:05:33 +02:00
Elichai Turkel
21fc2d4219 [NOD-1433] Write specified unit tests for GHOSTDAG (#1010)
commit 3830df34b2
Merge: 46dc2e977 17e7819c2
Author: Elichai Turkel <elichai.turkel@gmail.com>
Date:   Tue Dec 1 16:29:51 2020 +0200

    Merge pull request #1170 from kaspanet/tal-ghost-fix

    Fix GhostDAG tests and jsons

commit 17e7819c27
Author: Elichai Turkel <elichai.turkel@gmail.com>
Date:   Tue Dec 1 16:24:01 2020 +0200

    Remove non-json ghostdag tests

commit 4bebb1d96a
Author: Elichai Turkel <elichai.turkel@gmail.com>
Date:   Tue Dec 1 13:26:06 2020 +0200

    Add a coment above tal's ghostdag2 impl

commit faf21a042e
Author: Elichai Turkel <elichai.turkel@gmail.com>
Date:   Tue Dec 1 13:20:08 2020 +0200

    fix the interfaces after merge

commit a8b7a25b2e
Merge: af91b69b2 f1c6df48c
Author: Elichai Turkel <elichai.turkel@gmail.com>
Date:   Tue Dec 1 13:19:08 2020 +0200

    Merge branch 'v0.8.2-dev' into tal-ghost-fix

commit af91b69b20
Author: Elichai Turkel <elichai.turkel@gmail.com>
Date:   Tue Dec 1 13:18:41 2020 +0200

    Fix the non-json tests

commit c56f34b73b
Author: Elichai Turkel <elichai.turkel@gmail.com>
Date:   Tue Dec 1 13:18:17 2020 +0200

    Fix the jsons

commit 46dc2e9773
Author: tal <tal@daglabs.com>
Date:   Mon Nov 30 17:15:20 2020 +0200

    [NOD - 1143] Cosmetics changes.

commit b28e5ce816
Author: tal <tal@daglabs.com>
Date:   Mon Nov 30 15:48:08 2020 +0200

    [#1126] Place selectedParent to be first on blueMergeSet.

commit 4b56ed2da9
Author: tal <tal@daglabs.com>
Date:   Mon Nov 30 14:51:50 2020 +0200

    [#1126] Change pacement between blockRight and blockLeft .

commit b09f31be93
Merge: e17a98b7b 0db39833f
Author: talelbaz <63008512+talelbaz@users.noreply.github.com>
Date:   Mon Nov 30 14:30:22 2020 +0200

    Merge pull request #1162 from kaspanet/new-jsons

    Update the dag json tests

commit e17a98b7ba
Author: tal <tal@daglabs.com>
Date:   Mon Nov 30 14:08:25 2020 +0200

    [#1126] Use WALK function in tests & cosmetic changes.

commit 0db39833f3
Author: Elichai Turkel <elichai.turkel@gmail.com>
Date:   Mon Nov 30 12:20:13 2020 +0200

    Update the dag json tests

commit 5a3da43dd4
Author: tal <tal@daglabs.com>
Date:   Sun Nov 29 12:03:37 2020 +0200

    [NOD-1433] Remove unneccessry code.

commit a6cde558ac
Author: tal <tal@daglabs.com>
Date:   Mon Nov 23 17:05:56 2020 +0200

    [NOD-1433] Change "Stage" sig function according to the new interface - added error as a return type.

commit 07859b6218
Author: tal <tal@daglabs.com>
Date:   Mon Nov 23 17:03:26 2020 +0200

    [NOD-1433]  Print formats changed & Cosmetics code changes.

commit e1a851664e
Author: tal <tal@daglabs.com>
Date:   Sun Nov 15 17:34:59 2020 +0200

    [NOD-1433] Travers the tests dir and run each test.

commit 4c7474edc1
Author: tal <tal@daglabs.com>
Date:   Mon Nov 9 12:44:53 2020 +0200

    [NOD-1433] Travers the tests dir and run each test.

commit 89dd1e61d3
Author: tal <tal@daglabs.com>
Date:   Mon Nov 9 11:48:36 2020 +0200

    [NOD-1433] Change implementation to adjust genesis's score 0.
    Also, keep changing the test file to fit the new implementation.

commit 6acdcd17de
Author: tal <tal@daglabs.com>
Date:   Sun Nov 8 17:07:22 2020 +0200

    [NOD-1433] New test was added(Test 6).

commit bf23889317
Author: tal <tal@daglabs.com>
Date:   Sun Nov 8 14:59:36 2020 +0200

    Fix golint errors

commit 79ff990b5f
Author: tal <tal@daglabs.com>
Date:   Sun Nov 8 14:47:12 2020 +0200

    added "Optimize imports".

commit 73d0128f63
Author: tal <tal@daglabs.com>
Date:   Sun Nov 8 13:03:22 2020 +0200

    Added an implementation factory.

commit 61ca8b2e7e
Author: tal <tal@daglabs.com>
Date:   Thu Nov 5 16:03:18 2020 +0200

    1. impl - choose the highest hash.
    2. test - changed the test accordingly.

commit ef0943ca29
Author: tal <tal@daglabs.com>
Date:   Thu Oct 29 18:00:45 2020 +0200

    Update Tests

commit 6e5936abff
Author: tal <tal@daglabs.com>
Date:   Tue Oct 27 10:22:45 2020 +0200

    Change to the new API

commit 5a70dc48b3
Author: tal <tal@daglabs.com>
Date:   Mon Oct 26 18:35:31 2020 +0200

    1. Added tests for ori

commit 2b9f78353f
Author: tal <tal@daglabs.com>
Date:   Mon Oct 26 13:04:37 2020 +0200

    1. Added structure "isolatedTest" {k, test}
    2. Added for loop on the tests.
    3. New test - Test 5.

commit c026d7b7a2
Author: tal <tal@daglabs.com>
Date:   Thu Oct 22 17:35:56 2020 +0300

    Fix bugs in the GHOSTDAG : counters, conntains and isAncestorOf.
    Added more tests.

commit 74493b27d2
Author: tal <tal@daglabs.com>
Date:   Thu Oct 22 16:49:27 2020 +0300

    added compare between Hashes

commit f689253463
Author: tal <tal@daglabs.com>
Date:   Thu Oct 22 11:49:01 2020 +0300

    added compare between Hashes

commit 66be07f616
Author: tal <tal@daglabs.com>
Date:   Mon Oct 19 18:42:40 2020 +0300

    First test - pass.

commit 327f34f2dc
Author: tal <tal@daglabs.com>
Date:   Mon Oct 19 15:20:27 2020 +0300

    Add alternative implementation for ghostdag.
    change all function's signatures (add error type)

commit fd2ea3d84a
Author: tal <tal@daglabs.com>
Date:   Mon Oct 19 11:57:05 2020 +0300

    add alternative implementation for ghostdag
2020-12-01 16:54:13 +02:00
Elichai Turkel
f1c6df48c9 [#1028] Replace oldschnorr with the BIP340 schnorr variant (#1165)
* Update go-secp256k1 to v0.0.3

* Update the txscript engine to support only 32 bytes pubkeys

* Update the txscript engine tests

* Update txscript/sign.go to use the new Schnorr KeyPair API

* Update txscript sign_test to use the new schnorr

* Update sigcache tests to use new schnorr pubkey

* Update integration tests to use the new txscript and new schnorr pubkey
2020-12-01 08:48:23 +02:00
Svarog
80c445c78b [NOD-1551] Optimize binary writes + remove redundant VarInt code (#1163)
* [NOD-1551] Optimize binary writes + remove redundant VarInt code

* [NOD-1551] Remove varInt tests

* [NOD-1551] Fix TestBech32 for Go1.15
2020-11-30 13:45:06 +02:00
Svarog
3b6eb73e53 [NOD-1551] Remove lock in SigCache (#1161) 2020-11-30 11:34:19 +02:00
talelbaz
f407c44a8d [Issue - #1126] - Checking pruning point violation - pruning point in the past. (#1160)
* [NOD-1126]
1. Change function name in BlockValidator interface from: "ValidateProofOfWorkAndDifficulty" to "ValidatePruningPointViolationAndProofOfWorkAndDifficulty".
2. Add to the blockValidator struct the pruningManager (also added to the function "New" Respectively).
3. Added new function "checkPruningPointViolation" of blockValidator type.
4. Add new internal check - "checkPruningPointViolation", on the function "ValidateProofOfWorkAndDifficulty".(The third check).
5. Add new error rule - "ErrPruningPointViolation".

* [Issue-1126]
1. Remove the function "PruningPoint" from PruningManager interface.
2. Changes in blockValidator struct - remove pruningManager, and adding pruningStore.
3. Reads for "pruningPoint" function from pruningStore instead of pruningManager (because of note 1 above) in the functions: * "checkPruningPointViolation" of type blockValidator.
             * "FindNextPruningPoint" of type pruningManager.

* [Issue-1126]
1. Add missing error handling.

* [Issue-1126] Changes in function "checkPruningPointViolation": If header = genesis, stop checking and return nil.

* [Issue-1126] In function "checkPruningPointViolation" - change from a for loop to the "IsAncestorOfAny" function.

* [#1126] "FindNextPruningPoint" - save the pruning point in case the point is the genesis and change code internal order.

* [#1126] "FindNextPruningPoint" - cosmetics change.

* [#1126] "FindNextPruningPoint" - remove "return nil" when there is no pruning point on the if expression.

Co-authored-by: tal <tal@daglabs.com>
2020-11-30 09:57:15 +02:00
stasatdaglabs
a1af992d15 [NOD-1578] Fix areHeaderTipsSyncedMaxTimeDifference (#1157)
* [NOD-1578] Fix areHeaderTipsSyncedMaxTimeDifference.

* [NOD-1578] Return errors that occur in the new logClosure.
2020-11-29 10:44:50 +02:00
Svarog
048caebda3 [NOD-1551] Add SigCache to TransactionValidator + Option to manipulate it in TestConsensus (#1159)
* [NOD-1551] Add SigCache

* [NOD-1551] Add option to edit SigCache in TestConsensus

* [NOD-1551] Fix comments and make SetSigCache pointer-receiver
2020-11-29 10:18:00 +02:00
oudeis
baa4311a34 Update to version 0.8.2 2020-11-29 05:12:30 +00:00
alexandratran
f6dfce8180 Update README.md 2020-11-26 21:46:57 -08:00
Ori Newman
0e91b44fc6 [NOD-1577] Change cache size to 200 (#1156) 2020-11-26 17:11:49 +02:00
Svarog
f7fa823f17 [NOD-1551] Requirements for performance tests (#1154)
* [NOD-1551] Add NewTestConsensusWithDataDir to factory

* [NOD-1551] Cache transaction ID

* [NOD-1551] Should return err if err != nil

* [NOD-1551] BuildBlockWithParents returns the blocks pastUTXOData

* [NOD-1551] Set BlockCoinbaseMaturity to 0 in TestDoubleSpends

* [NOD-1551] Fix comments

* --amend

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2020-11-26 12:12:01 +02:00
Svarog
546ea83123 [NOD-1570] Fix the way UTXO iterators work (#1153)
* [NOD-1570] Implement utxo.IteratorWithDiff

* [NOD-1570] Utilize utxo.ITeratorWithDiff in RestorePastUTXOSetIterator and VirtualUTXOSetIterator

* [NOD-1570] Fix comment
2020-11-25 18:28:42 +02:00
Elichai Turkel
f9c2137344 [RES-65] Add a test for BoundedMergeDepth - new (#1131)
* Test bounded merge depth

* Fix a bug in GetBlockInfo, where trying to use reachability on an invalid block

* Add a test to reproduce and test the GetBlockInfo bug
2020-11-25 13:42:55 +02:00
stasatdaglabs
0fa13357c3 [NOD-1566] Add caching to all stores (#1152)
* [NOD-1566] Add a dependency to golang-lru.

* [NOD-1566] Add caching to blockstore.go.

* [NOD-1566] Add LRUCache to all store objects and initialize them.

* [NOD-1566] Add caching to acceptanceDataStore.

* [NOD-1566] Add caching to blockHeaderStore.

* [NOD-1566] Implement a simpler LRU cache.

* [NOD-1566] Use the simpler cache implementation everywhere.

* [NOD-1566] Remove dependency in golang-lru.

* [NOD-1566] Fix object reuse issues in store Get functions.

* [NOD-1566] Add caching to blockRelationStore.

* [NOD-1566] Add caching to blockStatusStore.

* [NOD-1566] Add caching to ghostdagDataStore.

* [NOD-1566] Add caching to multisetStore.

* [NOD-1566] Add caching to reachabilityDataStore.

* [NOD-1566] Add caching to utxoDiffStore.

* [NOD-1566] Add caching to reachabilityReindexRoot.

* [NOD-1566] Add caching to pruningStore.

* [NOD-1566] Add caching to headerTipsStore.

* [NOD-1566] Add caching to consensusStateStore.

* [NOD-1566] Add comments explaining why we don't discard staging at the normal location in consensusStateStore.

* [NOD-1566] Make go vet happy.

* [NOD-1566] Fix merge errors.

* [NOD-1566] Add a missing break statement.

* [NOD-1566] Run go mod tidy.

* [NOD-1566] Remove serializedUTXOSetCache.
2020-11-25 13:41:13 +02:00
Ori Newman
5b2fae0457 [NOD-1568] Add staticcheck checks (#1150) 2020-11-25 11:43:51 +02:00
Ori Newman
3bad9ec1eb [NOD-1569] Stop using ReceiveFromChanWhenDone (#1151) 2020-11-25 11:30:07 +02:00
Ori Newman
45d9b63572 [NOD-1567] Add clone methods to data stores types (#1149)
* [NOD-1567] Add clone methods to data stores types

* [NOD-1567] Fix comments

* [NOD-1567] Fix test
2020-11-24 17:56:18 +02:00
Elichai Turkel
afc634d871 Add TestCheckBlockSanity back (#1137) 2020-11-24 16:57:40 +02:00
Ori Newman
2334f8b4eb [NOD-1564] Add TestChainedTransactions (#1145)
* [NOD-1564] Add TestChainedTransactions

* [NOD-1564] Fix errors
2020-11-24 11:42:53 +02:00
stasatdaglabs
d65f382c80 [NOD-1565] Reorder getSyncInfo in a way that won't unnecessarily call HeaderTipsPruningPoint. (#1146) 2020-11-24 11:34:02 +02:00
Ori Newman
2096a28d1c [NOD-1563] Add TestMaxHeaders (#1144) 2020-11-23 18:33:45 +02:00
Ori Newman
96d9e5800f [NOD-1561] Add TestCheckParentsIncest and fix validation order (#1143) 2020-11-23 18:27:44 +02:00
Ori Newman
8264369c81 [NOD-1561] Add TestValidateMedianTime (#1141)
* [NOD-1561] Add TestValidateMedianTime

* [NOD-1561] Remove redundant variable
2020-11-23 17:18:30 +02:00
Ori Newman
bb2d7f72ac [NOD-1560] Add TestValidateTransactionInIsolation (#1140)
* [NOD-1560] Add TestValidateTransactionInIsolation

* [NOD-1560] Make ForAllNets copy the params before mutating them

* [NOD-1560] Remove redundant continue

* [NOD-1560] Don't change finality duration
2020-11-23 16:28:59 +02:00
Ori Newman
c1505b4748 [NOD-1555] Use stageDiff to update virtualDiffParents (#1139)
* [NOD-1555] Filter ancestors in updateVirtualDiffParents

* [NOD-1555] Use stageDiff to update virtualDiffParents

* [NOD-1555] Don't add existing blocks in addToVirtualDiffParents

* [NOD-1555] Remove redundant check

* [NOD-1555] Fix log and rename removeAncestorsFromVirtualDiffParents->removeAncestorsFromVirtualDiffParentsAndAssignDiffChild

* [NOD-1555] Add logs

* [NOD-1555] Fix comment

* [NOD-1555] Fix logs
2020-11-23 15:09:39 +02:00
stasatdaglabs
dec9ef5f75 [NOD-1555] Implement TestResolveBlockStatusSanity (#1138)
* [NOD-1555] Implement TestResolveBlockStatusSanity.

* [NOD-1555] Fix the test name string.
2020-11-23 14:29:41 +02:00
Mike Zak
5211727206 [NOD-1557] Cover the consensusStateManager package in trace logs (#1135)
* [NOD-1557] Add trace logs in add_block_to_virtual.go.

* [NOD-1557] Add trace logs in resolve_block_status.go.

* [NOD-1557] Add trace logs in calculate_past_utxo.go.

* [NOD-1557] Add trace logs in finality.go.

* [NOD-1557] Add trace logs in multisets.go.

* [NOD-1557] Fix compilation errors.

* [NOD-1557] Add trace logs to verify_and_build_utxo.go.

* [NOD-1557] Add trace logs to update_virtual.go.

* [NOD-1557] Add trace logs to set_pruning_utxo_set.go.

* [NOD-1557] Add trace logs to populate_tx_with_utxo_entries.go.

* [NOD-1557] Add trace logs to pick_virtual_parents.go.

* [NOD-1557] Make go vet happy.

* [NOD-1557] Clarify that some logic in AddBlockToVirtual is there for the sake of logging alone.

* [NOD-1557] Call blockStatusStore directly in AddBlockToVirtual when refetching the block status.
2020-11-23 13:08:10 +02:00
Elichai Turkel
fafe1d534f Add TestSequenceLocksActive back (#1133) 2020-11-22 17:17:39 +02:00
Elichai Turkel
c56a5336f3 Re-add TestPruningDepth (#1132) 2020-11-22 17:04:13 +02:00
Elichai Turkel
b3a3121725 Add TestFinality back (#1129)
* Add VirtualFinalityPoint to TestConsensusStateManager

* Add TestFinality back
2020-11-22 12:30:27 +02:00
Svarog
950dd0cc8d [NOD-1556] Add some logs (#1110)
* [NOD-1556] Add logs regarding block status and virtual blue score

* [NOD-1556] UTXODiffAlgebra: add the offending outpoint to the text of errors

* [NOD-1556] Make checkIntersectionWithRule return ok as well
2020-11-19 11:17:05 +02:00
stasatdaglabs
bb244706ea [NOD-1543] Optimize the performance of Count() in BlockHeaderStore and BlockStore (#1109)
* [NOD-1543] Optimize Count() in BlockHeaderStore.

* [NOD-1543] Optimize Count() in BlockStore.

* [NOD-1543] Fix commitCount.

* [NOD-1543] Explicitly initialize count to 0.
2020-11-18 16:35:32 +02:00
stasatdaglabs
ed386bbc8f [NOD-1550] Don't request blocks for invs that are known to be orphans (#1108)
* [NOD-1550] Implement IsOrphan().

* [NOD-1550] Don't request blocks for invs that are known to be orphans.
2020-11-18 13:37:14 +02:00
stasatdaglabs
75d21d39cc [NOD-1549] Properly handle errors in unorphanBlock (#1107)
* [NOD-1549] In AddBlock, simply log RuleErrors.

* [NOD-1549] Properly handle errors in unorphanBlock.
2020-11-18 12:19:30 +02:00
Elichai Turkel
3f92ddd827 Add blueScore to RPC GetBlock, and add more INFO logs (#1103)
* Add BlueScore to RPC command GetBlock

* Add info logs when getting new blocks from the p2p
2020-11-18 11:19:12 +02:00
Ori Newman
8500acd86b [NOD-1548] Remove PoW check from tests (#1105)
* [NOD-1548] Add TestDifficulty and remove PoW check from tests

* [NOD-1548] Add TestSkipProofOfWork

* [NOD-1548] Remove TestDifficulty
2020-11-18 10:27:29 +02:00
Elichai Turkel
5b037950d8 Fix double printing the mainnet has not launched yet message (#1101) 2020-11-18 09:16:58 +02:00
stasatdaglabs
184911f76e [NOD-1547] Make the SendAddresses flow not one-time for the sake of DNSSeeder (#1104)
* [NOD-1547] Make the SendAddresses flow not one-time for the sake of DNSSeeder.

* [NOD-1547] Add all special commands to chooseRouteForCommand.
2020-11-17 18:05:14 +02:00
stasatdaglabs
7479f5f5e8 [NOD-1545] Fix incorrect block difficulty calculation in buildHeader. (#1102) 2020-11-17 16:40:55 +02:00
Ori Newman
891095563e Fix blocks order (#1099) 2020-11-17 16:00:16 +02:00
Ori Newman
60c24d8dea Fix TestBlueBlockWindow (#1098)
* Fix TestBlueBlockWindow

* Add comments
2020-11-17 16:00:16 +02:00
Svarog
d4993c1d06 [NOD-1542] Don't try to return more addresses then we have (#1097)
* [NOD-1542] Don't try to return more addresses then we have

* [NOD-1542] Allocate according to updated count
2020-11-17 16:00:16 +02:00
Elichai Turkel
c785ca0e52 Add more compactBits tests (#1096) 2020-11-17 16:00:16 +02:00
Svarog
9eb5c4a0ed [NOD-1532] Make all nets equal in mining difficulty (#1095)
* [NOD-1532] Make all nets equal in mining difficulty

* [NOD-1532] Fix comments
2020-11-17 16:00:16 +02:00
stasatdaglabs
9d5d1b02dc [NOD-1538] Implement a simple orphan pool (#1093)
* [NOD-1538] Implement a simple orphan pool.

* [NOD-1538] Connect the orphan pool to the appropriate flows.

* [NOD-1538] Make UnorphanBlocks actually unorphan blocks.

* [NOD-1538] Fix logs.

* [NOD-1538] Make unorphaned blocks call LogBlock.

* [NOD-1538] Fix a log and some bad names.

* [NOD-1538] Don't return an error from LogBlock.

* [NOD-1538] Pass a pointer to hash in findChildOrphansOfBlock.

* [NOD-1538] Extract addChildOrphansToProcessQueue to a separate function.
2020-11-17 16:00:16 +02:00
stasatdaglabs
213be67c47 [NOD-1538] Fix isBlockInHeaderPruningPointFuture. (#1094) 2020-11-17 16:00:16 +02:00
Ori Newman
14d7ab5fc6 Add TestBigToCompact and TestCompactToBig (#1092)
* Add TestBigToCompact and TestCompactToBig

* Add tests
2020-11-17 16:00:16 +02:00
Mike Zak
7224d58940 [NOD-1532] Add comments 2020-11-17 16:00:16 +02:00
Mike Zak
b2188f5993 [NOD-1532] AlwaysCallResolveBlockStatus in BuildBlock + Fixes to make it work if there's nothing to resolve 2020-11-17 16:00:16 +02:00
Mike Zak
dbd15aecf5 [NOD-1532] Invert condition in isViolatingFinality 2020-11-17 16:00:16 +02:00
Mike Zak
66f5a5bd7d [NOD-1532] Genesis is not violating finality by definition 2020-11-17 16:00:16 +02:00
Mike Zak
c994200878 [NOD-1532] ResolveBlockStatus should return the blockStatus 2020-11-17 16:00:16 +02:00
Ori Newman
7050ebeac9 [NOD-1541] Add TestPastMedianTime (#1091) 2020-11-17 16:00:16 +02:00
Svarog
f2df48139f [NOD-1532] Remove virtual from ParentChildren when checking for virtualSelectedParent candidates (#1089)
* [NOD-1532] Remove virtual from ParentChildren when checking for virtualSelectedParent candidates

* [NOD-1532] Fix minor issues
2020-11-17 16:00:16 +02:00
stasatdaglabs
48d8137604 [NOD-1538] Implement GetBlockCount. 2020-11-17 16:00:16 +02:00
stasatdaglabs
310cf0bb9b [NOD-1538] Remove bad check in selectPeerForIBD. 2020-11-17 16:00:16 +02:00
Ori Newman
b6c47fdd21 [NOD-1535] fix reachability tests (#1087)
* [NOD-1535] Don't use pointer to outpoint when serializing

* [NOD-1535] Fix reachability tests
2020-11-17 16:00:16 +02:00
Ori Newman
e6a2b7366f [NOD-1535] Don't use pointer to outpoint when serializing (#1086) 2020-11-17 16:00:16 +02:00
Mike Zak
d8f72e2b27 [NOD-1532] Update VirtualUTXODiffParents diffs even if list didn't change 2020-11-17 16:00:16 +02:00
stasatdaglabs
08749deaeb [NOD-1538] Fix mempool not wrapping consensus errors and bad invalid message handling (#1082)
* [NOD-1538] Correct messages.proto.

* [NOD-1538] Fix invalid message handling.

* [NOD-1538] Fix mempool not wrapping consensus errors.

* [NOD-1538] Extract wrapping logic to a separate function.

* [NOD-1538] Extract wrapping logic to an even better separate function.
2020-11-17 16:00:16 +02:00
Mike Zak
83a88d9989 [NOD-1532] newUTXOSetIterator should start with -1 index 2020-11-17 16:00:16 +02:00
Mike Zak
151910c27a [NOD-1532] Check UTXOCommitment for all blocks 2020-11-17 16:00:16 +02:00
Mike Zak
fca8ed57bd [NOD-1532] Add another block in TestUTXOCommitment 2020-11-17 16:00:16 +02:00
Ori Newman
56679818be [NOD-1535] Add non coinbase transactions to diff (#1084) 2020-11-17 16:00:16 +02:00
Mike Zak
f07f2edad2 [NOD-1532] Properly deal with selectedParentStatuses in buildBlockWithParents 2020-11-17 16:00:16 +02:00
Mike Zak
2dcfe90850 [NOD-1532] Shouldn't update parent diff if the parent is not UTXO-verified 2020-11-17 16:00:16 +02:00
Mike Zak
dc80a39c54 [NOD-1532] OpTrueScript should also return the redeem script 2020-11-17 16:00:16 +02:00
Mike Zak
34be898491 [NOD-1532] utxoSetIterator should be a pointer receiver 2020-11-17 16:00:16 +02:00
Mike Zak
f4a2fbf64f [NOD-1532] Fixes in updateVirtualDiffParents 2020-11-17 16:00:16 +02:00
Ori Newman
a0c6076ccc [NOD-1535] Add new block to virtual diff parents only if it's valid (#1077) 2020-11-17 16:00:16 +02:00
Mike Zak
fddce00d08 [NOD-1532] Fixes in updateVirtualDiffParent 2020-11-17 16:00:16 +02:00
Mike Zak
ae682d59f7 [NOD-1532] Fixes in updateVirtualDiffParent 2020-11-17 16:00:16 +02:00
Ori Newman
347f3de15c [NOD-1535] fix reachability test (#1075)
* [NOD-1535] Don't compare pointers

* [NOD-1535] Fix condition on updateVirtualDiffParents
2020-11-17 16:00:16 +02:00
stasatdaglabs
a34091991a [NOD-1538] Fix MinimalNetAdapter and don't insert BlockRelations before making sure the block's parents exist (#1074)
* [NOD-1538] Fix minimal net adapter.

* [NOD-1538] Don't insert block relation until we've validated that the block's parents exist.

* [NOD-1538] Don't hold addressManager in MinimalNetAdapter.

* [NOD-1538] Fix a comment in messages.proto.
2020-11-17 16:00:16 +02:00
Mike Zak
efe1986a56 [NOD-1532] Don't validate coinbase transaction in normal flow 2020-11-17 16:00:16 +02:00
Mike Zak
3ab507b66f [NOD-1532] Use correct coinbase transaction in buildBlockWith Parents 2020-11-17 16:00:16 +02:00
Ori Newman
afbad73c0b [NOD-1535] Don't compare pointers (#1072) 2020-11-17 16:00:16 +02:00
Mike Zak
a1fa17d872 [NOD-1532] Add DiscardAllStores to TestConsensus 2020-11-17 16:00:16 +02:00
Ori Newman
b50421beee [NOD-1535] Don't reuse pointers on loop (#1069)
* [NOD-1535] Don't reuse pointers on loop

* [NOD-1535] Don't reuse pointers on loop
2020-11-17 16:00:16 +02:00
Mike Zak
aeded07815 [NOD-1532] Make BuildBlockWithParents resolve the status of the new block's selectedParent 2020-11-17 16:00:16 +02:00
Mike Zak
7d14f24b84 [NOD-1532] Fix some error messages 2020-11-17 16:00:16 +02:00
Mike Zak
c52b8100c6 [NOD-1532] make dagtopologymanager test external 2020-11-17 16:00:16 +02:00
Mike Zak
f52cddc25c [NOD-1532] Remove consensus rule that requires blocks are sorted by hash 2020-11-17 16:00:16 +02:00
Ori Newman
fc5e39f6cc [NOD-1535] fix reachability test (#1061)
* Revert "[NOD-1500] Delete integration tests"

This reverts commit fcb57a2066.

* [NOD-1518] hashserialization -> consenusserialization

* [NOD-1518] Fix add genesis to virtual

* [NOD-1518] Fix a bug in SerializeCoinbasePayload.

* [NOD-1518] Fix a loop error and make pastMedianTime behave correctly everywhere on genesis.

* [NOD-1518] Fix another bug and an infinite loop.

* [NOD-1518] Fix uninitialized slice.

* [NOD-1518] Fix bad should-commit checks and another infinite loop.

* [NOD-1518] Fix nil serialization.

* [NOD-1518] Rename blockHash to currentBlockHash.

* [NOD-1518] Move the check whether stagedVirtualUTXOSet != nil to the top of commitVirtualUTXODiff.

* [NOD-1518] Simplify utxoDiffStore.Commit.

* [NOD-1518] Unextract resolveBlockStatusAndCheckFinality.

* [NOD-1518] Move no-transactions logic into CalculateIDMerkleRoot.

* [NOD-1518] Remove redundant is-staged check.

* [NOD-1518] Fix merge errors.

* [NOD-1518] Don't write anything if utxoDiffChild is nil.

* [NOD-1518] Stage virtualAcceptanceData and virtualMultiset.

* [NOD-1518] Fix bugs in getBlockTemplate and submitBlock.

* [NOD-1518] Fix bad validation order in validateHeaderInContext.

* [NOD-1518] Fix bug in Next().

* [NOD-1518] Fix nil dereference of subnetworks in AddressCache.

* [NOD-1518] Fix multisetStore.Get returning a pointer to a multiset that is changed in place.

* [NOD-1518] Break on genesis in countSubtrees.

* [NOD-1518] Fix createBlockLocator.

* [NOD-1518] Fix MsgTxToDomainTransaction.

* [NOD-1518] Set MaxTxVersion to 1.

* [NOD-1518] Fix missing error handling, bug in MsgTxToDomainTransaction, and bad subnetwork equality check.

* [NOD-1518] Fix bug in hasUTXOByOutpointFromStagedVirtualUTXODiff.

* [NOD-1518] Remove irrelevant comments.

* [NOD-1518] Generate transactions with sufficient fee in tx_relay_test.

* [NOD-1518] Fix broken RPC handlers.

* [NOD-1518] Fix merge errors.

* [NOD-1518] Fix bad exists check in restorePastUTXO and missing genesis check in CalculatePastUTXOAndAcceptanceData.

* [NOD-1518] Add a comment.

* [NOD-1518] Use a regular mutex instead of a read-write mutex in consensus to avoid dealing with sneaky not-actually-read functions.

* [NOD-1518] Fix a deadlock in GetVirtualSelectedParent.

* [NOD-1518] Fix missing handler registration for CmdHeader.

* [NOD-1518] Fix processHeader calling OnNewBlock and LogBlock. Also fix conversion errors in IBDRootUTXOSetAndBlock.

* [NOD-1518] Fix bad Command() in MsgIBDRootUTXOSetAndBlock.

* [NOD-1518] Fix bad SyncStateMissingUTXOSet logic in resolveSyncState.

* [NOD-1518] Rename mode to syncState.

* [NOD-1518] Fix headers-only blocks coming in after the consensus thinks it's synced.

* [NOD-1518] Fix selectedChildIterator.Next not ignoring virtual, infinite loop in HashSet.Length().

* [NOD-1518] Fix not-properly wrapped IBD blocks.

* [NOD-1518] Fix bad conversion in RequestIBDBlocks.

* [NOD-1518] Fix bad string for CmdRequestHeaders.

* [NOD-1518] Fix bad string for CmdDoneHeaders.

* [NOD-1518] Fix bad Command() for MsgIBDRootNotFound.

* [NOD-1518] Fix bad areHeaderTipsSyncedMaxTimeDifference value.

* [NOD-1518] Add missing string for CmdRequestIBDBlocks.

* [NOD-1518] Fix bad check for SyncStateMissingBlockBodies.

* [NOD-1518] Fix bad timeout durations in tests.

* [NOD-1518] Fix IBD blocks not calling OnNewBlock.

* [NOD-1518] Change when IBD finishes.

* [NOD-1518] Properly clone utxoDiffChild.

* [NOD-1535] Fix reachability tests

* [NOD-1518] Fix merge errors.

* [NOD-1518] Move call to LogBlock to into OnNewBlock.

* [NOD-1518] Return "not implemented" in unimplemented RPC handlers.

* [NOD-1518] Extract cloning of hashes to a method over DomainHash.

* [NOD-1518] Use isHeaderOnlyBlock.

* [NOD-1518] Use constants.TransactionVersion.

* [NOD-1518] Break immediately if we reached the virtual in SelectedChildIterator.

* [NOD-1518] Don't stage nil utxoDiffChild.

* [NOD-1518] Properly check the genesis hash in CalculatePastUTXOAndAcceptanceData.

* [NOD-1518] Explain why we break on current == nil in countSubtrees.

* [NOD-1518] Add a comment explaining why we check against StatusValid in resolveSyncState.

* [NOD-1535] Add external reachability tests

* [NOD-1535] Fix reachability tests and fix related bugs

* [NOD-1535] Add setters fox reindex slack and window

* [NOD-1535] Remove redundant line

* [NOD-1535] Add comment

* [NOD-1535] Fix comments

* [NOD-1535] Rename DBReader->DatabaseContext

* [NOD-1535] Check that reindex root is changed

* [NOD-1535] Fix calculateNewTips

Co-authored-by: Mike Zak <feanorr@gmail.com>
Co-authored-by: stasatdaglabs <stas@daglabs.com>
2020-11-17 16:00:16 +02:00
Svarog
8ccf381fc7 [NOD-1532] csm unit tests (#1059)
* Revert "[NOD-1500] Delete integration tests"

This reverts commit fcb57a2066.

* [NOD-1518] hashserialization -> consenusserialization

* [NOD-1518] Fix add genesis to virtual

* [NOD-1518] Fix a bug in SerializeCoinbasePayload.

* [NOD-1518] Fix a loop error and make pastMedianTime behave correctly everywhere on genesis.

* [NOD-1518] Fix another bug and an infinite loop.

* [NOD-1518] Fix uninitialized slice.

* [NOD-1518] Fix bad should-commit checks and another infinite loop.

* [NOD-1518] Fix nil serialization.

* [NOD-1518] Rename blockHash to currentBlockHash.

* [NOD-1518] Move the check whether stagedVirtualUTXOSet != nil to the top of commitVirtualUTXODiff.

* [NOD-1518] Simplify utxoDiffStore.Commit.

* [NOD-1518] Unextract resolveBlockStatusAndCheckFinality.

* [NOD-1518] Move no-transactions logic into CalculateIDMerkleRoot.

* [NOD-1518] Remove redundant is-staged check.

* [NOD-1518] Fix merge errors.

* [NOD-1518] Don't write anything if utxoDiffChild is nil.

* [NOD-1518] Stage virtualAcceptanceData and virtualMultiset.

* [NOD-1518] Fix bugs in getBlockTemplate and submitBlock.

* [NOD-1518] Fix bad validation order in validateHeaderInContext.

* [NOD-1518] Fix bug in Next().

* [NOD-1518] Fix nil dereference of subnetworks in AddressCache.

* [NOD-1518] Fix multisetStore.Get returning a pointer to a multiset that is changed in place.

* [NOD-1518] Break on genesis in countSubtrees.

* [NOD-1518] Fix createBlockLocator.

* [NOD-1518] Fix MsgTxToDomainTransaction.

* [NOD-1518] Set MaxTxVersion to 1.

* [NOD-1518] Fix missing error handling, bug in MsgTxToDomainTransaction, and bad subnetwork equality check.

* [NOD-1518] Fix bug in hasUTXOByOutpointFromStagedVirtualUTXODiff.

* [NOD-1518] Remove irrelevant comments.

* [NOD-1518] Generate transactions with sufficient fee in tx_relay_test.

* [NOD-1518] Fix broken RPC handlers.

* [NOD-1518] Fix merge errors.

* [NOD-1518] Fix bad exists check in restorePastUTXO and missing genesis check in CalculatePastUTXOAndAcceptanceData.

* [NOD-1518] Add a comment.

* [NOD-1518] Use a regular mutex instead of a read-write mutex in consensus to avoid dealing with sneaky not-actually-read functions.

* [NOD-1518] Fix a deadlock in GetVirtualSelectedParent.

* [NOD-1518] Fix missing handler registration for CmdHeader.

* [NOD-1518] Fix processHeader calling OnNewBlock and LogBlock. Also fix conversion errors in IBDRootUTXOSetAndBlock.

* [NOD-1518] Fix bad Command() in MsgIBDRootUTXOSetAndBlock.

* [NOD-1518] Fix bad SyncStateMissingUTXOSet logic in resolveSyncState.

* [NOD-1518] Rename mode to syncState.

* [NOD-1518] Fix headers-only blocks coming in after the consensus thinks it's synced.

* [NOD-1518] Fix selectedChildIterator.Next not ignoring virtual, infinite loop in HashSet.Length().

* [NOD-1518] Fix not-properly wrapped IBD blocks.

* [NOD-1532] Add TestMultiset

* [NOD-1518] Fix bad conversion in RequestIBDBlocks.

* [NOD-1518] Fix bad string for CmdRequestHeaders.

* [NOD-1518] Fix bad string for CmdDoneHeaders.

* [NOD-1518] Fix bad Command() for MsgIBDRootNotFound.

* [NOD-1532] Add TestPastUTXOMultiset

* [NOD-1518] Fix bad areHeaderTipsSyncedMaxTimeDifference value.

* [NOD-1532] Added TestDoubleSpends

* [NOD-1518] Add missing string for CmdRequestIBDBlocks.

* [NOD-1518] Fix bad check for SyncStateMissingBlockBodies.

* [NOD-1518] Fix bad timeout durations in tests.

* [NOD-1518] Fix IBD blocks not calling OnNewBlock.

* [NOD-1518] Change when IBD finishes.

* [NOD-1518] Properly clone utxoDiffChild.

* [NOD-1532] Update hashes of blocks

* [NOD-1532] Fix genesis blocks and a few more bugs

* [NOD-1532] Bugfix: incorrect key passed to dbTx.Put

* [NOD-1532] Make sure there's no nil payloads

* [NOD-1532] Fix AddBlockToVirtual

* [NOD-1532] Update tips and virtualDiffParents properly

* [NOD-1532] Allow nil payload

* [NOD-1532] Check for actual error and not just some RuleError

* [NOD-1532] Get rid of SimpleCoinbaseData and make OpTrueScript P2SH

* [NOD-1532] If coinbaseData is nil - fill in with generic coinbaseData

Co-authored-by: Ori Newman <orinewman1@gmail.com>
Co-authored-by: stasatdaglabs <stas@daglabs.com>
2020-11-17 16:00:16 +02:00
stasatdaglabs
f320887bff [NOD-1538] Fix bad allocation in notBannedAddressesWithException. 2020-11-17 16:00:16 +02:00
stasatdaglabs
eef5e3768c [NOD-1518] Fix genesis block insertion and integration tests (#1013)
* Revert "[NOD-1500] Delete integration tests"

This reverts commit fcb57a2066.

* [NOD-1518] hashserialization -> consenusserialization

* [NOD-1518] Fix add genesis to virtual

* [NOD-1518] Fix a bug in SerializeCoinbasePayload.

* [NOD-1518] Fix a loop error and make pastMedianTime behave correctly everywhere on genesis.

* [NOD-1518] Fix another bug and an infinite loop.

* [NOD-1518] Fix uninitialized slice.

* [NOD-1518] Fix bad should-commit checks and another infinite loop.

* [NOD-1518] Fix nil serialization.

* [NOD-1518] Rename blockHash to currentBlockHash.

* [NOD-1518] Move the check whether stagedVirtualUTXOSet != nil to the top of commitVirtualUTXODiff.

* [NOD-1518] Simplify utxoDiffStore.Commit.

* [NOD-1518] Unextract resolveBlockStatusAndCheckFinality.

* [NOD-1518] Move no-transactions logic into CalculateIDMerkleRoot.

* [NOD-1518] Remove redundant is-staged check.

* [NOD-1518] Fix merge errors.

* [NOD-1518] Don't write anything if utxoDiffChild is nil.

* [NOD-1518] Stage virtualAcceptanceData and virtualMultiset.

* [NOD-1518] Fix bugs in getBlockTemplate and submitBlock.

* [NOD-1518] Fix bad validation order in validateHeaderInContext.

* [NOD-1518] Fix bug in Next().

* [NOD-1518] Fix nil dereference of subnetworks in AddressCache.

* [NOD-1518] Fix multisetStore.Get returning a pointer to a multiset that is changed in place.

* [NOD-1518] Break on genesis in countSubtrees.

* [NOD-1518] Fix createBlockLocator.

* [NOD-1518] Fix MsgTxToDomainTransaction.

* [NOD-1518] Set MaxTxVersion to 1.

* [NOD-1518] Fix missing error handling, bug in MsgTxToDomainTransaction, and bad subnetwork equality check.

* [NOD-1518] Fix bug in hasUTXOByOutpointFromStagedVirtualUTXODiff.

* [NOD-1518] Remove irrelevant comments.

* [NOD-1518] Generate transactions with sufficient fee in tx_relay_test.

* [NOD-1518] Fix broken RPC handlers.

* [NOD-1518] Fix merge errors.

* [NOD-1518] Fix bad exists check in restorePastUTXO and missing genesis check in CalculatePastUTXOAndAcceptanceData.

* [NOD-1518] Add a comment.

* [NOD-1518] Use a regular mutex instead of a read-write mutex in consensus to avoid dealing with sneaky not-actually-read functions.

* [NOD-1518] Fix a deadlock in GetVirtualSelectedParent.

* [NOD-1518] Fix missing handler registration for CmdHeader.

* [NOD-1518] Fix processHeader calling OnNewBlock and LogBlock. Also fix conversion errors in IBDRootUTXOSetAndBlock.

* [NOD-1518] Fix bad Command() in MsgIBDRootUTXOSetAndBlock.

* [NOD-1518] Fix bad SyncStateMissingUTXOSet logic in resolveSyncState.

* [NOD-1518] Rename mode to syncState.

* [NOD-1518] Fix headers-only blocks coming in after the consensus thinks it's synced.

* [NOD-1518] Fix selectedChildIterator.Next not ignoring virtual, infinite loop in HashSet.Length().

* [NOD-1518] Fix not-properly wrapped IBD blocks.

* [NOD-1518] Fix bad conversion in RequestIBDBlocks.

* [NOD-1518] Fix bad string for CmdRequestHeaders.

* [NOD-1518] Fix bad string for CmdDoneHeaders.

* [NOD-1518] Fix bad Command() for MsgIBDRootNotFound.

* [NOD-1518] Fix bad areHeaderTipsSyncedMaxTimeDifference value.

* [NOD-1518] Add missing string for CmdRequestIBDBlocks.

* [NOD-1518] Fix bad check for SyncStateMissingBlockBodies.

* [NOD-1518] Fix bad timeout durations in tests.

* [NOD-1518] Fix IBD blocks not calling OnNewBlock.

* [NOD-1518] Change when IBD finishes.

* [NOD-1518] Properly clone utxoDiffChild.

* [NOD-1518] Fix merge errors.

* [NOD-1518] Move call to LogBlock to into OnNewBlock.

* [NOD-1518] Return "not implemented" in unimplemented RPC handlers.

* [NOD-1518] Extract cloning of hashes to a method over DomainHash.

* [NOD-1518] Use isHeaderOnlyBlock.

* [NOD-1518] Use constants.TransactionVersion.

* [NOD-1518] Break immediately if we reached the virtual in SelectedChildIterator.

* [NOD-1518] Don't stage nil utxoDiffChild.

* [NOD-1518] Properly check the genesis hash in CalculatePastUTXOAndAcceptanceData.

* [NOD-1518] Explain why we break on current == nil in countSubtrees.

* [NOD-1518] Add a comment explaining why we check against StatusValid in resolveSyncState.

Co-authored-by: Mike Zak <feanorr@gmail.com>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2020-11-12 15:19:39 +02:00
Ori Newman
7a7821e1c8 [NOD-1313] Refactor AddressManager (#918) (#1049)
* [NOD-1313] Refactor AddressManager (#918)

* [NOD-1313] Refactor AddressManager.

* [NOD-1313]Remove old tests.Minor improvements,fixes.

* [NOD-1313] After merge fixes. Fix import cycle.

* [NOD-1313] Integration tests fixes.

* [NOD-1313] Allocate new slice for the returned key.

* [NOD-1313] AddressManager improvements and fixes.

* Move local and banned addresses to separate lists.
* Move AddressManager config to the separate file.
* Add LocalAddressManager.
* Remove redundant KnownAddress structure.
* Restore local addresses functionality.
* Call initListeners from the LocalAddressManager.
* AddressManager minor improvements and fixes.

* [NOD-1313] Minor fixes.

* [NOD-1313] Implement HandleGetPeerAddresses. Refactoring.

* [NOD-1313] After-merge fixes.

* [NOD-1313] Minor improvements.

* AddressManager: added BannedAddresses() method.
* AddressManager: HandleGetPeerAddresses() add banned addresses
  separately.
* AddressManager: remove addressEntry redundant struct.
* ConnectionManager: checkOutgoingConnections() minor improvements and
  fixes.
* Minor refactoring.
* Minor fixes.

* [NOD-1313] GetPeerAddresses RPC message update

* GetPeerAddresses RPC: add BannedAddresses in the separate field.
* Update protobuf.

* [NOD-1534] Update messages.pb.go

Co-authored-by: Kirill <gammerxpower@gmail.com>
2020-11-12 14:40:41 +02:00
Svarog
37fbdcb453 [NOD-1526] Restore txscript tests (#1019)
* [NOD-1526] Fix compilation errors

* [NOD-1526] Make MsgTx.PayloadHash non-pointer

* [NOD-1526] Fixed many tests

* [NOD-1526] Fix reference_test.go

* [NOD-1526] Removed last instances of appmessage in consensus

* [NOD-1526] No need to check for subnetwork
2020-11-12 10:22:17 +02:00
Svarog
135ffbd4f2 [NOD-1529] Add getters + AddBlock to TestConsensus (#1025)
* [NOD-1529] Add all stores and processes to consensus, and add access to TestConsensus

* [NOD-1529] Move the getters of TestConsensus to separate file

* [NOD-1529] Add AddBlock to TestConsensus

* [NOD-1529] Update NewTestConsensus to be more all-encompassing

* [NOD-1529] Remove test directory in teardown

* [NOD-1529] Add ForAllNets function

* [NOD-1529] Add comment
2020-11-11 12:31:13 +02:00
Ori Newman
4736213ba4 [NOD-1528] Make data stores copy data on stage (#1020)
* [NOD-1528] Make data stores copy data on stage

* [NOD-1528] Add proto objects to serialize consensus state objects

* [NOD-1528] Fix receiver names

* [NOD-1528] Add copy to block store and utxo diff staging

* [NOD-1528] Return errors where needed
2020-11-10 18:32:42 +02:00
oudeis
8290fadd3a [NOD-1521] use staticcheck (#1015)
* [NOD-1521] Use static check as part of jenkins to check for swallowed errors

* [NOD-1521] added staticcheck installation

* [NOD-1521] Fix static check errors

Co-authored-by: Ori Newman <orinewman1@gmail.com>
2020-11-10 17:59:35 +02:00
Ori Newman
23c1ea6c31 [NOD-1525] Implement headers first ibd (#1017)
* [NOD-1525] Implement headers first IBD

* [NOD-1525] Fix proto translators

* [NOD-1525] Register missing flows

* [NOD-1525] Rename SyncStateNormal->SyncStateRelay, simplifiy IBD peer selection code and get rid of panic in FinishIBD

* [NOD-1525] Remove redundant methods from interface
2020-11-10 16:14:51 +02:00
Ori Newman
31c5264430 [NOD-1527] Allow to process headers while in missing utxo set sync state (#1018)
* [NOD-1527] Allow to process headers while in missing utxo set sync state

* [NOD-1527] Add isHeaderOnlyBlock function
2020-11-10 14:43:18 +02:00
Ori Newman
32da4440ba [NOD-1495] Disallow non native transactions (#988)
* [NOD-1495] Disallow non native transactions

* [NOD-1495] Use deserializeUTXOSetBytes

* [NOD-1495] Delete checkNoNonNativeTransactions

* [NOD-1495] Invert condition in checkTransactionPayload

Co-authored-by: Mike Zak <feanorr@gmail.com>
2020-11-09 17:15:16 +02:00
Svarog
e7a61c7edf [NOD-1524] Add lock to consensus (#1014) 2020-11-09 16:21:09 +02:00
Svarog
6db337c8c5 [NOD-1519] Add TestAPI for BuildBlockWithParents (#1011)
* [NOD-1519] Separate BlockBuilder and BlockProcessor

* [NOD-1519] Wire blockBuilder properly + implement buildBlockWithParents

* [NOD-1519] Added testapi package, TestConsensus interface, and TestConsensus factory

* [NOD-1519] Add comments

* [NOD-1519] Separate TestBlockBuilder out of BlockBuilder

* [NOD-1519] TestBlockBuilder should also implement BlockBuilder

* [NOD-1519] Add NewTestConsensus to factory interface
2020-11-09 12:02:42 +02:00
Svarog
2282e36196 [NOD-1522] Add IsEqual to SubnetworkID (#1012)
* [NOD-1519] Add IsEqual to SubnetworkID

* [NOD-1522] Added comment
2020-11-09 10:52:57 +02:00
oudeis
72b5832f30 Update to version 0.8.0 2020-11-09 07:07:30 +00:00
Ori Newman
9a344152aa [NOD-1517] Properly initialize consensus with Genesis block (#1009)
* [NOD-1517] Properly initialize consensus with Genesis block

* [NOD-1517] Remove redundant AddHeaderTip

* [NOD-1517] Don't return nil from dbHash<->DomainHash converters

* [NOD-1517] Use pointer receivers

* [NOD-1517] Use domain block in dagParams

* [NOD-1517] Remove boolean from SelectedTip

* [NOD-1517] Rename hasHeader to isHeadersOnlyBlock

* [NOD-1517] Add comment

* [NOD-1517] Change genesis version

* [NOD-1517] Rename TestNewFactory->TestNewConsensus
2020-11-08 15:17:20 +02:00
Svarog
281944762d [NOD-1500] Glue between domain and application (#1007)
* [NOD-1500] Added Domain type and Constructor

* [NOD-1500] Replaced dag+txpool with domain in flowContext

* [NOD-1500] Replaced dag+txpool with domain in flowContext

* [NOD-1500] Converters: domain objects from/to appmessage

* [NOD-1500] Convert hashes to DomainHashes in appmessages

* [NOD-1500] Remove references to daghash in dagconfig

* [NOD-1500] Fixed all appmessage usages of hashes

* [NOD-1500] Update all RPC to use domain

* [NOD-1500] Big chunk of protocol flows re-wired to domain

* [NOD-1500] Finished re-wiring all protocol flows to new Domain

* [NOD-1500] Fix some mempool and kaspaminer compilation errors

* [NOD-1500] Deleted util/{block,tx,daghash} and dbaccess

* [NOD-1500] util.CoinbaseTransactionIndex -> transactionhelper.CoinbaseTransactionIndex

* [NOD-1500] Fix txsigner

* [NOD-1500] Removed all references to util/subnetworkid

* [NOD-1500] Update RpcGetBlock related messages

* [NOD-1500] Many more compilation fixes

* [NOD-1500] Return full list of missing blocks for orphan resolution

* [NOD-1500] Fixed handshake

* [NOD-1500] Fixed flowcontext compilation

* [NOD-1500] Update users of StartIBDIfRequired to handle error

* [NOD-1500] Removed some more fields from RPC

* [NOD-1500] Fix the getBlockTemplate flow

* [NOD-1500] Fix HandleGetCurrentNetwork

* [NOD-1500] Remove redundant code

* [NOD-1500] Remove obsolete notifications

* [NOD-1500] Split MiningManager and Consensus to separate fields in Domain

* [NOD-1500] Update two wrong references to location of txscript

* [NOD-1500] Added comments

* [NOD-1500] Fix some tests

* [NOD-1500] Removed serialization logic from appmessage

* [NOD-1500] Rename database/serialization/messages.proto to dbobjects.proto

* [NOD-1500] Delete integration tests

* [NOD-1500] Remove txsort

* [NOD-1500] Fix tiny bug

* [NOD-1500] Remove rogue dependancy on bchd

* [NOD-1500] Some stylistic fixes
2020-11-08 11:55:54 +02:00
Ori Newman
e3be67c3c7 [NOD-1516] Implement isBlockInHeaderPruningPointFuture (#1006) 2020-11-05 14:18:50 +02:00
Ori Newman
215ab512cd [NOD-1515] Allow to process pruning point while in SyncStateMissingUTXOSet (#1005) 2020-11-05 12:39:39 +02:00
stasatdaglabs
d0fc728c23 [NOD-1514] Allow full block validation during IBD. (#1004) 2020-11-05 12:18:16 +02:00
stasatdaglabs
1c710daf98 [NOD-1501] Finish implementing GetSyncInfo (#1002)
* [NOD-1501] Rename IsBlockInHeaderPruningPointFutureAndVirtualPast to IsBlockInHeaderPruningPointFuture.

* [NOD-1501] Create syncinfo.go.

* [NOD-1501] Implement resolveSyncState.

* [NOD-1501] Fix ChooseSelectedParent.

* [NOD-1501] Fix merge errors.

* [NOD-1501] Finish implementing getSyncState.

* [NOD-1501] Fix bad equality check.

* [NOD-1501] Fix merge errors.

* [NOD-1501] Pass targetTimePerBlock as int64 milliseconds.
2020-11-05 11:50:59 +02:00
Ori Newman
5566aaf95a [NOD-1512] Implement utxo deserialization (#1003)
* [NOD-1512] Implement UTXO set deserialization

* [NOD-1512] Remove redundant file

* [NOD-1512] Don't use big endian for serialization

* [NOD-1512] Use Read/Write element

* [NOD-1512] Unexport ReadElement

* [NOD-1512] Fix StageVirtualUTXOSet

* [NOD-1512] Get rid of dagParams in consensusStateManager

* [NOD-1512] Get rid of dagParams in consensusStateManager
2020-11-05 10:59:49 +02:00
Ori Newman
52c73d3a08 [NOD-1511] Implement missingBlockBodyHashes (#1000)
* [NOD-1511] Implement missingBlockBodyHashes

* [NOD-1511] Rename selectedparentiterator.go to blockiterator.go

* [NOD-1511] Fix condition

* [NOD-1511] Simplify missingBlocks logic
2020-11-05 10:11:42 +02:00
Ori Newman
baf8d25656 [NOD-1510] Update reachability reindex root based on header tips selected tip (#1001) 2020-11-04 16:55:59 +02:00
Ori Newman
2eb0d946e5 [NOD-1509] Implement StageVirtualUTXOSet (#999)
* [NOD-1509] Implement StageVirtualUTXODiff

* [NOD-1509] Fix HasUTXOByOutpoint, get rid of database.ErrNotFound, and fix errors
2020-11-04 16:30:08 +02:00
Elichai Turkel
ce95c6dc9d [NOD-1464] difficulty refactoring (#986)
* Refactor the Difficulty adjastment to the new design

* Add the necessary things to the factory for the DAA constructor

* Add missing dagParams to difficultymanager constructor

* Use DAGTraversal for blueBlockWindow, and don't store PowMax compactBits
2020-11-04 11:35:29 +02:00
Elichai Turkel
6a46cb2be6 [NOD-1503] Pruning Manager (#994)
* Update pruningmanager interface

* Add a ProtoUTXOSet to hashserialization

* Update miningmanager with all the necessary stores and managers

* Implement mining manager

* Prune P.AC not in V.Past

* PruningManager fix all review comments
2020-11-04 10:29:45 +02:00
Ori Newman
f06dc7ea90 [NOD-1508] Implement VirtualUTXOSetIterator (#998) 2020-11-03 18:38:57 +02:00
Ori Newman
7f2ef708a6 [NOD-1506] Implement SetPruningPointUTXOSet (#996)
* [NOD-1506] Implement SetPruningPointUTXOSet

* [NOD-1506] Rename ErrHeaderlessBlockInIBD->ErrMissingBlockHeaderInIBD

* [NOD-1506] Change virtualHeaderHash
2020-11-03 18:24:45 +02:00
Ori Newman
4ab2e0d498 [NOD-1507] Implement model.DBTransaction (#997) 2020-11-03 18:08:02 +02:00
stasatdaglabs
ca9161024f [NOD-1501] Add SyncManager-related interfaces (#995)
* [NOD-1501] Add logAndMeasureExecutionTime to SyncManager methods.

* [NOD-1501] Implement antiPastHashesBetween.

* [NOD-1501] Implement createBlockLocator.

* [NOD-1501] Implement findNextBlockLocatorBoundaries.

* [NOD-1501] Rename IsBlockHeaderInPruningPointFutureAndVirtualPast to IsBlockInHeaderPruningPointFutureAndVirtualPast.

* [NOD-1501] Add GetSyncInfo.

* [NOD-1501] Make go vet happy.

* [NOD-1501] Rename sync states.

* [NOD-1501] Move maxHashesInGetHashesBetween to antipast.go.

* [NOD-1501] Rename maxHashesInAntiPastHashesBetween.

* [NOD-1501] Implement LowestChainBlockAboveOrEqualToBlueScore.

* [NOD-1501] Fix bad variable name.

* [NOD-1501] Fix LowestChainBlockAboveOrEqualToBlueScore.

* [NOD-1501] Clarify LowestChainBlockAboveOrEqualToBlueScore.
2020-11-03 17:08:52 +02:00
Svarog
8dc246a2a7 [NOD-1498] Consensus State Store (#992)
* [NOD-1420] Start working on ConsensusStateManager. Might be redundant due to recent changes

* [NOD-1420] Convert model to externalapi in utxo_algerbra helpers

* [NOD-1420] Add UTXO-diff algebra

* [NOD-1420] Prepare skeleton of calculateAcceptanceDataAndMultiset

* [NOD-1420] Added skeleton for AddBlockToVirtual

* [NOD-1420] Implement PopulateTransactionWithUTXOEntries

* [NOD-1420] Implement restorePastUTXO

* [NOD-1420] Implement finality check

* [NOD-1420] Move handling of tips to consensusStateManager

* [NOD-1420] Implement calculateAcceptanceDataAndMultiset

* [NOD-1420] Start implementing resolveBlockStatus

* [NOD-1420] Implement resolveBlockStatus

* [NOD-1420] Update related fields in end of resolveSingleBlockStatus

* [NOD-1420] Start working on selectVirtualParents

* [NOD-1420] Implemented BlockHeap

* [NOD-1420] Implement selectVirtualParents

* [NOD-1420] Implement updateVirtual

* [NOD-1420] Added comments where they were missing

* [NOD-1420] Place all consensusStateManager functions in correct files

* [NOD-1420] Return the missing outpoints from populateTransactionWithUTXOEntriesFromVirtualOrDiff

* [NOD-1420] Outpoint.ID -> TransactionID

* [NOD-1420] Fix Stringer tests

* [NOD-1420] Copy hash.FromString into utils

* [NOD-1420] SetParents should return an error

* [NOD-1420] Remove all reachabilityManager references from consensusStateManager

* [NOD-1420] Remove VirtualData. Get the info from the stores where needed

* [NOD-1420] Invert parameters to IsAncestorOf

* [NOD-1420] Use model.AcceptanceData

* [NOD-1420] Don't return accumulatedMassBefore in error cases

* [NOD-1420] Don't expect store functions to return nil when the requested data was found - instead add HasXXX functions

* [NOD-1420] addTransactionToMultiset sets isCoinbase properly

* [NOD-1420] expected hash string length is externalapi.DomainHashSize * 2

* [NOD-1420] Rename reachabilityTree -> reachabilityManager + updateReindexRoot if isNextVirtualSelectedParent

* [NOD-1420] ValidateCoinbaseTransaction in csm.verifyAndBuildUTXO

* [NOD-1420] Re-write HAsUTXODiffChild

* [NOD-1420] delete past_utxo.go.bak

* [NOD-1420] Implement validateCoinbaseTransaction in CSM

* [NOD-1420] Imlemented missing functionality in ValidateTransactionAndPopulateWithConsensusData

* [NOD-1420] Moved merge depth logic to MergeDepthManager

* [NOD-1420] Add logs

* [NOD-1498] Implement tips-related methods of consensusStateStore

* [NOD-1498] Implement consensusStateStore virtualDiffParents functionality

* [NOD-1498] Implement ConsensusStateStore UTXO-Set part

* [NOD-1498] Implement rest of consensusStateStore methods

* [NOD-1498] Use io.ReadFull instead of r.Read

* [NOD-1498] Added comments

* [NOD-1498] Move utxo serialization to protobufs

* [NOD-1498] Add comments

* [NOD-1498] Minor fixes in ConsensusStateStore

* [NOD-1498] Use empty bucket key + simplify serializeUTXOEntry
2020-11-03 14:42:26 +02:00
Ori Newman
c7f2de73df [NOD-1502] Implement RestorePastUTXOSetIterator (#993)
* [NOD-1502] Implement RestorePastUTXOSetIterator

* [NOD-1502] Rename newUtxoSetIterator->newUTXOSetIterator
2020-11-02 18:36:55 +02:00
Ori Newman
3f979399b1 [NOD-1478] Implement coinbase manager (#990)
* [NOD-1478] Implement coinbase manager

* [NOD-1478] Add arguments to factory

* [NOD-1478] Remove validation functions from CoinbaseManager

* [NOD-1478] Remove ValidateCoinbaseTransactionInContext

* [NOD-1478] Add consts to constants package

* [NOD-1478] Move scriptPublicKeyMaxLength to constants.go
2020-11-02 16:51:47 +02:00
Ori Newman
2abd4a274b [NOD-1496] Implement headers only verification (#987)
* [NOD-1496] Implement headers only verification

* [NOD-1496] Add checkParentsExist

* [NOD-1496] Stage block statuses in block processor

* [NOD-1496] Rename AddBlock->AddHeaderTip

* [NOD-1496] Return early from validateAndInsertBlock on header only and put ValidateProofOfWorkAndDifficulty inside validateBlock
2020-11-02 16:30:59 +02:00
Svarog
c5707f64dc [NOD-1420] Implement consensusStateManager (#985)
* [NOD-1420] Start working on ConsensusStateManager. Might be redundant due to recent changes

* [NOD-1420] Convert model to externalapi in utxo_algerbra helpers

* [NOD-1420] Add UTXO-diff algebra

* [NOD-1420] Prepare skeleton of calculateAcceptanceDataAndMultiset

* [NOD-1420] Added skeleton for AddBlockToVirtual

* [NOD-1420] Implement PopulateTransactionWithUTXOEntries

* [NOD-1420] Implement restorePastUTXO

* [NOD-1420] Implement finality check

* [NOD-1420] Move handling of tips to consensusStateManager

* [NOD-1420] Implement calculateAcceptanceDataAndMultiset

* [NOD-1420] Start implementing resolveBlockStatus

* [NOD-1420] Implement resolveBlockStatus

* [NOD-1420] Update related fields in end of resolveSingleBlockStatus

* [NOD-1420] Start working on selectVirtualParents

* [NOD-1420] Implemented BlockHeap

* [NOD-1420] Implement selectVirtualParents

* [NOD-1420] Implement updateVirtual

* [NOD-1420] Added comments where they were missing

* [NOD-1420] Place all consensusStateManager functions in correct files

* [NOD-1420] Return the missing outpoints from populateTransactionWithUTXOEntriesFromVirtualOrDiff

* [NOD-1420] Outpoint.ID -> TransactionID

* [NOD-1420] Fix Stringer tests

* [NOD-1420] Copy hash.FromString into utils

* [NOD-1420] SetParents should return an error

* [NOD-1420] Remove all reachabilityManager references from consensusStateManager

* [NOD-1420] Remove VirtualData. Get the info from the stores where needed

* [NOD-1420] Invert parameters to IsAncestorOf

* [NOD-1420] Use model.AcceptanceData

* [NOD-1420] Don't return accumulatedMassBefore in error cases

* [NOD-1420] Don't expect store functions to return nil when the requested data was found - instead add HasXXX functions

* [NOD-1420] addTransactionToMultiset sets isCoinbase properly

* [NOD-1420] expected hash string length is externalapi.DomainHashSize * 2

* [NOD-1420] Rename reachabilityTree -> reachabilityManager + updateReindexRoot if isNextVirtualSelectedParent

* [NOD-1420] ValidateCoinbaseTransaction in csm.verifyAndBuildUTXO

* [NOD-1420] Re-write HAsUTXODiffChild

* [NOD-1420] delete past_utxo.go.bak

* [NOD-1420] Implement validateCoinbaseTransaction in CSM

* [NOD-1420] Imlemented missing functionality in ValidateTransactionAndPopulateWithConsensusData

* [NOD-1420] Moved merge depth logic to MergeDepthManager

* [NOD-1420] Add logs
2020-11-02 16:18:53 +02:00
stasatdaglabs
62bb841e89 [NOD-1497] Add additional methods to consensus' external API (#991)
* [NOD-1497] Add missing APIs.

* [NOD-1497] Rename some new APIs.

* [NOD-1497] Implement getBlock and getBlockHeader.

* [NOD-1497] Implement getPruningPointUTXOSet.

* [NOD-1497] Implement getSelectedParent.

* [NOD-1497] Implement getBlockInfo.

* [NOD-1497] Fix merge errors.

* [NOD-1497] Implement syncManager-related functions in consensus.

* [NOD-1497] Implement SetPruningPointUTXOSet in consensus.

* [NOD-1497] Add dependency from syncManager to dagTraversalManager.

* [NOD-1497] Move IsBlockHeaderInPruningPointFutureAndVirtualPast to syncManager.

* [NOD-1497] Rename lowHigh to lowHash.
2020-11-02 13:24:03 +02:00
stasatdaglabs
23cccb6396 [NOD-1497] Add additional methods to consensus external API (#989)
* [NOD-1497] Add missing APIs.

* [NOD-1497] Rename some new APIs.

* [NOD-1497] Add fields to BlockInfo.

* [NOD-1497] Add comments over BlockInfo and BlockLocator.

* [NOD-1497] Rename GetSelectedParent to GetVirtualSelectedParent.

* [NOD-1497] Add SetPruningPointUTXOSet.

* [NOD-1497] Rename GetHashesAbovePruningPoint to GetMissingBlockBodyHashes.

* [NOD-1497] Fix rename error.
2020-11-02 12:05:33 +02:00
Elichai Turkel
87ad9dfc59 [NOD-1423] Refactor the miner and mempool (#981)
* Make TransactionOutputEstimatedSerializedSize public

* Update the mempool interface

* Refactor the mempool to the new design

* refactor txselection and blocktemplatebuilder to the new design

* Update the mining manager

* Update the MiningManager factory

* mempool fix requested changed
2020-11-01 18:27:49 +02:00
Ori Newman
c59adaa4db [NOD-1494] Remove transactions from data store delete (#984)
* [NOD-1494] Remove transactions from data store delete

* [NOD-1494] Remove redundant underscores
2020-10-29 18:15:11 +02:00
Ori Newman
14fbe50636 [NOD-1493] Implement serialization in data stores (#983)
* [NOD-1493] Implement serialization in data stores

* [NOD-1493] Remove redundant functions

* [NOD-1493] Use bluesAnticoneSizesToDBBluesAnticoneSizes inside BlockGHOSTDAGDataToDBBlockGHOSTDAGData
2020-10-29 17:39:35 +02:00
Elichai Turkel
d3ede3a46f Add new ErrMissingTxOut and ErrInvalidTransactionsInNewBlock errors (#972)
* Add new ErrMissingTxOut error

* Add tests for ruleError wrapping

* Update consensus to use new ErrMissingTxOut type where appropriate

* Add new ErrInvalidTransactionsInNewBlock error

* Add wrapping tests for ErrInvalidTransactionsInNewBlock

* Fix Review suggestions

* Fix broken serialization(add pointer redirection)
2020-10-29 16:59:00 +02:00
stasatdaglabs
01c7c67aed [NOD-1493] Implement serialization in AcceptanceDataStore, BlockRelationStore, BlockStatusStore, and BlockStore (#982)
* [NOD-1493] Add DbHashToDomainHash and DomainHashToDbHash.

* [NOD-1493] Use DbHashToDomainHash and DomainHashToDbHash.

* [NOD-1493] Begin implementing serializeAcceptanceData.

* [NOD-1493] Extract serialization blockHeader logic to serialization.

* [NOD-1493] Extract serialization acceptance data logic to serialization.

* [NOD-1493] Implement acceptance data serialization/deserialization.

* [NOD-1493] Implement transaction serialization/deserialization.

* [NOD-1493] Implement outpoint serialization/deserialization.

* [NOD-1493] Implement transaction ID serialization/deserialization.

* [NOD-1493] Implement subnetwork ID serialization/deserialization.

* [NOD-1493] Implement block relation serialization/deserialization.

* [NOD-1493] Implement block status serialization/deserialization.

* [NOD-1493] Implement block serialization/deserialization.

* [NOD-1493] Implement serialization/deserialization in BlockRelationStore.

* [NOD-1493] Implement serialization/deserialization in BlockStatusStore.

* [NOD-1493] Implement serialization/deserialization in BlockStore.

* [NOD-1493] Make go vet happy.

* [NOD-1493] Use DomainHashesToDbHashes.
2020-10-29 16:49:05 +02:00
Elichai Turkel
971d50b684 [NOD-1418] Implement DAG Traversal (#953)
* Implement DAG Traversal

* Update the DAGTraversalManager interface
2020-10-29 16:48:41 +02:00
stasatdaglabs
9cf1557c37 [NOD-1493] Implement types for serialization (#980)
* [NOD-1493] Add DbAcceptanceData.

* [NOD-1493] Add DbBlockRelations.

* [NOD-1493] Add DbBlockStatus.

* [NOD-1493] Add DbBlockGhostdagData.

* [NOD-1493] Add DbMultiset.

* [NOD-1493] Add DbPruningPoint.

* [NOD-1493] Add DbUtxoSet.

* [NOD-1493] Add DbReachabilityData.

* [NOD-1493] Add DbReachabilityReindexRoot.

* [NOD-1493] Add DbUtxoDiff.

* [NOD-1493] Add DbUtxoDiffChild.

* [NOD-1493] Make sure everything is lowercase.

* [NOD-1493] Add DbHash.

* [NOD-1493] Fix BlockHeaderStore.
2020-10-29 12:18:18 +02:00
stasatdaglabs
126e2e49bb [NOD-1493] Implement serialization/deserialization inside BlockHeaderStore (#979)
* [NOD-1492] Rename dbmanager to database.

* [NOD-1492] Write messages.proto for DbBlock and DbTransaction.

* [NOD-1492] Implement serializeHeader.

* [NOD-1492] Implement deserializeHeader.
2020-10-29 11:15:14 +02:00
stasatdaglabs
c88266afed [NOD-1492] Implement GHOSTDAGDataStore, MultisetStore, PruningStore, ReachabilityDataStore, and UTXODiffStore (#977)
* [NOD-1492] Implement GHOSTDAGDataStore.

* [NOD-1492] Implement MultisetStore.

* [NOD-1492] Implement PruningStore.

* [NOD-1492] Implement ReachabilityDataStore.

* [NOD-1492] Implement UTXODiffStore.

* [NOD-1492] Pluralize the multiset bucket name.

* [NOD-1492] In PruningPoint and PruningPointSerializedUTXOSet, don't use IsStaged.

* [NOD-1492] Leave pruning point serialization/deserialization for future implementation.

* [NOD-1492] Leave reachability reindex root serialization/deserialization for future implementation.

* [NOD-1492] Leave utxo diff child serialization/deserialization for future implementation.

* [NOD-1492] Add Serialize() to Multiset.

* [NOD-1492] Also check serializedUTXOSetStaging in IsStaged.

* [NOD-1492] Also check utxoDiffChildStaging in IsStaged.

* [NOD-1492] Fix UTXODiffStore.Delete.
2020-10-28 17:13:14 +02:00
Ori Newman
7402f3fb0e [NOD-1492] Implement some data stores (#978)
* [NOD-1492] Implement some data stores

* [NOD-1492] Remove pointers to acceptance data

* [NOD-1492] Fix receiver names

* [NOD-1492] Implement delete for acceptanceDataStore

* [NOD-1492] In blockRelationStore rename IsAnythingStaged to IsStaged

* [NOD-1492] Rename bucket name
2020-10-28 16:30:55 +02:00
Ori Newman
eae8bce941 [NOD-1491] Implement block headers store (#976)
* [NOD-1491] Implement block headers store

* [NOD-1491] Don't commit transaction and delete from staging too
2020-10-28 14:34:00 +02:00
Ori Newman
8c0275421a [NOD-1490] Implement database manager (#975) 2020-10-28 12:59:34 +02:00
Ori Newman
a436b30ebf [NOD-1417] Implement reachability (#964)
* [NOD-1417] Implement reachability

* [NOD-1417] Rename package name

* [NOD-1417] Add UpdateReindexRoot to interface api

* [NOD-1417] Remove redundant type

* [NOD-1417] Rename reachabilityTreeManager/reachabilityTree to reachabilityManager

* [NOD-1417] Fix typo

* [NOD-1417] Remove redundant copyright message

* [NOD-1417] Fix comment
2020-10-28 12:19:50 +02:00
Ori Newman
a132f55302 [NOD-1477] Add selected parent to merge set (#967)
* [NOD-1477] Add selected parent to merge set

* [NOD-1469] Init BluesAnticoneSizes

* [NOD-1477] Undo changes in hash comparison
2020-10-28 11:44:08 +02:00
Ori Newman
be56fb7e8b [NOD-1488] Get rid of dbaccess (#973)
* [NOD-1488] Get rid of dbaccess

* [NOD-1488] Rename dbwrapper to dbmanager

* [NOD-1488] Create DBWriter interface

* [NOD-1488] Fix block header store

* [NOD-1488] Rename dbwrapper.go to dbmanager.go
2020-10-28 11:34:06 +02:00
stasatdaglabs
4fbe130592 [NOD-1489] Add BlockHeaderStore (#974)
* [NOD-1489] Add BlockHeaderStore.

* [NOD-1489] Use BlockHeaderStore.
2020-10-28 10:35:18 +02:00
Ori Newman
ed6d8243ef [NOD-1487] Implement dagtopology's IsAncestorOfAny and IsInSelectedParentChainOf (#971)
* [NOD-1487] Implement dagtopology's IsAncestorOfAny and IsInSelectedParentChainOf

* [NOD-1487] Fix IsInSelectedParentChainOf to use reachabilityTree
2020-10-27 17:46:30 +02:00
Ori Newman
03790ad8a2 [NOD-1469] Implement past median time (#968)
* [NOD-1469] Implement past median time

* [NOD-1469] Move BlueWindow to DAGTraversalManager
2020-10-27 17:45:47 +02:00
stasatdaglabs
97b5b0b875 [NOD-1416] Implement BlockProcessor. (#969)
* [NOD-1416] Add entry/exit logs to all the functions.

* [NOD-1416] Build some scaffolding inside BlockProcessor.

* [NOD-1416] Implement selectParentsForNewBlock.

* [NOD-1416] Implement validateBlock.

* [NOD-1476] Fix merge errors.

* [NOD-1416] Move buildBlock and validateAndInsertBlock to separate files.

* [NOD-1416] Begin implementing buildBlock.

* [NOD-1416] Implement newBlockDifficulty.

* [NOD-1416] Add skeletons for the rest of the buildBlock functions.

* [NOD-1416] Implement newBlockUTXOCommitment.

* [NOD-1416] Implement newBlockAcceptedIDMerkleRoot.

* [NOD-1416] Implement newBlockHashMerkleRoot.

* [NOD-1416] Fix bad function call.

* [NOD-1416] Implement validateHeaderAndProofOfWork and validateBody.

* [NOD-1416] Use ValidateProofOfWorkAndDifficulty.

* [NOD-1416] Finish validateAndInsertBlock.

* [NOD-1416] Implement newBlockHashMerkleRoot.

* [NOD-1416] Implement newBlockAcceptedIDMerkleRoot.

* [NOD-1416] Fix a comment.

* [NOD-1416] Implement newBlockCoinbaseTransaction.

* [NOD-1416] Add VirtualBlockHash.

* [NOD-1416] Add ParentHashes and SelectedParent to VirtualData().

* [NOD-1416] Make go vet happy.

* [NOD-1416] Implement discardAllChanges.

* [NOD-1416] Implement commitAllChanges.

* [NOD-1416] Fix factory.

* [NOD-1416] Make go vet happy.

* [NOD-1416] Format factory.

* [NOD-1416] Pass transactionsWithCoinbase to buildHeader.

* [NOD-1416] Call VirtualData() from buildHeader.

* [NOD-1416] Fix a typo.

* [NOD-1416] Fix in-out-of-context/header-body confusion.

* [NOD-1416] Extract LogAndMeasureExecutionTime.

* [NOD-1416] Add a comment about LogAndMeasureExecutionTime.

* [NOD-1416] Simplify discardAllChanges and commitAllChanges.

* [NOD-1416] If in-context validations fail, discard all changes and store the block with StatusInvalid.

* [NOD-1416] Add a comment above Store.

* [NOD-1416] Use errors.As instead of errors.Is.
2020-10-27 17:24:15 +02:00
Ori Newman
f62183473c [NOD-1486] Make coinbase mass and size 0 (#970) 2020-10-27 17:14:02 +02:00
Ori Newman
aeb4b96560 [NOD-1451] Implement Validators (#966)
* [NOD-1451] Implement block validator

* [NOD-1451] Implement block validator

* [NOD-1451] Fix merge errors

* [NOD-1451] Implement block validator

* [NOD-1451] Implement checkTransactionInIsolation

* [NOD-1451] Copy txscript to validator

* [NOD-1451] Change txscript to new design

* [NOD-1451] Add checkTransactionInContext

* [NOD-1451] Add checkBlockSize

* [NOD-1451] Add error handling

* [NOD-1451] Implement checkTransactionInContext

* [NOD-1451] Add checkTransactionMass placeholder

* [NOD-1451] Finish validators

* [NOD-1451] Add comments and stringers

* [NOD-1451] Return model.TransactionValidator interface

* [NOD-1451] Premake rule errors for each "code"

* [NOD-1451] Populate transaction mass

* [NOD-1451] Renmae functions

* [NOD-1451] Always use skipPow=false

* [NOD-1451] Renames

* [NOD-1451] Remove redundant types from WriteElement

* [NOD-1451] Fix error message

* [NOD-1451] Add checkTransactionPayload

* [NOD-1451] Add ValidateProofOfWorkAndDifficulty to block validator interface

* [NOD-1451] Move stringers to model

* [NOD-1451] Fix error message
2020-10-26 17:33:39 +02:00
stasatdaglabs
b413760136 [NOD-1476] Make further design changes (#965)
* [NOD-1476] Add dependency to BlockRelationStore in BlockProcessor.

* [NOD-1476] Add dependency to BlockStatusStore in BlockValidator.

* [NOD-1476] Add dependency to GHOSTDAGManager in BlockValidator.

* [NOD-1476] Rename CalculateConsensusStateChanges to AddBlockToVirtual.

* [NOD-1476] Remove RestoreDiffFromVirtual.

* [NOD-1476] Remove RestorePastUTXOSet.

* [NOD-1476] Add dependency to GHOSTDAGDataStore in ConsensusStateManager.

* [NOD-1476] Rename CalculateAcceptanceDataAndUTXOMultiset to just CalculateAcceptanceData.

* [NOD-1476] Remove UTXODiffManager and add dependencies to AcceptanceManager.

* [NOD-1476] Rename CalculateAcceptanceData to CalculateAcceptanceDataAndMultiset.

* [NOD-1476] Add dependency to DAGTopologyManager from ConsensusStateManager.

* [NOD-1476] Add dependency to BlockStore from ConsensusStateManager.

* [NOD-1476] Add dependency to PruningManager from ConsensusStateManager.

* [NOD-1476] Remove unnecessary stuff from ConsensusStateChanges.

* [NOD-1476] Add dependency to UTXODiffStore from ConsensusStateManager.

* [NOD-1476] Add tips to BlockRelationsStore.

* [NOD-1476] Add dependency to BlockRelationsStore from ConsensusStateManager.

* [NOD-1476] Remove Tips() from ConsensusStateStore.

* [NOD-1476] Remove acceptanceManager.

* [NOD-1476] Remove irrelevant functions out of ConsensusStateManager.
2020-10-25 15:19:20 +02:00
stasatdaglabs
45882343e6 [NOD-1475] Implement stage/discard/commit functionality for data structures (#962)
* [NOD-1475] Add Stage, Discard, and Commit methods to all stores.

* [NOD-1475] Simplify interfaces for processes.

* [NOD-1475] Fix GHOSTDAGManager.

* [NOD-1475] Simplify ChooseSelectedParent.

* [NOD-1475] Remove errors from Stage functions.

* [NOD-1475] Add IsStaged to all data structures.

* [NOD-1475] Remove isDisqualified from CalculateConsensusStateChanges.

* [NOD-1475] Add dependency from ConsensusStateManager to BlockStatusStore.

* [NOD-1475] Fix a comment.

* [NOD-1475] Add ReachabilityReindexRoot to reachabilityDataStore.

* [NOD-1475] Fix a comment.

* [NOD-1475] Rename IsStaged to IsAnythingStaged.
2020-10-21 12:37:22 +03:00
Svarog
4c1f24da82 [NOD-1466] Move UTXODiffStore from ConsensusStateManager to UTXODiffManager (#961) 2020-10-21 10:19:41 +03:00
stasatdaglabs
8c63835971 [NOD-1461] Make further design changes (#959)
* [NOD-1461] Split blockValidator and TransactionValidator.

* [NOD-1461] Remove feeDataStore.

* [NOD-1461] Move tips out of ConsensusStateManager and into DAGTopologyManager.

* [NOD-1461] Add UTXODiffManager.

* [NOD-1461] Add RestoreDiffFromVirtual.

* [NOD-1461] Add AcceptanceManager.

* [NOD-1461] Replace SetTips with AddTip.

* [NOD-1461] Fix merge errors.

* [NOD-1461] Rename CoinbaseData to DomainCoinbaseData.
2020-10-20 09:35:58 +03:00
stasatdaglabs
a96a5fd2ef [NOD-1462] Simplify consensus external API (#958)
* [NOD-1461] Change the external api interface to not having anything besides DomainTransactions and DomainBlocks.

* [NOD-1462] Move external api types to a separate package.

* [NOD-1462] Clarify which model we're using in miningmanager.

* [NOD-1462] Extract coinbase data to its own struct.

* [NOD-1462] Add a comment above CoinbaseData.

* [NOD-1462] Fix the comment above CoinbaseData.
2020-10-19 17:59:04 +03:00
stasatdaglabs
9a62fae012 [NOD-1458] Rename blockRelationStore.Insert to Update. 2020-10-18 17:34:49 +03:00
stasatdaglabs
81a10e9f89 [NOD-1458] Make further design changes (#956)
* [NOD-1458] Rename RestoreUTXOSet to RestorePastUTXOSet.

* [NOD-1458] Make CalculateAcceptanceDataAndMultiset take BlockGHOSTDAGData and nothing else.

* [NOD-1458] Make ConsensusStateStore's Update take ConsensusStateChanges instead of just UTXODiff.

* [NOD-1458] Add Tips() to ConsensusStateStore.

* [NOD-1458] Make all implementation structs private.

* [NOD-1458] Remove BlockAtDepth and add highHash to ChainBlockAtBlueScore.

* [NOD-1458] Rename CalculateAcceptanceDataAndMultiset to CalculateAcceptanceDataAndUTXOMultiset.

* [NOD-1458] Add a dependency to GHOSTDAGManager from ConsensusStateManager.

* [NOD-1458] Add ChooseSelectedParent to GHOSTDAGManager.

* [NOD-1458] Add DifficultyManager.

* [NOD-1458] Add PastMedianTimeManager.

* [NOD-1458] Add Hash() to Multiset.

* [NOD-1458] Add a dependency to ghostdagManager from blockProcessor.

* [NOD-1458] Add errors to all interfaces that need them.

* [NOD-1458] Uppercasify types in comments.

* [NOD-1458] Fix a bad comment.

* [NOD-1458] Fix a comment.

* [NOD-1458] Rename ChainBlockAtBlueScore to HighestChainBlockBelowBlueScore.

* [NOD-1458] Replace BlockAndTransactionValidator with an anonymous interface.
2020-10-18 12:34:00 +03:00
stasatdaglabs
db475bd511 [NOD-1460] Make the miningmanager package structure similar to consensus package's (#957)
* [NOD-1460] Move the miningmanager interfaces into its model package.

* [NOD-1460] Decouple miningmanager model from appmessage.

* [NOD-1460] Decouple miningmanager model from util.

* [NOD-1460] Make miningmanager implementation structs unexported.
2020-10-18 10:52:41 +03:00
Ori Newman
eef5f27a87 [NOD-1422] Implement GHOSTDAG (#950)
* [NOD-1422] Implement GHOSTDAG

* [NOD-1422] Rename bluest->findSelectedParent

* [NOD-1422] Remove preallocations from MergeSetBlues and add preallocation in candidateBluesAnticoneSizes

* [NOD-1422] Rename blockghostdagdata.go to ghostdag.go
2020-10-14 16:47:04 +03:00
Svarog
790dc74581 [NOD-1457] Pass DomainDBContext to all constructors, instead of passing a general dbContext (#955)
* [NOD-1457] Pass DomainDBContext to all constructors, instead of passing a general dbContext

* [NOD-1457] Add NewTx to DomainDBContext

* [NOD-1457] Added comment
2020-10-14 09:59:27 +03:00
stasatdaglabs
4f36accd81 [NOD-1413] Make some additional interface changes (#954)
* [NOD-1413] Remove /cmd/addblock

* [NOD-1413] Define and implement TransactionValidator.

* [NOD-1413] Make changes to ConsensusStateManager's interface.

* [NOD-1413] Make changes to PruningManager's interface.

* [NOD-1413] Make changes to DAGTraversalManager's interface.

* [NOD-1413] Make changes to MultisetStore's interface.

* [NOD-1413] Make changes to UTXODiffStore's interface.

* [NOD-1413] Make changes to UTXODiffStore's interface harder.

* [NOD-1413] Make changes to AcceptanceDataStore's interface harder.

* [NOD-1413] Make changes to PruningStore's interface.

* [NOD-1413] Delete BlockIndex.

* [NOD-1413] Add FeeDataStore.

* [NOD-1413] Update BlockMessageStore's interface.

* [NOD-1413] Fix interface violations.

* [NOD-1413] Add FeeDataStore to BlockProcessor.

* [NOD-1413] Make go vet happy.

* [NOD-1413] Add missing fields to ConsensusStateChanges.

* [NOD-1413] Add another missing field to ConsensusStateChanges.

* [NOD-1413] Add a reference to blockStore in consensusStateManager.

* [NOD-1413] Add missing methods to UTXODiffStore.

* [NOD-1413] Rename pruningPointStore to pruningStore everywhere.

* [NOD-1413] Remove superfluous parameters from CalculateConsensusStateChanges.

* [NOD-1413] Add missing dependencies to PruningManager.

* [NOD-1413] Remove implementation-y functions from TransactionValidator's interface.

* [NOD-1413] Make go vet happy.

* [NOD-1413] Add a couple of methods to DAGTopologyManager.

* [NOD-1413] Fix a typo in a file name.

* [NOD-1413] Remove non-interface functions from Validator.
2020-10-13 17:55:31 +03:00
stasatdaglabs
04ead57731 [NOD-1413] Remove /cmd/addblock (#951) 2020-10-12 13:23:19 +03:00
stasatdaglabs
e9951bc34a [NOD-1413] Decouple the model package from everything (#949)
* [NOD-1416] Move processes/datastructures interfaces into the model package.

* [NOD-1416] Decouple the model from dbaccess.

* [NOD-1413] Implement DomainBlock and DomainTransaction.

* [NOD-1413] Decouple model from appmessage.

* [NOD-1413] Decouple model from util.

* [NOD-1413] Decouple model from subnetworkid.

* [NOD-1413] Remove an unused const.

* [NOD-1413] Add DomainHash and DomainTransactionID.

* [NOD-1413] Decouple model from daghash.

* [NOD-1413] Decouple model from mstime.

* [NOD-1413] Decouple model from go-secp256k1.

* [NOD-1413] Add a proxy over dbaccess.

* [NOD-1413] Add comments over all added types.

* [NOD-1413] Fix a comment.

* [NOD-1413] Get rid of DomainTime.

* [NOD-1413] Simplify BlockGHOSTDAGData.
2020-10-11 14:32:41 +03:00
Ori Newman
74d13e271e [NOD-1419] Implement DAG topology (#948)
* [NOD-1419] Implement DAG topology

* [NOD-1419] Add isHashInSlice
2020-10-08 14:00:25 +03:00
stasatdaglabs
9181481fc8 [NOD-1413] Remove Handlers from Consensus (#947)
* [NOD-1413] Remove Handlers from Consensus.

* [NOD-1413] Remove ResolveFinalityConflicts.
2020-10-06 16:35:47 +03:00
Ori Newman
62ddd8fe1c [NOD-1444] Implement getHeaders RPC command (#944)
* [NOD-1444] Implement getHeaders RPC command

* [NOD-1444] Fix tests and comments

* [NOD-1444] Fix error message

* [NOD-1444] Make GetHeaders propagate header serialization errors

* [NOD-1444] RLock the dag on GetHeaders

* [NOD-1444] Change the error field number to 1000
2020-10-06 11:18:31 +03:00
stasatdaglabs
7891f73cb0 [NOD-1414] Write domain interfaces and stub implementations for the new kaspadstate architecture (#941)
* [NOD-1414] Add interfaces for Factory and State.

* [NOD-1414] Create interfaces for algorithms and data stores.

* [NOD-1414] Create empty implementations for algorithms and data stores.

* [NOD-1414] Add new functions for all the implementations.

* [NOD-1414] Begin filling in the interfaces.

* [NOD-1414] Fill in the interfaces for the data structures.

* [NOD-1414] Fill in the interfaces for the algorithms.

* [NOD-1414] Fix a bug in package names.

* [NOD-1414] Connect up the various interfaces.

* [NOD-1414] Add stubs to all the implementations.

* [NOD-1414] Create MiningManager and its Factory.

* [NOD-1414] Add interfaces for mempool and blockTemplateBuilder.

* [NOD-1414] Add implementation structs for miningManager.

* [NOD-1414] Add stub implementations for mempool and blockTemplateBuilder.

* [NOD-1414] Rename state to kaspadState.

* [NOD-1414] Restructure where interfaces sit.

* [NOD-1414] Restructure where interfaces sit in the algorithms package as well.

* [NOD-1414] Move remaining models out of models.go.

* [NOD-1414] Modified some interfaces.

* [NOD-1414] Make go vet happy.

* [NOD-1414] Move SerializedUTXOSet into PruningManager.

* [NOD-1414] Modify FindNextPruningPoint to return found and nextPruningPointUTXOSet.

* [NOD-1414] Add IsDAGAncestorOf.

* [NOD-1414] Add PruningPoint().

* [NOD-1414] Add Entry() to ReadOnlyUTXOSet.

* [NOD-1414] Add MergeSet() to BlockGHOSTDAGData.

* [NOD-1414] Write comments for all the exported types and functions in miningmanager.

* [NOD-1414] Add comments to the upper levels of KaspadState.

* [NOD-1414] Replace AddNode with ReachabilityChangeset.

* [NOD-1414] Add payAddress and extraData to GetBlockTemplate.

* [NOD-1414] Add scriptPublicKey and extraData to BuildBlock.

* [NOD-1414] Rename algorithms to processes.

* [NOD-1414] Rename kaspadState to consensus.

* [NOD-1414] Add ValidateAgainstPastUTXO and ValidateFinality.

* [NOD-1414] Add BlockGHOSTDAGData to ReachabilityChangeset.

* [NOD-1414] Fix the comment over Mempool.

* [NOD-1414] Fix the comment over ValidateTransaction.

* [NOD-1414] Fill up the data structures.

* [NOD-1414] Add comments to remaining uncommented items in miningmanager.

* [NOD-1414] Add comments to structs and constructors.

* [NOD-1414] Rename Set to Insert.

* [NOD-1414] Add comments to everything inside datastructures.

* [NOD-1414] Add comments to everything inside models.

* [NOD-1414] Add comments to the interfaces in processes.

* [NOD-1414] Add comments to everything in processes.

* [NOD-1414] Make go vet happy.

* [NOD-1414] Rename scriptPublicKey to coinbaseScriptPublicKey.

* [NOD-1414] Add handlers to the consensus.

* [NOD-1414] Add highHash to blockAtDepth.

* [NOD-1414] Add resolveFinalityConflict.

* [NOD-1414] Reorg BlockValidator.

* [NOD-1414] In ResolveFinalityConflicts, rename blockHash to newFinalityBlockHash.

* [NOD-1414] Fix a comment.

* [NOD-1414] Make reachability structs public.

* [NOD-1414] Make UTXO structs public.
2020-10-06 10:34:04 +03:00
Svarog
a359e2248b [NOD-1447] checkEntryAmounts should check against totalSompiInAfter, not totalSompiInBefore (#945)
* [NOD-1447] checkEntryAmounts should check against totalSompiInAfter, not totalSompiInBefore

* [NOD-1447] Remove lastSompiIn, and use totalSompiInBefore instead
2020-10-05 13:10:09 +03:00
Svarog
513ffa7e0c [NOD-1420] Restructure main (#942)
* [NOD-1420] Moved setting limits to executor

* [NOD-1420] Moved all code dealing with windows service to separate package

* [NOD-1420] Move practically all main to restructured app package

* [NOD-1420] Check for running as interactive only after checking if we are doing any service operation

* [NOD-1420] Add comments

* [NOD-1420] Add a comment
2020-10-01 08:28:16 +03:00
oudeis
ef6c46a231 Update to version 0.7.2 2020-09-30 14:07:18 +00:00
Svarog
22237a4a8d [NOD-1439] Added Stop command (#940)
* [NOD-1439] Added Stop command

* [NOD-1439] Added comment explaining why we wait before closing the StopChan

* [NOD-1439] Warnf -> Warn

* [NOD-1439] Rename Stop command to Shut Down

* [NOD-1439] Clean up pauseBeforeShutDown

* [NOD-1439] Add ShutDownRequestMessage case for toRPCPayload

* [NOD-1439] Minor stylistic changes
2020-09-29 15:59:47 +03:00
Ori Newman
6ab8ada9ff [NOD-1406] remove mempool utxo diff (#938)
* [NOD-1406] Remove mempool UTXO diff

* [NOD-1406] Fix mempool tests

* [NOD-1406] Fetch mempool transactions before locking the dag in NewBlockTemplate

* [NOD-1406] Remove redundant comment

* [NOD-1406] Move mempool UTXO set to a different file

* [NOD-1406] Fix transactionRelatedUTXOEntries receiver's name

* [NOD-1406] Fix variable names and fix comments

* [NOD-1406] Rename inputsWithUTXOEntries->referencedUTXOEntries

* [NOD-1406] Remove debug logs
2020-09-27 16:40:07 +03:00
Svarog
9a756939d8 [NOD-1412] Remove ffldb, remove dataStore from database, store blocks directly in levelDB (#939)
* [NOD-1412] Remove ffldb, and make ldb implement all the database
interfaces

* [NOD-1412] Removed any reference to dataStore and updated block dbaccess to work directly with key/values
2020-09-27 15:40:15 +03:00
Kirill
aea3baf897 [NOD-1320] Flush UTXOs to disk (#902)
* [NOD-1320] Flush UTXOs to disk.

* [NOD-1320] Minor improvements and fixes.

* FullUTXOSet: change size type from int64 to uint64.
* Rename FullUTXOSet.size to FullUTXOSet.estimatedSize
* Fill NewFullUTXOSetFromContext with db context on virtual block
  creation.
* Typo fixes.

* [NOD-1320] Stylystic fixes.

* [NOD-1320] Update tests. Improvements and fixes.

* Update blockdag/dag tests: prepare DB for tests.
* Update blockdag/utxoset tests: prepare DB for tests.
* Update blockdag/test_utils utils.
* Update blockdag/common tests.
* FullUTXOSet: remove embedded utxoCollection type. Rename
  utxoCollection to utxoCache.
* Fix blockdag/block_utxo genesisPastUTXO func.
* Minor fixes and improvements.
2020-09-27 13:16:11 +03:00
Ori Newman
f8d0f7f67a [NOD-1405] Add getMempoolEntries RPC command (#937)
* [NOD-1405] Add getMempoolEntries RPC command

* [NOD-1405] Remove redundant fields from GetMempoolEntryResponseMessage
2020-09-23 15:51:02 +03:00
stasatdaglabs
fed34273a1 [NOD-1404] Remove most of the notification manager to fix a deadlock (#936)
* [NOD-1404] Remove most of the notification manager to fix a deadlock.

* [NOD-1404] Rename a couple of fields.

* [NOD-1404] Fix merge errors.

* [NOD-1404] Remove most of the notification manager to fix a deadlock (#935)

* [NOD-1404] Remove most of the notification manager to fix a deadlock.

* [NOD-1404] Rename a couple of fields.
2020-09-23 14:00:05 +03:00
Ori Newman
34a1b30006 [NOD-1397] Add to rpc client ErrRPC (#934) 2020-09-17 19:26:03 +03:00
stasatdaglabs
798abf2103 [NOD-1395] Increase the grpcclient's max message size to match the grpcserver's. (#932) 2020-09-17 16:53:33 +03:00
stasatdaglabs
75e539f4d2 [NOD-1357] Implement getMempoolEntry (#931)
* [NOD-1357] Implement getMempoolEntry.

* [NOD-1357] Fix a nil point reference.

* [NOD-1357] Add a comment above BuildTransactionVerboseData.
2020-09-16 16:53:36 +03:00
oudeis
946e65d1c6 Update to version 0.7.1 2020-09-16 11:59:51 +00:00
stasatdaglabs
b8e36eacfd [NOD-1388] Use isInPastOfAny in addValidTip instead of just checking the parents (#930)
* [NOD-1388] Write a deterministic test that reproduces the crash.

* [NOD-1388] Fix a typo.

* [NOD-1388] Use isInPastOfAny in addValidTip instead of just checking the parents.

* [NOD-1388] Add a json representation of the crashing DAG.

* [NOD-1388] Remove crash_test.go.

* [NOD-1388] Change variable name, add a comment.

* [NOD-1388] Rephrase a comment.
2020-09-16 12:06:09 +03:00
Ori Newman
cd49c1dac7 [NOD-1390] Add timeout to kaspactl (#929)
* [NOD-1390] Add timeout to kaspactl

* [NOD-1390] Fix grammar
2020-09-14 12:33:42 +03:00
Ori Newman
86411a5ca5 [NOD-1389] Add panic on NumParentBlocks if number of parents is greater than 255 (#928) 2020-09-14 12:19:46 +03:00
stasatdaglabs
1186cad9ca [NOD-1373] Make kaspactl use the default port for the relevant network if it's not provided. (#927) 2020-09-14 12:18:51 +03:00
Elichai Turkel
e66de86a82 [NOD-1387] Some small optimizations to block processing (#926)
* Preallocate when cloning utxoCollection/blockSet

* inline binary serialization to serializeUTXO

* Add a benchmark for serializeUTXO
2020-09-13 18:12:13 +03:00
Svarog
1e08bfca9c [NOD-1032] Consensus updates pre-pruning (#917)
* [NOD-1249] Add pruning related constants (#869)

* [NOD-1249] Add pruning related constants

* [NOD-1249] Change status suspect to UTXONotVerified

* [NOD-1249] Add TestPruningDepth

* [NOD-1249] Add comment to pruningDepth

* [NOD-1249] Add pruning helper functions (#875)

* [NOD-1249] Added node.blockAtDepth

* [NOD-1249] Added node.finalityPoint()

* [NOD-1249] Add hasFinalityPointInOthersSelectedChain

* [NOD-1249] Add nonFinalityViolatingBlues

* [NOD-1249] Added isInPastOfAny

* [NOD-1249] Updated all calls to blockNode functions that require dag

* [NOD-1249] Add blockNode.reds field and persist it

* [NOD-1249] Add checkObjectiveFinality

* [NOD-1249] Add isViolatingSubjectiveFinality

* [NOD-1249] Added to TestGHOSTDAG check that reds are as expected

* [NOD-1249] Add checkMergeLimit and checkDAGRelations

* [NOD-1249] Invert condition in blockInDepth

* [NOD-1249] Make isInPastOfAny resemble isInPast

* [NOD-1249] Added comments to isInPast and isInPastOfAny

* [NOD-1252] Remove any references to legacy finality (#876)

* [NOD-1032] validateParents: check number of parents and that no parents were manually rejected (#877)

* [NOD-1254] Block verification changes (#882)

* [NOD-1254] Call checkDAGRelations and move it to correct place

* [NOD-1254] Use blockStatuses properly

* [NOD-1254] Add support for setting node's verification flag and set it to UTXONotVerified once block passes basic verification

* [NOD-1254] Check for subjctiveFinality, and for node not being in the selectedParentChain

* [NOD-1254] Make blockStatus an ordinary value - not bit flags

* [NOD-1254] Isolate all utxo-requiring validation into a single separate if branches

* [NOD-1254] Re-arrange connectBloc so that things that happen in UTXO-validated blocks only are all grouped together

* [NOD-1254] Resolve and check selectedParent's status before validatingUTXO

* [NOD-1254] Separate virtualUTXODiff from utxoVerificationOutput

* [NOD-1254] Stylistic fixes

* [NOD-1254] Use dag.index.(Set)BlockNodeStatus instead of accessing node.status

* [NOD-1288] Sub-routinize checkConnectToPastUTXO

* [NOD-1288] Re-write checkConnectToPastUTXO in a way that allows to filter-out invalid transactions

* [NOD-1288] Make checkTxSequenceLock use already calculated utxo outputs

* [NOD-1288] Make checkTxMass use already calculated utxo outputs

* [NOD-1288] Use dag.sigCache for ValidateTransactionScripts

* [NOD-1288] Use checkConnectTransactionToPastUTXO in applyBlueBlocks

* [NOD-1288] Clean-up old code-path from no longer used functions

* [NOD-1288] Skip any irrelevant parts of txo verification if block is genesis

* [NOD-1288] Set  where it should have been

* [NOD-1288] Fix reachability checks to never use the new node + make isInSelectedParentChainOf return true if node == other

* [NOD-1288] invert the condition for isNewSelectedTip

* [NOD-1288] Separate checkIsAccepted to own function, and properly handle coinbase

* [NOD-1288] Don't update utxo-diff for UTXONotVerified parents/tips + Make PrepareBlockForTest resolve the selectedParent's UTXOSet if needed

* [NOD-1288] Include mass off coinbase transactions

* [NOD-1288] Move comment to correct position

* [NOD-1288] If blockAtDepth should return genesis - do it immidiately

* [NOD-1288] Comment-out instead of removeing scriptval_test.go

* [NOD-1288] Rename: entry -> utxoEntry

* [NOD-1288] Remove special function for calcCoinbaseTxMass

* [NOD-1288] Remove redundant check from checkEntryAmounts

* [NOD-1288] Rename: MaxMassPerBlock -> MaxMassAcceptedByBlock

* [NOD-1255] Implement boundedMergeBreakingParents

* [NOD-1255] Implement selectAllowedTips

* [NOD-1255] Integrate virtual parent selection into block verification process

* [NOD-1255] Add node to tips all the time, remove it from candidates and add it's parents if it's disqualified

* [NOD-1255] remove tips from virtaulBlock

* [NOD-1255] Rename: didVirtualParentsChanged -> didVirtualParentsChange

* [NOD-1255] Remove redundant sanity check

* [NOD-1255] Handle a forgotten error

* [NOD-1255] Prettify selectVirtualParents

* [NOD-1255] UpdateTipsUTXO should run over all UTXO-Verified tips, even if they are not parents of virtual

* [NOD-1311] Make isInPast inclusive

* [NOD-1032] Handle finality conflicts (#904)

* [NOD-1312] AddTip should not include finalityViolating and manuallyRejected blocks

* [NOD-1312] Implement resolveFinalityConflict

* [NOD-1312] Implement dag notifications for finalityChanges + updateing DAG state

* [NOD-1312] Added finality conflict rpc boilerplate

* [NOD-1312] Implement handling of getFinalityConflicts + resolveFinalityConflict RPCs

* [NOD-1312] Implement finality conflict related notifications

* [NOD-1312] Move all time to millisecond time

* [NOD-1312] Add comments + unexport some methods

* [NOD-1312] Add clarification in comments

* [NOD-1312] Move updateFinalityConflictResolution to finality_conflicts.go

* [NOD-1312] Rename: currentSelectedTip -> selectedTip

* [NOD-1312] Add long comment to ResolveFinalityConflict

* [NOD-1312] Convert areAllInSelectedParentChainOf into isInSelectedParentChainOfAll

* [NOD-1312] Rename chainUpdates (type) -> selectedParentChainUpdates, to distinguish from the variable chainUpdates

* [NOD-1032] Make all blockdag tests compile

* [NOD-1278] Fix finality-related tests (#910)

* [NOD-1032] Don't return node.dag.genesis from blockAtDepth because it might still not exist

* [NOD-1032] Actually add a tip in dag.addTip

* [NOD-1278] Add transaction to utxo set if it's coinbase

* [NOD-1278] Use VirtualParentHashes instead of TipHashes where appropriate

* [NOD-1278] If no valid virtual parent candidates - return error, don't wait for panic

* [NOD-1278] Transition TestCalcSequenceLock from newTestDAG to DAGSetup

* [NOD-1278] Fix .bluest() tie-breaker

* [NOD-1278] Remove feeData structure, as it no longer works, store feeData in acceptanceData

* [NOD-1278] Remove dag parameter from blockNode methods

* [NOD-1278] Fix TestBlueBlockWindow

* [NOD-1278] Don't subject selectedParent to MaxMergeSet

* [NOD-1278] se PrepareAndProcessBlockForTest instead of .addTip in TestSelectedPath

* [NOD-1278] Fixed TestDAGStateSerialization

* [NOD-1278] Fix TestAcceptanceIndexRecover

* [NOD-1278] Fix TestCheckConnectBlockTemplate

* [NOD-1278] Fix TestChainUpdates

* [NOD-1278] Fix and rename TestVirtualBlock -> TestTips

* [NOD-1278] Rename checkIsAccepted -> maybeAcceptTx

* [NOD-1278] Re-activate TestDoubleSpends

* Revert "[NOD-1278] Fixed TestDAGStateSerialization"

This reverts commit 845095d6de.

* [NOD-1278] Remove dag parameter from expectedCoinbaseTransaction

* [NOD-1348] Implemented simplified Finality Conflict Resolution scheme (#911)

* [NOD-1348] Rename functions according to Research spec

* [NOD-1348] Added blockSet.areAllIn

* [NOD-1348] Implemented simplified finality conflict resolution scheme

* [NOD-1348] Refactorings and fixes in selectVirtualParents

* [NOD-1278] Fix bugs discovered by unit-tests + Fix unit-tests (#916)

* Updated to version v0.3.1

* [NOD-858] Don't switch sync peer if the syncing process hasn't yet started with the current sync peer (#700)

* [NOD-858] Don't switch sync peer if the syncing process hasn't yet started with the current sync peer

* [NOD-858] SetShouldSendBlockLocator(false) on OnBlockLocator

* [NOD-858] Rename shouldSendBlockLocator->wasBlockLocatorRequested

* [NOD-858] Move panic to shouldReplaceSyncPeer

* [NOD-869] Add a print after os.Exit(1) to see if it is ever called (#701)

* [NOD-1238] Fix acceptance index never being initialized. (#859)

* [NOD-1278] Genesis never violates finality

* [NOD-1348] Refactorings and fixes in selectVirtualParents

* [NOD-1278] Don't call dag.selectVirtualParents for genesis

* [NOD-1278] Properly organize errors in maybeAcceptBlock

* [NOD-1278] updateTipsUTXO should only run on tips whose status is

* [NOD-1278] updateTipsUTXO should only run on tips whose status is `valid`

* [NOD-1278] Fix TestDoubleSpends

* [NOD-1278] Fix TestDAGIndexFailedStatus

* [NOD-1278] IsFinalizedTransaction should use uint64 everywhere

* [NOD-1278] If tx is coinbase and not selectedParent - don't update pastUTXO

* [NOD-1278] Store tips and validTips separately

* [NOD-1278] Store ValidTips and VirtualParents in dagState

* [NOD-1278] Fix TestProcessOrphans

* [NOD-1278] Fix TestProcessOrphans

* [NOD-1278] Fix TestOrderInDiffFromAcceptanceData

* [NOD-1278] Fix TestHelp

* [NOD-1278] Remove mining.PrepareBlockForTest; use blockdag.PrepareBlockForTest instead

* [NOD-1278] Explicitly disallow chained transactions

* [NOD-1278]

* [NOD-1278] Fix some comments

Co-authored-by: Ori Newman <orinewman1@gmail.com>
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
Co-authored-by: Yuval Shaul <yuval.shaul@gmail.com>

* [NOD-1355] Add unit-test for finality + When resolving finalityConflict - make sure the block that will come out selectedTip is statusValid (#919)

* [NOD-1355] Added test for finality

* [NOD-1355] When resolving finalityConflict - make sure the block that will come out selectedTip is statusValid

* [NOD-1032] Renames: anything about inputsWithReferencedUTXOEntries -> remove 'Referenced'

* [NOD-1032] Don't ignore non-rule errors

* [NOD-1032] Fix comment

* [NOD-1032] Enhanced comments on TestChainUpdates

* [NOD-1032] Remove scriptval_test.go

* [NOD-1032] Extracted isNewSelectedTip to a method

* [NOD-1032] Use dag.Now() instead of mstime.Now()

* [NOD-1032] Print block status when accepting block

* [NOD-1032] Add comment explaining boundedMergeBreakingParents

* [NOD-1032] Enhanced test and imporved comments in TestFinality

* [NOD-1032] Rename: Objective finality -> bounded merge depth

* [NOD-1032] No need to check that validTips are valid

* [NOD-1032] Remove dag from arguments of updateDiffAndDiffChild

* [NOD-1032] Correct variable names in LookupNodes

[NOD-1032] Correct variable names in LookupNodes

* [NOD-1032] Fix some comments

* [NOD-1032] Some style changes

* [NOD-1032] Refactor isAnyInPastOf

* [NOD-1032] Enhance comment in updateVirtualParents

* [NOD-1032] Flip condition in updateVirtualParents

* [NOD-1032] Stylistic and grammatic fixes in dag.go and dag_test.go

* [NOD-1032] Explain why updateSelectedParentSet receives geneses on init

* [NOD-1032] Remove ErrParentManuallyRejected

* [NOD-1032] Added wrapper for resolveNodeStatus that creates a special transaction for it

* [NOD-1032] Rename: statusUTXONotVerified -> statusUTXOPendingVerification

* [NOD-1032] Use virtual parents in CurrentBits()

* [NOD-1032] rename: isViolatingSubjectiveFinality -> isViolatingFinality

* [NOD-1032] Move updateVirtualAndTips to applyDAGChanges

* [NOD-1032] Invert condition for isFinalityPointInPast

* [NOD-1032] Fix antiPastBetween isInPast became inclusive

* [NOD-1032] Remove redundant call for addTip

* [NOD-1032] Use calcCoinbaseTxMass where appropriate

* [NOD-1032] Remove time fields from conflict notifications

* [NOD-1032] Assign the correct thing to i

* [NOD-1032] unify checkOutputsAmounts and checkTxOutputAmounts

* [NOD-1032] Cleanup in CheckTransactionInputsAndCalulateFee

* [NOD-1032] Fixed some style and comments

* [NOD-1032] If selectedParent is disqualifiedFromChain - validateAndApplyUTXOSet should return this as a ruleError

* [NOD-1032] Set the status in resolveNodeStatus

* [NOD-1032] Correct comment on boundedMergeBreakingParents

* [NOD-1032] Fix a typo.

* [NOD-1032] Update a variable name.

* [NOD-1032] Fix a comment.

* [NOD-1032] Fix merge errors.

* [NOD-1032] Add VirtualParentHashes to getBlockDagInfo.

* [NOD-1032] Update handleGetBlockTemplate.

* [NOD-1032] Comment out all the old RPC stuff.

* [NOD-1032] Remove irrelevant type.

* [NOD-1032] Implement ResolveFinalityConflict.

* [NOD-1032] Remove irrelevant comments.

* [NOD-1032] Implement NotifyFinalityConflicts.

* [NOD-1032] Add FinalityConflictNotification and FinalityConflictResolvedNotification.

* [NOD-1032] Finish implementing finality conflict notifications.

* [NOD-1032] Remove old RPC stuff.

* [NOD-1032] Fix grammar in a comment.

Co-authored-by: Ori Newman <orinewman1@gmail.com>
Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
Co-authored-by: Yuval Shaul <yuval.shaul@gmail.com>
Co-authored-by: stasatdaglabs <stas@daglabs.com>
2020-09-13 17:49:59 +03:00
stasatdaglabs
64f5b96295 Update to version 0.7.0 2020-09-13 17:34:33 +03:00
oudeis
8d38a28b82 Update to version 0.6.11 2020-09-13 13:34:10 +00:00
Elichai Turkel
1743dc694a Stop using big.Int to compare hashes (#912)
* Add a benchmark for Hash.Cmp()

* Compare hashes directly without going through big.Int

* Add a more thorough test for Hash.Cmp()
2020-09-10 17:32:45 +03:00
stasatdaglabs
8fb30a5895 [NOD-1367] Fix a race condition with notification listeners (#925)
* [NOD-1367] Add an error handler to GRPCClient.

* [NOD-1367] Fix race condition with notification listeners.

* [NOD-1367] Make go vet happy.
2020-09-10 16:04:56 +03:00
Ori Newman
d59ed71465 [NOD-1381] Make Dockerfile for kaspactl (#924) 2020-09-09 19:01:51 +03:00
stasatdaglabs
ea0f5ca60e [NOD-1367] Remove leftover RPC-related stuff. (#923) 2020-09-09 17:14:34 +03:00
Ubuntu
bf74341257 Update to version 0.6.10 2020-09-09 13:21:51 +00:00
stasatdaglabs
c4e6dee1e6 [NOD-1367] Fix bad default RPC listen host (#922)
* [NOD-1367] Fix bad default RPC listen host.

* [NOD-1367] Fix a comment.
2020-09-09 15:23:04 +03:00
Ori Newman
34ab661cde [NOD-1370] in NewMinimalNetAdapter call to SetRPCRouterInitializer (#921) 2020-09-09 14:44:14 +03:00
stasatdaglabs
26b3ce4eb7 [NOD-1367] Implement getBlockCount and getBlockDagInfo (#920)
* [NOD-1367] Implement GetBlockCount.

* [NOD-1367] Implement GetBlockDagInfo.
2020-09-09 14:10:19 +03:00
oudeis
e10e418971 [NOD-1151] Update DNSSeeder to use grpc (#903)
* [NOD-1151] Added gRPC server for seeding peers

* [NOD-1151] Fix  branch after rebase

* [NOD-1151] Lint infrastructure/config/config.go

* [NOD-1151] Use Warnf instead of Infof

* [NOD-1151] Check if a.cfg.GRPCSeed is defined

* [NOD-1151] Delete Makefile

- Use go generate instead of Makefile

* [NOD-1151] Panic in case of GRPCSeed and DNSSeed are both defined

* [NOD-1151] Add generate.go file

* [NOD-1151] Allow dnsseed and grpcseed to work together

Co-authored-by: Bogdan Ovsiannikov <takahawkkun@gmail.com>
Co-authored-by: yaroslavr-itd <yaroslav.r@it-dimension.com>
Co-authored-by: Ori Newman <orinewman1@gmail.com>
2020-09-08 18:31:59 +03:00
stasatdaglabs
4c915f12b7 [NOD-1319] Reimplement kaspad's RPC in gRPC (#914)
* [NOD-1319] Create the protorpc package.

* [NOD-1319] Use a general ClientStream in closeSend.

* [NOD-1319] Decouple p2pServer from gRPCServer.

* [NOD-1319] Begin implementing rpcServer.

* [NOD-1319] Move grpcStream to grpc_connection.go.

* [NOD-1319] Fold the rpc messages.proto into a common message.proto.

* [NOD-1319] Remove code duplication in MessageStream.

* [NOD-1319] Rename methods in netadapter.

* [NOD-1319] Rename message_xxx to p2p_xxx.

* [NOD-1319] Section off p2p messages from rpc messages in messages.proto.

* [NOD-1319] Split toPayload to a p2p part and and rpc part.

* [NOD-1319] Rename msgxxx.go to p2p_msgxx.go in the appmessage package.

* [NOD-1319] Implement GetCurrentVersionRequestMessage and GetCurrentVersionResponseMessage.

* [NOD-1319] Implement toAppMessage and fromAppMessage for getCurrentNetwork

* [NOD-1319] Make a temporary workaround so that tests pass.

* [NOD-1319] Begin implementing the rpc manager.

* [NOD-1319] Implement an initial routerInitializer for rpc.

* [NOD-1319] Rename the spawn in routerInitializer.

* [NOD-1319] Implement an RPC context.

* [NOD-1319] Move the actual handlers to a separate package.

* [NOD-1319] Use the correct value for the GetCurrentNetwork response.

* [NOD-1319] Fix some names.

* [NOD-1319] Begin implementing a cli rpc client.

* [NOD-1319] Implement connecting to the RPC server.

* [NOD-1319] Make sure that connecting to the server and sending/receiving messages works.

* [NOD-1319] Make kaspactl2 speak in json strings.

* [NOD-1319] Finish implementing kaspactl2.

* [NOD-1319] Remove debug messages.

* [NOD-1319] Properly handle errors in rpc.go.

* [NOD-1319] Move the grpc client to a separate package.

* [NOD-1319] Extract Post out of PostString.

* [NOD-1319] Implement PostAppMessage.

* [NOD-1319] Stub out submitBlock.

* [NOD-1319] Stub out getBlockTemplate.

* [NOD-1319] Combine request and reponse files.

* [NOD-1319] Implement submitBlock.

* [NOD-1319] Implement returning errors from RPC.

* [NOD-1319] Begin implementing getBlockTemplate.

* [NOD-1319] Add missing field in GetBlockTemplateRequestMessage.

* [NOD-1319] Implement a minimal getBlockTemplate.

* [NOD-1319] Add getBlockTemplate stuff to grpc.

* [NOD-1319] Implement the rest of getBlockTemplate.

* [NOD-1319] Add block/transaction added handlers to the protocol manager.

* [NOD-1319] Implement NotifyTransactionAddedToMempool.

* [NOD-1319] Implement NotifyBlockAddedToDAG.

* [NOD-1319] Connect block/transaction added handlers.

* [NOD-1319] Add notifyBlockAdded.

* [NOD-1319] Add a notification system.

* [NOD-1319] Improve the notification system.

* [NOD-1319] Add a block added listener stub.

* [NOD-1319] Add BlockAddedNotificationMessage.

* [NOD-1319] Finish implementing HandleNotifyBlockAdded.

* [NOD-1319] Println instead of Print in kaspactl2.

* [NOD-1319] Remove unused flags in kaspactl2.

* [NOD-1319] Make kaspaminer work with the new RPC.

* [NOD-1319] Fix a bad log.

* [NOD-1319] Make kaspaminer work.

* [NOD-1319] Disconnect the old RPC.

* [NOD-1319] Move grpcclient.go.

* [NOD-1319] Begin generalizing the rpcClient.

* [NOD-1319] Move errors to the side of the payload.

* [NOD-1319] Add errors to appmessage.

* [NOD-1319] Move AttachRouter to grpcclient.

* [NOD-1319] Fix kaspaminer not handling responses.

* [NOD-1319] Properly handle blockAddedNotifications.

* [NOD-1319] Move errors into individual response objects.

* [NOD-1319] Begin replacing the RPC client in the integration tests.

* [NOD-1319] Implement GetPeerAddresses.

* [NOD-1319] Implement GetPeerAddresses.

* [NOD-1319] Fix setOnBlockAddedHandler.

* [NOD-1319] Remove the old kaspactl.

* [NOD-1319] Move ConvertGetBlockTemplateResultToBlock to the mining package.

* [NOD-1319] Implement getSelectedTipHash.

* [NOD-1319] Simplify testRPCRouter.

* [NOD-1319] Write stubs for the required test RPC commands.

* [NOD-1319] Implement a minimal getMempoolEntry.

* [NOD-1319] Implement a minimal getMempoolEntry.

* [NOD-1319] Implement getConnectedPeerInfo.

* [NOD-1319] Delete the old RPC.

* [NOD-1319] Fix a fromAppMessage.

* [NOD-1319] Implement connectToPeer.

* [NOD-1319] Fix a bug in registerForBlockAddedNotifications.

* [NOD-1319] Fix a deadlock in closing notification listeners.

* [NOD-1319] Fix merge errors.

* [NOD-1319] Fix an import.

* [NOD-1319] Properly handle errors in grpcclient.

* [NOD-1319] Fix TestIBD.

* [NOD-1319] Prevent kaspaminer from running when not connected.

* [NOD-1319] Implement sendRawTransaction.

* [NOD-1319] Implement sendRawTransaction in the client.

* [NOD-1319] Extract a general RPC client from the integration test RPC client.

* [NOD-1319] Use the general RPC client for the miner.

* [NOD-1319] Move the rpcclient package out of netadapter.

* [NOD-1319] Normalize onBlockAdded.

* [NOD-1319] Begin implementing notifyChainChanged.

* [NOD-1319] Implement the model for notifyChainChanged.

* [NOD-1319] Implement conversions for notifyChainChanged.

* [NOD-1319] Implement HandleNotifyChainChanged.

* [NOD-1319] Normalize notifications.

* [NOD-1319] Implement RegisterForChainChangedNotifications.

* [NOD-1319] Begin connecting blockdag's chain-changed notification with the RPC.

* [NOD-1319] Finish implementing notifyChainChanged.

* [NOD-1319] Implement getBlockHex.

* [NOD-1319] Rename getBlockHex to getBlock.

* [NOD-1319] Implement the verbose model for getBlock.

* [NOD-1319] Implement buildBlockVerboseData.

* [NOD-1319] Implement buildTransactionVerboseData.

* [NOD-1319] Move verboseData stuff to verbosedata.go.

* [NOD-1319] Add includeTransactionVerboseData.

* [NOD-1319] Begin implementing getSubnetwork.

* [NOD-1319] Finish implementing getSubnetwork.

* [NOD-1319] Begin implementing getChainFromBlock.

* [NOD-1319] Finish implementing getChainFromBlock.

* [NOD-1319] Begin implementing getBlocks.

* [NOD-1319] Finish implementing getBlocks.

* [NOD-1319] Fix bad responses in HandleNotifyChainChanged.

* [NOD-1319] Fix bugs in verbosedata.go.

* [NOD-1319] Fix more bugs in verbosedata.go.

* [NOD-1319] Make go vet happy.

* [NOD-1319] Extract handleBlockDAGNotifications to a method.

* [NOD-1319] Add a newline.

* [NOD-1319] Use peers instead of connections to check if connected.

* [NOD-1319] Add a comment.

* [NOD-1319] Lock the dag lock in getBlock.

* [NOD-1319] Rename netAdapter.connections to p2pConnections.

* [NOD-1319] In protowire, rename wireXXX to protoXXX.

* [NOD-1319] Rename PostString to PostJSON.

* [NOD-1319] Disallow empty transactions in SendRawTransaction.

* [NOD-1319] Disallow empty blocks in SubmitBlocks.

* [NOD-1319] Add SetLogger.

* [NOD-1319] Fix an error message.

* [NOD-1319] Fix an error message.

* [NOD-1319] Rename testTimeout to rpcTimeout.

* [NOD-1319] Rename SendRawTransaction to SubmitTransaction.

* [NOD-1319] Rename ConnectToPeer to AddPeer.

* [NOD-1319] Add missing longPollID to request.

* [NOD-1319] Rename ChainChangedChainBlock to ChainBlock.

* [NOD-1319] Rename Vin and Vout.

* [NOD-1319] Implement RPCErrorf.

* [NOD-1319] Fix RPCErrorf's comment.

* [NOD-1319] Remove unused flags in kaspaminer.
2020-09-07 14:35:40 +03:00
Ori Newman
3c454eefe9 [NOD-1353] Return error on capacity reached (#913)
* [NOD-1353] Return error on capacity reached

* [NOD-1353] Fix grammer error
2020-09-06 11:43:08 +03:00
oudeis
3839767aed [NOD-815] Refactor all UTXO-diff algebra methods (#857)
* UTXOSet: Refactoring.

* Use set operations for utxo collection rules.
* diffFrom Refactoring.
* withDiffInPlace Refactoring.

* [NOD-815] Refactor all UTXO-diff algebra methods

* Use set operations for utxo collection rules.
* diffFrom Refactoring.
* withDiffInPlace Refactoring.

* Stylistic fixes.

* UTXOSet: Refactoring. Add benchmarks. Optimizations.

* Add UTXOSet diffFrom, withDiff benchmarks.
* Add performance optimizations.
* Add both in-place and value-return methods for set operations.
* Remove redundant blue score condition checking in withDiffInPlace
  second error rule.
* Improve naming.
* PR fixes.

* After-merge build fixes.

* Typo fixes.

* Stylistic fixes.

* After-merge build fixes.

* Typo fixes.

Co-authored-by: Septen <gammerxpower@gmail.com>
2020-09-01 09:30:08 +03:00
Ori Newman
fc0a7ca7e3 Update to version 0.6.9 2020-08-31 16:11:16 +03:00
Ori Newman
a32a9011c7 [NOD-1305] Close client connection on disconnect (#909) 2020-08-31 15:57:11 +03:00
stasatdaglabs
5da957f16e Update to version 0.6.8 2020-08-30 11:31:43 +03:00
Ori Newman
505d264603 [NOD-1322] Fix compilation on windows (#905) 2020-08-27 18:04:54 +03:00
Ori Newman
883361fea3 [NOD-1323] Always save new block reachability data (#906) 2020-08-27 18:03:50 +03:00
stasatdaglabs
13a6872a45 Update to version 0.6.7 2020-08-26 12:13:43 +03:00
Elichai Turkel
c82a951a24 [NOD-1316] Refactor TestGHOSTDAG to enable arbitrary DAGs (#899)
* Add VirtualBlueHashes to BlockDAG

* Refactor TestGHOSTDAG to read DAGs from json files

* Added a new DAG for the ghostdag test suite

* Pass BehaviorFlags to delayed blocks
2020-08-25 14:00:43 +03:00
Ori Newman
bbb9dfa4cd [NOD-1318] Check if relay block is known before requesting it (#900) 2020-08-25 09:18:03 +03:00
stasatdaglabs
86d51fa1cb [NOD-1307] Fix duplicate connections (#897)
* [NOD-1307] Lock peersMutex in methods that don't.

* [NOD-1307] Fix duplicate connections.

* [NOD-1307] Use RLock instead of Lock.

* [NOD-1307] Simplify IsEqual.
2020-08-24 16:11:32 +03:00
Ori Newman
8dd7b95423 [NOD-1308] Don't call wg.done() on handshake if flow failed (#896) 2020-08-24 14:03:58 +03:00
stasatdaglabs
b668d98942 [NOD-1095] Fix data races in gRPCConnection.stream. (#895) 2020-08-24 12:56:19 +03:00
stasatdaglabs
e9602cc777 [NOD-1304] Fix nil deference originating in HandleHandshake. (#894) 2020-08-24 11:45:33 +03:00
stasatdaglabs
5fd164bf66 [NOD-1095] RLock the dagLock in SelectedTipHeader. (#893) 2020-08-24 11:31:12 +03:00
Ori Newman
83e7c9e8e4 [NOD-1303] Fix concurent access to UTXO set from RPC (#892) 2020-08-23 18:54:03 +03:00
Ori Newman
a6b8eea369 [NOD-1301] Add MsgReject to protowire mapping (#891) 2020-08-23 18:29:41 +03:00
stasatdaglabs
15b545ee2b [NOD-592] Remove TODOs and XXXs from the codebase (#890)
* [NOD-592] Remove TODOs related to fake nonces.

* [NOD-592] Remove irrelevant TODOs from handleRescanBlocks and parseTxAcceptedVerboseNtfnParams.

* [NOD-592] Fix TODO in handleGetTxOut.

* [NOD-592] Remove irrelevant TODO from updateAddress.

* [NOD-592] Move StandardVerifyFlags to a separate file.

* [NOD-592] Remove TODOs in sign.go.

* [NOD-592] Remove TODO in scriptval_test.go.

* [NOD-592] Remove TODO in reachabilitystore.go.

* [NOD-592] Remove XXXs.

* [NOD-592] Fix a comment.

* [NOD-557] Move AddAddressByIP out of AddressManager since it's used only for tests..

* [NOD-557] Remove rescan blocks.

* [NOD-592] Fix handleGetTxOut.
2020-08-23 17:17:06 +03:00
stasatdaglabs
667b2d46e9 [NOD-557] Remove RegTest (#889)
* [NOD-557] Remove regTest network.

* [NOD-557] Remove remaining references to regTest.

* [NOD-557] Move newHashFromStr from params.go to params_test.go.

* [NOD-557] Rename test to network in register_test.go.

* [NOD-557] Replaced removed tests in TestDecodeAddressErrorConditions.
2020-08-23 15:38:27 +03:00
stasatdaglabs
53ab906ea8 [NOD-1279] Handle ruleErrors properly in processIBDBlock. (#887) 2020-08-23 13:42:21 +03:00
stasatdaglabs
5d20772f94 [NOD-1293] Fix kaspad sending 127.0.0.1 in its msgVersion (#886)
* [NOD-1293] Use addressManager's GetBestLocalAddress.

* [NOD-1293] Copy the initListeners function from the old p2p to the address manager.

* [NOD-1293] Remove debug logs.

* [NOD-1293] Remove unused import.

* [NOD-1293] Fix a comment.
2020-08-23 13:11:48 +03:00
stasatdaglabs
d4728bd9b6 Update to version 0.6.6 2020-08-23 11:22:13 +03:00
Yuval Shaul
a361d62945 Merge remote-tracking branch 'origin/v0.6.2-dev' 2020-08-16 13:51:25 +03:00
Yuval Shaul
aac173ed72 Merge remote-tracking branch 'origin/v0.6.1-dev' 2020-08-12 10:48:51 +03:00
stasatdaglabs
5f3fb0bf9f [NOD-1238] Fix acceptance index never being initialized. (#859) 2020-08-11 12:04:54 +03:00
Mike Zak
61f383a713 Merge remote-tracking branch 'origin/v0.6.0-dev' 2020-08-09 09:09:27 +03:00
Mike Zak
c62bdb2fa1 Merge remote-tracking branch 'origin/v0.5.0-dev' 2020-07-01 15:05:02 +03:00
Svarog
c88869778d [NOD-869] Add a print after os.Exit(1) to see if it is ever called (#701) 2020-04-22 11:37:30 +03:00
Ori Newman
3fd647b291 [NOD-858] Don't switch sync peer if the syncing process hasn't yet started with the current sync peer (#700)
* [NOD-858] Don't switch sync peer if the syncing process hasn't yet started with the current sync peer

* [NOD-858] SetShouldSendBlockLocator(false) on OnBlockLocator

* [NOD-858] Rename shouldSendBlockLocator->wasBlockLocatorRequested

* [NOD-858] Move panic to shouldReplaceSyncPeer
2020-04-13 15:49:46 +03:00
Mike Zak
2f255952b7 Updated to version v0.3.1 2020-04-13 15:10:27 +03:00
1409 changed files with 133530 additions and 67805 deletions

9
.codecov.yml Normal file
View File

@@ -0,0 +1,9 @@
coverage:
status:
patch: off
project:
default:
informational: true
ignore:
- "**/*.pb.go" # Ignore all auto generated protobuf structures.

196
.github/workflows/SetPageFileSize.ps1 vendored Normal file
View File

@@ -0,0 +1,196 @@
<#
# MIT License (MIT) Copyright (c) 2020 Maxim Lobanov and contributors
# Source: https://github.com/al-cheb/configure-pagefile-action/blob/master/scripts/SetPageFileSize.ps1
.SYNOPSIS
Configure Pagefile on Windows machine
.NOTES
Author: Aleksandr Chebotov
.EXAMPLE
SetPageFileSize.ps1 -MinimumSize 4GB -MaximumSize 8GB -DiskRoot "D:"
#>
param(
[System.UInt64] $MinimumSize = 16gb ,
[System.UInt64] $MaximumSize = 16gb ,
[System.String] $DiskRoot = "D:"
)
# https://referencesource.microsoft.com/#System.IdentityModel/System/IdentityModel/NativeMethods.cs,619688d876febbe1
# https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/mm/modwrite/create.htm
# https://referencesource.microsoft.com/#mscorlib/microsoft/win32/safehandles/safefilehandle.cs,9b08210f3be75520
# https://referencesource.microsoft.com/#mscorlib/system/security/principal/tokenaccesslevels.cs,6eda91f498a38586
# https://www.autoitscript.com/forum/topic/117993-api-ntcreatepagingfile/
$source = @'
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
namespace Util
{
class NativeMethods
{
[StructLayout(LayoutKind.Sequential)]
internal struct LUID
{
internal uint LowPart;
internal uint HighPart;
}
[StructLayout(LayoutKind.Sequential)]
internal struct LUID_AND_ATTRIBUTES
{
internal LUID Luid;
internal uint Attributes;
}
[StructLayout(LayoutKind.Sequential)]
internal struct TOKEN_PRIVILEGE
{
internal uint PrivilegeCount;
internal LUID_AND_ATTRIBUTES Privilege;
internal static readonly uint Size = (uint)Marshal.SizeOf(typeof(TOKEN_PRIVILEGE));
}
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct UNICODE_STRING
{
internal UInt16 length;
internal UInt16 maximumLength;
internal string buffer;
}
[DllImport("kernel32.dll", SetLastError=true)]
internal static extern IntPtr LocalFree(IntPtr handle);
[DllImport("advapi32.dll", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern bool LookupPrivilegeValueW(
[In] string lpSystemName,
[In] string lpName,
[Out] out LUID luid
);
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = false)]
internal static extern bool AdjustTokenPrivileges(
[In] SafeCloseHandle tokenHandle,
[In] bool disableAllPrivileges,
[In] ref TOKEN_PRIVILEGE newState,
[In] uint bufferLength,
[Out] out TOKEN_PRIVILEGE previousState,
[Out] out uint returnLength
);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, PreserveSig = false)]
internal static extern bool OpenProcessToken(
[In] IntPtr processToken,
[In] int desiredAccess,
[Out] out SafeCloseHandle tokenHandle
);
[DllImport("ntdll.dll", CharSet = CharSet.Unicode, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern Int32 NtCreatePagingFile(
[In] ref UNICODE_STRING pageFileName,
[In] ref Int64 minimumSize,
[In] ref Int64 maximumSize,
[In] UInt32 flags
);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern uint QueryDosDeviceW(
string lpDeviceName,
StringBuilder lpTargetPath,
int ucchMax
);
}
public sealed class SafeCloseHandle: SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
internal extern static bool CloseHandle(IntPtr handle);
private SafeCloseHandle() : base(true)
{
}
public SafeCloseHandle(IntPtr preexistingHandle, bool ownsHandle) : base(ownsHandle)
{
SetHandle(preexistingHandle);
}
override protected bool ReleaseHandle()
{
return CloseHandle(handle);
}
}
public class PageFile
{
public static void SetPageFileSize(long minimumValue, long maximumValue, string lpDeviceName)
{
SetPageFilePrivilege();
StringBuilder lpTargetPath = new StringBuilder(260);
UInt32 resultQueryDosDevice = NativeMethods.QueryDosDeviceW(lpDeviceName, lpTargetPath, lpTargetPath.Capacity);
if (resultQueryDosDevice == 0)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
string pageFilePath = lpTargetPath.ToString() + "\\pagefile.sys";
NativeMethods.UNICODE_STRING pageFileName = new NativeMethods.UNICODE_STRING
{
length = (ushort)(pageFilePath.Length * 2),
maximumLength = (ushort)(2 * (pageFilePath.Length + 1)),
buffer = pageFilePath
};
Int32 resultNtCreatePagingFile = NativeMethods.NtCreatePagingFile(ref pageFileName, ref minimumValue, ref maximumValue, 0);
if (resultNtCreatePagingFile != 0)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
Console.WriteLine("PageFile: {0} / {1} bytes for {2}", minimumValue, maximumValue, pageFilePath);
}
static void SetPageFilePrivilege()
{
const int SE_PRIVILEGE_ENABLED = 0x00000002;
const int AdjustPrivileges = 0x00000020;
const int Query = 0x00000008;
NativeMethods.LUID luid;
NativeMethods.LookupPrivilegeValueW(null, "SeCreatePagefilePrivilege", out luid);
SafeCloseHandle hToken;
NativeMethods.OpenProcessToken(
Process.GetCurrentProcess().Handle,
AdjustPrivileges | Query,
out hToken
);
NativeMethods.TOKEN_PRIVILEGE previousState;
NativeMethods.TOKEN_PRIVILEGE newState;
uint previousSize = 0;
newState.PrivilegeCount = 1;
newState.Privilege.Luid = luid;
newState.Privilege.Attributes = SE_PRIVILEGE_ENABLED;
NativeMethods.AdjustTokenPrivileges(hToken, false, ref newState, NativeMethods.TOKEN_PRIVILEGE.Size, out previousState, out previousSize);
}
}
}
'@
Add-Type -TypeDefinition $source
# Set SetPageFileSize
[Util.PageFile]::SetPageFileSize($minimumSize, $maximumSize, $diskRoot)

76
.github/workflows/deploy.yaml vendored Normal file
View File

@@ -0,0 +1,76 @@
name: Build and upload assets
on:
release:
types: [ published ]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
name: Building, ${{ matrix.os }}
steps:
- name: Fix CRLF on Windows
if: runner.os == 'Windows'
run: git config --global core.autocrlf false
- name: Check out code into the Go module directory
uses: actions/checkout@v2
# Increase the pagefile size on Windows to aviod running out of memory
- name: Increase pagefile size on Windows
if: runner.os == 'Windows'
run: powershell -command .github\workflows\SetPageFileSize.ps1
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.16
- name: Build on Linux
if: runner.os == 'Linux'
# `-extldflags=-static` - means static link everything,
# `-tags netgo,osusergo` means use pure go replacements for "os/user" and "net"
# `-s -w` strips the binary to produce smaller size binaries
run: |
go build -v -ldflags="-s -w -extldflags=-static" -tags netgo,osusergo -o ./bin/ . ./cmd/...
archive="bin/kaspad-${{ github.event.release.tag_name }}-linux.zip"
asset_name="kaspad-${{ github.event.release.tag_name }}-linux.zip"
zip -r "${archive}" ./bin/*
echo "archive=${archive}" >> $GITHUB_ENV
echo "asset_name=${asset_name}" >> $GITHUB_ENV
- name: Build on Windows
if: runner.os == 'Windows'
shell: bash
run: |
go build -v -ldflags="-s -w" -o bin/ . ./cmd/...
archive="bin/kaspad-${{ github.event.release.tag_name }}-win64.zip"
asset_name="kaspad-${{ github.event.release.tag_name }}-win64.zip"
powershell "Compress-Archive bin/* \"${archive}\""
echo "archive=${archive}" >> $GITHUB_ENV
echo "asset_name=${asset_name}" >> $GITHUB_ENV
- name: Build on MacOS
if: runner.os == 'macOS'
run: |
go build -v -ldflags="-s -w" -o ./bin/ . ./cmd/...
archive="bin/kaspad-${{ github.event.release.tag_name }}-osx.zip"
asset_name="kaspad-${{ github.event.release.tag_name }}-osx.zip"
zip -r "${archive}" ./bin/*
echo "archive=${archive}" >> $GITHUB_ENV
echo "asset_name=${asset_name}" >> $GITHUB_ENV
- name: Upload release asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: "./${{ env.archive }}"
asset_name: "${{ env.asset_name }}"
asset_content_type: application/zip

49
.github/workflows/race.yaml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: Race
on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
jobs:
race_test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
branch: [ master, latest ]
name: Race detection on ${{ matrix.branch }}
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.16
- name: Set scheduled branch name
shell: bash
if: github.event_name == 'schedule'
run: |
if [ "${{ matrix.branch }}" == "master" ]; then
echo "run_on=master" >> $GITHUB_ENV
fi
if [ "${{ matrix.branch }}" == "latest" ]; then
branch=$(git branch -r | grep 'v\([0-9]\+\.\)\([0-9]\+\.\)\([0-9]\+\)-dev' | sort -Vr | head -1 | xargs)
echo "run_on=${branch}" >> $GITHUB_ENV
fi
- name: Set manual branch name
shell: bash
if: github.event_name == 'workflow_dispatch'
run: echo "run_on=${{ github.ref }}" >> $GITHUB_ENV
- name: Test with race detector
shell: bash
run: |
git checkout "${{ env.run_on }}"
git status
go test -timeout 20m -race ./...

98
.github/workflows/tests.yaml vendored Normal file
View File

@@ -0,0 +1,98 @@
name: Tests
on:
push:
pull_request:
# edtited - because base branch can be modified
# synchronize - update commits on PR
types: [opened, synchronize, edited]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, macos-latest ]
name: Tests, ${{ matrix.os }}
steps:
- name: Fix CRLF on Windows
if: runner.os == 'Windows'
run: git config --global core.autocrlf false
- name: Check out code into the Go module directory
uses: actions/checkout@v2
# Increase the pagefile size on Windows to aviod running out of memory
- name: Increase pagefile size on Windows
if: runner.os == 'Windows'
run: powershell -command .github\workflows\SetPageFileSize.ps1
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.16
# Source: https://github.com/actions/cache/blob/main/examples.md#go---modules
- name: Go Cache
uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Test
shell: bash
run: ./build_and_test.sh -v
stability-test-fast:
runs-on: ubuntu-latest
name: Fast stability tests, ${{ github.head_ref }}
steps:
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.16
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Install kaspad
run: go install ./...
- name: Install golint
run: go get -u golang.org/x/lint/golint
- name: Run fast stability tests
working-directory: stability-tests
run: ./install_and_test.sh
coverage:
runs-on: ubuntu-latest
name: Produce code coverage
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.16
- name: Delete the stability tests from coverage
run: rm -r stability-tests
- name: Create coverage file
run: go test -v -covermode=atomic -coverpkg=./... -coverprofile coverage.txt ./...
- name: Upload coverage file
run: bash <(curl -s https://codecov.io/bash)

18
.gitignore vendored
View File

@@ -13,6 +13,21 @@ kaspad.db
*.o
*.a
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Real binaries, build with `go build .`
kaspad
cmd/gencerts/gencerts
cmd/kaspactl/kaspactl
cmd/kasminer/kaspaminer
*.exe
*.exe~
# Output of the go coverage tool
*.out
# Folders
_obj
@@ -31,8 +46,7 @@ _cgo_export.*
_testmain.go
*.exe
# IDE
.idea
.vscode

18
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,18 @@
# Contributing to Kaspad
Any contribution to Kaspad is very welcome.
## Getting started
If you want to start contributing to Kaspad and don't know where to start, you can pick an issue from
the [list](https://github.com/kaspanet/kaspad/issues).
If you want to make a big change it's better to discuss it first by opening an issue or talk about it in
[Discord](https://discord.gg/WmGhhzk) to avoid duplicate work.
## Pull Request process
Any pull request should be opened against the development branch `dev`.
All pull requests should pass the checks written in `build_and_test.sh`, so it's recommended to run this script before
submitting your PR.

View File

@@ -1,20 +1,21 @@
Kaspad
====
Warning: This is pre-alpha software. There's no guarantee anything works.
====
[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](https://choosealicense.com/licenses/isc/)
[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/kaspanet/kaspad)
Kaspad is the reference full node Kaspa implementation written in Go (golang).
This project is currently under active development and is in a pre-Alpha state.
Some things still don't work and APIs are far from finalized. The code is provided for reference only.
This project is currently under active development and is in Beta state.
## What is kaspa
Kaspa is an attempt at a proof-of-work cryptocurrency with instant confirmations and sub-second block times. It is based on [the PHANTOM protocol](https://eprint.iacr.org/2018/104.pdf), a generalization of Nakamoto consensus.
## Requirements
Latest version of [Go](http://golang.org) (currently 1.13).
Go 1.16 or later.
## Installation
@@ -27,23 +28,17 @@ Latest version of [Go](http://golang.org) (currently 1.13).
```bash
$ go version
$ go env GOROOT GOPATH
```
NOTE: The `GOROOT` and `GOPATH` above must not be the same path. It is
recommended that `GOPATH` is set to a directory in your home directory such as
`~/dev/go` to avoid write permission issues. It is also recommended to add
`$GOPATH/bin` to your `PATH` at this point.
- Run the following commands to obtain and install kaspad including all dependencies:
```bash
$ git clone https://github.com/kaspanet/kaspad $GOPATH/src/github.com/kaspanet/kaspad
$ cd $GOPATH/src/github.com/kaspanet/kaspad
$ git clone https://github.com/kaspanet/kaspad
$ cd kaspad
$ go install . ./cmd/...
```
- Kaspad (and utilities) should now be installed in `$GOPATH/bin`. If you did
- Kaspad (and utilities) should now be installed in `$(go env GOPATH)/bin`. If you did
not already add the bin directory to your system path during Go installation,
you are encouraged to do so now.
@@ -53,25 +48,24 @@ $ go install . ./cmd/...
Kaspad has several configuration options available to tweak how it runs, but all
of the basic operations work with zero configuration.
#### Linux/BSD/POSIX/Source
```bash
$ ./kaspad
$ kaspad
```
## Discord
Join our discord server using the following link: https://discord.gg/WmGhhzk
Join our discord server using the following link: https://discord.gg/YNYnNN5Pf2
## Issue Tracker
The [integrated github issue tracker](https://github.com/kaspanet/kaspad/issues)
is used for this project.
Issue priorities may be seen at https://github.com/orgs/kaspanet/projects/4
## Documentation
The documentation is a work-in-progress. It is located in the [docs](https://github.com/kaspanet/kaspad/tree/master/docs) folder.
The [documentation](https://github.com/kaspanet/docs) is a work-in-progress
## License
Kaspad is licensed under the copyfree [ISC License](https://choosealicense.com/licenses/isc/).

View File

@@ -2,246 +2,188 @@ package app
import (
"fmt"
"sync/atomic"
"os"
"path/filepath"
"runtime"
"time"
"github.com/kaspanet/kaspad/infrastructure/network/addressmanager"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/id"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol"
"github.com/kaspanet/kaspad/domain/blockdag"
"github.com/kaspanet/kaspad/domain/blockdag/indexers"
"github.com/kaspanet/kaspad/domain/mempool"
"github.com/kaspanet/kaspad/domain/mining"
"github.com/kaspanet/kaspad/domain/txscript"
"github.com/kaspanet/kaspad/infrastructure/config"
"github.com/kaspanet/kaspad/infrastructure/db/dbaccess"
"github.com/kaspanet/kaspad/infrastructure/network/connmanager"
"github.com/kaspanet/kaspad/infrastructure/network/dnsseed"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter"
"github.com/kaspanet/kaspad/infrastructure/network/rpc"
"github.com/kaspanet/kaspad/infrastructure/db/database"
"github.com/kaspanet/kaspad/infrastructure/db/database/ldb"
"github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/kaspanet/kaspad/infrastructure/os/execenv"
"github.com/kaspanet/kaspad/infrastructure/os/limits"
"github.com/kaspanet/kaspad/infrastructure/os/signal"
"github.com/kaspanet/kaspad/util"
"github.com/kaspanet/kaspad/infrastructure/os/winservice"
"github.com/kaspanet/kaspad/util/panics"
"github.com/kaspanet/kaspad/util/profiling"
"github.com/kaspanet/kaspad/version"
)
// App is a wrapper for all the kaspad services
type App struct {
cfg *config.Config
rpcServer *rpc.Server
addressManager *addressmanager.AddressManager
protocolManager *protocol.Manager
connectionManager *connmanager.ConnectionManager
netAdapter *netadapter.NetAdapter
const (
leveldbCacheSizeMiB = 256
defaultDataDirname = "datadir2"
)
started, shutdown int32
var desiredLimits = &limits.DesiredLimits{
FileLimitWant: 2048,
FileLimitMin: 1024,
}
// Start launches all the kaspad services.
func (a *App) Start() {
// Already started?
if atomic.AddInt32(&a.started, 1) != 1 {
return
}
log.Trace("Starting kaspad")
err := a.protocolManager.Start()
if err != nil {
panics.Exit(log, fmt.Sprintf("Error starting the p2p protocol: %+v", err))
}
a.maybeSeedFromDNS()
a.connectionManager.Start()
if !a.cfg.DisableRPC {
a.rpcServer.Start()
}
var serviceDescription = &winservice.ServiceDescription{
Name: "kaspadsvc",
DisplayName: "Kaspad Service",
Description: "Downloads and stays synchronized with the Kaspa blockDAG and " +
"provides DAG services to applications.",
}
// Stop gracefully shuts down all the kaspad services.
func (a *App) Stop() {
// Make sure this only happens once.
if atomic.AddInt32(&a.shutdown, 1) != 1 {
log.Infof("Kaspad is already in the process of shutting down")
return
}
type kaspadApp struct {
cfg *config.Config
}
log.Warnf("Kaspad shutting down")
// StartApp starts the kaspad app, and blocks until it finishes running
func StartApp() error {
execenv.Initialize(desiredLimits)
a.connectionManager.Stop()
err := a.protocolManager.Stop()
// Load configuration and parse command line. This function also
// initializes logging and configures it accordingly.
cfg, err := config.LoadConfig()
if err != nil {
log.Errorf("Error stopping the p2p protocol: %+v", err)
fmt.Fprintln(os.Stderr, err)
return err
}
defer logger.BackendLog.Close()
defer panics.HandlePanic(log, "MAIN", nil)
// Shutdown the RPC server if it's not disabled.
if !a.cfg.DisableRPC {
err := a.rpcServer.Stop()
app := &kaspadApp{cfg: cfg}
// Call serviceMain on Windows to handle running as a service. When
// the return isService flag is true, exit now since we ran as a
// service. Otherwise, just fall through to normal operation.
if runtime.GOOS == "windows" {
isService, err := winservice.WinServiceMain(app.main, serviceDescription, cfg)
if err != nil {
log.Errorf("Error stopping rpcServer: %+v", err)
return err
}
if isService {
return nil
}
}
err = a.addressManager.Stop()
if err != nil {
log.Errorf("Error stopping address manager: %s", err)
}
return
return app.main(nil)
}
// New returns a new App instance configured to listen on addr for the
// kaspa network type specified by dagParams. Use start to begin accepting
// connections from peers.
func New(cfg *config.Config, databaseContext *dbaccess.DatabaseContext, interrupt <-chan struct{}) (*App, error) {
indexManager, acceptanceIndex := setupIndexes(cfg)
func (app *kaspadApp) main(startedChan chan<- struct{}) error {
// Get a channel that will be closed when a shutdown signal has been
// triggered either from an OS signal such as SIGINT (Ctrl+C) or from
// another subsystem such as the RPC server.
interrupt := signal.InterruptListener()
defer log.Info("Shutdown complete")
sigCache := txscript.NewSigCache(cfg.SigCacheMaxSize)
// Show version at startup.
log.Infof("Version %s", version.Version())
// Create a new block DAG instance with the appropriate configuration.
dag, err := setupDAG(cfg, databaseContext, interrupt, sigCache, indexManager)
if err != nil {
return nil, err
// Enable http profiling server if requested.
if app.cfg.Profile != "" {
profiling.Start(app.cfg.Profile, log)
}
profiling.TrackHeap(app.cfg.AppDir, log)
// Return now if an interrupt signal was triggered.
if signal.InterruptRequested(interrupt) {
return nil
}
txMempool := setupMempool(cfg, dag, sigCache)
netAdapter, err := netadapter.NewNetAdapter(cfg)
if err != nil {
return nil, err
}
addressManager := addressmanager.New(cfg, databaseContext)
connectionManager, err := connmanager.New(cfg, netAdapter, addressManager)
if err != nil {
return nil, err
}
protocolManager, err := protocol.NewManager(cfg, dag, netAdapter, addressManager, txMempool, connectionManager)
if err != nil {
return nil, err
}
rpcServer, err := setupRPC(
cfg, dag, txMempool, sigCache, acceptanceIndex, connectionManager, addressManager, protocolManager)
if err != nil {
return nil, err
}
return &App{
cfg: cfg,
rpcServer: rpcServer,
protocolManager: protocolManager,
connectionManager: connectionManager,
netAdapter: netAdapter,
addressManager: addressManager,
}, nil
}
func (a *App) maybeSeedFromDNS() {
if !a.cfg.DisableDNSSeed {
dnsseed.SeedFromDNS(a.cfg.NetParams(), a.cfg.DNSSeed, appmessage.SFNodeNetwork, false, nil,
a.cfg.Lookup, func(addresses []*appmessage.NetAddress) {
// Kaspad uses a lookup of the dns seeder here. Since seeder returns
// IPs of nodes and not its own IP, we can not know real IP of
// source. So we'll take first returned address as source.
a.addressManager.AddAddresses(addresses, addresses[0], nil)
})
}
}
func setupDAG(cfg *config.Config, databaseContext *dbaccess.DatabaseContext, interrupt <-chan struct{},
sigCache *txscript.SigCache, indexManager blockdag.IndexManager) (*blockdag.BlockDAG, error) {
dag, err := blockdag.New(&blockdag.Config{
Interrupt: interrupt,
DatabaseContext: databaseContext,
DAGParams: cfg.NetParams(),
TimeSource: blockdag.NewTimeSource(),
SigCache: sigCache,
IndexManager: indexManager,
SubnetworkID: cfg.SubnetworkID,
})
return dag, err
}
func setupIndexes(cfg *config.Config) (blockdag.IndexManager, *indexers.AcceptanceIndex) {
// Create indexes if needed.
var indexes []indexers.Indexer
var acceptanceIndex *indexers.AcceptanceIndex
if cfg.AcceptanceIndex {
log.Info("acceptance index is enabled")
acceptanceIndex = indexers.NewAcceptanceIndex()
indexes = append(indexes, acceptanceIndex)
}
// Create an index manager if any of the optional indexes are enabled.
if len(indexes) < 0 {
return nil, nil
}
indexManager := indexers.NewManager(indexes)
return indexManager, acceptanceIndex
}
func setupMempool(cfg *config.Config, dag *blockdag.BlockDAG, sigCache *txscript.SigCache) *mempool.TxPool {
mempoolConfig := mempool.Config{
Policy: mempool.Policy{
AcceptNonStd: cfg.RelayNonStd,
MaxOrphanTxs: cfg.MaxOrphanTxs,
MaxOrphanTxSize: config.DefaultMaxOrphanTxSize,
MinRelayTxFee: cfg.MinRelayTxFee,
MaxTxVersion: 1,
},
CalcSequenceLockNoLock: func(tx *util.Tx, utxoSet blockdag.UTXOSet) (*blockdag.SequenceLock, error) {
return dag.CalcSequenceLockNoLock(tx, utxoSet)
},
SigCache: sigCache,
DAG: dag,
}
return mempool.New(&mempoolConfig)
}
func setupRPC(cfg *config.Config,
dag *blockdag.BlockDAG,
txMempool *mempool.TxPool,
sigCache *txscript.SigCache,
acceptanceIndex *indexers.AcceptanceIndex,
connectionManager *connmanager.ConnectionManager,
addressManager *addressmanager.AddressManager,
protocolManager *protocol.Manager) (*rpc.Server, error) {
if !cfg.DisableRPC {
policy := mining.Policy{
BlockMaxMass: cfg.BlockMaxMass,
}
blockTemplateGenerator := mining.NewBlkTmplGenerator(&policy, txMempool, dag, sigCache)
rpcServer, err := rpc.NewRPCServer(cfg, dag, txMempool, acceptanceIndex, blockTemplateGenerator,
connectionManager, addressManager, protocolManager)
if app.cfg.ResetDatabase {
err := removeDatabase(app.cfg)
if err != nil {
return nil, err
log.Error(err)
return err
}
// Signal process shutdown when the RPC server requests it.
spawn("setupRPC-handleShutdownRequest", func() {
<-rpcServer.RequestedProcessShutdown()
signal.ShutdownRequestChannel <- struct{}{}
})
return rpcServer, nil
}
return nil, nil
// Open the database
databaseContext, err := openDB(app.cfg)
if err != nil {
log.Errorf("Loading database failed: %+v", err)
return err
}
defer func() {
log.Infof("Gracefully shutting down the database...")
err := databaseContext.Close()
if err != nil {
log.Errorf("Failed to close the database: %s", err)
}
}()
// Return now if an interrupt signal was triggered.
if signal.InterruptRequested(interrupt) {
return nil
}
// Create componentManager and start it.
componentManager, err := NewComponentManager(app.cfg, databaseContext, interrupt)
if err != nil {
log.Errorf("Unable to start kaspad: %+v", err)
return err
}
defer func() {
log.Infof("Gracefully shutting down kaspad...")
shutdownDone := make(chan struct{})
go func() {
componentManager.Stop()
shutdownDone <- struct{}{}
}()
const shutdownTimeout = 2 * time.Minute
select {
case <-shutdownDone:
case <-time.After(shutdownTimeout):
log.Criticalf("Graceful shutdown timed out %s. Terminating...", shutdownTimeout)
}
log.Infof("Kaspad shutdown complete")
}()
componentManager.Start()
if startedChan != nil {
startedChan <- struct{}{}
}
// Wait until the interrupt signal is received from an OS signal or
// shutdown is requested through one of the subsystems such as the RPC
// server.
<-interrupt
return nil
}
// P2PNodeID returns the network ID associated with this App
func (a *App) P2PNodeID() *id.ID {
return a.netAdapter.ID()
// dbPath returns the path to the block database given a database type.
func databasePath(cfg *config.Config) string {
return filepath.Join(cfg.AppDir, defaultDataDirname)
}
// AddressManager returns the AddressManager associated with this App
func (a *App) AddressManager() *addressmanager.AddressManager {
return a.addressManager
func removeDatabase(cfg *config.Config) error {
dbPath := databasePath(cfg)
return os.RemoveAll(dbPath)
}
func openDB(cfg *config.Config) (database.Database, error) {
dbPath := databasePath(cfg)
err := checkDatabaseVersion(dbPath)
if err != nil {
return nil, err
}
log.Infof("Loading database from '%s'", dbPath)
db, err := ldb.NewLevelDB(dbPath, leveldbCacheSizeMiB)
if err != nil {
return nil, err
}
return db, nil
}

View File

@@ -1,431 +0,0 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"bytes"
"compress/bzip2"
"io/ioutil"
"math"
"os"
"testing"
"github.com/kaspanet/kaspad/util/daghash"
)
// genesisCoinbaseTx is the coinbase transaction for the genesis blocks for
// the main network, regression test network, and test network.
var genesisCoinbaseTxIns = []*TxIn{
{
PreviousOutpoint: Outpoint{
TxID: daghash.TxID{},
Index: 0xffffffff,
},
SignatureScript: []byte{
0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x45, /* |.......E| */
0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, /* |The Time| */
0x73, 0x20, 0x30, 0x33, 0x2f, 0x4a, 0x61, 0x6e, /* |s 03/Jan| */
0x2f, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68, /* |/2009 Ch| */
0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x6f, 0x72, /* |ancellor| */
0x20, 0x6f, 0x6e, 0x20, 0x62, 0x72, 0x69, 0x6e, /* | on brin| */
0x6b, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, /* |k of sec|*/
0x6f, 0x6e, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6c, /* |ond bail| */
0x6f, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, /* |out for |*/
0x62, 0x61, 0x6e, 0x6b, 0x73, /* |banks| */
},
Sequence: math.MaxUint64,
},
}
var genesisCoinbaseTxOuts = []*TxOut{
{
Value: 0x12a05f200,
ScriptPubKey: []byte{
0x41, 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, /* |A.g....U| */
0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, /* |H'.g..q0| */
0xb7, 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, /* |..\..(.9| */
0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, /* |..yb...a| */
0xde, 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, /* |..I..?L.| */
0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, /* |8..U....| */
0x12, 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, /* |..\8M...| */
0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, /* |.W.Lp+k.| */
0x1d, 0x5f, 0xac, /* |._.| */
},
},
}
var genesisCoinbaseTx = NewNativeMsgTx(1, genesisCoinbaseTxIns, genesisCoinbaseTxOuts)
// BenchmarkWriteVarInt1 performs a benchmark on how long it takes to write
// a single byte variable length integer.
func BenchmarkWriteVarInt1(b *testing.B) {
for i := 0; i < b.N; i++ {
WriteVarInt(ioutil.Discard, 1)
}
}
// BenchmarkWriteVarInt3 performs a benchmark on how long it takes to write
// a three byte variable length integer.
func BenchmarkWriteVarInt3(b *testing.B) {
for i := 0; i < b.N; i++ {
WriteVarInt(ioutil.Discard, 65535)
}
}
// BenchmarkWriteVarInt5 performs a benchmark on how long it takes to write
// a five byte variable length integer.
func BenchmarkWriteVarInt5(b *testing.B) {
for i := 0; i < b.N; i++ {
WriteVarInt(ioutil.Discard, 4294967295)
}
}
// BenchmarkWriteVarInt9 performs a benchmark on how long it takes to write
// a nine byte variable length integer.
func BenchmarkWriteVarInt9(b *testing.B) {
for i := 0; i < b.N; i++ {
WriteVarInt(ioutil.Discard, 18446744073709551615)
}
}
// BenchmarkReadVarInt1 performs a benchmark on how long it takes to read
// a single byte variable length integer.
func BenchmarkReadVarInt1(b *testing.B) {
buf := []byte{0x01}
r := bytes.NewReader(buf)
for i := 0; i < b.N; i++ {
r.Seek(0, 0)
ReadVarInt(r)
}
}
// BenchmarkReadVarInt3 performs a benchmark on how long it takes to read
// a three byte variable length integer.
func BenchmarkReadVarInt3(b *testing.B) {
buf := []byte{0x0fd, 0xff, 0xff}
r := bytes.NewReader(buf)
for i := 0; i < b.N; i++ {
r.Seek(0, 0)
ReadVarInt(r)
}
}
// BenchmarkReadVarInt5 performs a benchmark on how long it takes to read
// a five byte variable length integer.
func BenchmarkReadVarInt5(b *testing.B) {
buf := []byte{0xfe, 0xff, 0xff, 0xff, 0xff}
r := bytes.NewReader(buf)
for i := 0; i < b.N; i++ {
r.Seek(0, 0)
ReadVarInt(r)
}
}
// BenchmarkReadVarInt9 performs a benchmark on how long it takes to read
// a nine byte variable length integer.
func BenchmarkReadVarInt9(b *testing.B) {
buf := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
r := bytes.NewReader(buf)
for i := 0; i < b.N; i++ {
r.Seek(0, 0)
ReadVarInt(r)
}
}
// BenchmarkReadVarStr4 performs a benchmark on how long it takes to read a
// four byte variable length string.
func BenchmarkReadVarStr4(b *testing.B) {
buf := []byte{0x04, 't', 'e', 's', 't'}
r := bytes.NewReader(buf)
for i := 0; i < b.N; i++ {
r.Seek(0, 0)
ReadVarString(r, 0)
}
}
// BenchmarkReadVarStr10 performs a benchmark on how long it takes to read a
// ten byte variable length string.
func BenchmarkReadVarStr10(b *testing.B) {
buf := []byte{0x0a, 't', 'e', 's', 't', '0', '1', '2', '3', '4', '5'}
r := bytes.NewReader(buf)
for i := 0; i < b.N; i++ {
r.Seek(0, 0)
ReadVarString(r, 0)
}
}
// BenchmarkWriteVarStr4 performs a benchmark on how long it takes to write a
// four byte variable length string.
func BenchmarkWriteVarStr4(b *testing.B) {
for i := 0; i < b.N; i++ {
WriteVarString(ioutil.Discard, "test")
}
}
// BenchmarkWriteVarStr10 performs a benchmark on how long it takes to write a
// ten byte variable length string.
func BenchmarkWriteVarStr10(b *testing.B) {
for i := 0; i < b.N; i++ {
WriteVarString(ioutil.Discard, "test012345")
}
}
// BenchmarkReadOutpoint performs a benchmark on how long it takes to read a
// transaction outpoint.
func BenchmarkReadOutpoint(b *testing.B) {
buf := []byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash
0xff, 0xff, 0xff, 0xff, // Previous output index
}
r := bytes.NewReader(buf)
var op Outpoint
for i := 0; i < b.N; i++ {
r.Seek(0, 0)
readOutpoint(r, 0, 0, &op)
}
}
// BenchmarkWriteOutpoint performs a benchmark on how long it takes to write a
// transaction outpoint.
func BenchmarkWriteOutpoint(b *testing.B) {
op := &Outpoint{
TxID: daghash.TxID{},
Index: 0,
}
for i := 0; i < b.N; i++ {
writeOutpoint(ioutil.Discard, 0, 0, op)
}
}
// BenchmarkReadTxOut performs a benchmark on how long it takes to read a
// transaction output.
func BenchmarkReadTxOut(b *testing.B) {
buf := []byte{
0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount
0x43, // Varint for length of scriptPubKey
0x41, // OP_DATA_65
0x04, 0x96, 0xb5, 0x38, 0xe8, 0x53, 0x51, 0x9c,
0x72, 0x6a, 0x2c, 0x91, 0xe6, 0x1e, 0xc1, 0x16,
0x00, 0xae, 0x13, 0x90, 0x81, 0x3a, 0x62, 0x7c,
0x66, 0xfb, 0x8b, 0xe7, 0x94, 0x7b, 0xe6, 0x3c,
0x52, 0xda, 0x75, 0x89, 0x37, 0x95, 0x15, 0xd4,
0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6,
0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e,
0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58,
0xee, // 65-byte signature
0xac, // OP_CHECKSIG
}
r := bytes.NewReader(buf)
var txOut TxOut
for i := 0; i < b.N; i++ {
r.Seek(0, 0)
readTxOut(r, 0, 0, &txOut)
scriptPool.Return(txOut.ScriptPubKey)
}
}
// BenchmarkWriteTxOut performs a benchmark on how long it takes to write
// a transaction output.
func BenchmarkWriteTxOut(b *testing.B) {
txOut := blockOne.Transactions[0].TxOut[0]
for i := 0; i < b.N; i++ {
WriteTxOut(ioutil.Discard, 0, 0, txOut)
}
}
// BenchmarkReadTxIn performs a benchmark on how long it takes to read a
// transaction input.
func BenchmarkReadTxIn(b *testing.B) {
buf := []byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash
0xff, 0xff, 0xff, 0xff, // Previous output index
0x07, // Varint for length of signature script
0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, // Signature script
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Sequence
}
r := bytes.NewReader(buf)
var txIn TxIn
for i := 0; i < b.N; i++ {
r.Seek(0, 0)
readTxIn(r, 0, 0, &txIn)
scriptPool.Return(txIn.SignatureScript)
}
}
// BenchmarkWriteTxIn performs a benchmark on how long it takes to write
// a transaction input.
func BenchmarkWriteTxIn(b *testing.B) {
txIn := blockOne.Transactions[0].TxIn[0]
for i := 0; i < b.N; i++ {
writeTxIn(ioutil.Discard, 0, 0, txIn, txEncodingFull)
}
}
// BenchmarkDeserializeTx performs a benchmark on how long it takes to
// deserialize a small transaction.
func BenchmarkDeserializeTxSmall(b *testing.B) {
buf := []byte{
0x01, 0x00, 0x00, 0x00, // Version
0x01, // Varint for number of input transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // // Previous output hash
0xff, 0xff, 0xff, 0xff, // Prevous output index
0x07, // Varint for length of signature script
0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, // Signature script
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Sequence
0x01, // Varint for number of output transactions
0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount
0x43, // Varint for length of scriptPubKey
0x41, // OP_DATA_65
0x04, 0x96, 0xb5, 0x38, 0xe8, 0x53, 0x51, 0x9c,
0x72, 0x6a, 0x2c, 0x91, 0xe6, 0x1e, 0xc1, 0x16,
0x00, 0xae, 0x13, 0x90, 0x81, 0x3a, 0x62, 0x7c,
0x66, 0xfb, 0x8b, 0xe7, 0x94, 0x7b, 0xe6, 0x3c,
0x52, 0xda, 0x75, 0x89, 0x37, 0x95, 0x15, 0xd4,
0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6,
0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e,
0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58,
0xee, // 65-byte signature
0xac, // OP_CHECKSIG
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
}
r := bytes.NewReader(buf)
var tx MsgTx
for i := 0; i < b.N; i++ {
r.Seek(0, 0)
tx.Deserialize(r)
}
}
// BenchmarkDeserializeTxLarge performs a benchmark on how long it takes to
// deserialize a very large transaction.
func BenchmarkDeserializeTxLarge(b *testing.B) {
fi, err := os.Open("testdata/megatx.bin.bz2")
if err != nil {
b.Fatalf("Failed to read transaction data: %v", err)
}
defer fi.Close()
buf, err := ioutil.ReadAll(bzip2.NewReader(fi))
if err != nil {
b.Fatalf("Failed to read transaction data: %v", err)
}
r := bytes.NewReader(buf)
var tx MsgTx
for i := 0; i < b.N; i++ {
r.Seek(0, 0)
tx.Deserialize(r)
}
}
// BenchmarkSerializeTx performs a benchmark on how long it takes to serialize
// a transaction.
func BenchmarkSerializeTx(b *testing.B) {
tx := blockOne.Transactions[0]
for i := 0; i < b.N; i++ {
tx.Serialize(ioutil.Discard)
}
}
// BenchmarkReadBlockHeader performs a benchmark on how long it takes to
// deserialize a block header.
func BenchmarkReadBlockHeader(b *testing.B) {
buf := []byte{
0x01, 0x00, 0x00, 0x00, // Version 1
0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2,
0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61,
0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32,
0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot
0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp
0xff, 0xff, 0x00, 0x1d, // Bits
0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce
0x00, // TxnCount Varint
}
r := bytes.NewReader(buf)
var header BlockHeader
for i := 0; i < b.N; i++ {
r.Seek(0, 0)
readBlockHeader(r, 0, &header)
}
}
// BenchmarkWriteBlockHeader performs a benchmark on how long it takes to
// serialize a block header.
func BenchmarkWriteBlockHeader(b *testing.B) {
header := blockOne.Header
for i := 0; i < b.N; i++ {
writeBlockHeader(ioutil.Discard, 0, &header)
}
}
// BenchmarkTxHash performs a benchmark on how long it takes to hash a
// transaction.
func BenchmarkTxHash(b *testing.B) {
for i := 0; i < b.N; i++ {
genesisCoinbaseTx.TxHash()
}
}
// BenchmarkDoubleHashB performs a benchmark on how long it takes to perform a
// double hash returning a byte slice.
func BenchmarkDoubleHashB(b *testing.B) {
var buf bytes.Buffer
if err := genesisCoinbaseTx.Serialize(&buf); err != nil {
b.Errorf("Serialize: unexpected error: %v", err)
return
}
txBytes := buf.Bytes()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = daghash.DoubleHashB(txBytes)
}
}
// BenchmarkDoubleHashH performs a benchmark on how long it takes to perform
// a double hash returning a daghash.Hash.
func BenchmarkDoubleHashH(b *testing.B) {
var buf bytes.Buffer
if err := genesisCoinbaseTx.Serialize(&buf); err != nil {
b.Errorf("Serialize: unexpected error: %v", err)
return
}
txBytes := buf.Bytes()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = daghash.DoubleHashH(txBytes)
}
}
// BenchmarkDoubleHashWriter performs a benchmark on how long it takes to perform
// a double hash via the writer returning a daghash.Hash.
func BenchmarkDoubleHashWriter(b *testing.B) {
var buf bytes.Buffer
err := genesisCoinbaseTx.Serialize(&buf)
if err != nil {
b.Fatalf("Serialize: unexpected error: %+v", err)
}
txBytes := buf.Bytes()
b.ResetTimer()
for i := 0; i < b.N; i++ {
writer := daghash.NewDoubleHashWriter()
_, _ = writer.Write(txBytes)
writer.Finalize()
}
}

View File

@@ -1,190 +0,0 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"fmt"
"io"
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/util/mstime"
)
// BaseBlockHeaderPayload is the base number of bytes a block header can be,
// not including the list of parent block headers.
// Version 4 bytes + Timestamp 8 bytes + Bits 4 bytes + Nonce 8 bytes +
// + NumParentBlocks 1 byte + HashMerkleRoot hash +
// + AcceptedIDMerkleRoot hash + UTXOCommitment hash.
// To get total size of block header len(ParentHashes) * daghash.HashSize should be
// added to this value
const BaseBlockHeaderPayload = 25 + 3*(daghash.HashSize)
// MaxNumParentBlocks is the maximum number of parent blocks a block can reference.
// Currently set to 255 as the maximum number NumParentBlocks can be due to it being a byte
const MaxNumParentBlocks = 255
// MaxBlockHeaderPayload is the maximum number of bytes a block header can be.
// BaseBlockHeaderPayload + up to MaxNumParentBlocks hashes of parent blocks
const MaxBlockHeaderPayload = BaseBlockHeaderPayload + (MaxNumParentBlocks * daghash.HashSize)
// BlockHeader defines information about a block and is used in the kaspa
// block (MsgBlock) and headers (MsgHeader) messages.
type BlockHeader struct {
// Version of the block. This is not the same as the protocol version.
Version int32
// Hashes of the parent block headers in the blockDAG.
ParentHashes []*daghash.Hash
// HashMerkleRoot is the merkle tree reference to hash of all transactions for the block.
HashMerkleRoot *daghash.Hash
// AcceptedIDMerkleRoot is merkle tree reference to hash all transactions
// accepted form the block.Blues
AcceptedIDMerkleRoot *daghash.Hash
// UTXOCommitment is an ECMH UTXO commitment to the block UTXO.
UTXOCommitment *daghash.Hash
// Time the block was created.
Timestamp mstime.Time
// Difficulty target for the block.
Bits uint32
// Nonce used to generate the block.
Nonce uint64
}
// NumParentBlocks return the number of entries in ParentHashes
func (h *BlockHeader) NumParentBlocks() byte {
return byte(len(h.ParentHashes))
}
// BlockHash computes the block identifier hash for the given block header.
func (h *BlockHeader) BlockHash() *daghash.Hash {
// Encode the header and double sha256 everything prior to the number of
// transactions.
writer := daghash.NewDoubleHashWriter()
err := writeBlockHeader(writer, 0, h)
if err != nil {
// It seems like this could only happen if the writer returned an error.
// and this writer should never return an error (no allocations or possible failures)
// the only non-writer error path here is unknown types in `WriteElement`
panic(fmt.Sprintf("BlockHash() failed. this should never fail unless BlockHeader was changed. err: %+v", err))
}
res := writer.Finalize()
return &res
}
// IsGenesis returns true iff this block is a genesis block
func (h *BlockHeader) IsGenesis() bool {
return h.NumParentBlocks() == 0
}
// KaspaDecode decodes r using the kaspa protocol encoding into the receiver.
// This is part of the Message interface implementation.
// See Deserialize for decoding block headers stored to disk, such as in a
// database, as opposed to decoding block headers from the appmessage.
func (h *BlockHeader) KaspaDecode(r io.Reader, pver uint32) error {
return readBlockHeader(r, pver, h)
}
// KaspaEncode encodes the receiver to w using the kaspa protocol encoding.
// This is part of the Message interface implementation.
// See Serialize for encoding block headers to be stored to disk, such as in a
// database, as opposed to encoding block headers for the appmessage.
func (h *BlockHeader) KaspaEncode(w io.Writer, pver uint32) error {
return writeBlockHeader(w, pver, h)
}
// Deserialize decodes a block header from r into the receiver using a format
// that is suitable for long-term storage such as a database while respecting
// the Version field.
func (h *BlockHeader) Deserialize(r io.Reader) error {
// At the current time, there is no difference between the appmessage encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of readBlockHeader.
return readBlockHeader(r, 0, h)
}
// Serialize encodes a block header from r into the receiver using a format
// that is suitable for long-term storage such as a database while respecting
// the Version field.
func (h *BlockHeader) Serialize(w io.Writer) error {
// At the current time, there is no difference between the appmessage encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of writeBlockHeader.
return writeBlockHeader(w, 0, h)
}
// SerializeSize returns the number of bytes it would take to serialize the
// block header.
func (h *BlockHeader) SerializeSize() int {
return BaseBlockHeaderPayload + int(h.NumParentBlocks())*daghash.HashSize
}
// NewBlockHeader returns a new BlockHeader using the provided version, previous
// block hash, hash merkle root, accepted ID merkle root, difficulty bits, and nonce used to generate the
// block with defaults or calclulated values for the remaining fields.
func NewBlockHeader(version int32, parentHashes []*daghash.Hash, hashMerkleRoot *daghash.Hash,
acceptedIDMerkleRoot *daghash.Hash, utxoCommitment *daghash.Hash, bits uint32, nonce uint64) *BlockHeader {
// Limit the timestamp to one millisecond precision since the protocol
// doesn't support better.
return &BlockHeader{
Version: version,
ParentHashes: parentHashes,
HashMerkleRoot: hashMerkleRoot,
AcceptedIDMerkleRoot: acceptedIDMerkleRoot,
UTXOCommitment: utxoCommitment,
Timestamp: mstime.Now(),
Bits: bits,
Nonce: nonce,
}
}
// readBlockHeader reads a kaspa block header from r. See Deserialize for
// decoding block headers stored to disk, such as in a database, as opposed to
// decoding from the appmessage.
func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error {
var numParentBlocks byte
err := readElements(r, &bh.Version, &numParentBlocks)
if err != nil {
return err
}
bh.ParentHashes = make([]*daghash.Hash, numParentBlocks)
for i := byte(0); i < numParentBlocks; i++ {
hash := &daghash.Hash{}
err := ReadElement(r, hash)
if err != nil {
return err
}
bh.ParentHashes[i] = hash
}
bh.HashMerkleRoot = &daghash.Hash{}
bh.AcceptedIDMerkleRoot = &daghash.Hash{}
bh.UTXOCommitment = &daghash.Hash{}
return readElements(r, bh.HashMerkleRoot, bh.AcceptedIDMerkleRoot, bh.UTXOCommitment,
(*int64Time)(&bh.Timestamp), &bh.Bits, &bh.Nonce)
}
// writeBlockHeader writes a kaspa block header to w. See Serialize for
// encoding block headers to be stored to disk, such as in a database, as
// opposed to encoding for the appmessage.
func writeBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error {
timestamp := bh.Timestamp.UnixMilliseconds()
if err := writeElements(w, bh.Version, bh.NumParentBlocks()); err != nil {
return err
}
for _, hash := range bh.ParentHashes {
if err := WriteElement(w, hash); err != nil {
return err
}
}
return writeElements(w, bh.HashMerkleRoot, bh.AcceptedIDMerkleRoot, bh.UTXOCommitment, timestamp, bh.Bits, bh.Nonce)
}

View File

@@ -1,345 +0,0 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"bytes"
"github.com/davecgh/go-spew/spew"
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/util/mstime"
"github.com/kaspanet/kaspad/util/random"
"reflect"
"testing"
)
// TestBlockHeader tests the BlockHeader API.
func TestBlockHeader(t *testing.T) {
nonce, err := random.Uint64()
if err != nil {
t.Errorf("random.Uint64: Error generating nonce: %v", err)
}
hashes := []*daghash.Hash{mainnetGenesisHash, simnetGenesisHash}
merkleHash := mainnetGenesisMerkleRoot
acceptedIDMerkleRoot := exampleAcceptedIDMerkleRoot
bits := uint32(0x1d00ffff)
bh := NewBlockHeader(1, hashes, merkleHash, acceptedIDMerkleRoot, exampleUTXOCommitment, bits, nonce)
// Ensure we get the same data back out.
if !reflect.DeepEqual(bh.ParentHashes, hashes) {
t.Errorf("NewBlockHeader: wrong prev hashes - got %v, want %v",
spew.Sprint(bh.ParentHashes), spew.Sprint(hashes))
}
if !bh.HashMerkleRoot.IsEqual(merkleHash) {
t.Errorf("NewBlockHeader: wrong merkle root - got %v, want %v",
spew.Sprint(bh.HashMerkleRoot), spew.Sprint(merkleHash))
}
if bh.Bits != bits {
t.Errorf("NewBlockHeader: wrong bits - got %v, want %v",
bh.Bits, bits)
}
if bh.Nonce != nonce {
t.Errorf("NewBlockHeader: wrong nonce - got %v, want %v",
bh.Nonce, nonce)
}
}
// TestBlockHeaderEncoding tests the BlockHeader appmessage encode and decode for various
// protocol versions.
func TestBlockHeaderEncoding(t *testing.T) {
nonce := uint64(123123) // 0x000000000001e0f3
pver := ProtocolVersion
// baseBlockHdr is used in the various tests as a baseline BlockHeader.
bits := uint32(0x1d00ffff)
baseBlockHdr := &BlockHeader{
Version: 1,
ParentHashes: []*daghash.Hash{mainnetGenesisHash, simnetGenesisHash},
HashMerkleRoot: mainnetGenesisMerkleRoot,
AcceptedIDMerkleRoot: exampleAcceptedIDMerkleRoot,
UTXOCommitment: exampleUTXOCommitment,
Timestamp: mstime.UnixMilliseconds(0x17315ed0f99),
Bits: bits,
Nonce: nonce,
}
// baseBlockHdrEncoded is the appmessage encoded bytes of baseBlockHdr.
baseBlockHdrEncoded := []byte{
0x01, 0x00, 0x00, 0x00, // Version 1
0x02, // NumParentBlocks
0xdc, 0x5f, 0x5b, 0x5b, 0x1d, 0xc2, 0xa7, 0x25, // mainnetGenesisHash
0x49, 0xd5, 0x1d, 0x4d, 0xee, 0xd7, 0xa4, 0x8b,
0xaf, 0xd3, 0x14, 0x4b, 0x56, 0x78, 0x98, 0xb1,
0x8c, 0xfd, 0x9f, 0x69, 0xdd, 0xcf, 0xbb, 0x63,
0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // simnetGenesisHash
0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0,
0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91,
0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68,
0x4a, 0x5e, 0x1e, 0x4b, 0xaa, 0xb8, 0x9f, 0x3a, // HashMerkleRoot
0x32, 0x51, 0x8a, 0x88, 0xc3, 0x1b, 0xc8, 0x7f,
0x61, 0x8f, 0x76, 0x67, 0x3e, 0x2c, 0xc7, 0x7a,
0xb2, 0x12, 0x7b, 0x7a, 0xfd, 0xed, 0xa3, 0x3b,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // AcceptedIDMerkleRoot
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x10, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // UTXOCommitment
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x99, 0x0f, 0xed, 0x15, 0x73, 0x01, 0x00, 0x00, // Timestamp
0xff, 0xff, 0x00, 0x1d, // Bits
0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce
}
tests := []struct {
in *BlockHeader // Data to encode
out *BlockHeader // Expected decoded data
buf []byte // Encoded data
pver uint32 // Protocol version for appmessage encoding
}{
// Latest protocol version.
{
baseBlockHdr,
baseBlockHdr,
baseBlockHdrEncoded,
ProtocolVersion,
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to appmessage format.
var buf bytes.Buffer
err := writeBlockHeader(&buf, test.pver, test.in)
if err != nil {
t.Errorf("writeBlockHeader #%d error %v", i, err)
continue
}
if !bytes.Equal(buf.Bytes(), test.buf) {
t.Errorf("writeBlockHeader #%d\n got: %s want: %s", i,
spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
continue
}
buf.Reset()
err = test.in.KaspaEncode(&buf, pver)
if err != nil {
t.Errorf("KaspaEncode #%d error %v", i, err)
continue
}
if !bytes.Equal(buf.Bytes(), test.buf) {
t.Errorf("KaspaEncode #%d\n got: %s want: %s", i,
spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
continue
}
// Decode the block header from appmessage format.
var bh BlockHeader
rbuf := bytes.NewReader(test.buf)
err = readBlockHeader(rbuf, test.pver, &bh)
if err != nil {
t.Errorf("readBlockHeader #%d error %v", i, err)
continue
}
if !reflect.DeepEqual(&bh, test.out) {
t.Errorf("readBlockHeader #%d\n got: %s want: %s", i,
spew.Sdump(&bh), spew.Sdump(test.out))
continue
}
rbuf = bytes.NewReader(test.buf)
err = bh.KaspaDecode(rbuf, pver)
if err != nil {
t.Errorf("KaspaDecode #%d error %v", i, err)
continue
}
if !reflect.DeepEqual(&bh, test.out) {
t.Errorf("KaspaDecode #%d\n got: %s want: %s", i,
spew.Sdump(&bh), spew.Sdump(test.out))
continue
}
}
}
// TestBlockHeaderSerialize tests BlockHeader serialize and deserialize.
func TestBlockHeaderSerialize(t *testing.T) {
nonce := uint64(123123) // 0x01e0f3
// baseBlockHdr is used in the various tests as a baseline BlockHeader.
bits := uint32(0x1d00ffff)
baseBlockHdr := &BlockHeader{
Version: 1,
ParentHashes: []*daghash.Hash{mainnetGenesisHash, simnetGenesisHash},
HashMerkleRoot: mainnetGenesisMerkleRoot,
AcceptedIDMerkleRoot: exampleAcceptedIDMerkleRoot,
UTXOCommitment: exampleUTXOCommitment,
Timestamp: mstime.UnixMilliseconds(0x17315ed0f99),
Bits: bits,
Nonce: nonce,
}
// baseBlockHdrEncoded is the appmessage encoded bytes of baseBlockHdr.
baseBlockHdrEncoded := []byte{
0x01, 0x00, 0x00, 0x00, // Version 1
0x02, // NumParentBlocks
0xdc, 0x5f, 0x5b, 0x5b, 0x1d, 0xc2, 0xa7, 0x25, // mainnetGenesisHash
0x49, 0xd5, 0x1d, 0x4d, 0xee, 0xd7, 0xa4, 0x8b,
0xaf, 0xd3, 0x14, 0x4b, 0x56, 0x78, 0x98, 0xb1,
0x8c, 0xfd, 0x9f, 0x69, 0xdd, 0xcf, 0xbb, 0x63,
0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // simnetGenesisHash
0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0,
0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91,
0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68,
0x4a, 0x5e, 0x1e, 0x4b, 0xaa, 0xb8, 0x9f, 0x3a, // HashMerkleRoot
0x32, 0x51, 0x8a, 0x88, 0xc3, 0x1b, 0xc8, 0x7f,
0x61, 0x8f, 0x76, 0x67, 0x3e, 0x2c, 0xc7, 0x7a,
0xb2, 0x12, 0x7b, 0x7a, 0xfd, 0xed, 0xa3, 0x3b,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // AcceptedIDMerkleRoot
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x10, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // UTXOCommitment
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x99, 0x0f, 0xed, 0x15, 0x73, 0x01, 0x00, 0x00, // Timestamp
0xff, 0xff, 0x00, 0x1d, // Bits
0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce
}
tests := []struct {
in *BlockHeader // Data to encode
out *BlockHeader // Expected decoded data
buf []byte // Serialized data
}{
{
baseBlockHdr,
baseBlockHdr,
baseBlockHdrEncoded,
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Serialize the block header.
var buf bytes.Buffer
err := test.in.Serialize(&buf)
if err != nil {
t.Errorf("Serialize #%d error %v", i, err)
continue
}
if !bytes.Equal(buf.Bytes(), test.buf) {
t.Errorf("Serialize #%d\n got: %s want: %s", i,
spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
continue
}
// Deserialize the block header.
var bh BlockHeader
rbuf := bytes.NewReader(test.buf)
err = bh.Deserialize(rbuf)
if err != nil {
t.Errorf("Deserialize #%d error %v", i, err)
continue
}
if !reflect.DeepEqual(&bh, test.out) {
t.Errorf("Deserialize #%d\n got: %s want: %s", i,
spew.Sdump(&bh), spew.Sdump(test.out))
continue
}
}
}
// TestBlockHeaderSerializeSize performs tests to ensure the serialize size for
// various block headers is accurate.
func TestBlockHeaderSerializeSize(t *testing.T) {
nonce := uint64(123123) // 0x1e0f3
bits := uint32(0x1d00ffff)
timestamp := mstime.UnixMilliseconds(0x495fab29000)
baseBlockHdr := &BlockHeader{
Version: 1,
ParentHashes: []*daghash.Hash{mainnetGenesisHash, simnetGenesisHash},
HashMerkleRoot: mainnetGenesisMerkleRoot,
AcceptedIDMerkleRoot: &daghash.ZeroHash,
UTXOCommitment: &daghash.ZeroHash,
Timestamp: timestamp,
Bits: bits,
Nonce: nonce,
}
genesisBlockHdr := &BlockHeader{
Version: 1,
ParentHashes: []*daghash.Hash{},
HashMerkleRoot: mainnetGenesisMerkleRoot,
AcceptedIDMerkleRoot: &daghash.ZeroHash,
UTXOCommitment: &daghash.ZeroHash,
Timestamp: timestamp,
Bits: bits,
Nonce: nonce,
}
tests := []struct {
in *BlockHeader // Block header to encode
size int // Expected serialized size
}{
// Block with no transactions.
{genesisBlockHdr, 121},
// First block in the mainnet block DAG.
{baseBlockHdr, 185},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
serializedSize := test.in.SerializeSize()
if serializedSize != test.size {
t.Errorf("BlockHeader.SerializeSize: #%d got: %d, want: "+
"%d", i, serializedSize, test.size)
continue
}
}
}
func TestIsGenesis(t *testing.T) {
nonce := uint64(123123) // 0x1e0f3
bits := uint32(0x1d00ffff)
timestamp := mstime.UnixMilliseconds(0x495fab29000)
baseBlockHdr := &BlockHeader{
Version: 1,
ParentHashes: []*daghash.Hash{mainnetGenesisHash, simnetGenesisHash},
HashMerkleRoot: mainnetGenesisMerkleRoot,
Timestamp: timestamp,
Bits: bits,
Nonce: nonce,
}
genesisBlockHdr := &BlockHeader{
Version: 1,
ParentHashes: []*daghash.Hash{},
HashMerkleRoot: mainnetGenesisMerkleRoot,
Timestamp: timestamp,
Bits: bits,
Nonce: nonce,
}
tests := []struct {
in *BlockHeader // Block header to encode
isGenesis bool // Expected result for call of .IsGenesis
}{
{genesisBlockHdr, true},
{baseBlockHdr, false},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
isGenesis := test.in.IsGenesis()
if isGenesis != test.isGenesis {
t.Errorf("BlockHeader.IsGenesis: #%d got: %t, want: %t",
i, isGenesis, test.isGenesis)
}
}
}

View File

@@ -5,34 +5,12 @@
package appmessage
import (
"encoding/binary"
"fmt"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/id"
"github.com/kaspanet/kaspad/util/binaryserializer"
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/util/mstime"
"github.com/kaspanet/kaspad/util/subnetworkid"
"github.com/pkg/errors"
"io"
"math"
)
// MaxVarIntPayload is the maximum payload size for a variable length integer.
const MaxVarIntPayload = 9
// MaxInvPerMsg is the maximum number of inventory vectors that can be in any type of kaspa inv message.
const MaxInvPerMsg = 1 << 17
var (
// littleEndian is a convenience variable since binary.LittleEndian is
// quite long.
littleEndian = binary.LittleEndian
// bigEndian is a convenience variable since binary.BigEndian is quite
// long.
bigEndian = binary.BigEndian
)
// errNonCanonicalVarInt is the common format string used for non-canonically
// encoded variable length integer errors.
var errNonCanonicalVarInt = "non-canonical varint %x - discriminant %x must " +
@@ -40,472 +18,3 @@ var errNonCanonicalVarInt = "non-canonical varint %x - discriminant %x must " +
// errNoEncodingForType signifies that there's no encoding for the given type.
var errNoEncodingForType = errors.New("there's no encoding for this type")
// int64Time represents a unix timestamp with milliseconds precision encoded with
// an int64. It is used as a way to signal the readElement function how to decode
// a timestamp into a Go mstime.Time since it is otherwise ambiguous.
type int64Time mstime.Time
// ReadElement reads the next sequence of bytes from r using little endian
// depending on the concrete type of element pointed to.
func ReadElement(r io.Reader, element interface{}) error {
// Attempt to read the element based on the concrete type via fast
// type assertions first.
switch e := element.(type) {
case *int32:
rv, err := binaryserializer.Uint32(r, littleEndian)
if err != nil {
return err
}
*e = int32(rv)
return nil
case *uint32:
rv, err := binaryserializer.Uint32(r, littleEndian)
if err != nil {
return err
}
*e = rv
return nil
case *int64:
rv, err := binaryserializer.Uint64(r, littleEndian)
if err != nil {
return err
}
*e = int64(rv)
return nil
case *uint64:
rv, err := binaryserializer.Uint64(r, littleEndian)
if err != nil {
return err
}
*e = rv
return nil
case *uint8:
rv, err := binaryserializer.Uint8(r)
if err != nil {
return err
}
*e = rv
return nil
case *bool:
rv, err := binaryserializer.Uint8(r)
if err != nil {
return err
}
if rv == 0x00 {
*e = false
} else {
*e = true
}
return nil
// Unix timestamp encoded as an int64.
case *int64Time:
rv, err := binaryserializer.Uint64(r, binary.LittleEndian)
if err != nil {
return err
}
*e = int64Time(mstime.UnixMilliseconds(int64(rv)))
return nil
// Message header checksum.
case *[4]byte:
_, err := io.ReadFull(r, e[:])
if err != nil {
return err
}
return nil
// Message header command.
case *MessageCommand:
rv, err := binaryserializer.Uint32(r, littleEndian)
if err != nil {
return err
}
*e = MessageCommand(rv)
return nil
// IP address.
case *[16]byte:
_, err := io.ReadFull(r, e[:])
if err != nil {
return err
}
return nil
case *daghash.Hash:
_, err := io.ReadFull(r, e[:])
if err != nil {
return err
}
return nil
case *id.ID:
return e.Deserialize(r)
case *subnetworkid.SubnetworkID:
_, err := io.ReadFull(r, e[:])
if err != nil {
return err
}
return nil
case *ServiceFlag:
rv, err := binaryserializer.Uint64(r, littleEndian)
if err != nil {
return err
}
*e = ServiceFlag(rv)
return nil
case *KaspaNet:
rv, err := binaryserializer.Uint32(r, littleEndian)
if err != nil {
return err
}
*e = KaspaNet(rv)
return nil
}
return errors.Wrapf(errNoEncodingForType, "couldn't find a way to read type %T", element)
}
// readElements reads multiple items from r. It is equivalent to multiple
// calls to readElement.
func readElements(r io.Reader, elements ...interface{}) error {
for _, element := range elements {
err := ReadElement(r, element)
if err != nil {
return err
}
}
return nil
}
// WriteElement writes the little endian representation of element to w.
func WriteElement(w io.Writer, element interface{}) error {
// Attempt to write the element based on the concrete type via fast
// type assertions first.
switch e := element.(type) {
case int32:
err := binaryserializer.PutUint32(w, littleEndian, uint32(e))
if err != nil {
return err
}
return nil
case uint32:
err := binaryserializer.PutUint32(w, littleEndian, e)
if err != nil {
return err
}
return nil
case int64:
err := binaryserializer.PutUint64(w, littleEndian, uint64(e))
if err != nil {
return err
}
return nil
case uint64:
err := binaryserializer.PutUint64(w, littleEndian, e)
if err != nil {
return err
}
return nil
case uint8:
err := binaryserializer.PutUint8(w, e)
if err != nil {
return err
}
return nil
case bool:
var err error
if e {
err = binaryserializer.PutUint8(w, 0x01)
} else {
err = binaryserializer.PutUint8(w, 0x00)
}
if err != nil {
return err
}
return nil
// Message header checksum.
case [4]byte:
_, err := w.Write(e[:])
if err != nil {
return err
}
return nil
// Message header command.
case MessageCommand:
err := binaryserializer.PutUint32(w, littleEndian, uint32(e))
if err != nil {
return err
}
return nil
// IP address.
case [16]byte:
_, err := w.Write(e[:])
if err != nil {
return err
}
return nil
case *daghash.Hash:
_, err := w.Write(e[:])
if err != nil {
return err
}
return nil
case *id.ID:
return e.Serialize(w)
case *subnetworkid.SubnetworkID:
_, err := w.Write(e[:])
if err != nil {
return err
}
return nil
case ServiceFlag:
err := binaryserializer.PutUint64(w, littleEndian, uint64(e))
if err != nil {
return err
}
return nil
case KaspaNet:
err := binaryserializer.PutUint32(w, littleEndian, uint32(e))
if err != nil {
return err
}
return nil
}
return errors.Wrapf(errNoEncodingForType, "couldn't find a way to write type %T", element)
}
// writeElements writes multiple items to w. It is equivalent to multiple
// calls to writeElement.
func writeElements(w io.Writer, elements ...interface{}) error {
for _, element := range elements {
err := WriteElement(w, element)
if err != nil {
return err
}
}
return nil
}
// ReadVarInt reads a variable length integer from r and returns it as a uint64.
func ReadVarInt(r io.Reader) (uint64, error) {
discriminant, err := binaryserializer.Uint8(r)
if err != nil {
return 0, err
}
var rv uint64
switch discriminant {
case 0xff:
sv, err := binaryserializer.Uint64(r, littleEndian)
if err != nil {
return 0, err
}
rv = sv
// The encoding is not canonical if the value could have been
// encoded using fewer bytes.
min := uint64(0x100000000)
if rv < min {
return 0, messageError("readVarInt", fmt.Sprintf(
errNonCanonicalVarInt, rv, discriminant, min))
}
case 0xfe:
sv, err := binaryserializer.Uint32(r, littleEndian)
if err != nil {
return 0, err
}
rv = uint64(sv)
// The encoding is not canonical if the value could have been
// encoded using fewer bytes.
min := uint64(0x10000)
if rv < min {
return 0, messageError("readVarInt", fmt.Sprintf(
errNonCanonicalVarInt, rv, discriminant, min))
}
case 0xfd:
sv, err := binaryserializer.Uint16(r, littleEndian)
if err != nil {
return 0, err
}
rv = uint64(sv)
// The encoding is not canonical if the value could have been
// encoded using fewer bytes.
min := uint64(0xfd)
if rv < min {
return 0, messageError("readVarInt", fmt.Sprintf(
errNonCanonicalVarInt, rv, discriminant, min))
}
default:
rv = uint64(discriminant)
}
return rv, nil
}
// WriteVarInt serializes val to w using a variable number of bytes depending
// on its value.
func WriteVarInt(w io.Writer, val uint64) error {
if val < 0xfd {
return binaryserializer.PutUint8(w, uint8(val))
}
if val <= math.MaxUint16 {
err := binaryserializer.PutUint8(w, 0xfd)
if err != nil {
return err
}
return binaryserializer.PutUint16(w, littleEndian, uint16(val))
}
if val <= math.MaxUint32 {
err := binaryserializer.PutUint8(w, 0xfe)
if err != nil {
return err
}
return binaryserializer.PutUint32(w, littleEndian, uint32(val))
}
err := binaryserializer.PutUint8(w, 0xff)
if err != nil {
return err
}
return binaryserializer.PutUint64(w, littleEndian, val)
}
// VarIntSerializeSize returns the number of bytes it would take to serialize
// val as a variable length integer.
func VarIntSerializeSize(val uint64) int {
// The value is small enough to be represented by itself, so it's
// just 1 byte.
if val < 0xfd {
return 1
}
// Discriminant 1 byte plus 2 bytes for the uint16.
if val <= math.MaxUint16 {
return 3
}
// Discriminant 1 byte plus 4 bytes for the uint32.
if val <= math.MaxUint32 {
return 5
}
// Discriminant 1 byte plus 8 bytes for the uint64.
return 9
}
// ReadVarString reads a variable length string from r and returns it as a Go
// string. A variable length string is encoded as a variable length integer
// containing the length of the string followed by the bytes that represent the
// string itself. An error is returned if the length is greater than the
// maximum block payload size since it helps protect against memory exhaustion
// attacks and forced panics through malformed messages.
func ReadVarString(r io.Reader, pver uint32) (string, error) {
count, err := ReadVarInt(r)
if err != nil {
return "", err
}
// Prevent variable length strings that are larger than the maximum
// message size. It would be possible to cause memory exhaustion and
// panics without a sane upper bound on this count.
if count > MaxMessagePayload {
str := fmt.Sprintf("variable length string is too long "+
"[count %d, max %d]", count, MaxMessagePayload)
return "", messageError("ReadVarString", str)
}
buf := make([]byte, count)
_, err = io.ReadFull(r, buf)
if err != nil {
return "", err
}
return string(buf), nil
}
// WriteVarString serializes str to w as a variable length integer containing
// the length of the string followed by the bytes that represent the string
// itself.
func WriteVarString(w io.Writer, str string) error {
err := WriteVarInt(w, uint64(len(str)))
if err != nil {
return err
}
_, err = w.Write([]byte(str))
return err
}
// ReadVarBytes reads a variable length byte array. A byte array is encoded
// as a varInt containing the length of the array followed by the bytes
// themselves. An error is returned if the length is greater than the
// passed maxAllowed parameter which helps protect against memory exhaustion
// attacks and forced panics through malformed messages. The fieldName
// parameter is only used for the error message so it provides more context in
// the error.
func ReadVarBytes(r io.Reader, pver uint32, maxAllowed uint32,
fieldName string) ([]byte, error) {
count, err := ReadVarInt(r)
if err != nil {
return nil, err
}
// Prevent byte array larger than the max message size. It would
// be possible to cause memory exhaustion and panics without a sane
// upper bound on this count.
if count > uint64(maxAllowed) {
str := fmt.Sprintf("%s is larger than the max allowed size "+
"[count %d, max %d]", fieldName, count, maxAllowed)
return nil, messageError("ReadVarBytes", str)
}
b := make([]byte, count)
_, err = io.ReadFull(r, b)
if err != nil {
return nil, err
}
return b, nil
}
// WriteVarBytes serializes a variable length byte array to w as a varInt
// containing the number of bytes, followed by the bytes themselves.
func WriteVarBytes(w io.Writer, pver uint32, bytes []byte) error {
slen := uint64(len(bytes))
err := WriteVarInt(w, slen)
if err != nil {
return err
}
_, err = w.Write(bytes)
return err
}

View File

@@ -1,695 +1,44 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"bytes"
"github.com/pkg/errors"
"io"
"reflect"
"strings"
"testing"
"github.com/davecgh/go-spew/spew"
"github.com/kaspanet/kaspad/util/daghash"
)
import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
// mainnetGenesisHash is the hash of the first block in the block DAG for the
// main network (genesis block).
var mainnetGenesisHash = &daghash.Hash{
var mainnetGenesisHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0xdc, 0x5f, 0x5b, 0x5b, 0x1d, 0xc2, 0xa7, 0x25,
0x49, 0xd5, 0x1d, 0x4d, 0xee, 0xd7, 0xa4, 0x8b,
0xaf, 0xd3, 0x14, 0x4b, 0x56, 0x78, 0x98, 0xb1,
0x8c, 0xfd, 0x9f, 0x69, 0xdd, 0xcf, 0xbb, 0x63,
}
})
// simnetGenesisHash is the hash of the first block in the block DAG for the
// simulation test network.
var simnetGenesisHash = &daghash.Hash{
0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a,
0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0,
0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91,
0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68,
}
var simnetGenesisHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x9d, 0x89, 0xb0, 0x6e, 0xb3, 0x47, 0xb5, 0x6e,
0xcd, 0x6c, 0x63, 0x99, 0x45, 0x91, 0xd5, 0xce,
0x9b, 0x43, 0x05, 0xc1, 0xa5, 0x5e, 0x2a, 0xda,
0x90, 0x4c, 0xf0, 0x6c, 0x4d, 0x5f, 0xd3, 0x62,
})
// mainnetGenesisMerkleRoot is the hash of the first transaction in the genesis
// block for the main network.
var mainnetGenesisMerkleRoot = &daghash.Hash{
var mainnetGenesisMerkleRoot = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x4a, 0x5e, 0x1e, 0x4b, 0xaa, 0xb8, 0x9f, 0x3a,
0x32, 0x51, 0x8a, 0x88, 0xc3, 0x1b, 0xc8, 0x7f,
0x61, 0x8f, 0x76, 0x67, 0x3e, 0x2c, 0xc7, 0x7a,
0xb2, 0x12, 0x7b, 0x7a, 0xfd, 0xed, 0xa3, 0x3b,
}
})
var exampleAcceptedIDMerkleRoot = &daghash.Hash{
var exampleAcceptedIDMerkleRoot = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C,
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
}
})
var exampleUTXOCommitment = &daghash.Hash{
var exampleUTXOCommitment = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x10, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C,
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
}
// TestElementEncoding tests appmessage encode and decode for various element types. This
// is mainly to test the "fast" paths in readElement and writeElement which use
// type assertions to avoid reflection when possible.
func TestElementEncoding(t *testing.T) {
tests := []struct {
in interface{} // Value to encode
buf []byte // Encoded value
}{
{int32(1), []byte{0x01, 0x00, 0x00, 0x00}},
{uint32(256), []byte{0x00, 0x01, 0x00, 0x00}},
{
int64(65536),
[]byte{0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00},
},
{
uint64(4294967296),
[]byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00},
},
{
true,
[]byte{0x01},
},
{
false,
[]byte{0x00},
},
{
[4]byte{0x01, 0x02, 0x03, 0x04},
[]byte{0x01, 0x02, 0x03, 0x04},
},
{
MessageCommand(0x10),
[]byte{
0x10, 0x00, 0x00, 0x00,
},
},
{
[16]byte{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
},
[]byte{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
},
},
{
(*daghash.Hash)(&[daghash.HashSize]byte{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
}),
[]byte{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
},
},
{
ServiceFlag(SFNodeNetwork),
[]byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
},
{
KaspaNet(Mainnet),
[]byte{0x1d, 0xf7, 0xdc, 0x3d},
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Write to appmessage format.
var buf bytes.Buffer
err := WriteElement(&buf, test.in)
if err != nil {
t.Errorf("writeElement #%d error %v", i, err)
continue
}
if !bytes.Equal(buf.Bytes(), test.buf) {
t.Errorf("writeElement #%d\n got: %s want: %s", i,
spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
continue
}
// Read from appmessage format.
rbuf := bytes.NewReader(test.buf)
val := test.in
if reflect.ValueOf(test.in).Kind() != reflect.Ptr {
val = reflect.New(reflect.TypeOf(test.in)).Interface()
}
err = ReadElement(rbuf, val)
if err != nil {
t.Errorf("readElement #%d error %v", i, err)
continue
}
ival := val
if reflect.ValueOf(test.in).Kind() != reflect.Ptr {
ival = reflect.Indirect(reflect.ValueOf(val)).Interface()
}
if !reflect.DeepEqual(ival, test.in) {
t.Errorf("readElement #%d\n got: %s want: %s", i,
spew.Sdump(ival), spew.Sdump(test.in))
continue
}
}
}
// TestElementEncodingErrors performs negative tests against appmessage encode and decode
// of various element types to confirm error paths work correctly.
func TestElementEncodingErrors(t *testing.T) {
type writeElementReflect int32
tests := []struct {
in interface{} // Value to encode
max int // Max size of fixed buffer to induce errors
writeErr error // Expected write error
readErr error // Expected read error
}{
{int32(1), 0, io.ErrShortWrite, io.EOF},
{uint32(256), 0, io.ErrShortWrite, io.EOF},
{int64(65536), 0, io.ErrShortWrite, io.EOF},
{true, 0, io.ErrShortWrite, io.EOF},
{[4]byte{0x01, 0x02, 0x03, 0x04}, 0, io.ErrShortWrite, io.EOF},
{
MessageCommand(10),
0, io.ErrShortWrite, io.EOF,
},
{
[16]byte{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
},
0, io.ErrShortWrite, io.EOF,
},
{
(*daghash.Hash)(&[daghash.HashSize]byte{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
}),
0, io.ErrShortWrite, io.EOF,
},
{ServiceFlag(SFNodeNetwork), 0, io.ErrShortWrite, io.EOF},
{KaspaNet(Mainnet), 0, io.ErrShortWrite, io.EOF},
// Type with no supported encoding.
{writeElementReflect(0), 0, errNoEncodingForType, errNoEncodingForType},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to appmessage format.
w := newFixedWriter(test.max)
err := WriteElement(w, test.in)
if !errors.Is(err, test.writeErr) {
t.Errorf("writeElement #%d wrong error got: %v, want: %v",
i, err, test.writeErr)
continue
}
// Decode from appmessage format.
r := newFixedReader(test.max, nil)
val := test.in
if reflect.ValueOf(test.in).Kind() != reflect.Ptr {
val = reflect.New(reflect.TypeOf(test.in)).Interface()
}
err = ReadElement(r, val)
if !errors.Is(err, test.readErr) {
t.Errorf("readElement #%d wrong error got: %v, want: %v",
i, err, test.readErr)
continue
}
}
}
// TestVarIntEncoding tests appmessage encode and decode for variable length integers.
func TestVarIntEncoding(t *testing.T) {
tests := []struct {
value uint64 // Value to encode
buf []byte // Encoded value
}{
// Latest protocol version.
// Single byte
{0, []byte{0x00}},
// Max single byte
{0xfc, []byte{0xfc}},
// Min 2-byte
{0xfd, []byte{0xfd, 0x0fd, 0x00}},
// Max 2-byte
{0xffff, []byte{0xfd, 0xff, 0xff}},
// Min 4-byte
{0x10000, []byte{0xfe, 0x00, 0x00, 0x01, 0x00}},
// Max 4-byte
{0xffffffff, []byte{0xfe, 0xff, 0xff, 0xff, 0xff}},
// Min 8-byte
{
0x100000000,
[]byte{0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00},
},
// Max 8-byte
{
0xffffffffffffffff,
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to appmessage format.
buf := &bytes.Buffer{}
err := WriteVarInt(buf, test.value)
if err != nil {
t.Errorf("WriteVarInt #%d error %v", i, err)
continue
}
if !bytes.Equal(buf.Bytes(), test.buf) {
t.Errorf("WriteVarInt #%d\n got: %s want: %s", i,
spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
continue
}
// Decode from appmessage format.
rbuf := bytes.NewReader(test.buf)
val, err := ReadVarInt(rbuf)
if err != nil {
t.Errorf("ReadVarInt #%d error %v", i, err)
continue
}
if val != test.value {
t.Errorf("ReadVarInt #%d\n got: %x want: %x", i,
val, test.value)
continue
}
}
}
// TestVarIntEncodingErrors performs negative tests against appmessage encode and decode
// of variable length integers to confirm error paths work correctly.
func TestVarIntEncodingErrors(t *testing.T) {
tests := []struct {
in uint64 // Value to encode
buf []byte // Encoded value
max int // Max size of fixed buffer to induce errors
writeErr error // Expected write error
readErr error // Expected read error
}{
// Force errors on discriminant.
{0, []byte{0x00}, 0, io.ErrShortWrite, io.EOF},
// Force errors on 2-byte read/write.
{0xfd, []byte{0xfd}, 0, io.ErrShortWrite, io.EOF}, // error on writing length
{0xfd, []byte{0xfd}, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // error on writing actual data
// Force errors on 4-byte read/write.
{0x10000, []byte{0xfe}, 0, io.ErrShortWrite, io.EOF}, // error on writing length
{0x10000, []byte{0xfe}, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // error on writing actual data
// Force errors on 8-byte read/write.
{0x100000000, []byte{0xff}, 0, io.ErrShortWrite, io.EOF}, // error on writing length
{0x100000000, []byte{0xff}, 2, io.ErrShortWrite, io.ErrUnexpectedEOF}, // error on writing actual data
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to appmessage format.
w := newFixedWriter(test.max)
err := WriteVarInt(w, test.in)
if !errors.Is(err, test.writeErr) {
t.Errorf("WriteVarInt #%d wrong error got: %v, want: %v",
i, err, test.writeErr)
continue
}
// Decode from appmessage format.
r := newFixedReader(test.max, test.buf)
_, err = ReadVarInt(r)
if !errors.Is(err, test.readErr) {
t.Errorf("ReadVarInt #%d wrong error got: %v, want: %v",
i, err, test.readErr)
continue
}
}
}
// TestVarIntNonCanonical ensures variable length integers that are not encoded
// canonically return the expected error.
func TestVarIntNonCanonical(t *testing.T) {
pver := ProtocolVersion
tests := []struct {
name string // Test name for easier identification
in []byte // Value to decode
pver uint32 // Protocol version for appmessage encoding
}{
{
"0 encoded with 3 bytes", []byte{0xfd, 0x00, 0x00},
pver,
},
{
"max single-byte value encoded with 3 bytes",
[]byte{0xfd, 0xfc, 0x00}, pver,
},
{
"0 encoded with 5 bytes",
[]byte{0xfe, 0x00, 0x00, 0x00, 0x00}, pver,
},
{
"max three-byte value encoded with 5 bytes",
[]byte{0xfe, 0xff, 0xff, 0x00, 0x00}, pver,
},
{
"0 encoded with 9 bytes",
[]byte{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
pver,
},
{
"max five-byte value encoded with 9 bytes",
[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00},
pver,
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Decode from appmessage format.
rbuf := bytes.NewReader(test.in)
val, err := ReadVarInt(rbuf)
if msgErr := &(MessageError{}); !errors.As(err, &msgErr) {
t.Errorf("ReadVarInt #%d (%s) unexpected error %v", i,
test.name, err)
continue
}
if val != 0 {
t.Errorf("ReadVarInt #%d (%s)\n got: %d want: 0", i,
test.name, val)
continue
}
}
}
// TestVarIntEncoding tests the serialize size for variable length integers.
func TestVarIntSerializeSize(t *testing.T) {
tests := []struct {
val uint64 // Value to get the serialized size for
size int // Expected serialized size
}{
// Single byte
{0, 1},
// Max single byte
{0xfc, 1},
// Min 2-byte
{0xfd, 3},
// Max 2-byte
{0xffff, 3},
// Min 4-byte
{0x10000, 5},
// Max 4-byte
{0xffffffff, 5},
// Min 8-byte
{0x100000000, 9},
// Max 8-byte
{0xffffffffffffffff, 9},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
serializedSize := VarIntSerializeSize(test.val)
if serializedSize != test.size {
t.Errorf("VarIntSerializeSize #%d got: %d, want: %d", i,
serializedSize, test.size)
continue
}
}
}
// TestVarStringEncoding tests appmessage encode and decode for variable length strings.
func TestVarStringEncoding(t *testing.T) {
pver := ProtocolVersion
// str256 is a string that takes a 2-byte varint to encode.
str256 := strings.Repeat("test", 64)
tests := []struct {
in string // String to encode
out string // String to decoded value
buf []byte // Encoded value
pver uint32 // Protocol version for appmessage encoding
}{
// Latest protocol version.
// Empty string
{"", "", []byte{0x00}, pver},
// Single byte varint + string
{"Test", "Test", append([]byte{0x04}, []byte("Test")...), pver},
// 2-byte varint + string
{str256, str256, append([]byte{0xfd, 0x00, 0x01}, []byte(str256)...), pver},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to appmessage format.
var buf bytes.Buffer
err := WriteVarString(&buf, test.in)
if err != nil {
t.Errorf("WriteVarString #%d error %v", i, err)
continue
}
if !bytes.Equal(buf.Bytes(), test.buf) {
t.Errorf("WriteVarString #%d\n got: %s want: %s", i,
spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
continue
}
// Decode from appmessage format.
rbuf := bytes.NewReader(test.buf)
val, err := ReadVarString(rbuf, test.pver)
if err != nil {
t.Errorf("ReadVarString #%d error %v", i, err)
continue
}
if val != test.out {
t.Errorf("ReadVarString #%d\n got: %s want: %s", i,
val, test.out)
continue
}
}
}
// TestVarStringEncodingErrors performs negative tests against appmessage encode and
// decode of variable length strings to confirm error paths work correctly.
func TestVarStringEncodingErrors(t *testing.T) {
pver := ProtocolVersion
// str256 is a string that takes a 2-byte varint to encode.
str256 := strings.Repeat("test", 64)
tests := []struct {
in string // Value to encode
buf []byte // Encoded value
pver uint32 // Protocol version for appmessage encoding
max int // Max size of fixed buffer to induce errors
writeErr error // Expected write error
readErr error // Expected read error
}{
// Latest protocol version with intentional read/write errors.
// Force errors on empty string.
{"", []byte{0x00}, pver, 0, io.ErrShortWrite, io.EOF},
// Force error on single byte varint + string.
{"Test", []byte{0x04}, pver, 2, io.ErrShortWrite, io.ErrUnexpectedEOF},
// Force errors on 2-byte varint + string.
{str256, []byte{0xfd}, pver, 2, io.ErrShortWrite, io.ErrUnexpectedEOF},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to appmessage format.
w := newFixedWriter(test.max)
err := WriteVarString(w, test.in)
if !errors.Is(err, test.writeErr) {
t.Errorf("WriteVarString #%d wrong error got: %v, want: %v",
i, err, test.writeErr)
continue
}
// Decode from appmessage format.
r := newFixedReader(test.max, test.buf)
_, err = ReadVarString(r, test.pver)
if !errors.Is(err, test.readErr) {
t.Errorf("ReadVarString #%d wrong error got: %v, want: %v",
i, err, test.readErr)
continue
}
}
}
// TestVarStringOverflowErrors performs tests to ensure deserializing variable
// length strings intentionally crafted to use large values for the string
// length are handled properly. This could otherwise potentially be used as an
// attack vector.
func TestVarStringOverflowErrors(t *testing.T) {
pver := ProtocolVersion
tests := []struct {
buf []byte // Encoded value
pver uint32 // Protocol version for appmessage encoding
err error // Expected error
}{
{[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
pver, &MessageError{}},
{[]byte{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
pver, &MessageError{}},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Decode from appmessage format.
rbuf := bytes.NewReader(test.buf)
_, err := ReadVarString(rbuf, test.pver)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
t.Errorf("ReadVarString #%d wrong error got: %v, "+
"want: %v", i, err, reflect.TypeOf(test.err))
continue
}
}
}
// TestVarBytesEncoding tests appmessage encode and decode for variable length byte array.
func TestVarBytesEncoding(t *testing.T) {
pver := ProtocolVersion
// bytes256 is a byte array that takes a 2-byte varint to encode.
bytes256 := bytes.Repeat([]byte{0x01}, 256)
tests := []struct {
in []byte // Byte Array to write
buf []byte // Encoded value
pver uint32 // Protocol version for appmessage encoding
}{
// Latest protocol version.
// Empty byte array
{[]byte{}, []byte{0x00}, pver},
// Single byte varint + byte array
{[]byte{0x01}, []byte{0x01, 0x01}, pver},
// 2-byte varint + byte array
{bytes256, append([]byte{0xfd, 0x00, 0x01}, bytes256...), pver},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to appmessage format.
var buf bytes.Buffer
err := WriteVarBytes(&buf, test.pver, test.in)
if err != nil {
t.Errorf("WriteVarBytes #%d error %v", i, err)
continue
}
if !bytes.Equal(buf.Bytes(), test.buf) {
t.Errorf("WriteVarBytes #%d\n got: %s want: %s", i,
spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
continue
}
// Decode from appmessage format.
rbuf := bytes.NewReader(test.buf)
val, err := ReadVarBytes(rbuf, test.pver, MaxMessagePayload,
"test payload")
if err != nil {
t.Errorf("ReadVarBytes #%d error %v", i, err)
continue
}
if !bytes.Equal(buf.Bytes(), test.buf) {
t.Errorf("ReadVarBytes #%d\n got: %s want: %s", i,
val, test.buf)
continue
}
}
}
// TestVarBytesEncodingErrors performs negative tests against appmessage encode and
// decode of variable length byte arrays to confirm error paths work correctly.
func TestVarBytesEncodingErrors(t *testing.T) {
pver := ProtocolVersion
// bytes256 is a byte array that takes a 2-byte varint to encode.
bytes256 := bytes.Repeat([]byte{0x01}, 256)
tests := []struct {
in []byte // Byte Array to write
buf []byte // Encoded value
pver uint32 // Protocol version for appmessage encoding
max int // Max size of fixed buffer to induce errors
writeErr error // Expected write error
readErr error // Expected read error
}{
// Latest protocol version with intentional read/write errors.
// Force errors on empty byte array.
{[]byte{}, []byte{0x00}, pver, 0, io.ErrShortWrite, io.EOF},
// Force error on single byte varint + byte array.
{[]byte{0x01, 0x02, 0x03}, []byte{0x04}, pver, 2, io.ErrShortWrite, io.ErrUnexpectedEOF},
// Force errors on 2-byte varint + byte array.
{bytes256, []byte{0xfd}, pver, 2, io.ErrShortWrite, io.ErrUnexpectedEOF},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to appmessage format.
w := newFixedWriter(test.max)
err := WriteVarBytes(w, test.pver, test.in)
if !errors.Is(err, test.writeErr) {
t.Errorf("WriteVarBytes #%d wrong error got: %v, want: %v",
i, err, test.writeErr)
continue
}
// Decode from appmessage format.
r := newFixedReader(test.max, test.buf)
_, err = ReadVarBytes(r, test.pver, MaxMessagePayload,
"test payload")
if !errors.Is(err, test.readErr) {
t.Errorf("ReadVarBytes #%d wrong error got: %v, want: %v",
i, err, test.readErr)
continue
}
}
}
// TestVarBytesOverflowErrors performs tests to ensure deserializing variable
// length byte arrays intentionally crafted to use large values for the array
// length are handled properly. This could otherwise potentially be used as an
// attack vector.
func TestVarBytesOverflowErrors(t *testing.T) {
pver := ProtocolVersion
tests := []struct {
buf []byte // Encoded value
pver uint32 // Protocol version for appmessage encoding
err error // Expected error
}{
{[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
pver, &MessageError{}},
{[]byte{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
pver, &MessageError{}},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Decode from appmessage format.
rbuf := bytes.NewReader(test.buf)
_, err := ReadVarBytes(rbuf, test.pver, MaxMessagePayload,
"test payload")
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
t.Errorf("ReadVarBytes #%d wrong error got: %v, "+
"want: %v", i, err, reflect.TypeOf(test.err))
continue
}
}
}
})

View File

@@ -68,7 +68,6 @@ the following constants:
appmessage.Mainnet
appmessage.Testnet (Test network)
appmessage.Regtest (Regression test network)
appmessage.Simnet (Simulation test network)
appmessage.Devnet (Development network)

View File

@@ -0,0 +1,601 @@
package appmessage
import (
"encoding/hex"
"github.com/pkg/errors"
"math/big"
"github.com/kaspanet/kaspad/domain/consensus/utils/blockheader"
"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
"github.com/kaspanet/kaspad/domain/consensus/utils/utxo"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionid"
"github.com/kaspanet/kaspad/util/mstime"
)
// DomainBlockToMsgBlock converts an externalapi.DomainBlock to MsgBlock
func DomainBlockToMsgBlock(domainBlock *externalapi.DomainBlock) *MsgBlock {
msgTxs := make([]*MsgTx, 0, len(domainBlock.Transactions))
for _, domainTransaction := range domainBlock.Transactions {
msgTxs = append(msgTxs, DomainTransactionToMsgTx(domainTransaction))
}
return &MsgBlock{
Header: *DomainBlockHeaderToBlockHeader(domainBlock.Header),
Transactions: msgTxs,
}
}
// DomainBlockHeaderToBlockHeader converts an externalapi.BlockHeader to MsgBlockHeader
func DomainBlockHeaderToBlockHeader(domainBlockHeader externalapi.BlockHeader) *MsgBlockHeader {
return &MsgBlockHeader{
Version: domainBlockHeader.Version(),
Parents: domainBlockHeader.Parents(),
HashMerkleRoot: domainBlockHeader.HashMerkleRoot(),
AcceptedIDMerkleRoot: domainBlockHeader.AcceptedIDMerkleRoot(),
UTXOCommitment: domainBlockHeader.UTXOCommitment(),
Timestamp: mstime.UnixMilliseconds(domainBlockHeader.TimeInMilliseconds()),
Bits: domainBlockHeader.Bits(),
Nonce: domainBlockHeader.Nonce(),
BlueScore: domainBlockHeader.BlueScore(),
DAAScore: domainBlockHeader.DAAScore(),
BlueWork: domainBlockHeader.BlueWork(),
PruningPoint: domainBlockHeader.PruningPoint(),
}
}
// MsgBlockToDomainBlock converts a MsgBlock to externalapi.DomainBlock
func MsgBlockToDomainBlock(msgBlock *MsgBlock) *externalapi.DomainBlock {
transactions := make([]*externalapi.DomainTransaction, 0, len(msgBlock.Transactions))
for _, msgTx := range msgBlock.Transactions {
transactions = append(transactions, MsgTxToDomainTransaction(msgTx))
}
return &externalapi.DomainBlock{
Header: BlockHeaderToDomainBlockHeader(&msgBlock.Header),
Transactions: transactions,
}
}
// BlockHeaderToDomainBlockHeader converts a MsgBlockHeader to externalapi.BlockHeader
func BlockHeaderToDomainBlockHeader(blockHeader *MsgBlockHeader) externalapi.BlockHeader {
return blockheader.NewImmutableBlockHeader(
blockHeader.Version,
blockHeader.Parents,
blockHeader.HashMerkleRoot,
blockHeader.AcceptedIDMerkleRoot,
blockHeader.UTXOCommitment,
blockHeader.Timestamp.UnixMilliseconds(),
blockHeader.Bits,
blockHeader.Nonce,
blockHeader.DAAScore,
blockHeader.BlueScore,
blockHeader.BlueWork,
blockHeader.PruningPoint,
)
}
// DomainTransactionToMsgTx converts an externalapi.DomainTransaction into an MsgTx
func DomainTransactionToMsgTx(domainTransaction *externalapi.DomainTransaction) *MsgTx {
txIns := make([]*TxIn, 0, len(domainTransaction.Inputs))
for _, input := range domainTransaction.Inputs {
txIns = append(txIns, domainTransactionInputToTxIn(input))
}
txOuts := make([]*TxOut, 0, len(domainTransaction.Outputs))
for _, output := range domainTransaction.Outputs {
txOuts = append(txOuts, domainTransactionOutputToTxOut(output))
}
return &MsgTx{
Version: domainTransaction.Version,
TxIn: txIns,
TxOut: txOuts,
LockTime: domainTransaction.LockTime,
SubnetworkID: domainTransaction.SubnetworkID,
Gas: domainTransaction.Gas,
Payload: domainTransaction.Payload,
}
}
func domainTransactionOutputToTxOut(domainTransactionOutput *externalapi.DomainTransactionOutput) *TxOut {
return &TxOut{
Value: domainTransactionOutput.Value,
ScriptPubKey: domainTransactionOutput.ScriptPublicKey,
}
}
func domainTransactionInputToTxIn(domainTransactionInput *externalapi.DomainTransactionInput) *TxIn {
return &TxIn{
PreviousOutpoint: *domainOutpointToOutpoint(domainTransactionInput.PreviousOutpoint),
SignatureScript: domainTransactionInput.SignatureScript,
Sequence: domainTransactionInput.Sequence,
SigOpCount: domainTransactionInput.SigOpCount,
}
}
func domainOutpointToOutpoint(domainOutpoint externalapi.DomainOutpoint) *Outpoint {
return NewOutpoint(
&domainOutpoint.TransactionID,
domainOutpoint.Index)
}
// MsgTxToDomainTransaction converts an MsgTx into externalapi.DomainTransaction
func MsgTxToDomainTransaction(msgTx *MsgTx) *externalapi.DomainTransaction {
transactionInputs := make([]*externalapi.DomainTransactionInput, 0, len(msgTx.TxIn))
for _, txIn := range msgTx.TxIn {
transactionInputs = append(transactionInputs, txInToDomainTransactionInput(txIn))
}
transactionOutputs := make([]*externalapi.DomainTransactionOutput, 0, len(msgTx.TxOut))
for _, txOut := range msgTx.TxOut {
transactionOutputs = append(transactionOutputs, txOutToDomainTransactionOutput(txOut))
}
payload := make([]byte, 0)
if msgTx.Payload != nil {
payload = msgTx.Payload
}
return &externalapi.DomainTransaction{
Version: msgTx.Version,
Inputs: transactionInputs,
Outputs: transactionOutputs,
LockTime: msgTx.LockTime,
SubnetworkID: msgTx.SubnetworkID,
Gas: msgTx.Gas,
Payload: payload,
}
}
func txOutToDomainTransactionOutput(txOut *TxOut) *externalapi.DomainTransactionOutput {
return &externalapi.DomainTransactionOutput{
Value: txOut.Value,
ScriptPublicKey: txOut.ScriptPubKey,
}
}
func txInToDomainTransactionInput(txIn *TxIn) *externalapi.DomainTransactionInput {
return &externalapi.DomainTransactionInput{
PreviousOutpoint: *outpointToDomainOutpoint(&txIn.PreviousOutpoint), //TODO
SignatureScript: txIn.SignatureScript,
SigOpCount: txIn.SigOpCount,
Sequence: txIn.Sequence,
}
}
func outpointToDomainOutpoint(outpoint *Outpoint) *externalapi.DomainOutpoint {
return &externalapi.DomainOutpoint{
TransactionID: outpoint.TxID,
Index: outpoint.Index,
}
}
// RPCTransactionToDomainTransaction converts RPCTransactions to DomainTransactions
func RPCTransactionToDomainTransaction(rpcTransaction *RPCTransaction) (*externalapi.DomainTransaction, error) {
inputs := make([]*externalapi.DomainTransactionInput, len(rpcTransaction.Inputs))
for i, input := range rpcTransaction.Inputs {
previousOutpoint, err := RPCOutpointToDomainOutpoint(input.PreviousOutpoint)
if err != nil {
return nil, err
}
signatureScript, err := hex.DecodeString(input.SignatureScript)
if err != nil {
return nil, err
}
inputs[i] = &externalapi.DomainTransactionInput{
PreviousOutpoint: *previousOutpoint,
SignatureScript: signatureScript,
Sequence: input.Sequence,
SigOpCount: input.SigOpCount,
}
}
outputs := make([]*externalapi.DomainTransactionOutput, len(rpcTransaction.Outputs))
for i, output := range rpcTransaction.Outputs {
scriptPublicKey, err := hex.DecodeString(output.ScriptPublicKey.Script)
if err != nil {
return nil, err
}
outputs[i] = &externalapi.DomainTransactionOutput{
Value: output.Amount,
ScriptPublicKey: &externalapi.ScriptPublicKey{Script: scriptPublicKey, Version: output.ScriptPublicKey.Version},
}
}
subnetworkID, err := subnetworks.FromString(rpcTransaction.SubnetworkID)
if err != nil {
return nil, err
}
payload, err := hex.DecodeString(rpcTransaction.Payload)
if err != nil {
return nil, err
}
return &externalapi.DomainTransaction{
Version: rpcTransaction.Version,
Inputs: inputs,
Outputs: outputs,
LockTime: rpcTransaction.LockTime,
SubnetworkID: *subnetworkID,
Gas: rpcTransaction.LockTime,
Payload: payload,
}, nil
}
// RPCOutpointToDomainOutpoint converts RPCOutpoint to DomainOutpoint
func RPCOutpointToDomainOutpoint(outpoint *RPCOutpoint) (*externalapi.DomainOutpoint, error) {
transactionID, err := transactionid.FromString(outpoint.TransactionID)
if err != nil {
return nil, err
}
return &externalapi.DomainOutpoint{
TransactionID: *transactionID,
Index: outpoint.Index,
}, nil
}
// RPCUTXOEntryToUTXOEntry converts RPCUTXOEntry to UTXOEntry
func RPCUTXOEntryToUTXOEntry(entry *RPCUTXOEntry) (externalapi.UTXOEntry, error) {
script, err := hex.DecodeString(entry.ScriptPublicKey.Script)
if err != nil {
return nil, err
}
return utxo.NewUTXOEntry(
entry.Amount,
&externalapi.ScriptPublicKey{
Script: script,
Version: entry.ScriptPublicKey.Version,
},
entry.IsCoinbase,
entry.BlockDAAScore,
), nil
}
// DomainTransactionToRPCTransaction converts DomainTransactions to RPCTransactions
func DomainTransactionToRPCTransaction(transaction *externalapi.DomainTransaction) *RPCTransaction {
inputs := make([]*RPCTransactionInput, len(transaction.Inputs))
for i, input := range transaction.Inputs {
transactionID := input.PreviousOutpoint.TransactionID.String()
previousOutpoint := &RPCOutpoint{
TransactionID: transactionID,
Index: input.PreviousOutpoint.Index,
}
signatureScript := hex.EncodeToString(input.SignatureScript)
inputs[i] = &RPCTransactionInput{
PreviousOutpoint: previousOutpoint,
SignatureScript: signatureScript,
Sequence: input.Sequence,
SigOpCount: input.SigOpCount,
}
}
outputs := make([]*RPCTransactionOutput, len(transaction.Outputs))
for i, output := range transaction.Outputs {
scriptPublicKey := hex.EncodeToString(output.ScriptPublicKey.Script)
outputs[i] = &RPCTransactionOutput{
Amount: output.Value,
ScriptPublicKey: &RPCScriptPublicKey{Script: scriptPublicKey, Version: output.ScriptPublicKey.Version},
}
}
subnetworkID := transaction.SubnetworkID.String()
payload := hex.EncodeToString(transaction.Payload)
return &RPCTransaction{
Version: transaction.Version,
Inputs: inputs,
Outputs: outputs,
LockTime: transaction.LockTime,
SubnetworkID: subnetworkID,
Gas: transaction.LockTime,
Payload: payload,
}
}
// OutpointAndUTXOEntryPairsToDomainOutpointAndUTXOEntryPairs converts
// OutpointAndUTXOEntryPairs to domain OutpointAndUTXOEntryPairs
func OutpointAndUTXOEntryPairsToDomainOutpointAndUTXOEntryPairs(
outpointAndUTXOEntryPairs []*OutpointAndUTXOEntryPair) []*externalapi.OutpointAndUTXOEntryPair {
domainOutpointAndUTXOEntryPairs := make([]*externalapi.OutpointAndUTXOEntryPair, len(outpointAndUTXOEntryPairs))
for i, outpointAndUTXOEntryPair := range outpointAndUTXOEntryPairs {
domainOutpointAndUTXOEntryPairs[i] = outpointAndUTXOEntryPairToDomainOutpointAndUTXOEntryPair(outpointAndUTXOEntryPair)
}
return domainOutpointAndUTXOEntryPairs
}
func outpointAndUTXOEntryPairToDomainOutpointAndUTXOEntryPair(
outpointAndUTXOEntryPair *OutpointAndUTXOEntryPair) *externalapi.OutpointAndUTXOEntryPair {
return &externalapi.OutpointAndUTXOEntryPair{
Outpoint: &externalapi.DomainOutpoint{
TransactionID: outpointAndUTXOEntryPair.Outpoint.TxID,
Index: outpointAndUTXOEntryPair.Outpoint.Index,
},
UTXOEntry: utxo.NewUTXOEntry(
outpointAndUTXOEntryPair.UTXOEntry.Amount,
outpointAndUTXOEntryPair.UTXOEntry.ScriptPublicKey,
outpointAndUTXOEntryPair.UTXOEntry.IsCoinbase,
outpointAndUTXOEntryPair.UTXOEntry.BlockDAAScore,
),
}
}
// DomainOutpointAndUTXOEntryPairsToOutpointAndUTXOEntryPairs converts
// domain OutpointAndUTXOEntryPairs to OutpointAndUTXOEntryPairs
func DomainOutpointAndUTXOEntryPairsToOutpointAndUTXOEntryPairs(
outpointAndUTXOEntryPairs []*externalapi.OutpointAndUTXOEntryPair) []*OutpointAndUTXOEntryPair {
domainOutpointAndUTXOEntryPairs := make([]*OutpointAndUTXOEntryPair, len(outpointAndUTXOEntryPairs))
for i, outpointAndUTXOEntryPair := range outpointAndUTXOEntryPairs {
domainOutpointAndUTXOEntryPairs[i] = &OutpointAndUTXOEntryPair{
Outpoint: &Outpoint{
TxID: outpointAndUTXOEntryPair.Outpoint.TransactionID,
Index: outpointAndUTXOEntryPair.Outpoint.Index,
},
UTXOEntry: &UTXOEntry{
Amount: outpointAndUTXOEntryPair.UTXOEntry.Amount(),
ScriptPublicKey: outpointAndUTXOEntryPair.UTXOEntry.ScriptPublicKey(),
IsCoinbase: outpointAndUTXOEntryPair.UTXOEntry.IsCoinbase(),
BlockDAAScore: outpointAndUTXOEntryPair.UTXOEntry.BlockDAAScore(),
},
}
}
return domainOutpointAndUTXOEntryPairs
}
// DomainBlockToRPCBlock converts DomainBlocks to RPCBlocks
func DomainBlockToRPCBlock(block *externalapi.DomainBlock) *RPCBlock {
parents := make([]*RPCBlockLevelParents, len(block.Header.Parents()))
for i, blockLevelParents := range block.Header.Parents() {
parents[i] = &RPCBlockLevelParents{
ParentHashes: hashes.ToStrings(blockLevelParents),
}
}
header := &RPCBlockHeader{
Version: uint32(block.Header.Version()),
Parents: parents,
HashMerkleRoot: block.Header.HashMerkleRoot().String(),
AcceptedIDMerkleRoot: block.Header.AcceptedIDMerkleRoot().String(),
UTXOCommitment: block.Header.UTXOCommitment().String(),
Timestamp: block.Header.TimeInMilliseconds(),
Bits: block.Header.Bits(),
Nonce: block.Header.Nonce(),
DAAScore: block.Header.DAAScore(),
BlueScore: block.Header.BlueScore(),
BlueWork: block.Header.BlueWork().Text(16),
PruningPoint: block.Header.PruningPoint().String(),
}
transactions := make([]*RPCTransaction, len(block.Transactions))
for i, transaction := range block.Transactions {
transactions[i] = DomainTransactionToRPCTransaction(transaction)
}
return &RPCBlock{
Header: header,
Transactions: transactions,
}
}
// RPCBlockToDomainBlock converts `block` into a DomainBlock
func RPCBlockToDomainBlock(block *RPCBlock) (*externalapi.DomainBlock, error) {
parents := make([]externalapi.BlockLevelParents, len(block.Header.Parents))
for i, blockLevelParents := range block.Header.Parents {
parents[i] = make(externalapi.BlockLevelParents, len(blockLevelParents.ParentHashes))
for j, parentHash := range blockLevelParents.ParentHashes {
var err error
parents[i][j], err = externalapi.NewDomainHashFromString(parentHash)
if err != nil {
return nil, err
}
}
}
hashMerkleRoot, err := externalapi.NewDomainHashFromString(block.Header.HashMerkleRoot)
if err != nil {
return nil, err
}
acceptedIDMerkleRoot, err := externalapi.NewDomainHashFromString(block.Header.AcceptedIDMerkleRoot)
if err != nil {
return nil, err
}
utxoCommitment, err := externalapi.NewDomainHashFromString(block.Header.UTXOCommitment)
if err != nil {
return nil, err
}
blueWork, success := new(big.Int).SetString(block.Header.BlueWork, 16)
if !success {
return nil, errors.Errorf("failed to parse blue work: %s", block.Header.BlueWork)
}
pruningPoint, err := externalapi.NewDomainHashFromString(block.Header.PruningPoint)
if err != nil {
return nil, err
}
header := blockheader.NewImmutableBlockHeader(
uint16(block.Header.Version),
parents,
hashMerkleRoot,
acceptedIDMerkleRoot,
utxoCommitment,
block.Header.Timestamp,
block.Header.Bits,
block.Header.Nonce,
block.Header.DAAScore,
block.Header.BlueScore,
blueWork,
pruningPoint)
transactions := make([]*externalapi.DomainTransaction, len(block.Transactions))
for i, transaction := range block.Transactions {
domainTransaction, err := RPCTransactionToDomainTransaction(transaction)
if err != nil {
return nil, err
}
transactions[i] = domainTransaction
}
return &externalapi.DomainBlock{
Header: header,
Transactions: transactions,
}, nil
}
// BlockWithTrustedDataToDomainBlockWithTrustedData converts *MsgBlockWithTrustedData to *externalapi.BlockWithTrustedData
func BlockWithTrustedDataToDomainBlockWithTrustedData(block *MsgBlockWithTrustedData) *externalapi.BlockWithTrustedData {
daaWindow := make([]*externalapi.TrustedDataDataDAAHeader, len(block.DAAWindow))
for i, daaBlock := range block.DAAWindow {
daaWindow[i] = &externalapi.TrustedDataDataDAAHeader{
Header: BlockHeaderToDomainBlockHeader(&daaBlock.Block.Header),
GHOSTDAGData: ghostdagDataToDomainGHOSTDAGData(daaBlock.GHOSTDAGData),
}
}
ghostdagData := make([]*externalapi.BlockGHOSTDAGDataHashPair, len(block.GHOSTDAGData))
for i, datum := range block.GHOSTDAGData {
ghostdagData[i] = &externalapi.BlockGHOSTDAGDataHashPair{
Hash: datum.Hash,
GHOSTDAGData: ghostdagDataToDomainGHOSTDAGData(datum.GHOSTDAGData),
}
}
return &externalapi.BlockWithTrustedData{
Block: MsgBlockToDomainBlock(block.Block),
DAAWindow: daaWindow,
GHOSTDAGData: ghostdagData,
}
}
// TrustedDataDataDAABlockV4ToTrustedDataDataDAAHeader converts *TrustedDataDAAHeader to *externalapi.TrustedDataDataDAAHeader
func TrustedDataDataDAABlockV4ToTrustedDataDataDAAHeader(daaBlock *TrustedDataDAAHeader) *externalapi.TrustedDataDataDAAHeader {
return &externalapi.TrustedDataDataDAAHeader{
Header: BlockHeaderToDomainBlockHeader(daaBlock.Header),
GHOSTDAGData: ghostdagDataToDomainGHOSTDAGData(daaBlock.GHOSTDAGData),
}
}
// GHOSTDAGHashPairToDomainGHOSTDAGHashPair converts *BlockGHOSTDAGDataHashPair to *externalapi.BlockGHOSTDAGDataHashPair
func GHOSTDAGHashPairToDomainGHOSTDAGHashPair(datum *BlockGHOSTDAGDataHashPair) *externalapi.BlockGHOSTDAGDataHashPair {
return &externalapi.BlockGHOSTDAGDataHashPair{
Hash: datum.Hash,
GHOSTDAGData: ghostdagDataToDomainGHOSTDAGData(datum.GHOSTDAGData),
}
}
func ghostdagDataToDomainGHOSTDAGData(data *BlockGHOSTDAGData) *externalapi.BlockGHOSTDAGData {
bluesAnticoneSizes := make(map[externalapi.DomainHash]externalapi.KType, len(data.BluesAnticoneSizes))
for _, pair := range data.BluesAnticoneSizes {
bluesAnticoneSizes[*pair.BlueHash] = pair.AnticoneSize
}
return externalapi.NewBlockGHOSTDAGData(
data.BlueScore,
data.BlueWork,
data.SelectedParent,
data.MergeSetBlues,
data.MergeSetReds,
bluesAnticoneSizes,
)
}
func domainGHOSTDAGDataGHOSTDAGData(data *externalapi.BlockGHOSTDAGData) *BlockGHOSTDAGData {
bluesAnticoneSizes := make([]*BluesAnticoneSizes, 0, len(data.BluesAnticoneSizes()))
for blueHash, anticoneSize := range data.BluesAnticoneSizes() {
blueHashCopy := blueHash
bluesAnticoneSizes = append(bluesAnticoneSizes, &BluesAnticoneSizes{
BlueHash: &blueHashCopy,
AnticoneSize: anticoneSize,
})
}
return &BlockGHOSTDAGData{
BlueScore: data.BlueScore(),
BlueWork: data.BlueWork(),
SelectedParent: data.SelectedParent(),
MergeSetBlues: data.MergeSetBlues(),
MergeSetReds: data.MergeSetReds(),
BluesAnticoneSizes: bluesAnticoneSizes,
}
}
// DomainBlockWithTrustedDataToBlockWithTrustedData converts *externalapi.BlockWithTrustedData to *MsgBlockWithTrustedData
func DomainBlockWithTrustedDataToBlockWithTrustedData(block *externalapi.BlockWithTrustedData) *MsgBlockWithTrustedData {
daaWindow := make([]*TrustedDataDataDAABlock, len(block.DAAWindow))
for i, daaBlock := range block.DAAWindow {
daaWindow[i] = &TrustedDataDataDAABlock{
Block: &MsgBlock{
Header: *DomainBlockHeaderToBlockHeader(daaBlock.Header),
},
GHOSTDAGData: domainGHOSTDAGDataGHOSTDAGData(daaBlock.GHOSTDAGData),
}
}
ghostdagData := make([]*BlockGHOSTDAGDataHashPair, len(block.GHOSTDAGData))
for i, datum := range block.GHOSTDAGData {
ghostdagData[i] = &BlockGHOSTDAGDataHashPair{
Hash: datum.Hash,
GHOSTDAGData: domainGHOSTDAGDataGHOSTDAGData(datum.GHOSTDAGData),
}
}
return &MsgBlockWithTrustedData{
Block: DomainBlockToMsgBlock(block.Block),
DAAScore: block.Block.Header.DAAScore(),
DAAWindow: daaWindow,
GHOSTDAGData: ghostdagData,
}
}
// DomainBlockWithTrustedDataToBlockWithTrustedDataV4 converts a set of *externalapi.DomainBlock, daa window indices and ghostdag data indices
// to *MsgBlockWithTrustedDataV4
func DomainBlockWithTrustedDataToBlockWithTrustedDataV4(block *externalapi.DomainBlock, daaWindowIndices, ghostdagDataIndices []uint64) *MsgBlockWithTrustedDataV4 {
return &MsgBlockWithTrustedDataV4{
Block: DomainBlockToMsgBlock(block),
DAAWindowIndices: daaWindowIndices,
GHOSTDAGDataIndices: ghostdagDataIndices,
}
}
// DomainTrustedDataToTrustedData converts *externalapi.BlockWithTrustedData to *MsgBlockWithTrustedData
func DomainTrustedDataToTrustedData(domainDAAWindow []*externalapi.TrustedDataDataDAAHeader, domainGHOSTDAGData []*externalapi.BlockGHOSTDAGDataHashPair) *MsgTrustedData {
daaWindow := make([]*TrustedDataDAAHeader, len(domainDAAWindow))
for i, daaBlock := range domainDAAWindow {
daaWindow[i] = &TrustedDataDAAHeader{
Header: DomainBlockHeaderToBlockHeader(daaBlock.Header),
GHOSTDAGData: domainGHOSTDAGDataGHOSTDAGData(daaBlock.GHOSTDAGData),
}
}
ghostdagData := make([]*BlockGHOSTDAGDataHashPair, len(domainGHOSTDAGData))
for i, datum := range domainGHOSTDAGData {
ghostdagData[i] = &BlockGHOSTDAGDataHashPair{
Hash: datum.Hash,
GHOSTDAGData: domainGHOSTDAGDataGHOSTDAGData(datum.GHOSTDAGData),
}
}
return &MsgTrustedData{
DAAWindow: daaWindow,
GHOSTDAGData: ghostdagData,
}
}
// MsgPruningPointProofToDomainPruningPointProof converts *MsgPruningPointProof to *externalapi.PruningPointProof
func MsgPruningPointProofToDomainPruningPointProof(pruningPointProofMessage *MsgPruningPointProof) *externalapi.PruningPointProof {
headers := make([][]externalapi.BlockHeader, len(pruningPointProofMessage.Headers))
for blockLevel, blockLevelParents := range pruningPointProofMessage.Headers {
headers[blockLevel] = make([]externalapi.BlockHeader, len(blockLevelParents))
for i, header := range blockLevelParents {
headers[blockLevel][i] = BlockHeaderToDomainBlockHeader(header)
}
}
return &externalapi.PruningPointProof{
Headers: headers,
}
}
// DomainPruningPointProofToMsgPruningPointProof converts *externalapi.PruningPointProof to *MsgPruningPointProof
func DomainPruningPointProofToMsgPruningPointProof(pruningPointProof *externalapi.PruningPointProof) *MsgPruningPointProof {
headers := make([][]*MsgBlockHeader, len(pruningPointProof.Headers))
for blockLevel, blockLevelParents := range pruningPointProof.Headers {
headers[blockLevel] = make([]*MsgBlockHeader, len(blockLevelParents))
for i, header := range blockLevelParents {
headers[blockLevel][i] = DomainBlockHeaderToBlockHeader(header)
}
}
return &MsgPruningPointProof{
Headers: headers,
}
}

View File

@@ -32,3 +32,20 @@ func (e *MessageError) Error() string {
func messageError(f string, desc string) *MessageError {
return &MessageError{Func: f, Description: desc}
}
// RPCError represents an error arriving from the RPC
type RPCError struct {
Message string
}
func (err RPCError) Error() string {
return err.Message
}
// RPCErrorf formats according to a format specifier and returns the string
// as an RPCError.
func RPCErrorf(format string, args ...interface{}) *RPCError {
return &RPCError{
Message: fmt.Sprintf(format, args...),
}
}

View File

@@ -1,56 +0,0 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import "io"
// fakeMessage implements the Message interface and is used to force encode
// errors in messages.
type fakeMessage struct {
command MessageCommand
payload []byte
forceEncodeErr bool
forceLenErr bool
}
// KaspaDecode doesn't do anything. It just satisfies the appmessage.Message
// interface.
func (msg *fakeMessage) KaspaDecode(r io.Reader, pver uint32) error {
return nil
}
// KaspaEncode writes the payload field of the fake message or forces an error
// if the forceEncodeErr flag of the fake message is set. It also satisfies the
// appmessage.Message interface.
func (msg *fakeMessage) KaspaEncode(w io.Writer, pver uint32) error {
if msg.forceEncodeErr {
err := &MessageError{
Func: "fakeMessage.KaspaEncode",
Description: "intentional error",
}
return err
}
_, err := w.Write(msg.payload)
return err
}
// Command returns the command field of the fake message and satisfies the
// Message interface.
func (msg *fakeMessage) Command() MessageCommand {
return msg.command
}
// MaxPayloadLength returns the length of the payload field of fake message
// or a smaller value if the forceLenErr flag of the fake message is set. It
// satisfies the Message interface.
func (msg *fakeMessage) MaxPayloadLength(pver uint32) uint32 {
lenp := uint32(len(msg.payload))
if msg.forceLenErr {
return lenp - 1
}
return lenp
}

View File

@@ -11,13 +11,16 @@ import (
// MaxMessagePayload is the maximum bytes a message can be regardless of other
// individual limits imposed by messages themselves.
const MaxMessagePayload = (1024 * 1024 * 32) // 32MB
const MaxMessagePayload = 1024 * 1024 * 32 // 32MB
// MessageCommand is a number in the header of a message that represents its type.
type MessageCommand uint32
func (cmd MessageCommand) String() string {
cmdString, ok := MessageCommandToString[cmd]
cmdString, ok := ProtocolMessageCommandToString[cmd]
if !ok {
cmdString, ok = RPCMessageCommandToString[cmd]
}
if !ok {
cmdString = "unknown command"
}
@@ -26,54 +29,255 @@ func (cmd MessageCommand) String() string {
// Commands used in kaspa message headers which describe the type of message.
const (
// protocol
CmdVersion MessageCommand = iota
CmdVerAck
CmdRequestAddresses
CmdAddresses
CmdRequestIBDBlocks
CmdRequestHeaders
CmdBlock
CmdTx
CmdPing
CmdPong
CmdRequestBlockLocator
CmdBlockLocator
CmdSelectedTip
CmdRequestSelectedTip
CmdInvRelayBlock
CmdRequestRelayBlocks
CmdInvTransaction
CmdRequestTransactions
CmdIBDBlock
CmdRequestNextIBDBlocks
CmdDoneIBDBlocks
CmdDoneHeaders
CmdTransactionNotFound
CmdReject
CmdRequestNextHeaders
CmdRequestPruningPointUTXOSet
CmdPruningPointUTXOSetChunk
CmdUnexpectedPruningPoint
CmdIBDBlockLocator
CmdIBDBlockLocatorHighestHash
CmdIBDBlockLocatorHighestHashNotFound
CmdBlockHeaders
CmdRequestNextPruningPointUTXOSetChunk
CmdDonePruningPointUTXOSetChunks
CmdBlockWithTrustedData
CmdDoneBlocksWithTrustedData
CmdRequestPruningPointAndItsAnticone
CmdIBDBlock
CmdRequestIBDBlocks
CmdPruningPoints
CmdRequestPruningPointProof
CmdPruningPointProof
CmdReady
CmdTrustedData
CmdBlockWithTrustedDataV4
// rpc
CmdGetCurrentNetworkRequestMessage
CmdGetCurrentNetworkResponseMessage
CmdSubmitBlockRequestMessage
CmdSubmitBlockResponseMessage
CmdGetBlockTemplateRequestMessage
CmdGetBlockTemplateResponseMessage
CmdGetBlockTemplateTransactionMessage
CmdNotifyBlockAddedRequestMessage
CmdNotifyBlockAddedResponseMessage
CmdBlockAddedNotificationMessage
CmdGetPeerAddressesRequestMessage
CmdGetPeerAddressesResponseMessage
CmdGetSelectedTipHashRequestMessage
CmdGetSelectedTipHashResponseMessage
CmdGetMempoolEntryRequestMessage
CmdGetMempoolEntryResponseMessage
CmdGetConnectedPeerInfoRequestMessage
CmdGetConnectedPeerInfoResponseMessage
CmdAddPeerRequestMessage
CmdAddPeerResponseMessage
CmdSubmitTransactionRequestMessage
CmdSubmitTransactionResponseMessage
CmdNotifyVirtualSelectedParentChainChangedRequestMessage
CmdNotifyVirtualSelectedParentChainChangedResponseMessage
CmdVirtualSelectedParentChainChangedNotificationMessage
CmdGetBlockRequestMessage
CmdGetBlockResponseMessage
CmdGetSubnetworkRequestMessage
CmdGetSubnetworkResponseMessage
CmdGetVirtualSelectedParentChainFromBlockRequestMessage
CmdGetVirtualSelectedParentChainFromBlockResponseMessage
CmdGetBlocksRequestMessage
CmdGetBlocksResponseMessage
CmdGetBlockCountRequestMessage
CmdGetBlockCountResponseMessage
CmdGetBlockDAGInfoRequestMessage
CmdGetBlockDAGInfoResponseMessage
CmdResolveFinalityConflictRequestMessage
CmdResolveFinalityConflictResponseMessage
CmdNotifyFinalityConflictsRequestMessage
CmdNotifyFinalityConflictsResponseMessage
CmdFinalityConflictNotificationMessage
CmdFinalityConflictResolvedNotificationMessage
CmdGetMempoolEntriesRequestMessage
CmdGetMempoolEntriesResponseMessage
CmdShutDownRequestMessage
CmdShutDownResponseMessage
CmdGetHeadersRequestMessage
CmdGetHeadersResponseMessage
CmdNotifyUTXOsChangedRequestMessage
CmdNotifyUTXOsChangedResponseMessage
CmdUTXOsChangedNotificationMessage
CmdStopNotifyingUTXOsChangedRequestMessage
CmdStopNotifyingUTXOsChangedResponseMessage
CmdGetUTXOsByAddressesRequestMessage
CmdGetUTXOsByAddressesResponseMessage
CmdGetBalanceByAddressRequestMessage
CmdGetBalanceByAddressResponseMessage
CmdGetVirtualSelectedParentBlueScoreRequestMessage
CmdGetVirtualSelectedParentBlueScoreResponseMessage
CmdNotifyVirtualSelectedParentBlueScoreChangedRequestMessage
CmdNotifyVirtualSelectedParentBlueScoreChangedResponseMessage
CmdVirtualSelectedParentBlueScoreChangedNotificationMessage
CmdBanRequestMessage
CmdBanResponseMessage
CmdUnbanRequestMessage
CmdUnbanResponseMessage
CmdGetInfoRequestMessage
CmdGetInfoResponseMessage
CmdNotifyPruningPointUTXOSetOverrideRequestMessage
CmdNotifyPruningPointUTXOSetOverrideResponseMessage
CmdPruningPointUTXOSetOverrideNotificationMessage
CmdStopNotifyingPruningPointUTXOSetOverrideRequestMessage
CmdStopNotifyingPruningPointUTXOSetOverrideResponseMessage
CmdEstimateNetworkHashesPerSecondRequestMessage
CmdEstimateNetworkHashesPerSecondResponseMessage
CmdNotifyVirtualDaaScoreChangedRequestMessage
CmdNotifyVirtualDaaScoreChangedResponseMessage
CmdVirtualDaaScoreChangedNotificationMessage
CmdGetBalancesByAddressesRequestMessage
CmdGetBalancesByAddressesResponseMessage
)
// MessageCommandToString maps all MessageCommands to their string representation
var MessageCommandToString = map[MessageCommand]string{
CmdVersion: "Version",
CmdVerAck: "VerAck",
CmdRequestAddresses: "RequestAddresses",
CmdAddresses: "Addresses",
CmdRequestIBDBlocks: "RequestBlocks",
CmdBlock: "Block",
CmdTx: "Tx",
CmdPing: "Ping",
CmdPong: "Pong",
CmdRequestBlockLocator: "RequestBlockLocator",
CmdBlockLocator: "BlockLocator",
CmdSelectedTip: "SelectedTip",
CmdRequestSelectedTip: "RequestSelectedTip",
CmdInvRelayBlock: "InvRelayBlock",
CmdRequestRelayBlocks: "RequestRelayBlocks",
CmdInvTransaction: "InvTransaction",
CmdRequestTransactions: "RequestTransactions",
CmdIBDBlock: "IBDBlock",
CmdRequestNextIBDBlocks: "RequestNextIBDBlocks",
CmdDoneIBDBlocks: "DoneIBDBlocks",
CmdTransactionNotFound: "TransactionNotFound",
CmdReject: "Reject",
// ProtocolMessageCommandToString maps all MessageCommands to their string representation
var ProtocolMessageCommandToString = map[MessageCommand]string{
CmdVersion: "Version",
CmdVerAck: "VerAck",
CmdRequestAddresses: "RequestAddresses",
CmdAddresses: "Addresses",
CmdRequestHeaders: "CmdRequestHeaders",
CmdBlock: "Block",
CmdTx: "Tx",
CmdPing: "Ping",
CmdPong: "Pong",
CmdRequestBlockLocator: "RequestBlockLocator",
CmdBlockLocator: "BlockLocator",
CmdInvRelayBlock: "InvRelayBlock",
CmdRequestRelayBlocks: "RequestRelayBlocks",
CmdInvTransaction: "InvTransaction",
CmdRequestTransactions: "RequestTransactions",
CmdDoneHeaders: "DoneHeaders",
CmdTransactionNotFound: "TransactionNotFound",
CmdReject: "Reject",
CmdRequestNextHeaders: "RequestNextHeaders",
CmdRequestPruningPointUTXOSet: "RequestPruningPointUTXOSet",
CmdPruningPointUTXOSetChunk: "PruningPointUTXOSetChunk",
CmdUnexpectedPruningPoint: "UnexpectedPruningPoint",
CmdIBDBlockLocator: "IBDBlockLocator",
CmdIBDBlockLocatorHighestHash: "IBDBlockLocatorHighestHash",
CmdIBDBlockLocatorHighestHashNotFound: "IBDBlockLocatorHighestHashNotFound",
CmdBlockHeaders: "BlockHeaders",
CmdRequestNextPruningPointUTXOSetChunk: "RequestNextPruningPointUTXOSetChunk",
CmdDonePruningPointUTXOSetChunks: "DonePruningPointUTXOSetChunks",
CmdBlockWithTrustedData: "BlockWithTrustedData",
CmdDoneBlocksWithTrustedData: "DoneBlocksWithTrustedData",
CmdRequestPruningPointAndItsAnticone: "RequestPruningPointAndItsAnticoneHeaders",
CmdIBDBlock: "IBDBlock",
CmdRequestIBDBlocks: "RequestIBDBlocks",
CmdPruningPoints: "PruningPoints",
CmdRequestPruningPointProof: "RequestPruningPointProof",
CmdPruningPointProof: "PruningPointProof",
CmdReady: "Ready",
CmdTrustedData: "TrustedData",
CmdBlockWithTrustedDataV4: "BlockWithTrustedDataV4",
}
// RPCMessageCommandToString maps all MessageCommands to their string representation
var RPCMessageCommandToString = map[MessageCommand]string{
CmdGetCurrentNetworkRequestMessage: "GetCurrentNetworkRequest",
CmdGetCurrentNetworkResponseMessage: "GetCurrentNetworkResponse",
CmdSubmitBlockRequestMessage: "SubmitBlockRequest",
CmdSubmitBlockResponseMessage: "SubmitBlockResponse",
CmdGetBlockTemplateRequestMessage: "GetBlockTemplateRequest",
CmdGetBlockTemplateResponseMessage: "GetBlockTemplateResponse",
CmdGetBlockTemplateTransactionMessage: "CmdGetBlockTemplateTransaction",
CmdNotifyBlockAddedRequestMessage: "NotifyBlockAddedRequest",
CmdNotifyBlockAddedResponseMessage: "NotifyBlockAddedResponse",
CmdBlockAddedNotificationMessage: "BlockAddedNotification",
CmdGetPeerAddressesRequestMessage: "GetPeerAddressesRequest",
CmdGetPeerAddressesResponseMessage: "GetPeerAddressesResponse",
CmdGetSelectedTipHashRequestMessage: "GetSelectedTipHashRequest",
CmdGetSelectedTipHashResponseMessage: "GetSelectedTipHashResponse",
CmdGetMempoolEntryRequestMessage: "GetMempoolEntryRequest",
CmdGetMempoolEntryResponseMessage: "GetMempoolEntryResponse",
CmdGetConnectedPeerInfoRequestMessage: "GetConnectedPeerInfoRequest",
CmdGetConnectedPeerInfoResponseMessage: "GetConnectedPeerInfoResponse",
CmdAddPeerRequestMessage: "AddPeerRequest",
CmdAddPeerResponseMessage: "AddPeerResponse",
CmdSubmitTransactionRequestMessage: "SubmitTransactionRequest",
CmdSubmitTransactionResponseMessage: "SubmitTransactionResponse",
CmdNotifyVirtualSelectedParentChainChangedRequestMessage: "NotifyVirtualSelectedParentChainChangedRequest",
CmdNotifyVirtualSelectedParentChainChangedResponseMessage: "NotifyVirtualSelectedParentChainChangedResponse",
CmdVirtualSelectedParentChainChangedNotificationMessage: "VirtualSelectedParentChainChangedNotification",
CmdGetBlockRequestMessage: "GetBlockRequest",
CmdGetBlockResponseMessage: "GetBlockResponse",
CmdGetSubnetworkRequestMessage: "GetSubnetworkRequest",
CmdGetSubnetworkResponseMessage: "GetSubnetworkResponse",
CmdGetVirtualSelectedParentChainFromBlockRequestMessage: "GetVirtualSelectedParentChainFromBlockRequest",
CmdGetVirtualSelectedParentChainFromBlockResponseMessage: "GetVirtualSelectedParentChainFromBlockResponse",
CmdGetBlocksRequestMessage: "GetBlocksRequest",
CmdGetBlocksResponseMessage: "GetBlocksResponse",
CmdGetBlockCountRequestMessage: "GetBlockCountRequest",
CmdGetBlockCountResponseMessage: "GetBlockCountResponse",
CmdGetBlockDAGInfoRequestMessage: "GetBlockDAGInfoRequest",
CmdGetBlockDAGInfoResponseMessage: "GetBlockDAGInfoResponse",
CmdResolveFinalityConflictRequestMessage: "ResolveFinalityConflictRequest",
CmdResolveFinalityConflictResponseMessage: "ResolveFinalityConflictResponse",
CmdNotifyFinalityConflictsRequestMessage: "NotifyFinalityConflictsRequest",
CmdNotifyFinalityConflictsResponseMessage: "NotifyFinalityConflictsResponse",
CmdFinalityConflictNotificationMessage: "FinalityConflictNotification",
CmdFinalityConflictResolvedNotificationMessage: "FinalityConflictResolvedNotification",
CmdGetMempoolEntriesRequestMessage: "GetMempoolEntriesRequest",
CmdGetMempoolEntriesResponseMessage: "GetMempoolEntriesResponse",
CmdGetHeadersRequestMessage: "GetHeadersRequest",
CmdGetHeadersResponseMessage: "GetHeadersResponse",
CmdNotifyUTXOsChangedRequestMessage: "NotifyUTXOsChangedRequest",
CmdNotifyUTXOsChangedResponseMessage: "NotifyUTXOsChangedResponse",
CmdUTXOsChangedNotificationMessage: "UTXOsChangedNotification",
CmdStopNotifyingUTXOsChangedRequestMessage: "StopNotifyingUTXOsChangedRequest",
CmdStopNotifyingUTXOsChangedResponseMessage: "StopNotifyingUTXOsChangedResponse",
CmdGetUTXOsByAddressesRequestMessage: "GetUTXOsByAddressesRequest",
CmdGetUTXOsByAddressesResponseMessage: "GetUTXOsByAddressesResponse",
CmdGetBalanceByAddressRequestMessage: "GetBalanceByAddressRequest",
CmdGetBalanceByAddressResponseMessage: "GetBalancesByAddressResponse",
CmdGetVirtualSelectedParentBlueScoreRequestMessage: "GetVirtualSelectedParentBlueScoreRequest",
CmdGetVirtualSelectedParentBlueScoreResponseMessage: "GetVirtualSelectedParentBlueScoreResponse",
CmdNotifyVirtualSelectedParentBlueScoreChangedRequestMessage: "NotifyVirtualSelectedParentBlueScoreChangedRequest",
CmdNotifyVirtualSelectedParentBlueScoreChangedResponseMessage: "NotifyVirtualSelectedParentBlueScoreChangedResponse",
CmdVirtualSelectedParentBlueScoreChangedNotificationMessage: "VirtualSelectedParentBlueScoreChangedNotification",
CmdBanRequestMessage: "BanRequest",
CmdBanResponseMessage: "BanResponse",
CmdUnbanRequestMessage: "UnbanRequest",
CmdUnbanResponseMessage: "UnbanResponse",
CmdGetInfoRequestMessage: "GetInfoRequest",
CmdGetInfoResponseMessage: "GeInfoResponse",
CmdNotifyPruningPointUTXOSetOverrideRequestMessage: "NotifyPruningPointUTXOSetOverrideRequest",
CmdNotifyPruningPointUTXOSetOverrideResponseMessage: "NotifyPruningPointUTXOSetOverrideResponse",
CmdPruningPointUTXOSetOverrideNotificationMessage: "PruningPointUTXOSetOverrideNotification",
CmdStopNotifyingPruningPointUTXOSetOverrideRequestMessage: "StopNotifyingPruningPointUTXOSetOverrideRequest",
CmdStopNotifyingPruningPointUTXOSetOverrideResponseMessage: "StopNotifyingPruningPointUTXOSetOverrideResponse",
CmdEstimateNetworkHashesPerSecondRequestMessage: "EstimateNetworkHashesPerSecondRequest",
CmdEstimateNetworkHashesPerSecondResponseMessage: "EstimateNetworkHashesPerSecondResponse",
CmdNotifyVirtualDaaScoreChangedRequestMessage: "NotifyVirtualDaaScoreChangedRequest",
CmdNotifyVirtualDaaScoreChangedResponseMessage: "NotifyVirtualDaaScoreChangedResponse",
CmdVirtualDaaScoreChangedNotificationMessage: "VirtualDaaScoreChangedNotification",
CmdGetBalancesByAddressesRequestMessage: "GetBalancesByAddressesRequest",
CmdGetBalancesByAddressesResponseMessage: "GetBalancesByAddressesResponse",
}
// Message is an interface that describes a kaspa message. A type that

View File

@@ -1,75 +0,0 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"fmt"
"github.com/kaspanet/kaspad/util/subnetworkid"
)
// MaxAddressesPerMsg is the maximum number of addresses that can be in a single
// kaspa Addresses message (MsgAddresses).
const MaxAddressesPerMsg = 1000
// MsgAddresses implements the Message interface and represents a kaspa
// Addresses message. It is used to provide a list of known active peers on the
// network. An active peer is considered one that has transmitted a message
// within the last 3 hours. Nodes which have not transmitted in that time
// frame should be forgotten. Each message is limited to a maximum number of
// addresses, which is currently 1000. As a result, multiple messages must
// be used to relay the full list.
//
// Use the AddAddress function to build up the list of known addresses when
// sending an Addresses message to another peer.
type MsgAddresses struct {
baseMessage
IncludeAllSubnetworks bool
SubnetworkID *subnetworkid.SubnetworkID
AddrList []*NetAddress
}
// AddAddress adds a known active peer to the message.
func (msg *MsgAddresses) AddAddress(na *NetAddress) error {
if len(msg.AddrList)+1 > MaxAddressesPerMsg {
str := fmt.Sprintf("too many addresses in message [max %d]",
MaxAddressesPerMsg)
return messageError("MsgAddresses.AddAddress", str)
}
msg.AddrList = append(msg.AddrList, na)
return nil
}
// AddAddresses adds multiple known active peers to the message.
func (msg *MsgAddresses) AddAddresses(netAddrs ...*NetAddress) error {
for _, na := range netAddrs {
err := msg.AddAddress(na)
if err != nil {
return err
}
}
return nil
}
// ClearAddresses removes all addresses from the message.
func (msg *MsgAddresses) ClearAddresses() {
msg.AddrList = []*NetAddress{}
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgAddresses) Command() MessageCommand {
return CmdAddresses
}
// NewMsgAddresses returns a new kaspa Addresses message that conforms to the
// Message interface. See MsgAddresses for details.
func NewMsgAddresses(includeAllSubnetworks bool, subnetworkID *subnetworkid.SubnetworkID) *MsgAddresses {
return &MsgAddresses{
IncludeAllSubnetworks: includeAllSubnetworks,
SubnetworkID: subnetworkID,
AddrList: make([]*NetAddress, 0, MaxAddressesPerMsg),
}
}

View File

@@ -1,58 +0,0 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"net"
"testing"
"github.com/davecgh/go-spew/spew"
)
// TestAddresses tests the MsgAddresses API.
func TestAddresses(t *testing.T) {
// Ensure the command is expected value.
wantCmd := MessageCommand(3)
msg := NewMsgAddresses(false, nil)
if cmd := msg.Command(); cmd != wantCmd {
t.Errorf("NewMsgAddresses: wrong command - got %v want %v",
cmd, wantCmd)
}
// Ensure NetAddresses are added properly.
tcpAddr := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 16111}
na := NewNetAddress(tcpAddr, SFNodeNetwork)
err := msg.AddAddress(na)
if err != nil {
t.Errorf("AddAddress: %v", err)
}
if msg.AddrList[0] != na {
t.Errorf("AddAddress: wrong address added - got %v, want %v",
spew.Sprint(msg.AddrList[0]), spew.Sprint(na))
}
// Ensure the address list is cleared properly.
msg.ClearAddresses()
if len(msg.AddrList) != 0 {
t.Errorf("ClearAddresses: address list is not empty - "+
"got %v [%v], want %v", len(msg.AddrList),
spew.Sprint(msg.AddrList[0]), 0)
}
// Ensure adding more than the max allowed addresses per message returns
// error.
for i := 0; i < MaxAddressesPerMsg+1; i++ {
err = msg.AddAddress(na)
}
if err == nil {
t.Errorf("AddAddress: expected error on too many addresses " +
"not received")
}
err = msg.AddAddresses(na)
if err == nil {
t.Errorf("AddAddresses: expected error on too many addresses " +
"not received")
}
}

View File

@@ -1,250 +0,0 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"bytes"
"fmt"
"io"
"github.com/kaspanet/kaspad/util/subnetworkid"
"github.com/kaspanet/kaspad/util/daghash"
)
// defaultTransactionAlloc is the default size used for the backing array
// for transactions. The transaction array will dynamically grow as needed, but
// this figure is intended to provide enough space for the number of
// transactions in the vast majority of blocks without needing to grow the
// backing array multiple times.
const defaultTransactionAlloc = 2048
// MaxMassPerBlock is the maximum total transaction mass a block may have.
const MaxMassPerBlock = 10000000
// MaxMassPerTx is the maximum total mass a transaction may have.
const MaxMassPerTx = MaxMassPerBlock / 2
// MaxTxPerBlock is the maximum number of transactions that could
// possibly fit into a block.
const MaxTxPerBlock = (MaxMassPerBlock / minTxPayload) + 1
// TxLoc holds locator data for the offset and length of where a transaction is
// located within a MsgBlock data buffer.
type TxLoc struct {
TxStart int
TxLen int
}
// MsgBlock implements the Message interface and represents a kaspa
// block message. It is used to deliver block and transaction information in
// response to a getdata message (MsgGetData) for a given block hash.
type MsgBlock struct {
baseMessage
Header BlockHeader
Transactions []*MsgTx
}
// AddTransaction adds a transaction to the message.
func (msg *MsgBlock) AddTransaction(tx *MsgTx) {
msg.Transactions = append(msg.Transactions, tx)
}
// ClearTransactions removes all transactions from the message.
func (msg *MsgBlock) ClearTransactions() {
msg.Transactions = make([]*MsgTx, 0, defaultTransactionAlloc)
}
// KaspaDecode decodes r using the kaspa protocol encoding into the receiver.
// This is part of the Message interface implementation.
// See Deserialize for decoding blocks stored to disk, such as in a database, as
// opposed to decoding blocks from the appmessage.
func (msg *MsgBlock) KaspaDecode(r io.Reader, pver uint32) error {
err := readBlockHeader(r, pver, &msg.Header)
if err != nil {
return err
}
txCount, err := ReadVarInt(r)
if err != nil {
return err
}
// Prevent more transactions than could possibly fit into a block.
// It would be possible to cause memory exhaustion and panics without
// a sane upper bound on this count.
if txCount > MaxTxPerBlock {
str := fmt.Sprintf("too many transactions to fit into a block "+
"[count %d, max %d]", txCount, MaxTxPerBlock)
return messageError("MsgBlock.KaspaDecode", str)
}
msg.Transactions = make([]*MsgTx, 0, txCount)
for i := uint64(0); i < txCount; i++ {
tx := MsgTx{}
err := tx.KaspaDecode(r, pver)
if err != nil {
return err
}
msg.Transactions = append(msg.Transactions, &tx)
}
return nil
}
// Deserialize decodes a block from r into the receiver using a format that is
// suitable for long-term storage such as a database while respecting the
// Version field in the block. This function differs from KaspaDecode in that
// KaspaDecode decodes from the kaspa appmessage protocol as it was sent across the
// network. The appmessage encoding can technically differ depending on the protocol
// version and doesn't even really need to match the format of a stored block at
// all. As of the time this comment was written, the encoded block is the same
// in both instances, but there is a distinct difference and separating the two
// allows the API to be flexible enough to deal with changes.
func (msg *MsgBlock) Deserialize(r io.Reader) error {
// At the current time, there is no difference between the appmessage encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of KaspaDecode.
return msg.KaspaDecode(r, 0)
}
// DeserializeTxLoc decodes r in the same manner Deserialize does, but it takes
// a byte buffer instead of a generic reader and returns a slice containing the
// start and length of each transaction within the raw data that is being
// deserialized.
func (msg *MsgBlock) DeserializeTxLoc(r *bytes.Buffer) ([]TxLoc, error) {
fullLen := r.Len()
// At the current time, there is no difference between the appmessage encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of existing appmessage protocol functions.
err := readBlockHeader(r, 0, &msg.Header)
if err != nil {
return nil, err
}
txCount, err := ReadVarInt(r)
if err != nil {
return nil, err
}
// Prevent more transactions than could possibly fit into a block.
// It would be possible to cause memory exhaustion and panics without
// a sane upper bound on this count.
if txCount > MaxTxPerBlock {
str := fmt.Sprintf("too many transactions to fit into a block "+
"[count %d, max %d]", txCount, MaxTxPerBlock)
return nil, messageError("MsgBlock.DeserializeTxLoc", str)
}
// Deserialize each transaction while keeping track of its location
// within the byte stream.
msg.Transactions = make([]*MsgTx, 0, txCount)
txLocs := make([]TxLoc, txCount)
for i := uint64(0); i < txCount; i++ {
txLocs[i].TxStart = fullLen - r.Len()
tx := MsgTx{}
err := tx.Deserialize(r)
if err != nil {
return nil, err
}
msg.Transactions = append(msg.Transactions, &tx)
txLocs[i].TxLen = (fullLen - r.Len()) - txLocs[i].TxStart
}
return txLocs, nil
}
// KaspaEncode encodes the receiver to w using the kaspa protocol encoding.
// This is part of the Message interface implementation.
// See Serialize for encoding blocks to be stored to disk, such as in a
// database, as opposed to encoding blocks for the appmessage.
func (msg *MsgBlock) KaspaEncode(w io.Writer, pver uint32) error {
err := writeBlockHeader(w, pver, &msg.Header)
if err != nil {
return err
}
err = WriteVarInt(w, uint64(len(msg.Transactions)))
if err != nil {
return err
}
for _, tx := range msg.Transactions {
err = tx.KaspaEncode(w, pver)
if err != nil {
return err
}
}
return nil
}
// Serialize encodes the block to w using a format that suitable for long-term
// storage such as a database while respecting the Version field in the block.
// This function differs from KaspaEncode in that KaspaEncode encodes the block to
// the kaspa appmessage protocol in order to be sent across the network. The appmessage
// encoding can technically differ depending on the protocol version and doesn't
// even really need to match the format of a stored block at all. As of the
// time this comment was written, the encoded block is the same in both
// instances, but there is a distinct difference and separating the two allows
// the API to be flexible enough to deal with changes.
func (msg *MsgBlock) Serialize(w io.Writer) error {
// At the current time, there is no difference between the appmessage encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of KaspaEncode.
return msg.KaspaEncode(w, 0)
}
// SerializeSize returns the number of bytes it would take to serialize the
// block.
func (msg *MsgBlock) SerializeSize() int {
// Block header bytes + Serialized varint size for the number of
// transactions.
n := msg.Header.SerializeSize() + VarIntSerializeSize(uint64(len(msg.Transactions)))
for _, tx := range msg.Transactions {
n += tx.SerializeSize()
}
return n
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgBlock) Command() MessageCommand {
return CmdBlock
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgBlock) MaxPayloadLength(pver uint32) uint32 {
return MaxMessagePayload
}
// BlockHash computes the block identifier hash for this block.
func (msg *MsgBlock) BlockHash() *daghash.Hash {
return msg.Header.BlockHash()
}
// ConvertToPartial clears out all the payloads of the subnetworks that are
// incompatible with the given subnetwork ID.
// Note: this operation modifies the block in place.
func (msg *MsgBlock) ConvertToPartial(subnetworkID *subnetworkid.SubnetworkID) {
for _, tx := range msg.Transactions {
if !tx.SubnetworkID.IsEqual(subnetworkID) {
tx.Payload = []byte{}
}
}
}
// NewMsgBlock returns a new kaspa block message that conforms to the
// Message interface. See MsgBlock for details.
func NewMsgBlock(blockHeader *BlockHeader) *MsgBlock {
return &MsgBlock{
Header: *blockHeader,
Transactions: make([]*MsgTx, 0, defaultTransactionAlloc),
}
}

View File

@@ -1,610 +0,0 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"bytes"
"github.com/kaspanet/kaspad/util/mstime"
"github.com/kaspanet/kaspad/util/subnetworkid"
"github.com/pkg/errors"
"io"
"math"
"reflect"
"testing"
"github.com/davecgh/go-spew/spew"
"github.com/kaspanet/kaspad/util/daghash"
)
// TestBlock tests the MsgBlock API.
func TestBlock(t *testing.T) {
pver := ProtocolVersion
// Block 1 header.
parentHashes := blockOne.Header.ParentHashes
hashMerkleRoot := blockOne.Header.HashMerkleRoot
acceptedIDMerkleRoot := blockOne.Header.AcceptedIDMerkleRoot
utxoCommitment := blockOne.Header.UTXOCommitment
bits := blockOne.Header.Bits
nonce := blockOne.Header.Nonce
bh := NewBlockHeader(1, parentHashes, hashMerkleRoot, acceptedIDMerkleRoot, utxoCommitment, bits, nonce)
// Ensure the command is expected value.
wantCmd := MessageCommand(5)
msg := NewMsgBlock(bh)
if cmd := msg.Command(); cmd != wantCmd {
t.Errorf("NewMsgBlock: wrong command - got %v want %v",
cmd, wantCmd)
}
// Ensure max payload is expected value for latest protocol version.
wantPayload := uint32(1024 * 1024 * 32)
maxPayload := msg.MaxPayloadLength(pver)
if maxPayload != wantPayload {
t.Errorf("MaxPayloadLength: wrong max payload length for "+
"protocol version %d - got %v, want %v", pver,
maxPayload, wantPayload)
}
// Ensure we get the same block header data back out.
if !reflect.DeepEqual(&msg.Header, bh) {
t.Errorf("NewMsgBlock: wrong block header - got %v, want %v",
spew.Sdump(&msg.Header), spew.Sdump(bh))
}
// Ensure transactions are added properly.
tx := blockOne.Transactions[0].Copy()
msg.AddTransaction(tx)
if !reflect.DeepEqual(msg.Transactions, blockOne.Transactions) {
t.Errorf("AddTransaction: wrong transactions - got %v, want %v",
spew.Sdump(msg.Transactions),
spew.Sdump(blockOne.Transactions))
}
// Ensure transactions are properly cleared.
msg.ClearTransactions()
if len(msg.Transactions) != 0 {
t.Errorf("ClearTransactions: wrong transactions - got %v, want %v",
len(msg.Transactions), 0)
}
}
// TestBlockHash tests the ability to generate the hash of a block accurately.
func TestBlockHash(t *testing.T) {
// Block 1 hash.
hashStr := "55d71bd49a8233bc9f0edbcbd0ad5d3eaebffe1fc6a6443a1c1f310fd02c11a5"
wantHash, err := daghash.NewHashFromStr(hashStr)
if err != nil {
t.Errorf("NewHashFromStr: %v", err)
}
// Ensure the hash produced is expected.
blockHash := blockOne.BlockHash()
if !blockHash.IsEqual(wantHash) {
t.Errorf("BlockHash: wrong hash - got %v, want %v",
spew.Sprint(blockHash), spew.Sprint(wantHash))
}
}
func TestConvertToPartial(t *testing.T) {
transactions := []struct {
subnetworkID *subnetworkid.SubnetworkID
payload []byte
expectedPayloadLength int
}{
{
subnetworkID: subnetworkid.SubnetworkIDNative,
payload: []byte{},
expectedPayloadLength: 0,
},
{
subnetworkID: subnetworkid.SubnetworkIDRegistry,
payload: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},
expectedPayloadLength: 0,
},
{
subnetworkID: &subnetworkid.SubnetworkID{123},
payload: []byte{0x01},
expectedPayloadLength: 1,
},
{
subnetworkID: &subnetworkid.SubnetworkID{234},
payload: []byte{0x02},
expectedPayloadLength: 0,
},
}
block := MsgBlock{}
payload := []byte{1}
for _, transaction := range transactions {
block.Transactions = append(block.Transactions, NewSubnetworkMsgTx(1, nil, nil, transaction.subnetworkID, 0, payload))
}
block.ConvertToPartial(&subnetworkid.SubnetworkID{123})
for _, transaction := range transactions {
var subnetworkTx *MsgTx
for _, tx := range block.Transactions {
if tx.SubnetworkID.IsEqual(transaction.subnetworkID) {
subnetworkTx = tx
}
}
if subnetworkTx == nil {
t.Errorf("ConvertToPartial: subnetworkID '%s' not found in block!", transaction.subnetworkID)
continue
}
payloadLength := len(subnetworkTx.Payload)
if payloadLength != transaction.expectedPayloadLength {
t.Errorf("ConvertToPartial: unexpected payload length for subnetwork '%s': expected: %d, got: %d",
transaction.subnetworkID, transaction.expectedPayloadLength, payloadLength)
}
}
}
// TestBlockEncoding tests the MsgBlock appmessage encode and decode for various numbers
// of transaction inputs and outputs and protocol versions.
func TestBlockEncoding(t *testing.T) {
tests := []struct {
in *MsgBlock // Message to encode
out *MsgBlock // Expected decoded message
buf []byte // Encoded value
txLocs []TxLoc // Expected transaction locations
pver uint32 // Protocol version for appmessage encoding
}{
// Latest protocol version.
{
&blockOne,
&blockOne,
blockOneBytes,
blockOneTxLocs,
ProtocolVersion,
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode the message to appmessage format.
var buf bytes.Buffer
err := test.in.KaspaEncode(&buf, test.pver)
if err != nil {
t.Errorf("KaspaEncode #%d error %v", i, err)
continue
}
if !bytes.Equal(buf.Bytes(), test.buf) {
t.Errorf("KaspaEncode #%d\n got: %s want: %s", i,
spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
continue
}
// Decode the message from appmessage format.
var msg MsgBlock
rbuf := bytes.NewReader(test.buf)
err = msg.KaspaDecode(rbuf, test.pver)
if err != nil {
t.Errorf("KaspaDecode #%d error %v", i, err)
continue
}
if !reflect.DeepEqual(&msg, test.out) {
t.Errorf("KaspaDecode #%d\n got: %s want: %s", i,
spew.Sdump(&msg), spew.Sdump(test.out))
continue
}
}
}
// TestBlockEncodingErrors performs negative tests against appmessage encode and decode
// of MsgBlock to confirm error paths work correctly.
func TestBlockEncodingErrors(t *testing.T) {
pver := ProtocolVersion
tests := []struct {
in *MsgBlock // Value to encode
buf []byte // Encoded value
pver uint32 // Protocol version for appmessage encoding
max int // Max size of fixed buffer to induce errors
writeErr error // Expected write error
readErr error // Expected read error
}{
// Force error in version.
{&blockOne, blockOneBytes, pver, 0, io.ErrShortWrite, io.EOF},
// Force error in num block hashes.
{&blockOne, blockOneBytes, pver, 4, io.ErrShortWrite, io.EOF},
// Force error in prev block hash #1.
{&blockOne, blockOneBytes, pver, 5, io.ErrShortWrite, io.EOF},
// Force error in prev block hash #2.
{&blockOne, blockOneBytes, pver, 37, io.ErrShortWrite, io.EOF},
// Force error in hash merkle root.
{&blockOne, blockOneBytes, pver, 69, io.ErrShortWrite, io.EOF},
// Force error in accepted ID merkle root.
{&blockOne, blockOneBytes, pver, 101, io.ErrShortWrite, io.EOF},
// Force error in utxo commitment.
{&blockOne, blockOneBytes, pver, 133, io.ErrShortWrite, io.EOF},
// Force error in timestamp.
{&blockOne, blockOneBytes, pver, 165, io.ErrShortWrite, io.EOF},
// Force error in difficulty bits.
{&blockOne, blockOneBytes, pver, 173, io.ErrShortWrite, io.EOF},
// Force error in header nonce.
{&blockOne, blockOneBytes, pver, 177, io.ErrShortWrite, io.EOF},
// Force error in transaction count.
{&blockOne, blockOneBytes, pver, 185, io.ErrShortWrite, io.EOF},
// Force error in transactions.
{&blockOne, blockOneBytes, pver, 186, io.ErrShortWrite, io.EOF},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to appmessage format.
w := newFixedWriter(test.max)
err := test.in.KaspaEncode(w, test.pver)
if !errors.Is(err, test.writeErr) {
t.Errorf("KaspaEncode #%d wrong error got: %v, want: %v",
i, err, test.writeErr)
continue
}
// Decode from appmessage format.
var msg MsgBlock
r := newFixedReader(test.max, test.buf)
err = msg.KaspaDecode(r, test.pver)
if !errors.Is(err, test.readErr) {
t.Errorf("KaspaDecode #%d wrong error got: %v, want: %v",
i, err, test.readErr)
continue
}
}
}
// TestBlockSerialize tests MsgBlock serialize and deserialize.
func TestBlockSerialize(t *testing.T) {
tests := []struct {
in *MsgBlock // Message to encode
out *MsgBlock // Expected decoded message
buf []byte // Serialized data
txLocs []TxLoc // Expected transaction locations
}{
{
&blockOne,
&blockOne,
blockOneBytes,
blockOneTxLocs,
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Serialize the block.
var buf bytes.Buffer
err := test.in.Serialize(&buf)
if err != nil {
t.Errorf("Serialize #%d error %v", i, err)
continue
}
if !bytes.Equal(buf.Bytes(), test.buf) {
t.Errorf("Serialize #%d\n got: %s want: %s", i,
spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
continue
}
// Deserialize the block.
var block MsgBlock
rbuf := bytes.NewReader(test.buf)
err = block.Deserialize(rbuf)
if err != nil {
t.Errorf("Deserialize #%d error %v", i, err)
continue
}
if !reflect.DeepEqual(&block, test.out) {
t.Errorf("Deserialize #%d\n got: %s want: %s", i,
spew.Sdump(&block), spew.Sdump(test.out))
continue
}
// Deserialize the block while gathering transaction location
// information.
var txLocBlock MsgBlock
br := bytes.NewBuffer(test.buf)
txLocs, err := txLocBlock.DeserializeTxLoc(br)
if err != nil {
t.Errorf("DeserializeTxLoc #%d error %v", i, err)
continue
}
if !reflect.DeepEqual(&txLocBlock, test.out) {
t.Errorf("DeserializeTxLoc #%d\n got: %s want: %s", i,
spew.Sdump(&txLocBlock), spew.Sdump(test.out))
continue
}
if !reflect.DeepEqual(txLocs, test.txLocs) {
t.Errorf("DeserializeTxLoc #%d\n got: %s want: %s", i,
spew.Sdump(txLocs), spew.Sdump(test.txLocs))
continue
}
}
}
// TestBlockSerializeErrors performs negative tests against appmessage encode and
// decode of MsgBlock to confirm error paths work correctly.
func TestBlockSerializeErrors(t *testing.T) {
tests := []struct {
in *MsgBlock // Value to encode
buf []byte // Serialized data
max int // Max size of fixed buffer to induce errors
writeErr error // Expected write error
readErr error // Expected read error
}{
// Force error in version.
{&blockOne, blockOneBytes, 0, io.ErrShortWrite, io.EOF},
// Force error in numParentBlocks.
{&blockOne, blockOneBytes, 4, io.ErrShortWrite, io.EOF},
// Force error in prev block hash #1.
{&blockOne, blockOneBytes, 5, io.ErrShortWrite, io.EOF},
// Force error in prev block hash #2.
{&blockOne, blockOneBytes, 37, io.ErrShortWrite, io.EOF},
// Force error in hash merkle root.
{&blockOne, blockOneBytes, 69, io.ErrShortWrite, io.EOF},
// Force error in accepted ID merkle root.
{&blockOne, blockOneBytes, 101, io.ErrShortWrite, io.EOF},
// Force error in utxo commitment.
{&blockOne, blockOneBytes, 133, io.ErrShortWrite, io.EOF},
// Force error in timestamp.
{&blockOne, blockOneBytes, 165, io.ErrShortWrite, io.EOF},
// Force error in difficulty bits.
{&blockOne, blockOneBytes, 173, io.ErrShortWrite, io.EOF},
// Force error in header nonce.
{&blockOne, blockOneBytes, 177, io.ErrShortWrite, io.EOF},
// Force error in transaction count.
{&blockOne, blockOneBytes, 185, io.ErrShortWrite, io.EOF},
// Force error in transactions.
{&blockOne, blockOneBytes, 186, io.ErrShortWrite, io.EOF},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Serialize the block.
w := newFixedWriter(test.max)
err := test.in.Serialize(w)
if !errors.Is(err, test.writeErr) {
t.Errorf("Serialize #%d wrong error got: %v, want: %v",
i, err, test.writeErr)
continue
}
// Deserialize the block.
var block MsgBlock
r := newFixedReader(test.max, test.buf)
err = block.Deserialize(r)
if !errors.Is(err, test.readErr) {
t.Errorf("Deserialize #%d wrong error got: %v, want: %v",
i, err, test.readErr)
continue
}
var txLocBlock MsgBlock
br := bytes.NewBuffer(test.buf[0:test.max])
_, err = txLocBlock.DeserializeTxLoc(br)
if !errors.Is(err, test.readErr) {
t.Errorf("DeserializeTxLoc #%d wrong error got: %v, want: %v",
i, err, test.readErr)
continue
}
}
}
// TestBlockOverflowErrors performs tests to ensure deserializing blocks which
// are intentionally crafted to use large values for the number of transactions
// are handled properly. This could otherwise potentially be used as an attack
// vector.
func TestBlockOverflowErrors(t *testing.T) {
pver := ProtocolVersion
tests := []struct {
buf []byte // Encoded value
pver uint32 // Protocol version for appmessage encoding
err error // Expected error
}{
// Block that claims to have ~uint64(0) transactions.
{
[]byte{
0x01, 0x00, 0x00, 0x00, // Version 1
0x02, // NumParentBlocks
0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, // mainnetGenesisHash
0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // simnetGenesisHash
0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0,
0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91,
0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68,
0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, // HashMerkleRoot
0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61,
0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32,
0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // AcceptedIDMerkleRoot
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x10, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // UTXOCommitment
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x61, 0xbc, 0x66, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp
0xff, 0xff, 0x00, 0x1d, // Bits
0x01, 0xe3, 0x62, 0x99, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, // TxnCount
}, pver, &MessageError{},
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Decode from appmessage format.
var msg MsgBlock
r := bytes.NewReader(test.buf)
err := msg.KaspaDecode(r, test.pver)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
t.Errorf("KaspaDecode #%d wrong error got: %v, want: %v",
i, err, reflect.TypeOf(test.err))
continue
}
// Deserialize from appmessage format.
r = bytes.NewReader(test.buf)
err = msg.Deserialize(r)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
t.Errorf("Deserialize #%d wrong error got: %v, want: %v",
i, err, reflect.TypeOf(test.err))
continue
}
// Deserialize with transaction location info from appmessage format.
br := bytes.NewBuffer(test.buf)
_, err = msg.DeserializeTxLoc(br)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
t.Errorf("DeserializeTxLoc #%d wrong error got: %v, "+
"want: %v", i, err, reflect.TypeOf(test.err))
continue
}
}
}
// TestBlockSerializeSize performs tests to ensure the serialize size for
// various blocks is accurate.
func TestBlockSerializeSize(t *testing.T) {
// Block with no transactions.
noTxBlock := NewMsgBlock(&blockOne.Header)
tests := []struct {
in *MsgBlock // Block to encode
size int // Expected serialized size
}{
// Block with no transactions.
{noTxBlock, 186},
// First block in the mainnet block DAG.
{&blockOne, len(blockOneBytes)},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
serializedSize := test.in.SerializeSize()
if serializedSize != test.size {
t.Errorf("MsgBlock.SerializeSize: #%d got: %d, want: "+
"%d", i, serializedSize, test.size)
continue
}
}
}
// blockOne is the first block in the mainnet block DAG.
var blockOne = MsgBlock{
Header: BlockHeader{
Version: 1,
ParentHashes: []*daghash.Hash{mainnetGenesisHash, simnetGenesisHash},
HashMerkleRoot: mainnetGenesisMerkleRoot,
AcceptedIDMerkleRoot: exampleAcceptedIDMerkleRoot,
UTXOCommitment: exampleUTXOCommitment,
Timestamp: mstime.UnixMilliseconds(0x17315ed0f99),
Bits: 0x1d00ffff, // 486604799
Nonce: 0x9962e301, // 2573394689
},
Transactions: []*MsgTx{
NewNativeMsgTx(1,
[]*TxIn{
{
PreviousOutpoint: Outpoint{
TxID: daghash.TxID{},
Index: 0xffffffff,
},
SignatureScript: []byte{
0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04,
},
Sequence: math.MaxUint64,
},
},
[]*TxOut{
{
Value: 0x12a05f200,
ScriptPubKey: []byte{
0x41, // OP_DATA_65
0x04, 0x96, 0xb5, 0x38, 0xe8, 0x53, 0x51, 0x9c,
0x72, 0x6a, 0x2c, 0x91, 0xe6, 0x1e, 0xc1, 0x16,
0x00, 0xae, 0x13, 0x90, 0x81, 0x3a, 0x62, 0x7c,
0x66, 0xfb, 0x8b, 0xe7, 0x94, 0x7b, 0xe6, 0x3c,
0x52, 0xda, 0x75, 0x89, 0x37, 0x95, 0x15, 0xd4,
0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6,
0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e,
0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58,
0xee, // 65-byte signature
0xac, // OP_CHECKSIG
},
},
}),
},
}
// Block one serialized bytes.
var blockOneBytes = []byte{
0x01, 0x00, 0x00, 0x00, // Version 1
0x02, // NumParentBlocks
0xdc, 0x5f, 0x5b, 0x5b, 0x1d, 0xc2, 0xa7, 0x25, // mainnetGenesisHash
0x49, 0xd5, 0x1d, 0x4d, 0xee, 0xd7, 0xa4, 0x8b,
0xaf, 0xd3, 0x14, 0x4b, 0x56, 0x78, 0x98, 0xb1,
0x8c, 0xfd, 0x9f, 0x69, 0xdd, 0xcf, 0xbb, 0x63,
0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // simnetGenesisHash
0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0,
0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91,
0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68,
0x4a, 0x5e, 0x1e, 0x4b, 0xaa, 0xb8, 0x9f, 0x3a, // HashMerkleRoot
0x32, 0x51, 0x8a, 0x88, 0xc3, 0x1b, 0xc8, 0x7f,
0x61, 0x8f, 0x76, 0x67, 0x3e, 0x2c, 0xc7, 0x7a,
0xb2, 0x12, 0x7b, 0x7a, 0xfd, 0xed, 0xa3, 0x3b,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // AcceptedIDMerkleRoot
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x10, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // UTXOCommitment
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x99, 0x0f, 0xed, 0x15, 0x73, 0x01, 0x00, 0x00, // Timestamp
0xff, 0xff, 0x00, 0x1d, // Bits
0x01, 0xe3, 0x62, 0x99, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce
0x01, // TxnCount
0x01, 0x00, 0x00, 0x00, // Version
0x01, // Varint for number of transaction inputs
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash
0xff, 0xff, 0xff, 0xff, // Prevous output index
0x07, // Varint for length of signature script
0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, // Signature script (coinbase)
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Sequence
0x01, // Varint for number of transaction outputs
0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount
0x43, // Varint for length of scriptPubKey
0x41, // OP_DATA_65
0x04, 0x96, 0xb5, 0x38, 0xe8, 0x53, 0x51, 0x9c,
0x72, 0x6a, 0x2c, 0x91, 0xe6, 0x1e, 0xc1, 0x16,
0x00, 0xae, 0x13, 0x90, 0x81, 0x3a, 0x62, 0x7c,
0x66, 0xfb, 0x8b, 0xe7, 0x94, 0x7b, 0xe6, 0x3c,
0x52, 0xda, 0x75, 0x89, 0x37, 0x95, 0x15, 0xd4,
0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6,
0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e,
0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58,
0xee, // 65-byte uncompressed public key
0xac, // OP_CHECKSIG
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // SubnetworkID
}
// Transaction location information for block one transactions.
var blockOneTxLocs = []TxLoc{
{TxStart: 186, TxLen: 162},
}

View File

@@ -1,22 +0,0 @@
package appmessage
// MsgDoneIBDBlocks implements the Message interface and represents a kaspa
// DoneIBDBlocks message. It is used to notify the IBD syncing peer that the
// syncer sent all the requested blocks.
//
// This message has no payload.
type MsgDoneIBDBlocks struct {
baseMessage
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgDoneIBDBlocks) Command() MessageCommand {
return CmdDoneIBDBlocks
}
// NewMsgDoneIBDBlocks returns a new kaspa DoneIBDBlocks message that conforms to the
// Message interface.
func NewMsgDoneIBDBlocks() *MsgDoneIBDBlocks {
return &MsgDoneIBDBlocks{}
}

View File

@@ -1,118 +0,0 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"bytes"
"reflect"
"testing"
"github.com/davecgh/go-spew/spew"
)
// TestIBDBlock tests the MsgIBDBlock API.
func TestIBDBlock(t *testing.T) {
pver := ProtocolVersion
// Block 1 header.
parentHashes := blockOne.Header.ParentHashes
hashMerkleRoot := blockOne.Header.HashMerkleRoot
acceptedIDMerkleRoot := blockOne.Header.AcceptedIDMerkleRoot
utxoCommitment := blockOne.Header.UTXOCommitment
bits := blockOne.Header.Bits
nonce := blockOne.Header.Nonce
bh := NewBlockHeader(1, parentHashes, hashMerkleRoot, acceptedIDMerkleRoot, utxoCommitment, bits, nonce)
// Ensure the command is expected value.
wantCmd := MessageCommand(17)
msg := NewMsgIBDBlock(NewMsgBlock(bh))
if cmd := msg.Command(); cmd != wantCmd {
t.Errorf("NewMsgIBDBlock: wrong command - got %v want %v",
cmd, wantCmd)
}
// Ensure max payload is expected value for latest protocol version.
wantPayload := uint32(1024 * 1024 * 32)
maxPayload := msg.MaxPayloadLength(pver)
if maxPayload != wantPayload {
t.Errorf("MaxPayloadLength: wrong max payload length for "+
"protocol version %d - got %v, want %v", pver,
maxPayload, wantPayload)
}
// Ensure we get the same block header data back out.
if !reflect.DeepEqual(&msg.Header, bh) {
t.Errorf("NewMsgIBDBlock: wrong block header - got %v, want %v",
spew.Sdump(&msg.Header), spew.Sdump(bh))
}
// Ensure transactions are added properly.
tx := blockOne.Transactions[0].Copy()
msg.AddTransaction(tx)
if !reflect.DeepEqual(msg.Transactions, blockOne.Transactions) {
t.Errorf("AddTransaction: wrong transactions - got %v, want %v",
spew.Sdump(msg.Transactions),
spew.Sdump(blockOne.Transactions))
}
// Ensure transactions are properly cleared.
msg.ClearTransactions()
if len(msg.Transactions) != 0 {
t.Errorf("ClearTransactions: wrong transactions - got %v, want %v",
len(msg.Transactions), 0)
}
}
// TestIBDBlockEncoding tests the MsgIBDBlock appmessage encode and decode for various numbers
// of transaction inputs and outputs and protocol versions.
func TestIBDBlockEncoding(t *testing.T) {
tests := []struct {
in *MsgIBDBlock // Message to encode
out *MsgIBDBlock // Expected decoded message
buf []byte // Encoded value
txLocs []TxLoc // Expected transaction locations
pver uint32 // Protocol version for appmessage encoding
}{
// Latest protocol version.
{
&MsgIBDBlock{MsgBlock: &blockOne},
&MsgIBDBlock{MsgBlock: &blockOne},
blockOneBytes,
blockOneTxLocs,
ProtocolVersion,
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode the message to appmessage format.
var buf bytes.Buffer
err := test.in.KaspaEncode(&buf, test.pver)
if err != nil {
t.Errorf("KaspaEncode #%d error %v", i, err)
continue
}
if !bytes.Equal(buf.Bytes(), test.buf) {
t.Errorf("KaspaEncode #%d\n got: %s want: %s", i,
spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
continue
}
// Decode the message from appmessage format.
var msg MsgIBDBlock
msg.MsgBlock = new(MsgBlock)
rbuf := bytes.NewReader(test.buf)
err = msg.KaspaDecode(rbuf, test.pver)
if err != nil {
t.Errorf("KaspaDecode #%d error %v", i, err)
continue
}
if !reflect.DeepEqual(&msg, test.out) {
t.Errorf("KaspaDecode #%d\n got: %s want: %s", i,
spew.Sdump(&msg), spew.Sdump(test.out))
continue
}
}
}

View File

@@ -1,34 +0,0 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"
)
// MsgRequestIBDBlocks implements the Message interface and represents a kaspa
// RequestIBDBlocks message. It is used to request a list of blocks starting after the
// low hash and until the high hash.
type MsgRequestIBDBlocks struct {
baseMessage
LowHash *daghash.Hash
HighHash *daghash.Hash
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgRequestIBDBlocks) Command() MessageCommand {
return CmdRequestIBDBlocks
}
// NewMsgRequstIBDBlocks returns a new kaspa RequestIBDBlocks message that conforms to the
// Message interface using the passed parameters and defaults for the remaining
// fields.
func NewMsgRequstIBDBlocks(lowHash, highHash *daghash.Hash) *MsgRequestIBDBlocks {
return &MsgRequestIBDBlocks{
LowHash: lowHash,
HighHash: highHash,
}
}

View File

@@ -1,22 +0,0 @@
package appmessage
// MsgRequestNextIBDBlocks implements the Message interface and represents a kaspa
// RequestNextIBDBlocks message. It is used to notify the IBD syncer peer to send
// more blocks.
//
// This message has no payload.
type MsgRequestNextIBDBlocks struct {
baseMessage
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgRequestNextIBDBlocks) Command() MessageCommand {
return CmdRequestNextIBDBlocks
}
// NewMsgRequestNextIBDBlocks returns a new kaspa RequestNextIBDBlocks message that conforms to the
// Message interface.
func NewMsgRequestNextIBDBlocks() *MsgRequestNextIBDBlocks {
return &MsgRequestNextIBDBlocks{}
}

View File

@@ -1,21 +0,0 @@
package appmessage
// MsgRequestSelectedTip implements the Message interface and represents a kaspa
// RequestSelectedTip message. It is used to request the selected tip of another peer.
//
// This message has no payload.
type MsgRequestSelectedTip struct {
baseMessage
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgRequestSelectedTip) Command() MessageCommand {
return CmdRequestSelectedTip
}
// NewMsgRequestSelectedTip returns a new kaspa RequestSelectedTip message that conforms to the
// Message interface.
func NewMsgRequestSelectedTip() *MsgRequestSelectedTip {
return &MsgRequestSelectedTip{}
}

View File

@@ -1,20 +0,0 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"testing"
)
// TestRequestSelectedTip tests the MsgRequestSelectedTip API.
func TestRequestSelectedTip(t *testing.T) {
// Ensure the command is expected value.
wantCmd := MessageCommand(12)
msg := NewMsgRequestSelectedTip()
if cmd := msg.Command(); cmd != wantCmd {
t.Errorf("NewMsgRequestSelectedTip: wrong command - got %v want %v",
cmd, wantCmd)
}
}

View File

@@ -1,28 +0,0 @@
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"
)
// MsgSelectedTip implements the Message interface and represents a kaspa
// selectedtip message. It is used to answer getseltip messages and tell
// the asking peer what is the selected tip of this peer.
type MsgSelectedTip struct {
baseMessage
// The selected tip hash of the generator of the message.
SelectedTipHash *daghash.Hash
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgSelectedTip) Command() MessageCommand {
return CmdSelectedTip
}
// NewMsgSelectedTip returns a new kaspa selectedtip message that conforms to the
// Message interface.
func NewMsgSelectedTip(selectedTipHash *daghash.Hash) *MsgSelectedTip {
return &MsgSelectedTip{
SelectedTipHash: selectedTipHash,
}
}

View File

@@ -1,18 +0,0 @@
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"
"testing"
)
// TestSelectedTip tests the MsgSelectedTip API.
func TestSelectedTip(t *testing.T) {
// Ensure the command is expected value.
wantCmd := MessageCommand(11)
msg := NewMsgSelectedTip(&daghash.ZeroHash)
if cmd := msg.Command(); cmd != wantCmd {
t.Errorf("NewMsgSelectedTip: wrong command - got %v want %v",
cmd, wantCmd)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,942 +0,0 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"bytes"
"fmt"
"github.com/pkg/errors"
"io"
"math"
"reflect"
"testing"
"unsafe"
"github.com/davecgh/go-spew/spew"
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/util/subnetworkid"
)
// TestTx tests the MsgTx API.
func TestTx(t *testing.T) {
pver := ProtocolVersion
txIDStr := "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
txID, err := daghash.NewTxIDFromStr(txIDStr)
if err != nil {
t.Errorf("NewTxIDFromStr: %v", err)
}
// Ensure the command is expected value.
wantCmd := MessageCommand(6)
msg := NewNativeMsgTx(1, nil, nil)
if cmd := msg.Command(); cmd != wantCmd {
t.Errorf("NewMsgAddresses: wrong command - got %v want %v",
cmd, wantCmd)
}
// Ensure max payload is expected value for latest protocol version.
wantPayload := uint32(1024 * 1024 * 32)
maxPayload := msg.MaxPayloadLength(pver)
if maxPayload != wantPayload {
t.Errorf("MaxPayloadLength: wrong max payload length for "+
"protocol version %d - got %v, want %v", pver,
maxPayload, wantPayload)
}
// Ensure we get the same transaction outpoint data back out.
// NOTE: This is a block hash and made up index, but we're only
// testing package functionality.
prevOutIndex := uint32(1)
prevOut := NewOutpoint(txID, prevOutIndex)
if !prevOut.TxID.IsEqual(txID) {
t.Errorf("NewOutpoint: wrong ID - got %v, want %v",
spew.Sprint(&prevOut.TxID), spew.Sprint(txID))
}
if prevOut.Index != prevOutIndex {
t.Errorf("NewOutpoint: wrong index - got %v, want %v",
prevOut.Index, prevOutIndex)
}
prevOutStr := fmt.Sprintf("%s:%d", txID.String(), prevOutIndex)
if s := prevOut.String(); s != prevOutStr {
t.Errorf("Outpoint.String: unexpected result - got %v, "+
"want %v", s, prevOutStr)
}
// Ensure we get the same transaction input back out.
sigScript := []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62}
txIn := NewTxIn(prevOut, sigScript)
if !reflect.DeepEqual(&txIn.PreviousOutpoint, prevOut) {
t.Errorf("NewTxIn: wrong prev outpoint - got %v, want %v",
spew.Sprint(&txIn.PreviousOutpoint),
spew.Sprint(prevOut))
}
if !bytes.Equal(txIn.SignatureScript, sigScript) {
t.Errorf("NewTxIn: wrong signature script - got %v, want %v",
spew.Sdump(txIn.SignatureScript),
spew.Sdump(sigScript))
}
// Ensure we get the same transaction output back out.
txValue := uint64(5000000000)
scriptPubKey := []byte{
0x41, // OP_DATA_65
0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5,
0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42,
0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1,
0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24,
0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97,
0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78,
0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20,
0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63,
0xa6, // 65-byte signature
0xac, // OP_CHECKSIG
}
txOut := NewTxOut(txValue, scriptPubKey)
if txOut.Value != txValue {
t.Errorf("NewTxOut: wrong scriptPubKey - got %v, want %v",
txOut.Value, txValue)
}
if !bytes.Equal(txOut.ScriptPubKey, scriptPubKey) {
t.Errorf("NewTxOut: wrong scriptPubKey - got %v, want %v",
spew.Sdump(txOut.ScriptPubKey),
spew.Sdump(scriptPubKey))
}
// Ensure transaction inputs are added properly.
msg.AddTxIn(txIn)
if !reflect.DeepEqual(msg.TxIn[0], txIn) {
t.Errorf("AddTxIn: wrong transaction input added - got %v, want %v",
spew.Sprint(msg.TxIn[0]), spew.Sprint(txIn))
}
// Ensure transaction outputs are added properly.
msg.AddTxOut(txOut)
if !reflect.DeepEqual(msg.TxOut[0], txOut) {
t.Errorf("AddTxIn: wrong transaction output added - got %v, want %v",
spew.Sprint(msg.TxOut[0]), spew.Sprint(txOut))
}
// Ensure the copy produced an identical transaction message.
newMsg := msg.Copy()
if !reflect.DeepEqual(newMsg, msg) {
t.Errorf("Copy: mismatched tx messages - got %v, want %v",
spew.Sdump(newMsg), spew.Sdump(msg))
}
}
// TestTxHash tests the ability to generate the hash of a transaction accurately.
func TestTxHashAndID(t *testing.T) {
txID1Str := "edca872f27279674c7a52192b32fd68b8b8be714bfea52d98b2c3c86c30e85c6"
wantTxID1, err := daghash.NewTxIDFromStr(txID1Str)
if err != nil {
t.Errorf("NewTxIDFromStr: %v", err)
return
}
// A coinbase transaction
txIn := &TxIn{
PreviousOutpoint: Outpoint{
TxID: daghash.TxID{},
Index: math.MaxUint32,
},
SignatureScript: []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62},
Sequence: math.MaxUint64,
}
txOut := &TxOut{
Value: 5000000000,
ScriptPubKey: []byte{
0x41, // OP_DATA_65
0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5,
0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42,
0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1,
0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24,
0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97,
0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78,
0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20,
0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63,
0xa6, // 65-byte signature
0xac, // OP_CHECKSIG
},
}
tx1 := NewSubnetworkMsgTx(1, []*TxIn{txIn}, []*TxOut{txOut}, subnetworkid.SubnetworkIDCoinbase, 0, nil)
// Ensure the hash produced is expected.
tx1Hash := tx1.TxHash()
if !tx1Hash.IsEqual((*daghash.Hash)(wantTxID1)) {
t.Errorf("TxHash: wrong hash - got %v, want %v",
spew.Sprint(tx1Hash), spew.Sprint(wantTxID1))
}
// Ensure the TxID for coinbase transaction is the same as TxHash.
tx1ID := tx1.TxID()
if !tx1ID.IsEqual(wantTxID1) {
t.Errorf("TxID: wrong ID - got %v, want %v",
spew.Sprint(tx1ID), spew.Sprint(wantTxID1))
}
hash2Str := "b11924b7eeffea821522222576c53dc5b8ddd97602f81e5e124d2626646d74ca"
wantHash2, err := daghash.NewHashFromStr(hash2Str)
if err != nil {
t.Errorf("NewTxIDFromStr: %v", err)
return
}
id2Str := "750499ae9e6d44961ef8bad8af27a44dd4bcbea166b71baf181e8d3997e1ff72"
wantID2, err := daghash.NewTxIDFromStr(id2Str)
if err != nil {
t.Errorf("NewTxIDFromStr: %v", err)
return
}
payload := []byte{1, 2, 3}
txIns := []*TxIn{{
PreviousOutpoint: Outpoint{
Index: 0,
TxID: daghash.TxID{1, 2, 3},
},
SignatureScript: []byte{
0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xDA, 0x0D, 0xC6, 0xAE, 0xCE, 0xFE, 0x1E, 0x06, 0xEF, 0xDF,
0x05, 0x77, 0x37, 0x57, 0xDE, 0xB1, 0x68, 0x82, 0x09, 0x30, 0xE3, 0xB0, 0xD0, 0x3F, 0x46, 0xF5,
0xFC, 0xF1, 0x50, 0xBF, 0x99, 0x0C, 0x02, 0x21, 0x00, 0xD2, 0x5B, 0x5C, 0x87, 0x04, 0x00, 0x76,
0xE4, 0xF2, 0x53, 0xF8, 0x26, 0x2E, 0x76, 0x3E, 0x2D, 0xD5, 0x1E, 0x7F, 0xF0, 0xBE, 0x15, 0x77,
0x27, 0xC4, 0xBC, 0x42, 0x80, 0x7F, 0x17, 0xBD, 0x39, 0x01, 0x41, 0x04, 0xE6, 0xC2, 0x6E, 0xF6,
0x7D, 0xC6, 0x10, 0xD2, 0xCD, 0x19, 0x24, 0x84, 0x78, 0x9A, 0x6C, 0xF9, 0xAE, 0xA9, 0x93, 0x0B,
0x94, 0x4B, 0x7E, 0x2D, 0xB5, 0x34, 0x2B, 0x9D, 0x9E, 0x5B, 0x9F, 0xF7, 0x9A, 0xFF, 0x9A, 0x2E,
0xE1, 0x97, 0x8D, 0xD7, 0xFD, 0x01, 0xDF, 0xC5, 0x22, 0xEE, 0x02, 0x28, 0x3D, 0x3B, 0x06, 0xA9,
0xD0, 0x3A, 0xCF, 0x80, 0x96, 0x96, 0x8D, 0x7D, 0xBB, 0x0F, 0x91, 0x78,
},
Sequence: math.MaxUint64,
}}
txOuts := []*TxOut{
{
Value: 244623243,
ScriptPubKey: []byte{
0x76, 0xA9, 0x14, 0xBA, 0xDE, 0xEC, 0xFD, 0xEF, 0x05, 0x07, 0x24, 0x7F, 0xC8, 0xF7, 0x42, 0x41,
0xD7, 0x3B, 0xC0, 0x39, 0x97, 0x2D, 0x7B, 0x88, 0xAC,
},
},
{
Value: 44602432,
ScriptPubKey: []byte{
0x76, 0xA9, 0x14, 0xC1, 0x09, 0x32, 0x48, 0x3F, 0xEC, 0x93, 0xED, 0x51, 0xF5, 0xFE, 0x95, 0xE7,
0x25, 0x59, 0xF2, 0xCC, 0x70, 0x43, 0xF9, 0x88, 0xAC,
},
},
}
tx2 := NewSubnetworkMsgTx(1, txIns, txOuts, &subnetworkid.SubnetworkID{1, 2, 3}, 0, payload)
// Ensure the hash produced is expected.
tx2Hash := tx2.TxHash()
if !tx2Hash.IsEqual(wantHash2) {
t.Errorf("TxHash: wrong hash - got %v, want %v",
spew.Sprint(tx2Hash), spew.Sprint(wantHash2))
}
// Ensure the TxID for coinbase transaction is the same as TxHash.
tx2ID := tx2.TxID()
if !tx2ID.IsEqual(wantID2) {
t.Errorf("TxID: wrong ID - got %v, want %v",
spew.Sprint(tx2ID), spew.Sprint(wantID2))
}
if tx2ID.IsEqual((*daghash.TxID)(tx2Hash)) {
t.Errorf("tx2ID and tx2Hash shouldn't be the same for non-coinbase transaction with signature and/or payload")
}
tx2.TxIn[0].SignatureScript = []byte{}
newTx2Hash := tx2.TxHash()
if !tx2ID.IsEqual((*daghash.TxID)(newTx2Hash)) {
t.Errorf("tx2ID and newTx2Hash should be the same for transaction with an empty signature")
}
}
// TestTxEncoding tests the MsgTx appmessage encode and decode for various numbers
// of transaction inputs and outputs and protocol versions.
func TestTxEncoding(t *testing.T) {
// Empty tx message.
noTx := NewNativeMsgTx(1, nil, nil)
noTxEncoded := []byte{
0x01, 0x00, 0x00, 0x00, // Version
0x00, // Varint for number of input transactions
0x00, // Varint for number of output transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // Sub Network ID
}
tests := []struct {
in *MsgTx // Message to encode
out *MsgTx // Expected decoded message
buf []byte // Encoded value
pver uint32 // Protocol version for appmessage encoding
}{
// Latest protocol version with no transactions.
{
noTx,
noTx,
noTxEncoded,
ProtocolVersion,
},
// Latest protocol version with multiple transactions.
{
multiTx,
multiTx,
multiTxEncoded,
ProtocolVersion,
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode the message to appmessage format.
var buf bytes.Buffer
err := test.in.KaspaEncode(&buf, test.pver)
if err != nil {
t.Errorf("KaspaEncode #%d error %v", i, err)
continue
}
if !bytes.Equal(buf.Bytes(), test.buf) {
t.Errorf("KaspaEncode #%d\n got: %s want: %s", i,
spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
continue
}
// Decode the message from appmessage format.
var msg MsgTx
rbuf := bytes.NewReader(test.buf)
err = msg.KaspaDecode(rbuf, test.pver)
if err != nil {
t.Errorf("KaspaDecode #%d error %v", i, err)
continue
}
if !reflect.DeepEqual(&msg, test.out) {
t.Errorf("KaspaDecode #%d\n got: %s want: %s", i,
spew.Sdump(&msg), spew.Sdump(test.out))
continue
}
}
}
// TestTxEncodingErrors performs negative tests against appmessage encode and decode
// of MsgTx to confirm error paths work correctly.
func TestTxEncodingErrors(t *testing.T) {
pver := ProtocolVersion
tests := []struct {
in *MsgTx // Value to encode
buf []byte // Encoded value
pver uint32 // Protocol version for appmessage encoding
max int // Max size of fixed buffer to induce errors
writeErr error // Expected write error
readErr error // Expected read error
}{
// Force error in version.
{multiTx, multiTxEncoded, pver, 0, io.ErrShortWrite, io.EOF},
// Force error in number of transaction inputs.
{multiTx, multiTxEncoded, pver, 4, io.ErrShortWrite, io.EOF},
// Force error in transaction input previous block hash.
{multiTx, multiTxEncoded, pver, 5, io.ErrShortWrite, io.EOF},
// Force error in transaction input previous block output index.
{multiTx, multiTxEncoded, pver, 37, io.ErrShortWrite, io.EOF},
// Force error in transaction input signature script length.
{multiTx, multiTxEncoded, pver, 41, io.ErrShortWrite, io.EOF},
// Force error in transaction input signature script.
{multiTx, multiTxEncoded, pver, 42, io.ErrShortWrite, io.EOF},
// Force error in transaction input sequence.
{multiTx, multiTxEncoded, pver, 49, io.ErrShortWrite, io.EOF},
// Force error in number of transaction outputs.
{multiTx, multiTxEncoded, pver, 57, io.ErrShortWrite, io.EOF},
// Force error in transaction output value.
{multiTx, multiTxEncoded, pver, 58, io.ErrShortWrite, io.EOF},
// Force error in transaction output scriptPubKey length.
{multiTx, multiTxEncoded, pver, 66, io.ErrShortWrite, io.EOF},
// Force error in transaction output scriptPubKey.
{multiTx, multiTxEncoded, pver, 67, io.ErrShortWrite, io.EOF},
// Force error in transaction output lock time.
{multiTx, multiTxEncoded, pver, 210, io.ErrShortWrite, io.EOF},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to appmessage format.
w := newFixedWriter(test.max)
err := test.in.KaspaEncode(w, test.pver)
if !errors.Is(err, test.writeErr) {
t.Errorf("KaspaEncode #%d wrong error got: %v, want: %v",
i, err, test.writeErr)
continue
}
// Decode from appmessage format.
var msg MsgTx
r := newFixedReader(test.max, test.buf)
err = msg.KaspaDecode(r, test.pver)
if !errors.Is(err, test.readErr) {
t.Errorf("KaspaDecode #%d wrong error got: %v, want: %v",
i, err, test.readErr)
continue
}
}
}
// TestTxSerialize tests MsgTx serialize and deserialize.
func TestTxSerialize(t *testing.T) {
noTx := NewNativeMsgTx(1, nil, nil)
noTxEncoded := []byte{
0x01, 0x00, 0x00, 0x00, // Version
0x00, // Varint for number of input transactions
0x00, // Varint for number of output transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // Sub Network ID
}
registryTx := NewRegistryMsgTx(1, nil, nil, 16)
registryTxEncoded := []byte{
0x01, 0x00, 0x00, 0x00, // Version
0x00, // Varint for number of input transactions
0x00, // Varint for number of output transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // Sub Network ID
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Gas
0x77, 0x56, 0x36, 0xb4, 0x89, 0x32, 0xe9, 0xa8,
0xbb, 0x67, 0xe6, 0x54, 0x84, 0x36, 0x93, 0x8d,
0x9f, 0xc5, 0x62, 0x49, 0x79, 0x5c, 0x0d, 0x0a,
0x86, 0xaf, 0x7c, 0x5d, 0x54, 0x45, 0x4c, 0x4b, // Payload hash
0x08, // Payload length varint
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Payload / Gas limit
}
subnetworkTx := NewSubnetworkMsgTx(1, nil, nil, &subnetworkid.SubnetworkID{0xff}, 5, []byte{0, 1, 2})
subnetworkTxEncoded := []byte{
0x01, 0x00, 0x00, 0x00, // Version
0x00, // Varint for number of input transactions
0x00, // Varint for number of output transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // Sub Network ID
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Gas
0x35, 0xf9, 0xf2, 0x93, 0x0e, 0xa3, 0x44, 0x61,
0x88, 0x22, 0x79, 0x5e, 0xee, 0xc5, 0x68, 0xae,
0x67, 0xab, 0x29, 0x87, 0xd8, 0xb1, 0x9e, 0x45,
0x91, 0xe1, 0x05, 0x27, 0xba, 0xa1, 0xdf, 0x3d, // Payload hash
0x03, // Payload length varint
0x00, 0x01, 0x02, // Payload
}
tests := []struct {
name string
in *MsgTx // Message to encode
out *MsgTx // Expected decoded message
buf []byte // Serialized data
scriptPubKeyLocs []int // Expected output script locations
}{
// No transactions.
{
"noTx",
noTx,
noTx,
noTxEncoded,
nil,
},
// Registry Transaction.
{
"registryTx",
registryTx,
registryTx,
registryTxEncoded,
nil,
},
// Sub Network Transaction.
{
"subnetworkTx",
subnetworkTx,
subnetworkTx,
subnetworkTxEncoded,
nil,
},
// Multiple transactions.
{
"multiTx",
multiTx,
multiTx,
multiTxEncoded,
multiTxScriptPubKeyLocs,
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Serialize the transaction.
var buf bytes.Buffer
err := test.in.Serialize(&buf)
if err != nil {
t.Errorf("Serialize %s: error %v", test.name, err)
continue
}
if !bytes.Equal(buf.Bytes(), test.buf) {
t.Errorf("Serialize %s:\n got: %s want: %s", test.name,
spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
continue
}
// Deserialize the transaction.
var tx MsgTx
rbuf := bytes.NewReader(test.buf)
err = tx.Deserialize(rbuf)
if err != nil {
t.Errorf("Deserialize #%d error %v", i, err)
continue
}
if !reflect.DeepEqual(&tx, test.out) {
t.Errorf("Deserialize #%d\n got: %s want: %s", i,
spew.Sdump(&tx), spew.Sdump(test.out))
continue
}
// Ensure the public key script locations are accurate.
scriptPubKeyLocs := test.in.ScriptPubKeyLocs()
if !reflect.DeepEqual(scriptPubKeyLocs, test.scriptPubKeyLocs) {
t.Errorf("ScriptPubKeyLocs #%d\n got: %s want: %s", i,
spew.Sdump(scriptPubKeyLocs),
spew.Sdump(test.scriptPubKeyLocs))
continue
}
for j, loc := range scriptPubKeyLocs {
wantScriptPubKey := test.in.TxOut[j].ScriptPubKey
gotScriptPubKey := test.buf[loc : loc+len(wantScriptPubKey)]
if !bytes.Equal(gotScriptPubKey, wantScriptPubKey) {
t.Errorf("ScriptPubKeyLocs #%d:%d\n unexpected "+
"script got: %s want: %s", i, j,
spew.Sdump(gotScriptPubKey),
spew.Sdump(wantScriptPubKey))
}
}
}
}
// TestTxSerializeErrors performs negative tests against appmessage encode and decode
// of MsgTx to confirm error paths work correctly.
func TestTxSerializeErrors(t *testing.T) {
tests := []struct {
in *MsgTx // Value to encode
buf []byte // Serialized data
max int // Max size of fixed buffer to induce errors
writeErr error // Expected write error
readErr error // Expected read error
}{
// Force error in version.
{multiTx, multiTxEncoded, 0, io.ErrShortWrite, io.EOF},
// Force error in number of transaction inputs.
{multiTx, multiTxEncoded, 4, io.ErrShortWrite, io.EOF},
// Force error in transaction input previous block hash.
{multiTx, multiTxEncoded, 5, io.ErrShortWrite, io.EOF},
// Force error in transaction input previous block output index.
{multiTx, multiTxEncoded, 37, io.ErrShortWrite, io.EOF},
// Force error in transaction input signature script length.
{multiTx, multiTxEncoded, 41, io.ErrShortWrite, io.EOF},
// Force error in transaction input signature script.
{multiTx, multiTxEncoded, 42, io.ErrShortWrite, io.EOF},
// Force error in transaction input sequence.
{multiTx, multiTxEncoded, 49, io.ErrShortWrite, io.EOF},
// Force error in number of transaction outputs.
{multiTx, multiTxEncoded, 57, io.ErrShortWrite, io.EOF},
// Force error in transaction output value.
{multiTx, multiTxEncoded, 58, io.ErrShortWrite, io.EOF},
// Force error in transaction output scriptPubKey length.
{multiTx, multiTxEncoded, 66, io.ErrShortWrite, io.EOF},
// Force error in transaction output scriptPubKey.
{multiTx, multiTxEncoded, 67, io.ErrShortWrite, io.EOF},
// Force error in transaction output lock time.
{multiTx, multiTxEncoded, 210, io.ErrShortWrite, io.EOF},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Serialize the transaction.
w := newFixedWriter(test.max)
err := test.in.Serialize(w)
if !errors.Is(err, test.writeErr) {
t.Errorf("Serialize #%d wrong error got: %v, want: %v",
i, err, test.writeErr)
continue
}
// Deserialize the transaction.
var tx MsgTx
r := newFixedReader(test.max, test.buf)
err = tx.Deserialize(r)
if !errors.Is(err, test.readErr) {
t.Errorf("Deserialize #%d wrong error got: %v, want: %v",
i, err, test.readErr)
continue
}
}
registryTx := NewSubnetworkMsgTx(1, nil, nil, subnetworkid.SubnetworkIDRegistry, 1, nil)
w := bytes.NewBuffer(make([]byte, 0, registryTx.SerializeSize()))
err := registryTx.Serialize(w)
str := "Transactions from built-in should have 0 gas"
expectedErr := messageError("MsgTx.KaspaEncode", str)
if err == nil || err.Error() != expectedErr.Error() {
t.Errorf("TestTxSerializeErrors: expected error %v but got %v", expectedErr, err)
}
nativeTx := NewSubnetworkMsgTx(1, nil, nil, subnetworkid.SubnetworkIDNative, 1, nil)
w = bytes.NewBuffer(make([]byte, 0, registryTx.SerializeSize()))
err = nativeTx.Serialize(w)
str = "Transactions from native subnetwork should have 0 gas"
expectedErr = messageError("MsgTx.KaspaEncode", str)
if err == nil || err.Error() != expectedErr.Error() {
t.Errorf("TestTxSerializeErrors: expected error %v but got %v", expectedErr, err)
}
nativeTx.Gas = 0
nativeTx.Payload = []byte{1, 2, 3}
nativeTx.PayloadHash = daghash.DoubleHashP(nativeTx.Payload)
w = bytes.NewBuffer(make([]byte, 0, registryTx.SerializeSize()))
err = nativeTx.Serialize(w)
str = "Transactions from native subnetwork should have <nil> payload"
expectedErr = messageError("MsgTx.KaspaEncode", str)
if err == nil || err.Error() != expectedErr.Error() {
t.Errorf("TestTxSerializeErrors: expected error %v but got %v", expectedErr, err)
}
}
// TestTxOverflowErrors performs tests to ensure deserializing transactions
// which are intentionally crafted to use large values for the variable number
// of inputs and outputs are handled properly. This could otherwise potentially
// be used as an attack vector.
func TestTxOverflowErrors(t *testing.T) {
pver := ProtocolVersion
txVer := uint32(1)
tests := []struct {
buf []byte // Encoded value
pver uint32 // Protocol version for appmessage encoding
version uint32 // Transaction version
err error // Expected error
}{
// Transaction that claims to have ~uint64(0) inputs.
{
[]byte{
0x00, 0x00, 0x00, 0x01, // Version
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, // Varint for number of input transactions
}, pver, txVer, &MessageError{},
},
// Transaction that claims to have ~uint64(0) outputs.
{
[]byte{
0x00, 0x00, 0x00, 0x01, // Version
0x00, // Varint for number of input transactions
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, // Varint for number of output transactions
}, pver, txVer, &MessageError{},
},
// Transaction that has an input with a signature script that
// claims to have ~uint64(0) length.
{
[]byte{
0x00, 0x00, 0x00, 0x01, // Version
0x01, // Varint for number of input transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash
0xff, 0xff, 0xff, 0xff, // Prevous output index
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, // Varint for length of signature script
}, pver, txVer, &MessageError{},
},
// Transaction that has an output with a public key script
// that claims to have ~uint64(0) length.
{
[]byte{
0x00, 0x00, 0x00, 0x01, // Version
0x01, // Varint for number of input transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash
0xff, 0xff, 0xff, 0xff, // Prevous output index
0x00, // Varint for length of signature script
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Sequence
0x01, // Varint for number of output transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Transaction amount
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, // Varint for length of public key script
}, pver, txVer, &MessageError{},
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Decode from appmessage format.
var msg MsgTx
r := bytes.NewReader(test.buf)
err := msg.KaspaDecode(r, test.pver)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
t.Errorf("KaspaDecode #%d wrong error got: %v, want: %v",
i, err, reflect.TypeOf(test.err))
continue
}
// Decode from appmessage format.
r = bytes.NewReader(test.buf)
err = msg.Deserialize(r)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
t.Errorf("Deserialize #%d wrong error got: %v, want: %v",
i, err, reflect.TypeOf(test.err))
continue
}
}
}
// TestTxSerializeSize performs tests to ensure the serialize size for
// various transactions is accurate.
func TestTxSerializeSize(t *testing.T) {
// Empty tx message.
noTx := NewNativeMsgTx(1, nil, nil)
tests := []struct {
in *MsgTx // Tx to encode
size int // Expected serialized size
}{
// No inputs or outpus.
{noTx, 34},
// Transcaction with an input and an output.
{multiTx, 238},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
serializedSize := test.in.SerializeSize()
if serializedSize != test.size {
t.Errorf("MsgTx.SerializeSize: #%d got: %d, want: %d", i,
serializedSize, test.size)
continue
}
}
}
func TestIsSubnetworkCompatible(t *testing.T) {
testTx := NewSubnetworkMsgTx(1, nil, nil, &subnetworkid.SubnetworkID{123}, 0, []byte{})
tests := []struct {
name string
subnetworkID *subnetworkid.SubnetworkID
expectedResult bool
}{
{
name: "Native subnetwork",
subnetworkID: subnetworkid.SubnetworkIDNative,
expectedResult: true,
},
{
name: "same subnetwork as test tx",
subnetworkID: &subnetworkid.SubnetworkID{123},
expectedResult: true,
},
{
name: "other subnetwork",
subnetworkID: &subnetworkid.SubnetworkID{234},
expectedResult: false,
},
}
for _, test := range tests {
result := testTx.IsSubnetworkCompatible(test.subnetworkID)
if result != test.expectedResult {
t.Errorf("IsSubnetworkCompatible got unexpected result in test '%s': "+
"expected: %t, want: %t", test.name, test.expectedResult, result)
}
}
}
func TestScriptFreeList(t *testing.T) {
var list scriptFreeList = make(chan []byte, freeListMaxItems)
expectedCapacity := 512
expectedLengthFirst := 12
expectedLengthSecond := 13
first := list.Borrow(uint64(expectedLengthFirst))
if cap(first) != expectedCapacity {
t.Errorf("MsgTx.TestScriptFreeList: Expected capacity for first %d, but got %d",
expectedCapacity, cap(first))
}
if len(first) != expectedLengthFirst {
t.Errorf("MsgTx.TestScriptFreeList: Expected length for first %d, but got %d",
expectedLengthFirst, len(first))
}
list.Return(first)
// Borrow again, and check that the underlying array is re-used for second
second := list.Borrow(uint64(expectedLengthSecond))
if cap(second) != expectedCapacity {
t.Errorf("MsgTx.TestScriptFreeList: Expected capacity for second %d, but got %d",
expectedCapacity, cap(second))
}
if len(second) != expectedLengthSecond {
t.Errorf("MsgTx.TestScriptFreeList: Expected length for second %d, but got %d",
expectedLengthSecond, len(second))
}
firstArrayAddress := underlyingArrayAddress(first)
secondArrayAddress := underlyingArrayAddress(second)
if firstArrayAddress != secondArrayAddress {
t.Errorf("First underlying array is at address %d and second at address %d, "+
"which means memory was not re-used", firstArrayAddress, secondArrayAddress)
}
list.Return(second)
// test for buffers bigger than freeListMaxScriptSize
expectedCapacityBig := freeListMaxScriptSize + 1
expectedLengthBig := expectedCapacityBig
big := list.Borrow(uint64(expectedCapacityBig))
if cap(big) != expectedCapacityBig {
t.Errorf("MsgTx.TestScriptFreeList: Expected capacity for second %d, but got %d",
expectedCapacityBig, cap(big))
}
if len(big) != expectedLengthBig {
t.Errorf("MsgTx.TestScriptFreeList: Expected length for second %d, but got %d",
expectedLengthBig, len(big))
}
list.Return(big)
// test there's no crash when channel is full because borrowed too much
buffers := make([][]byte, freeListMaxItems+1)
for i := 0; i < freeListMaxItems+1; i++ {
buffers[i] = list.Borrow(1)
}
for i := 0; i < freeListMaxItems+1; i++ {
list.Return(buffers[i])
}
}
func underlyingArrayAddress(buf []byte) uint64 {
return uint64((*reflect.SliceHeader)(unsafe.Pointer(&buf)).Data)
}
// multiTx is a MsgTx with an input and output and used in various tests.
var multiTxIns = []*TxIn{
{
PreviousOutpoint: Outpoint{
TxID: daghash.TxID{},
Index: 0xffffffff,
},
SignatureScript: []byte{
0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62,
},
Sequence: math.MaxUint64,
},
}
var multiTxOuts = []*TxOut{
{
Value: 0x12a05f200,
ScriptPubKey: []byte{
0x41, // OP_DATA_65
0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5,
0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42,
0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1,
0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24,
0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97,
0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78,
0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20,
0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63,
0xa6, // 65-byte signature
0xac, // OP_CHECKSIG
},
},
{
Value: 0x5f5e100,
ScriptPubKey: []byte{
0x41, // OP_DATA_65
0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5,
0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42,
0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1,
0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24,
0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97,
0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78,
0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20,
0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63,
0xa6, // 65-byte signature
0xac, // OP_CHECKSIG
},
},
}
var multiTx = NewNativeMsgTx(1, multiTxIns, multiTxOuts)
// multiTxEncoded is the appmessage encoded bytes for multiTx using protocol version
// 60002 and is used in the various tests.
var multiTxEncoded = []byte{
0x01, 0x00, 0x00, 0x00, // Version
0x01, // Varint for number of input transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash
0xff, 0xff, 0xff, 0xff, // Prevous output index
0x07, // Varint for length of signature script
0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62, // Signature script
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Sequence
0x02, // Varint for number of output transactions
0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount
0x43, // Varint for length of scriptPubKey
0x41, // OP_DATA_65
0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5,
0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42,
0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1,
0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24,
0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97,
0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78,
0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20,
0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63,
0xa6, // 65-byte signature
0xac, // OP_CHECKSIG
0x00, 0xe1, 0xf5, 0x05, 0x00, 0x00, 0x00, 0x00, // Transaction amount
0x43, // Varint for length of scriptPubKey
0x41, // OP_DATA_65
0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5,
0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42,
0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1,
0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24,
0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97,
0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78,
0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20,
0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63,
0xa6, // 65-byte signature
0xac, // OP_CHECKSIG
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // Sub Network ID
}
// multiTxScriptPubKeyLocs is the location information for the public key scripts
// located in multiTx.
var multiTxScriptPubKeyLocs = []int{67, 143}

View File

@@ -0,0 +1,19 @@
package appmessage
// BlockHeadersMessage represents a kaspa BlockHeaders message
type BlockHeadersMessage struct {
baseMessage
BlockHeaders []*MsgBlockHeader
}
// Command returns the protocol command string for the message
func (msg *BlockHeadersMessage) Command() MessageCommand {
return CmdBlockHeaders
}
// NewBlockHeadersMessage returns a new kaspa BlockHeaders message
func NewBlockHeadersMessage(blockHeaders []*MsgBlockHeader) *BlockHeadersMessage {
return &BlockHeadersMessage{
BlockHeaders: blockHeaders,
}
}

View File

@@ -0,0 +1,30 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
// MaxAddressesPerMsg is the maximum number of addresses that can be in a single
// kaspa Addresses message (MsgAddresses).
const MaxAddressesPerMsg = 1000
// MsgAddresses implements the Message interface and represents a kaspa
// Addresses message.
type MsgAddresses struct {
baseMessage
AddressList []*NetAddress
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgAddresses) Command() MessageCommand {
return CmdAddresses
}
// NewMsgAddresses returns a new kaspa Addresses message that conforms to the
// Message interface. See MsgAddresses for details.
func NewMsgAddresses(addressList []*NetAddress) *MsgAddresses {
return &MsgAddresses{
AddressList: addressList,
}
}

View File

@@ -0,0 +1,74 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// defaultTransactionAlloc is the default size used for the backing array
// for transactions. The transaction array will dynamically grow as needed, but
// this figure is intended to provide enough space for the number of
// transactions in the vast majority of blocks without needing to grow the
// backing array multiple times.
const defaultTransactionAlloc = 2048
// TxLoc holds locator data for the offset and length of where a transaction is
// located within a MsgBlock data buffer.
type TxLoc struct {
TxStart int
TxLen int
}
// MsgBlock implements the Message interface and represents a kaspa
// block message. It is used to deliver block and transaction information in
// response to a getdata message (MsgGetData) for a given block hash.
type MsgBlock struct {
baseMessage
Header MsgBlockHeader
Transactions []*MsgTx
}
// AddTransaction adds a transaction to the message.
func (msg *MsgBlock) AddTransaction(tx *MsgTx) {
msg.Transactions = append(msg.Transactions, tx)
}
// ClearTransactions removes all transactions from the message.
func (msg *MsgBlock) ClearTransactions() {
msg.Transactions = make([]*MsgTx, 0, defaultTransactionAlloc)
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgBlock) Command() MessageCommand {
return CmdBlock
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgBlock) MaxPayloadLength(pver uint32) uint32 {
return MaxMessagePayload
}
// ConvertToPartial clears out all the payloads of the subnetworks that are
// incompatible with the given subnetwork ID.
// Note: this operation modifies the block in place.
func (msg *MsgBlock) ConvertToPartial(subnetworkID *externalapi.DomainSubnetworkID) {
for _, tx := range msg.Transactions {
if !tx.SubnetworkID.Equal(subnetworkID) {
tx.Payload = []byte{}
}
}
}
// NewMsgBlock returns a new kaspa block message that conforms to the
// Message interface. See MsgBlock for details.
func NewMsgBlock(blockHeader *MsgBlockHeader) *MsgBlock {
return &MsgBlock{
Header: *blockHeader,
Transactions: make([]*MsgTx, 0, defaultTransactionAlloc),
}
}

View File

@@ -0,0 +1,245 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"github.com/davecgh/go-spew/spew"
"github.com/kaspanet/kaspad/util/mstime"
"math"
"reflect"
"testing"
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// TestBlock tests the MsgBlock API.
func TestBlock(t *testing.T) {
pver := uint32(4)
// Block 1 header.
parents := blockOne.Header.Parents
hashMerkleRoot := blockOne.Header.HashMerkleRoot
acceptedIDMerkleRoot := blockOne.Header.AcceptedIDMerkleRoot
utxoCommitment := blockOne.Header.UTXOCommitment
bits := blockOne.Header.Bits
nonce := blockOne.Header.Nonce
daaScore := blockOne.Header.DAAScore
blueScore := blockOne.Header.BlueScore
blueWork := blockOne.Header.BlueWork
pruningPoint := blockOne.Header.PruningPoint
bh := NewBlockHeader(1, parents, hashMerkleRoot, acceptedIDMerkleRoot, utxoCommitment, bits, nonce,
daaScore, blueScore, blueWork, pruningPoint)
// Ensure the command is expected value.
wantCmd := MessageCommand(5)
msg := NewMsgBlock(bh)
if cmd := msg.Command(); cmd != wantCmd {
t.Errorf("NewMsgBlock: wrong command - got %v want %v",
cmd, wantCmd)
}
// Ensure max payload is expected value for latest protocol version.
wantPayload := uint32(1024 * 1024 * 32)
maxPayload := msg.MaxPayloadLength(pver)
if maxPayload != wantPayload {
t.Errorf("MaxPayloadLength: wrong max payload length for "+
"protocol version %d - got %v, want %v", pver,
maxPayload, wantPayload)
}
// Ensure we get the same block header data back out.
if !reflect.DeepEqual(&msg.Header, bh) {
t.Errorf("NewMsgBlock: wrong block header - got %v, want %v",
spew.Sdump(&msg.Header), spew.Sdump(bh))
}
// Ensure transactions are added properly.
tx := blockOne.Transactions[0].Copy()
msg.AddTransaction(tx)
if !reflect.DeepEqual(msg.Transactions, blockOne.Transactions) {
t.Errorf("AddTransaction: wrong transactions - got %v, want %v",
spew.Sdump(msg.Transactions),
spew.Sdump(blockOne.Transactions))
}
// Ensure transactions are properly cleared.
msg.ClearTransactions()
if len(msg.Transactions) != 0 {
t.Errorf("ClearTransactions: wrong transactions - got %v, want %v",
len(msg.Transactions), 0)
}
}
func TestConvertToPartial(t *testing.T) {
localSubnetworkID := &externalapi.DomainSubnetworkID{0x12}
transactions := []struct {
subnetworkID *externalapi.DomainSubnetworkID
payload []byte
expectedPayloadLength int
}{
{
subnetworkID: &subnetworks.SubnetworkIDNative,
payload: []byte{},
expectedPayloadLength: 0,
},
{
subnetworkID: &subnetworks.SubnetworkIDRegistry,
payload: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},
expectedPayloadLength: 0,
},
{
subnetworkID: localSubnetworkID,
payload: []byte{0x01},
expectedPayloadLength: 1,
},
{
subnetworkID: &externalapi.DomainSubnetworkID{0x34},
payload: []byte{0x02},
expectedPayloadLength: 0,
},
}
block := MsgBlock{}
payload := []byte{1}
for _, transaction := range transactions {
block.Transactions = append(block.Transactions, NewSubnetworkMsgTx(1, nil, nil, transaction.subnetworkID, 0, payload))
}
block.ConvertToPartial(localSubnetworkID)
for _, testTransaction := range transactions {
var subnetworkTx *MsgTx
for _, blockTransaction := range block.Transactions {
if blockTransaction.SubnetworkID.Equal(testTransaction.subnetworkID) {
subnetworkTx = blockTransaction
}
}
if subnetworkTx == nil {
t.Errorf("ConvertToPartial: subnetworkID '%s' not found in block!", testTransaction.subnetworkID)
continue
}
payloadLength := len(subnetworkTx.Payload)
if payloadLength != testTransaction.expectedPayloadLength {
t.Errorf("ConvertToPartial: unexpected payload length for subnetwork '%s': expected: %d, got: %d",
testTransaction.subnetworkID, testTransaction.expectedPayloadLength, payloadLength)
}
}
}
//blockOne is the first block in the mainnet block DAG.
var blockOne = MsgBlock{
Header: MsgBlockHeader{
Version: 0,
Parents: []externalapi.BlockLevelParents{[]*externalapi.DomainHash{mainnetGenesisHash, simnetGenesisHash}},
HashMerkleRoot: mainnetGenesisMerkleRoot,
AcceptedIDMerkleRoot: exampleAcceptedIDMerkleRoot,
UTXOCommitment: exampleUTXOCommitment,
Timestamp: mstime.UnixMilliseconds(0x17315ed0f99),
Bits: 0x1d00ffff, // 486604799
Nonce: 0x9962e301, // 2573394689
},
Transactions: []*MsgTx{
NewNativeMsgTx(1,
[]*TxIn{
{
PreviousOutpoint: Outpoint{
TxID: externalapi.DomainTransactionID{},
Index: 0xffffffff,
},
SignatureScript: []byte{
0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04,
},
Sequence: math.MaxUint64,
},
},
[]*TxOut{
{
Value: 0x12a05f200,
ScriptPubKey: &externalapi.ScriptPublicKey{
Script: []byte{
0x41, // OP_DATA_65
0x04, 0x96, 0xb5, 0x38, 0xe8, 0x53, 0x51, 0x9c,
0x72, 0x6a, 0x2c, 0x91, 0xe6, 0x1e, 0xc1, 0x16,
0x00, 0xae, 0x13, 0x90, 0x81, 0x3a, 0x62, 0x7c,
0x66, 0xfb, 0x8b, 0xe7, 0x94, 0x7b, 0xe6, 0x3c,
0x52, 0xda, 0x75, 0x89, 0x37, 0x95, 0x15, 0xd4,
0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6,
0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e,
0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58,
0xee, // 65-byte signature
0xac, // OP_CHECKSIG
},
Version: 0},
},
}),
},
}
// Block one serialized bytes.
var blockOneBytes = []byte{
0x00, 0x00, // Version 0
0x02, // NumParentBlocks
0xdc, 0x5f, 0x5b, 0x5b, 0x1d, 0xc2, 0xa7, 0x25, // mainnetGenesisHash
0x49, 0xd5, 0x1d, 0x4d, 0xee, 0xd7, 0xa4, 0x8b,
0xaf, 0xd3, 0x14, 0x4b, 0x56, 0x78, 0x98, 0xb1,
0x8c, 0xfd, 0x9f, 0x69, 0xdd, 0xcf, 0xbb, 0x63,
0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // simnetGenesisHash
0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0,
0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91,
0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68,
0x4a, 0x5e, 0x1e, 0x4b, 0xaa, 0xb8, 0x9f, 0x3a, // HashMerkleRoot
0x32, 0x51, 0x8a, 0x88, 0xc3, 0x1b, 0xc8, 0x7f,
0x61, 0x8f, 0x76, 0x67, 0x3e, 0x2c, 0xc7, 0x7a,
0xb2, 0x12, 0x7b, 0x7a, 0xfd, 0xed, 0xa3, 0x3b,
0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // AcceptedIDMerkleRoot
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x10, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // UTXOCommitment
0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87,
0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63,
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
0x99, 0x0f, 0xed, 0x15, 0x73, 0x01, 0x00, 0x00, // Timestamp
0xff, 0xff, 0x00, 0x1d, // Bits
0x01, 0xe3, 0x62, 0x99, 0x00, 0x00, 0x00, 0x00, // Fake Nonce
0x01, // TxnCount
0x00, 0x00, 0x00, 0x00, // Version
0x01, // Varint for number of transaction inputs
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash
0xff, 0xff, 0xff, 0xff, // Prevous output index
0x07, // Varint for length of signature script
0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, // Signature script (coinbase)
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Sequence
0x01, // Varint for number of transaction outputs
0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount
0x43, // Varint for length of scriptPubKey
0x41, // OP_DATA_65
0x04, 0x96, 0xb5, 0x38, 0xe8, 0x53, 0x51, 0x9c,
0x72, 0x6a, 0x2c, 0x91, 0xe6, 0x1e, 0xc1, 0x16,
0x00, 0xae, 0x13, 0x90, 0x81, 0x3a, 0x62, 0x7c,
0x66, 0xfb, 0x8b, 0xe7, 0x94, 0x7b, 0xe6, 0x3c,
0x52, 0xda, 0x75, 0x89, 0x37, 0x95, 0x15, 0xd4,
0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6,
0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e,
0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58,
0xee, // 65-byte uncompressed public key
0xac, // OP_CHECKSIG
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // SubnetworkID
}
// Transaction location information for block one transactions.
var blockOneTxLocs = []TxLoc{
{TxStart: 186, TxLen: 162},
}

View File

@@ -0,0 +1,102 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"math/big"
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/util/mstime"
)
// BaseBlockHeaderPayload is the base number of bytes a block header can be,
// not including the list of parent block headers.
// Version 4 bytes + Timestamp 8 bytes + Bits 4 bytes + Nonce 8 bytes +
// + NumParentBlocks 1 byte + HashMerkleRoot hash +
// + AcceptedIDMerkleRoot hash + UTXOCommitment hash.
// To get total size of block header len(ParentHashes) * externalapi.DomainHashSize should be
// added to this value
const BaseBlockHeaderPayload = 25 + 3*(externalapi.DomainHashSize)
// MaxNumParentBlocks is the maximum number of parent blocks a block can reference.
// Currently set to 255 as the maximum number NumParentBlocks can be due to it being a byte
const MaxNumParentBlocks = 255
// MaxBlockHeaderPayload is the maximum number of bytes a block header can be.
// BaseBlockHeaderPayload + up to MaxNumParentBlocks hashes of parent blocks
const MaxBlockHeaderPayload = BaseBlockHeaderPayload + (MaxNumParentBlocks * externalapi.DomainHashSize)
// MsgBlockHeader defines information about a block and is used in the kaspa
// block (MsgBlock) and headers (MsgHeader) messages.
type MsgBlockHeader struct {
baseMessage
// Version of the block. This is not the same as the protocol version.
Version uint16
// Parents are the parent block hashes of the block in the DAG per superblock level.
Parents []externalapi.BlockLevelParents
// HashMerkleRoot is the merkle tree reference to hash of all transactions for the block.
HashMerkleRoot *externalapi.DomainHash
// AcceptedIDMerkleRoot is merkle tree reference to hash all transactions
// accepted form the block.Blues
AcceptedIDMerkleRoot *externalapi.DomainHash
// UTXOCommitment is an ECMH UTXO commitment to the block UTXO.
UTXOCommitment *externalapi.DomainHash
// Time the block was created.
Timestamp mstime.Time
// Difficulty target for the block.
Bits uint32
// Nonce used to generate the block.
Nonce uint64
// DAASCore is the DAA score of the block.
DAAScore uint64
BlueScore uint64
// BlueWork is the blue work of the block.
BlueWork *big.Int
PruningPoint *externalapi.DomainHash
}
// BlockHash computes the block identifier hash for the given block header.
func (h *MsgBlockHeader) BlockHash() *externalapi.DomainHash {
return consensushashing.HeaderHash(BlockHeaderToDomainBlockHeader(h))
}
// NewBlockHeader returns a new MsgBlockHeader using the provided version, previous
// block hash, hash merkle root, accepted ID merkle root, difficulty bits, and nonce used to generate the
// block with defaults or calclulated values for the remaining fields.
func NewBlockHeader(version uint16, parents []externalapi.BlockLevelParents, hashMerkleRoot *externalapi.DomainHash,
acceptedIDMerkleRoot *externalapi.DomainHash, utxoCommitment *externalapi.DomainHash, bits uint32, nonce,
daaScore, blueScore uint64, blueWork *big.Int, pruningPoint *externalapi.DomainHash) *MsgBlockHeader {
// Limit the timestamp to one millisecond precision since the protocol
// doesn't support better.
return &MsgBlockHeader{
Version: version,
Parents: parents,
HashMerkleRoot: hashMerkleRoot,
AcceptedIDMerkleRoot: acceptedIDMerkleRoot,
UTXOCommitment: utxoCommitment,
Timestamp: mstime.Now(),
Bits: bits,
Nonce: nonce,
DAAScore: daaScore,
BlueScore: blueScore,
BlueWork: blueWork,
PruningPoint: pruningPoint,
}
}

View File

@@ -0,0 +1,65 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"math/big"
"reflect"
"testing"
"github.com/davecgh/go-spew/spew"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// TestBlockHeader tests the MsgBlockHeader API.
func TestBlockHeader(t *testing.T) {
nonce := uint64(0xba4d87a69924a93d)
parents := []externalapi.BlockLevelParents{[]*externalapi.DomainHash{mainnetGenesisHash, simnetGenesisHash}}
merkleHash := mainnetGenesisMerkleRoot
acceptedIDMerkleRoot := exampleAcceptedIDMerkleRoot
bits := uint32(0x1d00ffff)
daaScore := uint64(123)
blueScore := uint64(456)
blueWork := big.NewInt(789)
pruningPoint := simnetGenesisHash
bh := NewBlockHeader(1, parents, merkleHash, acceptedIDMerkleRoot, exampleUTXOCommitment, bits, nonce,
daaScore, blueScore, blueWork, pruningPoint)
// Ensure we get the same data back out.
if !reflect.DeepEqual(bh.Parents, parents) {
t.Errorf("NewBlockHeader: wrong parents - got %v, want %v",
spew.Sprint(bh.Parents), spew.Sprint(parents))
}
if bh.HashMerkleRoot != merkleHash {
t.Errorf("NewBlockHeader: wrong merkle root - got %v, want %v",
spew.Sprint(bh.HashMerkleRoot), spew.Sprint(merkleHash))
}
if bh.Bits != bits {
t.Errorf("NewBlockHeader: wrong bits - got %v, want %v",
bh.Bits, bits)
}
if bh.Nonce != nonce {
t.Errorf("NewBlockHeader: wrong nonce - got %v, want %v",
bh.Nonce, nonce)
}
if bh.DAAScore != daaScore {
t.Errorf("NewBlockHeader: wrong daaScore - got %v, want %v",
bh.DAAScore, daaScore)
}
if bh.BlueScore != blueScore {
t.Errorf("NewBlockHeader: wrong blueScore - got %v, want %v",
bh.BlueScore, blueScore)
}
if bh.BlueWork != blueWork {
t.Errorf("NewBlockHeader: wrong blueWork - got %v, want %v",
bh.BlueWork, blueWork)
}
if !bh.PruningPoint.Equal(pruningPoint) {
t.Errorf("NewBlockHeader: wrong pruningPoint - got %v, want %v",
bh.PruningPoint, pruningPoint)
}
}

View File

@@ -1,7 +1,7 @@
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MaxBlockLocatorsPerMsg is the maximum number of block locator hashes allowed
@@ -13,7 +13,7 @@ const MaxBlockLocatorsPerMsg = 500
// syncing with you.
type MsgBlockLocator struct {
baseMessage
BlockLocatorHashes []*daghash.Hash
BlockLocatorHashes []*externalapi.DomainHash
}
// Command returns the protocol command string for the message. This is part
@@ -24,7 +24,7 @@ func (msg *MsgBlockLocator) Command() MessageCommand {
// NewMsgBlockLocator returns a new kaspa locator message that conforms to
// the Message interface. See MsgBlockLocator for details.
func NewMsgBlockLocator(locatorHashes []*daghash.Hash) *MsgBlockLocator {
func NewMsgBlockLocator(locatorHashes []*externalapi.DomainHash) *MsgBlockLocator {
return &MsgBlockLocator{
BlockLocatorHashes: locatorHashes,
}

View File

@@ -3,19 +3,20 @@ package appmessage
import (
"testing"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/davecgh/go-spew/spew"
"github.com/kaspanet/kaspad/util/daghash"
)
// TestBlockLocator tests the MsgBlockLocator API.
func TestBlockLocator(t *testing.T) {
hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
locatorHash, err := daghash.NewHashFromStr(hashStr)
locatorHash, err := externalapi.NewDomainHashFromString(hashStr)
if err != nil {
t.Errorf("NewHashFromStr: %v", err)
}
msg := NewMsgBlockLocator([]*daghash.Hash{locatorHash})
msg := NewMsgBlockLocator([]*externalapi.DomainHash{locatorHash})
// Ensure the command is expected value.
wantCmd := MessageCommand(10)

View File

@@ -0,0 +1,54 @@
package appmessage
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"math/big"
)
// MsgBlockWithTrustedData represents a kaspa BlockWithTrustedData message
type MsgBlockWithTrustedData struct {
baseMessage
Block *MsgBlock
DAAScore uint64
DAAWindow []*TrustedDataDataDAABlock
GHOSTDAGData []*BlockGHOSTDAGDataHashPair
}
// Command returns the protocol command string for the message
func (msg *MsgBlockWithTrustedData) Command() MessageCommand {
return CmdBlockWithTrustedData
}
// NewMsgBlockWithTrustedData returns a new MsgBlockWithTrustedData.
func NewMsgBlockWithTrustedData() *MsgBlockWithTrustedData {
return &MsgBlockWithTrustedData{}
}
// TrustedDataDataDAABlock is an appmessage representation of externalapi.TrustedDataDataDAABlock
type TrustedDataDataDAABlock struct {
Block *MsgBlock
GHOSTDAGData *BlockGHOSTDAGData
}
// BlockGHOSTDAGData is an appmessage representation of externalapi.BlockGHOSTDAGData
type BlockGHOSTDAGData struct {
BlueScore uint64
BlueWork *big.Int
SelectedParent *externalapi.DomainHash
MergeSetBlues []*externalapi.DomainHash
MergeSetReds []*externalapi.DomainHash
BluesAnticoneSizes []*BluesAnticoneSizes
}
// BluesAnticoneSizes is an appmessage representation of the BluesAnticoneSizes part of GHOSTDAG data.
type BluesAnticoneSizes struct {
BlueHash *externalapi.DomainHash
AnticoneSize externalapi.KType
}
// BlockGHOSTDAGDataHashPair is an appmessage representation of externalapi.BlockGHOSTDAGDataHashPair
type BlockGHOSTDAGDataHashPair struct {
Hash *externalapi.DomainHash
GHOSTDAGData *BlockGHOSTDAGData
}

View File

@@ -0,0 +1,20 @@
package appmessage
// MsgBlockWithTrustedDataV4 represents a kaspa BlockWithTrustedDataV4 message
type MsgBlockWithTrustedDataV4 struct {
baseMessage
Block *MsgBlock
DAAWindowIndices []uint64
GHOSTDAGDataIndices []uint64
}
// Command returns the protocol command string for the message
func (msg *MsgBlockWithTrustedDataV4) Command() MessageCommand {
return CmdBlockWithTrustedDataV4
}
// NewMsgBlockWithTrustedDataV4 returns a new MsgBlockWithTrustedDataV4.
func NewMsgBlockWithTrustedDataV4() *MsgBlockWithTrustedDataV4 {
return &MsgBlockWithTrustedDataV4{}
}

View File

@@ -0,0 +1,21 @@
package appmessage
// MsgDoneBlocksWithTrustedData implements the Message interface and represents a kaspa
// DoneBlocksWithTrustedData message
//
// This message has no payload.
type MsgDoneBlocksWithTrustedData struct {
baseMessage
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgDoneBlocksWithTrustedData) Command() MessageCommand {
return CmdDoneBlocksWithTrustedData
}
// NewMsgDoneBlocksWithTrustedData returns a new kaspa DoneBlocksWithTrustedData message that conforms to the
// Message interface.
func NewMsgDoneBlocksWithTrustedData() *MsgDoneBlocksWithTrustedData {
return &MsgDoneBlocksWithTrustedData{}
}

View File

@@ -0,0 +1,22 @@
package appmessage
// MsgDoneHeaders implements the Message interface and represents a kaspa
// DoneHeaders message. It is used to notify the IBD syncing peer that the
// syncer sent all the requested headers.
//
// This message has no payload.
type MsgDoneHeaders struct {
baseMessage
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgDoneHeaders) Command() MessageCommand {
return CmdDoneHeaders
}
// NewMsgDoneHeaders returns a new kaspa DoneIBDBlocks message that conforms to the
// Message interface.
func NewMsgDoneHeaders() *MsgDoneHeaders {
return &MsgDoneHeaders{}
}

View File

@@ -0,0 +1,16 @@
package appmessage
// MsgDonePruningPointUTXOSetChunks represents a kaspa DonePruningPointUTXOSetChunks message
type MsgDonePruningPointUTXOSetChunks struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *MsgDonePruningPointUTXOSetChunks) Command() MessageCommand {
return CmdDonePruningPointUTXOSetChunks
}
// NewMsgDonePruningPointUTXOSetChunks returns a new MsgDonePruningPointUTXOSetChunks.
func NewMsgDonePruningPointUTXOSetChunks() *MsgDonePruningPointUTXOSetChunks {
return &MsgDonePruningPointUTXOSetChunks{}
}

View File

@@ -0,0 +1,16 @@
package appmessage
// MsgRequestPruningPointAndItsAnticone represents a kaspa RequestPruningPointAndItsAnticone message
type MsgRequestPruningPointAndItsAnticone struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *MsgRequestPruningPointAndItsAnticone) Command() MessageCommand {
return CmdRequestPruningPointAndItsAnticone
}
// NewMsgRequestPruningPointAndItsAnticone returns a new MsgRequestPruningPointAndItsAnticone.
func NewMsgRequestPruningPointAndItsAnticone() *MsgRequestPruningPointAndItsAnticone {
return &MsgRequestPruningPointAndItsAnticone{}
}

View File

@@ -0,0 +1,27 @@
package appmessage
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MsgIBDBlockLocator represents a kaspa ibdBlockLocator message
type MsgIBDBlockLocator struct {
baseMessage
TargetHash *externalapi.DomainHash
BlockLocatorHashes []*externalapi.DomainHash
}
// Command returns the protocol command string for the message
func (msg *MsgIBDBlockLocator) Command() MessageCommand {
return CmdIBDBlockLocator
}
// NewMsgIBDBlockLocator returns a new kaspa ibdBlockLocator message
func NewMsgIBDBlockLocator(targetHash *externalapi.DomainHash,
blockLocatorHashes []*externalapi.DomainHash) *MsgIBDBlockLocator {
return &MsgIBDBlockLocator{
TargetHash: targetHash,
BlockLocatorHashes: blockLocatorHashes,
}
}

View File

@@ -0,0 +1,23 @@
package appmessage
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MsgIBDBlockLocatorHighestHash represents a kaspa BlockLocatorHighestHash message
type MsgIBDBlockLocatorHighestHash struct {
baseMessage
HighestHash *externalapi.DomainHash
}
// Command returns the protocol command string for the message
func (msg *MsgIBDBlockLocatorHighestHash) Command() MessageCommand {
return CmdIBDBlockLocatorHighestHash
}
// NewMsgIBDBlockLocatorHighestHash returns a new BlockLocatorHighestHash message
func NewMsgIBDBlockLocatorHighestHash(highestHash *externalapi.DomainHash) *MsgIBDBlockLocatorHighestHash {
return &MsgIBDBlockLocatorHighestHash{
HighestHash: highestHash,
}
}

View File

@@ -0,0 +1,16 @@
package appmessage
// MsgIBDBlockLocatorHighestHashNotFound represents a kaspa BlockLocatorHighestHashNotFound message
type MsgIBDBlockLocatorHighestHashNotFound struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *MsgIBDBlockLocatorHighestHashNotFound) Command() MessageCommand {
return CmdIBDBlockLocatorHighestHashNotFound
}
// NewMsgIBDBlockLocatorHighestHashNotFound returns a new IBDBlockLocatorHighestHashNotFound message
func NewMsgIBDBlockLocatorHighestHashNotFound() *MsgIBDBlockLocatorHighestHashNotFound {
return &MsgIBDBlockLocatorHighestHashNotFound{}
}

View File

@@ -1,7 +1,7 @@
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MsgInvRelayBlock implements the Message interface and represents a kaspa
@@ -9,7 +9,7 @@ import (
// by sending their hash, and let the receiving node decide if it needs it.
type MsgInvRelayBlock struct {
baseMessage
Hash *daghash.Hash
Hash *externalapi.DomainHash
}
// Command returns the protocol command string for the message. This is part
@@ -20,7 +20,7 @@ func (msg *MsgInvRelayBlock) Command() MessageCommand {
// NewMsgInvBlock returns a new kaspa invrelblk message that conforms to
// the Message interface. See MsgInvRelayBlock for details.
func NewMsgInvBlock(hash *daghash.Hash) *MsgInvRelayBlock {
func NewMsgInvBlock(hash *externalapi.DomainHash) *MsgInvRelayBlock {
return &MsgInvRelayBlock{
Hash: hash,
}

View File

@@ -1,7 +1,7 @@
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MaxInvPerTxInvMsg is the maximum number of hashes that can
@@ -13,7 +13,7 @@ const MaxInvPerTxInvMsg = MaxInvPerMsg
// by sending their ID, and let the receiving node decide if it needs it.
type MsgInvTransaction struct {
baseMessage
TxIDs []*daghash.TxID
TxIDs []*externalapi.DomainTransactionID
}
// Command returns the protocol command string for the message. This is part
@@ -24,7 +24,7 @@ func (msg *MsgInvTransaction) Command() MessageCommand {
// NewMsgInvTransaction returns a new kaspa TxInv message that conforms to
// the Message interface. See MsgInvTransaction for details.
func NewMsgInvTransaction(ids []*daghash.TxID) *MsgInvTransaction {
func NewMsgInvTransaction(ids []*externalapi.DomainTransactionID) *MsgInvTransaction {
return &MsgInvTransaction{
TxIDs: ids,
}

View File

@@ -6,17 +6,12 @@ package appmessage
import (
"testing"
"github.com/kaspanet/kaspad/util/random"
)
// TestPing tests the MsgPing API against the latest protocol version.
func TestPing(t *testing.T) {
// Ensure we get the same nonce back out.
nonce, err := random.Uint64()
if err != nil {
t.Errorf("random.Uint64: Error generating nonce: %v", err)
}
nonce := uint64(0x61c2c5535902862)
msg := NewMsgPing(nonce)
if msg.Nonce != nonce {
t.Errorf("NewMsgPing: wrong nonce - got %v, want %v",

View File

@@ -6,16 +6,11 @@ package appmessage
import (
"testing"
"github.com/kaspanet/kaspad/util/random"
)
// TestPongLatest tests the MsgPong API against the latest protocol version.
func TestPongLatest(t *testing.T) {
nonce, err := random.Uint64()
if err != nil {
t.Errorf("random.Uint64: error generating nonce: %v", err)
}
nonce := uint64(0x1a05b581a5182c)
msg := NewMsgPong(nonce)
if msg.Nonce != nonce {
t.Errorf("NewMsgPong: wrong nonce - got %v, want %v",

View File

@@ -0,0 +1,20 @@
package appmessage
// MsgPruningPointProof represents a kaspa PruningPointProof message
type MsgPruningPointProof struct {
baseMessage
Headers [][]*MsgBlockHeader
}
// Command returns the protocol command string for the message
func (msg *MsgPruningPointProof) Command() MessageCommand {
return CmdPruningPointProof
}
// NewMsgPruningPointProof returns a new MsgPruningPointProof.
func NewMsgPruningPointProof(headers [][]*MsgBlockHeader) *MsgPruningPointProof {
return &MsgPruningPointProof{
Headers: headers,
}
}

View File

@@ -0,0 +1,20 @@
package appmessage
// MsgPruningPoints represents a kaspa PruningPoints message
type MsgPruningPoints struct {
baseMessage
Headers []*MsgBlockHeader
}
// Command returns the protocol command string for the message
func (msg *MsgPruningPoints) Command() MessageCommand {
return CmdPruningPoints
}
// NewMsgPruningPoints returns a new MsgPruningPoints.
func NewMsgPruningPoints(headers []*MsgBlockHeader) *MsgPruningPoints {
return &MsgPruningPoints{
Headers: headers,
}
}

View File

@@ -0,0 +1,36 @@
package appmessage
import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
// MsgPruningPointUTXOSetChunk represents a kaspa PruningPointUTXOSetChunk message
type MsgPruningPointUTXOSetChunk struct {
baseMessage
OutpointAndUTXOEntryPairs []*OutpointAndUTXOEntryPair
}
// Command returns the protocol command string for the message
func (msg *MsgPruningPointUTXOSetChunk) Command() MessageCommand {
return CmdPruningPointUTXOSetChunk
}
// NewMsgPruningPointUTXOSetChunk returns a new MsgPruningPointUTXOSetChunk.
func NewMsgPruningPointUTXOSetChunk(outpointAndUTXOEntryPairs []*OutpointAndUTXOEntryPair) *MsgPruningPointUTXOSetChunk {
return &MsgPruningPointUTXOSetChunk{
OutpointAndUTXOEntryPairs: outpointAndUTXOEntryPairs,
}
}
// OutpointAndUTXOEntryPair is an outpoint along with its
// respective UTXO entry
type OutpointAndUTXOEntryPair struct {
Outpoint *Outpoint
UTXOEntry *UTXOEntry
}
// UTXOEntry houses details about an individual transaction output in a UTXO
type UTXOEntry struct {
Amount uint64
ScriptPublicKey *externalapi.ScriptPublicKey
BlockDAAScore uint64
IsCoinbase bool
}

View File

@@ -5,7 +5,7 @@
package appmessage
import (
"github.com/kaspanet/kaspad/util/subnetworkid"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MsgRequestAddresses implements the Message interface and represents a kaspa
@@ -17,7 +17,7 @@ import (
type MsgRequestAddresses struct {
baseMessage
IncludeAllSubnetworks bool
SubnetworkID *subnetworkid.SubnetworkID
SubnetworkID *externalapi.DomainSubnetworkID
}
// Command returns the protocol command string for the message. This is part
@@ -28,7 +28,7 @@ func (msg *MsgRequestAddresses) Command() MessageCommand {
// NewMsgRequestAddresses returns a new kaspa RequestAddresses message that conforms to the
// Message interface. See MsgRequestAddresses for details.
func NewMsgRequestAddresses(includeAllSubnetworks bool, subnetworkID *subnetworkid.SubnetworkID) *MsgRequestAddresses {
func NewMsgRequestAddresses(includeAllSubnetworks bool, subnetworkID *externalapi.DomainSubnetworkID) *MsgRequestAddresses {
return &MsgRequestAddresses{
IncludeAllSubnetworks: includeAllSubnetworks,
SubnetworkID: subnetworkID,

View File

@@ -1,17 +1,17 @@
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MsgRequestBlockLocator implements the Message interface and represents a kaspa
// RequestBlockLocator message. It is used to request a block locator between high
// and low hash.
// RequestBlockLocator message. It is used to request a block locator between low
// and high hash.
// The locator is returned via a locator message (MsgBlockLocator).
type MsgRequestBlockLocator struct {
baseMessage
HighHash *daghash.Hash
LowHash *daghash.Hash
HighHash *externalapi.DomainHash
Limit uint32
}
// Command returns the protocol command string for the message. This is part
@@ -23,9 +23,9 @@ func (msg *MsgRequestBlockLocator) Command() MessageCommand {
// NewMsgRequestBlockLocator returns a new RequestBlockLocator message that conforms to the
// Message interface using the passed parameters and defaults for the remaining
// fields.
func NewMsgRequestBlockLocator(highHash, lowHash *daghash.Hash) *MsgRequestBlockLocator {
func NewMsgRequestBlockLocator(highHash *externalapi.DomainHash, limit uint32) *MsgRequestBlockLocator {
return &MsgRequestBlockLocator{
HighHash: highHash,
LowHash: lowHash,
Limit: limit,
}
}

View File

@@ -3,20 +3,20 @@ package appmessage
import (
"testing"
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// TestRequestBlockLocator tests the MsgRequestBlockLocator API.
func TestRequestBlockLocator(t *testing.T) {
hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
highHash, err := daghash.NewHashFromStr(hashStr)
highHash, err := externalapi.NewDomainHashFromString(hashStr)
if err != nil {
t.Errorf("NewHashFromStr: %v", err)
}
// Ensure the command is expected value.
wantCmd := MessageCommand(9)
msg := NewMsgRequestBlockLocator(highHash, &daghash.ZeroHash)
msg := NewMsgRequestBlockLocator(highHash, 0)
if cmd := msg.Command(); cmd != wantCmd {
t.Errorf("NewMsgRequestBlockLocator: wrong command - got %v want %v",
cmd, wantCmd)

View File

@@ -0,0 +1,34 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MsgRequestHeaders implements the Message interface and represents a kaspa
// RequestHeaders message. It is used to request a list of blocks starting after the
// low hash and until the high hash.
type MsgRequestHeaders struct {
baseMessage
LowHash *externalapi.DomainHash
HighHash *externalapi.DomainHash
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgRequestHeaders) Command() MessageCommand {
return CmdRequestHeaders
}
// NewMsgRequstHeaders returns a new kaspa RequestHeaders message that conforms to the
// Message interface using the passed parameters and defaults for the remaining
// fields.
func NewMsgRequstHeaders(lowHash, highHash *externalapi.DomainHash) *MsgRequestHeaders {
return &MsgRequestHeaders{
LowHash: lowHash,
HighHash: highHash,
}
}

View File

@@ -7,26 +7,26 @@ package appmessage
import (
"testing"
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// TestRequstIBDBlocks tests the MsgRequestIBDBlocks API.
func TestRequstIBDBlocks(t *testing.T) {
hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
lowHash, err := daghash.NewHashFromStr(hashStr)
lowHash, err := externalapi.NewDomainHashFromString(hashStr)
if err != nil {
t.Errorf("NewHashFromStr: %v", err)
}
hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
highHash, err := daghash.NewHashFromStr(hashStr)
hashStr = "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
highHash, err := externalapi.NewDomainHashFromString(hashStr)
if err != nil {
t.Errorf("NewHashFromStr: %v", err)
}
// Ensure we get the same data back out.
msg := NewMsgRequstIBDBlocks(lowHash, highHash)
if !msg.HighHash.IsEqual(highHash) {
msg := NewMsgRequstHeaders(lowHash, highHash)
if !msg.HighHash.Equal(highHash) {
t.Errorf("NewMsgRequstIBDBlocks: wrong high hash - got %v, want %v",
msg.HighHash, highHash)
}

View File

@@ -0,0 +1,26 @@
package appmessage
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MsgRequestIBDBlocks implements the Message interface and represents a kaspa
// RequestIBDBlocks message. It is used to request blocks as part of the IBD
// protocol.
type MsgRequestIBDBlocks struct {
baseMessage
Hashes []*externalapi.DomainHash
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgRequestIBDBlocks) Command() MessageCommand {
return CmdRequestIBDBlocks
}
// NewMsgRequestIBDBlocks returns a new MsgRequestIBDBlocks.
func NewMsgRequestIBDBlocks(hashes []*externalapi.DomainHash) *MsgRequestIBDBlocks {
return &MsgRequestIBDBlocks{
Hashes: hashes,
}
}

View File

@@ -0,0 +1,22 @@
package appmessage
// MsgRequestNextHeaders implements the Message interface and represents a kaspa
// RequestNextHeaders message. It is used to notify the IBD syncer peer to send
// more headers.
//
// This message has no payload.
type MsgRequestNextHeaders struct {
baseMessage
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgRequestNextHeaders) Command() MessageCommand {
return CmdRequestNextHeaders
}
// NewMsgRequestNextHeaders returns a new kaspa RequestNextHeaders message that conforms to the
// Message interface.
func NewMsgRequestNextHeaders() *MsgRequestNextHeaders {
return &MsgRequestNextHeaders{}
}

View File

@@ -0,0 +1,16 @@
package appmessage
// MsgRequestNextPruningPointUTXOSetChunk represents a kaspa RequestNextPruningPointUTXOSetChunk message
type MsgRequestNextPruningPointUTXOSetChunk struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *MsgRequestNextPruningPointUTXOSetChunk) Command() MessageCommand {
return CmdRequestNextPruningPointUTXOSetChunk
}
// NewMsgRequestNextPruningPointUTXOSetChunk returns a new MsgRequestNextPruningPointUTXOSetChunk.
func NewMsgRequestNextPruningPointUTXOSetChunk() *MsgRequestNextPruningPointUTXOSetChunk {
return &MsgRequestNextPruningPointUTXOSetChunk{}
}

View File

@@ -0,0 +1,16 @@
package appmessage
// MsgRequestPruningPointProof represents a kaspa RequestPruningPointProof message
type MsgRequestPruningPointProof struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *MsgRequestPruningPointProof) Command() MessageCommand {
return CmdRequestPruningPointProof
}
// NewMsgRequestPruningPointProof returns a new MsgRequestPruningPointProof.
func NewMsgRequestPruningPointProof() *MsgRequestPruningPointProof {
return &MsgRequestPruningPointProof{}
}

View File

@@ -0,0 +1,23 @@
package appmessage
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MsgRequestPruningPointUTXOSet represents a kaspa RequestPruningPointUTXOSet message
type MsgRequestPruningPointUTXOSet struct {
baseMessage
PruningPointHash *externalapi.DomainHash
}
// Command returns the protocol command string for the message
func (msg *MsgRequestPruningPointUTXOSet) Command() MessageCommand {
return CmdRequestPruningPointUTXOSet
}
// NewMsgRequestPruningPointUTXOSet returns a new MsgRequestPruningPointUTXOSet
func NewMsgRequestPruningPointUTXOSet(pruningPointHash *externalapi.DomainHash) *MsgRequestPruningPointUTXOSet {
return &MsgRequestPruningPointUTXOSet{
PruningPointHash: pruningPointHash,
}
}

View File

@@ -1,19 +1,19 @@
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MsgRequestRelayBlocksHashes is the maximum number of hashes that can
// MaxRequestRelayBlocksHashes is the maximum number of hashes that can
// be in a single RequestRelayBlocks message.
const MsgRequestRelayBlocksHashes = MaxInvPerMsg
const MaxRequestRelayBlocksHashes = MaxInvPerMsg
// MsgRequestRelayBlocks implements the Message interface and represents a kaspa
// RequestRelayBlocks message. It is used to request blocks as part of the block
// relay protocol.
type MsgRequestRelayBlocks struct {
baseMessage
Hashes []*daghash.Hash
Hashes []*externalapi.DomainHash
}
// Command returns the protocol command string for the message. This is part
@@ -24,7 +24,7 @@ func (msg *MsgRequestRelayBlocks) Command() MessageCommand {
// NewMsgRequestRelayBlocks returns a new kaspa RequestRelayBlocks message that conforms to
// the Message interface. See MsgRequestRelayBlocks for details.
func NewMsgRequestRelayBlocks(hashes []*daghash.Hash) *MsgRequestRelayBlocks {
func NewMsgRequestRelayBlocks(hashes []*externalapi.DomainHash) *MsgRequestRelayBlocks {
return &MsgRequestRelayBlocks{
Hashes: hashes,
}

View File

@@ -1,7 +1,7 @@
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MaxInvPerRequestTransactionsMsg is the maximum number of hashes that can
@@ -13,7 +13,7 @@ const MaxInvPerRequestTransactionsMsg = MaxInvPerMsg
// transactions relay protocol.
type MsgRequestTransactions struct {
baseMessage
IDs []*daghash.TxID
IDs []*externalapi.DomainTransactionID
}
// Command returns the protocol command string for the message. This is part
@@ -24,7 +24,7 @@ func (msg *MsgRequestTransactions) Command() MessageCommand {
// NewMsgRequestTransactions returns a new kaspa RequestTransactions message that conforms to
// the Message interface. See MsgRequestTransactions for details.
func NewMsgRequestTransactions(ids []*daghash.TxID) *MsgRequestTransactions {
func NewMsgRequestTransactions(ids []*externalapi.DomainTransactionID) *MsgRequestTransactions {
return &MsgRequestTransactions{
IDs: ids,
}

View File

@@ -5,14 +5,14 @@
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// MsgTransactionNotFound defines a kaspa TransactionNotFound message which is sent in response to
// a RequestTransactions message if any of the requested data in not available on the peer.
type MsgTransactionNotFound struct {
baseMessage
ID *daghash.TxID
ID *externalapi.DomainTransactionID
}
// Command returns the protocol command string for the message. This is part
@@ -23,7 +23,7 @@ func (msg *MsgTransactionNotFound) Command() MessageCommand {
// NewMsgTransactionNotFound returns a new kaspa transactionsnotfound message that conforms to the
// Message interface. See MsgTransactionNotFound for details.
func NewMsgTransactionNotFound(id *daghash.TxID) *MsgTransactionNotFound {
func NewMsgTransactionNotFound(id *externalapi.DomainTransactionID) *MsgTransactionNotFound {
return &MsgTransactionNotFound{
ID: id,
}

View File

@@ -0,0 +1,25 @@
package appmessage
// MsgTrustedData represents a kaspa TrustedData message
type MsgTrustedData struct {
baseMessage
DAAWindow []*TrustedDataDAAHeader
GHOSTDAGData []*BlockGHOSTDAGDataHashPair
}
// Command returns the protocol command string for the message
func (msg *MsgTrustedData) Command() MessageCommand {
return CmdTrustedData
}
// NewMsgTrustedData returns a new MsgTrustedData.
func NewMsgTrustedData() *MsgTrustedData {
return &MsgTrustedData{}
}
// TrustedDataDAAHeader is an appmessage representation of externalapi.TrustedDataDataDAAHeader
type TrustedDataDAAHeader struct {
Header *MsgBlockHeader
GHOSTDAGData *BlockGHOSTDAGData
}

319
app/appmessage/p2p_msgtx.go Normal file
View File

@@ -0,0 +1,319 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"encoding/binary"
"strconv"
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
const (
// MaxPrevOutIndex is the maximum index the index field of a previous
// outpoint can be.
MaxPrevOutIndex uint32 = 0xffffffff
// defaultTxInOutAlloc is the default size used for the backing array for
// transaction inputs and outputs. The array will dynamically grow as needed,
// but this figure is intended to provide enough space for the number of
// inputs and outputs in a typical transaction without needing to grow the
// backing array multiple times.
defaultTxInOutAlloc = 15
// minTxInPayload is the minimum payload size for a transaction input.
// PreviousOutpoint.TxID + PreviousOutpoint.Index 4 bytes + Varint for
// SignatureScript length 1 byte + Sequence 4 bytes.
minTxInPayload = 9 + externalapi.DomainHashSize
// maxTxInPerMessage is the maximum number of transactions inputs that
// a transaction which fits into a message could possibly have.
maxTxInPerMessage = (MaxMessagePayload / minTxInPayload) + 1
// MinTxOutPayload is the minimum payload size for a transaction output.
// Value 8 bytes + version 2 bytes + Varint for ScriptPublicKey length 1 byte.
MinTxOutPayload = 11
// maxTxOutPerMessage is the maximum number of transactions outputs that
// a transaction which fits into a message could possibly have.
maxTxOutPerMessage = (MaxMessagePayload / MinTxOutPayload) + 1
// minTxPayload is the minimum payload size for a transaction. Note
// that any realistically usable transaction must have at least one
// input or output, but that is a rule enforced at a higher layer, so
// it is intentionally not included here.
// Version 4 bytes + Varint number of transaction inputs 1 byte + Varint
// number of transaction outputs 1 byte + LockTime 4 bytes + min input
// payload + min output payload.
minTxPayload = 10
)
// Outpoint defines a kaspa data type that is used to track previous
// transaction outputs.
type Outpoint struct {
TxID externalapi.DomainTransactionID
Index uint32
}
// NewOutpoint returns a new kaspa transaction outpoint point with the
// provided hash and index.
func NewOutpoint(txID *externalapi.DomainTransactionID, index uint32) *Outpoint {
return &Outpoint{
TxID: *txID,
Index: index,
}
}
// String returns the Outpoint in the human-readable form "txID:index".
func (o Outpoint) String() string {
// Allocate enough for ID string, colon, and 10 digits. Although
// at the time of writing, the number of digits can be no greater than
// the length of the decimal representation of maxTxOutPerMessage, the
// maximum message payload may increase in the future and this
// optimization may go unnoticed, so allocate space for 10 decimal
// digits, which will fit any uint32.
buf := make([]byte, 2*externalapi.DomainHashSize+1, 2*externalapi.DomainHashSize+1+10)
copy(buf, o.TxID.String())
buf[2*externalapi.DomainHashSize] = ':'
buf = strconv.AppendUint(buf, uint64(o.Index), 10)
return string(buf)
}
// TxIn defines a kaspa transaction input.
type TxIn struct {
PreviousOutpoint Outpoint
SignatureScript []byte
Sequence uint64
SigOpCount byte
}
// NewTxIn returns a new kaspa transaction input with the provided
// previous outpoint point and signature script with a default sequence of
// MaxTxInSequenceNum.
func NewTxIn(prevOut *Outpoint, signatureScript []byte, sequence uint64, sigOpCount byte) *TxIn {
return &TxIn{
PreviousOutpoint: *prevOut,
SignatureScript: signatureScript,
Sequence: sequence,
SigOpCount: sigOpCount,
}
}
// TxOut defines a kaspa transaction output.
type TxOut struct {
Value uint64
ScriptPubKey *externalapi.ScriptPublicKey
}
// NewTxOut returns a new kaspa transaction output with the provided
// transaction value and public key script.
func NewTxOut(value uint64, scriptPubKey *externalapi.ScriptPublicKey) *TxOut {
return &TxOut{
Value: value,
ScriptPubKey: scriptPubKey,
}
}
// MsgTx implements the Message interface and represents a kaspa tx message.
// It is used to deliver transaction information in response to a getdata
// message (MsgGetData) for a given transaction.
//
// Use the AddTxIn and AddTxOut functions to build up the list of transaction
// inputs and outputs.
type MsgTx struct {
baseMessage
Version uint16
TxIn []*TxIn
TxOut []*TxOut
LockTime uint64
SubnetworkID externalapi.DomainSubnetworkID
Gas uint64
Payload []byte
}
// AddTxIn adds a transaction input to the message.
func (msg *MsgTx) AddTxIn(ti *TxIn) {
msg.TxIn = append(msg.TxIn, ti)
}
// AddTxOut adds a transaction output to the message.
func (msg *MsgTx) AddTxOut(to *TxOut) {
msg.TxOut = append(msg.TxOut, to)
}
// IsCoinBase determines whether or not a transaction is a coinbase transaction. A coinbase
// transaction is a special transaction created by miners that distributes fees and block subsidy
// to the previous blocks' miners, and to specify the scriptPubKey that will be used to pay the current
// miner in future blocks. Each input of the coinbase transaction should set index to maximum
// value and reference the relevant block id, instead of previous transaction id.
func (msg *MsgTx) IsCoinBase() bool {
// A coinbase transaction must have subnetwork id SubnetworkIDCoinbase
return msg.SubnetworkID == subnetworks.SubnetworkIDCoinbase
}
// TxHash generates the Hash for the transaction.
func (msg *MsgTx) TxHash() *externalapi.DomainHash {
return consensushashing.TransactionHash(MsgTxToDomainTransaction(msg))
}
// TxID generates the Hash for the transaction without the signature script, gas and payload fields.
func (msg *MsgTx) TxID() *externalapi.DomainTransactionID {
return consensushashing.TransactionID(MsgTxToDomainTransaction(msg))
}
// Copy creates a deep copy of a transaction so that the original does not get
// modified when the copy is manipulated.
func (msg *MsgTx) Copy() *MsgTx {
// Create new tx and start by copying primitive values and making space
// for the transaction inputs and outputs.
newTx := MsgTx{
Version: msg.Version,
TxIn: make([]*TxIn, 0, len(msg.TxIn)),
TxOut: make([]*TxOut, 0, len(msg.TxOut)),
LockTime: msg.LockTime,
SubnetworkID: msg.SubnetworkID,
Gas: msg.Gas,
}
if msg.Payload != nil {
newTx.Payload = make([]byte, len(msg.Payload))
copy(newTx.Payload, msg.Payload)
}
// Deep copy the old TxIn data.
for _, oldTxIn := range msg.TxIn {
// Deep copy the old previous outpoint.
oldOutpoint := oldTxIn.PreviousOutpoint
newOutpoint := Outpoint{}
newOutpoint.TxID = oldOutpoint.TxID
newOutpoint.Index = oldOutpoint.Index
// Deep copy the old signature script.
var newScript []byte
oldScript := oldTxIn.SignatureScript
oldScriptLen := len(oldScript)
if oldScriptLen > 0 {
newScript = make([]byte, oldScriptLen)
copy(newScript, oldScript[:oldScriptLen])
}
// Create new txIn with the deep copied data.
newTxIn := TxIn{
PreviousOutpoint: newOutpoint,
SignatureScript: newScript,
Sequence: oldTxIn.Sequence,
SigOpCount: oldTxIn.SigOpCount,
}
// Finally, append this fully copied txin.
newTx.TxIn = append(newTx.TxIn, &newTxIn)
}
// Deep copy the old TxOut data.
for _, oldTxOut := range msg.TxOut {
// Deep copy the old ScriptPublicKey
var newScript externalapi.ScriptPublicKey
oldScript := oldTxOut.ScriptPubKey
oldScriptLen := len(oldScript.Script)
if oldScriptLen > 0 {
newScript = externalapi.ScriptPublicKey{Script: make([]byte, oldScriptLen), Version: oldScript.Version}
copy(newScript.Script, oldScript.Script[:oldScriptLen])
}
// Create new txOut with the deep copied data and append it to
// new Tx.
newTxOut := TxOut{
Value: oldTxOut.Value,
ScriptPubKey: &newScript,
}
newTx.TxOut = append(newTx.TxOut, &newTxOut)
}
return &newTx
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgTx) Command() MessageCommand {
return CmdTx
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgTx) MaxPayloadLength(pver uint32) uint32 {
return MaxMessagePayload
}
// IsSubnetworkCompatible return true iff subnetworkID is one or more of the following:
// 1. The SupportsAll subnetwork (full node)
// 2. The native subnetwork
// 3. The transaction's subnetwork
func (msg *MsgTx) IsSubnetworkCompatible(subnetworkID *externalapi.DomainSubnetworkID) bool {
return subnetworkID == nil ||
subnetworkID.Equal(&subnetworks.SubnetworkIDNative) ||
subnetworkID.Equal(&msg.SubnetworkID)
}
// newMsgTx returns a new tx message that conforms to the Message interface.
//
// All fields except version and gas has default values if nil is passed:
// txIn, txOut - empty arrays
// payload - an empty payload
//
// The payload hash is calculated automatically according to provided payload.
// Also, the lock time is set to zero to indicate the transaction is valid
// immediately as opposed to some time in future.
func newMsgTx(version uint16, txIn []*TxIn, txOut []*TxOut, subnetworkID *externalapi.DomainSubnetworkID,
gas uint64, payload []byte, lockTime uint64) *MsgTx {
if txIn == nil {
txIn = make([]*TxIn, 0, defaultTxInOutAlloc)
}
if txOut == nil {
txOut = make([]*TxOut, 0, defaultTxInOutAlloc)
}
return &MsgTx{
Version: version,
TxIn: txIn,
TxOut: txOut,
SubnetworkID: *subnetworkID,
Gas: gas,
Payload: payload,
LockTime: lockTime,
}
}
// NewNativeMsgTx returns a new tx message in the native subnetwork
func NewNativeMsgTx(version uint16, txIn []*TxIn, txOut []*TxOut) *MsgTx {
return newMsgTx(version, txIn, txOut, &subnetworks.SubnetworkIDNative, 0, nil, 0)
}
// NewSubnetworkMsgTx returns a new tx message in the specified subnetwork with specified gas and payload
func NewSubnetworkMsgTx(version uint16, txIn []*TxIn, txOut []*TxOut, subnetworkID *externalapi.DomainSubnetworkID,
gas uint64, payload []byte) *MsgTx {
return newMsgTx(version, txIn, txOut, subnetworkID, gas, payload, 0)
}
// NewNativeMsgTxWithLocktime returns a new tx message in the native subnetwork with a locktime.
//
// See newMsgTx for further documntation of the parameters
func NewNativeMsgTxWithLocktime(version uint16, txIn []*TxIn, txOut []*TxOut, locktime uint64) *MsgTx {
return newMsgTx(version, txIn, txOut, &subnetworks.SubnetworkIDNative, 0, nil, locktime)
}
// NewRegistryMsgTx creates a new MsgTx that registers a new subnetwork
func NewRegistryMsgTx(version uint16, txIn []*TxIn, txOut []*TxOut, gasLimit uint64) *MsgTx {
payload := make([]byte, 8)
binary.LittleEndian.PutUint64(payload, gasLimit)
return NewSubnetworkMsgTx(version, txIn, txOut, &subnetworks.SubnetworkIDRegistry, 0, payload)
}

View File

@@ -0,0 +1,261 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package appmessage
import (
"bytes"
"fmt"
"math"
"reflect"
"testing"
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionid"
"github.com/davecgh/go-spew/spew"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// TestTx tests the MsgTx API.
func TestTx(t *testing.T) {
pver := uint32(4)
txIDStr := "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
txID, err := transactionid.FromString(txIDStr)
if err != nil {
t.Errorf("NewTxIDFromStr: %v", err)
}
// Ensure the command is expected value.
wantCmd := MessageCommand(6)
msg := NewNativeMsgTx(1, nil, nil)
if cmd := msg.Command(); cmd != wantCmd {
t.Errorf("NewMsgAddresses: wrong command - got %v want %v",
cmd, wantCmd)
}
// Ensure max payload is expected value for latest protocol version.
wantPayload := uint32(1024 * 1024 * 32)
maxPayload := msg.MaxPayloadLength(pver)
if maxPayload != wantPayload {
t.Errorf("MaxPayloadLength: wrong max payload length for "+
"protocol version %d - got %v, want %v", pver,
maxPayload, wantPayload)
}
// Ensure we get the same transaction outpoint data back out.
// NOTE: This is a block hash and made up index, but we're only
// testing package functionality.
prevOutIndex := uint32(1)
prevOut := NewOutpoint(txID, prevOutIndex)
if !prevOut.TxID.Equal(txID) {
t.Errorf("NewOutpoint: wrong ID - got %v, want %v",
spew.Sprint(&prevOut.TxID), spew.Sprint(txID))
}
if prevOut.Index != prevOutIndex {
t.Errorf("NewOutpoint: wrong index - got %v, want %v",
prevOut.Index, prevOutIndex)
}
prevOutStr := fmt.Sprintf("%s:%d", txID.String(), prevOutIndex)
if s := prevOut.String(); s != prevOutStr {
t.Errorf("Outpoint.String: unexpected result - got %v, "+
"want %v", s, prevOutStr)
}
// Ensure we get the same transaction input back out.
sigScript := []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62}
txIn := NewTxIn(prevOut, sigScript, constants.MaxTxInSequenceNum, 1)
if !reflect.DeepEqual(&txIn.PreviousOutpoint, prevOut) {
t.Errorf("NewTxIn: wrong prev outpoint - got %v, want %v",
spew.Sprint(&txIn.PreviousOutpoint),
spew.Sprint(prevOut))
}
if !bytes.Equal(txIn.SignatureScript, sigScript) {
t.Errorf("NewTxIn: wrong signature script - got %v, want %v",
spew.Sdump(txIn.SignatureScript),
spew.Sdump(sigScript))
}
// Ensure we get the same transaction output back out.
txValue := uint64(5000000000)
scriptPubKey := &externalapi.ScriptPublicKey{
Script: []byte{
0x41, // OP_DATA_65
0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5,
0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42,
0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1,
0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24,
0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97,
0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78,
0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20,
0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63,
0xa6, // 65-byte signature
0xac, // OP_CHECKSIG
},
Version: 0}
txOut := NewTxOut(txValue, scriptPubKey)
if txOut.Value != txValue {
t.Errorf("NewTxOut: wrong scriptPubKey - got %v, want %v",
txOut.Value, txValue)
}
if !bytes.Equal(txOut.ScriptPubKey.Script, scriptPubKey.Script) {
t.Errorf("NewTxOut: wrong scriptPubKey - got %v, want %v",
spew.Sdump(txOut.ScriptPubKey),
spew.Sdump(scriptPubKey))
}
// Ensure transaction inputs are added properly.
msg.AddTxIn(txIn)
if !reflect.DeepEqual(msg.TxIn[0], txIn) {
t.Errorf("AddTxIn: wrong transaction input added - got %v, want %v",
spew.Sprint(msg.TxIn[0]), spew.Sprint(txIn))
}
// Ensure transaction outputs are added properly.
msg.AddTxOut(txOut)
if !reflect.DeepEqual(msg.TxOut[0], txOut) {
t.Errorf("AddTxIn: wrong transaction output added - got %v, want %v",
spew.Sprint(msg.TxOut[0]), spew.Sprint(txOut))
}
// Ensure the copy produced an identical transaction message.
newMsg := msg.Copy()
if !reflect.DeepEqual(newMsg, msg) {
t.Errorf("Copy: mismatched tx messages - got %v, want %v",
spew.Sdump(newMsg), spew.Sdump(msg))
}
}
// TestTxHash tests the ability to generate the hash of a transaction accurately.
func TestTxHashAndID(t *testing.T) {
txHash1Str := "93663e597f6c968d32d229002f76408edf30d6a0151ff679fc729812d8cb2acc"
txID1Str := "24079c6d2bdf602fc389cc307349054937744a9c8dc0f07c023e6af0e949a4e7"
wantTxID1, err := transactionid.FromString(txID1Str)
if err != nil {
t.Fatalf("NewTxIDFromStr: %v", err)
}
wantTxHash1, err := transactionid.FromString(txHash1Str)
if err != nil {
t.Fatalf("NewTxIDFromStr: %v", err)
}
// A coinbase transaction
txIn := &TxIn{
PreviousOutpoint: Outpoint{
TxID: externalapi.DomainTransactionID{},
Index: math.MaxUint32,
},
SignatureScript: []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62},
Sequence: math.MaxUint64,
}
txOut := &TxOut{
Value: 5000000000,
ScriptPubKey: &externalapi.ScriptPublicKey{Script: []byte{
0x41, // OP_DATA_65
0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5,
0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42,
0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1,
0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24,
0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97,
0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78,
0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20,
0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63,
0xa6, // 65-byte signature
0xac, // OP_CHECKSIG
}, Version: 0},
}
tx1 := NewSubnetworkMsgTx(0, []*TxIn{txIn}, []*TxOut{txOut}, &subnetworks.SubnetworkIDCoinbase, 0, nil)
// Ensure the hash produced is expected.
tx1Hash := tx1.TxHash()
if *tx1Hash != (externalapi.DomainHash)(*wantTxHash1) {
t.Errorf("TxHash: wrong hash - got %v, want %v",
spew.Sprint(tx1Hash), spew.Sprint(wantTxHash1))
}
// Ensure the TxID for coinbase transaction is the same as TxHash.
tx1ID := tx1.TxID()
if !tx1ID.Equal(wantTxID1) {
t.Errorf("TxID: wrong ID - got %v, want %v",
spew.Sprint(tx1ID), spew.Sprint(wantTxID1))
}
hash2Str := "8dafd1bec24527d8e3b443ceb0a3b92fffc0d60026317f890b2faf5e9afc177a"
wantHash2, err := externalapi.NewDomainHashFromString(hash2Str)
if err != nil {
t.Errorf("NewTxIDFromStr: %v", err)
return
}
id2Str := "89ffb49474637502d9059af38b8a95fc2f0d3baef5c801d7a9b9c8830671b711"
wantID2, err := transactionid.FromString(id2Str)
if err != nil {
t.Errorf("NewTxIDFromStr: %v", err)
return
}
payload := []byte{1, 2, 3}
txIns := []*TxIn{{
PreviousOutpoint: Outpoint{
Index: 0,
TxID: *externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{1, 2, 3}),
},
SignatureScript: []byte{
0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xDA, 0x0D, 0xC6, 0xAE, 0xCE, 0xFE, 0x1E, 0x06, 0xEF, 0xDF,
0x05, 0x77, 0x37, 0x57, 0xDE, 0xB1, 0x68, 0x82, 0x09, 0x30, 0xE3, 0xB0, 0xD0, 0x3F, 0x46, 0xF5,
0xFC, 0xF1, 0x50, 0xBF, 0x99, 0x0C, 0x02, 0x21, 0x00, 0xD2, 0x5B, 0x5C, 0x87, 0x04, 0x00, 0x76,
0xE4, 0xF2, 0x53, 0xF8, 0x26, 0x2E, 0x76, 0x3E, 0x2D, 0xD5, 0x1E, 0x7F, 0xF0, 0xBE, 0x15, 0x77,
0x27, 0xC4, 0xBC, 0x42, 0x80, 0x7F, 0x17, 0xBD, 0x39, 0x01, 0x41, 0x04, 0xE6, 0xC2, 0x6E, 0xF6,
0x7D, 0xC6, 0x10, 0xD2, 0xCD, 0x19, 0x24, 0x84, 0x78, 0x9A, 0x6C, 0xF9, 0xAE, 0xA9, 0x93, 0x0B,
0x94, 0x4B, 0x7E, 0x2D, 0xB5, 0x34, 0x2B, 0x9D, 0x9E, 0x5B, 0x9F, 0xF7, 0x9A, 0xFF, 0x9A, 0x2E,
0xE1, 0x97, 0x8D, 0xD7, 0xFD, 0x01, 0xDF, 0xC5, 0x22, 0xEE, 0x02, 0x28, 0x3D, 0x3B, 0x06, 0xA9,
0xD0, 0x3A, 0xCF, 0x80, 0x96, 0x96, 0x8D, 0x7D, 0xBB, 0x0F, 0x91, 0x78,
},
Sequence: math.MaxUint64,
}}
txOuts := []*TxOut{
{
Value: 244623243,
ScriptPubKey: &externalapi.ScriptPublicKey{Script: []byte{
0x76, 0xA9, 0x14, 0xBA, 0xDE, 0xEC, 0xFD, 0xEF, 0x05, 0x07, 0x24, 0x7F, 0xC8, 0xF7, 0x42, 0x41,
0xD7, 0x3B, 0xC0, 0x39, 0x97, 0x2D, 0x7B, 0x88, 0xAC,
}, Version: 0},
},
{
Value: 44602432,
ScriptPubKey: &externalapi.ScriptPublicKey{Script: []byte{
0x76, 0xA9, 0x14, 0xC1, 0x09, 0x32, 0x48, 0x3F, 0xEC, 0x93, 0xED, 0x51, 0xF5, 0xFE, 0x95, 0xE7,
0x25, 0x59, 0xF2, 0xCC, 0x70, 0x43, 0xF9, 0x88, 0xAC,
}, Version: 0},
},
}
tx2 := NewSubnetworkMsgTx(1, txIns, txOuts, &externalapi.DomainSubnetworkID{1, 2, 3}, 0, payload)
// Ensure the hash produced is expected.
tx2Hash := tx2.TxHash()
if !tx2Hash.Equal(wantHash2) {
t.Errorf("TxHash: wrong hash - got %v, want %v",
spew.Sprint(tx2Hash), spew.Sprint(wantHash2))
}
// Ensure the TxID for coinbase transaction is the same as TxHash.
tx2ID := tx2.TxID()
if !tx2ID.Equal(wantID2) {
t.Errorf("TxID: wrong ID - got %v, want %v",
spew.Sprint(tx2ID), spew.Sprint(wantID2))
}
if tx2ID.Equal((*externalapi.DomainTransactionID)(tx2Hash)) {
t.Errorf("tx2ID and tx2Hash shouldn't be the same for non-coinbase transaction with signature and/or payload")
}
tx2.TxIn[0].SignatureScript = []byte{}
newTx2Hash := tx2.TxHash()
if *tx2ID == (externalapi.DomainTransactionID)(*newTx2Hash) {
t.Errorf("tx2ID and newTx2Hash should not be the same even for transaction with an empty signature")
}
}

View File

@@ -6,14 +6,13 @@ package appmessage
import (
"fmt"
"github.com/kaspanet/kaspad/version"
"strings"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/version"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/id"
"github.com/kaspanet/kaspad/util/mstime"
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/util/subnetworkid"
)
// MaxUserAgentLen is the maximum allowed length for the user agent field in a
@@ -54,14 +53,11 @@ type MsgVersion struct {
// on the appmessage. This has a max length of MaxUserAgentLen.
UserAgent string
// The selected tip hash of the generator of the version message.
SelectedTipHash *daghash.Hash
// Don't announce transactions to peer.
DisableRelayTx bool
// The subnetwork of the generator of the version message. Should be nil in full nodes
SubnetworkID *subnetworkid.SubnetworkID
SubnetworkID *externalapi.DomainSubnetworkID
}
// HasService returns whether the specified service is supported by the peer
@@ -86,19 +82,18 @@ func (msg *MsgVersion) Command() MessageCommand {
// Message interface using the passed parameters and defaults for the remaining
// fields.
func NewMsgVersion(addr *NetAddress, id *id.ID, network string,
selectedTipHash *daghash.Hash, subnetworkID *subnetworkid.SubnetworkID) *MsgVersion {
subnetworkID *externalapi.DomainSubnetworkID, protocolVersion uint32) *MsgVersion {
// Limit the timestamp to one millisecond precision since the protocol
// doesn't support better.
return &MsgVersion{
ProtocolVersion: ProtocolVersion,
ProtocolVersion: protocolVersion,
Network: network,
Services: 0,
Timestamp: mstime.Now(),
Address: addr,
ID: id,
UserAgent: DefaultUserAgent,
SelectedTipHash: selectedTipHash,
DisableRelayTx: false,
SubnetworkID: subnetworkID,
}

View File

@@ -5,29 +5,28 @@
package appmessage
import (
"github.com/davecgh/go-spew/spew"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/id"
"github.com/kaspanet/kaspad/util/daghash"
"net"
"reflect"
"testing"
"github.com/davecgh/go-spew/spew"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/id"
)
// TestVersion tests the MsgVersion API.
func TestVersion(t *testing.T) {
pver := ProtocolVersion
pver := uint32(4)
// Create version message data.
selectedTipHash := &daghash.Hash{12, 34}
tcpAddrMe := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 16111}
me := NewNetAddress(tcpAddrMe, SFNodeNetwork)
me := NewNetAddress(tcpAddrMe)
generatedID, err := id.GenerateID()
if err != nil {
t.Fatalf("id.GenerateID: %s", err)
}
// Ensure we get the correct data back out.
msg := NewMsgVersion(me, generatedID, "mainnet", selectedTipHash, nil)
msg := NewMsgVersion(me, generatedID, "mainnet", nil, 4)
if msg.ProtocolVersion != pver {
t.Errorf("NewMsgVersion: wrong protocol version - got %v, want %v",
msg.ProtocolVersion, pver)
@@ -44,10 +43,6 @@ func TestVersion(t *testing.T) {
t.Errorf("NewMsgVersion: wrong user agent - got %v, want %v",
msg.UserAgent, DefaultUserAgent)
}
if !msg.SelectedTipHash.IsEqual(selectedTipHash) {
t.Errorf("NewMsgVersion: wrong selected tip hash - got %s, want %s",
msg.SelectedTipHash, selectedTipHash)
}
if msg.DisableRelayTx {
t.Errorf("NewMsgVersion: disable relay tx is not false by "+
"default - got %v, want %v", msg.DisableRelayTx, false)

View File

@@ -5,8 +5,9 @@
package appmessage
import (
"github.com/kaspanet/kaspad/util/mstime"
"net"
"github.com/kaspanet/kaspad/util/mstime"
)
// NetAddress defines information about a peer on the network including the time
@@ -15,9 +16,6 @@ type NetAddress struct {
// Last time the address was seen.
Timestamp mstime.Time
// Bitfield which identifies the services supported by the address.
Services ServiceFlag
// IP address of the peer.
IP net.IP
@@ -26,17 +24,6 @@ type NetAddress struct {
Port uint16
}
// HasService returns whether the specified service is supported by the address.
func (na *NetAddress) HasService(service ServiceFlag) bool {
return na.Services&service == service
}
// AddService adds service as a supported service by the peer generating the
// message.
func (na *NetAddress) AddService(service ServiceFlag) {
na.Services |= service
}
// TCPAddress converts the NetAddress to *net.TCPAddr
func (na *NetAddress) TCPAddress() *net.TCPAddr {
return &net.TCPAddr{
@@ -47,20 +34,19 @@ func (na *NetAddress) TCPAddress() *net.TCPAddr {
// NewNetAddressIPPort returns a new NetAddress using the provided IP, port, and
// supported services with defaults for the remaining fields.
func NewNetAddressIPPort(ip net.IP, port uint16, services ServiceFlag) *NetAddress {
return NewNetAddressTimestamp(mstime.Now(), services, ip, port)
func NewNetAddressIPPort(ip net.IP, port uint16) *NetAddress {
return NewNetAddressTimestamp(mstime.Now(), ip, port)
}
// NewNetAddressTimestamp returns a new NetAddress using the provided
// timestamp, IP, port, and supported services. The timestamp is rounded to
// single millisecond precision.
func NewNetAddressTimestamp(
timestamp mstime.Time, services ServiceFlag, ip net.IP, port uint16) *NetAddress {
timestamp mstime.Time, ip net.IP, port uint16) *NetAddress {
// Limit the timestamp to one millisecond precision since the protocol
// doesn't support better.
na := NetAddress{
Timestamp: timestamp,
Services: services,
IP: ip,
Port: port,
}
@@ -69,6 +55,10 @@ func NewNetAddressTimestamp(
// NewNetAddress returns a new NetAddress using the provided TCP address and
// supported services with defaults for the remaining fields.
func NewNetAddress(addr *net.TCPAddr, services ServiceFlag) *NetAddress {
return NewNetAddressIPPort(addr.IP, uint16(addr.Port), services)
func NewNetAddress(addr *net.TCPAddr) *NetAddress {
return NewNetAddressIPPort(addr.IP, uint16(addr.Port))
}
func (na NetAddress) String() string {
return na.TCPAddress().String()
}

View File

@@ -15,7 +15,7 @@ func TestNetAddress(t *testing.T) {
port := 16111
// Test NewNetAddress.
na := NewNetAddress(&net.TCPAddr{IP: ip, Port: port}, 0)
na := NewNetAddress(&net.TCPAddr{IP: ip, Port: port})
// Ensure we get the same ip, port, and services back out.
if !na.IP.Equal(ip) {
@@ -25,21 +25,4 @@ func TestNetAddress(t *testing.T) {
t.Errorf("NetNetAddress: wrong port - got %v, want %v", na.Port,
port)
}
if na.Services != 0 {
t.Errorf("NetNetAddress: wrong services - got %v, want %v",
na.Services, 0)
}
if na.HasService(SFNodeNetwork) {
t.Errorf("HasService: SFNodeNetwork service is set")
}
// Ensure adding the full service node flag works.
na.AddService(SFNodeNetwork)
if na.Services != SFNodeNetwork {
t.Errorf("AddService: wrong services - got %v, want %v",
na.Services, SFNodeNetwork)
}
if !na.HasService(SFNodeNetwork) {
t.Errorf("HasService: SFNodeNetwork service not set")
}
}

View File

@@ -0,0 +1,22 @@
package appmessage
// MsgReady implements the Message interface and represents a kaspa
// Ready message. It is used to notify that the peer is ready to receive
// messages.
//
// This message has no payload.
type MsgReady struct {
baseMessage
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgReady) Command() MessageCommand {
return CmdReady
}
// NewMsgReady returns a new kaspa Ready message that conforms to the
// Message interface.
func NewMsgReady() *MsgReady {
return &MsgReady{}
}

View File

@@ -0,0 +1,16 @@
package appmessage
// MsgUnexpectedPruningPoint represents a kaspa UnexpectedPruningPoint message
type MsgUnexpectedPruningPoint struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *MsgUnexpectedPruningPoint) Command() MessageCommand {
return CmdUnexpectedPruningPoint
}
// NewMsgUnexpectedPruningPoint returns a new kaspa UnexpectedPruningPoint message
func NewMsgUnexpectedPruningPoint() *MsgUnexpectedPruningPoint {
return &MsgUnexpectedPruningPoint{}
}

View File

@@ -10,10 +10,10 @@ import (
"strings"
)
// XXX pedro: we will probably need to bump this.
const (
// ProtocolVersion is the latest protocol version this package supports.
ProtocolVersion uint32 = 1
// DefaultServices describes the default services that are supported by
// the server.
DefaultServices = SFNodeNetwork | SFNodeBloom | SFNodeCF
)
// ServiceFlag identifies services supported by a kaspa peer.
@@ -103,9 +103,6 @@ const (
// Testnet represents the test network.
Testnet KaspaNet = 0xddb8af8f
// Regtest represents the regression test network.
Regtest KaspaNet = 0xf396cdd6
// Simnet represents the simulation test network.
Simnet KaspaNet = 0x374dcf1c
@@ -118,7 +115,6 @@ const (
var bnStrings = map[KaspaNet]string{
Mainnet: "Mainnet",
Testnet: "Testnet",
Regtest: "Regtest",
Simnet: "Simnet",
Devnet: "Devnet",
}

View File

@@ -40,7 +40,6 @@ func TestKaspaNetStringer(t *testing.T) {
want string
}{
{Mainnet, "Mainnet"},
{Regtest, "Regtest"},
{Testnet, "Testnet"},
{Simnet, "Simnet"},
{0xffffffff, "Unknown KaspaNet (4294967295)"},

View File

@@ -0,0 +1,39 @@
package appmessage
// AddPeerRequestMessage is an appmessage corresponding to
// its respective RPC message
type AddPeerRequestMessage struct {
baseMessage
Address string
IsPermanent bool
}
// Command returns the protocol command string for the message
func (msg *AddPeerRequestMessage) Command() MessageCommand {
return CmdAddPeerRequestMessage
}
// NewAddPeerRequestMessage returns a instance of the message
func NewAddPeerRequestMessage(address string, isPermanent bool) *AddPeerRequestMessage {
return &AddPeerRequestMessage{
Address: address,
IsPermanent: isPermanent,
}
}
// AddPeerResponseMessage is an appmessage corresponding to
// its respective RPC message
type AddPeerResponseMessage struct {
baseMessage
Error *RPCError
}
// Command returns the protocol command string for the message
func (msg *AddPeerResponseMessage) Command() MessageCommand {
return CmdAddPeerResponseMessage
}
// NewAddPeerResponseMessage returns a instance of the message
func NewAddPeerResponseMessage() *AddPeerResponseMessage {
return &AddPeerResponseMessage{}
}

39
app/appmessage/rpc_ban.go Normal file
View File

@@ -0,0 +1,39 @@
package appmessage
// BanRequestMessage is an appmessage corresponding to
// its respective RPC message
type BanRequestMessage struct {
baseMessage
IP string
}
// Command returns the protocol command string for the message
func (msg *BanRequestMessage) Command() MessageCommand {
return CmdBanRequestMessage
}
// NewBanRequestMessage returns an instance of the message
func NewBanRequestMessage(ip string) *BanRequestMessage {
return &BanRequestMessage{
IP: ip,
}
}
// BanResponseMessage is an appmessage corresponding to
// its respective RPC message
type BanResponseMessage struct {
baseMessage
Error *RPCError
}
// Command returns the protocol command string for the message
func (msg *BanResponseMessage) Command() MessageCommand {
return CmdBanResponseMessage
}
// NewBanResponseMessage returns a instance of the message
func NewBanResponseMessage() *BanResponseMessage {
return &BanResponseMessage{}
}

View File

@@ -0,0 +1,43 @@
package appmessage
// EstimateNetworkHashesPerSecondRequestMessage is an appmessage corresponding to
// its respective RPC message
type EstimateNetworkHashesPerSecondRequestMessage struct {
baseMessage
StartHash string
WindowSize uint32
}
// Command returns the protocol command string for the message
func (msg *EstimateNetworkHashesPerSecondRequestMessage) Command() MessageCommand {
return CmdEstimateNetworkHashesPerSecondRequestMessage
}
// NewEstimateNetworkHashesPerSecondRequestMessage returns a instance of the message
func NewEstimateNetworkHashesPerSecondRequestMessage(startHash string, windowSize uint32) *EstimateNetworkHashesPerSecondRequestMessage {
return &EstimateNetworkHashesPerSecondRequestMessage{
StartHash: startHash,
WindowSize: windowSize,
}
}
// EstimateNetworkHashesPerSecondResponseMessage is an appmessage corresponding to
// its respective RPC message
type EstimateNetworkHashesPerSecondResponseMessage struct {
baseMessage
NetworkHashesPerSecond uint64
Error *RPCError
}
// Command returns the protocol command string for the message
func (msg *EstimateNetworkHashesPerSecondResponseMessage) Command() MessageCommand {
return CmdEstimateNetworkHashesPerSecondResponseMessage
}
// NewEstimateNetworkHashesPerSecondResponseMessage returns a instance of the message
func NewEstimateNetworkHashesPerSecondResponseMessage(networkHashesPerSecond uint64) *EstimateNetworkHashesPerSecondResponseMessage {
return &EstimateNetworkHashesPerSecondResponseMessage{
NetworkHashesPerSecond: networkHashesPerSecond,
}
}

View File

@@ -0,0 +1,41 @@
package appmessage
// GetBalanceByAddressRequestMessage is an appmessage corresponding to
// its respective RPC message
type GetBalanceByAddressRequestMessage struct {
baseMessage
Address string
}
// Command returns the protocol command string for the message
func (msg *GetBalanceByAddressRequestMessage) Command() MessageCommand {
return CmdGetBalanceByAddressRequestMessage
}
// NewGetBalanceByAddressRequest returns a instance of the message
func NewGetBalanceByAddressRequest(address string) *GetBalanceByAddressRequestMessage {
return &GetBalanceByAddressRequestMessage{
Address: address,
}
}
// GetBalanceByAddressResponseMessage is an appmessage corresponding to
// its respective RPC message
type GetBalanceByAddressResponseMessage struct {
baseMessage
Balance uint64
Error *RPCError
}
// Command returns the protocol command string for the message
func (msg *GetBalanceByAddressResponseMessage) Command() MessageCommand {
return CmdGetBalanceByAddressResponseMessage
}
// NewGetBalanceByAddressResponse returns an instance of the message
func NewGetBalanceByAddressResponse(Balance uint64) *GetBalanceByAddressResponseMessage {
return &GetBalanceByAddressResponseMessage{
Balance: Balance,
}
}

View File

@@ -0,0 +1,47 @@
package appmessage
// GetBalancesByAddressesRequestMessage is an appmessage corresponding to
// its respective RPC message
type GetBalancesByAddressesRequestMessage struct {
baseMessage
Addresses []string
}
// Command returns the protocol command string for the message
func (msg *GetBalancesByAddressesRequestMessage) Command() MessageCommand {
return CmdGetBalancesByAddressesRequestMessage
}
// NewGetBalancesByAddressesRequest returns a instance of the message
func NewGetBalancesByAddressesRequest(addresses []string) *GetBalancesByAddressesRequestMessage {
return &GetBalancesByAddressesRequestMessage{
Addresses: addresses,
}
}
// BalancesByAddressesEntry represents the balance of some address
type BalancesByAddressesEntry struct {
Address string
Balance uint64
}
// GetBalancesByAddressesResponseMessage is an appmessage corresponding to
// its respective RPC message
type GetBalancesByAddressesResponseMessage struct {
baseMessage
Entries []*BalancesByAddressesEntry
Error *RPCError
}
// Command returns the protocol command string for the message
func (msg *GetBalancesByAddressesResponseMessage) Command() MessageCommand {
return CmdGetBalancesByAddressesResponseMessage
}
// NewGetBalancesByAddressesResponse returns an instance of the message
func NewGetBalancesByAddressesResponse(entries []*BalancesByAddressesEntry) *GetBalancesByAddressesResponseMessage {
return &GetBalancesByAddressesResponseMessage{
Entries: entries,
}
}

View File

@@ -0,0 +1,41 @@
package appmessage
// GetBlockRequestMessage is an appmessage corresponding to
// its respective RPC message
type GetBlockRequestMessage struct {
baseMessage
Hash string
IncludeTransactions bool
}
// Command returns the protocol command string for the message
func (msg *GetBlockRequestMessage) Command() MessageCommand {
return CmdGetBlockRequestMessage
}
// NewGetBlockRequestMessage returns a instance of the message
func NewGetBlockRequestMessage(hash string, includeTransactions bool) *GetBlockRequestMessage {
return &GetBlockRequestMessage{
Hash: hash,
IncludeTransactions: includeTransactions,
}
}
// GetBlockResponseMessage is an appmessage corresponding to
// its respective RPC message
type GetBlockResponseMessage struct {
baseMessage
Block *RPCBlock
Error *RPCError
}
// Command returns the protocol command string for the message
func (msg *GetBlockResponseMessage) Command() MessageCommand {
return CmdGetBlockResponseMessage
}
// NewGetBlockResponseMessage returns a instance of the message
func NewGetBlockResponseMessage() *GetBlockResponseMessage {
return &GetBlockResponseMessage{}
}

View File

@@ -0,0 +1,42 @@
package appmessage
import "github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
// GetBlockCountRequestMessage is an appmessage corresponding to
// its respective RPC message
type GetBlockCountRequestMessage struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *GetBlockCountRequestMessage) Command() MessageCommand {
return CmdGetBlockCountRequestMessage
}
// NewGetBlockCountRequestMessage returns a instance of the message
func NewGetBlockCountRequestMessage() *GetBlockCountRequestMessage {
return &GetBlockCountRequestMessage{}
}
// GetBlockCountResponseMessage is an appmessage corresponding to
// its respective RPC message
type GetBlockCountResponseMessage struct {
baseMessage
BlockCount uint64
HeaderCount uint64
Error *RPCError
}
// Command returns the protocol command string for the message
func (msg *GetBlockCountResponseMessage) Command() MessageCommand {
return CmdGetBlockCountResponseMessage
}
// NewGetBlockCountResponseMessage returns a instance of the message
func NewGetBlockCountResponseMessage(syncInfo *externalapi.SyncInfo) *GetBlockCountResponseMessage {
return &GetBlockCountResponseMessage{
BlockCount: syncInfo.BlockCount,
HeaderCount: syncInfo.HeaderCount,
}
}

View File

@@ -0,0 +1,44 @@
package appmessage
// GetBlockDAGInfoRequestMessage is an appmessage corresponding to
// its respective RPC message
type GetBlockDAGInfoRequestMessage struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *GetBlockDAGInfoRequestMessage) Command() MessageCommand {
return CmdGetBlockDAGInfoRequestMessage
}
// NewGetBlockDAGInfoRequestMessage returns a instance of the message
func NewGetBlockDAGInfoRequestMessage() *GetBlockDAGInfoRequestMessage {
return &GetBlockDAGInfoRequestMessage{}
}
// GetBlockDAGInfoResponseMessage is an appmessage corresponding to
// its respective RPC message
type GetBlockDAGInfoResponseMessage struct {
baseMessage
NetworkName string
BlockCount uint64
HeaderCount uint64
TipHashes []string
VirtualParentHashes []string
Difficulty float64
PastMedianTime int64
PruningPointHash string
VirtualDAAScore uint64
Error *RPCError
}
// Command returns the protocol command string for the message
func (msg *GetBlockDAGInfoResponseMessage) Command() MessageCommand {
return CmdGetBlockDAGInfoResponseMessage
}
// NewGetBlockDAGInfoResponseMessage returns a instance of the message
func NewGetBlockDAGInfoResponseMessage() *GetBlockDAGInfoResponseMessage {
return &GetBlockDAGInfoResponseMessage{}
}

View File

@@ -0,0 +1,43 @@
package appmessage
// GetBlockTemplateRequestMessage is an appmessage corresponding to
// its respective RPC message
type GetBlockTemplateRequestMessage struct {
baseMessage
PayAddress string
}
// Command returns the protocol command string for the message
func (msg *GetBlockTemplateRequestMessage) Command() MessageCommand {
return CmdGetBlockTemplateRequestMessage
}
// NewGetBlockTemplateRequestMessage returns a instance of the message
func NewGetBlockTemplateRequestMessage(payAddress string) *GetBlockTemplateRequestMessage {
return &GetBlockTemplateRequestMessage{
PayAddress: payAddress,
}
}
// GetBlockTemplateResponseMessage is an appmessage corresponding to
// its respective RPC message
type GetBlockTemplateResponseMessage struct {
baseMessage
Block *RPCBlock
IsSynced bool
Error *RPCError
}
// Command returns the protocol command string for the message
func (msg *GetBlockTemplateResponseMessage) Command() MessageCommand {
return CmdGetBlockTemplateResponseMessage
}
// NewGetBlockTemplateResponseMessage returns a instance of the message
func NewGetBlockTemplateResponseMessage(block *RPCBlock, isSynced bool) *GetBlockTemplateResponseMessage {
return &GetBlockTemplateResponseMessage{
Block: block,
IsSynced: isSynced,
}
}

View File

@@ -0,0 +1,45 @@
package appmessage
// GetBlocksRequestMessage is an appmessage corresponding to
// its respective RPC message
type GetBlocksRequestMessage struct {
baseMessage
LowHash string
IncludeBlocks bool
IncludeTransactions bool
}
// Command returns the protocol command string for the message
func (msg *GetBlocksRequestMessage) Command() MessageCommand {
return CmdGetBlocksRequestMessage
}
// NewGetBlocksRequestMessage returns a instance of the message
func NewGetBlocksRequestMessage(lowHash string, includeBlocks bool,
includeTransactions bool) *GetBlocksRequestMessage {
return &GetBlocksRequestMessage{
LowHash: lowHash,
IncludeBlocks: includeBlocks,
IncludeTransactions: includeTransactions,
}
}
// GetBlocksResponseMessage is an appmessage corresponding to
// its respective RPC message
type GetBlocksResponseMessage struct {
baseMessage
BlockHashes []string
Blocks []*RPCBlock
Error *RPCError
}
// Command returns the protocol command string for the message
func (msg *GetBlocksResponseMessage) Command() MessageCommand {
return CmdGetBlocksResponseMessage
}
// NewGetBlocksResponseMessage returns a instance of the message
func NewGetBlocksResponseMessage() *GetBlocksResponseMessage {
return &GetBlocksResponseMessage{}
}

View File

@@ -0,0 +1,50 @@
package appmessage
// GetConnectedPeerInfoRequestMessage is an appmessage corresponding to
// its respective RPC message
type GetConnectedPeerInfoRequestMessage struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *GetConnectedPeerInfoRequestMessage) Command() MessageCommand {
return CmdGetConnectedPeerInfoRequestMessage
}
// NewGetConnectedPeerInfoRequestMessage returns a instance of the message
func NewGetConnectedPeerInfoRequestMessage() *GetConnectedPeerInfoRequestMessage {
return &GetConnectedPeerInfoRequestMessage{}
}
// GetConnectedPeerInfoResponseMessage is an appmessage corresponding to
// its respective RPC message
type GetConnectedPeerInfoResponseMessage struct {
baseMessage
Infos []*GetConnectedPeerInfoMessage
Error *RPCError
}
// Command returns the protocol command string for the message
func (msg *GetConnectedPeerInfoResponseMessage) Command() MessageCommand {
return CmdGetConnectedPeerInfoResponseMessage
}
// NewGetConnectedPeerInfoResponseMessage returns a instance of the message
func NewGetConnectedPeerInfoResponseMessage(infos []*GetConnectedPeerInfoMessage) *GetConnectedPeerInfoResponseMessage {
return &GetConnectedPeerInfoResponseMessage{
Infos: infos,
}
}
// GetConnectedPeerInfoMessage holds information about a connected peer
type GetConnectedPeerInfoMessage struct {
ID string
Address string
LastPingDuration int64
IsOutbound bool
TimeOffset int64
UserAgent string
AdvertisedProtocolVersion uint32
TimeConnected int64
IsIBDPeer bool
}

View File

@@ -0,0 +1,38 @@
package appmessage
// GetCurrentNetworkRequestMessage is an appmessage corresponding to
// its respective RPC message
type GetCurrentNetworkRequestMessage struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *GetCurrentNetworkRequestMessage) Command() MessageCommand {
return CmdGetCurrentNetworkRequestMessage
}
// NewGetCurrentNetworkRequestMessage returns a instance of the message
func NewGetCurrentNetworkRequestMessage() *GetCurrentNetworkRequestMessage {
return &GetCurrentNetworkRequestMessage{}
}
// GetCurrentNetworkResponseMessage is an appmessage corresponding to
// its respective RPC message
type GetCurrentNetworkResponseMessage struct {
baseMessage
CurrentNetwork string
Error *RPCError
}
// Command returns the protocol command string for the message
func (msg *GetCurrentNetworkResponseMessage) Command() MessageCommand {
return CmdGetCurrentNetworkResponseMessage
}
// NewGetCurrentNetworkResponseMessage returns a instance of the message
func NewGetCurrentNetworkResponseMessage(currentNetwork string) *GetCurrentNetworkResponseMessage {
return &GetCurrentNetworkResponseMessage{
CurrentNetwork: currentNetwork,
}
}

Some files were not shown because too many files have changed in this diff Show More