This commit adds a new function named SerializeSize to the public API for
MsgBlock which can be used to determine how many bytes the serialized data would
take without having to actually serialize it. In addition, it makes the
exported BlockVersion an untyped constant as well as changes the block and
tx versions to a signed integer to more closely match the protocol.
Finally, this commit also adds tests for the new function.
The following benchmark shows the difference between using the new
function to get the serialize size for a typical block and serializing
into a temporary buffer and taking the length of it:
Bufffer: BenchmarkBlockSerializeSizeBuffer 200000 27050 ns/op
New: BenchmarkBlockSerializeSizeNew 100000000 34 ns/op
Closes#19.
Rather than using bytes.NewBuffer, which is a read/write entity
(io.ReadWriter), use bytes.NewReader which is only a read entitiy
(io.Reader) in all cases where it is possible. Benchmarking shows it's
slightly faster and it's also technically more accurate since it ensures
the data is read-only.
There are a few cases where bytes.NewBuffer must still be used since a
buffer with a known length is required for those instances.
This commit updates doc.go to include the new simulation test network
magic constant as well as remove the information about BIP0037 not being
supported since that is no longer true.
The default network ports are not really part of the wire protocol rather
they are part of a network parameters. Thus, this commit moves them to
the btcnet package.
The genesis blocks are not really part of the wire protocol rather they
are part of a network parameters. Thus, this commit moves the all of the
gensis blocks and tests to the btcnet package.
Also, create variables in the test package for the mainnet genesis hash,
merkle root, and coinbase transaction for use throughout the tests since
they the exported values are no longer available.
This commit adds a full suite tests for the new reject message added in
protocol version 70002 to bring the overall test coverage of btcwire back
up to 100%.
Closes#9.
This commit adds the new reject protocol message added to recent versions
of the reference implementation. This message is intended to be used in
response to messages from a remote peer when it is rejected for some
reason such as blocks being rejected due to not conforming to the chain
rules, transactions double spending inputs, and version messages sent
after they're already sent.
This is work toward issue #9.
- Correct MsgFilterLoad max payload
- Enforce max flag bytes per merkle block
- Improve and finish tests to include testing all error paths
- Add fast paths for BloomUpdateType
- Convert all byte fields to use read/writeVarBytes
- Style and consistency updates
- README.md and doc.go updates
Closes#12.
- Group the new read/writeVarBytes functions together to be consistent
with the existing code
- Modify the comments on the new read/writeVarBytes to be a little more
descriptive and consistent with existing code
- Use "test payload" for field name in the tests for the
read/writeVarBytes functions which is more accurate
- Remove reserved param from NewAlert since there is no point is having
the caller deal with a reserved param
- Various comment tweaks for clarity and consistency
- Use camel case for fuction params for consistency
- Move the NewAlert and NewAlertFromPayload functions after the receiver
definitions for code layout consistency
Closes#11.
* Introduced common methods readVarBytes, writeVarBytes.
* Added type Alert which knows how to deserialize
the serialized payload and also serialize itself back.
* Updated MsgAlert BtcEncode/BtcDecode methods to handle the
new Alert.
* Sane limits are placed on variable length fields like SetCancel
and SetSubVer
The code was updated to automatically handle the transaction count in the
block header without having the additional field some time ago. This
comment was outdated.
the new function AddUserAgent adds the user agent to the stack
and formats it as per BIP 0014
e.g: "/btcwire:0.1.4/myclient:1.2.3(optional; comments)/"
the validation on UserAgent has been moved to a new function
validateUserAgent
- Coalesce the new bytes into the max message size constant to stay
consistent
- Correct optional relay tx field handling
- Rename the relay transactions field to DisableRelayTx so the zero value
of false has the correct default behavior
- Add tests for new bool fast paths in read/writeElement
- Stay consistent with version order in tests
- Add a single entry to TestVersionWire to test the new functionality
instead of adding a whole new TextVersionRelayTx function.
- Use BIP0037 in tests instead of hard coding 70001
- Nuke XXX that 70001 is different since this is handled now
- Fix and cleanup some comments
- Update test coverage report
Since fields of a version message after the AddrMe field are optional,
this commit adds a series of tests which ensure parsing version messages
which omit each of the optional fields works properly.
This commit modifies the MsgVersion.BtcDecode function to match the
behavior where fields after the first address field (AddrYou) are optional
and only read if the buffer contains remaining bytes.
Unfortunately this means the reader for MsgVersion.BtcDecode must be a
*bytes.Buffer or an error is returned. This is not an issue for the vast
majority of cases since all of the message reading code which is the main
way messages are read is already using a *bytes.Buffer, however, this
change might affect external callers if they are doing something special
with custom readers.
Fixes#14.
serialization buffer in MsgTx's TxSha().
Benchmarking shows this is slightly faster due to avoiding the extra
garbage collection in addition to less peak memory usage.
Before: BenchmarkTxShaOld 500000 5626 ns/op
After: BenchmarkTxShaNew 500000 5457 ns/op
This commit exports the VarIntSerializeSize function to provide callers
with an easy method to determine how many bytes it would take to serialize
the passed value as a variable length integer.
This commit changes all cases which generate default timestamps to
time.Now to limit the timestamp to one second precision. The code which
serializes and deserializes timestamps already does this, but it is useful
to make sure defaults don't exceed the precision of the protocol either.
With this change there is less chance that developers using defaults will
end up with structures that have a higher time precision than what will
ultimately be sent across the wire.
This commit adds two new funtions named ReadMessageN and WriteMessageN
which return an additional paramter for the number of bytes read or written,
respectively.
It also adds tests to ensure the number of bytes read and written are the
expected values both for successful reads/writes and unsuccessful ones.
Closes#6.
This commit introduces two new functions for Blockheader named Serialize
and Deserialize. The functions provide a stable mechanism for serializing
and deserializing block headers to and from disk. The main benefit here
is deserialization of the header since typically only full blocks are
serialized to disk. Then when a header is needed, only the header portion
of the block is read and deserialized.
This commit removes the TxnCount field from the BlockHeader type and
updates the tests accordingly. Note that this change does not affect the
actual wire protocol encoding in any way.
The reason the field has been removed is it really doesn't belong there
even though the wire protocol wiki entry on the official bitcoin wiki
implies it does. The implication is an artifact from the way the
reference implementation serializes headers (MsgHeaders) messages. It
includes the transaction count, which is naturally always 0 for headers,
along with every header. However, in reality, a block header does not
include the transaction count. This can be evidenced by looking at how a
block hash is calculated. It is only up to and including the Nonce field
(a total of 80 bytes).
From an API standpoint, having the field as part of the BlockHeader type
results in several odd cases.
For example, the transaction count for MsgBlocks (the only place that
actually has a real transaction count since MsgHeaders does not) is
available by taking the len of the Transactions slice. As such, having
the extra field in the BlockHeader is really a useless field that could
potentially get out of sync and cause the encode to fail.
Another example is related to deserializing a block header from the
database in order to serve it in response to a getheaders (MsgGetheaders)
request. If a block header is assumed to have the transaction count as a
part of it, then derserializing a block header not only consumes more than
the 80 bytes that actually comprise the header as stated above, but you
then need to change the transaction count to 0 before sending the headers
(MsgHeaders) message. So, not only are you reading and deserializing more
bytes than needed, but worse, you generally have to make a copy of it so
you can change the transaction count without busting cached headers.
This is part 1 of #13.