Compare commits

..

28 Commits

Author SHA1 Message Date
stasatdaglabs
8534d7f317 Empty commit. 2020-08-19 15:43:01 +03:00
Ori Newman
8dae378bd9 [NOD-1285] Fix deadlock on connection manager (#880) 2020-08-19 13:24:20 +03:00
stasatdaglabs
8dd409dc1c [NOD-1223] Rename executables package back to cmd. (#879) 2020-08-19 11:45:11 +03:00
Ori Newman
74110a2e49 [NOD-1282] Remove peer after disconnect (#878) 2020-08-19 11:10:10 +03:00
Ori Newman
ce876a7c44 Merge remote-tracking branch 'origin/v0.6.3-dev' into v0.6.4-dev 2020-08-18 19:03:52 +03:00
stasatdaglabs
d14809694f [NOD-1223] Reorganize directory structure (#874)
* [NOD-1223] Delete unused files/packages.

* [NOD-1223] Move signal and limits to the os package.

* [NOD-1223] Put database and dbaccess into the db package.

* [NOD-1223] Fold the logs package into the logger package.

* [NOD-1223] Rename domainmessage to appmessage.

* [NOD-1223] Rename to/from DomainMessage to AppMessage.

* [NOD-1223] Move appmessage to the app packge.

* [NOD-1223] Move protocol to the app packge.

* [NOD-1223] Move the network package to the infrastructure packge.

* [NOD-1223] Rename cmd to executables.

* [NOD-1223] Fix go.doc in the logger package.
2020-08-18 10:26:39 +03:00
stasatdaglabs
450ff81f86 [NOD-1275] Fix onNewBlock not being called from RPC submitBlock (#873)
* [NOD-1275] Fix onNewBlock not being called from from RPC submitBlock.

* [NOD-1275] Rename tx to txID.
2020-08-17 15:24:00 +03:00
Ori Newman
1f04f30ea7 [NOD-1273] Order parents in PrepareBlockForTest (#872) 2020-08-17 14:26:56 +03:00
Ori Newman
3e4e8d8b6b Merge remote-tracking branch 'origin/v0.6.2-dev' into v0.6.3-dev 2020-08-16 18:13:46 +03:00
Ori Newman
31c0399484 Update to version 0.6.4 2020-08-16 17:55:49 +03:00
Ori Newman
8cac582f6d Update to version 0.6.4 2020-08-16 17:30:09 +03:00
Ori Newman
f2a3ccd9ab [NOD-1271] Move version package to the top level (#871)
* [NOD-1271] Move version package to the top level

* [NOD-1271] Fix imports
2020-08-16 17:16:11 +03:00
Ori Newman
31b5cd8d28 Fix merge errors from v0.6.2-rc2 to v0.6.3-dev 2020-08-16 15:35:47 +03:00
Ori Newman
96bd1fa99b [NOD-1262] Add network name to MinimalNetAdapter handshake (#867) 2020-08-16 15:30:04 +03:00
Svarog
48d498e820 [NOD-1259] Do not panic on non-protocol errors from RPC (#863)
* [NOD-1259] All rule-errors should be protocol-errors

* [NOD-1259] Handle submitting of coinbase transactions properly

* Revert "[NOD-1259] All rule-errors should be protocol-errors"

This reverts commit 2fd30c1856.

* [NOD-1259] Don't panic on non-protocol errors in ProtocolManager.AddTransaction/AddBlock

* [NOD-1259] Implement subnetworkid.IsBuiltInOrNative and use where appropriate
2020-08-16 15:29:23 +03:00
Ori Newman
32c5cfeaf5 [NOD-1204] Add timestamp and message number to domain messages (#854) 2020-08-16 15:26:02 +03:00
stasatdaglabs
d55f4e8164 [NOD-1220] Add network string field to Version message (#852)
* [NOD-1220] Add network name to the version message.

* [NOD-1220] Ban peers from the wrong network.

* [NOD-1220] Add the network parameter to protowire.

* [NOD-1220] Add "kaspa-" to network names.
2020-08-16 15:25:25 +03:00
stasatdaglabs
1927e81202 [NOD-1129] Fix NewBlockTemplate creating incesous blocks (#870)
* [NOD-1129] Implement TestIncestousNewBlockTemplate.

* [NOD-1129] Add some debug logs to TestIncestousNewBlockTemplate.

* [NOD-1129] Fix merge errors.

* [NOD-1129] Narrow down on the failure.

* [NOD-1129] Fix bad initial value for child.interval in reachabilityTreeNode.addChild.

* [NOD-1129] Rewrite the test to be specific to reachability.
2020-08-16 13:14:44 +03:00
stasatdaglabs
8a4ece1101 [NOD-1223] Reorganize project (#868)
* [NOD-1223] Move all network stuff into a new network package.

* [NOD-1223] Delete the unused package testutil.

* [NOD-1223] Move infrastructure stuff into a new instrastructure package.

* [NOD-1223] Move domain stuff into a new domain package.
2020-08-13 17:27:25 +03:00
Elichai Turkel
0bf1052abf [NOD-1101] Hash data without serializing into a buffer first (#779)
* Add Hash Writers

* Add the hash writers to the tests

* Add the DoubleHash Writer to the benchmarks

* Remove buffers from hashing by using the Hash Writer

* Replace empty slice with nil in mempool test payload
2020-08-13 15:40:54 +03:00
Ori Newman
2af03c1ccf [NOD-1207] Send reject messages (#855)
* [NOD-1207] Send reject messages

* [NOD-1207] Empty outgoing route before disconnecting

* [NOD-1207] Renumber fields in RejectMessage

* [NOD-1207] Use more accurate log messages

* [NOD-1207] Call registerRejectsFlow

* [NOD-1207] Panic if outgoingRoute.Enqueue returns unexpected error

* [NOD-1207] Fix comment and rename variables

* [NOD-1207] Fix comment

* [NOD-1207] add baseMessage to MsgReject

* [NOD-1207] Fix comments and add block hash to error if it's rejected
2020-08-13 15:32:41 +03:00
Ori Newman
a2aa58c8a4 [NOD-1201] Panic if callbacks are not set (#856)
* [NOD-1201] Panic if necessary callback are not set in gRPCConnection and gRPCServer

* [NOD-1201] Fix comment and change return order

* [NOD-1201] Return nil instead of error on gRPCServer.Start

* [NOD-1201] Fix typo
2020-08-13 15:21:52 +03:00
oudeis
7e74fc0b2b [NOD-1248] netadapter unit test (#865)
* [NOD-1246/NOD-1248] Add unit test for NetAdapter

* [NOD-1246/NOD-1248] Do not ignore OK

* [NOD-1248] Lint code

- Move `t *testing.T` to be first parameter in test-helper function
- Rename `getRouterInitializer` to `routerInitializerForTest`
- Make test data constants

Co-authored-by: Yaroslav Reshetnyk <yaroslav.r@it-dimension.com>
2020-08-13 15:07:20 +03:00
stasatdaglabs
0653e59e16 [NOD-1190] Refactor process.go (#858)
* [NOD-1190] Move non-processBlock stuff out of process.go.

* [NOD-1190] Move everything out of accept.go.

* [NOD-1190] Move all processBlock functions to process.go.

* [NOD-1190] Move orphan stuff to orphan.go.

* [NOD-1190] Remove thresholdstate stuff.

* [NOD-1190] Move isSynced to sync_rate.go.

* [NOD-1190] Move delayed block stuff to delayed_blocks.go.

* [NOD-1190] Rename orphans.go to orphaned_blocks.go.

* [NOD-1190] Move non-BlockDAG structs out of dag.go.

* [NOD-1190] Remove unused fields.

* [NOD-1190] Fixup BlockDAG.New a bit.

* [NOD-1190] Move sequence lock stuff to sequence_lock.go

* [NOD-1190] Move some multiset stuff out of dag.go.

* [NOD-1190] Move finality stuff out of dag.go.

* [NOD-1190] Move blocklocator stuff out of dag.go.

* [NOD-1190] Move confirmation stuff out of dag.go.

* [NOD-1190] Move utxo and selected parent chain stuff out of dag.go.

* [NOD-1190] Move BlockDAG lock functions to the beginning of dag.go.

* [NOD-1190] Move verifyAndBuildUTXO out of process.go.

* [NOD-1190] Extract handleProcessBlockError to a function.

* [NOD-1190] Remove daglock unlock in notifyBlockAccepted.

* [NOD-1190] Extract checkDuplicateBlock to a method.

* [NOD-1190] Fix merge errors.

* [NOD-1190] Remove unused parameter from CalcSequenceLock.

* [NOD-1190] Extract processBlock contents into functions.

* [NOD-1190] Fix parent delayed blocks not marking their children as delayed

* [NOD-1190] Fix TestProcessDelayedBlocks.

* [NOD-1190] Extract stuff in maybeAcceptBlock to separate functions.

* [NOD-1190] Rename handleProcessBlockError to handleConnectBlockError.

* [NOD-1190] Remove some comments.

* [NOD-1190] Use lowercase in error messages.

* [NOD-1190] Rename createNewBlockNode to createBlockNodeFromBlock.

* [NOD-1190] Rename orphaned_blocks.go to orpan_blocks.go.

* [NOD-1190] Extract validateUTXOCommitment to a separate function.

* [NOD-1190] Fix a bug in validateUTXOCommitment.

* [NOD-1190] Rename checkBlockTxsFinalized to checkBlockTransactionsFinalized.

* [NOD-1190] Add a comment over createBlockNodeFromBlock.

* [NOD-1190] Fold validateAllTxsFinalized into checkBlockTransactionsFinalized.

* [NOD-1190] Return parents from checkBlockParents.

* [NOD-1190] Remove the processBlock prefix from the functions that had it.

* [NOD-1190] Begin extracting functions out of checkTransactionSanity.

* [NOD-1190] Finish extracting functions out of checkTransactionSanity.

* [NOD-1190] Remove an unused parameter.

* [NOD-1190] Fix merge errors.

* [NOD-1190] Added an explanation as to why we change the nonce in TestProcessDelayedBlocks.

* [NOD-1190] Fix a comment.

* [NOD-1190] Fix a comment.

* [NOD-1190] Fix a typo.

* [NOD-1190] Replace checkBlockParents with handleLookupParentNodesError.
2020-08-13 13:33:43 +03:00
oudeis
32463ce906 [NOD-1247] Add check for routerInitializer presence (#864)
Co-authored-by: Yaroslav Reshetnyk <yaroslav.r@it-dimension.com>
2020-08-13 12:04:43 +03:00
stasatdaglabs
23a3594c18 [NOD-1233] Go over all TODO(libp2p)s and either fix them or create tickets for them (#860)
* [NOD-1233] Remove HandleNewBlockOld.

* [NOD-1233] Make ErrRouteClosed not a protocol error.

* [NOD-1233] Fix ambiguous comments.

* [NOD-1233] Remove a no-longer-relevant comment.

* [NOD-1233] Remove some of the TODOs.

* [NOD-1233] Replace fakeSourceAddress with a real sourceAddress.

* [NOD-1233] Remove a no-longer-relevant TODO.

* [NOD-1233] Remove TODO from handleGetNetTotals.

* [NOD-1233] Remove a no-longer-relevant TODO.

* [NOD-1233] Disconnect if connected to wrong partial/full type.

* [NOD-1233] Get rid of mempool tags.

* [NOD-1233] Remove TODOs.

* [NOD-1233] Simplify a test.

* [NOD-1190] Remove getNetTotals.
2020-08-13 09:41:02 +03:00
Ori Newman
ca3172dad0 [NOD-1239] Delete app.WaitForShutdown() (#866) 2020-08-12 16:38:52 +03:00
Ori Newman
22dc3f998f [NOD-1256] Optimize PrepareBlockForTest (#861)
* [NOD-1256] Optimize PrepareBlockForTest

* [NOD-1256] Remove redundant comment
2020-08-12 16:25:42 +03:00
532 changed files with 6195 additions and 6921 deletions

View File

@@ -40,10 +40,8 @@ recommended that `GOPATH` is set to a directory in your home directory such as
```bash
$ git clone https://github.com/kaspanet/kaspad $GOPATH/src/github.com/kaspanet/kaspad
$ cd $GOPATH/src/github.com/kaspanet/kaspad
$ ./test.sh
$ go install . ./cmd/...
```
`./test.sh` tests can be skipped, but some things might not run correctly on your system if tests fail.
- Kaspad (and utilities) should now be installed in `$GOPATH/bin`. If you did
not already add the bin directory to your system path during Go installation,
@@ -76,4 +74,3 @@ The documentation is a work-in-progress. It is located in the [docs](https://git
## License
Kaspad is licensed under the copyfree [ISC License](https://choosealicense.com/licenses/isc/).

View File

@@ -4,24 +4,24 @@ import (
"fmt"
"sync/atomic"
"github.com/kaspanet/kaspad/addressmanager"
"github.com/kaspanet/kaspad/infrastructure/network/addressmanager"
"github.com/kaspanet/kaspad/netadapter/id"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/id"
"github.com/kaspanet/kaspad/blockdag"
"github.com/kaspanet/kaspad/blockdag/indexers"
"github.com/kaspanet/kaspad/config"
"github.com/kaspanet/kaspad/connmanager"
"github.com/kaspanet/kaspad/dbaccess"
"github.com/kaspanet/kaspad/dnsseed"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/mempool"
"github.com/kaspanet/kaspad/mining"
"github.com/kaspanet/kaspad/netadapter"
"github.com/kaspanet/kaspad/protocol"
"github.com/kaspanet/kaspad/rpc"
"github.com/kaspanet/kaspad/signal"
"github.com/kaspanet/kaspad/txscript"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol"
"github.com/kaspanet/kaspad/domain/blockdag"
"github.com/kaspanet/kaspad/domain/blockdag/indexers"
"github.com/kaspanet/kaspad/domain/mempool"
"github.com/kaspanet/kaspad/domain/mining"
"github.com/kaspanet/kaspad/domain/txscript"
"github.com/kaspanet/kaspad/infrastructure/config"
"github.com/kaspanet/kaspad/infrastructure/db/dbaccess"
"github.com/kaspanet/kaspad/infrastructure/network/connmanager"
"github.com/kaspanet/kaspad/infrastructure/network/dnsseed"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter"
"github.com/kaspanet/kaspad/infrastructure/network/rpc"
"github.com/kaspanet/kaspad/infrastructure/os/signal"
"github.com/kaspanet/kaspad/util"
"github.com/kaspanet/kaspad/util/panics"
)
@@ -62,11 +62,11 @@ func (a *App) Start() {
}
// Stop gracefully shuts down all the kaspad services.
func (a *App) Stop() error {
func (a *App) Stop() {
// Make sure this only happens once.
if atomic.AddInt32(&a.shutdown, 1) != 1 {
log.Infof("Kaspad is already in the process of shutting down")
return nil
return
}
log.Warnf("Kaspad shutting down")
@@ -86,7 +86,12 @@ func (a *App) Stop() error {
}
}
return nil
err = a.addressManager.Stop()
if err != nil {
log.Errorf("Error stopping address manager: %s", err)
}
return
}
// New returns a new App instance configured to listen on addr for the
@@ -138,8 +143,8 @@ func New(cfg *config.Config, databaseContext *dbaccess.DatabaseContext, interrup
func (a *App) maybeSeedFromDNS() {
if !a.cfg.DisableDNSSeed {
dnsseed.SeedFromDNS(a.cfg.NetParams(), a.cfg.DNSSeed, domainmessage.SFNodeNetwork, false, nil,
a.cfg.Lookup, func(addresses []*domainmessage.NetAddress) {
dnsseed.SeedFromDNS(a.cfg.NetParams(), a.cfg.DNSSeed, appmessage.SFNodeNetwork, false, nil,
a.cfg.Lookup, func(addresses []*appmessage.NetAddress) {
// Kaspad uses a lookup of the dns seeder here. Since seeder returns
// IPs of nodes and not its own IP, we can not know real IP of
// source. So we'll take first returned address as source.
@@ -190,11 +195,10 @@ func setupMempool(cfg *config.Config, dag *blockdag.BlockDAG, sigCache *txscript
MaxTxVersion: 1,
},
CalcSequenceLockNoLock: func(tx *util.Tx, utxoSet blockdag.UTXOSet) (*blockdag.SequenceLock, error) {
return dag.CalcSequenceLockNoLock(tx, utxoSet, true)
return dag.CalcSequenceLockNoLock(tx, utxoSet)
},
IsDeploymentActive: dag.IsDeploymentActive,
SigCache: sigCache,
DAG: dag,
SigCache: sigCache,
DAG: dag,
}
return mempool.New(&mempoolConfig)
@@ -241,9 +245,3 @@ func (a *App) P2PNodeID() *id.ID {
func (a *App) AddressManager() *addressmanager.AddressManager {
return a.addressManager
}
// WaitForShutdown blocks until the main listener and peer handlers are stopped.
func (a *App) WaitForShutdown() {
// TODO(libp2p)
// a.p2pServer.WaitForShutdown()
}

View File

@@ -36,7 +36,7 @@ to a remote node running a kaspa peer. Example syntax is:
// Reads and validates the next kaspa message from conn using the
// protocol version pver and the kaspa network kaspanet. The returns
// are a domainmessage.Message, a []byte which contains the unmarshalled
// are a appmessage.Message, a []byte which contains the unmarshalled
// raw payload, and a possible error.
msg, rawPayload, err := wire.ReadMessage(conn, pver, kaspanet)
if err != nil {

View File

@@ -1,4 +1,4 @@
package domainmessage
package appmessage
import "time"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"bytes"
@@ -411,3 +411,21 @@ func BenchmarkDoubleHashH(b *testing.B) {
_ = daghash.DoubleHashH(txBytes)
}
}
// BenchmarkDoubleHashWriter performs a benchmark on how long it takes to perform
// a double hash via the writer returning a daghash.Hash.
func BenchmarkDoubleHashWriter(b *testing.B) {
var buf bytes.Buffer
err := genesisCoinbaseTx.Serialize(&buf)
if err != nil {
b.Fatalf("Serialize: unexpected error: %+v", err)
}
txBytes := buf.Bytes()
b.ResetTimer()
for i := 0; i < b.N; i++ {
writer := daghash.NewDoubleHashWriter()
_, _ = writer.Write(txBytes)
writer.Finalize()
}
}

View File

@@ -2,13 +2,14 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"bytes"
"fmt"
"io"
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/util/mstime"
"io"
)
// BaseBlockHeaderPayload is the base number of bytes a block header can be,
@@ -65,13 +66,18 @@ func (h *BlockHeader) NumParentBlocks() byte {
// BlockHash computes the block identifier hash for the given block header.
func (h *BlockHeader) BlockHash() *daghash.Hash {
// Encode the header and double sha256 everything prior to the number of
// transactions. Ignore the error returns since there is no way the
// encode could fail except being out of memory which would cause a
// run-time panic.
buf := bytes.NewBuffer(make([]byte, 0, BaseBlockHeaderPayload+h.NumParentBlocks()))
_ = writeBlockHeader(buf, 0, h)
// transactions.
writer := daghash.NewDoubleHashWriter()
err := writeBlockHeader(writer, 0, h)
if err != nil {
// It seems like this could only happen if the writer returned an error.
// and this writer should never return an error (no allocations or possible failures)
// the only non-writer error path here is unknown types in `WriteElement`
panic(fmt.Sprintf("BlockHash() failed. this should never fail unless BlockHeader was changed. err: %+v", err))
}
return daghash.DoubleHashP(buf.Bytes())
res := writer.Finalize()
return &res
}
// IsGenesis returns true iff this block is a genesis block
@@ -82,7 +88,7 @@ func (h *BlockHeader) IsGenesis() bool {
// KaspaDecode decodes r using the kaspa protocol encoding into the receiver.
// This is part of the Message interface implementation.
// See Deserialize for decoding block headers stored to disk, such as in a
// database, as opposed to decoding block headers from the domainmessage.
// database, as opposed to decoding block headers from the appmessage.
func (h *BlockHeader) KaspaDecode(r io.Reader, pver uint32) error {
return readBlockHeader(r, pver, h)
}
@@ -90,7 +96,7 @@ func (h *BlockHeader) KaspaDecode(r io.Reader, pver uint32) error {
// KaspaEncode encodes the receiver to w using the kaspa protocol encoding.
// This is part of the Message interface implementation.
// See Serialize for encoding block headers to be stored to disk, such as in a
// database, as opposed to encoding block headers for the domainmessage.
// database, as opposed to encoding block headers for the appmessage.
func (h *BlockHeader) KaspaEncode(w io.Writer, pver uint32) error {
return writeBlockHeader(w, pver, h)
}
@@ -99,7 +105,7 @@ func (h *BlockHeader) KaspaEncode(w io.Writer, pver uint32) error {
// that is suitable for long-term storage such as a database while respecting
// the Version field.
func (h *BlockHeader) Deserialize(r io.Reader) error {
// At the current time, there is no difference between the domainmessage encoding
// At the current time, there is no difference between the appmessage encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of readBlockHeader.
return readBlockHeader(r, 0, h)
@@ -109,7 +115,7 @@ func (h *BlockHeader) Deserialize(r io.Reader) error {
// that is suitable for long-term storage such as a database while respecting
// the Version field.
func (h *BlockHeader) Serialize(w io.Writer) error {
// At the current time, there is no difference between the domainmessage encoding
// At the current time, there is no difference between the appmessage encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of writeBlockHeader.
return writeBlockHeader(w, 0, h)
@@ -143,7 +149,7 @@ func NewBlockHeader(version int32, parentHashes []*daghash.Hash, hashMerkleRoot
// readBlockHeader reads a kaspa block header from r. See Deserialize for
// decoding block headers stored to disk, such as in a database, as opposed to
// decoding from the domainmessage.
// decoding from the appmessage.
func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error {
var numParentBlocks byte
err := readElements(r, &bh.Version, &numParentBlocks)
@@ -169,7 +175,7 @@ func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error {
// writeBlockHeader writes a kaspa block header to w. See Serialize for
// encoding block headers to be stored to disk, such as in a database, as
// opposed to encoding for the domainmessage.
// opposed to encoding for the appmessage.
func writeBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error {
timestamp := bh.Timestamp.UnixMilliseconds()
if err := writeElements(w, bh.Version, bh.NumParentBlocks()); err != nil {

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"bytes"
@@ -47,7 +47,7 @@ func TestBlockHeader(t *testing.T) {
}
}
// TestBlockHeaderEncoding tests the BlockHeader domainmessage encode and decode for various
// TestBlockHeaderEncoding tests the BlockHeader appmessage encode and decode for various
// protocol versions.
func TestBlockHeaderEncoding(t *testing.T) {
nonce := uint64(123123) // 0x000000000001e0f3
@@ -66,7 +66,7 @@ func TestBlockHeaderEncoding(t *testing.T) {
Nonce: nonce,
}
// baseBlockHdrEncoded is the domainmessage encoded bytes of baseBlockHdr.
// baseBlockHdrEncoded is the appmessage encoded bytes of baseBlockHdr.
baseBlockHdrEncoded := []byte{
0x01, 0x00, 0x00, 0x00, // Version 1
0x02, // NumParentBlocks
@@ -99,7 +99,7 @@ func TestBlockHeaderEncoding(t *testing.T) {
in *BlockHeader // Data to encode
out *BlockHeader // Expected decoded data
buf []byte // Encoded data
pver uint32 // Protocol version for domainmessage encoding
pver uint32 // Protocol version for appmessage encoding
}{
// Latest protocol version.
{
@@ -112,7 +112,7 @@ func TestBlockHeaderEncoding(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to domainmessage format.
// Encode to appmessage format.
var buf bytes.Buffer
err := writeBlockHeader(&buf, test.pver, test.in)
if err != nil {
@@ -137,7 +137,7 @@ func TestBlockHeaderEncoding(t *testing.T) {
continue
}
// Decode the block header from domainmessage format.
// Decode the block header from appmessage format.
var bh BlockHeader
rbuf := bytes.NewReader(test.buf)
err = readBlockHeader(rbuf, test.pver, &bh)
@@ -182,7 +182,7 @@ func TestBlockHeaderSerialize(t *testing.T) {
Nonce: nonce,
}
// baseBlockHdrEncoded is the domainmessage encoded bytes of baseBlockHdr.
// baseBlockHdrEncoded is the appmessage encoded bytes of baseBlockHdr.
baseBlockHdrEncoded := []byte{
0x01, 0x00, 0x00, 0x00, // Version 1
0x02, // NumParentBlocks

View File

@@ -2,12 +2,12 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"encoding/binary"
"fmt"
"github.com/kaspanet/kaspad/netadapter/id"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/id"
"github.com/kaspanet/kaspad/util/binaryserializer"
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/util/mstime"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"bytes"
@@ -57,7 +57,7 @@ var exampleUTXOCommitment = &daghash.Hash{
0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F,
}
// TestElementEncoding tests domainmessage encode and decode for various element types. This
// TestElementEncoding tests appmessage encode and decode for various element types. This
// is mainly to test the "fast" paths in readElement and writeElement which use
// type assertions to avoid reflection when possible.
func TestElementEncoding(t *testing.T) {
@@ -129,7 +129,7 @@ func TestElementEncoding(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Write to domainmessage format.
// Write to appmessage format.
var buf bytes.Buffer
err := WriteElement(&buf, test.in)
if err != nil {
@@ -142,7 +142,7 @@ func TestElementEncoding(t *testing.T) {
continue
}
// Read from domainmessage format.
// Read from appmessage format.
rbuf := bytes.NewReader(test.buf)
val := test.in
if reflect.ValueOf(test.in).Kind() != reflect.Ptr {
@@ -165,7 +165,7 @@ func TestElementEncoding(t *testing.T) {
}
}
// TestElementEncodingErrors performs negative tests against domainmessage encode and decode
// TestElementEncodingErrors performs negative tests against appmessage encode and decode
// of various element types to confirm error paths work correctly.
func TestElementEncodingErrors(t *testing.T) {
type writeElementReflect int32
@@ -209,7 +209,7 @@ func TestElementEncodingErrors(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to domainmessage format.
// Encode to appmessage format.
w := newFixedWriter(test.max)
err := WriteElement(w, test.in)
if !errors.Is(err, test.writeErr) {
@@ -218,7 +218,7 @@ func TestElementEncodingErrors(t *testing.T) {
continue
}
// Decode from domainmessage format.
// Decode from appmessage format.
r := newFixedReader(test.max, nil)
val := test.in
if reflect.ValueOf(test.in).Kind() != reflect.Ptr {
@@ -233,7 +233,7 @@ func TestElementEncodingErrors(t *testing.T) {
}
}
// TestVarIntEncoding tests domainmessage encode and decode for variable length integers.
// TestVarIntEncoding tests appmessage encode and decode for variable length integers.
func TestVarIntEncoding(t *testing.T) {
tests := []struct {
value uint64 // Value to encode
@@ -266,7 +266,7 @@ func TestVarIntEncoding(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to domainmessage format.
// Encode to appmessage format.
buf := &bytes.Buffer{}
err := WriteVarInt(buf, test.value)
if err != nil {
@@ -279,7 +279,7 @@ func TestVarIntEncoding(t *testing.T) {
continue
}
// Decode from domainmessage format.
// Decode from appmessage format.
rbuf := bytes.NewReader(test.buf)
val, err := ReadVarInt(rbuf)
if err != nil {
@@ -294,7 +294,7 @@ func TestVarIntEncoding(t *testing.T) {
}
}
// TestVarIntEncodingErrors performs negative tests against domainmessage encode and decode
// TestVarIntEncodingErrors performs negative tests against appmessage encode and decode
// of variable length integers to confirm error paths work correctly.
func TestVarIntEncodingErrors(t *testing.T) {
tests := []struct {
@@ -319,7 +319,7 @@ func TestVarIntEncodingErrors(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to domainmessage format.
// Encode to appmessage format.
w := newFixedWriter(test.max)
err := WriteVarInt(w, test.in)
if !errors.Is(err, test.writeErr) {
@@ -328,7 +328,7 @@ func TestVarIntEncodingErrors(t *testing.T) {
continue
}
// Decode from domainmessage format.
// Decode from appmessage format.
r := newFixedReader(test.max, test.buf)
_, err = ReadVarInt(r)
if !errors.Is(err, test.readErr) {
@@ -347,7 +347,7 @@ func TestVarIntNonCanonical(t *testing.T) {
tests := []struct {
name string // Test name for easier identification
in []byte // Value to decode
pver uint32 // Protocol version for domainmessage encoding
pver uint32 // Protocol version for appmessage encoding
}{
{
"0 encoded with 3 bytes", []byte{0xfd, 0x00, 0x00},
@@ -379,7 +379,7 @@ func TestVarIntNonCanonical(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Decode from domainmessage format.
// Decode from appmessage format.
rbuf := bytes.NewReader(test.in)
val, err := ReadVarInt(rbuf)
if msgErr := &(MessageError{}); !errors.As(err, &msgErr) {
@@ -430,7 +430,7 @@ func TestVarIntSerializeSize(t *testing.T) {
}
}
// TestVarStringEncoding tests domainmessage encode and decode for variable length strings.
// TestVarStringEncoding tests appmessage encode and decode for variable length strings.
func TestVarStringEncoding(t *testing.T) {
pver := ProtocolVersion
@@ -441,7 +441,7 @@ func TestVarStringEncoding(t *testing.T) {
in string // String to encode
out string // String to decoded value
buf []byte // Encoded value
pver uint32 // Protocol version for domainmessage encoding
pver uint32 // Protocol version for appmessage encoding
}{
// Latest protocol version.
// Empty string
@@ -454,7 +454,7 @@ func TestVarStringEncoding(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to domainmessage format.
// Encode to appmessage format.
var buf bytes.Buffer
err := WriteVarString(&buf, test.in)
if err != nil {
@@ -467,7 +467,7 @@ func TestVarStringEncoding(t *testing.T) {
continue
}
// Decode from domainmessage format.
// Decode from appmessage format.
rbuf := bytes.NewReader(test.buf)
val, err := ReadVarString(rbuf, test.pver)
if err != nil {
@@ -482,7 +482,7 @@ func TestVarStringEncoding(t *testing.T) {
}
}
// TestVarStringEncodingErrors performs negative tests against domainmessage encode and
// TestVarStringEncodingErrors performs negative tests against appmessage encode and
// decode of variable length strings to confirm error paths work correctly.
func TestVarStringEncodingErrors(t *testing.T) {
pver := ProtocolVersion
@@ -493,7 +493,7 @@ func TestVarStringEncodingErrors(t *testing.T) {
tests := []struct {
in string // Value to encode
buf []byte // Encoded value
pver uint32 // Protocol version for domainmessage encoding
pver uint32 // Protocol version for appmessage encoding
max int // Max size of fixed buffer to induce errors
writeErr error // Expected write error
readErr error // Expected read error
@@ -509,7 +509,7 @@ func TestVarStringEncodingErrors(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to domainmessage format.
// Encode to appmessage format.
w := newFixedWriter(test.max)
err := WriteVarString(w, test.in)
if !errors.Is(err, test.writeErr) {
@@ -518,7 +518,7 @@ func TestVarStringEncodingErrors(t *testing.T) {
continue
}
// Decode from domainmessage format.
// Decode from appmessage format.
r := newFixedReader(test.max, test.buf)
_, err = ReadVarString(r, test.pver)
if !errors.Is(err, test.readErr) {
@@ -538,7 +538,7 @@ func TestVarStringOverflowErrors(t *testing.T) {
tests := []struct {
buf []byte // Encoded value
pver uint32 // Protocol version for domainmessage encoding
pver uint32 // Protocol version for appmessage encoding
err error // Expected error
}{
{[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
@@ -549,7 +549,7 @@ func TestVarStringOverflowErrors(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Decode from domainmessage format.
// Decode from appmessage format.
rbuf := bytes.NewReader(test.buf)
_, err := ReadVarString(rbuf, test.pver)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
@@ -561,7 +561,7 @@ func TestVarStringOverflowErrors(t *testing.T) {
}
// TestVarBytesEncoding tests domainmessage encode and decode for variable length byte array.
// TestVarBytesEncoding tests appmessage encode and decode for variable length byte array.
func TestVarBytesEncoding(t *testing.T) {
pver := ProtocolVersion
@@ -571,7 +571,7 @@ func TestVarBytesEncoding(t *testing.T) {
tests := []struct {
in []byte // Byte Array to write
buf []byte // Encoded value
pver uint32 // Protocol version for domainmessage encoding
pver uint32 // Protocol version for appmessage encoding
}{
// Latest protocol version.
// Empty byte array
@@ -584,7 +584,7 @@ func TestVarBytesEncoding(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to domainmessage format.
// Encode to appmessage format.
var buf bytes.Buffer
err := WriteVarBytes(&buf, test.pver, test.in)
if err != nil {
@@ -597,7 +597,7 @@ func TestVarBytesEncoding(t *testing.T) {
continue
}
// Decode from domainmessage format.
// Decode from appmessage format.
rbuf := bytes.NewReader(test.buf)
val, err := ReadVarBytes(rbuf, test.pver, MaxMessagePayload,
"test payload")
@@ -613,7 +613,7 @@ func TestVarBytesEncoding(t *testing.T) {
}
}
// TestVarBytesEncodingErrors performs negative tests against domainmessage encode and
// TestVarBytesEncodingErrors performs negative tests against appmessage encode and
// decode of variable length byte arrays to confirm error paths work correctly.
func TestVarBytesEncodingErrors(t *testing.T) {
pver := ProtocolVersion
@@ -624,7 +624,7 @@ func TestVarBytesEncodingErrors(t *testing.T) {
tests := []struct {
in []byte // Byte Array to write
buf []byte // Encoded value
pver uint32 // Protocol version for domainmessage encoding
pver uint32 // Protocol version for appmessage encoding
max int // Max size of fixed buffer to induce errors
writeErr error // Expected write error
readErr error // Expected read error
@@ -640,7 +640,7 @@ func TestVarBytesEncodingErrors(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to domainmessage format.
// Encode to appmessage format.
w := newFixedWriter(test.max)
err := WriteVarBytes(w, test.pver, test.in)
if !errors.Is(err, test.writeErr) {
@@ -649,7 +649,7 @@ func TestVarBytesEncodingErrors(t *testing.T) {
continue
}
// Decode from domainmessage format.
// Decode from appmessage format.
r := newFixedReader(test.max, test.buf)
_, err = ReadVarBytes(r, test.pver, MaxMessagePayload,
"test payload")
@@ -670,7 +670,7 @@ func TestVarBytesOverflowErrors(t *testing.T) {
tests := []struct {
buf []byte // Encoded value
pver uint32 // Protocol version for domainmessage encoding
pver uint32 // Protocol version for appmessage encoding
err error // Expected error
}{
{[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
@@ -681,7 +681,7 @@ func TestVarBytesOverflowErrors(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Decode from domainmessage format.
// Decode from appmessage format.
rbuf := bytes.NewReader(test.buf)
_, err := ReadVarBytes(rbuf, test.pver, MaxMessagePayload,
"test payload")

View File

@@ -1,8 +1,8 @@
/*
Package domainmessage implements the kaspa domainmessage protocol.
Package appmessage implements the kaspa appmessage protocol.
At a high level, this package provides support for marshalling and unmarshalling
supported kaspa messages to and from the domainmessage. This package does not deal
supported kaspa messages to and from the appmessage. This package does not deal
with the specifics of message handling such as what to do when a message is
received. This provides the caller with a high level of flexibility.
@@ -19,7 +19,7 @@ Message which allows messages of any type to be read, written, or passed around
through channels, functions, etc. In addition, concrete implementations of most
of the currently supported kaspa messages are provided. For these supported
messages, all of the details of marshalling and unmarshalling to and from the
domainmessage using kaspa encoding are handled so the caller doesn't have to concern
appmessage using kaspa encoding are handled so the caller doesn't have to concern
themselves with the specifics.
Message Interaction
@@ -55,7 +55,7 @@ Protocol Version
The protocol version should be negotiated with the remote peer at a higher
level than this package via the version (MsgVersion) message exchange, however,
this package provides the domainmessage.ProtocolVersion constant which indicates the
this package provides the appmessage.ProtocolVersion constant which indicates the
latest protocol version this package supports and is typically the value to use
for all outbound connections before a potentially lower protocol version is
negotiated.
@@ -66,11 +66,11 @@ The kaspa network is a magic number which is used to identify the start of a
message and which kaspa network the message applies to. This package provides
the following constants:
domainmessage.Mainnet
domainmessage.Testnet (Test network)
domainmessage.Regtest (Regression test network)
domainmessage.Simnet (Simulation test network)
domainmessage.Devnet (Development network)
appmessage.Mainnet
appmessage.Testnet (Test network)
appmessage.Regtest (Regression test network)
appmessage.Simnet (Simulation test network)
appmessage.Devnet (Development network)
Determining Message Type
@@ -82,43 +82,43 @@ switch or type assertion. An example of a type switch follows:
// Assumes msg is already a valid concrete message such as one created
// via NewMsgVersion or read via ReadMessage.
switch msg := msg.(type) {
case *domainmessage.MsgVersion:
case *appmessage.MsgVersion:
// The message is a pointer to a MsgVersion struct.
fmt.Printf("Protocol version: %d", msg.ProtocolVersion)
case *domainmessage.MsgBlock:
case *appmessage.MsgBlock:
// The message is a pointer to a MsgBlock struct.
fmt.Printf("Number of tx in block: %d", msg.Header.TxnCount)
}
Reading Messages
In order to unmarshall kaspa messages from the domainmessage, use the ReadMessage
In order to unmarshall kaspa messages from the appmessage, use the ReadMessage
function. It accepts any io.Reader, but typically this will be a net.Conn to
a remote node running a kaspa peer. Example syntax is:
// Reads and validates the next kaspa message from conn using the
// protocol version pver and the kaspa network kaspaNet. The returns
// are a domainmessage.Message, a []byte which contains the unmarshalled
// are a appmessage.Message, a []byte which contains the unmarshalled
// raw payload, and a possible error.
msg, rawPayload, err := domainmessage.ReadMessage(conn, pver, kaspaNet)
msg, rawPayload, err := appmessage.ReadMessage(conn, pver, kaspaNet)
if err != nil {
// Log and handle the error
}
Writing Messages
In order to marshall kaspa messages to the domainmessage, use the WriteMessage
In order to marshall kaspa messages to the appmessage, use the WriteMessage
function. It accepts any io.Writer, but typically this will be a net.Conn to
a remote node running a kaspa peer. Example syntax to request addresses
from a remote peer is:
// Create a new getaddr kaspa message.
msg := domainmessage.NewMsgRequestAddresses()
msg := appmessage.NewMsgRequestAddresses()
// Writes a kaspa message msg to conn using the protocol version
// pver, and the kaspa network kaspaNet. The return is a possible
// error.
err := domainmessage.WriteMessage(conn, msg, pver, kaspaNet)
err := appmessage.WriteMessage(conn, msg, pver, kaspaNet)
if err != nil {
// Log and handle the error
}
@@ -127,8 +127,8 @@ Errors
Errors returned by this package are either the raw errors provided by underlying
calls to read/write from streams such as io.EOF, io.ErrUnexpectedEOF, and
io.ErrShortWrite, or of type domainmessage.MessageError. This allows the caller to
io.ErrShortWrite, or of type appmessage.MessageError. This allows the caller to
differentiate between general IO errors and malformed messages through type
assertions.
*/
package domainmessage
package appmessage

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"fmt"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import "io"
@@ -15,7 +15,7 @@ type fakeMessage struct {
forceLenErr bool
}
// KaspaDecode doesn't do anything. It just satisfies the domainmessage.Message
// KaspaDecode doesn't do anything. It just satisfies the appmessage.Message
// interface.
func (msg *fakeMessage) KaspaDecode(r io.Reader, pver uint32) error {
return nil
@@ -23,7 +23,7 @@ func (msg *fakeMessage) KaspaDecode(r io.Reader, pver uint32) error {
// KaspaEncode writes the payload field of the fake message or forces an error
// if the forceEncodeErr flag of the fake message is set. It also satisfies the
// domainmessage.Message interface.
// appmessage.Message interface.
func (msg *fakeMessage) KaspaEncode(w io.Writer, pver uint32) error {
if msg.forceEncodeErr {
err := &MessageError{

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"bytes"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"fmt"
@@ -47,6 +47,7 @@ const (
CmdRequestNextIBDBlocks
CmdDoneIBDBlocks
CmdTransactionNotFound
CmdReject
)
// MessageCommandToString maps all MessageCommands to their string representation
@@ -72,6 +73,7 @@ var MessageCommandToString = map[MessageCommand]string{
CmdRequestNextIBDBlocks: "RequestNextIBDBlocks",
CmdDoneIBDBlocks: "DoneIBDBlocks",
CmdTransactionNotFound: "TransactionNotFound",
CmdReject: "Reject",
}
// Message is an interface that describes a kaspa message. A type that

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"fmt"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"net"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"bytes"
@@ -60,7 +60,7 @@ func (msg *MsgBlock) ClearTransactions() {
// KaspaDecode decodes r using the kaspa protocol encoding into the receiver.
// This is part of the Message interface implementation.
// See Deserialize for decoding blocks stored to disk, such as in a database, as
// opposed to decoding blocks from the domainmessage.
// opposed to decoding blocks from the appmessage.
func (msg *MsgBlock) KaspaDecode(r io.Reader, pver uint32) error {
err := readBlockHeader(r, pver, &msg.Header)
if err != nil {
@@ -97,14 +97,14 @@ func (msg *MsgBlock) KaspaDecode(r io.Reader, pver uint32) error {
// Deserialize decodes a block from r into the receiver using a format that is
// suitable for long-term storage such as a database while respecting the
// Version field in the block. This function differs from KaspaDecode in that
// KaspaDecode decodes from the kaspa domainmessage protocol as it was sent across the
// network. The domainmessage encoding can technically differ depending on the protocol
// KaspaDecode decodes from the kaspa appmessage protocol as it was sent across the
// network. The appmessage encoding can technically differ depending on the protocol
// version and doesn't even really need to match the format of a stored block at
// all. As of the time this comment was written, the encoded block is the same
// in both instances, but there is a distinct difference and separating the two
// allows the API to be flexible enough to deal with changes.
func (msg *MsgBlock) Deserialize(r io.Reader) error {
// At the current time, there is no difference between the domainmessage encoding
// At the current time, there is no difference between the appmessage encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of KaspaDecode.
return msg.KaspaDecode(r, 0)
@@ -117,9 +117,9 @@ func (msg *MsgBlock) Deserialize(r io.Reader) error {
func (msg *MsgBlock) DeserializeTxLoc(r *bytes.Buffer) ([]TxLoc, error) {
fullLen := r.Len()
// At the current time, there is no difference between the domainmessage encoding
// At the current time, there is no difference between the appmessage encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of existing domainmessage protocol functions.
// a result, make use of existing appmessage protocol functions.
err := readBlockHeader(r, 0, &msg.Header)
if err != nil {
return nil, err
@@ -160,7 +160,7 @@ func (msg *MsgBlock) DeserializeTxLoc(r *bytes.Buffer) ([]TxLoc, error) {
// KaspaEncode encodes the receiver to w using the kaspa protocol encoding.
// This is part of the Message interface implementation.
// See Serialize for encoding blocks to be stored to disk, such as in a
// database, as opposed to encoding blocks for the domainmessage.
// database, as opposed to encoding blocks for the appmessage.
func (msg *MsgBlock) KaspaEncode(w io.Writer, pver uint32) error {
err := writeBlockHeader(w, pver, &msg.Header)
if err != nil {
@@ -185,14 +185,14 @@ func (msg *MsgBlock) KaspaEncode(w io.Writer, pver uint32) error {
// Serialize encodes the block to w using a format that suitable for long-term
// storage such as a database while respecting the Version field in the block.
// This function differs from KaspaEncode in that KaspaEncode encodes the block to
// the kaspa domainmessage protocol in order to be sent across the network. The domainmessage
// the kaspa appmessage protocol in order to be sent across the network. The appmessage
// encoding can technically differ depending on the protocol version and doesn't
// even really need to match the format of a stored block at all. As of the
// time this comment was written, the encoded block is the same in both
// instances, but there is a distinct difference and separating the two allows
// the API to be flexible enough to deal with changes.
func (msg *MsgBlock) Serialize(w io.Writer) error {
// At the current time, there is no difference between the domainmessage encoding
// At the current time, there is no difference between the appmessage encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of KaspaEncode.
return msg.KaspaEncode(w, 0)

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"bytes"
@@ -144,7 +144,7 @@ func TestConvertToPartial(t *testing.T) {
}
}
// TestBlockEncoding tests the MsgBlock domainmessage encode and decode for various numbers
// TestBlockEncoding tests the MsgBlock appmessage encode and decode for various numbers
// of transaction inputs and outputs and protocol versions.
func TestBlockEncoding(t *testing.T) {
tests := []struct {
@@ -152,7 +152,7 @@ func TestBlockEncoding(t *testing.T) {
out *MsgBlock // Expected decoded message
buf []byte // Encoded value
txLocs []TxLoc // Expected transaction locations
pver uint32 // Protocol version for domainmessage encoding
pver uint32 // Protocol version for appmessage encoding
}{
// Latest protocol version.
{
@@ -166,7 +166,7 @@ func TestBlockEncoding(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode the message to domainmessage format.
// Encode the message to appmessage format.
var buf bytes.Buffer
err := test.in.KaspaEncode(&buf, test.pver)
if err != nil {
@@ -179,7 +179,7 @@ func TestBlockEncoding(t *testing.T) {
continue
}
// Decode the message from domainmessage format.
// Decode the message from appmessage format.
var msg MsgBlock
rbuf := bytes.NewReader(test.buf)
err = msg.KaspaDecode(rbuf, test.pver)
@@ -195,7 +195,7 @@ func TestBlockEncoding(t *testing.T) {
}
}
// TestBlockEncodingErrors performs negative tests against domainmessage encode and decode
// TestBlockEncodingErrors performs negative tests against appmessage encode and decode
// of MsgBlock to confirm error paths work correctly.
func TestBlockEncodingErrors(t *testing.T) {
pver := ProtocolVersion
@@ -203,7 +203,7 @@ func TestBlockEncodingErrors(t *testing.T) {
tests := []struct {
in *MsgBlock // Value to encode
buf []byte // Encoded value
pver uint32 // Protocol version for domainmessage encoding
pver uint32 // Protocol version for appmessage encoding
max int // Max size of fixed buffer to induce errors
writeErr error // Expected write error
readErr error // Expected read error
@@ -236,7 +236,7 @@ func TestBlockEncodingErrors(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to domainmessage format.
// Encode to appmessage format.
w := newFixedWriter(test.max)
err := test.in.KaspaEncode(w, test.pver)
if !errors.Is(err, test.writeErr) {
@@ -245,7 +245,7 @@ func TestBlockEncodingErrors(t *testing.T) {
continue
}
// Decode from domainmessage format.
// Decode from appmessage format.
var msg MsgBlock
r := newFixedReader(test.max, test.buf)
err = msg.KaspaDecode(r, test.pver)
@@ -324,7 +324,7 @@ func TestBlockSerialize(t *testing.T) {
}
}
// TestBlockSerializeErrors performs negative tests against domainmessage encode and
// TestBlockSerializeErrors performs negative tests against appmessage encode and
// decode of MsgBlock to confirm error paths work correctly.
func TestBlockSerializeErrors(t *testing.T) {
tests := []struct {
@@ -401,7 +401,7 @@ func TestBlockOverflowErrors(t *testing.T) {
tests := []struct {
buf []byte // Encoded value
pver uint32 // Protocol version for domainmessage encoding
pver uint32 // Protocol version for appmessage encoding
err error // Expected error
}{
// Block that claims to have ~uint64(0) transactions.
@@ -440,7 +440,7 @@ func TestBlockOverflowErrors(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Decode from domainmessage format.
// Decode from appmessage format.
var msg MsgBlock
r := bytes.NewReader(test.buf)
err := msg.KaspaDecode(r, test.pver)
@@ -450,7 +450,7 @@ func TestBlockOverflowErrors(t *testing.T) {
continue
}
// Deserialize from domainmessage format.
// Deserialize from appmessage format.
r = bytes.NewReader(test.buf)
err = msg.Deserialize(r)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
@@ -459,7 +459,7 @@ func TestBlockOverflowErrors(t *testing.T) {
continue
}
// Deserialize with transaction location info from domainmessage format.
// Deserialize with transaction location info from appmessage format.
br := bytes.NewBuffer(test.buf)
_, err = msg.DeserializeTxLoc(br)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {

View File

@@ -1,4 +1,4 @@
package domainmessage
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"

View File

@@ -1,4 +1,4 @@
package domainmessage
package appmessage
import (
"testing"

View File

@@ -1,4 +1,4 @@
package domainmessage
package appmessage
// MsgDoneIBDBlocks implements the Message interface and represents a kaspa
// DoneIBDBlocks message. It is used to notify the IBD syncing peer that the

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
// MsgIBDBlock implements the Message interface and represents a kaspa
// ibdblock message. It is used to deliver block and transaction information in

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"bytes"
@@ -65,7 +65,7 @@ func TestIBDBlock(t *testing.T) {
}
}
// TestIBDBlockEncoding tests the MsgIBDBlock domainmessage encode and decode for various numbers
// TestIBDBlockEncoding tests the MsgIBDBlock appmessage encode and decode for various numbers
// of transaction inputs and outputs and protocol versions.
func TestIBDBlockEncoding(t *testing.T) {
tests := []struct {
@@ -73,7 +73,7 @@ func TestIBDBlockEncoding(t *testing.T) {
out *MsgIBDBlock // Expected decoded message
buf []byte // Encoded value
txLocs []TxLoc // Expected transaction locations
pver uint32 // Protocol version for domainmessage encoding
pver uint32 // Protocol version for appmessage encoding
}{
// Latest protocol version.
{
@@ -87,7 +87,7 @@ func TestIBDBlockEncoding(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode the message to domainmessage format.
// Encode the message to appmessage format.
var buf bytes.Buffer
err := test.in.KaspaEncode(&buf, test.pver)
if err != nil {
@@ -100,7 +100,7 @@ func TestIBDBlockEncoding(t *testing.T) {
continue
}
// Decode the message from domainmessage format.
// Decode the message from appmessage format.
var msg MsgIBDBlock
msg.MsgBlock = new(MsgBlock)
rbuf := bytes.NewReader(test.buf)

View File

@@ -1,4 +1,4 @@
package domainmessage
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"

View File

@@ -1,4 +1,4 @@
package domainmessage
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
// MsgPing implements the Message interface and represents a kaspa ping
// message.

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"testing"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
// MsgPong implements the Message interface and represents a kaspa pong
// message which is used primarily to confirm that a connection is still valid

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"testing"

View File

@@ -0,0 +1,22 @@
package appmessage
// MsgReject implements the Message interface and represents a kaspa
// Reject message. It is used to notify peers why they are banned.
type MsgReject struct {
baseMessage
Reason string
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgReject) Command() MessageCommand {
return CmdReject
}
// NewMsgReject returns a new kaspa Reject message that conforms to the
// Message interface.
func NewMsgReject(reason string) *MsgReject {
return &MsgReject{
Reason: reason,
}
}

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"github.com/kaspanet/kaspad/util/subnetworkid"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"testing"

View File

@@ -1,4 +1,4 @@
package domainmessage
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"

View File

@@ -1,4 +1,4 @@
package domainmessage
package appmessage
import (
"testing"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"testing"

View File

@@ -1,4 +1,4 @@
package domainmessage
package appmessage
// MsgRequestNextIBDBlocks implements the Message interface and represents a kaspa
// RequestNextIBDBlocks message. It is used to notify the IBD syncer peer to send

View File

@@ -1,4 +1,4 @@
package domainmessage
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"

View File

@@ -1,4 +1,4 @@
package domainmessage
package appmessage
// MsgRequestSelectedTip implements the Message interface and represents a kaspa
// RequestSelectedTip message. It is used to request the selected tip of another peer.

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"testing"

View File

@@ -1,4 +1,4 @@
package domainmessage
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"

View File

@@ -1,4 +1,4 @@
package domainmessage
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"

View File

@@ -1,4 +1,4 @@
package domainmessage
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"github.com/kaspanet/kaspad/util/daghash"

View File

@@ -2,10 +2,9 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"bytes"
"encoding/binary"
"fmt"
"io"
@@ -84,7 +83,7 @@ const (
minTxPayload = 10
// freeListMaxScriptSize is the size of each buffer in the free list
// that is used for deserializing scripts from the domainmessage before they are
// that is used for deserializing scripts from the appmessage before they are
// concatenated into a single contiguous buffers. This value was chosen
// because it is slightly more than twice the size of the vast majority
// of all "standard" scripts. Larger scripts are still deserialized
@@ -302,29 +301,34 @@ func (msg *MsgTx) IsCoinBase() bool {
// TxHash generates the Hash for the transaction.
func (msg *MsgTx) TxHash() *daghash.Hash {
// Encode the transaction and calculate double sha256 on the result.
// Ignore the error returns since the only way the encode could fail
// is being out of memory or due to nil pointers, both of which would
// cause a run-time panic.
buf := bytes.NewBuffer(make([]byte, 0, msg.serializeSize(txEncodingExcludePayload)))
_ = msg.serialize(buf, txEncodingExcludePayload)
writer := daghash.NewDoubleHashWriter()
err := msg.serialize(writer, txEncodingExcludePayload)
if err != nil {
// this writer never return errors (no allocations or possible failures) so errors can only come from validity checks,
// and we assume we never construct malformed transactions.
panic(fmt.Sprintf("TxHash() failed. this should never fail for structurally-valid transactions. err: %+v", err))
}
hash := daghash.Hash(daghash.DoubleHashH(buf.Bytes()))
hash := writer.Finalize()
return &hash
}
// TxID generates the Hash for the transaction without the signature script, gas and payload fields.
func (msg *MsgTx) TxID() *daghash.TxID {
// Encode the transaction, replace signature script with zeroes, cut off
// payload and calculate double sha256 on the result. Ignore the error
// returns since the only way the encode could fail is being out of memory or
// due to nil pointers, both of which would cause a run-time panic.
// payload and calculate double sha256 on the result.
var encodingFlags txEncoding
if !msg.IsCoinBase() {
encodingFlags = txEncodingExcludeSignatureScript | txEncodingExcludePayload
}
buf := bytes.NewBuffer(make([]byte, 0, msg.serializeSize(encodingFlags)))
_ = msg.serialize(buf, encodingFlags)
txID := daghash.TxID(daghash.DoubleHashH(buf.Bytes()))
writer := daghash.NewDoubleHashWriter()
err := msg.serialize(writer, encodingFlags)
if err != nil {
// this writer never return errors (no allocations or possible failures) so errors can only come from validity checks,
// and we assume we never construct malformed transactions.
panic(fmt.Sprintf("TxID() failed. this should never fail for structurally-valid transactions. err: %+v", err))
}
txID := daghash.TxID(writer.Finalize())
return &txID
}
@@ -402,7 +406,7 @@ func (msg *MsgTx) Copy() *MsgTx {
// KaspaDecode decodes r using the kaspa protocol encoding into the receiver.
// This is part of the Message interface implementation.
// See Deserialize for decoding transactions stored to disk, such as in a
// database, as opposed to decoding transactions from the domainmessage.
// database, as opposed to decoding transactions from the appmessage.
func (msg *MsgTx) KaspaDecode(r io.Reader, pver uint32) error {
version, err := binaryserializer.Uint32(r, littleEndian)
if err != nil {
@@ -592,15 +596,15 @@ func (msg *MsgTx) KaspaDecode(r io.Reader, pver uint32) error {
// Deserialize decodes a transaction from r into the receiver using a format
// that is suitable for long-term storage such as a database while respecting
// the Version field in the transaction. This function differs from KaspaDecode
// in that KaspaDecode decodes from the kaspa domainmessage protocol as it was sent
// across the network. The domainmessage encoding can technically differ depending on
// in that KaspaDecode decodes from the kaspa appmessage protocol as it was sent
// across the network. The appmessage encoding can technically differ depending on
// the protocol version and doesn't even really need to match the format of a
// stored transaction at all. As of the time this comment was written, the
// encoded transaction is the same in both instances, but there is a distinct
// difference and separating the two allows the API to be flexible enough to
// deal with changes.
func (msg *MsgTx) Deserialize(r io.Reader) error {
// At the current time, there is no difference between the domainmessage encoding
// At the current time, there is no difference between the appmessage encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of KaspaDecode.
return msg.KaspaDecode(r, 0)
@@ -609,7 +613,7 @@ func (msg *MsgTx) Deserialize(r io.Reader) error {
// KaspaEncode encodes the receiver to w using the kaspa protocol encoding.
// This is part of the Message interface implementation.
// See Serialize for encoding transactions to be stored to disk, such as in a
// database, as opposed to encoding transactions for the domainmessage.
// database, as opposed to encoding transactions for the appmessage.
func (msg *MsgTx) KaspaEncode(w io.Writer, pver uint32) error {
return msg.encode(w, pver, txEncodingFull)
}
@@ -698,22 +702,22 @@ func (msg *MsgTx) encode(w io.Writer, pver uint32, encodingFlags txEncoding) err
// Serialize encodes the transaction to w using a format that suitable for
// long-term storage such as a database while respecting the Version field in
// the transaction. This function differs from KaspaEncode in that KaspaEncode
// encodes the transaction to the kaspa domainmessage protocol in order to be sent
// across the network. The domainmessage encoding can technically differ depending on
// encodes the transaction to the kaspa appmessage protocol in order to be sent
// across the network. The appmessage encoding can technically differ depending on
// the protocol version and doesn't even really need to match the format of a
// stored transaction at all. As of the time this comment was written, the
// encoded transaction is the same in both instances, but there is a distinct
// difference and separating the two allows the API to be flexible enough to
// deal with changes.
func (msg *MsgTx) Serialize(w io.Writer) error {
// At the current time, there is no difference between the domainmessage encoding
// At the current time, there is no difference between the appmessage encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of KaspaEncode.
return msg.KaspaEncode(w, 0)
}
func (msg *MsgTx) serialize(w io.Writer, encodingFlags txEncoding) error {
// At the current time, there is no difference between the domainmessage encoding
// At the current time, there is no difference between the appmessage encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of `encode`.
return msg.encode(w, 0, encodingFlags)

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"bytes"
@@ -253,7 +253,7 @@ func TestTxHashAndID(t *testing.T) {
}
}
// TestTxEncoding tests the MsgTx domainmessage encode and decode for various numbers
// TestTxEncoding tests the MsgTx appmessage encode and decode for various numbers
// of transaction inputs and outputs and protocol versions.
func TestTxEncoding(t *testing.T) {
// Empty tx message.
@@ -272,7 +272,7 @@ func TestTxEncoding(t *testing.T) {
in *MsgTx // Message to encode
out *MsgTx // Expected decoded message
buf []byte // Encoded value
pver uint32 // Protocol version for domainmessage encoding
pver uint32 // Protocol version for appmessage encoding
}{
// Latest protocol version with no transactions.
{
@@ -293,7 +293,7 @@ func TestTxEncoding(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode the message to domainmessage format.
// Encode the message to appmessage format.
var buf bytes.Buffer
err := test.in.KaspaEncode(&buf, test.pver)
if err != nil {
@@ -306,7 +306,7 @@ func TestTxEncoding(t *testing.T) {
continue
}
// Decode the message from domainmessage format.
// Decode the message from appmessage format.
var msg MsgTx
rbuf := bytes.NewReader(test.buf)
err = msg.KaspaDecode(rbuf, test.pver)
@@ -322,7 +322,7 @@ func TestTxEncoding(t *testing.T) {
}
}
// TestTxEncodingErrors performs negative tests against domainmessage encode and decode
// TestTxEncodingErrors performs negative tests against appmessage encode and decode
// of MsgTx to confirm error paths work correctly.
func TestTxEncodingErrors(t *testing.T) {
pver := ProtocolVersion
@@ -330,7 +330,7 @@ func TestTxEncodingErrors(t *testing.T) {
tests := []struct {
in *MsgTx // Value to encode
buf []byte // Encoded value
pver uint32 // Protocol version for domainmessage encoding
pver uint32 // Protocol version for appmessage encoding
max int // Max size of fixed buffer to induce errors
writeErr error // Expected write error
readErr error // Expected read error
@@ -363,7 +363,7 @@ func TestTxEncodingErrors(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Encode to domainmessage format.
// Encode to appmessage format.
w := newFixedWriter(test.max)
err := test.in.KaspaEncode(w, test.pver)
if !errors.Is(err, test.writeErr) {
@@ -372,7 +372,7 @@ func TestTxEncodingErrors(t *testing.T) {
continue
}
// Decode from domainmessage format.
// Decode from appmessage format.
var msg MsgTx
r := newFixedReader(test.max, test.buf)
err = msg.KaspaDecode(r, test.pver)
@@ -528,7 +528,7 @@ func TestTxSerialize(t *testing.T) {
}
}
// TestTxSerializeErrors performs negative tests against domainmessage encode and decode
// TestTxSerializeErrors performs negative tests against appmessage encode and decode
// of MsgTx to confirm error paths work correctly.
func TestTxSerializeErrors(t *testing.T) {
tests := []struct {
@@ -629,7 +629,7 @@ func TestTxOverflowErrors(t *testing.T) {
tests := []struct {
buf []byte // Encoded value
pver uint32 // Protocol version for domainmessage encoding
pver uint32 // Protocol version for appmessage encoding
version uint32 // Transaction version
err error // Expected error
}{
@@ -691,7 +691,7 @@ func TestTxOverflowErrors(t *testing.T) {
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Decode from domainmessage format.
// Decode from appmessage format.
var msg MsgTx
r := bytes.NewReader(test.buf)
err := msg.KaspaDecode(r, test.pver)
@@ -701,7 +701,7 @@ func TestTxOverflowErrors(t *testing.T) {
continue
}
// Decode from domainmessage format.
// Decode from appmessage format.
r = bytes.NewReader(test.buf)
err = msg.Deserialize(r)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
@@ -891,7 +891,7 @@ var multiTxOuts = []*TxOut{
}
var multiTx = NewNativeMsgTx(1, multiTxIns, multiTxOuts)
// multiTxEncoded is the domainmessage encoded bytes for multiTx using protocol version
// multiTxEncoded is the appmessage encoded bytes for multiTx using protocol version
// 60002 and is used in the various tests.
var multiTxEncoded = []byte{
0x01, 0x00, 0x00, 0x00, // Version

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
// MsgVerAck defines a kaspa verack message which is used for a peer to
// acknowledge a version message (MsgVersion) after it has used the information

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"testing"

View File

@@ -2,15 +2,15 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"fmt"
"github.com/kaspanet/kaspad/version"
"strings"
"github.com/kaspanet/kaspad/netadapter/id"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/id"
"github.com/kaspanet/kaspad/util/mstime"
"github.com/kaspanet/kaspad/version"
"github.com/kaspanet/kaspad/util/daghash"
"github.com/kaspanet/kaspad/util/subnetworkid"
@@ -20,7 +20,7 @@ import (
// version message (MsgVersion).
const MaxUserAgentLen = 256
// DefaultUserAgent for domainmessage in the stack
// DefaultUserAgent for appmessage in the stack
var DefaultUserAgent = fmt.Sprintf("/kaspad:%s/", version.Version())
// MsgVersion implements the Message interface and represents a kaspa version
@@ -41,7 +41,7 @@ type MsgVersion struct {
// Bitfield which identifies the enabled services.
Services ServiceFlag
// Time the message was generated. This is encoded as an int64 on the domainmessage.
// Time the message was generated. This is encoded as an int64 on the appmessage.
Timestamp mstime.Time
// Address of the local peer.
@@ -51,7 +51,7 @@ type MsgVersion struct {
ID *id.ID
// The user agent that generated messsage. This is a encoded as a varString
// on the domainmessage. This has a max length of MaxUserAgentLen.
// on the appmessage. This has a max length of MaxUserAgentLen.
UserAgent string
// The selected tip hash of the generator of the version message.

View File

@@ -2,11 +2,11 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"github.com/davecgh/go-spew/spew"
"github.com/kaspanet/kaspad/netadapter/id"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/id"
"github.com/kaspanet/kaspad/util/daghash"
"net"
"reflect"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"github.com/kaspanet/kaspad/util/mstime"
@@ -21,7 +21,7 @@ type NetAddress struct {
// IP address of the peer.
IP net.IP
// Port the peer is using. This is encoded in big endian on the domainmessage
// Port the peer is using. This is encoded in big endian on the appmessage
// which differs from most everything else.
Port uint16
}

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"net"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import (
"fmt"

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package domainmessage
package appmessage
import "testing"

View File

@@ -6,7 +6,7 @@
package app
import (
"github.com/kaspanet/kaspad/logger"
"github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/kaspanet/kaspad/util/panics"
)

View File

@@ -5,7 +5,7 @@
package blocklogger
import (
"github.com/kaspanet/kaspad/logger"
"github.com/kaspanet/kaspad/infrastructure/logger"
)
var log, _ = logger.Get(logger.SubsystemTags.PROT)

View File

@@ -1,7 +1,7 @@
package flowcontext
import (
"github.com/kaspanet/kaspad/addressmanager"
"github.com/kaspanet/kaspad/infrastructure/network/addressmanager"
)
// AddressManager returns the address manager associated to the flow context.

View File

@@ -3,9 +3,9 @@ package flowcontext
import (
"sync/atomic"
"github.com/kaspanet/kaspad/blockdag"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/protocol/flows/blockrelay"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/flows/blockrelay"
"github.com/kaspanet/kaspad/domain/blockdag"
"github.com/kaspanet/kaspad/util"
"github.com/kaspanet/kaspad/util/daghash"
)
@@ -19,8 +19,6 @@ func (f *FlowContext) OnNewBlock(block *util.Block) error {
return err
}
// TODO(libp2p) Notify transactionsAcceptedToMempool to RPC
return f.broadcastTransactionsAfterBlockAdded(block, transactionsAcceptedToMempool)
}
@@ -41,16 +39,18 @@ func (f *FlowContext) broadcastTransactionsAfterBlockAdded(block *util.Block, tr
for i, tx := range transactionsAcceptedToMempool {
txIDsToBroadcast[i] = tx.ID()
}
copy(txIDsToBroadcast[len(transactionsAcceptedToMempool):], txIDsToBroadcast)
offset := len(transactionsAcceptedToMempool)
for i, txID := range txIDsToRebroadcast {
txIDsToBroadcast[offset+i] = txID
}
if len(txIDsToBroadcast) == 0 {
return nil
}
if len(txIDsToBroadcast) > domainmessage.MaxInvPerTxInvMsg {
txIDsToBroadcast = txIDsToBroadcast[:domainmessage.MaxInvPerTxInvMsg]
if len(txIDsToBroadcast) > appmessage.MaxInvPerTxInvMsg {
txIDsToBroadcast = txIDsToBroadcast[:appmessage.MaxInvPerTxInvMsg]
}
inv := domainmessage.NewMsgInvTransaction(txIDsToBroadcast)
inv := appmessage.NewMsgInvTransaction(txIDsToBroadcast)
return f.Broadcast(inv)
}
@@ -66,5 +66,9 @@ func (f *FlowContext) AddBlock(block *util.Block, flags blockdag.BehaviorFlags)
if err != nil {
return err
}
return f.Broadcast(domainmessage.NewMsgInvBlock(block.Hash()))
err = f.OnNewBlock(block)
if err != nil {
return err
}
return f.Broadcast(appmessage.NewMsgInvBlock(block.Hash()))
}

View File

@@ -1,6 +1,6 @@
package flowcontext
import "github.com/kaspanet/kaspad/config"
import "github.com/kaspanet/kaspad/infrastructure/config"
// Config returns an instance of *config.Config associated to the flow context.
func (f *FlowContext) Config() *config.Config {

View File

@@ -1,6 +1,6 @@
package flowcontext
import "github.com/kaspanet/kaspad/blockdag"
import "github.com/kaspanet/kaspad/domain/blockdag"
// DAG returns the DAG associated to the flow context.
func (f *FlowContext) DAG() *blockdag.BlockDAG {

View File

@@ -0,0 +1,31 @@
package flowcontext
import (
"errors"
"sync/atomic"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
)
// HandleError handles an error from a flow,
// It sends the error to errChan if isStopping == 0 and increments isStopping
//
// If this is ErrRouteClosed - forward it to errChan
// If this is ProtocolError - logs the error, and forward it to errChan
// Otherwise - panics
func (*FlowContext) HandleError(err error, flowName string, isStopping *uint32, errChan chan<- error) {
isErrRouteClosed := errors.Is(err, router.ErrRouteClosed)
if !isErrRouteClosed {
if protocolErr := &(protocolerrors.ProtocolError{}); !errors.As(err, &protocolErr) {
panic(err)
}
log.Errorf("error from %s: %+v", flowName, err)
}
if atomic.AddUint32(isStopping, 1) == 1 {
errChan <- err
}
}

View File

@@ -4,16 +4,16 @@ import (
"sync"
"time"
"github.com/kaspanet/kaspad/addressmanager"
"github.com/kaspanet/kaspad/blockdag"
"github.com/kaspanet/kaspad/config"
"github.com/kaspanet/kaspad/connmanager"
"github.com/kaspanet/kaspad/mempool"
"github.com/kaspanet/kaspad/netadapter"
"github.com/kaspanet/kaspad/netadapter/id"
"github.com/kaspanet/kaspad/protocol/flows/blockrelay"
"github.com/kaspanet/kaspad/protocol/flows/relaytransactions"
peerpkg "github.com/kaspanet/kaspad/protocol/peer"
"github.com/kaspanet/kaspad/app/protocol/flows/blockrelay"
"github.com/kaspanet/kaspad/app/protocol/flows/relaytransactions"
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
"github.com/kaspanet/kaspad/domain/blockdag"
"github.com/kaspanet/kaspad/domain/mempool"
"github.com/kaspanet/kaspad/infrastructure/config"
"github.com/kaspanet/kaspad/infrastructure/network/addressmanager"
"github.com/kaspanet/kaspad/infrastructure/network/connmanager"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/id"
"github.com/kaspanet/kaspad/util"
"github.com/kaspanet/kaspad/util/daghash"
)

View File

@@ -4,8 +4,8 @@ import (
"sync/atomic"
"time"
"github.com/kaspanet/kaspad/blockdag"
peerpkg "github.com/kaspanet/kaspad/protocol/peer"
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
"github.com/kaspanet/kaspad/domain/blockdag"
)
// StartIBDIfRequired selects a peer and starts IBD against it

View File

@@ -1,7 +1,7 @@
package flowcontext
import (
"github.com/kaspanet/kaspad/logger"
"github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/kaspanet/kaspad/util/panics"
)

View File

@@ -1,11 +1,11 @@
package flowcontext
import (
"github.com/kaspanet/kaspad/connmanager"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter"
"github.com/kaspanet/kaspad/protocol/common"
peerpkg "github.com/kaspanet/kaspad/protocol/peer"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/common"
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
"github.com/kaspanet/kaspad/infrastructure/network/connmanager"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter"
"github.com/pkg/errors"
)
@@ -33,6 +33,14 @@ func (f *FlowContext) AddToPeers(peer *peerpkg.Peer) error {
return nil
}
// RemoveFromPeers remove this peer from the peers list.
func (f *FlowContext) RemoveFromPeers(peer *peerpkg.Peer) {
f.peersMutex.Lock()
defer f.peersMutex.Unlock()
delete(f.peers, peer.ID())
}
// readyPeerConnections returns the NetConnections of all the ready peers.
func (f *FlowContext) readyPeerConnections() []*netadapter.NetConnection {
f.peersMutex.RLock()
@@ -47,7 +55,7 @@ func (f *FlowContext) readyPeerConnections() []*netadapter.NetConnection {
}
// Broadcast broadcast the given message to all the ready peers.
func (f *FlowContext) Broadcast(message domainmessage.Message) error {
func (f *FlowContext) Broadcast(message appmessage.Message) error {
return f.netAdapter.Broadcast(f.readyPeerConnections(), message)
}

View File

@@ -1,9 +1,9 @@
package flowcontext
import (
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/mempool"
"github.com/kaspanet/kaspad/protocol/flows/relaytransactions"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/flows/relaytransactions"
"github.com/kaspanet/kaspad/domain/mempool"
"github.com/kaspanet/kaspad/util"
"github.com/kaspanet/kaspad/util/daghash"
"github.com/pkg/errors"
@@ -15,7 +15,7 @@ func (f *FlowContext) AddTransaction(tx *util.Tx) error {
f.transactionsToRebroadcastLock.Lock()
defer f.transactionsToRebroadcastLock.Unlock()
transactionsAcceptedToMempool, err := f.txPool.ProcessTransaction(tx, false, 0)
transactionsAcceptedToMempool, err := f.txPool.ProcessTransaction(tx, false)
if err != nil {
return err
}
@@ -25,7 +25,7 @@ func (f *FlowContext) AddTransaction(tx *util.Tx) error {
}
f.transactionsToRebroadcast[*tx.ID()] = tx
inv := domainmessage.NewMsgInvTransaction([]*daghash.TxID{tx.ID()})
inv := appmessage.NewMsgInvTransaction([]*daghash.TxID{tx.ID()})
return f.Broadcast(inv)
}

View File

@@ -1,13 +1,13 @@
package addressexchange
import (
"github.com/kaspanet/kaspad/addressmanager"
"github.com/kaspanet/kaspad/config"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter/router"
"github.com/kaspanet/kaspad/protocol/common"
peerpkg "github.com/kaspanet/kaspad/protocol/peer"
"github.com/kaspanet/kaspad/protocol/protocolerrors"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/common"
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
"github.com/kaspanet/kaspad/infrastructure/config"
"github.com/kaspanet/kaspad/infrastructure/network/addressmanager"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
)
// ReceiveAddressesContext is the interface for the context needed for the ReceiveAddresses flow.
@@ -25,7 +25,7 @@ func ReceiveAddresses(context ReceiveAddressesContext, incomingRoute *router.Rou
}
subnetworkID := peer.SubnetworkID()
msgGetAddresses := domainmessage.NewMsgRequestAddresses(false, subnetworkID)
msgGetAddresses := appmessage.NewMsgRequestAddresses(false, subnetworkID)
err := outgoingRoute.Enqueue(msgGetAddresses)
if err != nil {
return err
@@ -36,7 +36,7 @@ func ReceiveAddresses(context ReceiveAddressesContext, incomingRoute *router.Rou
return err
}
msgAddresses := message.(*domainmessage.MsgAddresses)
msgAddresses := message.(*appmessage.MsgAddresses)
if len(msgAddresses.AddrList) > addressmanager.GetAddressesMax {
return protocolerrors.Errorf(true, "address count excceeded %d", addressmanager.GetAddressesMax)
}
@@ -51,9 +51,7 @@ func ReceiveAddresses(context ReceiveAddressesContext, incomingRoute *router.Rou
context.Config().SubnetworkID, msgAddresses.Command(), msgAddresses.SubnetworkID)
}
// TODO(libp2p) Consider adding to peer known addresses set
// TODO(libp2p) Replace with real peer IP
fakeSourceAddress := new(domainmessage.NetAddress)
context.AddressManager().AddAddresses(msgAddresses.AddrList, fakeSourceAddress, msgAddresses.SubnetworkID)
sourceAddress := peer.Connection().NetAddress()
context.AddressManager().AddAddresses(msgAddresses.AddrList, sourceAddress, msgAddresses.SubnetworkID)
return nil
}

View File

@@ -1,9 +1,9 @@
package addressexchange
import (
"github.com/kaspanet/kaspad/addressmanager"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter/router"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/infrastructure/network/addressmanager"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
"math/rand"
)
@@ -20,10 +20,10 @@ func SendAddresses(context SendAddressesContext, incomingRoute *router.Route, ou
return err
}
msgGetAddresses := message.(*domainmessage.MsgRequestAddresses)
msgGetAddresses := message.(*appmessage.MsgRequestAddresses)
addresses := context.AddressManager().AddressCache(msgGetAddresses.IncludeAllSubnetworks,
msgGetAddresses.SubnetworkID)
msgAddresses := domainmessage.NewMsgAddresses(msgGetAddresses.IncludeAllSubnetworks, msgGetAddresses.SubnetworkID)
msgAddresses := appmessage.NewMsgAddresses(msgGetAddresses.IncludeAllSubnetworks, msgGetAddresses.SubnetworkID)
err = msgAddresses.AddAddresses(shuffleAddresses(addresses)...)
if err != nil {
return err
@@ -33,14 +33,14 @@ func SendAddresses(context SendAddressesContext, incomingRoute *router.Route, ou
}
// shuffleAddresses randomizes the given addresses sent if there are more than the maximum allowed in one message.
func shuffleAddresses(addresses []*domainmessage.NetAddress) []*domainmessage.NetAddress {
func shuffleAddresses(addresses []*appmessage.NetAddress) []*appmessage.NetAddress {
addressCount := len(addresses)
if addressCount < domainmessage.MaxAddressesPerMsg {
if addressCount < appmessage.MaxAddressesPerMsg {
return addresses
}
shuffleAddresses := make([]*domainmessage.NetAddress, addressCount)
shuffleAddresses := make([]*appmessage.NetAddress, addressCount)
copy(shuffleAddresses, addresses)
rand.Shuffle(addressCount, func(i, j int) {
@@ -48,6 +48,6 @@ func shuffleAddresses(addresses []*domainmessage.NetAddress) []*domainmessage.Ne
})
// Truncate it to the maximum size.
shuffleAddresses = shuffleAddresses[:domainmessage.MaxAddressesPerMsg]
shuffleAddresses = shuffleAddresses[:appmessage.MaxAddressesPerMsg]
return shuffleAddresses
}

View File

@@ -1,11 +1,11 @@
package blockrelay
import (
"github.com/kaspanet/kaspad/blockdag"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter/router"
peerpkg "github.com/kaspanet/kaspad/protocol/peer"
"github.com/kaspanet/kaspad/protocol/protocolerrors"
"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/blockdag"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
"github.com/pkg/errors"
)
@@ -14,7 +14,7 @@ type RelayBlockRequestsContext interface {
DAG() *blockdag.BlockDAG
}
// HandleRelayBlockRequests listens to domainmessage.MsgRequestRelayBlocks messages and sends
// HandleRelayBlockRequests listens to appmessage.MsgRequestRelayBlocks messages and sends
// their corresponding blocks to the requesting peer.
func HandleRelayBlockRequests(context RelayBlockRequestsContext, incomingRoute *router.Route,
outgoingRoute *router.Route, peer *peerpkg.Peer) error {
@@ -24,7 +24,7 @@ func HandleRelayBlockRequests(context RelayBlockRequestsContext, incomingRoute *
if err != nil {
return err
}
getRelayBlocksMessage := message.(*domainmessage.MsgRequestRelayBlocks)
getRelayBlocksMessage := message.(*appmessage.MsgRequestRelayBlocks)
for _, hash := range getRelayBlocksMessage.Hashes {
// Fetch the block from the database.
block, err := context.DAG().BlockByHash(hash)

View File

@@ -1,14 +1,14 @@
package blockrelay
import (
"github.com/kaspanet/kaspad/blockdag"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter"
"github.com/kaspanet/kaspad/netadapter/router"
"github.com/kaspanet/kaspad/protocol/blocklogger"
"github.com/kaspanet/kaspad/protocol/common"
peerpkg "github.com/kaspanet/kaspad/protocol/peer"
"github.com/kaspanet/kaspad/protocol/protocolerrors"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/blocklogger"
"github.com/kaspanet/kaspad/app/protocol/common"
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
"github.com/kaspanet/kaspad/domain/blockdag"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
"github.com/kaspanet/kaspad/util"
"github.com/kaspanet/kaspad/util/daghash"
mathUtil "github.com/kaspanet/kaspad/util/math"
@@ -23,17 +23,17 @@ type RelayInvsContext interface {
SharedRequestedBlocks() *SharedRequestedBlocks
StartIBDIfRequired()
IsInIBD() bool
Broadcast(message domainmessage.Message) error
Broadcast(message appmessage.Message) error
}
type handleRelayInvsFlow struct {
RelayInvsContext
incomingRoute, outgoingRoute *router.Route
peer *peerpkg.Peer
invsQueue []*domainmessage.MsgInvRelayBlock
invsQueue []*appmessage.MsgInvRelayBlock
}
// HandleRelayInvs listens to domainmessage.MsgInvRelayBlock messages, requests their corresponding blocks if they
// HandleRelayInvs listens to appmessage.MsgInvRelayBlock messages, requests their corresponding blocks if they
// are missing, adds them to the DAG and propagates them to the rest of the network.
func HandleRelayInvs(context RelayInvsContext, incomingRoute *router.Route, outgoingRoute *router.Route,
peer *peerpkg.Peer) error {
@@ -43,7 +43,7 @@ func HandleRelayInvs(context RelayInvsContext, incomingRoute *router.Route, outg
incomingRoute: incomingRoute,
outgoingRoute: outgoingRoute,
peer: peer,
invsQueue: make([]*domainmessage.MsgInvRelayBlock, 0),
invsQueue: make([]*appmessage.MsgInvRelayBlock, 0),
}
return flow.start()
}
@@ -81,10 +81,10 @@ func (flow *handleRelayInvsFlow) start() error {
}
}
func (flow *handleRelayInvsFlow) readInv() (*domainmessage.MsgInvRelayBlock, error) {
func (flow *handleRelayInvsFlow) readInv() (*appmessage.MsgInvRelayBlock, error) {
if len(flow.invsQueue) > 0 {
var inv *domainmessage.MsgInvRelayBlock
var inv *appmessage.MsgInvRelayBlock
inv, flow.invsQueue = flow.invsQueue[0], flow.invsQueue[1:]
return inv, nil
}
@@ -94,7 +94,7 @@ func (flow *handleRelayInvsFlow) readInv() (*domainmessage.MsgInvRelayBlock, err
return nil, err
}
inv, ok := msg.(*domainmessage.MsgInvRelayBlock)
inv, ok := msg.(*appmessage.MsgInvRelayBlock)
if !ok {
return nil, protocolerrors.Errorf(true, "unexpected %s message in the block relay handleRelayInvsFlow while "+
"expecting an inv message", msg.Command())
@@ -103,7 +103,7 @@ func (flow *handleRelayInvsFlow) readInv() (*domainmessage.MsgInvRelayBlock, err
}
func (flow *handleRelayInvsFlow) requestBlocks(requestQueue *hashesQueueSet) error {
numHashesToRequest := mathUtil.MinInt(domainmessage.MsgRequestRelayBlocksHashes, requestQueue.len())
numHashesToRequest := mathUtil.MinInt(appmessage.MsgRequestRelayBlocksHashes, requestQueue.len())
hashesToRequest := requestQueue.dequeue(numHashesToRequest)
pendingBlocks := map[daghash.Hash]struct{}{}
@@ -127,7 +127,7 @@ func (flow *handleRelayInvsFlow) requestBlocks(requestQueue *hashesQueueSet) err
// clean from any pending blocks.
defer flow.SharedRequestedBlocks().removeSet(pendingBlocks)
getRelayBlocksMsg := domainmessage.NewMsgRequestRelayBlocks(filteredHashesToRequest)
getRelayBlocksMsg := appmessage.NewMsgRequestRelayBlocks(filteredHashesToRequest)
err := flow.outgoingRoute.Enqueue(getRelayBlocksMsg)
if err != nil {
return err
@@ -160,9 +160,9 @@ func (flow *handleRelayInvsFlow) requestBlocks(requestQueue *hashesQueueSet) err
// readMsgBlock returns the next msgBlock in msgChan, and populates invsQueue with any inv messages that meanwhile arrive.
//
// Note: this function assumes msgChan can contain only domainmessage.MsgInvRelayBlock and domainmessage.MsgBlock messages.
// Note: this function assumes msgChan can contain only appmessage.MsgInvRelayBlock and appmessage.MsgBlock messages.
func (flow *handleRelayInvsFlow) readMsgBlock() (
msgBlock *domainmessage.MsgBlock, err error) {
msgBlock *appmessage.MsgBlock, err error) {
for {
message, err := flow.incomingRoute.DequeueWithTimeout(common.DefaultTimeout)
@@ -171,9 +171,9 @@ func (flow *handleRelayInvsFlow) readMsgBlock() (
}
switch message := message.(type) {
case *domainmessage.MsgInvRelayBlock:
case *appmessage.MsgInvRelayBlock:
flow.invsQueue = append(flow.invsQueue, message)
case *domainmessage.MsgBlock:
case *appmessage.MsgBlock:
return message, nil
default:
return nil, errors.Errorf("unexpected message %s", message.Command())
@@ -190,7 +190,7 @@ func (flow *handleRelayInvsFlow) processAndRelayBlock(requestQueue *hashesQueueS
}
log.Infof("Rejected block %s from %s: %s", blockHash, flow.peer, err)
return protocolerrors.Wrap(true, err, "got invalid block")
return protocolerrors.Wrapf(true, err, "got invalid block %s", blockHash)
}
if isDelayed {
@@ -224,13 +224,7 @@ func (flow *handleRelayInvsFlow) processAndRelayBlock(requestQueue *hashesQueueS
if err != nil {
return err
}
//TODO(libp2p)
//// When the block is not an orphan, log information about it and
//// update the DAG state.
// sm.restartSyncIfNeeded()
//// Clear the rejected transactions.
//sm.rejectedTxns = make(map[daghash.TxID]struct{})
err = flow.Broadcast(domainmessage.NewMsgInvBlock(blockHash))
err = flow.Broadcast(appmessage.NewMsgInvBlock(blockHash))
if err != nil {
return err
}

View File

@@ -1,7 +1,7 @@
package blockrelay
import (
"github.com/kaspanet/kaspad/logger"
"github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/kaspanet/kaspad/util/panics"
)

View File

@@ -4,18 +4,17 @@ import (
"sync"
"sync/atomic"
"github.com/kaspanet/kaspad/addressmanager"
"github.com/kaspanet/kaspad/protocol/common"
"github.com/kaspanet/kaspad/protocol/protocolerrors"
"github.com/kaspanet/kaspad/app/protocol/common"
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
"github.com/kaspanet/kaspad/infrastructure/network/addressmanager"
"github.com/kaspanet/kaspad/blockdag"
"github.com/kaspanet/kaspad/config"
"github.com/kaspanet/kaspad/netadapter"
"github.com/kaspanet/kaspad/domain/blockdag"
"github.com/kaspanet/kaspad/infrastructure/config"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter/router"
routerpkg "github.com/kaspanet/kaspad/netadapter/router"
peerpkg "github.com/kaspanet/kaspad/protocol/peer"
"github.com/kaspanet/kaspad/app/appmessage"
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
routerpkg "github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
"github.com/kaspanet/kaspad/util/locks"
"github.com/pkg/errors"
)
@@ -48,7 +47,7 @@ func HandleHandshake(context HandleHandshakeContext, netConnection *netadapter.N
peer = peerpkg.New(netConnection)
var peerAddress *domainmessage.NetAddress
var peerAddress *appmessage.NetAddress
spawn("HandleHandshake-ReceiveVersion", func() {
defer wg.Done()
address, err := ReceiveVersion(context, receiveVersionRoute, outgoingRoute, peer)
@@ -99,7 +98,7 @@ func HandleHandshake(context HandleHandshakeContext, netConnection *netadapter.N
// Handshake is different from other flows, since in it should forward router.ErrRouteClosed to errChan
// Therefore we implement a separate handleError for handshake
func handleError(err error, flowName string, isStopping *uint32, errChan chan error) {
if errors.Is(err, router.ErrRouteClosed) {
if errors.Is(err, routerpkg.ErrRouteClosed) {
if atomic.AddUint32(isStopping, 1) == 1 {
errChan <- err
}

View File

@@ -1,7 +1,7 @@
package handshake
import (
"github.com/kaspanet/kaspad/logger"
"github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/kaspanet/kaspad/util/panics"
)

View File

@@ -1,11 +1,11 @@
package handshake
import (
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter/router"
"github.com/kaspanet/kaspad/protocol/common"
peerpkg "github.com/kaspanet/kaspad/protocol/peer"
"github.com/kaspanet/kaspad/protocol/protocolerrors"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/common"
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
)
var (
@@ -16,7 +16,7 @@ var (
// minAcceptableProtocolVersion is the lowest protocol version that a
// connected peer may support.
minAcceptableProtocolVersion = domainmessage.ProtocolVersion
minAcceptableProtocolVersion = appmessage.ProtocolVersion
)
type receiveVersionFlow struct {
@@ -28,7 +28,7 @@ type receiveVersionFlow struct {
// ReceiveVersion waits for the peer to send a version message, sends a
// verack in response, and updates its info accordingly.
func ReceiveVersion(context HandleHandshakeContext, incomingRoute *router.Route, outgoingRoute *router.Route,
peer *peerpkg.Peer) (*domainmessage.NetAddress, error) {
peer *peerpkg.Peer) (*appmessage.NetAddress, error) {
flow := &receiveVersionFlow{
HandleHandshakeContext: context,
@@ -40,13 +40,13 @@ func ReceiveVersion(context HandleHandshakeContext, incomingRoute *router.Route,
return flow.start()
}
func (flow *receiveVersionFlow) start() (*domainmessage.NetAddress, error) {
func (flow *receiveVersionFlow) start() (*appmessage.NetAddress, error) {
message, err := flow.incomingRoute.DequeueWithTimeout(common.DefaultTimeout)
if err != nil {
return nil, err
}
msgVersion, ok := message.(*domainmessage.MsgVersion)
msgVersion, ok := message.(*appmessage.MsgVersion)
if !ok {
return nil, protocolerrors.New(true, "a version message must precede all others")
}
@@ -64,10 +64,9 @@ func (flow *receiveVersionFlow) start() (*domainmessage.NetAddress, error) {
// too old.
//
// NOTE: If minAcceptableProtocolVersion is raised to be higher than
// domainmessage.RejectVersion, this should send a reject packet before
// appmessage.RejectVersion, this should send a reject packet before
// disconnecting.
if msgVersion.ProtocolVersion < minAcceptableProtocolVersion {
//TODO(libp2p) create error type for disconnect but don't ban
return nil, protocolerrors.Errorf(false, "protocol version must be %d or greater",
minAcceptableProtocolVersion)
}
@@ -77,21 +76,21 @@ func (flow *receiveVersionFlow) start() (*domainmessage.NetAddress, error) {
return nil, protocolerrors.New(true, "partial nodes are not allowed")
}
// TODO(libp2p)
//// Disconnect if:
//// - we are a full node and the outbound connection we've initiated is a partial node
//// - the remote node is partial and our subnetwork doesn't match their subnetwork
//localSubnetworkID := config.ActiveConfig().SubnetworkID
//isLocalNodeFull := localSubnetworkID == nil
//isRemoteNodeFull := msgVersion.SubnetworkID == nil
//if (isLocalNodeFull && !isRemoteNodeFull && !connection.IsInbound()) ||
// (!isLocalNodeFull && !isRemoteNodeFull && !msgVersion.SubnetworkID.IsEqual(localSubnetworkID)) {
//
// return nil, false, errors.New("incompatible subnetworks")
//}
// Disconnect if:
// - we are a full node and the outbound connection we've initiated is a partial node
// - the remote node is partial and our subnetwork doesn't match their subnetwork
localSubnetworkID := flow.Config().SubnetworkID
isLocalNodeFull := localSubnetworkID == nil
isRemoteNodeFull := msgVersion.SubnetworkID == nil
isOutbound := flow.peer.Connection().IsOutbound()
if (isLocalNodeFull && !isRemoteNodeFull && isOutbound) ||
(!isLocalNodeFull && !isRemoteNodeFull && !msgVersion.SubnetworkID.IsEqual(localSubnetworkID)) {
return nil, protocolerrors.New(false, "incompatible subnetworks")
}
flow.peer.UpdateFieldsFromMsgVersion(msgVersion)
err = flow.outgoingRoute.Enqueue(domainmessage.NewMsgVerAck())
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgVerAck())
if err != nil {
return nil, err
}

View File

@@ -1,9 +1,9 @@
package handshake
import (
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter/router"
"github.com/kaspanet/kaspad/protocol/common"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/common"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
"github.com/kaspanet/kaspad/version"
)
@@ -18,11 +18,11 @@ var (
// defaultServices describes the default services that are supported by
// the server.
defaultServices = domainmessage.SFNodeNetwork | domainmessage.SFNodeBloom | domainmessage.SFNodeCF
defaultServices = appmessage.SFNodeNetwork | appmessage.SFNodeBloom | appmessage.SFNodeCF
// defaultRequiredServices describes the default services that are
// required to be supported by outbound peers.
defaultRequiredServices = domainmessage.SFNodeNetwork
defaultRequiredServices = appmessage.SFNodeNetwork
)
type sendVersionFlow struct {
@@ -49,7 +49,7 @@ func (flow *sendVersionFlow) start() error {
if err != nil {
return err
}
msg := domainmessage.NewMsgVersion(localAddress, flow.NetAdapter().ID(),
msg := appmessage.NewMsgVersion(localAddress, flow.NetAdapter().ID(),
flow.Config().ActiveNetParams.Name, selectedTipHash, subnetworkID)
msg.AddUserAgent(userAgentName, userAgentVersion, flow.Config().UserAgentComments...)
@@ -57,7 +57,7 @@ func (flow *sendVersionFlow) start() error {
msg.Services = defaultServices
// Advertise our max supported protocol version.
msg.ProtocolVersion = domainmessage.ProtocolVersion
msg.ProtocolVersion = appmessage.ProtocolVersion
// Advertise if inv messages for transactions are desired.
msg.DisableRelayTx = flow.Config().BlocksOnly

View File

@@ -1,10 +1,10 @@
package ibd
import (
"github.com/kaspanet/kaspad/blockdag"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter/router"
"github.com/kaspanet/kaspad/protocol/protocolerrors"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
"github.com/kaspanet/kaspad/domain/blockdag"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
"github.com/kaspanet/kaspad/util/daghash"
)
@@ -57,13 +57,13 @@ func (flow *handleRequestBlockLocatorFlow) receiveGetBlockLocator() (lowHash *da
if err != nil {
return nil, nil, err
}
msgGetBlockLocator := message.(*domainmessage.MsgRequestBlockLocator)
msgGetBlockLocator := message.(*appmessage.MsgRequestBlockLocator)
return msgGetBlockLocator.LowHash, msgGetBlockLocator.HighHash, nil
}
func (flow *handleRequestBlockLocatorFlow) sendBlockLocator(locator blockdag.BlockLocator) error {
msgBlockLocator := domainmessage.NewMsgBlockLocator(locator)
msgBlockLocator := appmessage.NewMsgBlockLocator(locator)
err := flow.outgoingRoute.Enqueue(msgBlockLocator)
if err != nil {
return err

View File

@@ -2,10 +2,10 @@ package ibd
import (
"errors"
"github.com/kaspanet/kaspad/blockdag"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter/router"
"github.com/kaspanet/kaspad/protocol/protocolerrors"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
"github.com/kaspanet/kaspad/domain/blockdag"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
"github.com/kaspanet/kaspad/util/daghash"
)
@@ -66,12 +66,12 @@ func (flow *handleRequestBlocksFlow) start() error {
return err
}
if _, ok := message.(*domainmessage.MsgRequestNextIBDBlocks); !ok {
if _, ok := message.(*appmessage.MsgRequestNextIBDBlocks); !ok {
return protocolerrors.Errorf(true, "received unexpected message type. "+
"expected: %s, got: %s", domainmessage.CmdRequestNextIBDBlocks, message.Command())
"expected: %s, got: %s", appmessage.CmdRequestNextIBDBlocks, message.Command())
}
}
err = flow.outgoingRoute.Enqueue(domainmessage.NewMsgDoneIBDBlocks())
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgDoneIBDBlocks())
if err != nil {
return err
}
@@ -85,15 +85,15 @@ func receiveRequestIBDBlocks(incomingRoute *router.Route) (lowHash *daghash.Hash
if err != nil {
return nil, nil, err
}
msgRequestIBDBlocks := message.(*domainmessage.MsgRequestIBDBlocks)
msgRequestIBDBlocks := message.(*appmessage.MsgRequestIBDBlocks)
return msgRequestIBDBlocks.LowHash, msgRequestIBDBlocks.HighHash, nil
}
func (flow *handleRequestBlocksFlow) buildMsgIBDBlocks(lowHash *daghash.Hash,
highHash *daghash.Hash) ([]*domainmessage.MsgIBDBlock, error) {
highHash *daghash.Hash) ([]*appmessage.MsgIBDBlock, error) {
const maxHashesInMsgIBDBlocks = domainmessage.MaxInvPerMsg
const maxHashesInMsgIBDBlocks = appmessage.MaxInvPerMsg
blockHashes, err := flow.DAG().AntiPastHashesBetween(lowHash, highHash, maxHashesInMsgIBDBlocks)
if err != nil {
if errors.Is(err, blockdag.ErrInvalidParameter) {
@@ -103,19 +103,19 @@ func (flow *handleRequestBlocksFlow) buildMsgIBDBlocks(lowHash *daghash.Hash,
return nil, err
}
msgIBDBlocks := make([]*domainmessage.MsgIBDBlock, len(blockHashes))
msgIBDBlocks := make([]*appmessage.MsgIBDBlock, len(blockHashes))
for i, blockHash := range blockHashes {
block, err := flow.DAG().BlockByHash(blockHash)
if err != nil {
return nil, err
}
msgIBDBlocks[i] = domainmessage.NewMsgIBDBlock(block.MsgBlock())
msgIBDBlocks[i] = appmessage.NewMsgIBDBlock(block.MsgBlock())
}
return msgIBDBlocks, nil
}
func (flow *handleRequestBlocksFlow) sendMsgIBDBlocks(msgIBDBlocks []*domainmessage.MsgIBDBlock) error {
func (flow *handleRequestBlocksFlow) sendMsgIBDBlocks(msgIBDBlocks []*appmessage.MsgIBDBlock) error {
for _, msgIBDBlock := range msgIBDBlocks {
err := flow.outgoingRoute.Enqueue(msgIBDBlock)
if err != nil {

View File

@@ -1,12 +1,12 @@
package ibd
import (
"github.com/kaspanet/kaspad/blockdag"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter/router"
"github.com/kaspanet/kaspad/protocol/common"
peerpkg "github.com/kaspanet/kaspad/protocol/peer"
"github.com/kaspanet/kaspad/protocol/protocolerrors"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/common"
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
"github.com/kaspanet/kaspad/domain/blockdag"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
"github.com/kaspanet/kaspad/util"
"github.com/kaspanet/kaspad/util/daghash"
)
@@ -96,7 +96,7 @@ func (flow *handleIBDFlow) findHighestSharedBlockHash(peerSelectedTipHash *dagha
func (flow *handleIBDFlow) sendGetBlockLocator(lowHash *daghash.Hash, highHash *daghash.Hash) error {
msgGetBlockLocator := domainmessage.NewMsgRequestBlockLocator(highHash, lowHash)
msgGetBlockLocator := appmessage.NewMsgRequestBlockLocator(highHash, lowHash)
return flow.outgoingRoute.Enqueue(msgGetBlockLocator)
}
@@ -105,11 +105,11 @@ func (flow *handleIBDFlow) receiveBlockLocator() (blockLocatorHashes []*daghash.
if err != nil {
return nil, err
}
msgBlockLocator, ok := message.(*domainmessage.MsgBlockLocator)
msgBlockLocator, ok := message.(*appmessage.MsgBlockLocator)
if !ok {
return nil,
protocolerrors.Errorf(true, "received unexpected message type. "+
"expected: %s, got: %s", domainmessage.CmdBlockLocator, message.Command())
"expected: %s, got: %s", appmessage.CmdBlockLocator, message.Command())
}
return msgBlockLocator.BlockLocatorHashes, nil
}
@@ -140,7 +140,7 @@ func (flow *handleIBDFlow) downloadBlocks(highestSharedBlockHash *daghash.Hash,
blocksReceived++
if blocksReceived%ibdBatchSize == 0 {
err = flow.outgoingRoute.Enqueue(domainmessage.NewMsgRequestNextIBDBlocks())
err = flow.outgoingRoute.Enqueue(appmessage.NewMsgRequestNextIBDBlocks())
if err != nil {
return err
}
@@ -151,28 +151,28 @@ func (flow *handleIBDFlow) downloadBlocks(highestSharedBlockHash *daghash.Hash,
func (flow *handleIBDFlow) sendGetBlocks(highestSharedBlockHash *daghash.Hash,
peerSelectedTipHash *daghash.Hash) error {
msgGetBlockInvs := domainmessage.NewMsgRequstIBDBlocks(highestSharedBlockHash, peerSelectedTipHash)
msgGetBlockInvs := appmessage.NewMsgRequstIBDBlocks(highestSharedBlockHash, peerSelectedTipHash)
return flow.outgoingRoute.Enqueue(msgGetBlockInvs)
}
func (flow *handleIBDFlow) receiveIBDBlock() (msgIBDBlock *domainmessage.MsgIBDBlock, doneIBD bool, err error) {
func (flow *handleIBDFlow) receiveIBDBlock() (msgIBDBlock *appmessage.MsgIBDBlock, doneIBD bool, err error) {
message, err := flow.incomingRoute.DequeueWithTimeout(common.DefaultTimeout)
if err != nil {
return nil, false, err
}
switch message := message.(type) {
case *domainmessage.MsgIBDBlock:
case *appmessage.MsgIBDBlock:
return message, false, nil
case *domainmessage.MsgDoneIBDBlocks:
case *appmessage.MsgDoneIBDBlocks:
return nil, true, nil
default:
return nil, false,
protocolerrors.Errorf(true, "received unexpected message type. "+
"expected: %s, got: %s", domainmessage.CmdIBDBlock, message.Command())
"expected: %s, got: %s", appmessage.CmdIBDBlock, message.Command())
}
}
func (flow *handleIBDFlow) processIBDBlock(msgIBDBlock *domainmessage.MsgIBDBlock) error {
func (flow *handleIBDFlow) processIBDBlock(msgIBDBlock *appmessage.MsgIBDBlock) error {
block := util.NewBlock(msgIBDBlock.MsgBlock)
if flow.DAG().IsInDAG(block.Hash()) {

View File

@@ -1,7 +1,7 @@
package ibd
import (
"github.com/kaspanet/kaspad/logger"
"github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/kaspanet/kaspad/util/panics"
)

View File

@@ -1,9 +1,9 @@
package selectedtip
import (
"github.com/kaspanet/kaspad/blockdag"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter/router"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/domain/blockdag"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
"github.com/pkg/errors"
)
@@ -46,16 +46,16 @@ func (flow *handleRequestSelectedTipFlow) receiveGetSelectedTip() error {
if err != nil {
return err
}
_, ok := message.(*domainmessage.MsgRequestSelectedTip)
_, ok := message.(*appmessage.MsgRequestSelectedTip)
if !ok {
return errors.Errorf("received unexpected message type. "+
"expected: %s, got: %s", domainmessage.CmdRequestSelectedTip, message.Command())
"expected: %s, got: %s", appmessage.CmdRequestSelectedTip, message.Command())
}
return nil
}
func (flow *handleRequestSelectedTipFlow) sendSelectedTipHash() error {
msgSelectedTip := domainmessage.NewMsgSelectedTip(flow.DAG().SelectedTipHash())
msgSelectedTip := appmessage.NewMsgSelectedTip(flow.DAG().SelectedTipHash())
return flow.outgoingRoute.Enqueue(msgSelectedTip)
}

View File

@@ -1,11 +1,11 @@
package selectedtip
import (
"github.com/kaspanet/kaspad/blockdag"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter/router"
"github.com/kaspanet/kaspad/protocol/common"
peerpkg "github.com/kaspanet/kaspad/protocol/peer"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/common"
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
"github.com/kaspanet/kaspad/domain/blockdag"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
"github.com/kaspanet/kaspad/util/daghash"
)
@@ -64,7 +64,7 @@ func (flow *requestSelectedTipFlow) runSelectedTipRequest() error {
}
func (flow *requestSelectedTipFlow) requestSelectedTip() error {
msgGetSelectedTip := domainmessage.NewMsgRequestSelectedTip()
msgGetSelectedTip := appmessage.NewMsgRequestSelectedTip()
return flow.outgoingRoute.Enqueue(msgGetSelectedTip)
}
@@ -73,7 +73,7 @@ func (flow *requestSelectedTipFlow) receiveSelectedTip() (selectedTipHash *dagha
if err != nil {
return nil, err
}
msgSelectedTip := message.(*domainmessage.MsgSelectedTip)
msgSelectedTip := message.(*appmessage.MsgSelectedTip)
return msgSelectedTip.SelectedTipHash, nil
}

View File

@@ -1,8 +1,8 @@
package ping
import (
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter/router"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
)
// ReceivePingsContext is the interface for the context needed for the ReceivePings flow.
@@ -31,9 +31,9 @@ func (flow *receivePingsFlow) start() error {
if err != nil {
return err
}
pingMessage := message.(*domainmessage.MsgPing)
pingMessage := message.(*appmessage.MsgPing)
pongMessage := domainmessage.NewMsgPong(pingMessage.Nonce)
pongMessage := appmessage.NewMsgPong(pingMessage.Nonce)
err = flow.outgoingRoute.Enqueue(pongMessage)
if err != nil {
return err

View File

@@ -3,11 +3,11 @@ package ping
import (
"time"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter/router"
"github.com/kaspanet/kaspad/protocol/common"
peerpkg "github.com/kaspanet/kaspad/protocol/peer"
"github.com/kaspanet/kaspad/protocol/protocolerrors"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/common"
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
"github.com/kaspanet/kaspad/util/random"
)
@@ -46,7 +46,7 @@ func (flow *sendPingsFlow) start() error {
}
flow.peer.SetPingPending(nonce)
pingMessage := domainmessage.NewMsgPing(nonce)
pingMessage := appmessage.NewMsgPing(nonce)
err = flow.outgoingRoute.Enqueue(pingMessage)
if err != nil {
return err
@@ -56,7 +56,7 @@ func (flow *sendPingsFlow) start() error {
if err != nil {
return err
}
pongMessage := message.(*domainmessage.MsgPong)
pongMessage := message.(*appmessage.MsgPong)
if pongMessage.Nonce != pingMessage.Nonce {
return protocolerrors.New(true, "nonce mismatch between ping and pong")
}

View File

@@ -0,0 +1,42 @@
package rejects
import (
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
)
// HandleRejectsContext is the interface for the context needed for the HandleRejects flow.
type HandleRejectsContext interface {
}
type handleRejectsFlow struct {
HandleRejectsContext
incomingRoute, outgoingRoute *router.Route
}
// HandleRejects handles all reject messages coming through incomingRoute.
// This function assumes that incomingRoute will only return MsgReject.
func HandleRejects(context HandleRejectsContext, incomingRoute *router.Route, outgoingRoute *router.Route) error {
flow := &handleRejectsFlow{
HandleRejectsContext: context,
incomingRoute: incomingRoute,
outgoingRoute: outgoingRoute,
}
return flow.start()
}
func (flow *handleRejectsFlow) start() error {
message, err := flow.incomingRoute.Dequeue()
if err != nil {
return err
}
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)
}

View File

@@ -1,13 +1,13 @@
package relaytransactions
import (
"github.com/kaspanet/kaspad/blockdag"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/mempool"
"github.com/kaspanet/kaspad/netadapter"
"github.com/kaspanet/kaspad/netadapter/router"
"github.com/kaspanet/kaspad/protocol/common"
"github.com/kaspanet/kaspad/protocol/protocolerrors"
"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/blockdag"
"github.com/kaspanet/kaspad/domain/mempool"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
"github.com/kaspanet/kaspad/util"
"github.com/kaspanet/kaspad/util/daghash"
"github.com/pkg/errors"
@@ -20,23 +20,23 @@ type TransactionsRelayContext interface {
DAG() *blockdag.BlockDAG
SharedRequestedTransactions() *SharedRequestedTransactions
TxPool() *mempool.TxPool
Broadcast(message domainmessage.Message) error
Broadcast(message appmessage.Message) error
}
type handleRelayedTransactionsFlow struct {
TransactionsRelayContext
incomingRoute, outgoingRoute *router.Route
invsQueue []*domainmessage.MsgInvTransaction
invsQueue []*appmessage.MsgInvTransaction
}
// HandleRelayedTransactions listens to domainmessage.MsgInvTransaction messages, requests their corresponding transactions if they
// HandleRelayedTransactions listens to appmessage.MsgInvTransaction messages, requests their corresponding transactions if they
// are missing, adds them to the mempool and propagates them to the rest of the network.
func HandleRelayedTransactions(context TransactionsRelayContext, incomingRoute *router.Route, outgoingRoute *router.Route) error {
flow := &handleRelayedTransactionsFlow{
TransactionsRelayContext: context,
incomingRoute: incomingRoute,
outgoingRoute: outgoingRoute,
invsQueue: make([]*domainmessage.MsgInvTransaction, 0),
invsQueue: make([]*appmessage.MsgInvTransaction, 0),
}
return flow.start()
}
@@ -61,7 +61,7 @@ func (flow *handleRelayedTransactionsFlow) start() error {
}
func (flow *handleRelayedTransactionsFlow) requestInvTransactions(
inv *domainmessage.MsgInvTransaction) (requestedIDs []*daghash.TxID, err error) {
inv *appmessage.MsgInvTransaction) (requestedIDs []*daghash.TxID, err error) {
idsToRequest := make([]*daghash.TxID, 0, len(inv.TxIDs))
for _, txID := range inv.TxIDs {
@@ -79,7 +79,7 @@ func (flow *handleRelayedTransactionsFlow) requestInvTransactions(
return idsToRequest, nil
}
msgGetTransactions := domainmessage.NewMsgRequestTransactions(idsToRequest)
msgGetTransactions := appmessage.NewMsgRequestTransactions(idsToRequest)
err = flow.outgoingRoute.Enqueue(msgGetTransactions)
if err != nil {
flow.SharedRequestedTransactions().removeMany(idsToRequest)
@@ -103,7 +103,7 @@ func (flow *handleRelayedTransactionsFlow) isKnownTransaction(txID *daghash.TxID
// checked because the vast majority of transactions consist of
// two outputs where one is some form of "pay-to-somebody-else"
// and the other is a change output.
prevOut := domainmessage.Outpoint{TxID: *txID}
prevOut := appmessage.Outpoint{TxID: *txID}
for i := uint32(0); i < 2; i++ {
prevOut.Index = i
_, ok := flow.DAG().GetUTXOEntry(prevOut)
@@ -114,9 +114,9 @@ func (flow *handleRelayedTransactionsFlow) isKnownTransaction(txID *daghash.TxID
return false
}
func (flow *handleRelayedTransactionsFlow) readInv() (*domainmessage.MsgInvTransaction, error) {
func (flow *handleRelayedTransactionsFlow) readInv() (*appmessage.MsgInvTransaction, error) {
if len(flow.invsQueue) > 0 {
var inv *domainmessage.MsgInvTransaction
var inv *appmessage.MsgInvTransaction
inv, flow.invsQueue = flow.invsQueue[0], flow.invsQueue[1:]
return inv, nil
}
@@ -126,7 +126,7 @@ func (flow *handleRelayedTransactionsFlow) readInv() (*domainmessage.MsgInvTrans
return nil, err
}
inv, ok := msg.(*domainmessage.MsgInvTransaction)
inv, ok := msg.(*appmessage.MsgInvTransaction)
if !ok {
return nil, protocolerrors.Errorf(true, "unexpected %s message in the block relay flow while "+
"expecting an inv message", msg.Command())
@@ -135,13 +135,11 @@ func (flow *handleRelayedTransactionsFlow) readInv() (*domainmessage.MsgInvTrans
}
func (flow *handleRelayedTransactionsFlow) broadcastAcceptedTransactions(acceptedTxs []*mempool.TxDesc) error {
// TODO(libp2p) Add mechanism to avoid sending to other peers invs that are known to them (e.g. mruinvmap)
// TODO(libp2p) Consider broadcasting in bulks
idsToBroadcast := make([]*daghash.TxID, len(acceptedTxs))
for i, tx := range acceptedTxs {
idsToBroadcast[i] = tx.Tx.ID()
}
inv := domainmessage.NewMsgInvTransaction(idsToBroadcast)
inv := appmessage.NewMsgInvTransaction(idsToBroadcast)
return flow.Broadcast(inv)
}
@@ -150,7 +148,7 @@ func (flow *handleRelayedTransactionsFlow) broadcastAcceptedTransactions(accepte
//
// and populates invsQueue with any inv messages that meanwhile arrive.
func (flow *handleRelayedTransactionsFlow) readMsgTxOrNotFound() (
msgTx *domainmessage.MsgTx, msgNotFound *domainmessage.MsgTransactionNotFound, err error) {
msgTx *appmessage.MsgTx, msgNotFound *appmessage.MsgTransactionNotFound, err error) {
for {
message, err := flow.incomingRoute.DequeueWithTimeout(common.DefaultTimeout)
@@ -159,11 +157,11 @@ func (flow *handleRelayedTransactionsFlow) readMsgTxOrNotFound() (
}
switch message := message.(type) {
case *domainmessage.MsgInvTransaction:
case *appmessage.MsgInvTransaction:
flow.invsQueue = append(flow.invsQueue, message)
case *domainmessage.MsgTx:
case *appmessage.MsgTx:
return message, nil, nil
case *domainmessage.MsgTransactionNotFound:
case *appmessage.MsgTransactionNotFound:
return nil, message, nil
default:
return nil, nil, errors.Errorf("unexpected message %s", message.Command())
@@ -194,7 +192,7 @@ func (flow *handleRelayedTransactionsFlow) receiveTransactions(requestedTransact
expectedID, tx.ID())
}
acceptedTxs, err := flow.TxPool().ProcessTransaction(tx, true, 0) // TODO(libp2p) Use the peer ID for the mempool tag
acceptedTxs, err := flow.TxPool().ProcessTransaction(tx, true)
if err != nil {
ruleErr := &mempool.RuleError{}
if !errors.As(err, ruleErr) {
@@ -220,7 +218,6 @@ func (flow *handleRelayedTransactionsFlow) receiveTransactions(requestedTransact
if err != nil {
return err
}
// TODO(libp2p) Notify transactionsAcceptedToMempool to RPC
}
return nil
}

View File

@@ -1,8 +1,8 @@
package relaytransactions
import (
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter/router"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
)
type handleRequestedTransactionsFlow struct {
@@ -10,7 +10,7 @@ type handleRequestedTransactionsFlow struct {
incomingRoute, outgoingRoute *router.Route
}
// HandleRequestedTransactions listens to domainmessage.MsgRequestTransactions messages, responding with the requested
// HandleRequestedTransactions listens to appmessage.MsgRequestTransactions messages, responding with the requested
// transactions if those are in the mempool.
// Missing transactions would be ignored
func HandleRequestedTransactions(context TransactionsRelayContext, incomingRoute *router.Route, outgoingRoute *router.Route) error {
@@ -33,7 +33,7 @@ func (flow *handleRequestedTransactionsFlow) start() error {
tx, ok := flow.TxPool().FetchTransaction(transactionID)
if !ok {
msgTransactionNotFound := domainmessage.NewMsgTransactionNotFound(transactionID)
msgTransactionNotFound := appmessage.NewMsgTransactionNotFound(transactionID)
err := flow.outgoingRoute.Enqueue(msgTransactionNotFound)
if err != nil {
return err
@@ -49,11 +49,11 @@ func (flow *handleRequestedTransactionsFlow) start() error {
}
}
func (flow *handleRequestedTransactionsFlow) readRequestTransactions() (*domainmessage.MsgRequestTransactions, error) {
func (flow *handleRequestedTransactionsFlow) readRequestTransactions() (*appmessage.MsgRequestTransactions, error) {
msg, err := flow.incomingRoute.Dequeue()
if err != nil {
return nil, err
}
return msg.(*domainmessage.MsgRequestTransactions), nil
return msg.(*appmessage.MsgRequestTransactions), nil
}

View File

@@ -1,7 +1,7 @@
package protocol
import (
"github.com/kaspanet/kaspad/logger"
"github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/kaspanet/kaspad/util/panics"
)

View File

@@ -3,14 +3,14 @@ package protocol
import (
"fmt"
"github.com/kaspanet/kaspad/addressmanager"
"github.com/kaspanet/kaspad/blockdag"
"github.com/kaspanet/kaspad/config"
"github.com/kaspanet/kaspad/connmanager"
"github.com/kaspanet/kaspad/mempool"
"github.com/kaspanet/kaspad/netadapter"
"github.com/kaspanet/kaspad/protocol/flowcontext"
peerpkg "github.com/kaspanet/kaspad/protocol/peer"
"github.com/kaspanet/kaspad/app/protocol/flowcontext"
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
"github.com/kaspanet/kaspad/domain/blockdag"
"github.com/kaspanet/kaspad/domain/mempool"
"github.com/kaspanet/kaspad/infrastructure/config"
"github.com/kaspanet/kaspad/infrastructure/network/addressmanager"
"github.com/kaspanet/kaspad/infrastructure/network/connmanager"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter"
"github.com/kaspanet/kaspad/util"
)

View File

@@ -1,7 +1,7 @@
package peer
import (
"github.com/kaspanet/kaspad/logger"
"github.com/kaspanet/kaspad/infrastructure/logger"
"github.com/kaspanet/kaspad/util/panics"
)

View File

@@ -1,13 +1,13 @@
package peer
import (
"github.com/kaspanet/kaspad/netadapter"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter"
"sync"
"sync/atomic"
"time"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter/id"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/id"
"github.com/kaspanet/kaspad/util/daghash"
mathUtil "github.com/kaspanet/kaspad/util/math"
"github.com/kaspanet/kaspad/util/mstime"
@@ -22,7 +22,7 @@ type Peer struct {
selectedTipHash *daghash.Hash
userAgent string
services domainmessage.ServiceFlag
services appmessage.ServiceFlag
advertisedProtocolVerion uint32 // protocol version advertised by remote
protocolVersion uint32 // negotiated protocol version
disableRelayTx bool
@@ -109,7 +109,7 @@ func (p *Peer) IsOutbound() bool {
}
// UpdateFieldsFromMsgVersion updates the peer with the data from the version message.
func (p *Peer) UpdateFieldsFromMsgVersion(msg *domainmessage.MsgVersion) {
func (p *Peer) UpdateFieldsFromMsgVersion(msg *appmessage.MsgVersion) {
// Negotiate the protocol version.
p.advertisedProtocolVerion = msg.ProtocolVersion
p.protocolVersion = mathUtil.MinUint32(p.protocolVersion, p.advertisedProtocolVerion)

View File

@@ -1,21 +1,22 @@
package protocol
import (
"github.com/kaspanet/kaspad/app/protocol/flows/rejects"
"sync/atomic"
"github.com/kaspanet/kaspad/addressmanager"
"github.com/kaspanet/kaspad/domainmessage"
"github.com/kaspanet/kaspad/netadapter"
routerpkg "github.com/kaspanet/kaspad/netadapter/router"
"github.com/kaspanet/kaspad/protocol/flows/addressexchange"
"github.com/kaspanet/kaspad/protocol/flows/blockrelay"
"github.com/kaspanet/kaspad/protocol/flows/handshake"
"github.com/kaspanet/kaspad/protocol/flows/ibd"
"github.com/kaspanet/kaspad/protocol/flows/ibd/selectedtip"
"github.com/kaspanet/kaspad/protocol/flows/ping"
"github.com/kaspanet/kaspad/protocol/flows/relaytransactions"
peerpkg "github.com/kaspanet/kaspad/protocol/peer"
"github.com/kaspanet/kaspad/protocol/protocolerrors"
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/protocol/flows/addressexchange"
"github.com/kaspanet/kaspad/app/protocol/flows/blockrelay"
"github.com/kaspanet/kaspad/app/protocol/flows/handshake"
"github.com/kaspanet/kaspad/app/protocol/flows/ibd"
"github.com/kaspanet/kaspad/app/protocol/flows/ibd/selectedtip"
"github.com/kaspanet/kaspad/app/protocol/flows/ping"
"github.com/kaspanet/kaspad/app/protocol/flows/relaytransactions"
peerpkg "github.com/kaspanet/kaspad/app/protocol/peer"
"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
"github.com/kaspanet/kaspad/infrastructure/network/addressmanager"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter"
routerpkg "github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
"github.com/pkg/errors"
)
@@ -49,37 +50,50 @@ func (m *Manager) routerInitializer(router *routerpkg.Router, netConnection *net
return
}
netConnection.SetOnInvalidMessageHandler(func(err error) {
if atomic.AddUint32(&isStopping, 1) == 1 {
errChan <- protocolerrors.Wrap(true, err, "received bad message")
spawn("Manager.routerInitializer-netConnection.DequeueInvalidMessage", func() {
for {
isOpen, err := netConnection.DequeueInvalidMessage()
if !isOpen {
return
}
if atomic.AddUint32(&isStopping, 1) == 1 {
errChan <- protocolerrors.Wrap(true, err, "received bad message")
}
}
})
peer, err := handshake.HandleHandshake(m.context, netConnection, receiveVersionRoute,
sendVersionRoute, router.OutgoingRoute())
if err != nil {
m.handleError(err, netConnection)
m.handleError(err, netConnection, router.OutgoingRoute())
return
}
defer m.context.RemoveFromPeers(peer)
removeHandshakeRoutes(router)
err = m.runFlows(flows, peer, errChan)
if err != nil {
m.handleError(err, netConnection)
m.handleError(err, netConnection, router.OutgoingRoute())
return
}
})
}
func (m *Manager) handleError(err error, netConnection *netadapter.NetConnection) {
func (m *Manager) handleError(err error, netConnection *netadapter.NetConnection, outgoingRoute *routerpkg.Route) {
if protocolErr := &(protocolerrors.ProtocolError{}); errors.As(err, &protocolErr) {
if !m.context.Config().DisableBanning && protocolErr.ShouldBan {
log.Warnf("Banning %s (reason: %s)", netConnection, protocolErr.Cause)
err := m.context.ConnectionManager().Ban(netConnection)
if err != nil && !errors.Is(err, addressmanager.ErrAddressNotFound) {
panic(err)
}
err = outgoingRoute.Enqueue(appmessage.NewMsgReject(protocolErr.Error()))
if err != nil && !errors.Is(err, routerpkg.ErrRouteClosed) {
panic(err)
}
}
netConnection.Disconnect()
return
@@ -101,6 +115,7 @@ func (m *Manager) registerFlows(router *routerpkg.Router, errChan chan error, is
flows = append(flows, m.registerPingFlows(router, isStopping, errChan)...)
flows = append(flows, m.registerIBDFlows(router, isStopping, errChan)...)
flows = append(flows, m.registerTransactionRelayFlow(router, isStopping, errChan)...)
flows = append(flows, m.registerRejectsFlow(router, isStopping, errChan)...)
return flows
}
@@ -109,13 +124,13 @@ func (m *Manager) registerAddressFlows(router *routerpkg.Router, isStopping *uin
outgoingRoute := router.OutgoingRoute()
return []*flow{
m.registerOneTimeFlow("SendAddresses", router, []domainmessage.MessageCommand{domainmessage.CmdRequestAddresses}, isStopping, errChan,
m.registerOneTimeFlow("SendAddresses", router, []appmessage.MessageCommand{appmessage.CmdRequestAddresses}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return addressexchange.SendAddresses(m.context, incomingRoute, outgoingRoute)
},
),
m.registerOneTimeFlow("ReceiveAddresses", router, []domainmessage.MessageCommand{domainmessage.CmdAddresses}, isStopping, errChan,
m.registerOneTimeFlow("ReceiveAddresses", router, []appmessage.MessageCommand{appmessage.CmdAddresses}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return addressexchange.ReceiveAddresses(m.context, incomingRoute, outgoingRoute, peer)
},
@@ -127,14 +142,14 @@ func (m *Manager) registerBlockRelayFlows(router *routerpkg.Router, isStopping *
outgoingRoute := router.OutgoingRoute()
return []*flow{
m.registerFlow("HandleRelayInvs", router, []domainmessage.MessageCommand{domainmessage.CmdInvRelayBlock, domainmessage.CmdBlock}, isStopping, errChan,
m.registerFlow("HandleRelayInvs", router, []appmessage.MessageCommand{appmessage.CmdInvRelayBlock, appmessage.CmdBlock}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return blockrelay.HandleRelayInvs(m.context, incomingRoute,
outgoingRoute, peer)
},
),
m.registerFlow("HandleRelayBlockRequests", router, []domainmessage.MessageCommand{domainmessage.CmdRequestRelayBlocks}, isStopping, errChan,
m.registerFlow("HandleRelayBlockRequests", router, []appmessage.MessageCommand{appmessage.CmdRequestRelayBlocks}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return blockrelay.HandleRelayBlockRequests(m.context, incomingRoute, outgoingRoute, peer)
},
@@ -146,13 +161,13 @@ func (m *Manager) registerPingFlows(router *routerpkg.Router, isStopping *uint32
outgoingRoute := router.OutgoingRoute()
return []*flow{
m.registerFlow("ReceivePings", router, []domainmessage.MessageCommand{domainmessage.CmdPing}, isStopping, errChan,
m.registerFlow("ReceivePings", router, []appmessage.MessageCommand{appmessage.CmdPing}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return ping.ReceivePings(m.context, incomingRoute, outgoingRoute)
},
),
m.registerFlow("SendPings", router, []domainmessage.MessageCommand{domainmessage.CmdPong}, isStopping, errChan,
m.registerFlow("SendPings", router, []appmessage.MessageCommand{appmessage.CmdPong}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return ping.SendPings(m.context, incomingRoute, outgoingRoute, peer)
},
@@ -164,32 +179,32 @@ func (m *Manager) registerIBDFlows(router *routerpkg.Router, isStopping *uint32,
outgoingRoute := router.OutgoingRoute()
return []*flow{
m.registerFlow("HandleIBD", router, []domainmessage.MessageCommand{domainmessage.CmdBlockLocator, domainmessage.CmdIBDBlock,
domainmessage.CmdDoneIBDBlocks}, isStopping, errChan,
m.registerFlow("HandleIBD", router, []appmessage.MessageCommand{appmessage.CmdBlockLocator, appmessage.CmdIBDBlock,
appmessage.CmdDoneIBDBlocks}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return ibd.HandleIBD(m.context, incomingRoute, outgoingRoute, peer)
},
),
m.registerFlow("RequestSelectedTip", router, []domainmessage.MessageCommand{domainmessage.CmdSelectedTip}, isStopping, errChan,
m.registerFlow("RequestSelectedTip", router, []appmessage.MessageCommand{appmessage.CmdSelectedTip}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return selectedtip.RequestSelectedTip(m.context, incomingRoute, outgoingRoute, peer)
},
),
m.registerFlow("HandleRequestSelectedTip", router, []domainmessage.MessageCommand{domainmessage.CmdRequestSelectedTip}, isStopping, errChan,
m.registerFlow("HandleRequestSelectedTip", router, []appmessage.MessageCommand{appmessage.CmdRequestSelectedTip}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return selectedtip.HandleRequestSelectedTip(m.context, incomingRoute, outgoingRoute)
},
),
m.registerFlow("HandleRequestBlockLocator", router, []domainmessage.MessageCommand{domainmessage.CmdRequestBlockLocator}, isStopping, errChan,
m.registerFlow("HandleRequestBlockLocator", router, []appmessage.MessageCommand{appmessage.CmdRequestBlockLocator}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return ibd.HandleRequestBlockLocator(m.context, incomingRoute, outgoingRoute)
},
),
m.registerFlow("HandleRequestIBDBlocks", router, []domainmessage.MessageCommand{domainmessage.CmdRequestIBDBlocks, domainmessage.CmdRequestNextIBDBlocks}, isStopping, errChan,
m.registerFlow("HandleRequestIBDBlocks", router, []appmessage.MessageCommand{appmessage.CmdRequestIBDBlocks, appmessage.CmdRequestNextIBDBlocks}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return ibd.HandleRequestIBDBlocks(m.context, incomingRoute, outgoingRoute)
},
@@ -202,13 +217,13 @@ func (m *Manager) registerTransactionRelayFlow(router *routerpkg.Router, isStopp
return []*flow{
m.registerFlow("HandleRelayedTransactions", router,
[]domainmessage.MessageCommand{domainmessage.CmdInvTransaction, domainmessage.CmdTx, domainmessage.CmdTransactionNotFound}, isStopping, errChan,
[]appmessage.MessageCommand{appmessage.CmdInvTransaction, appmessage.CmdTx, appmessage.CmdTransactionNotFound}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return relaytransactions.HandleRelayedTransactions(m.context, incomingRoute, outgoingRoute)
},
),
m.registerFlow("HandleRequestTransactions", router,
[]domainmessage.MessageCommand{domainmessage.CmdRequestTransactions}, isStopping, errChan,
[]appmessage.MessageCommand{appmessage.CmdRequestTransactions}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return relaytransactions.HandleRequestedTransactions(m.context, incomingRoute, outgoingRoute)
},
@@ -216,7 +231,20 @@ func (m *Manager) registerTransactionRelayFlow(router *routerpkg.Router, isStopp
}
}
func (m *Manager) registerFlow(name string, router *routerpkg.Router, messageTypes []domainmessage.MessageCommand, isStopping *uint32,
func (m *Manager) registerRejectsFlow(router *routerpkg.Router, isStopping *uint32, errChan chan error) []*flow {
outgoingRoute := router.OutgoingRoute()
return []*flow{
m.registerFlow("HandleRejects", router,
[]appmessage.MessageCommand{appmessage.CmdReject}, isStopping, errChan,
func(incomingRoute *routerpkg.Route, peer *peerpkg.Peer) error {
return rejects.HandleRejects(m.context, incomingRoute, outgoingRoute)
},
),
}
}
func (m *Manager) registerFlow(name string, router *routerpkg.Router, messageTypes []appmessage.MessageCommand, isStopping *uint32,
errChan chan error, initializeFunc flowInitializeFunc) *flow {
route, err := router.AddIncomingRoute(messageTypes)
@@ -236,7 +264,7 @@ func (m *Manager) registerFlow(name string, router *routerpkg.Router, messageTyp
}
}
func (m *Manager) registerOneTimeFlow(name string, router *routerpkg.Router, messageTypes []domainmessage.MessageCommand,
func (m *Manager) registerOneTimeFlow(name string, router *routerpkg.Router, messageTypes []appmessage.MessageCommand,
isStopping *uint32, stopChan chan error, initializeFunc flowInitializeFunc) *flow {
route, err := router.AddIncomingRoute(messageTypes)
@@ -265,12 +293,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([]domainmessage.MessageCommand{domainmessage.CmdVersion})
receiveVersionRoute, err := router.AddIncomingRoute([]appmessage.MessageCommand{appmessage.CmdVersion})
if err != nil {
panic(err)
}
sendVersionRoute, err = router.AddIncomingRoute([]domainmessage.MessageCommand{domainmessage.CmdVerAck})
sendVersionRoute, err = router.AddIncomingRoute([]appmessage.MessageCommand{appmessage.CmdVerAck})
if err != nil {
panic(err)
}
@@ -279,7 +307,7 @@ func registerHandshakeRoutes(router *routerpkg.Router) (
}
func removeHandshakeRoutes(router *routerpkg.Router) {
err := router.RemoveRoute([]domainmessage.MessageCommand{domainmessage.CmdVersion, domainmessage.CmdVerAck})
err := router.RemoveRoute([]appmessage.MessageCommand{appmessage.CmdVersion, appmessage.CmdVerAck})
if err != nil {
panic(err)
}

View File

@@ -18,8 +18,7 @@ func (e *ProtocolError) Unwrap() error {
}
// Errorf formats according to a format specifier and returns the string
// as a value that satisfies error.
// Errorf also records the stack trace at the point it was called.
// as a ProtocolError.
func Errorf(shouldBan bool, format string, args ...interface{}) error {
return &ProtocolError{
ShouldBan: shouldBan,
@@ -27,7 +26,7 @@ func Errorf(shouldBan bool, format string, args ...interface{}) error {
}
}
// New returns an error with the supplied message.
// New returns a ProtocolError with the supplied message.
// New also records the stack trace at the point it was called.
func New(shouldBan bool, message string) error {
return &ProtocolError{
@@ -36,8 +35,7 @@ func New(shouldBan bool, message string) error {
}
}
// Wrap returns an error annotating err with a stack trace
// at the point Wrap is called, and the supplied message.
// Wrap wraps the given error and returns it as a ProtocolError.
func Wrap(shouldBan bool, err error, message string) error {
return &ProtocolError{
ShouldBan: shouldBan,
@@ -45,8 +43,7 @@ func Wrap(shouldBan bool, err error, message string) error {
}
}
// Wrapf returns an error annotating err with a stack trace
// at the point Wrapf is called, and the format specifier.
// Wrapf wraps the given error with the given format and returns it as a ProtocolError.
func Wrapf(shouldBan bool, err error, format string, args ...interface{}) error {
return &ProtocolError{
ShouldBan: shouldBan,

View File

@@ -1,154 +0,0 @@
// Copyright (c) 2013-2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package blockdag
import (
"fmt"
"github.com/kaspanet/kaspad/dbaccess"
"github.com/kaspanet/kaspad/util"
"github.com/pkg/errors"
)
func (dag *BlockDAG) addNodeToIndexWithInvalidAncestor(block *util.Block) error {
blockHeader := &block.MsgBlock().Header
newNode, _ := dag.newBlockNode(blockHeader, newBlockSet())
newNode.status = statusInvalidAncestor
dag.index.AddNode(newNode)
dbTx, err := dag.databaseContext.NewTx()
if err != nil {
return err
}
defer dbTx.RollbackUnlessClosed()
err = dag.index.flushToDB(dbTx)
if err != nil {
return err
}
return dbTx.Commit()
}
// maybeAcceptBlock potentially accepts a block into the block DAG. It
// performs several validation checks which depend on its position within
// the block DAG before adding it. The block is expected to have already
// gone through ProcessBlock before calling this function with it.
//
// The flags are also passed to checkBlockContext and connectToDAG. See
// their documentation for how the flags modify their behavior.
//
// This function MUST be called with the dagLock held (for writes).
func (dag *BlockDAG) maybeAcceptBlock(block *util.Block, flags BehaviorFlags) error {
parents, err := lookupParentNodes(block, dag)
if err != nil {
var ruleErr RuleError
if ok := errors.As(err, &ruleErr); ok && ruleErr.ErrorCode == ErrInvalidAncestorBlock {
err := dag.addNodeToIndexWithInvalidAncestor(block)
if err != nil {
return err
}
}
return err
}
// The block must pass all of the validation rules which depend on the
// position of the block within the block DAG.
err = dag.checkBlockContext(block, parents, flags)
if err != nil {
return err
}
// Create a new block node for the block and add it to the node index.
newNode, selectedParentAnticone := dag.newBlockNode(&block.MsgBlock().Header, parents)
newNode.status = statusDataStored
dag.index.AddNode(newNode)
// Insert the block into the database if it's not already there. Even
// though it is possible the block will ultimately fail to connect, it
// has already passed all proof-of-work and validity tests which means
// it would be prohibitively expensive for an attacker to fill up the
// disk with a bunch of blocks that fail to connect. This is necessary
// since it allows block download to be decoupled from the much more
// expensive connection logic. It also has some other nice properties
// such as making blocks that never become part of the DAG or
// blocks that fail to connect available for further analysis.
dbTx, err := dag.databaseContext.NewTx()
if err != nil {
return err
}
defer dbTx.RollbackUnlessClosed()
blockExists, err := dbaccess.HasBlock(dbTx, block.Hash())
if err != nil {
return err
}
if !blockExists {
err := storeBlock(dbTx, block)
if err != nil {
return err
}
}
err = dag.index.flushToDB(dbTx)
if err != nil {
return err
}
err = dbTx.Commit()
if err != nil {
return err
}
// Make sure that all the block's transactions are finalized
fastAdd := flags&BFFastAdd == BFFastAdd
bluestParent := parents.bluest()
if !fastAdd {
if err := dag.validateAllTxsFinalized(block, newNode, bluestParent); err != nil {
return err
}
}
// Connect the passed block to the DAG. This also handles validation of the
// transaction scripts.
chainUpdates, err := dag.addBlock(newNode, block, selectedParentAnticone, flags)
if err != nil {
return err
}
// Notify the caller that the new block was accepted into the block
// DAG. The caller would typically want to react by relaying the
// inventory to other peers.
dag.dagLock.Unlock()
dag.sendNotification(NTBlockAdded, &BlockAddedNotificationData{
Block: block,
WasUnorphaned: flags&BFWasUnorphaned != 0,
})
if len(chainUpdates.addedChainBlockHashes) > 0 {
dag.sendNotification(NTChainChanged, &ChainChangedNotificationData{
RemovedChainBlockHashes: chainUpdates.removedChainBlockHashes,
AddedChainBlockHashes: chainUpdates.addedChainBlockHashes,
})
}
dag.dagLock.Lock()
return nil
}
func lookupParentNodes(block *util.Block, dag *BlockDAG) (blockSet, error) {
header := block.MsgBlock().Header
parentHashes := header.ParentHashes
nodes := newBlockSet()
for _, parentHash := range parentHashes {
node, ok := dag.index.LookupNode(parentHash)
if !ok {
str := fmt.Sprintf("parent block %s is unknown", parentHash)
return nil, ruleError(ErrParentBlockUnknown, str)
} else if dag.index.NodeStatus(node).KnownInvalid() {
str := fmt.Sprintf("parent block %s is known to be invalid", parentHash)
return nil, ruleError(ErrInvalidAncestorBlock, str)
}
nodes.add(node)
}
return nodes, nil
}

View File

@@ -1,107 +0,0 @@
package blockdag
import (
"errors"
"path/filepath"
"testing"
"github.com/kaspanet/kaspad/dagconfig"
)
func TestMaybeAcceptBlockErrors(t *testing.T) {
// Create a new database and DAG instance to run tests against.
dag, teardownFunc, err := DAGSetup("TestMaybeAcceptBlockErrors", true, Config{
DAGParams: &dagconfig.SimnetParams,
})
if err != nil {
t.Fatalf("TestMaybeAcceptBlockErrors: Failed to setup DAG instance: %v", err)
}
defer teardownFunc()
dag.TestSetCoinbaseMaturity(0)
// Test rejecting the block if its parents are missing
orphanBlockFile := "blk_3B.dat"
loadedBlocks, err := LoadBlocks(filepath.Join("testdata/", orphanBlockFile))
if err != nil {
t.Fatalf("TestMaybeAcceptBlockErrors: "+
"Error loading file '%s': %s\n", orphanBlockFile, err)
}
block := loadedBlocks[0]
err = dag.maybeAcceptBlock(block, BFNone)
if err == nil {
t.Errorf("TestMaybeAcceptBlockErrors: rejecting the block if its parents are missing: "+
"Expected: %s, got: <nil>", ErrParentBlockUnknown)
}
var ruleErr RuleError
if ok := errors.As(err, &ruleErr); !ok {
t.Errorf("TestMaybeAcceptBlockErrors: rejecting the block if its parents are missing: "+
"Expected RuleError but got %s", err)
} else if ruleErr.ErrorCode != ErrParentBlockUnknown {
t.Errorf("TestMaybeAcceptBlockErrors: rejecting the block if its parents are missing: "+
"Unexpected error code. Want: %s, got: %s", ErrParentBlockUnknown, ruleErr.ErrorCode)
}
// Test rejecting the block if its parents are invalid
blocksFile := "blk_0_to_4.dat"
blocks, err := LoadBlocks(filepath.Join("testdata/", blocksFile))
if err != nil {
t.Fatalf("TestMaybeAcceptBlockErrors: "+
"Error loading file '%s': %s\n", blocksFile, err)
}
// Add a valid block and mark it as invalid
block1 := blocks[1]
isOrphan, isDelayed, err := dag.ProcessBlock(block1, BFNone)
if err != nil {
t.Fatalf("TestMaybeAcceptBlockErrors: Valid block unexpectedly returned an error: %s", err)
}
if isDelayed {
t.Fatalf("TestMaybeAcceptBlockErrors: block 1 is too far in the future")
}
if isOrphan {
t.Fatalf("TestMaybeAcceptBlockErrors: incorrectly returned block 1 is an orphan")
}
blockNode1, ok := dag.index.LookupNode(block1.Hash())
if !ok {
t.Fatalf("block %s does not exist in the DAG", block1.Hash())
}
dag.index.SetStatusFlags(blockNode1, statusValidateFailed)
block2 := blocks[2]
err = dag.maybeAcceptBlock(block2, BFNone)
if err == nil {
t.Errorf("TestMaybeAcceptBlockErrors: rejecting the block if its parents are invalid: "+
"Expected: %s, got: <nil>", ErrInvalidAncestorBlock)
}
if ok := errors.As(err, &ruleErr); !ok {
t.Errorf("TestMaybeAcceptBlockErrors: rejecting the block if its parents are invalid: "+
"Expected RuleError but got %s", err)
} else if ruleErr.ErrorCode != ErrInvalidAncestorBlock {
t.Errorf("TestMaybeAcceptBlockErrors: rejecting the block if its parents are invalid: "+
"Unexpected error. Want: %s, got: %s", ErrInvalidAncestorBlock, ruleErr.ErrorCode)
}
// Set block1's status back to valid for next tests
dag.index.UnsetStatusFlags(blockNode1, statusValidateFailed)
// Test rejecting the block due to bad context
originalBits := block2.MsgBlock().Header.Bits
block2.MsgBlock().Header.Bits = 0
err = dag.maybeAcceptBlock(block2, BFNone)
if err == nil {
t.Errorf("TestMaybeAcceptBlockErrors: rejecting the block due to bad context: "+
"Expected: %s, got: <nil>", ErrUnexpectedDifficulty)
}
if ok := errors.As(err, &ruleErr); !ok {
t.Errorf("TestMaybeAcceptBlockErrors: rejecting the block due to bad context: "+
"Expected RuleError but got %s", err)
} else if ruleErr.ErrorCode != ErrUnexpectedDifficulty {
t.Errorf("TestMaybeAcceptBlockErrors: rejecting the block due to bad context: "+
"Unexpected error. Want: %s, got: %s", ErrUnexpectedDifficulty, ruleErr.ErrorCode)
}
// Set block2's bits back to valid for next tests
block2.MsgBlock().Header.Bits = originalBits
}

Some files were not shown because too many files have changed in this diff Show More