This repurposes the sequence number of version 2 transaction inputs to provide consensus-enforced relative lock-time semantics so that a transaction can require inputs to have a specified relative age before they are allowed to be included in a block. Each relative time lock can either specify a relative number of seconds (with a granularity of 512 seconds and a maximum value of 33,553,920) or a specific number of blocks (max 65535). The number of seconds is calculated relative to the past median time of the block before the one that contains the referenced output. This is done because, due to other changes that will also be included in the same agenda vote, said time will become the earliest possible time the block that contains the referenced output could have been (technically it will be one second after that, but that complexity is ignored since there is already a granularity involved anyways). It is also possible to disable the behavior by setting bit 31 of the sequence number (which all transactions currently do by default since they are set to the max). In order for the transaction to be permitted to the mempool, relayed, considered for inclusion into block templates, and allowed into a block, the specified relative time locks for all of its inputs must be satisfied. This only implements the required logic and tests to enforce the new behavior. Code to enforce the new behavior when considering candidate transactions for acceptance to the mempool, relaying, and inclusion into block templates will be added in a separate commit. A consensus vote is required in order to reject blocks which contain transactions that violate the new rules at a consensus level. Code to selectively enable consensus enforcement based on the result of an agenda vote will be added in a separate commit. In order to accomplish this new behavior, the concept of a sequence lock is introduced which allows the minimum possible time and height at which a transaction can be included into a block to be calculated from all inputs with non-disabled relative time locks, and functions to calculate and evaluate the sequence lock are added. The following is an overview of the changes: - Introduce a new struct named SequenceLock to represent the previously described sequence lock - Define new constants related to sequence numbers named SequenceLockTimeDisabled, SequenceLockTimeIsSeconds, SequenceLockTimeMask, and SequenceLockTimeGranularity - Add a new function named calcSequenceLock to calculate the sequence lock for a given transaction - Add a new function named SequenceLockActive to determine if a given sequence lock is satisfied for a given block height and past median time - Add a convenience function named LockTimeToSequence which can be used to convert a relative lock time to a sequence number - Add a comprehensive set of tests for all of the new funcs |
||
|---|---|---|
| .. | ||
| bench_test.go | ||
| blockheader_test.go | ||
| blockheader.go | ||
| common_test.go | ||
| common.go | ||
| doc.go | ||
| error.go | ||
| fakeconn_test.go | ||
| fakemessage_test.go | ||
| fixedIO_test.go | ||
| invvect_test.go | ||
| invvect.go | ||
| message_test.go | ||
| message.go | ||
| msgaddr_test.go | ||
| msgaddr.go | ||
| msgalert_test.go | ||
| msgalert.go | ||
| msgblock_test.go | ||
| msgblock.go | ||
| msgfeefilter_test.go | ||
| msgfeefilter.go | ||
| msgfilteradd_test.go | ||
| msgfilteradd.go | ||
| msgfilterclear_test.go | ||
| msgfilterclear.go | ||
| msgfilterload_test.go | ||
| msgfilterload.go | ||
| msggetaddr_test.go | ||
| msggetaddr.go | ||
| msggetblocks_test.go | ||
| msggetblocks.go | ||
| msggetdata_test.go | ||
| msggetdata.go | ||
| msggetheaders_test.go | ||
| msggetheaders.go | ||
| msggetminingstate.go | ||
| msgheaders_test.go | ||
| msgheaders.go | ||
| msginv_test.go | ||
| msginv.go | ||
| msgmempool_test.go | ||
| msgmempool.go | ||
| msgmerkleblock_test.go | ||
| msgmerkleblock.go | ||
| msgminingstate_test.go | ||
| msgminingstate.go | ||
| msgnotfound_test.go | ||
| msgnotfound.go | ||
| msgping_test.go | ||
| msgping.go | ||
| msgpong_test.go | ||
| msgpong.go | ||
| msgreject_test.go | ||
| msgreject.go | ||
| msgsendheaders_test.go | ||
| msgsendheaders.go | ||
| msgtx_test.go | ||
| msgtx.go | ||
| msgverack_test.go | ||
| msgverack.go | ||
| msgversion_test.go | ||
| msgversion.go | ||
| netaddress_test.go | ||
| netaddress.go | ||
| protocol_test.go | ||
| protocol.go | ||
| README.md | ||
wire
Package wire implements the decred wire protocol. A comprehensive suite of tests with 100% test coverage is provided to ensure proper functionality.
This package has intentionally been designed so it can be used as a standalone package for any projects needing to interface with decred peers at the wire protocol level.
Installation and Updating
$ go get -u github.com/decred/dcrd/wire
Decred Message Overview
The decred protocol consists of exchanging messages between peers. Each message is preceded by a header which identifies information about it such as which decred network it is a part of, its type, how big it is, and a checksum to verify validity. All encoding and decoding of message headers is handled by this package.
To accomplish this, there is a generic interface for decred messages named
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 decred messages are provided. For these
supported messages, all of the details of marshalling and unmarshalling to and
from the wire using decred encoding are handled so the caller doesn't have to
concern themselves with the specifics.
Reading Messages Example
In order to unmarshal decred messages from the wire, use the ReadMessage
function. It accepts any io.Reader, but typically this will be a net.Conn
to a remote node running a decred peer. Example syntax is:
// Use the most recent protocol version supported by the package and the
// main decred network.
pver := wire.ProtocolVersion
dcrnet := wire.MainNet
// Reads and validates the next decred message from conn using the
// protocol version pver and the decred network dcrnet. The returns
// are a wire.Message, a []byte which contains the unmarshalled
// raw payload, and a possible error.
msg, rawPayload, err := wire.ReadMessage(conn, pver, dcrnet)
if err != nil {
// Log and handle the error
}
See the package documentation for details on determining the message type.
Writing Messages Example
In order to marshal decred messages to the wire, use the WriteMessage
function. It accepts any io.Writer, but typically this will be a net.Conn
to a remote node running a decred peer. Example syntax to request addresses
from a remote peer is:
// Use the most recent protocol version supported by the package and the
// main decred network.
pver := wire.ProtocolVersion
dcrnet := wire.MainNet
// Create a new getaddr decred message.
msg := wire.NewMsgGetAddr()
// Writes a decred message msg to conn using the protocol version
// pver, and the decred network dcrnet. The return is a possible
// error.
err := wire.WriteMessage(conn, msg, pver, dcrnet)
if err != nil {
// Log and handle the error
}
License
Package wire is licensed under the copyfree ISC License.