It has a special `requestF` and a special initialization function, but other
than that it's an absolutely regular WSClient. Can be used to call, can be
used to subscribe. Fixes#2909.
According to docs, `Server` uses provided error channel only to write
encountered error to it. In this case, there is no need to accept rw
channel to create `Server` instance. Strengthening the type to
write-only will allow the caller to ensure control of reading errors
from the provided channel.
The change is backward compatible since any `chan` is `chan<-`.
Signed-off-by: Leonard Lyubich <ctulhurider@gmail.com>
We have both from and to here, so technically we can either drop the neg/neg
trick from the processTokenTransfer() or drop one field from the structure
(the other side is a part of the key). Drop the field since this can make the
DB a bit more compact. Change Amount to be a pointer along the way since
that's the "native" thing for big.Int, we've used non-pointer field
specifically to avoid Neg/Neg problems, but it looks like this is not
necessary.
This structure is only used by the RPC server and I doubt anyone uses it via
the *Blockchain.
And include some node-specific configurations there with backwards
compatibility. Note that in the future we'll remove Ledger's
fields from the ProtocolConfiguration and it'll be possible to access them in
Blockchain directly (not via .Ledger).
The other option tried was using two configuration types separately, but that
incurs more changes to the codebase, single structure that behaves almost like
the old one is better for backwards compatibility.
Fixes#2676.
It doesn't store id->hash mappings for native contracts. We need blockchain's
GetContractScriptHash to serve both anyway, so it was changed a bit. The only
other direct user of native.GetContractScriptHash is the VM CLI, but I doubt
anyone will use it for native contracts (they have ~zero VM code anyway).
There are no changes visible from the user side (at least for those
users who doesn't put Prometheus's or pprof's port in quotes), just
internal refactoring. From now and on, BasicService configuration is
used by RPC server config, TLS for RPC server, pprof and Prometheus.
It's more generic and convenient than MillisecondsPerBlock. This setting is
made in backwards-compatible fashion, but it'll override SecondsPerBlock if
both are used. Configurations are specifically not changed here, it's
important to check compatibility.
Fixes#2675.
Follow neo-project/neo#2807. Notice that this data is not cached, our previous
implementation wasn't too and it shouldn't be a problem (not on the hot path).
Blockchain's subscriptions, unsubscriptions and notifications are
handled by a single notificationDispatcher routine. Thus, on attempt
to send the subsequent event to Blockchain's subscribers, dispatcher
can't handle subscriptions\unsubscriptions. Make subscription and
unsubscription to be a non-blocking operation for blockchain on the
server side, otherwise it may cause the dispatcher locks.
To achieve this, use a separate lock for those code that make calls
to blockchain's subscription API and for subscription counters on
the server side.
If VUB-th block is received, we still can't guaranty that transaction
wasn't accepted to chain. Back this situation by rolling back to a
poll-based waiter.
Do not block subscribers until the unsubscription request to RPC server
is completed. Otherwise, another notification may be received from the
RPC server which will block the unsubscription process.
At the same time, fix event-based waiter. We must not block the receiver
channel during unsubscription because there's a chance that subsequent
event will be sent by the server. We need to read this event in order not
to block the WSClient's readloop.
client_test.go:1935:
Error Trace: /home/rik/dev/neo-go/pkg/services/rpcsrv/client_test.go:1935
Error: Should NOT be empty, but was 00000000-0000-0000-0000-000000000000
Test: TestClient_Iterator_SessionConfigVariations/sessions_disabled
It's obviously empty, since we have sessions disabled, but it was not
considered to be empty in testify 1.7.0, now it is, see 840cb80149
NEP-6 has a notion of locked acccounts and SignTx must respect this user's
choice. For some reason this setting was inappropriately used by our RPC
client tests (probably a different kind of lock was meant).
calculatenetworkfee MUST calculate complete proper network fee, if we have
some extensions enabled and some attributes should be paid for that they're a
part of the equation too.
We're dealing with a transaction here and it can't be decoded successfully
unless it has an appropriate number of witness scripts (matching the number of
signers) with appropriate hashes (matching signers). So this iterations make
no sense at all, we know exactly where to look for the
verification/invocation scripts.
Blockchain's notificationDispatcher sends events to channels and these
channels must be read from. Unfortunately, regular service shutdown procedure
does unsubscription first (outside of the read loop) and only then drains the
channel. While it waits for unsubscription request to be accepted
notificationDispatcher can try pushing more data into the same channel which
will lead to a deadlock. Reading in the same method solves this, any number of
events can be pushed until unsub channel accepts the data.
Unfortunately Go doesn't allow to easily reuse readers in full packages, still
we can have this wrapper with a little overhead (the alternative is to move
specific methods into types of their own, but I'm not sure how it's going to
be accepted user-side).
Notice that int64 types are used for gas per block or registration price
because the price has to fit into the system fee limitation and gas per block
value can't be more than 10 GAS. We use int64 for votes as well in other types
since NEO is limited to 100M.
And test it with the RPC server.
Notice that getters still return int64 instead of *big.Int, that's because
these values are very limited and technically could even fit into an int (but
that seems to be too dangerous to use for long-term compatibility).
See neo-project/neo#2390. Can't see it there? No wonder, that's why we have
this bug for a year and a half. Not critical, we don't care about versions,
but _very_ annoying.
They were first introduced in a058598ecc and
then carefully moved in 648e0bb242, but it looks
like they were never used by any external code. This code can be useful on the
server, but the server has its own params package to deal with
parameters. Clients usually create Parameters and then get results as
stackitem.Items, so they don't use this code either. So there is zero point in
keeping it.
Which allows to enable/disable the service, change nodes, keys and other
settings. Unfortunately, atomic.Value doesn't allow Store(nil), so we have to
store a pointer there that can point to nil interface.
It's not an ideal solution, but at least it solves the problem for
now. Caveats:
* consensus only needs one method, so it's mirrored to Blockchain
* rpcsrv uses core.* definition of the StateRoot (so technically it might as
well not have an internal Ledger), but it uses core already unfortunately
1. It's not good for pkg/core to import anything from pkg/neorpc.
2. The type is closely tied to the state package, even though it's not stored
in the DB
It doesn't add anything useful to regular Go types and actually native types
are always better to use in the Client. Especially given that this type is
not used by any code outside of the Client itself.
They test both module and service which is a bit wrong, but separating these
tests will lead to some duplication, so it's OK for now to have them in the
higher-order package (service imports module).
1. Move redirections check to the tcp level. Manually resolve request address
and create connection for the first suitable resolved address.
2. Remove URIValidator. Redirections checks are set in the custom http client,
so the user should take care of validation by himself when customizing the
client.
Notice that it makes the node accept Extensible payloads with any category
which is the same way C# node works. We're trusting Extensible senders,
improper payloads are harmless until they DoS the network, but we have some
protections against that too (and spamming with proper category doesn't differ
a lot).
Update includes:
1. New simple client mode that parses erroneous status codes as `error` and
returns them from the calls of the client methods.
2. `Client` is struct now, not an interface.
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
Replace `neofs-api-go` module with `neofs-sdk-go`. Adapt to NeoFS
response statuses in the implementation of NeoFS oracle.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Problem: transactions with wrong hashes are accepted to the chain if
consensus nodes are designated as Oracle nodes. The result is wrong
MerkleRoot for the accepted block. Consensus nodes got such blocks
right from the dbft and store them without errors, but if
non-consensus nodes are present in the network, they just can't accept
these "bad" blocks:
```
2021-11-29T12:56:40.533+0300 WARN blockQueue: failed adding block into the blockchain {"error": "invalid block: MerkleRoot mismatch (expected a866b57ad637934f7a7700e3635a549387e644970b42681d865a54c3b3a46122, calculated d465aafabaf4539a3f619d373d178eeeeab7acb9847e746e398706c8c1582bf8)", "blockHeight": 17, "nextIndex": 18}
```
This problem happens because of transaction hash caching. We can't set
transaction hash if transaction construction wasn't yet completed.
Notes for witnesses:
* [N sig + M multisig + K contract] combination is possible where N, M, K >=0.
* Each verification script should be properly filled in.
* Each invocation script should either be empty or contain exactly one
signature.
If an oracle node is resynchronized from the genesis the service receives all
requests from all blocks via AddRequests() invoked from the native
contract. Almost all of them are long obsolete and need to be removed, native
oracle contract will try to do that with RemoveRequests() calls, but they
won't change anything.
So queue up all "initial" requests in special map and manage it directly
before the module is Run() which happens after synchronization
completion. Then process any requests that are still active and work with new
blocks as usual.
Turns out, nothing should be changed in our implementation because
nil-check is done implicitly by type casts or type switches.
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
Update neofs-api-go to `v1.27.1`.
Add `WithURIAddress` client option.
Stop using `V2` abstractions outside
of the `api-go` library.
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
These are arbitrary numbers, but that's what C# node uses. maxRetries could be
set lower because we have exponential backoff anyway, but this works too.
And don't add/resend it multiple times.
1. We can be in a setup with one SV only and no AddSignature() called at all.
2. AddSignature() might add M-1 signatures and our signature should be the
last one to complete MPTRoot, but we'll never do that.