This modifies the CancelPending method of the connection manager to
return an error when there are no pending connections for the provided
address or the connection manager is already shutting down.
This change, in turn, ensures that attempts to remove a pending
connection that doesn't exist via RPC returns an error as expected.
This reworks the HTTPS seeding in the connmgr package and server to make
it easier to use properly and to make use of a couple of the new
capabilities it offers.
The current implementation of the SeedAddrs function is basically a
carbon copy of the older DNS seeding function with some slight
modifications and, as a result, its API is geared more towards the older
functionality which is not the most ideal for the new functionality.
First, since the SeedAddrs function is synchronous, as opposed
to the older async DNS seeder version, an OnSeed callback adds
unnecessary complexity since the addresses can simply be returned from
the function instead.
Next, this existing function does not make it very clear how to use the
additional filtering parameters and it also always sets them in the
query string which unnecessarily imposes a specific implementation on
the seeding server. More desirable behavior is to only set the specific
query parameters when the caller wishes to apply specific filters.
Finally, the code in the server that consumes the returned seeds
currently still contains a quirk that was required by the old DNS
seeding semantics which no longer apply where it attributes the source
of the addresses to the first returned address.
This addresses all of those issues and a couple of other minor nits.
The following is an overview of the changes:
- Modify the SeedAddrs func signature to return the addresses directly
instead of using an OnSeed callback
- Introduce a new HttpsSeederFilters struct along with exported
functions that allow the caller to selectively specify seed filters
- Modify the SeedAddrs func signature to accept a variable number of
filters specified via the aforementioned functions
- This allows only the specific filters the caller desires to be
specified and is easily extensible to support more filters with no
breaking API changes in the future should it be necessary
- Modify the implementation of the SeedAddrs func to only set the query
params for the various filter options if the caller provided them
- Improve the logging to properly handle any invalid addresses returned
from the seeder
- Improve the readability of the random time offset code in SeedAddrs
- Update the server code in accordance with the API changes
- Modify the server code that adds the discovered addresses to the
address manager to look up the IP address of the HTTPS seeder and use
that as the source address
- Fall back to the first returned address in the extremely rare event
the HTTPS seeder IP lookup fails
This updates the main go.mod direct dependencies to account for the
recent rpcclient bumps as follows:
- github.com/decred/dcrd/dcrutil/v3@v3.0.0-20200503044000-76f6906e50e5
- github.com/decred/dcrd/rpc/jsonrpc/types/v2@v2.0.1-0.20200503044000-76f6906e50e5
- github.com/gorilla/websocket@v1.4.2
The error handling in the tests for the wire package were recently
updated to make use of the new errors.Is and errors.As standard library
functions introduced in Go 1.13, but they were only updated mechanically
as opposed to being updated to use the new capabilities of errors.Is
checking for a specific error code as opposed to just the error type.
Consequently, this updates the tests to remove all of the additional
type checking via errors.As and instead look for the exact expected
error code via errors.Is. This change is desirable since only examining
the type of error doesn't prove that the test is actually hitting the
specific error it intends too, rather only that it is hitting an error
of the same type.
It also corrects a couple of tests and error returns that were
discovered to be incorrect in the process.
The test structs were created for testing the DisableRelayTx = true
case, but they weren't being used. Linter didn't pick up on it
because both test structs were being modified.
Methods calls on the Client type for performing dcrwallet JSON-RPCs
are being removed in order to simplify the dependency graphs between
projects. These calls are moving to a package in the dcrwallet module
that will abstract the actual connection and calling logic through an
interface (which rpcclient.Client will satisfy).
All callbacks for dcrwallet notifications have been removed.
Dcrwallet has not produced JSON-RPC notifications for several years at
this point.
The example program connecting to dcrwallet is also removed here. If
the dependencies of this program appeared in the go.mod (they don't
currently, as go-spew is missing), then rpcclient would be right back
to requiring the dcrwallet module. This example program may reappear
in the new wallet package. Any pointers towards the new wallet
package should be done in comments, not code that will update the
modules.
This updates the error handling in the wire package to be more
consistent with the rest of the code base, tightens some of the error
handling in message parsing to harden the protocol, and adds tests to
ensure the error implementations works correctly with the standard
library errors.Is and errors.As functions introduced in Go 1.13.
In particular, the error code semantics have been changed so the first
error starts at 0 instead of treating 0 is a sentinel "no error" value
because it goes against Go best practices which designed the errors
specifically to avoid the use of sentinel values. Further, the use of 0
as a sentinel means that there are two different ways to indicate "no
error", namely nil and an error code of zero. Thus callers have to know
that they need to check for both conditions which is incredibly error
prone. In fact, there is already at least one instance in the code base
that has that mistake in the tests.
Finally, while here, this hardens the protocol by enforcing more strict
parsing requirements lower in the software stack instead of relying on
upper layers to take care of it.
This removes the references to btcd from README.md since the code base
has diverged so much that there isn't very much in common anymore and
thus the text no longer reflected reality.
This modifies the peer initialization code to set a default idle timeout
of two minutes if the caller did not specify one.
This is desirable since the default is the zero value otherwise, which
results in an immediate disconnection for callers that don't specify a
timeout.
It is worth noting that the server code already has a default setting
that can be configured via the command-line or a configuration file
which is used to configure the peers, so this has no effect on dcrd, but
it is a nice addition for other consumers of the peer package.
The dcrctl project is being split out of the dcrd repo and module into
its own repo (https://github.com/decred/dcrctl) and module
(decred.org/dcrctl). This commit removes the dcrctl main package and
updates documentation throughout the repo mentioning dcrctl and its
build instructions.
This updates the primary `README.md` for the most recent versions of Go,
minimum recommended requirements, and to reflect reality for the latest
version of the test script.
This modifies the ParsePubKey function to avoid an additional
unnecessary check if the point is on the curve in the compressed pubkey
case because it necessarily has already determined if that is true via
the point decompression from the x coordinate.
Also, prevent x from escaping to the heap for the error print in
compressed case while here.
benchmark old ns/op new ns/op delta
------------------------------------------------------------------
BenchmarkParsePubKeyCompressed 11901 11745 -1.31%
BenchmarkParsePubKeyUncompressed 335 325 -2.99%
benchmark old allocs new allocs delta
-------------------------------------------------------------------
BenchmarkParsePubKeyCompressed 2 1 -50.00%
BenchmarkParsePubKeyUncompressed 2 1 -50.00%
benchmark old bytes new bytes delta
-------------------------------------------------------------------
BenchmarkParsePubKeyCompressed 128 80 -37.50%
BenchmarkParsePubKeyUncompressed 128 80 -37.50%
This updates the internal implementation of the PublicKey type to use
the FieldVal type instead of big.Ints and modifies NewPublicKey to
accept the FieldVals and updates all callers and tests in the repository
accordingly.
Public key parsing and serialization are now completely free of
big.Ints.
Finally, it moves the X and Y methods to the ellipticadaptor.go file
since they are only intended to provide interop with the standard
library elliptic curve adaptor code.
This reduces the number of allocations needed in the ecdsa compact
signature recovery as well as schnorr signature verification and results
in a slight speedup for both.
The following benchmarks show the before and after comparison:
benchmark old ns/op new ns/op delta
----------------------------------------------------------
BenchmarkRecoverCompact 198012 196173 -0.93%
BenchmarkSigVerify 179170 177805 -0.76%
benchmark old allocs new allocs delta
-----------------------------------------------------------
BenchmarkRecoverCompact 36 32 -11.11%
BenchmarkSigVerify 19 15 -21.05%
benchmark old bytes new bytes delta
-----------------------------------------------------------
BenchmarkRecoverCompact 1745 1617 -7.34%
BenchmarkSigVerify 977 848 -13.20%
This adds a new method to the PublicKey type which can be used to
determine if the public key is on the secp256k1 curve directly.
It also adds tests to ensure proper functionality.
This updates the public key parsing tests to test for the explicit
reason for the failure to ensure that each test is actually testing the
intended condition.
This introduces a new error type and associated error code for public
key errors which can be used with the errors.Is and errors.As interfaces
to programmatically detect the failure reason and updates the public key
parsing code to return appropriate error codes.
It includes full tests for the new error infrastructure.
This reworks the tests related to public keys to them more consistent
with the rest of the package and improve their coverage to include all
of the possible error paths.
It also brings back the hybrid pubkey parsing to match what the function
comment claims and corrects the tests accordingly. The restriction as
to which specific types of pubkeys are allowed must be (and is) enforced
by the opcode(s) that interpret them as opposed to the lib that
implements the more generic specification.
The following is an overview of the changes:
- Convert all tests to use hex strings
- Add and verify the expected x and y coordinates from a parsed pubkey
- Bring back support for parsing hybrid keys
- Correct remaining existing tests for hybrid pubkeys
- Add negative tests for all combinations of encoding what would
otherwise be valid pubkey with the wrong format byte and y coord
oddness
- Add negative tests for x and y coordinates == p for the uncompressed,
compressed, and hybrid formats
- Add negative tests for all formats such that either the x or y
coordinate are > p and are constructed in such a way that they would
be valid if the coordinate is taken mod p to ensure implementations
don't incorrectly ignore the range check
This updates the code to use the recently-added PutBytesUnchecked of
the FieldVal and ModNScalar types to serialize directly into larger
buffers where possible to avoid the need for additional copies.
This updates the code to use the recently-added PutBytesUnchecked of
the FieldVal and ModNScalar types to serialize directly into larger
buffers where possible to avoid the need for additional copies.
The following benchmarks show a before and after comparison of the
affected operations:
benchmark old ns/op new ns/op delta
--------------------------------------------------------
BenchmarkSign 52682 52284 -0.76%
BenchmarkSigVerify 178050 176977 -0.60%
BenchmarkSigSerialize 87.5 73.3 -16.23%
benchmark old allocs new allocs delta
--------------------------------------------------------
BenchmarkSign 16 16 +0.00%
BenchmarkSigVerify 21 21 +0.00%
BenchmarkSigSerialize 1 1 +0.00%
benchmark old bytes new bytes delta
--------------------------------------------------------
BenchmarkSign 960 960 +0.00%
BenchmarkSigVerify 1105 1105 +0.00%
This optimizes the various internal implementations that make use of
secp256k1 to use the specialized ModNScalar and JacobianPoint types
instead of big.Ints.
The following benchmarks show a before and after comparison:
benchmark old ns/op new ns/op delta
-----------------------------------------------------------
BenchmarkDeriveHardened 3702 3547 -4.19%
BenchmarkDeriveNormal 4053 3587 -11.50%
BenchmarkPrivToPub 94.7 94.0 -0.74%
BenchmarkDeserialize 5825 5797 -0.48%
BenchmarkSerialize 9509 9402 -1.13%
benchmark old allocs new allocs delta
-----------------------------------------------------------
BenchmarkDeriveHardened 14 12 -14.29%
BenchmarkDeriveNormal 15 12 -20.00%
BenchmarkPrivToPub 1 1 +0.00%
BenchmarkDeserialize 4 3 -25.00%
BenchmarkSerialize 3 3 +0.00%
benchmark old bytes new bytes delta
-----------------------------------------------------------
BenchmarkDeriveHardened 1360 1232 -9.41%
BenchmarkDeriveNormal 1409 1232 -12.56%
BenchmarkPrivToPub 112 112 +0.00%
BenchmarkDeserialize 320 256 -20.00%
BenchmarkSerialize 272 272 +0.00%
This adds a new method to ModNScalar named PutBytesUnchecked which can
be used by callers to serialize the scalar directly into a target byte
slice with the caveat that the caller must ensure the target has at
least 32 bytes available or it will panic.
This is useful in cases where the caller wishes to write into a larger
buffer without having to first serialize into a 32-byte array and copy
it.
It also updates the tests to ensure it works as expected.
This adds a new method to FieldVal named PutBytesUnchecked which can be
used by callers to serialize the field value directly into a target byte
slice with the caveat that the caller must ensure the target has at
least 32 bytes available or it will panic.
This is useful in cases where the caller wishes to write into a larger
buffer without having to first serialize into a 32-byte array and copy
it.
It also updates the tests to ensure it works as expected.
This renames some error codes to more closely match the failure as
follows:
- ErrBadInputSize -> ErrInvalidHashLen
- ErrInputValue -> ErrPrivateKeyIsZero
- ErrPointNotOnCurve -> ErrPubKeyNotOnCurve
- ErrBadSigRYValue -> ErrSigRYIsOdd
- ErrBadSigRNotOnCurve -> ErrSigRNotOnCurve
This updates the internal implementation of the Signature type to use
the ModNScalar and FieldVal types instead of big.Ints and modifies
NewSignature to accept the types accordingly.
Signature parsing and signing operations are now completely free of
big.Ints. Verification still relies on them due to their use in public
keys.
It also removes the now unused primitives.go file.