There is nothing wrong with iterators being implemented in other parts
of code (e.g. Storage.Find). In this case type assertions can
prevent bugs at compile-time.
bafdb916a0 change was wrong (probably brought
from neo-vm 3.0 at the state at which it existed back then), neo-vm 2.x
doesn't allow PICKITEM for arbitrary types.
Which makes iterating over map stable which is important for serialization and
and even fixes occasional test failures. We use the same ordering here as
NEO 3.0 uses, but it should also be fine for NEO 2.0 because it has no
defined order.
Fixes#809.
Basically, there are three alternative approaches to fixing it:
* allowing both []byte and string for ByteArrayType value
minimal invasion into existing code, but ugly as hell and will probably
backfire at some point
* storing string values in ByteArrayType
incurs quite a number of type conversions (and associated data copying),
though note that these values are not changed usually, so dynamic
properties of []byte are almost irrelevant here
* storing only []byte values in ByteArrayType
makes it impossible to use them as map keys which can be solved in several
ways:
- via an interface (Marshalable)
which is good, but makes testing and comparing values in general harder,
because of keys mismatch
- using serialized Parameter as a key (in a string)
which will need some additional marshaling/unmarshaling
- converting MapType from map to a slice of key-value pairs
not a bad idea as we don't use this map as a map really, the type
itself is all about input/output for real VM types and this approach is
also a bit closer to JSON representation of the Map
C# pushes value and key to the stack of non-serialized items, so key gets
serialized first followed by value. Fixes#806.
Notice though that neither IDictionary in C#, nor map in Go have elements
ordered, so we can easily get a difference in KV pairs order and it would be
impossible to fix.
Old implementation could view 0x62 byte in
a script as a JMP instruction irregardless of whether it is
a real opcode or a part of a parameter of another instruction.
In this commit instructions are decoded together with parameters
during jump label rewriting.
Seeing some
blockQueue: failed adding block into the blockchain {"error": "failed to store notifications: not supported", "blockHeight": 713984, "nextIndex": 713985}
in logs is not very helpful.