mirror of
https://github.com/kaspanet/kaspad.git
synced 2026-02-21 19:22:53 +00:00
Compare commits
7 Commits
readme-upd
...
testsCheck
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1175a8afe7 | ||
|
|
7e6eaf9299 | ||
|
|
b9339e8815 | ||
|
|
8aadb0bd44 | ||
|
|
092177d9a5 | ||
|
|
55ee5f3115 | ||
|
|
3084e3a366 |
4
.github/workflows/SetPageFileSize.ps1
vendored
4
.github/workflows/SetPageFileSize.ps1
vendored
@@ -11,8 +11,8 @@
|
||||
#>
|
||||
|
||||
param(
|
||||
[System.UInt64] $MinimumSize = 16gb ,
|
||||
[System.UInt64] $MaximumSize = 16gb ,
|
||||
[System.UInt64] $MinimumSize = 8gb ,
|
||||
[System.UInt64] $MaximumSize = 8gb ,
|
||||
[System.String] $DiskRoot = "D:"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: Build and upload assets
|
||||
name: Build and Upload assets
|
||||
on:
|
||||
release:
|
||||
types: [ published ]
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -10,33 +10,34 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest, macos-latest ]
|
||||
name: Building, ${{ matrix.os }}
|
||||
name: Building For ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Fix CRLF on Windows
|
||||
if: runner.os == 'Windows'
|
||||
- name: Fix windows CRLF
|
||||
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
|
||||
# We need to increase the page size because the tests run out of memory on github CI windows.
|
||||
# Use the powershell script from this github action: https://github.com/al-cheb/configure-pagefile-action/blob/master/scripts/SetPageFileSize.ps1
|
||||
# MIT License (MIT) Copyright (c) 2020 Maxim Lobanov and contributors
|
||||
- name: Increase page size on windows
|
||||
if: runner.os == 'Windows'
|
||||
run: powershell -command .github\workflows\SetPageFileSize.ps1
|
||||
shell: powershell
|
||||
run: powershell -command .\.github\workflows\SetPageFileSize.ps1
|
||||
|
||||
|
||||
- name: Setup Go
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
|
||||
- name: Build on Linux
|
||||
- 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"
|
||||
# `-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/...
|
||||
go build -v -ldflags="-s -w -extldflags=-static" -tags netgo,osusergo -o ./bin/ ./...
|
||||
archive="bin/kaspad-${{ github.event.release.tag_name }}-linux.zip"
|
||||
asset_name="kaspad-${{ github.event.release.tag_name }}-linux.zip"
|
||||
zip -r "${archive}" ./bin/*
|
||||
@@ -47,7 +48,7 @@ jobs:
|
||||
if: runner.os == 'Windows'
|
||||
shell: bash
|
||||
run: |
|
||||
go build -v -ldflags="-s -w" -o bin/ . ./cmd/...
|
||||
go build -v -ldflags="-s -w" -o bin/ ./...
|
||||
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}\""
|
||||
@@ -57,7 +58,7 @@ jobs:
|
||||
- name: Build on MacOS
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
go build -v -ldflags="-s -w" -o ./bin/ . ./cmd/...
|
||||
go build -v -ldflags="-s -w" -o ./bin/ ./...
|
||||
archive="bin/kaspad-${{ github.event.release.tag_name }}-osx.zip"
|
||||
asset_name="kaspad-${{ github.event.release.tag_name }}-osx.zip"
|
||||
zip -r "${archive}" ./bin/*
|
||||
@@ -65,7 +66,7 @@ jobs:
|
||||
echo "asset_name=${asset_name}" >> $GITHUB_ENV
|
||||
|
||||
|
||||
- name: Upload release asset
|
||||
- name: Upload Release Asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Race
|
||||
name: Go-Race
|
||||
|
||||
on:
|
||||
schedule:
|
||||
@@ -7,7 +7,7 @@ on:
|
||||
|
||||
jobs:
|
||||
race_test:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -19,10 +19,10 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Go
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
go-version: 1.15
|
||||
|
||||
- name: Set scheduled branch name
|
||||
shell: bash
|
||||
@@ -46,4 +46,4 @@ jobs:
|
||||
run: |
|
||||
git checkout "${{ env.run_on }}"
|
||||
git status
|
||||
go test -timeout 20m -race ./...
|
||||
go test -race ./...
|
||||
@@ -1,36 +1,38 @@
|
||||
name: Tests
|
||||
name: Go
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
# edtited - because base branch can be modified
|
||||
# synchronize - update commits on PR
|
||||
types: [opened, synchronize, edited]
|
||||
# edtited - "title, body, or the base branch of the PR is modified"
|
||||
# synchronize - "commit(s) pushed to the pull request"
|
||||
types: [opened, synchronize, edited, reopened]
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, macos-latest ]
|
||||
name: Tests, ${{ matrix.os }}
|
||||
os: [ ubuntu-16.04, macos-10.15, windows-2019 ]
|
||||
name: Testing on on ${{ matrix.os }}
|
||||
steps:
|
||||
|
||||
- name: Fix CRLF on Windows
|
||||
if: runner.os == 'Windows'
|
||||
- name: Fix windows CRLF
|
||||
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
|
||||
# We need to increase the page size because the tests run out of memory on github CI windows.
|
||||
# Use the powershell script from this github action: https://github.com/al-cheb/configure-pagefile-action/blob/master/scripts/SetPageFileSize.ps1
|
||||
# MIT License (MIT) Copyright (c) 2020 Maxim Lobanov and contributors
|
||||
- name: Increase page size on windows
|
||||
if: runner.os == 'Windows'
|
||||
run: powershell -command .github\workflows\SetPageFileSize.ps1
|
||||
shell: powershell
|
||||
run: powershell -command .\.github\workflows\SetPageFileSize.ps1
|
||||
|
||||
- name: Setup Go
|
||||
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
@@ -49,41 +51,14 @@ jobs:
|
||||
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
|
||||
runs-on: ubuntu-20.04
|
||||
name: Produce code coverage
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Go
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
@@ -95,4 +70,4 @@ jobs:
|
||||
run: go test -v -covermode=atomic -coverpkg=./... -coverprofile coverage.txt ./...
|
||||
|
||||
- name: Upload coverage file
|
||||
run: bash <(curl -s https://codecov.io/bash)
|
||||
run: bash <(curl -s https://codecov.io/bash)
|
||||
@@ -1,13 +1,16 @@
|
||||
|
||||
Kaspad
|
||||
====
|
||||
Warning: This is pre-alpha software. There's no guarantee anything works.
|
||||
====
|
||||
|
||||
[](https://choosealicense.com/licenses/isc/)
|
||||
[](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 Beta state.
|
||||
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.
|
||||
|
||||
## What is kaspa
|
||||
|
||||
|
||||
@@ -20,10 +20,7 @@ import (
|
||||
"github.com/kaspanet/kaspad/version"
|
||||
)
|
||||
|
||||
const (
|
||||
leveldbCacheSizeMiB = 256
|
||||
defaultDataDirname = "datadir2"
|
||||
)
|
||||
const leveldbCacheSizeMiB = 256
|
||||
|
||||
var desiredLimits = &limits.DesiredLimits{
|
||||
FileLimitWant: 2048,
|
||||
@@ -104,7 +101,7 @@ func (app *kaspadApp) main(startedChan chan<- struct{}) error {
|
||||
// Open the database
|
||||
databaseContext, err := openDB(app.cfg)
|
||||
if err != nil {
|
||||
log.Errorf("Loading database failed: %+v", err)
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -162,7 +159,7 @@ func (app *kaspadApp) main(startedChan chan<- struct{}) error {
|
||||
|
||||
// dbPath returns the path to the block database given a database type.
|
||||
func databasePath(cfg *config.Config) string {
|
||||
return filepath.Join(cfg.AppDir, defaultDataDirname)
|
||||
return filepath.Join(cfg.AppDir, "data")
|
||||
}
|
||||
|
||||
func removeDatabase(cfg *config.Config) error {
|
||||
|
||||
@@ -2,9 +2,6 @@ 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"
|
||||
@@ -31,17 +28,13 @@ func DomainBlockToMsgBlock(domainBlock *externalapi.DomainBlock) *MsgBlock {
|
||||
func DomainBlockHeaderToBlockHeader(domainBlockHeader externalapi.BlockHeader) *MsgBlockHeader {
|
||||
return &MsgBlockHeader{
|
||||
Version: domainBlockHeader.Version(),
|
||||
Parents: domainBlockHeader.Parents(),
|
||||
ParentHashes: domainBlockHeader.ParentHashes(),
|
||||
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(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,17 +55,13 @@ func MsgBlockToDomainBlock(msgBlock *MsgBlock) *externalapi.DomainBlock {
|
||||
func BlockHeaderToDomainBlockHeader(blockHeader *MsgBlockHeader) externalapi.BlockHeader {
|
||||
return blockheader.NewImmutableBlockHeader(
|
||||
blockHeader.Version,
|
||||
blockHeader.Parents,
|
||||
blockHeader.ParentHashes,
|
||||
blockHeader.HashMerkleRoot,
|
||||
blockHeader.AcceptedIDMerkleRoot,
|
||||
blockHeader.UTXOCommitment,
|
||||
blockHeader.Timestamp.UnixMilliseconds(),
|
||||
blockHeader.Bits,
|
||||
blockHeader.Nonce,
|
||||
blockHeader.DAAScore,
|
||||
blockHeader.BlueScore,
|
||||
blockHeader.BlueWork,
|
||||
blockHeader.PruningPoint,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -111,7 +100,6 @@ func domainTransactionInputToTxIn(domainTransactionInput *externalapi.DomainTran
|
||||
PreviousOutpoint: *domainOutpointToOutpoint(domainTransactionInput.PreviousOutpoint),
|
||||
SignatureScript: domainTransactionInput.SignatureScript,
|
||||
Sequence: domainTransactionInput.Sequence,
|
||||
SigOpCount: domainTransactionInput.SigOpCount,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +148,6 @@ func txInToDomainTransactionInput(txIn *TxIn) *externalapi.DomainTransactionInpu
|
||||
return &externalapi.DomainTransactionInput{
|
||||
PreviousOutpoint: *outpointToDomainOutpoint(&txIn.PreviousOutpoint), //TODO
|
||||
SignatureScript: txIn.SignatureScript,
|
||||
SigOpCount: txIn.SigOpCount,
|
||||
Sequence: txIn.Sequence,
|
||||
}
|
||||
}
|
||||
@@ -188,7 +175,6 @@ func RPCTransactionToDomainTransaction(rpcTransaction *RPCTransaction) (*externa
|
||||
PreviousOutpoint: *previousOutpoint,
|
||||
SignatureScript: signatureScript,
|
||||
Sequence: input.Sequence,
|
||||
SigOpCount: input.SigOpCount,
|
||||
}
|
||||
}
|
||||
outputs := make([]*externalapi.DomainTransactionOutput, len(rpcTransaction.Outputs))
|
||||
@@ -267,7 +253,6 @@ func DomainTransactionToRPCTransaction(transaction *externalapi.DomainTransactio
|
||||
PreviousOutpoint: previousOutpoint,
|
||||
SignatureScript: signatureScript,
|
||||
Sequence: input.Sequence,
|
||||
SigOpCount: input.SigOpCount,
|
||||
}
|
||||
}
|
||||
outputs := make([]*RPCTransactionOutput, len(transaction.Outputs))
|
||||
@@ -344,25 +329,15 @@ func DomainOutpointAndUTXOEntryPairsToOutpointAndUTXOEntryPairs(
|
||||
|
||||
// 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,
|
||||
ParentHashes: hashes.ToStrings(block.Header.ParentHashes()),
|
||||
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 {
|
||||
@@ -376,16 +351,13 @@ func DomainBlockToRPCBlock(block *externalapi.DomainBlock) *RPCBlock {
|
||||
|
||||
// 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
|
||||
}
|
||||
parentHashes := make([]*externalapi.DomainHash, len(block.Header.ParentHashes))
|
||||
for i, parentHash := range block.Header.ParentHashes {
|
||||
domainParentHashes, err := externalapi.NewDomainHashFromString(parentHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
parentHashes[i] = domainParentHashes
|
||||
}
|
||||
hashMerkleRoot, err := externalapi.NewDomainHashFromString(block.Header.HashMerkleRoot)
|
||||
if err != nil {
|
||||
@@ -399,27 +371,15 @@ func RPCBlockToDomainBlock(block *RPCBlock) (*externalapi.DomainBlock, error) {
|
||||
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,
|
||||
parentHashes,
|
||||
hashMerkleRoot,
|
||||
acceptedIDMerkleRoot,
|
||||
utxoCommitment,
|
||||
block.Header.Timestamp,
|
||||
block.Header.Bits,
|
||||
block.Header.Nonce,
|
||||
block.Header.DAAScore,
|
||||
block.Header.BlueScore,
|
||||
blueWork,
|
||||
pruningPoint)
|
||||
block.Header.Nonce)
|
||||
transactions := make([]*externalapi.DomainTransaction, len(block.Transactions))
|
||||
for i, transaction := range block.Transactions {
|
||||
domainTransaction, err := RPCTransactionToDomainTransaction(transaction)
|
||||
@@ -433,118 +393,3 @@ func RPCBlockToDomainBlock(block *RPCBlock) (*externalapi.DomainBlock, error) {
|
||||
Transactions: transactions,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// BlockWithTrustedDataToDomainBlockWithTrustedData converts *MsgBlockWithTrustedData to *externalapi.BlockWithTrustedData
|
||||
func BlockWithTrustedDataToDomainBlockWithTrustedData(block *MsgBlockWithTrustedData) *externalapi.BlockWithTrustedData {
|
||||
daaWindow := make([]*externalapi.TrustedDataDataDAABlock, len(block.DAAWindow))
|
||||
for i, daaBlock := range block.DAAWindow {
|
||||
daaWindow[i] = &externalapi.TrustedDataDataDAABlock{
|
||||
Block: MsgBlockToDomainBlock(daaBlock.Block),
|
||||
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),
|
||||
DAAScore: block.DAAScore,
|
||||
DAAWindow: daaWindow,
|
||||
GHOSTDAGData: 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: DomainBlockToMsgBlock(daaBlock.Block),
|
||||
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.DAAScore,
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,27 +45,24 @@ const (
|
||||
CmdRequestRelayBlocks
|
||||
CmdInvTransaction
|
||||
CmdRequestTransactions
|
||||
CmdIBDBlock
|
||||
CmdDoneHeaders
|
||||
CmdTransactionNotFound
|
||||
CmdReject
|
||||
CmdHeader
|
||||
CmdRequestNextHeaders
|
||||
CmdRequestPruningPointUTXOSet
|
||||
CmdRequestPruningPointUTXOSetAndBlock
|
||||
CmdPruningPointUTXOSetChunk
|
||||
CmdRequestIBDBlocks
|
||||
CmdUnexpectedPruningPoint
|
||||
CmdRequestPruningPointHash
|
||||
CmdPruningPointHash
|
||||
CmdIBDBlockLocator
|
||||
CmdIBDBlockLocatorHighestHash
|
||||
CmdIBDBlockLocatorHighestHashNotFound
|
||||
CmdBlockHeaders
|
||||
CmdRequestNextPruningPointUTXOSetChunk
|
||||
CmdDonePruningPointUTXOSetChunks
|
||||
CmdBlockWithTrustedData
|
||||
CmdDoneBlocksWithTrustedData
|
||||
CmdRequestPruningPointAndItsAnticone
|
||||
CmdIBDBlock
|
||||
CmdRequestIBDBlocks
|
||||
CmdPruningPoints
|
||||
CmdRequestPruningPointProof
|
||||
CmdPruningPointProof
|
||||
|
||||
// rpc
|
||||
CmdGetCurrentNetworkRequestMessage
|
||||
@@ -153,7 +150,7 @@ var ProtocolMessageCommandToString = map[MessageCommand]string{
|
||||
CmdVerAck: "VerAck",
|
||||
CmdRequestAddresses: "RequestAddresses",
|
||||
CmdAddresses: "Addresses",
|
||||
CmdRequestHeaders: "CmdRequestHeaders",
|
||||
CmdRequestHeaders: "RequestHeaders",
|
||||
CmdBlock: "Block",
|
||||
CmdTx: "Tx",
|
||||
CmdPing: "Ping",
|
||||
@@ -164,27 +161,24 @@ var ProtocolMessageCommandToString = map[MessageCommand]string{
|
||||
CmdRequestRelayBlocks: "RequestRelayBlocks",
|
||||
CmdInvTransaction: "InvTransaction",
|
||||
CmdRequestTransactions: "RequestTransactions",
|
||||
CmdIBDBlock: "IBDBlock",
|
||||
CmdDoneHeaders: "DoneHeaders",
|
||||
CmdTransactionNotFound: "TransactionNotFound",
|
||||
CmdReject: "Reject",
|
||||
CmdHeader: "Header",
|
||||
CmdRequestNextHeaders: "RequestNextHeaders",
|
||||
CmdRequestPruningPointUTXOSet: "RequestPruningPointUTXOSet",
|
||||
CmdRequestPruningPointUTXOSetAndBlock: "RequestPruningPointUTXOSetAndBlock",
|
||||
CmdPruningPointUTXOSetChunk: "PruningPointUTXOSetChunk",
|
||||
CmdRequestIBDBlocks: "RequestIBDBlocks",
|
||||
CmdUnexpectedPruningPoint: "UnexpectedPruningPoint",
|
||||
CmdRequestPruningPointHash: "RequestPruningPointHashHash",
|
||||
CmdPruningPointHash: "PruningPointHash",
|
||||
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",
|
||||
}
|
||||
|
||||
// RPCMessageCommandToString maps all MessageCommands to their string representation
|
||||
|
||||
@@ -21,18 +21,13 @@ func TestBlock(t *testing.T) {
|
||||
pver := ProtocolVersion
|
||||
|
||||
// Block 1 header.
|
||||
parents := blockOne.Header.Parents
|
||||
parentHashes := blockOne.Header.ParentHashes
|
||||
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)
|
||||
bh := NewBlockHeader(1, parentHashes, hashMerkleRoot, acceptedIDMerkleRoot, utxoCommitment, bits, nonce)
|
||||
|
||||
// Ensure the command is expected value.
|
||||
wantCmd := MessageCommand(5)
|
||||
@@ -136,7 +131,7 @@ func TestConvertToPartial(t *testing.T) {
|
||||
var blockOne = MsgBlock{
|
||||
Header: MsgBlockHeader{
|
||||
Version: 0,
|
||||
Parents: []externalapi.BlockLevelParents{[]*externalapi.DomainHash{mainnetGenesisHash, simnetGenesisHash}},
|
||||
ParentHashes: []*externalapi.DomainHash{mainnetGenesisHash, simnetGenesisHash},
|
||||
HashMerkleRoot: mainnetGenesisMerkleRoot,
|
||||
AcceptedIDMerkleRoot: exampleAcceptedIDMerkleRoot,
|
||||
UTXOCommitment: exampleUTXOCommitment,
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
package appmessage
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"math"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/util/mstime"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// BaseBlockHeaderPayload is the base number of bytes a block header can be,
|
||||
@@ -38,8 +39,8 @@ type MsgBlockHeader struct {
|
||||
// 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
|
||||
// Hashes of the parent block headers in the blockDAG.
|
||||
ParentHashes []*externalapi.DomainHash
|
||||
|
||||
// HashMerkleRoot is the merkle tree reference to hash of all transactions for the block.
|
||||
HashMerkleRoot *externalapi.DomainHash
|
||||
@@ -59,16 +60,15 @@ type MsgBlockHeader struct {
|
||||
|
||||
// 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
|
||||
// NumParentBlocks return the number of entries in ParentHashes
|
||||
func (h *MsgBlockHeader) NumParentBlocks() byte {
|
||||
numParents := len(h.ParentHashes)
|
||||
if numParents > math.MaxUint8 {
|
||||
panic(errors.Errorf("number of parents is %d, which is more than one byte can fit", numParents))
|
||||
}
|
||||
return byte(numParents)
|
||||
}
|
||||
|
||||
// BlockHash computes the block identifier hash for the given block header.
|
||||
@@ -76,27 +76,33 @@ func (h *MsgBlockHeader) BlockHash() *externalapi.DomainHash {
|
||||
return consensushashing.HeaderHash(BlockHeaderToDomainBlockHeader(h))
|
||||
}
|
||||
|
||||
// IsGenesis returns true iff this block is a genesis block
|
||||
func (h *MsgBlockHeader) IsGenesis() bool {
|
||||
return h.NumParentBlocks() == 0
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
// of the Message interface implementation.
|
||||
func (h *MsgBlockHeader) Command() MessageCommand {
|
||||
return CmdHeader
|
||||
}
|
||||
|
||||
// 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 {
|
||||
func NewBlockHeader(version uint16, parentHashes []*externalapi.DomainHash, hashMerkleRoot *externalapi.DomainHash,
|
||||
acceptedIDMerkleRoot *externalapi.DomainHash, utxoCommitment *externalapi.DomainHash, bits uint32, nonce uint64) *MsgBlockHeader {
|
||||
|
||||
// Limit the timestamp to one millisecond precision since the protocol
|
||||
// doesn't support better.
|
||||
return &MsgBlockHeader{
|
||||
Version: version,
|
||||
Parents: parents,
|
||||
ParentHashes: parentHashes,
|
||||
HashMerkleRoot: hashMerkleRoot,
|
||||
AcceptedIDMerkleRoot: acceptedIDMerkleRoot,
|
||||
UTXOCommitment: utxoCommitment,
|
||||
Timestamp: mstime.Now(),
|
||||
Bits: bits,
|
||||
Nonce: nonce,
|
||||
DAAScore: daaScore,
|
||||
BlueScore: blueScore,
|
||||
BlueWork: blueWork,
|
||||
PruningPoint: pruningPoint,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,34 +5,29 @@
|
||||
package appmessage
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/util/mstime"
|
||||
)
|
||||
|
||||
// TestBlockHeader tests the MsgBlockHeader API.
|
||||
func TestBlockHeader(t *testing.T) {
|
||||
nonce := uint64(0xba4d87a69924a93d)
|
||||
|
||||
parents := []externalapi.BlockLevelParents{[]*externalapi.DomainHash{mainnetGenesisHash, simnetGenesisHash}}
|
||||
hashes := []*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)
|
||||
bh := NewBlockHeader(1, hashes, merkleHash, acceptedIDMerkleRoot, exampleUTXOCommitment, bits, nonce)
|
||||
|
||||
// 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 !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 != merkleHash {
|
||||
t.Errorf("NewBlockHeader: wrong merkle root - got %v, want %v",
|
||||
@@ -46,20 +41,44 @@ func TestBlockHeader(t *testing.T) {
|
||||
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)
|
||||
}
|
||||
|
||||
func TestIsGenesis(t *testing.T) {
|
||||
nonce := uint64(123123) // 0x1e0f3
|
||||
bits := uint32(0x1d00ffff)
|
||||
timestamp := mstime.UnixMilliseconds(0x495fab29000)
|
||||
|
||||
baseBlockHdr := &MsgBlockHeader{
|
||||
Version: 1,
|
||||
ParentHashes: []*externalapi.DomainHash{mainnetGenesisHash, simnetGenesisHash},
|
||||
HashMerkleRoot: mainnetGenesisMerkleRoot,
|
||||
Timestamp: timestamp,
|
||||
Bits: bits,
|
||||
Nonce: nonce,
|
||||
}
|
||||
if bh.BlueScore != blueScore {
|
||||
t.Errorf("NewBlockHeader: wrong blueScore - got %v, want %v",
|
||||
bh.BlueScore, blueScore)
|
||||
genesisBlockHdr := &MsgBlockHeader{
|
||||
Version: 1,
|
||||
ParentHashes: []*externalapi.DomainHash{},
|
||||
HashMerkleRoot: mainnetGenesisMerkleRoot,
|
||||
Timestamp: timestamp,
|
||||
Bits: bits,
|
||||
Nonce: nonce,
|
||||
}
|
||||
if bh.BlueWork != blueWork {
|
||||
t.Errorf("NewBlockHeader: wrong blueWork - got %v, want %v",
|
||||
bh.BlueWork, blueWork)
|
||||
|
||||
tests := []struct {
|
||||
in *MsgBlockHeader // Block header to encode
|
||||
isGenesis bool // Expected result for call of .IsGenesis
|
||||
}{
|
||||
{genesisBlockHdr, true},
|
||||
{baseBlockHdr, false},
|
||||
}
|
||||
if !bh.PruningPoint.Equal(pruningPoint) {
|
||||
t.Errorf("NewBlockHeader: wrong pruningPoint - got %v, want %v",
|
||||
bh.PruningPoint, pruningPoint)
|
||||
|
||||
t.Logf("Running %d tests", len(tests))
|
||||
for i, test := range tests {
|
||||
isGenesis := test.in.IsGenesis()
|
||||
if isGenesis != test.isGenesis {
|
||||
t.Errorf("MsgBlockHeader.IsGenesis: #%d got: %t, want: %t",
|
||||
i, isGenesis, test.isGenesis)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
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{}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
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{}
|
||||
}
|
||||
65
app/appmessage/p2p_msgibdblock_test.go
Normal file
65
app/appmessage/p2p_msgibdblock_test.go
Normal 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 (
|
||||
"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(15)
|
||||
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)
|
||||
}
|
||||
}
|
||||
23
app/appmessage/p2p_msgpruningpointhash.go
Normal file
23
app/appmessage/p2p_msgpruningpointhash.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package appmessage
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
// MsgPruningPointHashMessage represents a kaspa PruningPointHash message
|
||||
type MsgPruningPointHashMessage struct {
|
||||
baseMessage
|
||||
Hash *externalapi.DomainHash
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message
|
||||
func (msg *MsgPruningPointHashMessage) Command() MessageCommand {
|
||||
return CmdPruningPointHash
|
||||
}
|
||||
|
||||
// NewPruningPointHashMessage returns a new kaspa PruningPointHash message
|
||||
func NewPruningPointHashMessage(hash *externalapi.DomainHash) *MsgPruningPointHashMessage {
|
||||
return &MsgPruningPointHashMessage{
|
||||
Hash: hash,
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
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,
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
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,
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
// The locator is returned via a locator message (MsgBlockLocator).
|
||||
type MsgRequestBlockLocator struct {
|
||||
baseMessage
|
||||
LowHash *externalapi.DomainHash
|
||||
HighHash *externalapi.DomainHash
|
||||
Limit uint32
|
||||
}
|
||||
@@ -23,8 +24,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 *externalapi.DomainHash, limit uint32) *MsgRequestBlockLocator {
|
||||
func NewMsgRequestBlockLocator(lowHash, highHash *externalapi.DomainHash, limit uint32) *MsgRequestBlockLocator {
|
||||
return &MsgRequestBlockLocator{
|
||||
LowHash: lowHash,
|
||||
HighHash: highHash,
|
||||
Limit: limit,
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ func TestRequestBlockLocator(t *testing.T) {
|
||||
|
||||
// Ensure the command is expected value.
|
||||
wantCmd := MessageCommand(9)
|
||||
msg := NewMsgRequestBlockLocator(highHash, 0)
|
||||
msg := NewMsgRequestBlockLocator(highHash, &externalapi.DomainHash{}, 0)
|
||||
if cmd := msg.Command(); cmd != wantCmd {
|
||||
t.Errorf("NewMsgRequestBlockLocator: wrong command - got %v want %v",
|
||||
cmd, wantCmd)
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
// TestRequstIBDBlocks tests the MsgRequestIBDBlocks API.
|
||||
// TestRequstIBDBlocks tests the MsgRequestHeaders API.
|
||||
func TestRequstIBDBlocks(t *testing.T) {
|
||||
hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0"
|
||||
lowHash, err := externalapi.NewDomainHashFromString(hashStr)
|
||||
@@ -27,14 +27,14 @@ func TestRequstIBDBlocks(t *testing.T) {
|
||||
// Ensure we get the same data back out.
|
||||
msg := NewMsgRequstHeaders(lowHash, highHash)
|
||||
if !msg.HighHash.Equal(highHash) {
|
||||
t.Errorf("NewMsgRequstIBDBlocks: wrong high hash - got %v, want %v",
|
||||
t.Errorf("NewMsgRequstHeaders: wrong high hash - got %v, want %v",
|
||||
msg.HighHash, highHash)
|
||||
}
|
||||
|
||||
// Ensure the command is expected value.
|
||||
wantCmd := MessageCommand(4)
|
||||
if cmd := msg.Command(); cmd != wantCmd {
|
||||
t.Errorf("NewMsgRequstIBDBlocks: wrong command - got %v want %v",
|
||||
t.Errorf("NewMsgRequstHeaders: wrong command - got %v want %v",
|
||||
cmd, wantCmd)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
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{}
|
||||
}
|
||||
@@ -4,20 +4,20 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
// MsgRequestPruningPointUTXOSet represents a kaspa RequestPruningPointUTXOSet message
|
||||
type MsgRequestPruningPointUTXOSet struct {
|
||||
// MsgRequestPruningPointUTXOSetAndBlock represents a kaspa RequestPruningPointUTXOSetAndBlock message
|
||||
type MsgRequestPruningPointUTXOSetAndBlock struct {
|
||||
baseMessage
|
||||
PruningPointHash *externalapi.DomainHash
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message
|
||||
func (msg *MsgRequestPruningPointUTXOSet) Command() MessageCommand {
|
||||
return CmdRequestPruningPointUTXOSet
|
||||
func (msg *MsgRequestPruningPointUTXOSetAndBlock) Command() MessageCommand {
|
||||
return CmdRequestPruningPointUTXOSetAndBlock
|
||||
}
|
||||
|
||||
// NewMsgRequestPruningPointUTXOSet returns a new MsgRequestPruningPointUTXOSet
|
||||
func NewMsgRequestPruningPointUTXOSet(pruningPointHash *externalapi.DomainHash) *MsgRequestPruningPointUTXOSet {
|
||||
return &MsgRequestPruningPointUTXOSet{
|
||||
// NewMsgRequestPruningPointUTXOSetAndBlock returns a new MsgRequestPruningPointUTXOSetAndBlock
|
||||
func NewMsgRequestPruningPointUTXOSetAndBlock(pruningPointHash *externalapi.DomainHash) *MsgRequestPruningPointUTXOSetAndBlock {
|
||||
return &MsgRequestPruningPointUTXOSetAndBlock{
|
||||
PruningPointHash: pruningPointHash,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,18 +90,16 @@ 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 {
|
||||
func NewTxIn(prevOut *Outpoint, signatureScript []byte, sequence uint64) *TxIn {
|
||||
return &TxIn{
|
||||
PreviousOutpoint: *prevOut,
|
||||
SignatureScript: signatureScript,
|
||||
Sequence: sequence,
|
||||
SigOpCount: sigOpCount,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +206,6 @@ func (msg *MsgTx) Copy() *MsgTx {
|
||||
PreviousOutpoint: newOutpoint,
|
||||
SignatureScript: newScript,
|
||||
Sequence: oldTxIn.Sequence,
|
||||
SigOpCount: oldTxIn.SigOpCount,
|
||||
}
|
||||
|
||||
// Finally, append this fully copied txin.
|
||||
|
||||
@@ -68,7 +68,7 @@ func TestTx(t *testing.T) {
|
||||
|
||||
// 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)
|
||||
txIn := NewTxIn(prevOut, sigScript, constants.MaxTxInSequenceNum)
|
||||
if !reflect.DeepEqual(&txIn.PreviousOutpoint, prevOut) {
|
||||
t.Errorf("NewTxIn: wrong prev outpoint - got %v, want %v",
|
||||
spew.Sprint(&txIn.PreviousOutpoint),
|
||||
|
||||
16
app/appmessage/p2p_requestpruningpointhash.go
Normal file
16
app/appmessage/p2p_requestpruningpointhash.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package appmessage
|
||||
|
||||
// MsgRequestPruningPointHashMessage represents a kaspa RequestPruningPointHashMessage message
|
||||
type MsgRequestPruningPointHashMessage struct {
|
||||
baseMessage
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message
|
||||
func (msg *MsgRequestPruningPointHashMessage) Command() MessageCommand {
|
||||
return CmdRequestPruningPointHash
|
||||
}
|
||||
|
||||
// NewMsgRequestPruningPointHashMessage returns a new kaspa RequestPruningPointHash message
|
||||
func NewMsgRequestPruningPointHashMessage() *MsgRequestPruningPointHashMessage {
|
||||
return &MsgRequestPruningPointHashMessage{}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
const (
|
||||
// ProtocolVersion is the latest protocol version this package supports.
|
||||
ProtocolVersion uint32 = 3
|
||||
ProtocolVersion uint32 = 1
|
||||
|
||||
// DefaultServices describes the default services that are supported by
|
||||
// the server.
|
||||
|
||||
@@ -20,9 +20,8 @@ func NewGetInfoRequestMessage() *GetInfoRequestMessage {
|
||||
// its respective RPC message
|
||||
type GetInfoResponseMessage struct {
|
||||
baseMessage
|
||||
P2PID string
|
||||
MempoolSize uint64
|
||||
ServerVersion string
|
||||
P2PID string
|
||||
MempoolSize uint64
|
||||
|
||||
Error *RPCError
|
||||
}
|
||||
@@ -33,10 +32,9 @@ func (msg *GetInfoResponseMessage) Command() MessageCommand {
|
||||
}
|
||||
|
||||
// NewGetInfoResponseMessage returns a instance of the message
|
||||
func NewGetInfoResponseMessage(p2pID string, mempoolSize uint64, serverVersion string) *GetInfoResponseMessage {
|
||||
func NewGetInfoResponseMessage(p2pID string, mempoolSize uint64) *GetInfoResponseMessage {
|
||||
return &GetInfoResponseMessage{
|
||||
P2PID: p2pID,
|
||||
MempoolSize: mempoolSize,
|
||||
ServerVersion: serverVersion,
|
||||
P2PID: p2pID,
|
||||
MempoolSize: mempoolSize,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ func NewGetVirtualSelectedParentChainFromBlockRequestMessage(startHash string) *
|
||||
type GetVirtualSelectedParentChainFromBlockResponseMessage struct {
|
||||
baseMessage
|
||||
RemovedChainBlockHashes []string
|
||||
AddedChainBlockHashes []string
|
||||
AddedChainBlocks []*ChainBlock
|
||||
|
||||
Error *RPCError
|
||||
}
|
||||
@@ -35,11 +35,11 @@ func (msg *GetVirtualSelectedParentChainFromBlockResponseMessage) Command() Mess
|
||||
}
|
||||
|
||||
// NewGetVirtualSelectedParentChainFromBlockResponseMessage returns a instance of the message
|
||||
func NewGetVirtualSelectedParentChainFromBlockResponseMessage(removedChainBlockHashes,
|
||||
addedChainBlockHashes []string) *GetVirtualSelectedParentChainFromBlockResponseMessage {
|
||||
func NewGetVirtualSelectedParentChainFromBlockResponseMessage(removedChainBlockHashes []string,
|
||||
addedChainBlocks []*ChainBlock) *GetVirtualSelectedParentChainFromBlockResponseMessage {
|
||||
|
||||
return &GetVirtualSelectedParentChainFromBlockResponseMessage{
|
||||
RemovedChainBlockHashes: removedChainBlockHashes,
|
||||
AddedChainBlockHashes: addedChainBlockHashes,
|
||||
AddedChainBlocks: addedChainBlocks,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,19 @@ func NewNotifyVirtualSelectedParentChainChangedResponseMessage() *NotifyVirtualS
|
||||
type VirtualSelectedParentChainChangedNotificationMessage struct {
|
||||
baseMessage
|
||||
RemovedChainBlockHashes []string
|
||||
AddedChainBlockHashes []string
|
||||
AddedChainBlocks []*ChainBlock
|
||||
}
|
||||
|
||||
// ChainBlock represents a DAG chain-block
|
||||
type ChainBlock struct {
|
||||
Hash string
|
||||
AcceptedBlocks []*AcceptedBlock
|
||||
}
|
||||
|
||||
// AcceptedBlock represents a block accepted into the DAG
|
||||
type AcceptedBlock struct {
|
||||
Hash string
|
||||
AcceptedTransactionIDs []string
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message
|
||||
@@ -47,11 +59,11 @@ func (msg *VirtualSelectedParentChainChangedNotificationMessage) Command() Messa
|
||||
}
|
||||
|
||||
// NewVirtualSelectedParentChainChangedNotificationMessage returns a instance of the message
|
||||
func NewVirtualSelectedParentChainChangedNotificationMessage(removedChainBlockHashes,
|
||||
addedChainBlocks []string) *VirtualSelectedParentChainChangedNotificationMessage {
|
||||
func NewVirtualSelectedParentChainChangedNotificationMessage(removedChainBlockHashes []string,
|
||||
addedChainBlocks []*ChainBlock) *VirtualSelectedParentChainChangedNotificationMessage {
|
||||
|
||||
return &VirtualSelectedParentChainChangedNotificationMessage{
|
||||
RemovedChainBlockHashes: removedChainBlockHashes,
|
||||
AddedChainBlockHashes: addedChainBlocks,
|
||||
AddedChainBlocks: addedChainBlocks,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func (msg *SubmitBlockResponseMessage) Command() MessageCommand {
|
||||
return CmdSubmitBlockResponseMessage
|
||||
}
|
||||
|
||||
// NewSubmitBlockResponseMessage returns an instance of the message
|
||||
// NewSubmitBlockResponseMessage returns a instance of the message
|
||||
func NewSubmitBlockResponseMessage() *SubmitBlockResponseMessage {
|
||||
return &SubmitBlockResponseMessage{}
|
||||
}
|
||||
@@ -70,22 +70,13 @@ type RPCBlock struct {
|
||||
// used over RPC
|
||||
type RPCBlockHeader struct {
|
||||
Version uint32
|
||||
Parents []*RPCBlockLevelParents
|
||||
ParentHashes []string
|
||||
HashMerkleRoot string
|
||||
AcceptedIDMerkleRoot string
|
||||
UTXOCommitment string
|
||||
Timestamp int64
|
||||
Bits uint32
|
||||
Nonce uint64
|
||||
DAAScore uint64
|
||||
BlueScore uint64
|
||||
BlueWork string
|
||||
PruningPoint string
|
||||
}
|
||||
|
||||
// RPCBlockLevelParents holds parent hashes for one block level
|
||||
type RPCBlockLevelParents struct {
|
||||
ParentHashes []string
|
||||
}
|
||||
|
||||
// RPCBlockVerboseData holds verbose data about a block
|
||||
|
||||
@@ -5,7 +5,6 @@ package appmessage
|
||||
type SubmitTransactionRequestMessage struct {
|
||||
baseMessage
|
||||
Transaction *RPCTransaction
|
||||
AllowOrphan bool
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message
|
||||
@@ -14,10 +13,9 @@ func (msg *SubmitTransactionRequestMessage) Command() MessageCommand {
|
||||
}
|
||||
|
||||
// NewSubmitTransactionRequestMessage returns a instance of the message
|
||||
func NewSubmitTransactionRequestMessage(transaction *RPCTransaction, allowOrphan bool) *SubmitTransactionRequestMessage {
|
||||
func NewSubmitTransactionRequestMessage(transaction *RPCTransaction) *SubmitTransactionRequestMessage {
|
||||
return &SubmitTransactionRequestMessage{
|
||||
Transaction: transaction,
|
||||
AllowOrphan: allowOrphan,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +59,6 @@ type RPCTransactionInput struct {
|
||||
PreviousOutpoint *RPCOutpoint
|
||||
SignatureScript string
|
||||
Sequence uint64
|
||||
SigOpCount byte
|
||||
VerboseData *RPCTransactionInputVerboseData
|
||||
}
|
||||
|
||||
@@ -99,7 +96,7 @@ type RPCUTXOEntry struct {
|
||||
type RPCTransactionVerboseData struct {
|
||||
TransactionID string
|
||||
Hash string
|
||||
Mass uint64
|
||||
Size uint64
|
||||
BlockHash string
|
||||
BlockTime uint64
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/miningmanager/mempool"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/protocol"
|
||||
"github.com/kaspanet/kaspad/app/rpc"
|
||||
"github.com/kaspanet/kaspad/domain"
|
||||
@@ -81,11 +79,8 @@ func NewComponentManager(cfg *config.Config, db infrastructuredatabase.Database,
|
||||
IsArchival: cfg.IsArchivalNode,
|
||||
EnableSanityCheckPruningUTXOSet: cfg.EnableSanityCheckPruningUTXOSet,
|
||||
}
|
||||
mempoolConfig := mempool.DefaultConfig(&consensusConfig.Params)
|
||||
mempoolConfig.MaximumOrphanTransactionCount = cfg.MaxOrphanTxs
|
||||
mempoolConfig.MinimumRelayTransactionFee = cfg.MinRelayTxFee
|
||||
|
||||
domain, err := domain.New(&consensusConfig, mempoolConfig, db)
|
||||
domain, err := domain.New(&consensusConfig, db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -152,7 +147,6 @@ func setupRPC(
|
||||
utxoIndex,
|
||||
shutDownChan,
|
||||
)
|
||||
protocolManager.SetOnVirtualChange(rpcManager.NotifyVirtualChange)
|
||||
protocolManager.SetOnBlockAddedToDAGHandler(rpcManager.NotifyBlockAddedToDAG)
|
||||
protocolManager.SetOnPruningPointUTXOSetOverrideHandler(rpcManager.NotifyPruningPointUTXOSetOverride)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
// DefaultTimeout is the default duration to wait for enqueuing/dequeuing
|
||||
// to/from routes.
|
||||
const DefaultTimeout = 120 * time.Second
|
||||
const DefaultTimeout = 30 * time.Second
|
||||
|
||||
// ErrPeerWithSameIDExists signifies that a peer with the same ID already exist.
|
||||
var ErrPeerWithSameIDExists = errors.New("ready peer with the same ID already exists")
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package flowcontext
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
|
||||
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/app/protocol/flows/blockrelay"
|
||||
)
|
||||
@@ -18,7 +17,7 @@ import (
|
||||
// relays newly unorphaned transactions and possibly rebroadcast
|
||||
// manually added transactions when not in IBD.
|
||||
func (f *FlowContext) OnNewBlock(block *externalapi.DomainBlock,
|
||||
virtualChangeSet *externalapi.VirtualChangeSet) error {
|
||||
blockInsertionResult *externalapi.BlockInsertionResult) error {
|
||||
|
||||
hash := consensushashing.BlockHash(block)
|
||||
log.Debugf("OnNewBlock start for block %s", hash)
|
||||
@@ -32,10 +31,10 @@ func (f *FlowContext) OnNewBlock(block *externalapi.DomainBlock,
|
||||
log.Debugf("OnNewBlock: block %s unorphaned %d blocks", hash, len(unorphaningResults))
|
||||
|
||||
newBlocks := []*externalapi.DomainBlock{block}
|
||||
newVirtualChangeSets := []*externalapi.VirtualChangeSet{virtualChangeSet}
|
||||
newBlockInsertionResults := []*externalapi.BlockInsertionResult{blockInsertionResult}
|
||||
for _, unorphaningResult := range unorphaningResults {
|
||||
newBlocks = append(newBlocks, unorphaningResult.block)
|
||||
newVirtualChangeSets = append(newVirtualChangeSets, unorphaningResult.virtualChangeSet)
|
||||
newBlockInsertionResults = append(newBlockInsertionResults, unorphaningResult.blockInsertionResult)
|
||||
}
|
||||
|
||||
allAcceptedTransactions := make([]*externalapi.DomainTransaction, 0)
|
||||
@@ -49,8 +48,8 @@ func (f *FlowContext) OnNewBlock(block *externalapi.DomainBlock,
|
||||
|
||||
if f.onBlockAddedToDAGHandler != nil {
|
||||
log.Debugf("OnNewBlock: calling f.onBlockAddedToDAGHandler for block %s", hash)
|
||||
virtualChangeSet = newVirtualChangeSets[i]
|
||||
err := f.onBlockAddedToDAGHandler(newBlock, virtualChangeSet)
|
||||
blockInsertionResult = newBlockInsertionResults[i]
|
||||
err := f.onBlockAddedToDAGHandler(newBlock, blockInsertionResult)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -60,15 +59,6 @@ func (f *FlowContext) OnNewBlock(block *externalapi.DomainBlock,
|
||||
return f.broadcastTransactionsAfterBlockAdded(newBlocks, allAcceptedTransactions)
|
||||
}
|
||||
|
||||
// OnVirtualChange calls the handler function whenever the virtual block changes.
|
||||
func (f *FlowContext) OnVirtualChange(virtualChangeSet *externalapi.VirtualChangeSet) error {
|
||||
if f.onVirtualChangeHandler != nil && virtualChangeSet != nil {
|
||||
return f.onVirtualChangeHandler(virtualChangeSet)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnPruningPointUTXOSetOverride calls the handler function whenever the UTXO set
|
||||
// resets due to pruning point change via IBD.
|
||||
func (f *FlowContext) OnPruningPointUTXOSetOverride() error {
|
||||
@@ -81,6 +71,8 @@ func (f *FlowContext) OnPruningPointUTXOSetOverride() error {
|
||||
func (f *FlowContext) broadcastTransactionsAfterBlockAdded(
|
||||
addedBlocks []*externalapi.DomainBlock, transactionsAcceptedToMempool []*externalapi.DomainTransaction) error {
|
||||
|
||||
f.updateTransactionsToRebroadcast(addedBlocks)
|
||||
|
||||
// Don't relay transactions when in IBD.
|
||||
if f.IsIBDRunning() {
|
||||
return nil
|
||||
@@ -88,12 +80,7 @@ func (f *FlowContext) broadcastTransactionsAfterBlockAdded(
|
||||
|
||||
var txIDsToRebroadcast []*externalapi.DomainTransactionID
|
||||
if f.shouldRebroadcastTransactions() {
|
||||
txsToRebroadcast, err := f.Domain().MiningManager().RevalidateHighPriorityTransactions()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
txIDsToRebroadcast = consensushashing.TransactionIDs(txsToRebroadcast)
|
||||
f.lastRebroadcastTime = time.Now()
|
||||
txIDsToRebroadcast = f.txIDsToRebroadcast()
|
||||
}
|
||||
|
||||
txIDsToBroadcast := make([]*externalapi.DomainTransactionID, len(transactionsAcceptedToMempool)+len(txIDsToRebroadcast))
|
||||
@@ -104,7 +91,15 @@ func (f *FlowContext) broadcastTransactionsAfterBlockAdded(
|
||||
for i, txID := range txIDsToRebroadcast {
|
||||
txIDsToBroadcast[offset+i] = txID
|
||||
}
|
||||
return f.EnqueueTransactionIDsForPropagation(txIDsToBroadcast)
|
||||
|
||||
if len(txIDsToBroadcast) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(txIDsToBroadcast) > appmessage.MaxInvPerTxInvMsg {
|
||||
txIDsToBroadcast = txIDsToBroadcast[:appmessage.MaxInvPerTxInvMsg]
|
||||
}
|
||||
inv := appmessage.NewMsgInvTransaction(txIDsToBroadcast)
|
||||
return f.Broadcast(inv)
|
||||
}
|
||||
|
||||
// SharedRequestedBlocks returns a *blockrelay.SharedRequestedBlocks for sharing
|
||||
@@ -119,14 +114,14 @@ func (f *FlowContext) AddBlock(block *externalapi.DomainBlock) error {
|
||||
return protocolerrors.Errorf(false, "cannot add header only block")
|
||||
}
|
||||
|
||||
virtualChangeSet, err := f.Domain().Consensus().ValidateAndInsertBlock(block, true)
|
||||
blockInsertionResult, err := f.Domain().Consensus().ValidateAndInsertBlock(block)
|
||||
if err != nil {
|
||||
if errors.As(err, &ruleerrors.RuleError{}) {
|
||||
log.Warnf("Validation failed for block %s: %s", consensushashing.BlockHash(block), err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
err = f.OnNewBlock(block, virtualChangeSet)
|
||||
err = f.OnNewBlock(block, blockInsertionResult)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -166,6 +161,7 @@ func (f *FlowContext) UnsetIBDRunning() {
|
||||
}
|
||||
|
||||
f.ibdPeer = nil
|
||||
log.Infof("IBD finished")
|
||||
}
|
||||
|
||||
// IBDPeer returns the current IBD peer or null if the node is not
|
||||
|
||||
@@ -29,8 +29,3 @@ func (*FlowContext) HandleError(err error, flowName string, isStopping *uint32,
|
||||
errChan <- err
|
||||
}
|
||||
}
|
||||
|
||||
// IsRecoverableError returns whether the error is recoverable
|
||||
func (*FlowContext) IsRecoverableError(err error) bool {
|
||||
return err == nil || errors.Is(err, router.ErrRouteClosed) || errors.As(err, &protocolerrors.ProtocolError{})
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package flowcontext
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/util/mstime"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/kaspanet/kaspad/util/mstime"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain"
|
||||
@@ -22,10 +21,7 @@ import (
|
||||
|
||||
// OnBlockAddedToDAGHandler is a handler function that's triggered
|
||||
// when a block is added to the DAG
|
||||
type OnBlockAddedToDAGHandler func(block *externalapi.DomainBlock, virtualChangeSet *externalapi.VirtualChangeSet) error
|
||||
|
||||
// OnVirtualChangeHandler is a handler function that's triggered when the virtual changes
|
||||
type OnVirtualChangeHandler func(virtualChangeSet *externalapi.VirtualChangeSet) error
|
||||
type OnBlockAddedToDAGHandler func(block *externalapi.DomainBlock, blockInsertionResult *externalapi.BlockInsertionResult) error
|
||||
|
||||
// OnPruningPointUTXOSetOverrideHandler is a handle function that's triggered whenever the UTXO set
|
||||
// resets due to pruning point change via IBD.
|
||||
@@ -46,13 +42,14 @@ type FlowContext struct {
|
||||
|
||||
timeStarted int64
|
||||
|
||||
onVirtualChangeHandler OnVirtualChangeHandler
|
||||
onBlockAddedToDAGHandler OnBlockAddedToDAGHandler
|
||||
onPruningPointUTXOSetOverrideHandler OnPruningPointUTXOSetOverrideHandler
|
||||
onTransactionAddedToMempoolHandler OnTransactionAddedToMempoolHandler
|
||||
|
||||
lastRebroadcastTime time.Time
|
||||
sharedRequestedTransactions *transactionrelay.SharedRequestedTransactions
|
||||
transactionsToRebroadcastLock sync.Mutex
|
||||
transactionsToRebroadcast map[externalapi.DomainTransactionID]*externalapi.DomainTransaction
|
||||
lastRebroadcastTime time.Time
|
||||
sharedRequestedTransactions *transactionrelay.SharedRequestedTransactions
|
||||
|
||||
sharedRequestedBlocks *blockrelay.SharedRequestedBlocks
|
||||
|
||||
@@ -65,10 +62,6 @@ type FlowContext struct {
|
||||
orphans map[externalapi.DomainHash]*externalapi.DomainBlock
|
||||
orphansMutex sync.RWMutex
|
||||
|
||||
transactionIDsToPropagate []*externalapi.DomainTransactionID
|
||||
lastTransactionIDPropagationTime time.Time
|
||||
transactionIDPropagationLock sync.Mutex
|
||||
|
||||
shutdownChan chan struct{}
|
||||
}
|
||||
|
||||
@@ -77,19 +70,18 @@ func New(cfg *config.Config, domain domain.Domain, addressManager *addressmanage
|
||||
netAdapter *netadapter.NetAdapter, connectionManager *connmanager.ConnectionManager) *FlowContext {
|
||||
|
||||
return &FlowContext{
|
||||
cfg: cfg,
|
||||
netAdapter: netAdapter,
|
||||
domain: domain,
|
||||
addressManager: addressManager,
|
||||
connectionManager: connectionManager,
|
||||
sharedRequestedTransactions: transactionrelay.NewSharedRequestedTransactions(),
|
||||
sharedRequestedBlocks: blockrelay.NewSharedRequestedBlocks(),
|
||||
peers: make(map[id.ID]*peerpkg.Peer),
|
||||
orphans: make(map[externalapi.DomainHash]*externalapi.DomainBlock),
|
||||
timeStarted: mstime.Now().UnixMilliseconds(),
|
||||
transactionIDsToPropagate: []*externalapi.DomainTransactionID{},
|
||||
lastTransactionIDPropagationTime: time.Now(),
|
||||
shutdownChan: make(chan struct{}),
|
||||
cfg: cfg,
|
||||
netAdapter: netAdapter,
|
||||
domain: domain,
|
||||
addressManager: addressManager,
|
||||
connectionManager: connectionManager,
|
||||
sharedRequestedTransactions: transactionrelay.NewSharedRequestedTransactions(),
|
||||
sharedRequestedBlocks: blockrelay.NewSharedRequestedBlocks(),
|
||||
peers: make(map[id.ID]*peerpkg.Peer),
|
||||
transactionsToRebroadcast: make(map[externalapi.DomainTransactionID]*externalapi.DomainTransaction),
|
||||
orphans: make(map[externalapi.DomainHash]*externalapi.DomainBlock),
|
||||
timeStarted: mstime.Now().UnixMilliseconds(),
|
||||
shutdownChan: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,11 +96,6 @@ func (f *FlowContext) ShutdownChan() <-chan struct{} {
|
||||
return f.shutdownChan
|
||||
}
|
||||
|
||||
// SetOnVirtualChangeHandler sets the onVirtualChangeHandler handler
|
||||
func (f *FlowContext) SetOnVirtualChangeHandler(onVirtualChangeHandler OnVirtualChangeHandler) {
|
||||
f.onVirtualChangeHandler = onVirtualChangeHandler
|
||||
}
|
||||
|
||||
// SetOnBlockAddedToDAGHandler sets the onBlockAddedToDAG handler
|
||||
func (f *FlowContext) SetOnBlockAddedToDAGHandler(onBlockAddedToDAGHandler OnBlockAddedToDAGHandler) {
|
||||
f.onBlockAddedToDAGHandler = onBlockAddedToDAGHandler
|
||||
|
||||
@@ -17,8 +17,8 @@ const maxOrphans = 600
|
||||
|
||||
// UnorphaningResult is the result of unorphaning a block
|
||||
type UnorphaningResult struct {
|
||||
block *externalapi.DomainBlock
|
||||
virtualChangeSet *externalapi.VirtualChangeSet
|
||||
block *externalapi.DomainBlock
|
||||
blockInsertionResult *externalapi.BlockInsertionResult
|
||||
}
|
||||
|
||||
// AddOrphan adds the block to the orphan set
|
||||
@@ -73,10 +73,10 @@ func (f *FlowContext) UnorphanBlocks(rootBlock *externalapi.DomainBlock) ([]*Uno
|
||||
orphanBlock := f.orphans[orphanHash]
|
||||
|
||||
log.Debugf("Considering to unorphan block %s with parents %s",
|
||||
orphanHash, orphanBlock.Header.DirectParents())
|
||||
orphanHash, orphanBlock.Header.ParentHashes())
|
||||
|
||||
canBeUnorphaned := true
|
||||
for _, orphanBlockParentHash := range orphanBlock.Header.DirectParents() {
|
||||
for _, orphanBlockParentHash := range orphanBlock.Header.ParentHashes() {
|
||||
orphanBlockParentInfo, err := f.domain.Consensus().GetBlockInfo(orphanBlockParentHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -90,14 +90,14 @@ func (f *FlowContext) UnorphanBlocks(rootBlock *externalapi.DomainBlock) ([]*Uno
|
||||
}
|
||||
}
|
||||
if canBeUnorphaned {
|
||||
virtualChangeSet, unorphaningSucceeded, err := f.unorphanBlock(orphanHash)
|
||||
blockInsertionResult, unorphaningSucceeded, err := f.unorphanBlock(orphanHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if unorphaningSucceeded {
|
||||
unorphaningResults = append(unorphaningResults, &UnorphaningResult{
|
||||
block: orphanBlock,
|
||||
virtualChangeSet: virtualChangeSet,
|
||||
block: orphanBlock,
|
||||
blockInsertionResult: blockInsertionResult,
|
||||
})
|
||||
processQueue = f.addChildOrphansToProcessQueue(&orphanHash, processQueue)
|
||||
}
|
||||
@@ -133,7 +133,7 @@ func (f *FlowContext) addChildOrphansToProcessQueue(blockHash *externalapi.Domai
|
||||
func (f *FlowContext) findChildOrphansOfBlock(blockHash *externalapi.DomainHash) []externalapi.DomainHash {
|
||||
var childOrphans []externalapi.DomainHash
|
||||
for orphanHash, orphanBlock := range f.orphans {
|
||||
for _, orphanBlockParentHash := range orphanBlock.Header.DirectParents() {
|
||||
for _, orphanBlockParentHash := range orphanBlock.Header.ParentHashes() {
|
||||
if orphanBlockParentHash.Equal(blockHash) {
|
||||
childOrphans = append(childOrphans, orphanHash)
|
||||
break
|
||||
@@ -143,14 +143,14 @@ func (f *FlowContext) findChildOrphansOfBlock(blockHash *externalapi.DomainHash)
|
||||
return childOrphans
|
||||
}
|
||||
|
||||
func (f *FlowContext) unorphanBlock(orphanHash externalapi.DomainHash) (*externalapi.VirtualChangeSet, bool, error) {
|
||||
func (f *FlowContext) unorphanBlock(orphanHash externalapi.DomainHash) (*externalapi.BlockInsertionResult, bool, error) {
|
||||
orphanBlock, ok := f.orphans[orphanHash]
|
||||
if !ok {
|
||||
return nil, false, errors.Errorf("attempted to unorphan a non-orphan block %s", orphanHash)
|
||||
}
|
||||
delete(f.orphans, orphanHash)
|
||||
|
||||
virtualChangeSet, err := f.domain.Consensus().ValidateAndInsertBlock(orphanBlock, true)
|
||||
blockInsertionResult, err := f.domain.Consensus().ValidateAndInsertBlock(orphanBlock)
|
||||
if err != nil {
|
||||
if errors.As(err, &ruleerrors.RuleError{}) {
|
||||
log.Warnf("Validation failed for orphan block %s: %s", orphanHash, err)
|
||||
@@ -160,7 +160,7 @@ func (f *FlowContext) unorphanBlock(orphanHash externalapi.DomainHash) (*externa
|
||||
}
|
||||
|
||||
log.Infof("Unorphaned block %s", orphanHash)
|
||||
return virtualChangeSet, true, nil
|
||||
return blockInsertionResult, true, nil
|
||||
}
|
||||
|
||||
// GetOrphanRoots returns the roots of the missing ancestors DAG of the given orphan
|
||||
@@ -201,7 +201,7 @@ func (f *FlowContext) GetOrphanRoots(orphan *externalapi.DomainHash) ([]*externa
|
||||
continue
|
||||
}
|
||||
|
||||
for _, parent := range block.Header.DirectParents() {
|
||||
for _, parent := range block.Header.ParentHashes() {
|
||||
if !addedToQueueSet.Contains(parent) {
|
||||
queue = append(queue, parent)
|
||||
addedToQueueSet.Add(parent)
|
||||
|
||||
@@ -25,10 +25,6 @@ func (f *FlowContext) ShouldMine() (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if virtualSelectedParent.Equal(f.Config().NetParams().GenesisHash) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
virtualSelectedParentHeader, err := f.domain.Consensus().GetBlockHeader(virtualSelectedParent)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
||||
@@ -9,18 +9,34 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
)
|
||||
|
||||
// TransactionIDPropagationInterval is the interval between transaction IDs propagations
|
||||
const TransactionIDPropagationInterval = 500 * time.Millisecond
|
||||
|
||||
// AddTransaction adds transaction to the mempool and propagates it.
|
||||
func (f *FlowContext) AddTransaction(tx *externalapi.DomainTransaction, allowOrphan bool) error {
|
||||
acceptedTransactions, err := f.Domain().MiningManager().ValidateAndInsertTransaction(tx, true, allowOrphan)
|
||||
func (f *FlowContext) AddTransaction(tx *externalapi.DomainTransaction) error {
|
||||
f.transactionsToRebroadcastLock.Lock()
|
||||
defer f.transactionsToRebroadcastLock.Unlock()
|
||||
|
||||
err := f.Domain().MiningManager().ValidateAndInsertTransaction(tx, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
acceptedTransactionIDs := consensushashing.TransactionIDs(acceptedTransactions)
|
||||
return f.EnqueueTransactionIDsForPropagation(acceptedTransactionIDs)
|
||||
transactionID := consensushashing.TransactionID(tx)
|
||||
f.transactionsToRebroadcast[*transactionID] = tx
|
||||
inv := appmessage.NewMsgInvTransaction([]*externalapi.DomainTransactionID{transactionID})
|
||||
return f.Broadcast(inv)
|
||||
}
|
||||
|
||||
func (f *FlowContext) updateTransactionsToRebroadcast(addedBlocks []*externalapi.DomainBlock) {
|
||||
f.transactionsToRebroadcastLock.Lock()
|
||||
defer f.transactionsToRebroadcastLock.Unlock()
|
||||
|
||||
for _, block := range addedBlocks {
|
||||
// Note: if a transaction is included in the DAG but not accepted,
|
||||
// it won't be rebroadcast anymore, although it is not included in
|
||||
// the UTXO set
|
||||
for _, tx := range block.Transactions {
|
||||
delete(f.transactionsToRebroadcast, *consensushashing.TransactionID(tx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FlowContext) shouldRebroadcastTransactions() bool {
|
||||
@@ -28,6 +44,19 @@ func (f *FlowContext) shouldRebroadcastTransactions() bool {
|
||||
return time.Since(f.lastRebroadcastTime) > rebroadcastInterval
|
||||
}
|
||||
|
||||
func (f *FlowContext) txIDsToRebroadcast() []*externalapi.DomainTransactionID {
|
||||
f.transactionsToRebroadcastLock.Lock()
|
||||
defer f.transactionsToRebroadcastLock.Unlock()
|
||||
|
||||
txIDs := make([]*externalapi.DomainTransactionID, len(f.transactionsToRebroadcast))
|
||||
i := 0
|
||||
for _, tx := range f.transactionsToRebroadcast {
|
||||
txIDs[i] = consensushashing.TransactionID(tx)
|
||||
i++
|
||||
}
|
||||
return txIDs
|
||||
}
|
||||
|
||||
// SharedRequestedTransactions returns a *transactionrelay.SharedRequestedTransactions for sharing
|
||||
// data about requested transactions between different peers.
|
||||
func (f *FlowContext) SharedRequestedTransactions() *transactionrelay.SharedRequestedTransactions {
|
||||
@@ -41,42 +70,3 @@ func (f *FlowContext) OnTransactionAddedToMempool() {
|
||||
f.onTransactionAddedToMempoolHandler()
|
||||
}
|
||||
}
|
||||
|
||||
// EnqueueTransactionIDsForPropagation add the given transactions IDs to a set of IDs to
|
||||
// propagate. The IDs will be broadcast to all peers within a single transaction Inv message.
|
||||
// The broadcast itself may happen only during a subsequent call to this method
|
||||
func (f *FlowContext) EnqueueTransactionIDsForPropagation(transactionIDs []*externalapi.DomainTransactionID) error {
|
||||
f.transactionIDPropagationLock.Lock()
|
||||
defer f.transactionIDPropagationLock.Unlock()
|
||||
|
||||
f.transactionIDsToPropagate = append(f.transactionIDsToPropagate, transactionIDs...)
|
||||
|
||||
return f.maybePropagateTransactions()
|
||||
}
|
||||
|
||||
func (f *FlowContext) maybePropagateTransactions() error {
|
||||
if time.Since(f.lastTransactionIDPropagationTime) < TransactionIDPropagationInterval &&
|
||||
len(f.transactionIDsToPropagate) < appmessage.MaxInvPerTxInvMsg {
|
||||
return nil
|
||||
}
|
||||
|
||||
for len(f.transactionIDsToPropagate) > 0 {
|
||||
transactionIDsToBroadcast := f.transactionIDsToPropagate
|
||||
if len(transactionIDsToBroadcast) > appmessage.MaxInvPerTxInvMsg {
|
||||
transactionIDsToBroadcast = f.transactionIDsToPropagate[:len(transactionIDsToBroadcast)]
|
||||
}
|
||||
log.Debugf("Transaction propagation: broadcasting %d transactions", len(transactionIDsToBroadcast))
|
||||
|
||||
inv := appmessage.NewMsgInvTransaction(transactionIDsToBroadcast)
|
||||
err := f.Broadcast(inv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.transactionIDsToPropagate = f.transactionIDsToPropagate[len(transactionIDsToBroadcast):]
|
||||
}
|
||||
|
||||
f.lastTransactionIDPropagationTime = time.Now()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,8 +7,10 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
func (flow *handleRelayInvsFlow) sendGetBlockLocator(highHash *externalapi.DomainHash, limit uint32) error {
|
||||
msgGetBlockLocator := appmessage.NewMsgRequestBlockLocator(highHash, limit)
|
||||
func (flow *handleRelayInvsFlow) sendGetBlockLocator(lowHash *externalapi.DomainHash,
|
||||
highHash *externalapi.DomainHash, limit uint32) error {
|
||||
|
||||
msgGetBlockLocator := appmessage.NewMsgRequestBlockLocator(lowHash, highHash, limit)
|
||||
return flow.outgoingRoute.Enqueue(msgGetBlockLocator)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"github.com/kaspanet/kaspad/app/protocol/peer"
|
||||
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
|
||||
"github.com/kaspanet/kaspad/domain"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
)
|
||||
|
||||
@@ -45,9 +44,7 @@ func HandleIBDBlockLocator(context HandleIBDBlockLocatorContext, incomingRoute *
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// The IBD block locator is checking only existing blocks with bodies.
|
||||
if !blockInfo.Exists || blockInfo.BlockStatus == externalapi.StatusHeaderOnly {
|
||||
if !blockInfo.Exists {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ func HandleIBDBlockRequests(context HandleIBDBlockRequestsContext, incomingRoute
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debugf("sent %d out of %d", i+1, len(msgRequestIBDBlocks.Hashes))
|
||||
log.Debugf("sent %d out of %d", i, len(msgRequestIBDBlocks.Hashes))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
package blockrelay
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
|
||||
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
|
||||
"github.com/kaspanet/kaspad/domain"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// PruningPointAndItsAnticoneRequestsContext is the interface for the context needed for the HandlePruningPointAndItsAnticoneRequests flow.
|
||||
type PruningPointAndItsAnticoneRequestsContext interface {
|
||||
Domain() domain.Domain
|
||||
}
|
||||
|
||||
var isBusy uint32
|
||||
|
||||
// HandlePruningPointAndItsAnticoneRequests listens to appmessage.MsgRequestPruningPointAndItsAnticone messages and sends
|
||||
// the pruning point and its anticone to the requesting peer.
|
||||
func HandlePruningPointAndItsAnticoneRequests(context PruningPointAndItsAnticoneRequestsContext, incomingRoute *router.Route,
|
||||
outgoingRoute *router.Route, peer *peerpkg.Peer) error {
|
||||
|
||||
for {
|
||||
err := func() error {
|
||||
_, err := incomingRoute.Dequeue()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !atomic.CompareAndSwapUint32(&isBusy, 0, 1) {
|
||||
return protocolerrors.Errorf(false, "node is busy with other pruning point anticone requests")
|
||||
}
|
||||
defer atomic.StoreUint32(&isBusy, 0)
|
||||
|
||||
log.Debugf("Got request for pruning point and its anticone from %s", peer)
|
||||
|
||||
pruningPointHeaders, err := context.Domain().Consensus().PruningPointHeaders()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgPruningPointHeaders := make([]*appmessage.MsgBlockHeader, len(pruningPointHeaders))
|
||||
for i, header := range pruningPointHeaders {
|
||||
msgPruningPointHeaders[i] = appmessage.DomainBlockHeaderToBlockHeader(header)
|
||||
}
|
||||
|
||||
err = outgoingRoute.Enqueue(appmessage.NewMsgPruningPoints(msgPruningPointHeaders))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pointAndItsAnticone, err := context.Domain().Consensus().PruningPointAndItsAnticone()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, blockHash := range pointAndItsAnticone {
|
||||
err := sendBlockWithTrustedData(context, outgoingRoute, blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = outgoingRoute.Enqueue(appmessage.NewMsgDoneBlocksWithTrustedData())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("Sent pruning point and its anticone to %s", peer)
|
||||
return nil
|
||||
}()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sendBlockWithTrustedData(context PruningPointAndItsAnticoneRequestsContext, outgoingRoute *router.Route, blockHash *externalapi.DomainHash) error {
|
||||
blockWithTrustedData, err := context.Domain().Consensus().BlockWithTrustedData(blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = outgoingRoute.Enqueue(appmessage.DomainBlockWithTrustedDataToBlockWithTrustedData(blockWithTrustedData))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
runtime.GC()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package blockrelay
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/domain"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
)
|
||||
|
||||
// HandlePruningPointHashRequestsFlowContext is the interface for the context needed for the handlePruningPointHashRequestsFlow flow.
|
||||
type HandlePruningPointHashRequestsFlowContext interface {
|
||||
Domain() domain.Domain
|
||||
}
|
||||
|
||||
type handlePruningPointHashRequestsFlow struct {
|
||||
HandlePruningPointHashRequestsFlowContext
|
||||
incomingRoute, outgoingRoute *router.Route
|
||||
}
|
||||
|
||||
// HandlePruningPointHashRequests listens to appmessage.MsgRequestPruningPointHashMessage messages and sends
|
||||
// the pruning point hash as response.
|
||||
func HandlePruningPointHashRequests(context HandlePruningPointHashRequestsFlowContext, incomingRoute,
|
||||
outgoingRoute *router.Route) error {
|
||||
flow := &handlePruningPointHashRequestsFlow{
|
||||
HandlePruningPointHashRequestsFlowContext: context,
|
||||
incomingRoute: incomingRoute,
|
||||
outgoingRoute: outgoingRoute,
|
||||
}
|
||||
|
||||
return flow.start()
|
||||
}
|
||||
|
||||
func (flow *handlePruningPointHashRequestsFlow) start() error {
|
||||
for {
|
||||
_, err := flow.incomingRoute.Dequeue()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debugf("Got request for a pruning point hash")
|
||||
|
||||
pruningPoint, err := flow.Domain().Consensus().PruningPoint()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = flow.outgoingRoute.Enqueue(appmessage.NewPruningPointHashMessage(pruningPoint))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debugf("Sent pruning point hash %s", pruningPoint)
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package blockrelay
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
|
||||
"github.com/kaspanet/kaspad/domain"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
)
|
||||
|
||||
// PruningPointProofRequestsContext is the interface for the context needed for the HandlePruningPointProofRequests flow.
|
||||
type PruningPointProofRequestsContext interface {
|
||||
Domain() domain.Domain
|
||||
}
|
||||
|
||||
// HandlePruningPointProofRequests listens to appmessage.MsgRequestPruningPointProof messages and sends
|
||||
// the pruning point proof to the requesting peer.
|
||||
func HandlePruningPointProofRequests(context PruningPointProofRequestsContext, incomingRoute *router.Route,
|
||||
outgoingRoute *router.Route, peer *peerpkg.Peer) error {
|
||||
|
||||
for {
|
||||
_, err := incomingRoute.Dequeue()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("Got request for pruning point proof from %s", peer)
|
||||
|
||||
pruningPointProof, err := context.Domain().Consensus().BuildPruningPointProof()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pruningPointProofMessage := appmessage.DomainPruningPointProofToMsgPruningPointProof(pruningPointProof)
|
||||
err = outgoingRoute.Enqueue(pruningPointProofMessage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("Sent pruning point proof to %s", peer)
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,7 @@ var orphanResolutionRange uint32 = 5
|
||||
type RelayInvsContext interface {
|
||||
Domain() domain.Domain
|
||||
Config() *config.Config
|
||||
OnNewBlock(block *externalapi.DomainBlock, virtualChangeSet *externalapi.VirtualChangeSet) error
|
||||
OnVirtualChange(virtualChangeSet *externalapi.VirtualChangeSet) error
|
||||
OnNewBlock(block *externalapi.DomainBlock, blockInsertionResult *externalapi.BlockInsertionResult) error
|
||||
OnPruningPointUTXOSetOverride() error
|
||||
SharedRequestedBlocks() *SharedRequestedBlocks
|
||||
Broadcast(message appmessage.Message) error
|
||||
@@ -34,7 +33,6 @@ type RelayInvsContext interface {
|
||||
IsIBDRunning() bool
|
||||
TrySetIBDRunning(ibdPeer *peerpkg.Peer) bool
|
||||
UnsetIBDRunning()
|
||||
IsRecoverableError(err error) bool
|
||||
}
|
||||
|
||||
type handleRelayInvsFlow struct {
|
||||
@@ -82,18 +80,7 @@ func (flow *handleRelayInvsFlow) start() error {
|
||||
continue
|
||||
}
|
||||
|
||||
isGenesisVirtualSelectedParent, err := flow.isGenesisVirtualSelectedParent()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if flow.IsOrphan(inv.Hash) {
|
||||
if flow.Config().NetParams().DisallowDirectBlocksOnTopOfGenesis && !flow.Config().AllowSubmitBlockWhenNotSynced && isGenesisVirtualSelectedParent {
|
||||
log.Infof("Cannot process orphan %s for a node with only the genesis block. The node needs to IBD "+
|
||||
"to the recent pruning point before normal operation can resume.", inv.Hash)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debugf("Block %s is a known orphan. Requesting its missing ancestors", inv.Hash)
|
||||
err := flow.AddOrphanRootsToQueue(inv.Hash)
|
||||
if err != nil {
|
||||
@@ -123,13 +110,8 @@ func (flow *handleRelayInvsFlow) start() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if flow.Config().NetParams().DisallowDirectBlocksOnTopOfGenesis && !flow.Config().AllowSubmitBlockWhenNotSynced && !flow.Config().Devnet && flow.isChildOfGenesis(block) {
|
||||
log.Infof("Cannot process %s because it's a direct child of genesis.", consensushashing.BlockHash(block))
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debugf("Processing block %s", inv.Hash)
|
||||
missingParents, virtualChangeSet, err := flow.processBlock(block)
|
||||
missingParents, blockInsertionResult, err := flow.processBlock(block)
|
||||
if err != nil {
|
||||
if errors.Is(err, ruleerrors.ErrPrunedBlock) {
|
||||
log.Infof("Ignoring pruned block %s", inv.Hash)
|
||||
@@ -144,7 +126,7 @@ func (flow *handleRelayInvsFlow) start() error {
|
||||
}
|
||||
if len(missingParents) > 0 {
|
||||
log.Debugf("Block %s is orphan and has missing parents: %s", inv.Hash, missingParents)
|
||||
err := flow.processOrphan(block)
|
||||
err := flow.processOrphan(block, missingParents)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -157,7 +139,7 @@ func (flow *handleRelayInvsFlow) start() error {
|
||||
return err
|
||||
}
|
||||
log.Infof("Accepted block %s via relay", inv.Hash)
|
||||
err = flow.OnNewBlock(block, virtualChangeSet)
|
||||
err = flow.OnNewBlock(block, blockInsertionResult)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -244,9 +226,9 @@ func (flow *handleRelayInvsFlow) readMsgBlock() (msgBlock *appmessage.MsgBlock,
|
||||
}
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) processBlock(block *externalapi.DomainBlock) ([]*externalapi.DomainHash, *externalapi.VirtualChangeSet, error) {
|
||||
func (flow *handleRelayInvsFlow) processBlock(block *externalapi.DomainBlock) ([]*externalapi.DomainHash, *externalapi.BlockInsertionResult, error) {
|
||||
blockHash := consensushashing.BlockHash(block)
|
||||
virtualChangeSet, err := flow.Domain().Consensus().ValidateAndInsertBlock(block, true)
|
||||
blockInsertionResult, err := flow.Domain().Consensus().ValidateAndInsertBlock(block)
|
||||
if err != nil {
|
||||
if !errors.As(err, &ruleerrors.RuleError{}) {
|
||||
return nil, nil, errors.Wrapf(err, "failed to process block %s", blockHash)
|
||||
@@ -259,7 +241,7 @@ func (flow *handleRelayInvsFlow) processBlock(block *externalapi.DomainBlock) ([
|
||||
log.Warnf("Rejected block %s from %s: %s", blockHash, flow.peer, err)
|
||||
return nil, nil, protocolerrors.Wrapf(true, err, "got invalid block %s from relay", blockHash)
|
||||
}
|
||||
return nil, virtualChangeSet, nil
|
||||
return nil, blockInsertionResult, nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) relayBlock(block *externalapi.DomainBlock) error {
|
||||
@@ -267,7 +249,7 @@ func (flow *handleRelayInvsFlow) relayBlock(block *externalapi.DomainBlock) erro
|
||||
return flow.Broadcast(appmessage.NewMsgInvBlock(blockHash))
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) processOrphan(block *externalapi.DomainBlock) error {
|
||||
func (flow *handleRelayInvsFlow) processOrphan(block *externalapi.DomainBlock, missingParents []*externalapi.DomainHash) error {
|
||||
blockHash := consensushashing.BlockHash(block)
|
||||
|
||||
// Return if the block has been orphaned from elsewhere already
|
||||
@@ -282,19 +264,6 @@ func (flow *handleRelayInvsFlow) processOrphan(block *externalapi.DomainBlock) e
|
||||
return err
|
||||
}
|
||||
if isBlockInOrphanResolutionRange {
|
||||
if flow.Config().NetParams().DisallowDirectBlocksOnTopOfGenesis && !flow.Config().AllowSubmitBlockWhenNotSynced {
|
||||
isGenesisVirtualSelectedParent, err := flow.isGenesisVirtualSelectedParent()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if isGenesisVirtualSelectedParent {
|
||||
log.Infof("Cannot process orphan %s for a node with only the genesis block. The node needs to IBD "+
|
||||
"to the recent pruning point before normal operation can resume.", blockHash)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("Block %s is within orphan resolution range. "+
|
||||
"Adding it to the orphan set", blockHash)
|
||||
flow.AddOrphan(block)
|
||||
@@ -305,21 +274,7 @@ func (flow *handleRelayInvsFlow) processOrphan(block *externalapi.DomainBlock) e
|
||||
// Start IBD unless we already are in IBD
|
||||
log.Debugf("Block %s is out of orphan resolution range. "+
|
||||
"Attempting to start IBD against it.", blockHash)
|
||||
return flow.runIBDIfNotRunning(block)
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) isGenesisVirtualSelectedParent() (bool, error) {
|
||||
virtualSelectedParent, err := flow.Domain().Consensus().GetVirtualSelectedParent()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return virtualSelectedParent.Equal(flow.Config().NetParams().GenesisHash), nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) isChildOfGenesis(block *externalapi.DomainBlock) bool {
|
||||
parents := block.Header.DirectParents()
|
||||
return len(parents) == 1 && parents[0].Equal(flow.Config().NetParams().GenesisHash)
|
||||
return flow.runIBDIfNotRunning(blockHash)
|
||||
}
|
||||
|
||||
// isBlockInOrphanResolutionRange finds out whether the given blockHash should be
|
||||
@@ -328,7 +283,8 @@ func (flow *handleRelayInvsFlow) isChildOfGenesis(block *externalapi.DomainBlock
|
||||
// In the response, if we know none of the hashes, we should retrieve the given
|
||||
// blockHash via IBD. Otherwise, via unorphaning.
|
||||
func (flow *handleRelayInvsFlow) isBlockInOrphanResolutionRange(blockHash *externalapi.DomainHash) (bool, error) {
|
||||
err := flow.sendGetBlockLocator(blockHash, orphanResolutionRange)
|
||||
lowHash := flow.Config().ActiveNetParams.GenesisHash
|
||||
err := flow.sendGetBlockLocator(lowHash, blockHash, orphanResolutionRange)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
@@ -32,19 +32,20 @@ func HandleRequestBlockLocator(context RequestBlockLocatorContext, incomingRoute
|
||||
|
||||
func (flow *handleRequestBlockLocatorFlow) start() error {
|
||||
for {
|
||||
highHash, limit, err := flow.receiveGetBlockLocator()
|
||||
lowHash, highHash, limit, err := flow.receiveGetBlockLocator()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debugf("Received getBlockLocator with highHash: %s, limit: %d", highHash, limit)
|
||||
log.Debugf("Received getBlockLocator with lowHash: %s, highHash: %s, limit: %d",
|
||||
lowHash, highHash, limit)
|
||||
|
||||
locator, err := flow.Domain().Consensus().CreateBlockLocatorFromPruningPoint(highHash, limit)
|
||||
locator, err := flow.Domain().Consensus().CreateBlockLocator(lowHash, highHash, limit)
|
||||
if err != nil || len(locator) == 0 {
|
||||
if err != nil {
|
||||
log.Debugf("Received error from CreateBlockLocatorFromPruningPoint: %s", err)
|
||||
log.Debugf("Received error from CreateBlockLocator: %s", err)
|
||||
}
|
||||
return protocolerrors.Errorf(true, "couldn't build a block "+
|
||||
"locator between the pruning point and %s", highHash)
|
||||
"locator between blocks %s and %s", lowHash, highHash)
|
||||
}
|
||||
|
||||
err = flow.sendBlockLocator(locator)
|
||||
@@ -54,15 +55,16 @@ func (flow *handleRequestBlockLocatorFlow) start() error {
|
||||
}
|
||||
}
|
||||
|
||||
func (flow *handleRequestBlockLocatorFlow) receiveGetBlockLocator() (highHash *externalapi.DomainHash, limit uint32, err error) {
|
||||
func (flow *handleRequestBlockLocatorFlow) receiveGetBlockLocator() (lowHash *externalapi.DomainHash,
|
||||
highHash *externalapi.DomainHash, limit uint32, err error) {
|
||||
|
||||
message, err := flow.incomingRoute.Dequeue()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
msgGetBlockLocator := message.(*appmessage.MsgRequestBlockLocator)
|
||||
|
||||
return msgGetBlockLocator.HighHash, msgGetBlockLocator.Limit, nil
|
||||
return msgGetBlockLocator.LowHash, msgGetBlockLocator.HighHash, msgGetBlockLocator.Limit, nil
|
||||
}
|
||||
|
||||
func (flow *handleRequestBlockLocatorFlow) sendBlockLocator(locator externalapi.BlockLocator) error {
|
||||
|
||||
@@ -12,26 +12,26 @@ import (
|
||||
|
||||
const ibdBatchSize = router.DefaultMaxMessages
|
||||
|
||||
// RequestHeadersContext is the interface for the context needed for the HandleRequestHeaders flow.
|
||||
type RequestHeadersContext interface {
|
||||
// RequestIBDBlocksContext is the interface for the context needed for the HandleRequestHeaders flow.
|
||||
type RequestIBDBlocksContext interface {
|
||||
Domain() domain.Domain
|
||||
}
|
||||
|
||||
type handleRequestHeadersFlow struct {
|
||||
RequestHeadersContext
|
||||
RequestIBDBlocksContext
|
||||
incomingRoute, outgoingRoute *router.Route
|
||||
peer *peer.Peer
|
||||
}
|
||||
|
||||
// HandleRequestHeaders handles RequestHeaders messages
|
||||
func HandleRequestHeaders(context RequestHeadersContext, incomingRoute *router.Route,
|
||||
func HandleRequestHeaders(context RequestIBDBlocksContext, incomingRoute *router.Route,
|
||||
outgoingRoute *router.Route, peer *peer.Peer) error {
|
||||
|
||||
flow := &handleRequestHeadersFlow{
|
||||
RequestHeadersContext: context,
|
||||
incomingRoute: incomingRoute,
|
||||
outgoingRoute: outgoingRoute,
|
||||
peer: peer,
|
||||
RequestIBDBlocksContext: context,
|
||||
incomingRoute: incomingRoute,
|
||||
outgoingRoute: outgoingRoute,
|
||||
peer: peer,
|
||||
}
|
||||
return flow.start()
|
||||
}
|
||||
@@ -49,9 +49,8 @@ func (flow *handleRequestHeadersFlow) start() error {
|
||||
|
||||
// GetHashesBetween is a relatively heavy operation so we limit it
|
||||
// in order to avoid locking the consensus for too long
|
||||
// maxBlocks MUST be >= MergeSetSizeLimit + 1
|
||||
const maxBlocks = 1 << 10
|
||||
blockHashes, _, err := flow.Domain().Consensus().GetHashesBetween(lowHash, highHash, maxBlocks)
|
||||
const maxBlueScoreDifference = 1 << 10
|
||||
blockHashes, _, err := flow.Domain().Consensus().GetHashesBetween(lowHash, highHash, maxBlueScoreDifference)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
package blockrelay
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/app/protocol/common"
|
||||
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
|
||||
"github.com/kaspanet/kaspad/domain"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/infrastructure/logger"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
)
|
||||
|
||||
// HandleRequestPruningPointUTXOSetContext is the interface for the context needed for the HandleRequestPruningPointUTXOSet flow.
|
||||
type HandleRequestPruningPointUTXOSetContext interface {
|
||||
Domain() domain.Domain
|
||||
}
|
||||
|
||||
type handleRequestPruningPointUTXOSetFlow struct {
|
||||
HandleRequestPruningPointUTXOSetContext
|
||||
incomingRoute, outgoingRoute *router.Route
|
||||
}
|
||||
|
||||
// HandleRequestPruningPointUTXOSet listens to appmessage.MsgRequestPruningPointUTXOSet messages and sends
|
||||
// the pruning point UTXO set and block body.
|
||||
func HandleRequestPruningPointUTXOSet(context HandleRequestPruningPointUTXOSetContext, incomingRoute,
|
||||
outgoingRoute *router.Route) error {
|
||||
|
||||
flow := &handleRequestPruningPointUTXOSetFlow{
|
||||
HandleRequestPruningPointUTXOSetContext: context,
|
||||
incomingRoute: incomingRoute,
|
||||
outgoingRoute: outgoingRoute,
|
||||
}
|
||||
|
||||
return flow.start()
|
||||
}
|
||||
|
||||
func (flow *handleRequestPruningPointUTXOSetFlow) start() error {
|
||||
for {
|
||||
msgRequestPruningPointUTXOSet, err := flow.waitForRequestPruningPointUTXOSetMessages()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = flow.handleRequestPruningPointUTXOSetMessage(msgRequestPruningPointUTXOSet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (flow *handleRequestPruningPointUTXOSetFlow) handleRequestPruningPointUTXOSetMessage(
|
||||
msgRequestPruningPointUTXOSet *appmessage.MsgRequestPruningPointUTXOSet) error {
|
||||
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "handleRequestPruningPointUTXOSetFlow")
|
||||
defer onEnd()
|
||||
|
||||
log.Debugf("Got request for pruning point UTXO set")
|
||||
|
||||
return flow.sendPruningPointUTXOSet(msgRequestPruningPointUTXOSet)
|
||||
}
|
||||
|
||||
func (flow *handleRequestPruningPointUTXOSetFlow) waitForRequestPruningPointUTXOSetMessages() (
|
||||
*appmessage.MsgRequestPruningPointUTXOSet, error) {
|
||||
|
||||
message, err := flow.incomingRoute.Dequeue()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msgRequestPruningPointUTXOSet, ok := message.(*appmessage.MsgRequestPruningPointUTXOSet)
|
||||
if !ok {
|
||||
// TODO: Change to shouldBan: true once we fix the bug of getting redundant messages
|
||||
return nil, protocolerrors.Errorf(false, "received unexpected message type. "+
|
||||
"expected: %s, got: %s", appmessage.CmdRequestPruningPointUTXOSet, message.Command())
|
||||
}
|
||||
return msgRequestPruningPointUTXOSet, nil
|
||||
}
|
||||
|
||||
func (flow *handleRequestPruningPointUTXOSetFlow) sendPruningPointUTXOSet(
|
||||
msgRequestPruningPointUTXOSet *appmessage.MsgRequestPruningPointUTXOSet) error {
|
||||
|
||||
// Send the UTXO set in `step`-sized chunks
|
||||
const step = 1000
|
||||
var fromOutpoint *externalapi.DomainOutpoint
|
||||
chunksSent := 0
|
||||
for {
|
||||
pruningPointUTXOs, err := flow.Domain().Consensus().GetPruningPointUTXOs(
|
||||
msgRequestPruningPointUTXOSet.PruningPointHash, fromOutpoint, step)
|
||||
if err != nil {
|
||||
if errors.Is(err, ruleerrors.ErrWrongPruningPointHash) {
|
||||
return flow.outgoingRoute.Enqueue(appmessage.NewMsgUnexpectedPruningPoint())
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("Retrieved %d UTXOs for pruning block %s",
|
||||
len(pruningPointUTXOs), msgRequestPruningPointUTXOSet.PruningPointHash)
|
||||
|
||||
outpointAndUTXOEntryPairs :=
|
||||
appmessage.DomainOutpointAndUTXOEntryPairsToOutpointAndUTXOEntryPairs(pruningPointUTXOs)
|
||||
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgPruningPointUTXOSetChunk(outpointAndUTXOEntryPairs))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
finished := len(pruningPointUTXOs) < step
|
||||
if finished && chunksSent%ibdBatchSize != 0 {
|
||||
log.Debugf("Finished sending UTXOs for pruning block %s",
|
||||
msgRequestPruningPointUTXOSet.PruningPointHash)
|
||||
|
||||
return flow.outgoingRoute.Enqueue(appmessage.NewMsgDonePruningPointUTXOSetChunks())
|
||||
}
|
||||
|
||||
if len(pruningPointUTXOs) > 0 {
|
||||
fromOutpoint = pruningPointUTXOs[len(pruningPointUTXOs)-1].Outpoint
|
||||
}
|
||||
chunksSent++
|
||||
|
||||
// Wait for the peer to request more chunks every `ibdBatchSize` chunks
|
||||
if chunksSent%ibdBatchSize == 0 {
|
||||
message, err := flow.incomingRoute.DequeueWithTimeout(common.DefaultTimeout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, ok := message.(*appmessage.MsgRequestNextPruningPointUTXOSetChunk)
|
||||
if !ok {
|
||||
// TODO: Change to shouldBan: true once we fix the bug of getting redundant messages
|
||||
return protocolerrors.Errorf(false, "received unexpected message type. "+
|
||||
"expected: %s, got: %s", appmessage.CmdRequestNextPruningPointUTXOSetChunk, message.Command())
|
||||
}
|
||||
|
||||
if finished {
|
||||
log.Debugf("Finished sending UTXOs for pruning block %s",
|
||||
msgRequestPruningPointUTXOSet.PruningPointHash)
|
||||
|
||||
return flow.outgoingRoute.Enqueue(appmessage.NewMsgDonePruningPointUTXOSetChunks())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package blockrelay
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/app/protocol/common"
|
||||
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
|
||||
"github.com/kaspanet/kaspad/domain"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/infrastructure/logger"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
)
|
||||
|
||||
// HandleRequestPruningPointUTXOSetAndBlockContext is the interface for the context needed for the HandleRequestPruningPointUTXOSetAndBlock flow.
|
||||
type HandleRequestPruningPointUTXOSetAndBlockContext interface {
|
||||
Domain() domain.Domain
|
||||
}
|
||||
|
||||
type handleRequestPruningPointUTXOSetAndBlockFlow struct {
|
||||
HandleRequestPruningPointUTXOSetAndBlockContext
|
||||
incomingRoute, outgoingRoute *router.Route
|
||||
}
|
||||
|
||||
// HandleRequestPruningPointUTXOSetAndBlock listens to appmessage.MsgRequestPruningPointUTXOSetAndBlock messages and sends
|
||||
// the pruning point UTXO set and block body.
|
||||
func HandleRequestPruningPointUTXOSetAndBlock(context HandleRequestPruningPointUTXOSetAndBlockContext, incomingRoute,
|
||||
outgoingRoute *router.Route) error {
|
||||
flow := &handleRequestPruningPointUTXOSetAndBlockFlow{
|
||||
HandleRequestPruningPointUTXOSetAndBlockContext: context,
|
||||
incomingRoute: incomingRoute,
|
||||
outgoingRoute: outgoingRoute,
|
||||
}
|
||||
|
||||
return flow.start()
|
||||
}
|
||||
|
||||
func (flow *handleRequestPruningPointUTXOSetAndBlockFlow) start() error {
|
||||
for {
|
||||
msgRequestPruningPointUTXOSetAndBlock, err := flow.waitForRequestPruningPointUTXOSetAndBlockMessages()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = flow.handleRequestPruningPointUTXOSetAndBlockMessage(msgRequestPruningPointUTXOSetAndBlock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (flow *handleRequestPruningPointUTXOSetAndBlockFlow) handleRequestPruningPointUTXOSetAndBlockMessage(
|
||||
msgRequestPruningPointUTXOSetAndBlock *appmessage.MsgRequestPruningPointUTXOSetAndBlock) error {
|
||||
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "handleRequestPruningPointUTXOSetAndBlockFlow")
|
||||
defer onEnd()
|
||||
|
||||
log.Debugf("Got request for PruningPointHash UTXOSet and Block")
|
||||
|
||||
err := flow.sendPruningPointBlock(msgRequestPruningPointUTXOSetAndBlock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return flow.sendPruningPointUTXOSet(msgRequestPruningPointUTXOSetAndBlock)
|
||||
}
|
||||
|
||||
func (flow *handleRequestPruningPointUTXOSetAndBlockFlow) waitForRequestPruningPointUTXOSetAndBlockMessages() (
|
||||
*appmessage.MsgRequestPruningPointUTXOSetAndBlock, error) {
|
||||
|
||||
message, err := flow.incomingRoute.Dequeue()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msgRequestPruningPointUTXOSetAndBlock, ok := message.(*appmessage.MsgRequestPruningPointUTXOSetAndBlock)
|
||||
if !ok {
|
||||
return nil, protocolerrors.Errorf(true, "received unexpected message type. "+
|
||||
"expected: %s, got: %s", appmessage.CmdRequestPruningPointUTXOSetAndBlock, message.Command())
|
||||
}
|
||||
return msgRequestPruningPointUTXOSetAndBlock, nil
|
||||
}
|
||||
|
||||
func (flow *handleRequestPruningPointUTXOSetAndBlockFlow) sendPruningPointBlock(
|
||||
msgRequestPruningPointUTXOSetAndBlock *appmessage.MsgRequestPruningPointUTXOSetAndBlock) error {
|
||||
|
||||
block, err := flow.Domain().Consensus().GetBlock(msgRequestPruningPointUTXOSetAndBlock.PruningPointHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debugf("Retrieved pruning block %s", msgRequestPruningPointUTXOSetAndBlock.PruningPointHash)
|
||||
|
||||
return flow.outgoingRoute.Enqueue(appmessage.NewMsgIBDBlock(appmessage.DomainBlockToMsgBlock(block)))
|
||||
}
|
||||
|
||||
func (flow *handleRequestPruningPointUTXOSetAndBlockFlow) sendPruningPointUTXOSet(
|
||||
msgRequestPruningPointUTXOSetAndBlock *appmessage.MsgRequestPruningPointUTXOSetAndBlock) error {
|
||||
|
||||
// Send the UTXO set in `step`-sized chunks
|
||||
const step = 1000
|
||||
var fromOutpoint *externalapi.DomainOutpoint
|
||||
chunksSent := 0
|
||||
for {
|
||||
pruningPointUTXOs, err := flow.Domain().Consensus().GetPruningPointUTXOs(
|
||||
msgRequestPruningPointUTXOSetAndBlock.PruningPointHash, fromOutpoint, step)
|
||||
if err != nil {
|
||||
if errors.Is(err, ruleerrors.ErrWrongPruningPointHash) {
|
||||
return flow.outgoingRoute.Enqueue(appmessage.NewMsgUnexpectedPruningPoint())
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("Retrieved %d UTXOs for pruning block %s",
|
||||
len(pruningPointUTXOs), msgRequestPruningPointUTXOSetAndBlock.PruningPointHash)
|
||||
|
||||
outpointAndUTXOEntryPairs :=
|
||||
appmessage.DomainOutpointAndUTXOEntryPairsToOutpointAndUTXOEntryPairs(pruningPointUTXOs)
|
||||
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgPruningPointUTXOSetChunk(outpointAndUTXOEntryPairs))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(pruningPointUTXOs) < step {
|
||||
log.Debugf("Finished sending UTXOs for pruning block %s",
|
||||
msgRequestPruningPointUTXOSetAndBlock.PruningPointHash)
|
||||
|
||||
return flow.outgoingRoute.Enqueue(appmessage.NewMsgDonePruningPointUTXOSetChunks())
|
||||
}
|
||||
|
||||
fromOutpoint = pruningPointUTXOs[len(pruningPointUTXOs)-1].Outpoint
|
||||
chunksSent++
|
||||
|
||||
// Wait for the peer to request more chunks every `ibdBatchSize` chunks
|
||||
if chunksSent%ibdBatchSize == 0 {
|
||||
message, err := flow.incomingRoute.DequeueWithTimeout(common.DefaultTimeout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, ok := message.(*appmessage.MsgRequestNextPruningPointUTXOSetChunk)
|
||||
if !ok {
|
||||
return protocolerrors.Errorf(true, "received unexpected message type. "+
|
||||
"expected: %s, got: %s", appmessage.CmdRequestNextPruningPointUTXOSetChunk, message.Command())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package blockrelay
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/kaspanet/kaspad/infrastructure/logger"
|
||||
@@ -16,80 +17,78 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (flow *handleRelayInvsFlow) runIBDIfNotRunning(block *externalapi.DomainBlock) error {
|
||||
func (flow *handleRelayInvsFlow) runIBDIfNotRunning(highHash *externalapi.DomainHash) error {
|
||||
wasIBDNotRunning := flow.TrySetIBDRunning(flow.peer)
|
||||
if !wasIBDNotRunning {
|
||||
log.Debugf("IBD is already running")
|
||||
return nil
|
||||
}
|
||||
defer flow.UnsetIBDRunning()
|
||||
|
||||
isFinishedSuccessfully := false
|
||||
defer func() {
|
||||
flow.UnsetIBDRunning()
|
||||
flow.logIBDFinished(isFinishedSuccessfully)
|
||||
}()
|
||||
|
||||
highHash := consensushashing.BlockHash(block)
|
||||
log.Debugf("IBD started with peer %s and highHash %s", flow.peer, highHash)
|
||||
log.Debugf("Syncing blocks up to %s", highHash)
|
||||
log.Debugf("Trying to find highest shared chain block with peer %s with high hash %s", flow.peer, highHash)
|
||||
highestSharedBlockHash, highestSharedBlockFound, err := flow.findHighestSharedBlockHash(highHash)
|
||||
|
||||
log.Debugf("Syncing headers up to %s", highHash)
|
||||
headersSynced, err := flow.syncHeaders(highHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debugf("Found highest shared chain block %s with peer %s", highestSharedBlockHash, flow.peer)
|
||||
|
||||
shouldDownloadHeadersProof, shouldSync, err := flow.shouldSyncAndShouldDownloadHeadersProof(block, highestSharedBlockFound)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !shouldSync {
|
||||
if !headersSynced {
|
||||
log.Debugf("Aborting IBD because the headers failed to sync")
|
||||
return nil
|
||||
}
|
||||
log.Debugf("Finished syncing headers up to %s", highHash)
|
||||
|
||||
if shouldDownloadHeadersProof {
|
||||
log.Infof("Starting IBD with headers proof")
|
||||
err := flow.ibdWithHeadersProof(highHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if flow.Config().NetParams().DisallowDirectBlocksOnTopOfGenesis && !flow.Config().AllowSubmitBlockWhenNotSynced {
|
||||
isGenesisVirtualSelectedParent, err := flow.isGenesisVirtualSelectedParent()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if isGenesisVirtualSelectedParent {
|
||||
log.Infof("Cannot IBD to %s because it won't change the pruning point. The node needs to IBD "+
|
||||
"to the recent pruning point before normal operation can resume.", highHash)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
err = flow.syncPruningPointFutureHeaders(flow.Domain().Consensus(), highestSharedBlockHash, highHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debugf("Syncing the current pruning point UTXO set")
|
||||
syncedPruningPointUTXOSetSuccessfully, err := flow.syncPruningPointUTXOSet()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !syncedPruningPointUTXOSetSuccessfully {
|
||||
log.Debugf("Aborting IBD because the pruning point UTXO set failed to sync")
|
||||
return nil
|
||||
}
|
||||
log.Debugf("Finished syncing the current pruning point UTXO set")
|
||||
|
||||
log.Debugf("Downloading block bodies up to %s", highHash)
|
||||
err = flow.syncMissingBlockBodies(highHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debugf("Finished downloading block bodies up to %s", highHash)
|
||||
|
||||
log.Debugf("Finished syncing blocks up to %s", highHash)
|
||||
isFinishedSuccessfully = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) logIBDFinished(isFinishedSuccessfully bool) {
|
||||
successString := "successfully"
|
||||
if !isFinishedSuccessfully {
|
||||
successString = "(interrupted)"
|
||||
// syncHeaders attempts to sync headers from the peer. This method may fail
|
||||
// because the peer and us have conflicting pruning points. In that case we
|
||||
// return (false, nil) so that we may stop IBD gracefully.
|
||||
func (flow *handleRelayInvsFlow) syncHeaders(highHash *externalapi.DomainHash) (bool, error) {
|
||||
log.Debugf("Trying to find highest shared chain block with peer %s with high hash %s", flow.peer, highHash)
|
||||
highestSharedBlockHash, highestSharedBlockFound, err := flow.findHighestSharedBlockHash(highHash)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
log.Infof("IBD finished %s", successString)
|
||||
if !highestSharedBlockFound {
|
||||
return false, nil
|
||||
}
|
||||
log.Debugf("Found highest shared chain block %s with peer %s", highestSharedBlockHash, flow.peer)
|
||||
|
||||
err = flow.downloadHeaders(highestSharedBlockHash, highHash)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// If the highHash has not been received, the peer is misbehaving
|
||||
highHashBlockInfo, err := flow.Domain().Consensus().GetBlockInfo(highHash)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !highHashBlockInfo.Exists {
|
||||
return false, protocolerrors.Errorf(true, "did not receive "+
|
||||
"highHash header %s from peer %s during header download", highHash, flow.peer)
|
||||
}
|
||||
log.Debugf("Headers downloaded from peer %s", flow.peer)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// findHighestSharedBlock attempts to find the highest shared block between the peer
|
||||
@@ -209,22 +208,20 @@ func (flow *handleRelayInvsFlow) fetchHighestHash(
|
||||
}
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) syncPruningPointFutureHeaders(consensus externalapi.Consensus, highestSharedBlockHash *externalapi.DomainHash,
|
||||
func (flow *handleRelayInvsFlow) downloadHeaders(highestSharedBlockHash *externalapi.DomainHash,
|
||||
highHash *externalapi.DomainHash) error {
|
||||
|
||||
log.Infof("Downloading headers from %s", flow.peer)
|
||||
|
||||
err := flow.sendRequestHeaders(highestSharedBlockHash, highHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Keep a short queue of BlockHeadersMessages so that there's
|
||||
// Keep a short queue of blockHeadersMessages so that there's
|
||||
// never a moment when the node is not validating and inserting
|
||||
// headers
|
||||
blockHeadersMessageChan := make(chan *appmessage.BlockHeadersMessage, 2)
|
||||
errChan := make(chan error)
|
||||
spawn("handleRelayInvsFlow-syncPruningPointFutureHeaders", func() {
|
||||
spawn("handleRelayInvsFlow-downloadHeaders", func() {
|
||||
for {
|
||||
blockHeadersMessage, doneIBD, err := flow.receiveHeaders()
|
||||
if err != nil {
|
||||
@@ -248,21 +245,12 @@ func (flow *handleRelayInvsFlow) syncPruningPointFutureHeaders(consensus externa
|
||||
|
||||
for {
|
||||
select {
|
||||
case ibdBlocksMessage, ok := <-blockHeadersMessageChan:
|
||||
case blockHeadersMessage, ok := <-blockHeadersMessageChan:
|
||||
if !ok {
|
||||
// If the highHash has not been received, the peer is misbehaving
|
||||
highHashBlockInfo, err := consensus.GetBlockInfo(highHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !highHashBlockInfo.Exists {
|
||||
return protocolerrors.Errorf(true, "did not receive "+
|
||||
"highHash block %s from peer %s during block download", highHash, flow.peer)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
for _, header := range ibdBlocksMessage.BlockHeaders {
|
||||
err = flow.processHeader(consensus, header)
|
||||
for _, header := range blockHeadersMessage.BlockHeaders {
|
||||
err = flow.processHeader(header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -280,7 +268,7 @@ func (flow *handleRelayInvsFlow) sendRequestHeaders(highestSharedBlockHash *exte
|
||||
return flow.outgoingRoute.Enqueue(msgGetBlockInvs)
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) receiveHeaders() (msgIBDBlock *appmessage.BlockHeadersMessage, doneHeaders bool, err error) {
|
||||
func (flow *handleRelayInvsFlow) receiveHeaders() (msgIBDBlock *appmessage.BlockHeadersMessage, doneIBD bool, err error) {
|
||||
message, err := flow.dequeueIncomingMessageAndSkipInvs(common.DefaultTimeout)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
@@ -293,14 +281,11 @@ func (flow *handleRelayInvsFlow) receiveHeaders() (msgIBDBlock *appmessage.Block
|
||||
default:
|
||||
return nil, false,
|
||||
protocolerrors.Errorf(true, "received unexpected message type. "+
|
||||
"expected: %s or %s, got: %s",
|
||||
appmessage.CmdBlockHeaders,
|
||||
appmessage.CmdDoneHeaders,
|
||||
message.Command())
|
||||
"expected: %s or %s, got: %s", appmessage.CmdHeader, appmessage.CmdDoneHeaders, message.Command())
|
||||
}
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) processHeader(consensus externalapi.Consensus, msgBlockHeader *appmessage.MsgBlockHeader) error {
|
||||
func (flow *handleRelayInvsFlow) processHeader(msgBlockHeader *appmessage.MsgBlockHeader) error {
|
||||
header := appmessage.BlockHeaderToDomainBlockHeader(msgBlockHeader)
|
||||
block := &externalapi.DomainBlock{
|
||||
Header: header,
|
||||
@@ -308,7 +293,7 @@ func (flow *handleRelayInvsFlow) processHeader(consensus externalapi.Consensus,
|
||||
}
|
||||
|
||||
blockHash := consensushashing.BlockHash(block)
|
||||
blockInfo, err := consensus.GetBlockInfo(blockHash)
|
||||
blockInfo, err := flow.Domain().Consensus().GetBlockInfo(blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -316,7 +301,7 @@ func (flow *handleRelayInvsFlow) processHeader(consensus externalapi.Consensus,
|
||||
log.Debugf("Block header %s is already in the DAG. Skipping...", blockHash)
|
||||
return nil
|
||||
}
|
||||
_, err = consensus.ValidateAndInsertBlock(block, false)
|
||||
_, err = flow.Domain().Consensus().ValidateAndInsertBlock(block)
|
||||
if err != nil {
|
||||
if !errors.As(err, &ruleerrors.RuleError{}) {
|
||||
return errors.Wrapf(err, "failed to process header %s during IBD", blockHash)
|
||||
@@ -333,42 +318,129 @@ func (flow *handleRelayInvsFlow) processHeader(consensus externalapi.Consensus,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) validatePruningPointFutureHeaderTimestamps() error {
|
||||
headerSelectedTipHash, err := flow.Domain().StagingConsensus().GetHeadersSelectedTip()
|
||||
func (flow *handleRelayInvsFlow) syncPruningPointUTXOSet() (bool, error) {
|
||||
log.Debugf("Checking if a new pruning point is available")
|
||||
err := flow.outgoingRoute.Enqueue(appmessage.NewMsgRequestPruningPointHashMessage())
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
headerSelectedTipHeader, err := flow.Domain().StagingConsensus().GetBlockHeader(headerSelectedTipHash)
|
||||
message, err := flow.dequeueIncomingMessageAndSkipInvs(common.DefaultTimeout)
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
headerSelectedTipTimestamp := headerSelectedTipHeader.TimeInMilliseconds()
|
||||
|
||||
currentSelectedTipHash, err := flow.Domain().Consensus().GetHeadersSelectedTip()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
currentSelectedTipHeader, err := flow.Domain().Consensus().GetBlockHeader(currentSelectedTipHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
currentSelectedTipTimestamp := currentSelectedTipHeader.TimeInMilliseconds()
|
||||
|
||||
if headerSelectedTipTimestamp < currentSelectedTipTimestamp {
|
||||
return protocolerrors.Errorf(false, "the timestamp of the candidate selected "+
|
||||
"tip is smaller than the current selected tip")
|
||||
msgPruningPointHash, ok := message.(*appmessage.MsgPruningPointHashMessage)
|
||||
if !ok {
|
||||
return false, protocolerrors.Errorf(true, "received unexpected message type. "+
|
||||
"expected: %s, got: %s", appmessage.CmdPruningPointHash, message.Command())
|
||||
}
|
||||
|
||||
minTimestampDifferenceInMilliseconds := (10 * time.Minute).Milliseconds()
|
||||
if headerSelectedTipTimestamp-currentSelectedTipTimestamp < minTimestampDifferenceInMilliseconds {
|
||||
return protocolerrors.Errorf(false, "difference between the timestamps of "+
|
||||
"the current pruning point and the candidate pruning point is too small. Aborting IBD...")
|
||||
blockInfo, err := flow.Domain().Consensus().GetBlockInfo(msgPruningPointHash.Hash)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return nil
|
||||
|
||||
if !blockInfo.Exists {
|
||||
return false, errors.Errorf("The pruning point header is missing")
|
||||
}
|
||||
|
||||
if blockInfo.BlockStatus != externalapi.StatusHeaderOnly {
|
||||
log.Debugf("Already has the block data of the new suggested pruning point %s", msgPruningPointHash.Hash)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
log.Infof("Checking if the suggested pruning point %s is compatible to the node DAG", msgPruningPointHash.Hash)
|
||||
isValid, err := flow.Domain().Consensus().IsValidPruningPoint(msgPruningPointHash.Hash)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !isValid {
|
||||
log.Infof("The suggested pruning point %s is incompatible to this node DAG, so stopping IBD with this"+
|
||||
" peer", msgPruningPointHash.Hash)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
log.Info("Fetching the pruning point UTXO set")
|
||||
succeed, err := flow.fetchMissingUTXOSet(msgPruningPointHash.Hash)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !succeed {
|
||||
log.Infof("Couldn't successfully fetch the pruning point UTXO set. Stopping IBD.")
|
||||
return false, nil
|
||||
}
|
||||
|
||||
log.Info("Fetched the new pruning point UTXO set")
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) fetchMissingUTXOSet(pruningPointHash *externalapi.DomainHash) (succeed bool, err error) {
|
||||
defer func() {
|
||||
err := flow.Domain().Consensus().ClearImportedPruningPointData()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to clear imported pruning point data: %s", err))
|
||||
}
|
||||
}()
|
||||
|
||||
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgRequestPruningPointUTXOSetAndBlock(pruningPointHash))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
block, err := flow.receivePruningPointBlock()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
receivedAll, err := flow.receiveAndInsertPruningPointUTXOSet(pruningPointHash)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !receivedAll {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
err = flow.Domain().Consensus().ValidateAndInsertImportedPruningPoint(block)
|
||||
if err != nil {
|
||||
// TODO: Find a better way to deal with finality conflicts.
|
||||
if errors.Is(err, ruleerrors.ErrSuggestedPruningViolatesFinality) {
|
||||
return false, nil
|
||||
}
|
||||
return false, protocolerrors.ConvertToBanningProtocolErrorIfRuleError(err, "error with pruning point UTXO set")
|
||||
}
|
||||
|
||||
err = flow.OnPruningPointUTXOSetOverride()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) receivePruningPointBlock() (*externalapi.DomainBlock, error) {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "receivePruningPointBlock")
|
||||
defer onEnd()
|
||||
|
||||
message, err := flow.dequeueIncomingMessageAndSkipInvs(common.DefaultTimeout)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ibdBlockMessage, ok := message.(*appmessage.MsgIBDBlock)
|
||||
if !ok {
|
||||
return nil, protocolerrors.Errorf(true, "received unexpected message type. "+
|
||||
"expected: %s, got: %s", appmessage.CmdIBDBlock, message.Command())
|
||||
}
|
||||
block := appmessage.MsgBlockToDomainBlock(ibdBlockMessage.MsgBlock)
|
||||
|
||||
log.Debugf("Received pruning point block %s", consensushashing.BlockHash(block))
|
||||
|
||||
return block, nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) receiveAndInsertPruningPointUTXOSet(
|
||||
consensus externalapi.Consensus, pruningPointHash *externalapi.DomainHash) (bool, error) {
|
||||
pruningPointHash *externalapi.DomainHash) (bool, error) {
|
||||
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "receiveAndInsertPruningPointUTXOSet")
|
||||
defer onEnd()
|
||||
@@ -387,7 +459,7 @@ func (flow *handleRelayInvsFlow) receiveAndInsertPruningPointUTXOSet(
|
||||
domainOutpointAndUTXOEntryPairs :=
|
||||
appmessage.OutpointAndUTXOEntryPairsToDomainOutpointAndUTXOEntryPairs(message.OutpointAndUTXOEntryPairs)
|
||||
|
||||
err := consensus.AppendImportedPruningPointUTXOs(domainOutpointAndUTXOEntryPairs)
|
||||
err := flow.Domain().Consensus().AppendImportedPruningPointUTXOs(domainOutpointAndUTXOEntryPairs)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -471,7 +543,7 @@ func (flow *handleRelayInvsFlow) syncMissingBlockBodies(highHash *externalapi.Do
|
||||
return err
|
||||
}
|
||||
|
||||
virtualChangeSet, err := flow.Domain().Consensus().ValidateAndInsertBlock(block, false)
|
||||
blockInsertionResult, err := flow.Domain().Consensus().ValidateAndInsertBlock(block)
|
||||
if err != nil {
|
||||
if errors.Is(err, ruleerrors.ErrDuplicateBlock) {
|
||||
log.Debugf("Skipping IBD Block %s as it has already been added to the DAG", blockHash)
|
||||
@@ -479,36 +551,14 @@ func (flow *handleRelayInvsFlow) syncMissingBlockBodies(highHash *externalapi.Do
|
||||
}
|
||||
return protocolerrors.ConvertToBanningProtocolErrorIfRuleError(err, "invalid block %s", blockHash)
|
||||
}
|
||||
err = flow.OnNewBlock(block, virtualChangeSet)
|
||||
err = flow.OnNewBlock(block, blockInsertionResult)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return flow.resolveVirtual()
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) resolveVirtual() error {
|
||||
for i := 0; ; i++ {
|
||||
if i%10 == 0 {
|
||||
log.Infof("Resolving virtual. This may take some time...")
|
||||
}
|
||||
virtualChangeSet, isCompletelyResolved, err := flow.Domain().Consensus().ResolveVirtual()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = flow.OnVirtualChange(virtualChangeSet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if isCompletelyResolved {
|
||||
log.Infof("Resolved virtual")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// dequeueIncomingMessageAndSkipInvs is a convenience method to be used during
|
||||
|
||||
@@ -1,364 +0,0 @@
|
||||
package blockrelay
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/app/protocol/common"
|
||||
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (flow *handleRelayInvsFlow) ibdWithHeadersProof(highHash *externalapi.DomainHash) error {
|
||||
err := flow.Domain().InitStagingConsensus()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = flow.downloadHeadersAndPruningUTXOSet(highHash)
|
||||
if err != nil {
|
||||
if !flow.IsRecoverableError(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
deleteStagingConsensusErr := flow.Domain().DeleteStagingConsensus()
|
||||
if deleteStagingConsensusErr != nil {
|
||||
return deleteStagingConsensusErr
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
err = flow.Domain().CommitStagingConsensus()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) shouldSyncAndShouldDownloadHeadersProof(highBlock *externalapi.DomainBlock,
|
||||
highestSharedBlockFound bool) (shouldDownload, shouldSync bool, err error) {
|
||||
|
||||
if !highestSharedBlockFound {
|
||||
hasMoreBlueWorkThanSelectedTipAndPruningDepthMoreBlueScore, err := flow.checkIfHighHashHasMoreBlueWorkThanSelectedTipAndPruningDepthMoreBlueScore(highBlock)
|
||||
if err != nil {
|
||||
return false, false, err
|
||||
}
|
||||
|
||||
if hasMoreBlueWorkThanSelectedTipAndPruningDepthMoreBlueScore {
|
||||
return true, true, nil
|
||||
}
|
||||
|
||||
return false, false, nil
|
||||
}
|
||||
|
||||
return false, true, nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) checkIfHighHashHasMoreBlueWorkThanSelectedTipAndPruningDepthMoreBlueScore(highBlock *externalapi.DomainBlock) (bool, error) {
|
||||
headersSelectedTip, err := flow.Domain().Consensus().GetHeadersSelectedTip()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
headersSelectedTipInfo, err := flow.Domain().Consensus().GetBlockInfo(headersSelectedTip)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if highBlock.Header.BlueScore() < headersSelectedTipInfo.BlueScore+flow.Config().NetParams().PruningDepth() {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return highBlock.Header.BlueWork().Cmp(headersSelectedTipInfo.BlueWork) > 0, nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) syncAndValidatePruningPointProof() (*externalapi.DomainHash, error) {
|
||||
log.Infof("Downloading the pruning point proof from %s", flow.peer)
|
||||
err := flow.outgoingRoute.Enqueue(appmessage.NewMsgRequestPruningPointProof())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
message, err := flow.dequeueIncomingMessageAndSkipInvs(common.DefaultTimeout)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pruningPointProofMessage, ok := message.(*appmessage.MsgPruningPointProof)
|
||||
if !ok {
|
||||
return nil, protocolerrors.Errorf(true, "received unexpected message type. "+
|
||||
"expected: %s, got: %s", appmessage.CmdPruningPointProof, message.Command())
|
||||
}
|
||||
pruningPointProof := appmessage.MsgPruningPointProofToDomainPruningPointProof(pruningPointProofMessage)
|
||||
err = flow.Domain().Consensus().ValidatePruningPointProof(pruningPointProof)
|
||||
if err != nil {
|
||||
if errors.As(err, &ruleerrors.RuleError{}) {
|
||||
return nil, protocolerrors.Wrapf(true, err, "pruning point proof validation failed")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = flow.Domain().StagingConsensus().ApplyPruningPointProof(pruningPointProof)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return consensushashing.HeaderHash(pruningPointProof.Headers[0][len(pruningPointProof.Headers[0])-1]), nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) downloadHeadersAndPruningUTXOSet(highHash *externalapi.DomainHash) error {
|
||||
proofPruningPoint, err := flow.syncAndValidatePruningPointProof()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = flow.syncPruningPointsAndPruningPointAnticone(proofPruningPoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: Remove this condition once there's more proper way to check finality violation
|
||||
// in the headers proof.
|
||||
if proofPruningPoint.Equal(flow.Config().NetParams().GenesisHash) {
|
||||
return protocolerrors.Errorf(true, "the genesis pruning point violates finality")
|
||||
}
|
||||
|
||||
err = flow.syncPruningPointFutureHeaders(flow.Domain().StagingConsensus(), proofPruningPoint, highHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("Headers downloaded from peer %s", flow.peer)
|
||||
|
||||
highHashInfo, err := flow.Domain().StagingConsensus().GetBlockInfo(highHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !highHashInfo.Exists {
|
||||
return protocolerrors.Errorf(true, "the triggering IBD block was not sent")
|
||||
}
|
||||
|
||||
err = flow.validatePruningPointFutureHeaderTimestamps()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("Syncing the current pruning point UTXO set")
|
||||
syncedPruningPointUTXOSetSuccessfully, err := flow.syncPruningPointUTXOSet(flow.Domain().StagingConsensus(), proofPruningPoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !syncedPruningPointUTXOSetSuccessfully {
|
||||
log.Debugf("Aborting IBD because the pruning point UTXO set failed to sync")
|
||||
return nil
|
||||
}
|
||||
log.Debugf("Finished syncing the current pruning point UTXO set")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) syncPruningPointsAndPruningPointAnticone(proofPruningPoint *externalapi.DomainHash) error {
|
||||
log.Infof("Downloading the past pruning points and the pruning point anticone from %s", flow.peer)
|
||||
err := flow.outgoingRoute.Enqueue(appmessage.NewMsgRequestPruningPointAndItsAnticone())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = flow.validateAndInsertPruningPoints(proofPruningPoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pruningPointWithMetaData, done, err := flow.receiveBlockWithTrustedData()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if done {
|
||||
return protocolerrors.Errorf(true, "got `done` message before receiving the pruning point")
|
||||
}
|
||||
|
||||
if !pruningPointWithMetaData.Block.Header.BlockHash().Equal(proofPruningPoint) {
|
||||
return protocolerrors.Errorf(true, "first block with trusted data is not the pruning point")
|
||||
}
|
||||
|
||||
err = flow.processBlockWithTrustedData(flow.Domain().StagingConsensus(), pruningPointWithMetaData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for {
|
||||
blockWithTrustedData, done, err := flow.receiveBlockWithTrustedData()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if done {
|
||||
break
|
||||
}
|
||||
|
||||
err = flow.processBlockWithTrustedData(flow.Domain().StagingConsensus(), blockWithTrustedData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("Finished downloading pruning point and its anticone from %s", flow.peer)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) processBlockWithTrustedData(
|
||||
consensus externalapi.Consensus, block *appmessage.MsgBlockWithTrustedData) error {
|
||||
|
||||
_, err := consensus.ValidateAndInsertBlockWithTrustedData(appmessage.BlockWithTrustedDataToDomainBlockWithTrustedData(block), false)
|
||||
return err
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) receiveBlockWithTrustedData() (*appmessage.MsgBlockWithTrustedData, bool, error) {
|
||||
message, err := flow.dequeueIncomingMessageAndSkipInvs(common.DefaultTimeout)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
switch downCastedMessage := message.(type) {
|
||||
case *appmessage.MsgBlockWithTrustedData:
|
||||
return downCastedMessage, false, nil
|
||||
case *appmessage.MsgDoneBlocksWithTrustedData:
|
||||
return nil, true, nil
|
||||
default:
|
||||
return nil, false,
|
||||
protocolerrors.Errorf(true, "received unexpected message type. "+
|
||||
"expected: %s or %s, got: %s",
|
||||
(&appmessage.MsgBlockWithTrustedData{}).Command(),
|
||||
(&appmessage.MsgDoneBlocksWithTrustedData{}).Command(),
|
||||
downCastedMessage.Command())
|
||||
}
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) receivePruningPoints() (*appmessage.MsgPruningPoints, error) {
|
||||
message, err := flow.dequeueIncomingMessageAndSkipInvs(common.DefaultTimeout)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgPruningPoints, ok := message.(*appmessage.MsgPruningPoints)
|
||||
if !ok {
|
||||
return nil,
|
||||
protocolerrors.Errorf(true, "received unexpected message type. "+
|
||||
"expected: %s, got: %s", appmessage.CmdPruningPoints, message.Command())
|
||||
}
|
||||
|
||||
return msgPruningPoints, nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) validateAndInsertPruningPoints(proofPruningPoint *externalapi.DomainHash) error {
|
||||
currentPruningPoint, err := flow.Domain().Consensus().PruningPoint()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if currentPruningPoint.Equal(proofPruningPoint) {
|
||||
return protocolerrors.Errorf(true, "the proposed pruning point is the same as the current pruning point")
|
||||
}
|
||||
|
||||
pruningPoints, err := flow.receivePruningPoints()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
headers := make([]externalapi.BlockHeader, len(pruningPoints.Headers))
|
||||
for i, header := range pruningPoints.Headers {
|
||||
headers[i] = appmessage.BlockHeaderToDomainBlockHeader(header)
|
||||
}
|
||||
|
||||
arePruningPointsViolatingFinality, err := flow.Domain().Consensus().ArePruningPointsViolatingFinality(headers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if arePruningPointsViolatingFinality {
|
||||
// TODO: Find a better way to deal with finality conflicts.
|
||||
return protocolerrors.Errorf(false, "pruning points are violating finality")
|
||||
}
|
||||
|
||||
lastPruningPoint := consensushashing.HeaderHash(headers[len(headers)-1])
|
||||
if !lastPruningPoint.Equal(proofPruningPoint) {
|
||||
return protocolerrors.Errorf(true, "the proof pruning point is not equal to the last pruning "+
|
||||
"point in the list")
|
||||
}
|
||||
|
||||
err = flow.Domain().StagingConsensus().ImportPruningPoints(headers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) syncPruningPointUTXOSet(consensus externalapi.Consensus,
|
||||
pruningPoint *externalapi.DomainHash) (bool, error) {
|
||||
|
||||
log.Infof("Checking if the suggested pruning point %s is compatible to the node DAG", pruningPoint)
|
||||
isValid, err := flow.Domain().StagingConsensus().IsValidPruningPoint(pruningPoint)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !isValid {
|
||||
return false, protocolerrors.Errorf(true, "invalid pruning point %s", pruningPoint)
|
||||
}
|
||||
|
||||
log.Info("Fetching the pruning point UTXO set")
|
||||
isSuccessful, err := flow.fetchMissingUTXOSet(consensus, pruningPoint)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !isSuccessful {
|
||||
log.Infof("Couldn't successfully fetch the pruning point UTXO set. Stopping IBD.")
|
||||
return false, nil
|
||||
}
|
||||
|
||||
log.Info("Fetched the new pruning point UTXO set")
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (flow *handleRelayInvsFlow) fetchMissingUTXOSet(consensus externalapi.Consensus, pruningPointHash *externalapi.DomainHash) (succeed bool, err error) {
|
||||
defer func() {
|
||||
err := flow.Domain().StagingConsensus().ClearImportedPruningPointData()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to clear imported pruning point data: %s", err))
|
||||
}
|
||||
}()
|
||||
|
||||
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgRequestPruningPointUTXOSet(pruningPointHash))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
receivedAll, err := flow.receiveAndInsertPruningPointUTXOSet(consensus, pruningPointHash)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !receivedAll {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
err = flow.Domain().StagingConsensus().ValidateAndInsertImportedPruningPoint(pruningPointHash)
|
||||
if err != nil {
|
||||
// TODO: Find a better way to deal with finality conflicts.
|
||||
if errors.Is(err, ruleerrors.ErrSuggestedPruningViolatesFinality) {
|
||||
return false, nil
|
||||
}
|
||||
return false, protocolerrors.ConvertToBanningProtocolErrorIfRuleError(err, "error with pruning point UTXO set")
|
||||
}
|
||||
|
||||
err = flow.OnPruningPointUTXOSetOverride()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
@@ -4,14 +4,12 @@ import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
|
||||
"github.com/kaspanet/kaspad/domain"
|
||||
"github.com/kaspanet/kaspad/infrastructure/config"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
)
|
||||
|
||||
// SendVirtualSelectedParentInvContext is the interface for the context needed for the SendVirtualSelectedParentInv flow.
|
||||
type SendVirtualSelectedParentInvContext interface {
|
||||
Domain() domain.Domain
|
||||
Config() *config.Config
|
||||
}
|
||||
|
||||
// SendVirtualSelectedParentInv sends a peer the selected parent hash of the virtual
|
||||
@@ -23,11 +21,6 @@ func SendVirtualSelectedParentInv(context SendVirtualSelectedParentInvContext,
|
||||
return err
|
||||
}
|
||||
|
||||
if virtualSelectedParent.Equal(context.Config().NetParams().GenesisHash) {
|
||||
log.Debugf("Skipping sending the virtual selected parent hash to peer %s because it's the genesis", peer)
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Debugf("Sending virtual selected parent hash %s to peer %s", virtualSelectedParent, peer)
|
||||
|
||||
virtualSelectedParentInv := appmessage.NewMsgInvBlock(virtualSelectedParent)
|
||||
|
||||
@@ -33,5 +33,10 @@ func (flow *handleRejectsFlow) start() error {
|
||||
}
|
||||
rejectMessage := message.(*appmessage.MsgReject)
|
||||
|
||||
const maxReasonLength = 255
|
||||
if len(rejectMessage.Reason) > maxReasonLength {
|
||||
return protocolerrors.Errorf(false, "got reject message longer than %d", maxReasonLength)
|
||||
}
|
||||
|
||||
return protocolerrors.Errorf(false, "got reject message: `%s`", rejectMessage.Reason)
|
||||
}
|
||||
|
||||
1571
app/protocol/flows/testing/handle_relay_invs_test.go
Normal file
1571
app/protocol/flows/testing/handle_relay_invs_test.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -21,8 +21,8 @@ func (f fakeReceiveAddressesContext) AddressManager() *addressmanager.AddressMan
|
||||
|
||||
func TestReceiveAddressesErrors(t *testing.T) {
|
||||
testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) {
|
||||
incomingRoute := router.NewRoute("incoming")
|
||||
outgoingRoute := router.NewRoute("outgoing")
|
||||
incomingRoute := router.NewRoute()
|
||||
outgoingRoute := router.NewRoute()
|
||||
peer := peerpkg.New(nil)
|
||||
errChan := make(chan error)
|
||||
go func() {
|
||||
|
||||
@@ -19,8 +19,8 @@ type TransactionsRelayContext interface {
|
||||
NetAdapter() *netadapter.NetAdapter
|
||||
Domain() domain.Domain
|
||||
SharedRequestedTransactions() *SharedRequestedTransactions
|
||||
Broadcast(message appmessage.Message) error
|
||||
OnTransactionAddedToMempool()
|
||||
EnqueueTransactionIDsForPropagation(transactionIDs []*externalapi.DomainTransactionID) error
|
||||
}
|
||||
|
||||
type handleRelayedTransactionsFlow struct {
|
||||
@@ -119,7 +119,8 @@ func (flow *handleRelayedTransactionsFlow) readInv() (*appmessage.MsgInvTransact
|
||||
}
|
||||
|
||||
func (flow *handleRelayedTransactionsFlow) broadcastAcceptedTransactions(acceptedTxIDs []*externalapi.DomainTransactionID) error {
|
||||
return flow.EnqueueTransactionIDsForPropagation(acceptedTxIDs)
|
||||
inv := appmessage.NewMsgInvTransaction(acceptedTxIDs)
|
||||
return flow.Broadcast(inv)
|
||||
}
|
||||
|
||||
// readMsgTxOrNotFound returns the next msgTx or msgTransactionNotFound in incomingRoute,
|
||||
@@ -172,18 +173,17 @@ func (flow *handleRelayedTransactionsFlow) receiveTransactions(requestedTransact
|
||||
expectedID, txID)
|
||||
}
|
||||
|
||||
acceptedTransactions, err :=
|
||||
flow.Domain().MiningManager().ValidateAndInsertTransaction(tx, false, true)
|
||||
err = flow.Domain().MiningManager().ValidateAndInsertTransaction(tx, true)
|
||||
if err != nil {
|
||||
ruleErr := &mempool.RuleError{}
|
||||
if !errors.As(err, ruleErr) {
|
||||
return errors.Wrapf(err, "failed to process transaction %s", txID)
|
||||
}
|
||||
|
||||
shouldBan := false
|
||||
shouldBan := true
|
||||
if txRuleErr := (&mempool.TxRuleError{}); errors.As(ruleErr.Err, txRuleErr) {
|
||||
if txRuleErr.RejectCode == mempool.RejectInvalid {
|
||||
shouldBan = true
|
||||
if txRuleErr.RejectCode != mempool.RejectInvalid {
|
||||
shouldBan = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ func (flow *handleRelayedTransactionsFlow) receiveTransactions(requestedTransact
|
||||
|
||||
return protocolerrors.Errorf(true, "rejected transaction %s: %s", txID, ruleErr)
|
||||
}
|
||||
err = flow.broadcastAcceptedTransactions(consensushashing.TransactionIDs(acceptedTransactions))
|
||||
err = flow.broadcastAcceptedTransactions([]*externalapi.DomainTransactionID{txID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -2,18 +2,16 @@ package transactionrelay_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/protocol/flows/transactionrelay"
|
||||
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
|
||||
"github.com/kaspanet/kaspad/domain"
|
||||
"github.com/kaspanet/kaspad/domain/consensus"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/testutils"
|
||||
"github.com/kaspanet/kaspad/domain/miningmanager/mempool"
|
||||
"github.com/kaspanet/kaspad/infrastructure/logger"
|
||||
"github.com/kaspanet/kaspad/util/panics"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/infrastructure/config"
|
||||
@@ -39,7 +37,7 @@ func (m *mocTransactionsRelayContext) SharedRequestedTransactions() *transaction
|
||||
return m.sharedRequestedTransactions
|
||||
}
|
||||
|
||||
func (m *mocTransactionsRelayContext) EnqueueTransactionIDsForPropagation(transactionIDs []*externalapi.DomainTransactionID) error {
|
||||
func (m *mocTransactionsRelayContext) Broadcast(appmessage.Message) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -65,7 +63,7 @@ func TestHandleRelayedTransactionsNotFound(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create a NetAdapter: %v", err)
|
||||
}
|
||||
domainInstance, err := domain.New(consensusConfig, mempool.DefaultConfig(&consensusConfig.Params), tc.Database())
|
||||
domainInstance, err := domain.New(consensusConfig, tc.Database())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to set up a domain instance: %v", err)
|
||||
}
|
||||
@@ -74,9 +72,9 @@ func TestHandleRelayedTransactionsNotFound(t *testing.T) {
|
||||
domain: domainInstance,
|
||||
sharedRequestedTransactions: sharedRequestedTransactions,
|
||||
}
|
||||
incomingRoute := router.NewRoute("incoming")
|
||||
incomingRoute := router.NewRoute()
|
||||
defer incomingRoute.Close()
|
||||
peerIncomingRoute := router.NewRoute("outgoing")
|
||||
peerIncomingRoute := router.NewRoute()
|
||||
defer peerIncomingRoute.Close()
|
||||
|
||||
txID1 := externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
|
||||
@@ -158,7 +156,7 @@ func TestOnClosedIncomingRoute(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to creat a NetAdapter : %v", err)
|
||||
}
|
||||
domainInstance, err := domain.New(consensusConfig, mempool.DefaultConfig(&consensusConfig.Params), tc.Database())
|
||||
domainInstance, err := domain.New(consensusConfig, tc.Database())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to set up a domain instance: %v", err)
|
||||
}
|
||||
@@ -167,8 +165,8 @@ func TestOnClosedIncomingRoute(t *testing.T) {
|
||||
domain: domainInstance,
|
||||
sharedRequestedTransactions: sharedRequestedTransactions,
|
||||
}
|
||||
incomingRoute := router.NewRoute("incoming")
|
||||
outgoingRoute := router.NewRoute("outgoing")
|
||||
incomingRoute := router.NewRoute()
|
||||
outgoingRoute := router.NewRoute()
|
||||
defer outgoingRoute.Close()
|
||||
|
||||
txID := externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package transactionrelay_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/app/protocol/flows/transactionrelay"
|
||||
"github.com/kaspanet/kaspad/domain"
|
||||
"github.com/kaspanet/kaspad/domain/consensus"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/testutils"
|
||||
"github.com/kaspanet/kaspad/domain/miningmanager/mempool"
|
||||
"github.com/kaspanet/kaspad/infrastructure/config"
|
||||
"github.com/kaspanet/kaspad/infrastructure/logger"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
"github.com/kaspanet/kaspad/util/panics"
|
||||
"github.com/pkg/errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestHandleRequestedTransactionsNotFound tests the flow of HandleRequestedTransactions
|
||||
@@ -36,7 +34,7 @@ func TestHandleRequestedTransactionsNotFound(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create a NetAdapter: %v", err)
|
||||
}
|
||||
domainInstance, err := domain.New(consensusConfig, mempool.DefaultConfig(&consensusConfig.Params), tc.Database())
|
||||
domainInstance, err := domain.New(consensusConfig, tc.Database())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to set up a domain Instance: %v", err)
|
||||
}
|
||||
@@ -45,8 +43,8 @@ func TestHandleRequestedTransactionsNotFound(t *testing.T) {
|
||||
domain: domainInstance,
|
||||
sharedRequestedTransactions: sharedRequestedTransactions,
|
||||
}
|
||||
incomingRoute := router.NewRoute("incoming")
|
||||
outgoingRoute := router.NewRoute("outgoing")
|
||||
incomingRoute := router.NewRoute()
|
||||
outgoingRoute := router.NewRoute()
|
||||
defer outgoingRoute.Close()
|
||||
|
||||
txID1 := externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
|
||||
|
||||
@@ -2,11 +2,10 @@ package protocol
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
@@ -62,8 +61,8 @@ func (m *Manager) IBDPeer() *peerpkg.Peer {
|
||||
}
|
||||
|
||||
// AddTransaction adds transaction to the mempool and propagates it.
|
||||
func (m *Manager) AddTransaction(tx *externalapi.DomainTransaction, allowOrphan bool) error {
|
||||
return m.context.AddTransaction(tx, allowOrphan)
|
||||
func (m *Manager) AddTransaction(tx *externalapi.DomainTransaction) error {
|
||||
return m.context.AddTransaction(tx)
|
||||
}
|
||||
|
||||
// AddBlock adds the given block to the DAG and propagates it.
|
||||
@@ -84,11 +83,6 @@ func (m *Manager) runFlows(flows []*flow, peer *peerpkg.Peer, errChan <-chan err
|
||||
return <-errChan
|
||||
}
|
||||
|
||||
// SetOnVirtualChange sets the onVirtualChangeHandler handler
|
||||
func (m *Manager) SetOnVirtualChange(onVirtualChangeHandler flowcontext.OnVirtualChangeHandler) {
|
||||
m.context.SetOnVirtualChangeHandler(onVirtualChangeHandler)
|
||||
}
|
||||
|
||||
// SetOnBlockAddedToDAGHandler sets the onBlockAddedToDAG handler
|
||||
func (m *Manager) SetOnBlockAddedToDAGHandler(onBlockAddedToDAGHandler flowcontext.OnBlockAddedToDAGHandler) {
|
||||
m.context.SetOnBlockAddedToDAGHandler(onBlockAddedToDAGHandler)
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
|
||||
// maxProtocolVersion version is the maximum supported protocol
|
||||
// version this kaspad node supports
|
||||
const maxProtocolVersion = 3
|
||||
const maxProtocolVersion = 1
|
||||
|
||||
// Peer holds data about a peer.
|
||||
type Peer struct {
|
||||
|
||||
@@ -102,7 +102,7 @@ func (m *Manager) routerInitializer(router *routerpkg.Router, netConnection *net
|
||||
|
||||
func (m *Manager) handleError(err error, netConnection *netadapter.NetConnection, outgoingRoute *routerpkg.Route) {
|
||||
if protocolErr := (protocolerrors.ProtocolError{}); errors.As(err, &protocolErr) {
|
||||
if m.context.Config().EnableBanning && protocolErr.ShouldBan {
|
||||
if !m.context.Config().DisableBanning && protocolErr.ShouldBan {
|
||||
log.Warnf("Banning %s (reason: %s)", netConnection, protocolErr.Cause)
|
||||
|
||||
err := m.context.ConnectionManager().Ban(netConnection)
|
||||
@@ -168,13 +168,10 @@ func (m *Manager) registerBlockRelayFlows(router *routerpkg.Router, isStopping *
|
||||
}),
|
||||
|
||||
m.registerFlow("HandleRelayInvs", router, []appmessage.MessageCommand{
|
||||
appmessage.CmdInvRelayBlock, appmessage.CmdBlock, appmessage.CmdBlockLocator,
|
||||
appmessage.CmdInvRelayBlock, appmessage.CmdBlock, appmessage.CmdBlockLocator, appmessage.CmdIBDBlock,
|
||||
appmessage.CmdDoneHeaders, appmessage.CmdUnexpectedPruningPoint, appmessage.CmdPruningPointUTXOSetChunk,
|
||||
appmessage.CmdBlockHeaders, appmessage.CmdIBDBlockLocatorHighestHash, appmessage.CmdBlockWithTrustedData,
|
||||
appmessage.CmdDoneBlocksWithTrustedData, appmessage.CmdIBDBlockLocatorHighestHashNotFound,
|
||||
appmessage.CmdDonePruningPointUTXOSetChunks, appmessage.CmdIBDBlock, appmessage.CmdPruningPoints,
|
||||
appmessage.CmdPruningPointProof,
|
||||
},
|
||||
appmessage.CmdBlockHeaders, appmessage.CmdPruningPointHash, appmessage.CmdIBDBlockLocatorHighestHash,
|
||||
appmessage.CmdIBDBlockLocatorHighestHashNotFound, appmessage.CmdDonePruningPointUTXOSetChunks},
|
||||
isStopping, errChan, func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
|
||||
return blockrelay.HandleRelayInvs(m.context, incomingRoute,
|
||||
outgoingRoute, peer)
|
||||
@@ -201,6 +198,14 @@ func (m *Manager) registerBlockRelayFlows(router *routerpkg.Router, isStopping *
|
||||
},
|
||||
),
|
||||
|
||||
m.registerFlow("HandleRequestPruningPointUTXOSetAndBlock", router,
|
||||
[]appmessage.MessageCommand{appmessage.CmdRequestPruningPointUTXOSetAndBlock,
|
||||
appmessage.CmdRequestNextPruningPointUTXOSetChunk}, isStopping, errChan,
|
||||
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
|
||||
return blockrelay.HandleRequestPruningPointUTXOSetAndBlock(m.context, incomingRoute, outgoingRoute)
|
||||
},
|
||||
),
|
||||
|
||||
m.registerFlow("HandleIBDBlockRequests", router,
|
||||
[]appmessage.MessageCommand{appmessage.CmdRequestIBDBlocks}, isStopping, errChan,
|
||||
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
|
||||
@@ -208,18 +213,10 @@ func (m *Manager) registerBlockRelayFlows(router *routerpkg.Router, isStopping *
|
||||
},
|
||||
),
|
||||
|
||||
m.registerFlow("HandleRequestPruningPointUTXOSet", router,
|
||||
[]appmessage.MessageCommand{appmessage.CmdRequestPruningPointUTXOSet,
|
||||
appmessage.CmdRequestNextPruningPointUTXOSetChunk}, isStopping, errChan,
|
||||
m.registerFlow("HandlePruningPointHashRequests", router,
|
||||
[]appmessage.MessageCommand{appmessage.CmdRequestPruningPointHash}, isStopping, errChan,
|
||||
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
|
||||
return blockrelay.HandleRequestPruningPointUTXOSet(m.context, incomingRoute, outgoingRoute)
|
||||
},
|
||||
),
|
||||
|
||||
m.registerFlow("HandlePruningPointAndItsAnticoneRequests", router,
|
||||
[]appmessage.MessageCommand{appmessage.CmdRequestPruningPointAndItsAnticone}, isStopping, errChan,
|
||||
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
|
||||
return blockrelay.HandlePruningPointAndItsAnticoneRequests(m.context, incomingRoute, outgoingRoute, peer)
|
||||
return blockrelay.HandlePruningPointHashRequests(m.context, incomingRoute, outgoingRoute)
|
||||
},
|
||||
),
|
||||
|
||||
@@ -229,13 +226,6 @@ func (m *Manager) registerBlockRelayFlows(router *routerpkg.Router, isStopping *
|
||||
return blockrelay.HandleIBDBlockLocator(m.context, incomingRoute, outgoingRoute, peer)
|
||||
},
|
||||
),
|
||||
|
||||
m.registerFlow("HandlePruningPointProofRequests", router,
|
||||
[]appmessage.MessageCommand{appmessage.CmdRequestPruningPointProof}, isStopping, errChan,
|
||||
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
|
||||
return blockrelay.HandlePruningPointProofRequests(m.context, incomingRoute, outgoingRoute, peer)
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +282,7 @@ func (m *Manager) registerRejectsFlow(router *routerpkg.Router, isStopping *uint
|
||||
func (m *Manager) registerFlow(name string, router *routerpkg.Router, messageTypes []appmessage.MessageCommand, isStopping *uint32,
|
||||
errChan chan error, initializeFunc flowInitializeFunc) *flow {
|
||||
|
||||
route, err := router.AddIncomingRoute(name, messageTypes)
|
||||
route, err := router.AddIncomingRoute(messageTypes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -304,7 +294,7 @@ func (m *Manager) registerFlowWithCapacity(name string, capacity int, router *ro
|
||||
messageTypes []appmessage.MessageCommand, isStopping *uint32,
|
||||
errChan chan error, initializeFunc flowInitializeFunc) *flow {
|
||||
|
||||
route, err := router.AddIncomingRouteWithCapacity(name, capacity, messageTypes)
|
||||
route, err := router.AddIncomingRouteWithCapacity(capacity, messageTypes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -330,7 +320,7 @@ func (m *Manager) registerFlowForRoute(route *routerpkg.Route, name string, isSt
|
||||
func (m *Manager) registerOneTimeFlow(name string, router *routerpkg.Router, messageTypes []appmessage.MessageCommand,
|
||||
isStopping *uint32, stopChan chan error, initializeFunc flowInitializeFunc) *flow {
|
||||
|
||||
route, err := router.AddIncomingRoute(name, messageTypes)
|
||||
route, err := router.AddIncomingRoute(messageTypes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -356,12 +346,12 @@ func (m *Manager) registerOneTimeFlow(name string, router *routerpkg.Router, mes
|
||||
|
||||
func registerHandshakeRoutes(router *routerpkg.Router) (
|
||||
receiveVersionRoute *routerpkg.Route, sendVersionRoute *routerpkg.Route) {
|
||||
receiveVersionRoute, err := router.AddIncomingRoute("recieveVersion - incoming", []appmessage.MessageCommand{appmessage.CmdVersion})
|
||||
receiveVersionRoute, err := router.AddIncomingRoute([]appmessage.MessageCommand{appmessage.CmdVersion})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
sendVersionRoute, err = router.AddIncomingRoute("sendVersion - incoming", []appmessage.MessageCommand{appmessage.CmdVerAck})
|
||||
sendVersionRoute, err = router.AddIncomingRoute([]appmessage.MessageCommand{appmessage.CmdVerAck})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@@ -48,31 +48,12 @@ func NewManager(
|
||||
}
|
||||
|
||||
// NotifyBlockAddedToDAG notifies the manager that a block has been added to the DAG
|
||||
func (m *Manager) NotifyBlockAddedToDAG(block *externalapi.DomainBlock, virtualChangeSet *externalapi.VirtualChangeSet) error {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.NotifyBlockAddedToDAG")
|
||||
defer onEnd()
|
||||
|
||||
err := m.NotifyVirtualChange(virtualChangeSet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rpcBlock := appmessage.DomainBlockToRPCBlock(block)
|
||||
err = m.context.PopulateBlockWithVerboseData(rpcBlock, block.Header, block, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
blockAddedNotification := appmessage.NewBlockAddedNotificationMessage(rpcBlock)
|
||||
return m.context.NotificationManager.NotifyBlockAdded(blockAddedNotification)
|
||||
}
|
||||
|
||||
// NotifyVirtualChange notifies the manager that the virtual block has been changed.
|
||||
func (m *Manager) NotifyVirtualChange(virtualChangeSet *externalapi.VirtualChangeSet) error {
|
||||
func (m *Manager) NotifyBlockAddedToDAG(block *externalapi.DomainBlock, blockInsertionResult *externalapi.BlockInsertionResult) error {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.NotifyBlockAddedToDAG")
|
||||
defer onEnd()
|
||||
|
||||
if m.context.Config.UTXOIndex {
|
||||
err := m.notifyUTXOsChanged(virtualChangeSet)
|
||||
err := m.notifyUTXOsChanged(blockInsertionResult)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -88,12 +69,18 @@ func (m *Manager) NotifyVirtualChange(virtualChangeSet *externalapi.VirtualChang
|
||||
return err
|
||||
}
|
||||
|
||||
err = m.notifyVirtualSelectedParentChainChanged(virtualChangeSet)
|
||||
err = m.notifyVirtualSelectedParentChainChanged(blockInsertionResult)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
rpcBlock := appmessage.DomainBlockToRPCBlock(block)
|
||||
err = m.context.PopulateBlockWithVerboseData(rpcBlock, block.Header, block, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
blockAddedNotification := appmessage.NewBlockAddedNotificationMessage(rpcBlock)
|
||||
return m.context.NotificationManager.NotifyBlockAdded(blockAddedNotification)
|
||||
}
|
||||
|
||||
// NotifyPruningPointUTXOSetOverride notifies the manager whenever the UTXO index
|
||||
@@ -130,11 +117,11 @@ func (m *Manager) NotifyFinalityConflictResolved(finalityBlockHash string) error
|
||||
return m.context.NotificationManager.NotifyFinalityConflictResolved(notification)
|
||||
}
|
||||
|
||||
func (m *Manager) notifyUTXOsChanged(virtualChangeSet *externalapi.VirtualChangeSet) error {
|
||||
func (m *Manager) notifyUTXOsChanged(blockInsertionResult *externalapi.BlockInsertionResult) error {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.NotifyUTXOsChanged")
|
||||
defer onEnd()
|
||||
|
||||
utxoIndexChanges, err := m.context.UTXOIndex.Update(virtualChangeSet)
|
||||
utxoIndexChanges, err := m.context.UTXOIndex.Update(blockInsertionResult)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -175,21 +162,21 @@ func (m *Manager) notifyVirtualDaaScoreChanged() error {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.NotifyVirtualDaaScoreChanged")
|
||||
defer onEnd()
|
||||
|
||||
virtualDAAScore, err := m.context.Domain.Consensus().GetVirtualDAAScore()
|
||||
virtualInfo, err := m.context.Domain.Consensus().GetVirtualInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
notification := appmessage.NewVirtualDaaScoreChangedNotificationMessage(virtualDAAScore)
|
||||
notification := appmessage.NewVirtualDaaScoreChangedNotificationMessage(virtualInfo.DAAScore)
|
||||
return m.context.NotificationManager.NotifyVirtualDaaScoreChanged(notification)
|
||||
}
|
||||
|
||||
func (m *Manager) notifyVirtualSelectedParentChainChanged(virtualChangeSet *externalapi.VirtualChangeSet) error {
|
||||
func (m *Manager) notifyVirtualSelectedParentChainChanged(blockInsertionResult *externalapi.BlockInsertionResult) error {
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.NotifyVirtualSelectedParentChainChanged")
|
||||
defer onEnd()
|
||||
|
||||
notification, err := m.context.ConvertVirtualSelectedParentChainChangesToChainChangedNotificationMessage(
|
||||
virtualChangeSet.VirtualSelectedParentChainChanges)
|
||||
blockInsertionResult.VirtualSelectedParentChainChanges)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func (m *Manager) routerInitializer(router *router.Router, netConnection *netada
|
||||
for messageType := range handlers {
|
||||
messageTypes = append(messageTypes, messageType)
|
||||
}
|
||||
incomingRoute, err := router.AddIncomingRoute("rpc router", messageTypes)
|
||||
incomingRoute, err := router.AddIncomingRoute(messageTypes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package rpccontext
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
)
|
||||
|
||||
// ConvertVirtualSelectedParentChainChangesToChainChangedNotificationMessage converts
|
||||
@@ -15,9 +16,29 @@ func (ctx *Context) ConvertVirtualSelectedParentChainChangesToChainChangedNotifi
|
||||
removedChainBlockHashes[i] = removed.String()
|
||||
}
|
||||
|
||||
addedChainBlocks := make([]string, len(selectedParentChainChanges.Added))
|
||||
addedChainBlocks := make([]*appmessage.ChainBlock, len(selectedParentChainChanges.Added))
|
||||
for i, added := range selectedParentChainChanges.Added {
|
||||
addedChainBlocks[i] = added.String()
|
||||
acceptanceData, err := ctx.Domain.Consensus().GetBlockAcceptanceData(added)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
acceptedBlocks := make([]*appmessage.AcceptedBlock, len(acceptanceData))
|
||||
for j, acceptedBlock := range acceptanceData {
|
||||
acceptedTransactionIDs := make([]string, len(acceptedBlock.TransactionAcceptanceData))
|
||||
for k, transaction := range acceptedBlock.TransactionAcceptanceData {
|
||||
transactionID := consensushashing.TransactionID(transaction.Transaction)
|
||||
acceptedTransactionIDs[k] = transactionID.String()
|
||||
}
|
||||
acceptedBlocks[j] = &appmessage.AcceptedBlock{
|
||||
Hash: acceptedBlock.BlockHash.String(),
|
||||
AcceptedTransactionIDs: acceptedTransactionIDs,
|
||||
}
|
||||
}
|
||||
|
||||
addedChainBlocks[i] = &appmessage.ChainBlock{
|
||||
Hash: added.String(),
|
||||
AcceptedBlocks: acceptedBlocks,
|
||||
}
|
||||
}
|
||||
|
||||
return appmessage.NewVirtualSelectedParentChainChangedNotificationMessage(removedChainBlockHashes, addedChainBlocks), nil
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/estimatedsize"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
@@ -113,11 +114,10 @@ func (ctx *Context) PopulateTransactionWithVerboseData(
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Domain.Consensus().PopulateMass(domainTransaction)
|
||||
transaction.VerboseData = &appmessage.RPCTransactionVerboseData{
|
||||
TransactionID: consensushashing.TransactionID(domainTransaction).String(),
|
||||
Hash: consensushashing.TransactionHash(domainTransaction).String(),
|
||||
Mass: domainTransaction.Mass,
|
||||
Size: estimatedsize.TransactionEstimatedSerializedSize(domainTransaction),
|
||||
}
|
||||
if domainBlockHeader != nil {
|
||||
transaction.VerboseData.BlockHash = consensushashing.HeaderHash(domainBlockHeader).String()
|
||||
|
||||
@@ -12,12 +12,8 @@ func HandleBan(context *rpccontext.Context, _ *router.Router, request appmessage
|
||||
banRequest := request.(*appmessage.BanRequestMessage)
|
||||
ip := net.ParseIP(banRequest.IP)
|
||||
if ip == nil {
|
||||
hint := ""
|
||||
if banRequest.IP[0] == '[' {
|
||||
hint = " (try to remove “[” and “]” symbols)"
|
||||
}
|
||||
errorMessage := &appmessage.BanResponseMessage{}
|
||||
errorMessage.Error = appmessage.RPCErrorf("Could not parse IP%s: %s", hint, banRequest.IP)
|
||||
errorMessage.Error = appmessage.RPCErrorf("Could not parse IP %s", banRequest.IP)
|
||||
return errorMessage, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,12 @@ import (
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
)
|
||||
|
||||
const (
|
||||
// maxBlocksInGetBlocksResponse is the max amount of blocks that are
|
||||
// allowed in a GetBlocksResult.
|
||||
maxBlocksInGetBlocksResponse = 1000
|
||||
)
|
||||
|
||||
// HandleGetBlocks handles the respectively named RPC command
|
||||
func HandleGetBlocks(context *rpccontext.Context, _ *router.Router, request appmessage.Message) (appmessage.Message, error) {
|
||||
getBlocksRequest := request.(*appmessage.GetBlocksRequestMessage)
|
||||
@@ -49,11 +55,7 @@ func HandleGetBlocks(context *rpccontext.Context, _ *router.Router, request appm
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// We use +1 because lowHash is also returned
|
||||
// maxBlocks MUST be >= MergeSetSizeLimit + 1
|
||||
maxBlocks := context.Config.NetParams().MergeSetSizeLimit + 1
|
||||
blockHashes, highHash, err := context.Domain.Consensus().GetHashesBetween(lowHash, virtualSelectedParent, maxBlocks)
|
||||
blockHashes, highHash, err := context.Domain.Consensus().GetHashesBetween(lowHash, virtualSelectedParent, maxBlocksInGetBlocksResponse)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -72,6 +74,12 @@ func HandleGetBlocks(context *rpccontext.Context, _ *router.Router, request appm
|
||||
blockHashes = append(blockHashes, virtualSelectedParentAnticone...)
|
||||
}
|
||||
|
||||
// Both GetHashesBetween and Anticone might return more then the allowed number of blocks, so
|
||||
// trim any extra blocks.
|
||||
if len(blockHashes) > maxBlocksInGetBlocksResponse {
|
||||
blockHashes = blockHashes[:maxBlocksInGetBlocksResponse]
|
||||
}
|
||||
|
||||
// Prepare the response
|
||||
response := appmessage.NewGetBlocksResponseMessage()
|
||||
response.BlockHashes = hashes.ToStrings(blockHashes)
|
||||
|
||||
@@ -23,22 +23,6 @@ type fakeDomain struct {
|
||||
testapi.TestConsensus
|
||||
}
|
||||
|
||||
func (d fakeDomain) DeleteStagingConsensus() error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (d fakeDomain) StagingConsensus() externalapi.Consensus {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (d fakeDomain) InitStagingConsensus() error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (d fakeDomain) CommitStagingConsensus() error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (d fakeDomain) Consensus() externalapi.Consensus { return d }
|
||||
func (d fakeDomain) MiningManager() miningmanager.MiningManager { return nil }
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/app/rpc/rpccontext"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
"github.com/kaspanet/kaspad/version"
|
||||
)
|
||||
|
||||
// HandleGetInfo handles the respectively named RPC command
|
||||
@@ -12,7 +11,6 @@ func HandleGetInfo(context *rpccontext.Context, _ *router.Router, _ appmessage.M
|
||||
response := appmessage.NewGetInfoResponseMessage(
|
||||
context.NetAdapter.ID().String(),
|
||||
uint64(context.Domain.MiningManager().TransactionCount()),
|
||||
version.Version(),
|
||||
)
|
||||
|
||||
return response, nil
|
||||
|
||||
@@ -8,14 +8,9 @@ import (
|
||||
|
||||
// HandleGetVirtualSelectedParentBlueScore handles the respectively named RPC command
|
||||
func HandleGetVirtualSelectedParentBlueScore(context *rpccontext.Context, _ *router.Router, _ appmessage.Message) (appmessage.Message, error) {
|
||||
c := context.Domain.Consensus()
|
||||
selectedParent, err := c.GetVirtualSelectedParent()
|
||||
virtualInfo, err := context.Domain.Consensus().GetVirtualInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockInfo, err := c.GetBlockInfo(selectedParent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return appmessage.NewGetVirtualSelectedParentBlueScoreResponseMessage(blockInfo.BlueScore), nil
|
||||
return appmessage.NewGetVirtualSelectedParentBlueScoreResponseMessage(virtualInfo.BlueScore), nil
|
||||
}
|
||||
|
||||
@@ -32,6 +32,6 @@ func HandleGetVirtualSelectedParentChainFromBlock(context *rpccontext.Context, _
|
||||
}
|
||||
|
||||
response := appmessage.NewGetVirtualSelectedParentChainFromBlockResponseMessage(
|
||||
chainChangedNotification.RemovedChainBlockHashes, chainChangedNotification.AddedChainBlockHashes)
|
||||
chainChangedNotification.RemovedChainBlockHashes, chainChangedNotification.AddedChainBlocks)
|
||||
return response, nil
|
||||
}
|
||||
|
||||
@@ -14,14 +14,9 @@ import (
|
||||
func HandleSubmitBlock(context *rpccontext.Context, _ *router.Router, request appmessage.Message) (appmessage.Message, error) {
|
||||
submitBlockRequest := request.(*appmessage.SubmitBlockRequestMessage)
|
||||
|
||||
isSynced, err := context.ProtocolManager.ShouldMine()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !context.Config.AllowSubmitBlockWhenNotSynced && !isSynced {
|
||||
if context.ProtocolManager.IsIBDRunning() {
|
||||
return &appmessage.SubmitBlockResponseMessage{
|
||||
Error: appmessage.RPCErrorf("Block not submitted - node is not synced"),
|
||||
Error: appmessage.RPCErrorf("Block not submitted - IBD is running"),
|
||||
RejectReason: appmessage.RejectReasonIsInIBD,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ func HandleSubmitTransaction(context *rpccontext.Context, _ *router.Router, requ
|
||||
}
|
||||
|
||||
transactionID := consensushashing.TransactionID(domainTransaction)
|
||||
err = context.ProtocolManager.AddTransaction(domainTransaction, submitTransactionRequest.AllowOrphan)
|
||||
err = context.ProtocolManager.AddTransaction(domainTransaction)
|
||||
if err != nil {
|
||||
if !errors.As(err, &mempool.RuleError{}) {
|
||||
return nil, err
|
||||
|
||||
@@ -12,12 +12,8 @@ func HandleUnban(context *rpccontext.Context, _ *router.Router, request appmessa
|
||||
unbanRequest := request.(*appmessage.UnbanRequestMessage)
|
||||
ip := net.ParseIP(unbanRequest.IP)
|
||||
if ip == nil {
|
||||
hint := ""
|
||||
if unbanRequest.IP[0] == '[' {
|
||||
hint = " (try to remove “[” and “]” symbols)"
|
||||
}
|
||||
errorMessage := &appmessage.UnbanResponseMessage{}
|
||||
errorMessage.Error = appmessage.RPCErrorf("Could not parse IP%s: %s", hint, unbanRequest.IP)
|
||||
errorMessage.Error = appmessage.RPCErrorf("Could not parse IP %s", unbanRequest.IP)
|
||||
return errorMessage, nil
|
||||
}
|
||||
err := context.AddressManager.Unban(appmessage.NewNetAddressIPPort(ip, 0))
|
||||
|
||||
@@ -15,11 +15,13 @@ golint -set_exit_status ./...
|
||||
|
||||
staticcheck -checks SA4006,SA4008,SA4009,SA4010,SA5003,SA1004,SA1014,SA1021,SA1023,SA1024,SA1025,SA1026,SA1027,SA1028,SA2000,SA2001,SA2003,SA4000,SA4001,SA4003,SA4004,SA4011,SA4012,SA4013,SA4014,SA4015,SA4016,SA4017,SA4018,SA4019,SA4020,SA4021,SA4022,SA4023,SA5000,SA5002,SA5004,SA5005,SA5007,SA5008,SA5009,SA5010,SA5011,SA5012,SA6001,SA6002,SA9001,SA9002,SA9003,SA9004,SA9005,SA9006,ST1019 ./...
|
||||
|
||||
go vet -composites=false $FLAGS ./...
|
||||
|
||||
go build $FLAGS -o kaspad .
|
||||
|
||||
if [ -n "${NO_PARALLEL}" ]
|
||||
then
|
||||
go test -timeout 20m -parallel=1 $FLAGS ./...
|
||||
go test -parallel=1 $FLAGS ./...
|
||||
else
|
||||
go test -timeout 20m $FLAGS ./...
|
||||
go test $FLAGS ./...
|
||||
fi
|
||||
@@ -1,31 +1,3 @@
|
||||
Kaspad v0.11.7 - 2021-12-11
|
||||
===========================
|
||||
Breaking changes:
|
||||
* kaspawallet: show-address →new-address + show-addresses (#1870)
|
||||
|
||||
Bug fixes:
|
||||
* Fix numThreads using getAEAD instead of decryptMnemonic (#1859)
|
||||
* Apply ResolveVirtual diffs to the UTXO index (#1868)
|
||||
|
||||
Non-breaking changes:
|
||||
* Ignore header mass in devnet and testnet (#1879)
|
||||
* Remove unused args from CalcSubsidy (#1877)
|
||||
* ExpectedHeaderPruningPoint fix (#1876)
|
||||
* Changes to libkaspawallet to support Kaspaper (#1878)
|
||||
* Get rid of genesis's UTXO dump (#1867)
|
||||
|
||||
Kaspad v0.11.2 - 2021-11-11
|
||||
===========================
|
||||
Bug fixes:
|
||||
* Enlarge p2p max message size to 1gb
|
||||
* Fix UTXO chunks logic
|
||||
* Increase tests timeout to 20 minutes
|
||||
|
||||
Kaspad v0.11.1 - 2021-11-09
|
||||
===========================
|
||||
Non-breaking changes:
|
||||
* Cache the miner state
|
||||
|
||||
Kaspad v0.10.2 - 2021-05-18
|
||||
===========================
|
||||
Non-breaking changes:
|
||||
|
||||
@@ -2,7 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/version"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
@@ -34,18 +33,6 @@ func main() {
|
||||
}
|
||||
defer client.Disconnect()
|
||||
|
||||
kaspadMessage, err := client.Post(&protowire.KaspadMessage{Payload: &protowire.KaspadMessage_GetInfoRequest{GetInfoRequest: &protowire.GetInfoRequestMessage{}}})
|
||||
if err != nil {
|
||||
printErrorAndExit(fmt.Sprintf("Cannot post GetInfo message: %s", err))
|
||||
}
|
||||
|
||||
localVersion := version.Version()
|
||||
remoteVersion := kaspadMessage.GetGetInfoResponse().ServerVersion
|
||||
|
||||
if localVersion != remoteVersion {
|
||||
printErrorAndExit(fmt.Sprintf("Server version mismatch, expect: %s, got: %s", localVersion, remoteVersion))
|
||||
}
|
||||
|
||||
responseChan := make(chan string)
|
||||
|
||||
if cfg.RequestJSON != "" {
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/pow"
|
||||
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
"github.com/kaspanet/kaspad/util/difficulty"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -142,20 +143,20 @@ func mineNextBlock(mineWhenNotSynced bool) *externalapi.DomainBlock {
|
||||
// In the rare case where the nonce space is exhausted for a specific
|
||||
// block, it'll keep looping the nonce until a new block template
|
||||
// is discovered.
|
||||
block, state := getBlockForMining(mineWhenNotSynced)
|
||||
state.Nonce = nonce
|
||||
block := getBlockForMining(mineWhenNotSynced)
|
||||
targetDifficulty := difficulty.CompactToBig(block.Header.Bits())
|
||||
headerForMining := block.Header.ToMutable()
|
||||
headerForMining.SetNonce(nonce)
|
||||
atomic.AddUint64(&hashesTried, 1)
|
||||
if state.CheckProofOfWork() {
|
||||
mutHeader := block.Header.ToMutable()
|
||||
mutHeader.SetNonce(nonce)
|
||||
block.Header = mutHeader.ToImmutable()
|
||||
log.Infof("Found block %s with parents %s", consensushashing.BlockHash(block), block.Header.DirectParents())
|
||||
if pow.CheckProofOfWorkWithTarget(headerForMining, targetDifficulty) {
|
||||
block.Header = headerForMining.ToImmutable()
|
||||
log.Infof("Found block %s with parents %s", consensushashing.BlockHash(block), block.Header.ParentHashes())
|
||||
return block
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getBlockForMining(mineWhenNotSynced bool) (*externalapi.DomainBlock, *pow.State) {
|
||||
func getBlockForMining(mineWhenNotSynced bool) *externalapi.DomainBlock {
|
||||
tryCount := 0
|
||||
|
||||
const sleepTime = 500 * time.Millisecond
|
||||
@@ -165,7 +166,7 @@ func getBlockForMining(mineWhenNotSynced bool) (*externalapi.DomainBlock, *pow.S
|
||||
tryCount++
|
||||
|
||||
shouldLog := (tryCount-1)%10 == 0
|
||||
template, state, isSynced := templatemanager.Get()
|
||||
template, isSynced := templatemanager.Get()
|
||||
if template == nil {
|
||||
if shouldLog {
|
||||
log.Info("Waiting for the initial template")
|
||||
@@ -181,7 +182,7 @@ func getBlockForMining(mineWhenNotSynced bool) (*externalapi.DomainBlock, *pow.S
|
||||
continue
|
||||
}
|
||||
|
||||
return template, state
|
||||
return template
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,26 +3,23 @@ package templatemanager
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/pow"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var currentTemplate *externalapi.DomainBlock
|
||||
var currentState *pow.State
|
||||
var isSynced bool
|
||||
var lock = &sync.Mutex{}
|
||||
|
||||
// Get returns the template to work on
|
||||
func Get() (*externalapi.DomainBlock, *pow.State, bool) {
|
||||
func Get() (*externalapi.DomainBlock, bool) {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
// Shallow copy the block so when the user replaces the header it won't affect the template here.
|
||||
if currentTemplate == nil {
|
||||
return nil, nil, false
|
||||
return nil, false
|
||||
}
|
||||
block := *currentTemplate
|
||||
state := *currentState
|
||||
return &block, &state, isSynced
|
||||
return &block, isSynced
|
||||
}
|
||||
|
||||
// Set sets the current template to work on
|
||||
@@ -34,7 +31,6 @@ func Set(template *appmessage.GetBlockTemplateResponseMessage) error {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
currentTemplate = block
|
||||
currentState = pow.NewState(block.Header.ToMutable())
|
||||
isSynced = template.IsSynced
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/client"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
)
|
||||
|
||||
func balance(conf *balanceConfig) error {
|
||||
@@ -22,9 +22,9 @@ func balance(conf *balanceConfig) error {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Balance:\t\tKAS %f\n", float64(response.Available)/constants.SompiPerKaspa)
|
||||
fmt.Printf("Balance:\t\tKAS %f\n", float64(response.Available)/util.SompiPerKaspa)
|
||||
if response.Pending > 0 {
|
||||
fmt.Printf("Pending balance:\tKAS %f\n", float64(response.Pending)/constants.SompiPerKaspa)
|
||||
fmt.Printf("Pending balance:\tKAS %f\n", float64(response.Pending)/util.SompiPerKaspa)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -15,8 +15,7 @@ const (
|
||||
createUnsignedTransactionSubCmd = "create-unsigned-transaction"
|
||||
signSubCmd = "sign"
|
||||
broadcastSubCmd = "broadcast"
|
||||
showAddressesSubCmd = "show-addresses"
|
||||
newAddressSubCmd = "new-address"
|
||||
showAddressSubCmd = "show-address"
|
||||
dumpUnencryptedDataSubCmd = "dump-unencrypted-data"
|
||||
startDaemonSubCmd = "start-daemon"
|
||||
)
|
||||
@@ -76,12 +75,7 @@ type broadcastConfig struct {
|
||||
config.NetworkFlags
|
||||
}
|
||||
|
||||
type showAddressesConfig struct {
|
||||
DaemonAddress string `long:"daemonaddress" short:"d" description:"Wallet daemon server to connect to (default: localhost:8082)"`
|
||||
config.NetworkFlags
|
||||
}
|
||||
|
||||
type newAddressConfig struct {
|
||||
type showAddressConfig struct {
|
||||
DaemonAddress string `long:"daemonaddress" short:"d" description:"Wallet daemon server to connect to (default: localhost:8082)"`
|
||||
config.NetworkFlags
|
||||
}
|
||||
@@ -129,13 +123,9 @@ func parseCommandLine() (subCommand string, config interface{}) {
|
||||
parser.AddCommand(broadcastSubCmd, "Broadcast the given transaction",
|
||||
"Broadcast the given transaction", broadcastConf)
|
||||
|
||||
showAddressesConf := &showAddressesConfig{DaemonAddress: defaultListen}
|
||||
parser.AddCommand(showAddressesSubCmd, "Shows all generated public addresses of the current wallet",
|
||||
"Shows all generated public addresses of the current wallet", showAddressesConf)
|
||||
|
||||
newAddressConf := &newAddressConfig{DaemonAddress: defaultListen}
|
||||
parser.AddCommand(newAddressSubCmd, "Generates new public address of the current wallet and shows it",
|
||||
"Generates new public address of the current wallet and shows it", newAddressConf)
|
||||
showAddressConf := &showAddressConfig{DaemonAddress: defaultListen}
|
||||
parser.AddCommand(showAddressSubCmd, "Shows the public address of the current wallet",
|
||||
"Shows the public address of the current wallet", showAddressConf)
|
||||
|
||||
dumpUnencryptedDataConf := &dumpUnencryptedDataConfig{}
|
||||
parser.AddCommand(dumpUnencryptedDataSubCmd, "Prints the unencrypted wallet data",
|
||||
@@ -203,20 +193,13 @@ func parseCommandLine() (subCommand string, config interface{}) {
|
||||
printErrorAndExit(err)
|
||||
}
|
||||
config = broadcastConf
|
||||
case showAddressesSubCmd:
|
||||
combineNetworkFlags(&showAddressesConf.NetworkFlags, &cfg.NetworkFlags)
|
||||
err := showAddressesConf.ResolveNetwork(parser)
|
||||
case showAddressSubCmd:
|
||||
combineNetworkFlags(&showAddressConf.NetworkFlags, &cfg.NetworkFlags)
|
||||
err := showAddressConf.ResolveNetwork(parser)
|
||||
if err != nil {
|
||||
printErrorAndExit(err)
|
||||
}
|
||||
config = showAddressesConf
|
||||
case newAddressSubCmd:
|
||||
combineNetworkFlags(&newAddressConf.NetworkFlags, &cfg.NetworkFlags)
|
||||
err := newAddressConf.ResolveNetwork(parser)
|
||||
if err != nil {
|
||||
printErrorAndExit(err)
|
||||
}
|
||||
config = newAddressConf
|
||||
config = showAddressConf
|
||||
case dumpUnencryptedDataSubCmd:
|
||||
combineNetworkFlags(&dumpUnencryptedDataConf.NetworkFlags, &cfg.NetworkFlags)
|
||||
err := dumpUnencryptedDataConf.ResolveNetwork(parser)
|
||||
|
||||
@@ -56,7 +56,6 @@ func create(conf *createConfig) error {
|
||||
}
|
||||
|
||||
file := keys.File{
|
||||
Version: keys.LastVersion,
|
||||
EncryptedMnemonics: encryptedMnemonics,
|
||||
ExtendedPublicKeys: extendedPublicKeys,
|
||||
MinimumSignatures: conf.MinimumSignatures,
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/client"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
)
|
||||
|
||||
func createUnsignedTransaction(conf *createUnsignedTransactionConfig) error {
|
||||
@@ -19,7 +19,7 @@ func createUnsignedTransaction(conf *createUnsignedTransactionConfig) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), daemonTimeout)
|
||||
defer cancel()
|
||||
|
||||
sendAmountSompi := uint64(conf.SendAmount * constants.SompiPerKaspa)
|
||||
sendAmountSompi := uint64(conf.SendAmount * util.SompiPerKaspa)
|
||||
response, err := daemonClient.CreateUnsignedTransaction(ctx, &pb.CreateUnsignedTransactionRequest{
|
||||
Address: conf.ToAddress,
|
||||
Amount: sendAmountSompi,
|
||||
|
||||
@@ -1,26 +1,14 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// Connect connects to the kaspawalletd server, and returns the client instance
|
||||
func Connect(address string) (pb.KaspawalletdClient, func(), error) {
|
||||
// Connection is local, so 1 second timeout is sufficient
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
|
||||
conn, err := grpc.DialContext(ctx, address, grpc.WithInsecure(), grpc.WithBlock())
|
||||
conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())
|
||||
if err != nil {
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
return nil, nil, errors.New("kaspawallet daemon is not running, start it with `kaspawallet start-daemon`")
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc v3.12.3
|
||||
// source: kaspawalletd.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -20,6 +21,10 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type GetBalanceRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -215,14 +220,14 @@ func (x *CreateUnsignedTransactionResponse) GetUnsignedTransaction() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
type ShowAddressesRequest struct {
|
||||
type GetReceiveAddressRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *ShowAddressesRequest) Reset() {
|
||||
*x = ShowAddressesRequest{}
|
||||
func (x *GetReceiveAddressRequest) Reset() {
|
||||
*x = GetReceiveAddressRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@@ -230,13 +235,13 @@ func (x *ShowAddressesRequest) Reset() {
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ShowAddressesRequest) String() string {
|
||||
func (x *GetReceiveAddressRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ShowAddressesRequest) ProtoMessage() {}
|
||||
func (*GetReceiveAddressRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ShowAddressesRequest) ProtoReflect() protoreflect.Message {
|
||||
func (x *GetReceiveAddressRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@@ -248,21 +253,21 @@ func (x *ShowAddressesRequest) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ShowAddressesRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ShowAddressesRequest) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use GetReceiveAddressRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetReceiveAddressRequest) Descriptor() ([]byte, []int) {
|
||||
return file_kaspawalletd_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
type ShowAddressesResponse struct {
|
||||
type GetReceiveAddressResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Address []string `protobuf:"bytes,1,rep,name=address,proto3" json:"address,omitempty"`
|
||||
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ShowAddressesResponse) Reset() {
|
||||
*x = ShowAddressesResponse{}
|
||||
func (x *GetReceiveAddressResponse) Reset() {
|
||||
*x = GetReceiveAddressResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@@ -270,13 +275,13 @@ func (x *ShowAddressesResponse) Reset() {
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ShowAddressesResponse) String() string {
|
||||
func (x *GetReceiveAddressResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ShowAddressesResponse) ProtoMessage() {}
|
||||
func (*GetReceiveAddressResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ShowAddressesResponse) ProtoReflect() protoreflect.Message {
|
||||
func (x *GetReceiveAddressResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@@ -288,97 +293,12 @@ func (x *ShowAddressesResponse) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ShowAddressesResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ShowAddressesResponse) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use GetReceiveAddressResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetReceiveAddressResponse) Descriptor() ([]byte, []int) {
|
||||
return file_kaspawalletd_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *ShowAddressesResponse) GetAddress() []string {
|
||||
if x != nil {
|
||||
return x.Address
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type NewAddressRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *NewAddressRequest) Reset() {
|
||||
*x = NewAddressRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *NewAddressRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*NewAddressRequest) ProtoMessage() {}
|
||||
|
||||
func (x *NewAddressRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use NewAddressRequest.ProtoReflect.Descriptor instead.
|
||||
func (*NewAddressRequest) Descriptor() ([]byte, []int) {
|
||||
return file_kaspawalletd_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
type NewAddressResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
|
||||
}
|
||||
|
||||
func (x *NewAddressResponse) Reset() {
|
||||
*x = NewAddressResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *NewAddressResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*NewAddressResponse) ProtoMessage() {}
|
||||
|
||||
func (x *NewAddressResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use NewAddressResponse.ProtoReflect.Descriptor instead.
|
||||
func (*NewAddressResponse) Descriptor() ([]byte, []int) {
|
||||
return file_kaspawalletd_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *NewAddressResponse) GetAddress() string {
|
||||
func (x *GetReceiveAddressResponse) GetAddress() string {
|
||||
if x != nil {
|
||||
return x.Address
|
||||
}
|
||||
@@ -396,7 +316,7 @@ type BroadcastRequest struct {
|
||||
func (x *BroadcastRequest) Reset() {
|
||||
*x = BroadcastRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[8]
|
||||
mi := &file_kaspawalletd_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -409,7 +329,7 @@ func (x *BroadcastRequest) String() string {
|
||||
func (*BroadcastRequest) ProtoMessage() {}
|
||||
|
||||
func (x *BroadcastRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[8]
|
||||
mi := &file_kaspawalletd_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -422,7 +342,7 @@ func (x *BroadcastRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use BroadcastRequest.ProtoReflect.Descriptor instead.
|
||||
func (*BroadcastRequest) Descriptor() ([]byte, []int) {
|
||||
return file_kaspawalletd_proto_rawDescGZIP(), []int{8}
|
||||
return file_kaspawalletd_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *BroadcastRequest) GetTransaction() []byte {
|
||||
@@ -443,7 +363,7 @@ type BroadcastResponse struct {
|
||||
func (x *BroadcastResponse) Reset() {
|
||||
*x = BroadcastResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[9]
|
||||
mi := &file_kaspawalletd_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -456,7 +376,7 @@ func (x *BroadcastResponse) String() string {
|
||||
func (*BroadcastResponse) ProtoMessage() {}
|
||||
|
||||
func (x *BroadcastResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[9]
|
||||
mi := &file_kaspawalletd_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -469,7 +389,7 @@ func (x *BroadcastResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use BroadcastResponse.ProtoReflect.Descriptor instead.
|
||||
func (*BroadcastResponse) Descriptor() ([]byte, []int) {
|
||||
return file_kaspawalletd_proto_rawDescGZIP(), []int{9}
|
||||
return file_kaspawalletd_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *BroadcastResponse) GetTxID() string {
|
||||
@@ -488,7 +408,7 @@ type ShutdownRequest struct {
|
||||
func (x *ShutdownRequest) Reset() {
|
||||
*x = ShutdownRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[10]
|
||||
mi := &file_kaspawalletd_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -501,7 +421,7 @@ func (x *ShutdownRequest) String() string {
|
||||
func (*ShutdownRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ShutdownRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[10]
|
||||
mi := &file_kaspawalletd_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -514,7 +434,7 @@ func (x *ShutdownRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ShutdownRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ShutdownRequest) Descriptor() ([]byte, []int) {
|
||||
return file_kaspawalletd_proto_rawDescGZIP(), []int{10}
|
||||
return file_kaspawalletd_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
type ShutdownResponse struct {
|
||||
@@ -526,7 +446,7 @@ type ShutdownResponse struct {
|
||||
func (x *ShutdownResponse) Reset() {
|
||||
*x = ShutdownResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[11]
|
||||
mi := &file_kaspawalletd_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -539,7 +459,7 @@ func (x *ShutdownResponse) String() string {
|
||||
func (*ShutdownResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ShutdownResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_kaspawalletd_proto_msgTypes[11]
|
||||
mi := &file_kaspawalletd_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -552,7 +472,7 @@ func (x *ShutdownResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ShutdownResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ShutdownResponse) Descriptor() ([]byte, []int) {
|
||||
return file_kaspawalletd_proto_rawDescGZIP(), []int{11}
|
||||
return file_kaspawalletd_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
var File_kaspawalletd_proto protoreflect.FileDescriptor
|
||||
@@ -576,53 +496,47 @@ var file_kaspawalletd_proto_rawDesc = []byte{
|
||||
0x73, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72,
|
||||
0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x13, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x22, 0x16, 0x0a, 0x14, 0x53, 0x68, 0x6f, 0x77, 0x41, 0x64, 0x64, 0x72,
|
||||
0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x31, 0x0a, 0x15,
|
||||
0x53, 0x68, 0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
|
||||
0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22,
|
||||
0x13, 0x0a, 0x11, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x22, 0x2e, 0x0a, 0x12, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65,
|
||||
0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64,
|
||||
0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64,
|
||||
0x72, 0x65, 0x73, 0x73, 0x22, 0x34, 0x0a, 0x10, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73,
|
||||
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x72, 0x61, 0x6e,
|
||||
0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x74,
|
||||
0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x27, 0x0a, 0x11, 0x42, 0x72,
|
||||
0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x74, 0x78, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74,
|
||||
0x78, 0x49, 0x44, 0x22, 0x11, 0x0a, 0x0f, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f,
|
||||
0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x91, 0x03, 0x0a, 0x0c, 0x6b,
|
||||
0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x12, 0x37, 0x0a, 0x0a, 0x47,
|
||||
0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x2e, 0x47, 0x65, 0x74, 0x42,
|
||||
0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e,
|
||||
0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x6e,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x21, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x73,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1a, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69,
|
||||
0x76, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x22, 0x35, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x41, 0x64,
|
||||
0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a,
|
||||
0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
|
||||
0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x34, 0x0a, 0x10, 0x42, 0x72, 0x6f, 0x61, 0x64,
|
||||
0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x74,
|
||||
0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
|
||||
0x52, 0x0b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x27, 0x0a,
|
||||
0x11, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x04, 0x74, 0x78, 0x49, 0x44, 0x22, 0x11, 0x0a, 0x0f, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f,
|
||||
0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x68, 0x75,
|
||||
0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xe4, 0x02,
|
||||
0x0a, 0x0c, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x64, 0x12, 0x37,
|
||||
0x0a, 0x0a, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x2e, 0x47,
|
||||
0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x13, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74,
|
||||
0x65, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x6e, 0x73,
|
||||
0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0d, 0x53, 0x68,
|
||||
0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x15, 0x2e, 0x53, 0x68,
|
||||
0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x16, 0x2e, 0x53, 0x68, 0x6f, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
|
||||
0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x0a,
|
||||
0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x2e, 0x4e, 0x65, 0x77,
|
||||
0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13,
|
||||
0x2e, 0x4e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77,
|
||||
0x6e, 0x12, 0x10, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x09, 0x42, 0x72, 0x6f, 0x61,
|
||||
0x64, 0x63, 0x61, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73,
|
||||
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64,
|
||||
0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x36,
|
||||
0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73,
|
||||
0x70, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x2f, 0x63, 0x6d, 0x64,
|
||||
0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x64, 0x61, 0x65,
|
||||
0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a,
|
||||
0x11, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65,
|
||||
0x73, 0x73, 0x12, 0x19, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x41,
|
||||
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e,
|
||||
0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
|
||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x08, 0x53,
|
||||
0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x10, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f,
|
||||
0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x53, 0x68, 0x75, 0x74,
|
||||
0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x34,
|
||||
0x0a, 0x09, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x42, 0x72,
|
||||
0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12,
|
||||
0x2e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x00, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x6b, 0x61, 0x73, 0x70,
|
||||
0x61, 0x64, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x77, 0x61, 0x6c, 0x6c,
|
||||
0x65, 0x74, 0x2f, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -637,39 +551,35 @@ func file_kaspawalletd_proto_rawDescGZIP() []byte {
|
||||
return file_kaspawalletd_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_kaspawalletd_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
|
||||
var file_kaspawalletd_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
|
||||
var file_kaspawalletd_proto_goTypes = []interface{}{
|
||||
(*GetBalanceRequest)(nil), // 0: GetBalanceRequest
|
||||
(*GetBalanceResponse)(nil), // 1: GetBalanceResponse
|
||||
(*CreateUnsignedTransactionRequest)(nil), // 2: CreateUnsignedTransactionRequest
|
||||
(*CreateUnsignedTransactionResponse)(nil), // 3: CreateUnsignedTransactionResponse
|
||||
(*ShowAddressesRequest)(nil), // 4: ShowAddressesRequest
|
||||
(*ShowAddressesResponse)(nil), // 5: ShowAddressesResponse
|
||||
(*NewAddressRequest)(nil), // 6: NewAddressRequest
|
||||
(*NewAddressResponse)(nil), // 7: NewAddressResponse
|
||||
(*BroadcastRequest)(nil), // 8: BroadcastRequest
|
||||
(*BroadcastResponse)(nil), // 9: BroadcastResponse
|
||||
(*ShutdownRequest)(nil), // 10: ShutdownRequest
|
||||
(*ShutdownResponse)(nil), // 11: ShutdownResponse
|
||||
(*GetReceiveAddressRequest)(nil), // 4: GetReceiveAddressRequest
|
||||
(*GetReceiveAddressResponse)(nil), // 5: GetReceiveAddressResponse
|
||||
(*BroadcastRequest)(nil), // 6: BroadcastRequest
|
||||
(*BroadcastResponse)(nil), // 7: BroadcastResponse
|
||||
(*ShutdownRequest)(nil), // 8: ShutdownRequest
|
||||
(*ShutdownResponse)(nil), // 9: ShutdownResponse
|
||||
}
|
||||
var file_kaspawalletd_proto_depIdxs = []int32{
|
||||
0, // 0: kaspawalletd.GetBalance:input_type -> GetBalanceRequest
|
||||
2, // 1: kaspawalletd.CreateUnsignedTransaction:input_type -> CreateUnsignedTransactionRequest
|
||||
4, // 2: kaspawalletd.ShowAddresses:input_type -> ShowAddressesRequest
|
||||
6, // 3: kaspawalletd.NewAddress:input_type -> NewAddressRequest
|
||||
10, // 4: kaspawalletd.Shutdown:input_type -> ShutdownRequest
|
||||
8, // 5: kaspawalletd.Broadcast:input_type -> BroadcastRequest
|
||||
1, // 6: kaspawalletd.GetBalance:output_type -> GetBalanceResponse
|
||||
3, // 7: kaspawalletd.CreateUnsignedTransaction:output_type -> CreateUnsignedTransactionResponse
|
||||
5, // 8: kaspawalletd.ShowAddresses:output_type -> ShowAddressesResponse
|
||||
7, // 9: kaspawalletd.NewAddress:output_type -> NewAddressResponse
|
||||
11, // 10: kaspawalletd.Shutdown:output_type -> ShutdownResponse
|
||||
9, // 11: kaspawalletd.Broadcast:output_type -> BroadcastResponse
|
||||
6, // [6:12] is the sub-list for method output_type
|
||||
0, // [0:6] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
0, // 0: kaspawalletd.GetBalance:input_type -> GetBalanceRequest
|
||||
2, // 1: kaspawalletd.CreateUnsignedTransaction:input_type -> CreateUnsignedTransactionRequest
|
||||
4, // 2: kaspawalletd.GetReceiveAddress:input_type -> GetReceiveAddressRequest
|
||||
8, // 3: kaspawalletd.Shutdown:input_type -> ShutdownRequest
|
||||
6, // 4: kaspawalletd.Broadcast:input_type -> BroadcastRequest
|
||||
1, // 5: kaspawalletd.GetBalance:output_type -> GetBalanceResponse
|
||||
3, // 6: kaspawalletd.CreateUnsignedTransaction:output_type -> CreateUnsignedTransactionResponse
|
||||
5, // 7: kaspawalletd.GetReceiveAddress:output_type -> GetReceiveAddressResponse
|
||||
9, // 8: kaspawalletd.Shutdown:output_type -> ShutdownResponse
|
||||
7, // 9: kaspawalletd.Broadcast:output_type -> BroadcastResponse
|
||||
5, // [5:10] is the sub-list for method output_type
|
||||
0, // [0:5] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_kaspawalletd_proto_init() }
|
||||
@@ -727,7 +637,7 @@ func file_kaspawalletd_proto_init() {
|
||||
}
|
||||
}
|
||||
file_kaspawalletd_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ShowAddressesRequest); i {
|
||||
switch v := v.(*GetReceiveAddressRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -739,7 +649,7 @@ func file_kaspawalletd_proto_init() {
|
||||
}
|
||||
}
|
||||
file_kaspawalletd_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ShowAddressesResponse); i {
|
||||
switch v := v.(*GetReceiveAddressResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -751,30 +661,6 @@ func file_kaspawalletd_proto_init() {
|
||||
}
|
||||
}
|
||||
file_kaspawalletd_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*NewAddressRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_kaspawalletd_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*NewAddressResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_kaspawalletd_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BroadcastRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -786,7 +672,7 @@ func file_kaspawalletd_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_kaspawalletd_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_kaspawalletd_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BroadcastResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -798,7 +684,7 @@ func file_kaspawalletd_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_kaspawalletd_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_kaspawalletd_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ShutdownRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -810,7 +696,7 @@ func file_kaspawalletd_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_kaspawalletd_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_kaspawalletd_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ShutdownResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -829,7 +715,7 @@ func file_kaspawalletd_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_kaspawalletd_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 12,
|
||||
NumMessages: 10,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@@ -5,8 +5,7 @@ option go_package = "github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb";
|
||||
service kaspawalletd {
|
||||
rpc GetBalance (GetBalanceRequest) returns (GetBalanceResponse) {}
|
||||
rpc CreateUnsignedTransaction (CreateUnsignedTransactionRequest) returns (CreateUnsignedTransactionResponse) {}
|
||||
rpc ShowAddresses (ShowAddressesRequest) returns (ShowAddressesResponse) {}
|
||||
rpc NewAddress (NewAddressRequest) returns (NewAddressResponse) {}
|
||||
rpc GetReceiveAddress (GetReceiveAddressRequest) returns (GetReceiveAddressResponse) {}
|
||||
rpc Shutdown (ShutdownRequest) returns (ShutdownResponse) {}
|
||||
rpc Broadcast (BroadcastRequest) returns (BroadcastResponse) {}
|
||||
}
|
||||
@@ -28,17 +27,10 @@ message CreateUnsignedTransactionResponse {
|
||||
bytes unsignedTransaction = 1;
|
||||
}
|
||||
|
||||
message ShowAddressesRequest {
|
||||
message GetReceiveAddressRequest {
|
||||
}
|
||||
|
||||
message ShowAddressesResponse {
|
||||
repeated string address = 1;
|
||||
}
|
||||
|
||||
message NewAddressRequest {
|
||||
}
|
||||
|
||||
message NewAddressResponse {
|
||||
message GetReceiveAddressResponse {
|
||||
string address = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@ import (
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
const _ = grpc.SupportPackageIsVersion6
|
||||
|
||||
// KaspawalletdClient is the client API for Kaspawalletd service.
|
||||
//
|
||||
@@ -20,8 +19,7 @@ const _ = grpc.SupportPackageIsVersion7
|
||||
type KaspawalletdClient interface {
|
||||
GetBalance(ctx context.Context, in *GetBalanceRequest, opts ...grpc.CallOption) (*GetBalanceResponse, error)
|
||||
CreateUnsignedTransaction(ctx context.Context, in *CreateUnsignedTransactionRequest, opts ...grpc.CallOption) (*CreateUnsignedTransactionResponse, error)
|
||||
ShowAddresses(ctx context.Context, in *ShowAddressesRequest, opts ...grpc.CallOption) (*ShowAddressesResponse, error)
|
||||
NewAddress(ctx context.Context, in *NewAddressRequest, opts ...grpc.CallOption) (*NewAddressResponse, error)
|
||||
GetReceiveAddress(ctx context.Context, in *GetReceiveAddressRequest, opts ...grpc.CallOption) (*GetReceiveAddressResponse, error)
|
||||
Shutdown(ctx context.Context, in *ShutdownRequest, opts ...grpc.CallOption) (*ShutdownResponse, error)
|
||||
Broadcast(ctx context.Context, in *BroadcastRequest, opts ...grpc.CallOption) (*BroadcastResponse, error)
|
||||
}
|
||||
@@ -52,18 +50,9 @@ func (c *kaspawalletdClient) CreateUnsignedTransaction(ctx context.Context, in *
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *kaspawalletdClient) ShowAddresses(ctx context.Context, in *ShowAddressesRequest, opts ...grpc.CallOption) (*ShowAddressesResponse, error) {
|
||||
out := new(ShowAddressesResponse)
|
||||
err := c.cc.Invoke(ctx, "/kaspawalletd/ShowAddresses", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *kaspawalletdClient) NewAddress(ctx context.Context, in *NewAddressRequest, opts ...grpc.CallOption) (*NewAddressResponse, error) {
|
||||
out := new(NewAddressResponse)
|
||||
err := c.cc.Invoke(ctx, "/kaspawalletd/NewAddress", in, out, opts...)
|
||||
func (c *kaspawalletdClient) GetReceiveAddress(ctx context.Context, in *GetReceiveAddressRequest, opts ...grpc.CallOption) (*GetReceiveAddressResponse, error) {
|
||||
out := new(GetReceiveAddressResponse)
|
||||
err := c.cc.Invoke(ctx, "/kaspawalletd/GetReceiveAddress", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -94,8 +83,7 @@ func (c *kaspawalletdClient) Broadcast(ctx context.Context, in *BroadcastRequest
|
||||
type KaspawalletdServer interface {
|
||||
GetBalance(context.Context, *GetBalanceRequest) (*GetBalanceResponse, error)
|
||||
CreateUnsignedTransaction(context.Context, *CreateUnsignedTransactionRequest) (*CreateUnsignedTransactionResponse, error)
|
||||
ShowAddresses(context.Context, *ShowAddressesRequest) (*ShowAddressesResponse, error)
|
||||
NewAddress(context.Context, *NewAddressRequest) (*NewAddressResponse, error)
|
||||
GetReceiveAddress(context.Context, *GetReceiveAddressRequest) (*GetReceiveAddressResponse, error)
|
||||
Shutdown(context.Context, *ShutdownRequest) (*ShutdownResponse, error)
|
||||
Broadcast(context.Context, *BroadcastRequest) (*BroadcastResponse, error)
|
||||
mustEmbedUnimplementedKaspawalletdServer()
|
||||
@@ -105,35 +93,25 @@ type KaspawalletdServer interface {
|
||||
type UnimplementedKaspawalletdServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedKaspawalletdServer) GetBalance(context.Context, *GetBalanceRequest) (*GetBalanceResponse, error) {
|
||||
func (*UnimplementedKaspawalletdServer) GetBalance(context.Context, *GetBalanceRequest) (*GetBalanceResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetBalance not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) CreateUnsignedTransaction(context.Context, *CreateUnsignedTransactionRequest) (*CreateUnsignedTransactionResponse, error) {
|
||||
func (*UnimplementedKaspawalletdServer) CreateUnsignedTransaction(context.Context, *CreateUnsignedTransactionRequest) (*CreateUnsignedTransactionResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateUnsignedTransaction not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) ShowAddresses(context.Context, *ShowAddressesRequest) (*ShowAddressesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ShowAddresses not implemented")
|
||||
func (*UnimplementedKaspawalletdServer) GetReceiveAddress(context.Context, *GetReceiveAddressRequest) (*GetReceiveAddressResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetReceiveAddress not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) NewAddress(context.Context, *NewAddressRequest) (*NewAddressResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method NewAddress not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) Shutdown(context.Context, *ShutdownRequest) (*ShutdownResponse, error) {
|
||||
func (*UnimplementedKaspawalletdServer) Shutdown(context.Context, *ShutdownRequest) (*ShutdownResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Shutdown not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) Broadcast(context.Context, *BroadcastRequest) (*BroadcastResponse, error) {
|
||||
func (*UnimplementedKaspawalletdServer) Broadcast(context.Context, *BroadcastRequest) (*BroadcastResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Broadcast not implemented")
|
||||
}
|
||||
func (UnimplementedKaspawalletdServer) mustEmbedUnimplementedKaspawalletdServer() {}
|
||||
func (*UnimplementedKaspawalletdServer) mustEmbedUnimplementedKaspawalletdServer() {}
|
||||
|
||||
// UnsafeKaspawalletdServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to KaspawalletdServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeKaspawalletdServer interface {
|
||||
mustEmbedUnimplementedKaspawalletdServer()
|
||||
}
|
||||
|
||||
func RegisterKaspawalletdServer(s grpc.ServiceRegistrar, srv KaspawalletdServer) {
|
||||
s.RegisterService(&Kaspawalletd_ServiceDesc, srv)
|
||||
func RegisterKaspawalletdServer(s *grpc.Server, srv KaspawalletdServer) {
|
||||
s.RegisterService(&_Kaspawalletd_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Kaspawalletd_GetBalance_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
@@ -172,38 +150,20 @@ func _Kaspawalletd_CreateUnsignedTransaction_Handler(srv interface{}, ctx contex
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Kaspawalletd_ShowAddresses_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ShowAddressesRequest)
|
||||
func _Kaspawalletd_GetReceiveAddress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetReceiveAddressRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(KaspawalletdServer).ShowAddresses(ctx, in)
|
||||
return srv.(KaspawalletdServer).GetReceiveAddress(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/kaspawalletd/ShowAddresses",
|
||||
FullMethod: "/kaspawalletd/GetReceiveAddress",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(KaspawalletdServer).ShowAddresses(ctx, req.(*ShowAddressesRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Kaspawalletd_NewAddress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(NewAddressRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(KaspawalletdServer).NewAddress(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/kaspawalletd/NewAddress",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(KaspawalletdServer).NewAddress(ctx, req.(*NewAddressRequest))
|
||||
return srv.(KaspawalletdServer).GetReceiveAddress(ctx, req.(*GetReceiveAddressRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
@@ -244,10 +204,7 @@ func _Kaspawalletd_Broadcast_Handler(srv interface{}, ctx context.Context, dec f
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// Kaspawalletd_ServiceDesc is the grpc.ServiceDesc for Kaspawalletd service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var Kaspawalletd_ServiceDesc = grpc.ServiceDesc{
|
||||
var _Kaspawalletd_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "kaspawalletd",
|
||||
HandlerType: (*KaspawalletdServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
@@ -260,12 +217,8 @@ var Kaspawalletd_ServiceDesc = grpc.ServiceDesc{
|
||||
Handler: _Kaspawalletd_CreateUnsignedTransaction_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ShowAddresses",
|
||||
Handler: _Kaspawalletd_ShowAddresses_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "NewAddress",
|
||||
Handler: _Kaspawalletd_NewAddress_Handler,
|
||||
MethodName: "GetReceiveAddress",
|
||||
Handler: _Kaspawalletd_GetReceiveAddress_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Shutdown",
|
||||
|
||||
@@ -3,7 +3,6 @@ package server
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
@@ -24,39 +23,13 @@ func (s *server) changeAddress() (util.Address, error) {
|
||||
walletAddr := &walletAddress{
|
||||
index: s.keysFile.LastUsedInternalIndex(),
|
||||
cosignerIndex: s.keysFile.CosignerIndex,
|
||||
keyChain: libkaspawallet.InternalKeychain,
|
||||
keyChain: internalKeychain,
|
||||
}
|
||||
path := s.walletAddressPath(walletAddr)
|
||||
return libkaspawallet.Address(s.params, s.keysFile.ExtendedPublicKeys, s.keysFile.MinimumSignatures, path, s.keysFile.ECDSA)
|
||||
}
|
||||
|
||||
func (s *server) ShowAddresses(_ context.Context, request *pb.ShowAddressesRequest) (*pb.ShowAddressesResponse, error) {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
if !s.isSynced() {
|
||||
return nil, errors.New("server is not synced")
|
||||
}
|
||||
|
||||
addresses := make([]string, 0)
|
||||
for i := uint32(1); i <= s.keysFile.LastUsedExternalIndex(); i++ {
|
||||
walletAddr := &walletAddress{
|
||||
index: i,
|
||||
cosignerIndex: s.keysFile.CosignerIndex,
|
||||
keyChain: libkaspawallet.ExternalKeychain,
|
||||
}
|
||||
path := s.walletAddressPath(walletAddr)
|
||||
address, err := libkaspawallet.Address(s.params, s.keysFile.ExtendedPublicKeys, s.keysFile.MinimumSignatures, path, s.keysFile.ECDSA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addresses = append(addresses, address.String())
|
||||
}
|
||||
|
||||
return &pb.ShowAddressesResponse{Address: addresses}, nil
|
||||
}
|
||||
|
||||
func (s *server) NewAddress(_ context.Context, request *pb.NewAddressRequest) (*pb.NewAddressResponse, error) {
|
||||
func (s *server) GetReceiveAddress(_ context.Context, request *pb.GetReceiveAddressRequest) (*pb.GetReceiveAddressResponse, error) {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
@@ -77,7 +50,7 @@ func (s *server) NewAddress(_ context.Context, request *pb.NewAddressRequest) (*
|
||||
walletAddr := &walletAddress{
|
||||
index: s.keysFile.LastUsedExternalIndex(),
|
||||
cosignerIndex: s.keysFile.CosignerIndex,
|
||||
keyChain: libkaspawallet.ExternalKeychain,
|
||||
keyChain: externalKeychain,
|
||||
}
|
||||
path := s.walletAddressPath(walletAddr)
|
||||
address, err := libkaspawallet.Address(s.params, s.keysFile.ExtendedPublicKeys, s.keysFile.MinimumSignatures, path, s.keysFile.ECDSA)
|
||||
@@ -85,7 +58,7 @@ func (s *server) NewAddress(_ context.Context, request *pb.NewAddressRequest) (*
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.NewAddressResponse{Address: address.String()}, nil
|
||||
return &pb.GetReceiveAddressResponse{Address: address.String()}, nil
|
||||
}
|
||||
|
||||
func (s *server) walletAddressString(wAddr *walletAddress) (string, error) {
|
||||
|
||||
@@ -2,7 +2,6 @@ package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
|
||||
@@ -26,7 +25,7 @@ func (s *server) Broadcast(_ context.Context, request *pb.BroadcastRequest) (*pb
|
||||
}
|
||||
|
||||
func sendTransaction(client *rpcclient.RPCClient, tx *externalapi.DomainTransaction) (string, error) {
|
||||
submitTransactionResponse, err := client.SubmitTransaction(appmessage.DomainTransactionToRPCTransaction(tx), false)
|
||||
submitTransactionResponse, err := client.SubmitTransaction(appmessage.DomainTransactionToRPCTransaction(tx))
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "error submitting transaction")
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/pb"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -28,7 +27,7 @@ func (s *server) CreateUnsignedTransaction(_ context.Context, request *pb.Create
|
||||
}
|
||||
|
||||
// TODO: Implement a better fee estimation mechanism
|
||||
const feePerInput = 10000
|
||||
const feePerInput = 1000
|
||||
selectedUTXOs, changeSompi, err := s.selectUTXOs(request.Amount, feePerInput)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -89,7 +88,7 @@ func (s *server) selectUTXOs(spendAmount uint64, feePerInput uint64) (
|
||||
totalSpend := spendAmount + fee
|
||||
if totalValue < totalSpend {
|
||||
return nil, 0, errors.Errorf("Insufficient funds for send: %f required, while only %f available",
|
||||
float64(totalSpend)/constants.SompiPerKaspa, float64(totalValue)/constants.SompiPerKaspa)
|
||||
float64(totalSpend)/util.SompiPerKaspa, float64(totalValue)/util.SompiPerKaspa)
|
||||
}
|
||||
|
||||
return selectedUTXOs, totalValue - totalSpend, nil
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/pkg/errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
var keyChains = []uint8{libkaspawallet.ExternalKeychain, libkaspawallet.InternalKeychain}
|
||||
const (
|
||||
// externalKeychain is the key chain that is used to create receive addresses
|
||||
externalKeychain = 0
|
||||
// internalKeychain is used to create change addresses
|
||||
internalKeychain = 1
|
||||
)
|
||||
|
||||
var keyChains = []uint8{externalKeychain, internalKeychain}
|
||||
|
||||
type walletAddressSet map[string]*walletAddress
|
||||
|
||||
@@ -176,7 +180,7 @@ func (s *server) updateLastUsedIndexes(addressSet walletAddressSet,
|
||||
continue
|
||||
}
|
||||
|
||||
if walletAddress.keyChain == libkaspawallet.ExternalKeychain {
|
||||
if walletAddress.keyChain == externalKeychain {
|
||||
if walletAddress.index > lastUsedExternalIndex {
|
||||
lastUsedExternalIndex = walletAddress.index
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ func encryptMnemonic(mnemonic string, password []byte) (*EncryptedMnemonic, erro
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aead, err := getAEAD(defaultNumThreads, password, salt)
|
||||
aead, err := getAEAD(password, salt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -6,12 +6,10 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/utils"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/utils"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/dagconfig"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
@@ -24,9 +22,6 @@ var (
|
||||
defaultAppDir = util.AppDir("kaspawallet", false)
|
||||
)
|
||||
|
||||
// LastVersion is the most up to date file format version
|
||||
const LastVersion = 1
|
||||
|
||||
func defaultKeysFile(netParams *dagconfig.Params) string {
|
||||
return filepath.Join(defaultAppDir, netParams.Name, "keys.json")
|
||||
}
|
||||
@@ -37,8 +32,6 @@ type encryptedPrivateKeyJSON struct {
|
||||
}
|
||||
|
||||
type keysFileJSON struct {
|
||||
Version uint32 `json:"version"`
|
||||
NumThreads uint8 `json:"numThreads,omitempty"` // This field is ignored for versions different from 0. See more details at the function `numThreads`.
|
||||
EncryptedPrivateKeys []*encryptedPrivateKeyJSON `json:"encryptedMnemonics"`
|
||||
ExtendedPublicKeys []string `json:"publicKeys"`
|
||||
MinimumSignatures uint32 `json:"minimumSignatures"`
|
||||
@@ -56,8 +49,6 @@ type EncryptedMnemonic struct {
|
||||
|
||||
// File holds all the data related to the wallet keys
|
||||
type File struct {
|
||||
Version uint32
|
||||
NumThreads uint8 // This field is ignored for versions different than 0
|
||||
EncryptedMnemonics []*EncryptedMnemonic
|
||||
ExtendedPublicKeys []string
|
||||
MinimumSignatures uint32
|
||||
@@ -78,8 +69,6 @@ func (d *File) toJSON() *keysFileJSON {
|
||||
}
|
||||
|
||||
return &keysFileJSON{
|
||||
Version: d.Version,
|
||||
NumThreads: d.NumThreads,
|
||||
EncryptedPrivateKeys: encryptedPrivateKeysJSON,
|
||||
ExtendedPublicKeys: d.ExtendedPublicKeys,
|
||||
MinimumSignatures: d.MinimumSignatures,
|
||||
@@ -90,26 +79,7 @@ func (d *File) toJSON() *keysFileJSON {
|
||||
}
|
||||
}
|
||||
|
||||
// NewFileFromMnemonic generates a new File from the given mnemonic string
|
||||
func NewFileFromMnemonic(params *dagconfig.Params, mnemonic string, password string) (*File, error) {
|
||||
encryptedMnemonics, extendedPublicKeys, err :=
|
||||
encryptedMnemonicExtendedPublicKeyPairs(params, []string{mnemonic}, password, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &File{
|
||||
Version: LastVersion,
|
||||
NumThreads: defaultNumThreads,
|
||||
EncryptedMnemonics: encryptedMnemonics,
|
||||
ExtendedPublicKeys: extendedPublicKeys,
|
||||
MinimumSignatures: 1,
|
||||
ECDSA: false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *File) fromJSON(fileJSON *keysFileJSON) error {
|
||||
d.Version = fileJSON.Version
|
||||
d.NumThreads = fileJSON.NumThreads
|
||||
d.MinimumSignatures = fileJSON.MinimumSignatures
|
||||
d.ECDSA = fileJSON.ECDSA
|
||||
d.ExtendedPublicKeys = fileJSON.ExtendedPublicKeys
|
||||
@@ -211,20 +181,10 @@ func (d *File) DecryptMnemonics(cmdLinePassword string) ([]string, error) {
|
||||
if len(password) == 0 {
|
||||
password = getPassword("Password:")
|
||||
}
|
||||
|
||||
var numThreads uint8
|
||||
if len(d.EncryptedMnemonics) > 0 {
|
||||
var err error
|
||||
numThreads, err = d.numThreads(password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
privateKeys := make([]string, len(d.EncryptedMnemonics))
|
||||
for i, encryptedPrivateKey := range d.EncryptedMnemonics {
|
||||
var err error
|
||||
privateKeys[i], err = decryptMnemonic(numThreads, encryptedPrivateKey, password)
|
||||
privateKeys[i], err = decryptMnemonic(encryptedPrivateKey, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -318,72 +278,13 @@ func (d *File) Save() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
const defaultNumThreads = 8
|
||||
|
||||
func (d *File) numThreads(password []byte) (uint8, error) {
|
||||
// There's a bug in v0 wallets where the number of threads
|
||||
// was determined by the number of logical CPUs at the machine,
|
||||
// which made the authentication non-deterministic across platforms.
|
||||
// In order to solve it we introduce v1 where the number of threads
|
||||
// is constant, and brute force the number of threads in v0. After we
|
||||
// find the right amount via brute force we save the result to the file.
|
||||
|
||||
if d.Version != 0 {
|
||||
return defaultNumThreads, nil
|
||||
}
|
||||
|
||||
numThreads, err := d.detectNumThreads(password, d.EncryptedMnemonics[0])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
d.NumThreads = numThreads
|
||||
err = d.Save()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return numThreads, nil
|
||||
}
|
||||
|
||||
func (d *File) detectNumThreads(password []byte, encryptedMnemonic *EncryptedMnemonic) (uint8, error) {
|
||||
firstGuessNumThreads := d.NumThreads
|
||||
if d.NumThreads == 0 {
|
||||
firstGuessNumThreads = uint8(runtime.NumCPU())
|
||||
}
|
||||
_, err := decryptMnemonic(firstGuessNumThreads, encryptedMnemonic, password)
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), "message authentication failed") {
|
||||
return 0, err
|
||||
}
|
||||
} else {
|
||||
return firstGuessNumThreads, nil
|
||||
}
|
||||
|
||||
for numThreadsGuess := uint8(1); ; numThreadsGuess++ {
|
||||
if numThreadsGuess == firstGuessNumThreads {
|
||||
continue
|
||||
}
|
||||
|
||||
_, err := decryptMnemonic(numThreadsGuess, encryptedMnemonic, password)
|
||||
if err != nil {
|
||||
const maxTries = 32
|
||||
if numThreadsGuess == maxTries || !strings.Contains(err.Error(), "message authentication failed") {
|
||||
return 0, err
|
||||
}
|
||||
} else {
|
||||
return numThreadsGuess, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getAEAD(threads uint8, password, salt []byte) (cipher.AEAD, error) {
|
||||
key := argon2.IDKey(password, salt, 1, 64*1024, threads, 32)
|
||||
func getAEAD(password, salt []byte) (cipher.AEAD, error) {
|
||||
key := argon2.IDKey(password, salt, 1, 64*1024, uint8(runtime.NumCPU()), 32)
|
||||
return chacha20poly1305.NewX(key)
|
||||
}
|
||||
|
||||
func decryptMnemonic(numThreads uint8, encryptedPrivateKey *EncryptedMnemonic, password []byte) (string, error) {
|
||||
aead, err := getAEAD(numThreads, password, encryptedPrivateKey.salt)
|
||||
func decryptMnemonic(encryptedPrivateKey *EncryptedMnemonic, password []byte) (string, error) {
|
||||
aead, err := getAEAD(password, encryptedPrivateKey.salt)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
package libkaspawallet
|
||||
|
||||
const (
|
||||
// ExternalKeychain is the key chain that is used to create receive addresses
|
||||
ExternalKeychain = 0
|
||||
// InternalKeychain is used to create change addresses
|
||||
InternalKeychain = 1
|
||||
)
|
||||
@@ -89,7 +89,7 @@ type PartiallySignedInput struct {
|
||||
PrevOutput *TransactionOutput `protobuf:"bytes,2,opt,name=prevOutput,proto3" json:"prevOutput,omitempty"`
|
||||
MinimumSignatures uint32 `protobuf:"varint,3,opt,name=minimumSignatures,proto3" json:"minimumSignatures,omitempty"`
|
||||
PubKeySignaturePairs []*PubKeySignaturePair `protobuf:"bytes,4,rep,name=pubKeySignaturePairs,proto3" json:"pubKeySignaturePairs,omitempty"`
|
||||
DerivationPath string `protobuf:"bytes,5,opt,name=derivationPath,proto3" json:"derivationPath,omitempty"`
|
||||
DerivationPath string `protobuf:"bytes,5,opt,name=DerivationPath,proto3" json:"DerivationPath,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PartiallySignedInput) Reset() {
|
||||
@@ -364,7 +364,6 @@ type TransactionInput struct {
|
||||
PreviousOutpoint *Outpoint `protobuf:"bytes,1,opt,name=previousOutpoint,proto3" json:"previousOutpoint,omitempty"`
|
||||
SignatureScript []byte `protobuf:"bytes,2,opt,name=signatureScript,proto3" json:"signatureScript,omitempty"`
|
||||
Sequence uint64 `protobuf:"varint,3,opt,name=sequence,proto3" json:"sequence,omitempty"`
|
||||
SigOpCount uint32 `protobuf:"varint,4,opt,name=sigOpCount,proto3" json:"sigOpCount,omitempty"`
|
||||
}
|
||||
|
||||
func (x *TransactionInput) Reset() {
|
||||
@@ -420,13 +419,6 @@ func (x *TransactionInput) GetSequence() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TransactionInput) GetSigOpCount() uint32 {
|
||||
if x != nil {
|
||||
return x.SigOpCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Outpoint struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -672,9 +664,9 @@ var file_wallet_proto_rawDesc = []byte{
|
||||
0x6f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50,
|
||||
0x75, 0x62, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x50, 0x61,
|
||||
0x69, 0x72, 0x52, 0x14, 0x70, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
|
||||
0x75, 0x72, 0x65, 0x50, 0x61, 0x69, 0x72, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x64, 0x65, 0x72, 0x69,
|
||||
0x75, 0x72, 0x65, 0x50, 0x61, 0x69, 0x72, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x44, 0x65, 0x72, 0x69,
|
||||
0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0e, 0x64, 0x65, 0x72, 0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68,
|
||||
0x52, 0x0e, 0x44, 0x65, 0x72, 0x69, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68,
|
||||
0x22, 0x5b, 0x0a, 0x13, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
|
||||
0x75, 0x72, 0x65, 0x50, 0x61, 0x69, 0x72, 0x12, 0x26, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x6e,
|
||||
0x64, 0x65, 0x64, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
@@ -703,7 +695,7 @@ var file_wallet_proto_rawDesc = []byte{
|
||||
0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x06, 0x20, 0x01,
|
||||
0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f,
|
||||
0x61, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61,
|
||||
0x64, 0x22, 0xc2, 0x01, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x64, 0x22, 0xa2, 0x01, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x48, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f,
|
||||
0x75, 0x73, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a,
|
||||
@@ -713,9 +705,7 @@ var file_wallet_proto_rawDesc = []byte{
|
||||
0x69, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x69, 0x67, 0x6e, 0x61,
|
||||
0x74, 0x75, 0x72, 0x65, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65,
|
||||
0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65,
|
||||
0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x4f, 0x70, 0x43,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x4f,
|
||||
0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x69, 0x0a, 0x08, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69,
|
||||
0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x69, 0x0a, 0x08, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69,
|
||||
0x6e, 0x74, 0x12, 0x47, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54,
|
||||
|
||||
@@ -13,7 +13,7 @@ message PartiallySignedInput{
|
||||
TransactionOutput prevOutput = 2;
|
||||
uint32 minimumSignatures = 3;
|
||||
repeated PubKeySignaturePair pubKeySignaturePairs = 4;
|
||||
string derivationPath = 5;
|
||||
string DerivationPath = 5;
|
||||
}
|
||||
|
||||
message PubKeySignaturePair{
|
||||
@@ -39,7 +39,6 @@ message TransactionInput{
|
||||
Outpoint previousOutpoint = 1;
|
||||
bytes signatureScript = 2;
|
||||
uint64 sequence = 3;
|
||||
uint32 sigOpCount = 4;
|
||||
}
|
||||
|
||||
message Outpoint{
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package serialization
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet/serialization/protoserialization"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
// PartiallySignedTransaction is a type that is intended
|
||||
@@ -191,10 +190,6 @@ func transactionToProto(tx *externalapi.DomainTransaction) *protoserialization.T
|
||||
}
|
||||
|
||||
func transactionInputFromProto(protoInput *protoserialization.TransactionInput) (*externalapi.DomainTransactionInput, error) {
|
||||
if protoInput.SigOpCount > math.MaxUint8 {
|
||||
return nil, errors.New("TransactionInput SigOpCount > math.MaxUint8")
|
||||
}
|
||||
|
||||
outpoint, err := outpointFromProto(protoInput.PreviousOutpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -204,7 +199,6 @@ func transactionInputFromProto(protoInput *protoserialization.TransactionInput)
|
||||
PreviousOutpoint: *outpoint,
|
||||
SignatureScript: protoInput.SignatureScript,
|
||||
Sequence: protoInput.Sequence,
|
||||
SigOpCount: byte(protoInput.SigOpCount),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -213,7 +207,6 @@ func transactionInputToProto(input *externalapi.DomainTransactionInput) *protose
|
||||
PreviousOutpoint: outpointToProto(&input.PreviousOutpoint),
|
||||
SignatureScript: input.SignatureScript,
|
||||
Sequence: input.Sequence,
|
||||
SigOpCount: uint32(input.SigOpCount),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@ func sign(params *dagconfig.Params, mnemonic string, partiallySignedTransaction
|
||||
false, // This is a fake value, because it's irrelevant for the signature
|
||||
0, // This is a fake value, because it's irrelevant for the signature
|
||||
)
|
||||
partiallySignedTransaction.Tx.Inputs[i].SigOpCount = byte(len(partiallySignedInput.PubKeySignaturePairs))
|
||||
}
|
||||
|
||||
signed := false
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user