Comments (11)
Here's an idea: when push_decode
is in we add the generic impl but try to downcast and simply return the bytes directly if the type is a slice (notice that push_decode
has slice/iterator encoders). This is zero cost when the type is statically known.
Note that I feel uneasy about saying that all vectors in Bitcoin are and will be always encoded as varint-prefixed. Especially because it already isn't true for the sequence of Witness
es in segwit-encoded transaction.
from rust-bitcoin.
If we restrict ourselves to a specific layout of what's logically a sequence then yeah, it's not an example. I tend to think about layouts separately from concepts and conceptually a sequence is best represented as Iterator
- that's what I did in push_decode
PR with a special exception for non-length-prefixed.
Anyway, not a big deal I guess.
from rust-bitcoin.
Concept NACK, several reasons:
- conflicts with
push_decode
- the impl probably kind of shouldn't exist (to be precise
IterEncoder
exists butEncode for Vec<T>
probably shouldn't) - we don't need to test that much - if each individual item is encoded correctly (and we test that) then any test that uses various lengths of arrays of some sufficiently distinct items (e.g. ints going 1, 2, 3, 4...) is enough because the serialization doesn't interact with how exactly an item is serialized (the distinct items requirement is only to detect stupid cases like repeating the first element
n
times)
Oh, and if coverage complains about it, it's probably just idiotic. It should see it as one line in impl not tested which doesn't matter.
from rust-bitcoin.
There is no generic Vec<T>
impl. We had to remove it because we couldn't specialize on Vec<u8>
which is the overwhelmingly most common case and also the one which can be sped up significantly when we're not trying to be generic.
Having said that, agree with you that we should wait on push_decode
to get this in to avoid conflicts.
But afterward we might as well stick these tests in there if it makes the coverage analysis happier. Yes, they are pointless, but they will run very quickly and nobody will ever have to look at them again.
from rust-bitcoin.
I mean, if we're going to have an impl then we should probably have pub struct Inputs(Vec<TxIn>)
& co to be explicit. I had another reason for it: allowing inherent methods. Though I don't remember which methods I thought were useful.
from rust-bitcoin.
If there were inherent impls I think this could be worth doing. But otherwise it feels like we're just obfuscating the types.
But honestly I wish we did have Vec<T>
for all T
because then it would be clear that there's one way to consensus-encode vectors of all objects, and that we're not deviating from that somehow. But we can't, for efficiency reasons.
from rust-bitcoin.
Note that I feel uneasy about saying that all vectors in Bitcoin are and will be always encoded as varint-prefixed. Especially because it already isn't true for the sequence of
Witness
es in segwit-encoded transaction.
If they're encoded different they can use a different struct, it should be rare enough. And knowing that Vec<T>
is always encoded certain way makes reasoning about things easier.
from rust-bitcoin.
Especially because it already isn't true for the sequence of
Witness
es in segwit-encoded transaction.
I'm confused. Witnesses are encoded as a Vec<Vec<u8>>
in the "generic" way. This used to be how we encoded them a long time ago before the Witness
type. We even had an Encodable
impl for this type.
from rust-bitcoin.
@apoelstra In transaction it would be Vec<Vec<Vec<u8>>>
because there is a list of witnesses. And that list doesn't have a length prefixed - it's taken from the length of the inputs. This caused me quite a bit of refactoring to support when I was writing the code.
@dpc maybe, but it can get hairy with all the macros assuming Encode
does the right thing. Though it doesn't apply in case of witnesses since that is even more complicated by being in inputs rather than separate.
Anyway, I'm not too much against it, just flagging it as potential issue.
from rust-bitcoin.
I've never thought of it as a Vec<Vec<Vec<u8>>>
. Aside from not being serialized like one, each witness is associated with a single input and is conceptually part of TxIn
. If the number of witnesses differed from the number of inputs then the transaction would be invalid. So encoding as a Vec<Vec<Vec>>
would increase the transaction size while allowing invalid encodings, and representing witnesses as a Vec<Vec<Vec>>
(either in code or in your head) allows invalid objects to be represented.
Yes, this makes TxIn
's encoding "non-local" which is pretty annoying, but it isn't an example of a vector that's encoded differently from other vectors.
from rust-bitcoin.
Here's an idea: when
push_decode
is in we add the generic impl but try to downcast and simply return the bytes directly if the type is a slice (notice thatpush_decode
has slice/iterator encoders). This is zero cost when the type is statically known.
This comment inspired me to do: fedimint/fedimint#4145
from rust-bitcoin.
Related Issues (20)
- version error PSBT versions greater than 0 are not supported HOT 1
- Principled fix for #2521
- CI: MemorySanitizer is erroring (ASAN job) HOT 12
- units: Audit all types for correct usage of `Ord` vs `ArbitraryOrd` HOT 4
- Inherent functions `to_bytes` / `from_bytes` HOT 6
- Shoosh semver informational part build warning
- CI fails are hard to view HOT 10
- crate labels go stale
- Changes that require updating the lock files do not fail CI HOT 3
- Add `just` command to install githooks HOT 1
- Our current merge policy/script causes excessive delay and work HOT 2
- deserializing network message can request arbitrary sized allocations HOT 6
- Can we sort `rustfmt` out once and for all HOT 5
- Add type data to TxOut HOT 15
- Should `LockTime` types live in `units` HOT 8
- Consider not deriving `serde` impls from `units` types HOT 12
- Is introducing `LockTimeUnit` enum promote redundancy? HOT 3
- Should `Script::witness_version` check if the script `is_witness_program` before it returns the version? HOT 2
- Make sure we mention than 'm/' is not handled in bip32 derivation paths HOT 1
- Use `Message::from` HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rust-bitcoin.