In previous implementation node's Object Search V2 service handler created a
new request for each RPC. Now original requests are re-signed according to
API specification. Logical handler abstracts from this version-dependent
logic through `RequestForwarder` callback.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Evicting from cache requires closing blobovnicza which
in turn needs to lock `activeMtx`. This lock is not needed on
every addition, but our LRU library doesn't return evicted keys.
In future we may consider switching to other implementation.
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
Neo node can return integers values where []byte is expected.
To cover such cases, try to parse integers in `BytesFromStackItem`.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Add handler closure over worker pool
in the event package.
Add `addNewEpochAsyncNotificationHandler`
function that uses that closure. Pass
the reputation report handler to worker
pool via using that function.
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This function already reused in different storage engine parts
so it makes sense to keep it in separate package.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Different SplitInfo parts may be stored in different shards. Storage
engine must not stop at first SplitInfoError and should make
best effort to complete SplitInfo structure if needed.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
There were no unit tests of storage engine. This commit
adds first test to reproduce missing link ID in split info
at `engine.Head(raw)` request.
Engine tests uses some constructors from metabase tests,
so it is better to locate such functions in common
package at local_object_storage.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Add checking if returned error contains
"already on chain" substring. Do not
consider that behavior to be erroneous.
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
If non-"HALT" `State` occurs after
calling `InvokeFunction` NeoGo client
method, add `FaultException` information
to returning error. Add returning state
check to `NotaryInvoke` method of the
morph/client.
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
New neo-go version provides:
- new type for roles in `RoleManagement` contract,
- methods to get keys from `RoleManagement` contract,
- new way to sign notary transaction.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Add `Router` to the reputation server. `Router` is
called on every incoming request and inits `Writer`
that sends `Trust`s to the next route point or
handle(logs in that implementation) them if current
node is the end point of the route.
Rename `onlyKeyRemoteServerInfo` struct for container
to separate it from the same implementation of the
same `ServerInfo` interface for reputation.
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
Declare interfaces for building list of
managers of certain peer in certain epoch.
Implement `Builder` struct that aggregates
fields that are necessary for building
list of managers.
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
Implement reputation `Router` and its constructor,
designed to define where to send local trusts.
Router is based on dependencies that are hidden
behind interfaces, that are declared in the router's
package.
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
Mint, Burn and Cheque details should contain hash of
main net tx of Deposit and Withdraw invocation. They will
be formatted inside the contracts so alphabet nodes must
not modify them.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Unified format uses transfer type as the first byte
and extra details next. List of transfer types used in
contracts defined in `details.go`. It includes:
- audit settlement,
- basic income collection,
- basic income distribution.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
`Inhume` operation can be performed on already deleted objects, and in this
case the entry will be added to the graveyard. `Delete` operation finishes
with error if object is not presented in metabase. However, the entry in the
cemetery must be deleted regardless of the presence of the object.
Additionally, now `Delete` does not return an error in the absence of an
object.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Extra blocks for notary deposit must not be less than extra blocks
at notary tx rounding.
Consider you make notary deposit every 1000 block for next
1100 blocks. At block 555 you made notary deposit up to 1655.
At block 1554 you want to send notary tx. Notary client uses rounding
to calculate `until` value. By default notary client rounds with up
to 150 block ahead, thus for tx at 1554 `until` will be 1700.
1700 is bigger than deposit limit at 1655 and tx will fail. However
if extra blocks for notary deposit will be 200, then this case
won't be possible.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Implement gRPC ReputationServiceServer on structure that forwards requests
to underlying NeoFS API v2 ReputationService `Server`.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Hex encoded values are often may be misinterpreted as base58
values. Reverse case is quite rare, so it is better to try
hex decoding first.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Alias type provide sort function so it is better to use it
everywhere where list of public keys is presented.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This method has been removed from netmap contract. Corresponding
event from neofs contract renamed to AlphabetUpdate and should not
be processed, because alphabet updated from `RoleManagement`
contract.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
RoleManagement native contract (ex designate contract) stores list
of keys per role. Main net uses NeoFSAlphabet role to store keys of
alphabet nodes of inner ring. Side chain uses the same role to store
keys of all inner ring nodes, including alphabet.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Committee invocations use other M/N parameters of multi signature
signer address. For committee M = N/2 + 1
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Replace usage of `cache.ClientCache` type with interface with similar
signature. This will further allow overloading clients without affecting the
logic of dependent packages.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Implement in-memory `Storage` which is going to be used to submit the
results of interactions with network members. `Storage` also provides an
iterator interface, so the component can be used in `Controller`.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Implement `Controller` designed to analyze the values collected by the local
node (the source is hidden behind Writer/WriterProvider interfaces) and
transfer them to the destination (hidden behind Iterator / IteratorProvider
interface).
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Metabase should not store payloads of objects. Make Put operation to cut
object payload before saving binary object in metabase.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Metabase should not store payloads of objects. Set payload in generated test
object. Ascertain that objects returned by Get method have no payload.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
On the `Deposit` events add gas balance check.
Make transfer only if the balance is greater
than the `GasTransferThreshold` that is defined
with environmental variable.
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
At object.Put operation node does not transfer any
data. It is done in the stream inside, so we should
register duration from `object.Put` invocation until
`CloseAndRecv` on the stream.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
We can't rely on object size in the header because it
might be omitted on initial put or it can be 0xFF.. on
streaming data.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Because options are not used when client is already in cache
providing them to shared cache is misleading at best.
In the worst case `dial_timeout` is set randomly (because of race
condition) which can lead to one service having `dial_timeout` of
another. Thus we set default client creation options when cache is
created.
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
Replace `eacl.Storage` interface implementation from eACL lib to neofs-node
app package. Remove `eacl.WithMorphClient` option in order to abstract eACL
validator from eACL storage implementation.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Previously UN-LOCODE attribute was required for each network map candidate.
In the absence of this attribute, the candidate was not allowed into the
network map. After revising the requirements for candidates, it was decided
not to require the mandatory installation of the attribute by candidates.
From now inner ring does not modify location attributes of the network map
candidate in the absence of UN-LOCODE attribute and does not block entry
into the network map for this criterion.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
With UN/LOCODE support, storage node may have
`UN-LOCODE` attribute. Policy parser should support
both `Ident` and `Strings` as filter keys to parse
rules such as `FILTER "UN-LOCODE" EQ "RU LED" AS F`.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Right now we pass redundant copy to callback outside the for-loop through
the helpful boolean variable instead of calling it deeply nested.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Detect redundant local copy of the object in Object Policer. Add redundant
copy callback (`WithRedundantCopyCallback` option). Pass address of the
redundant copy to callback.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Add `InhumePrm.MarkAsGarbage` method which marks passed objects to be
removed from local storage. Update `InhumePrm.WithTarget` doc to prevent
conflicting use with the new method.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
NeoFS contract can be deployed in sidechain instead of main chain.
Add `without_mainnet` config flag that can switch IR node to work with
sidechain only. By default this flag is unset.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
In previous implementation IR worked with exactly 7 alphabetic contracts
only. Actually number of contracts is limited to only the Glagolitic
alphabet.
Make IR to work with any valid number of alphabetic contracts. Change parser
of alphabetic contract addresses to read amount of processing contracts
before performance. Make Alphabet processor to use interface of the
alphabetic contract group. Use `alphabetContracts` type in IR `Server`.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Define `alphabetContracts` type that map glagolic letters to smart contract
addresses. Implement constructor and all methods which are going to be used
in IR processing.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Define `glagolicLetter` enumeration of the Glagolitsa alphabet letters.
Implement `configString` method that returns config-compatible string format
of the letters.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
There is no need to specify that IR indices are 32 bits in size.
Change return types of `Indexer` interface methods in audit and alphabet
packages. Support interface changes in `Server` implementation.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Re-compile protobuf definition of Control service. Implement required
messages on DropObjects RPC request and response messages. Implement
`DropObjects` method on Control service server of the node. Use
`StorageEngine.Delete` method as a deleted object handler on server.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
There is a need to define storage node's interface to remove objects from
the local storage.
Define `DropObjects` RPC in `ControlService`. Define `DropObjectsRequest` /
`DropObjectsResponse` structure of the request / response messages.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Implement `NetworkInfo` calls on full stack of Netmap services. Current
epoch is read from node local state, magic number is read via `MagicNumber`
call of morph client.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Implement `Client.MagicNumber` method that returns magic number of the
network to which the underlying RPC node client is connected.
Network magic value is received via `GetNetwork` method.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
According to nspcc-dev/neofs-api#136 tombstone body should store the same
attribute as in object header. If they are different, then check is failed
with `errTombstoneExpiration`.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Creating tombstones for tombstones is prohibited in NeoFS system. Metabase
graveyard contains records of the form {address: address}: key is an address
of inhumed object, value is an address of the tombstone. To prevent creation
tombstones for tombstones metabase must control incoming Inhume calls:
* if Inhume target is a tombstone, then "grave" should not be added;
* if {a1:a2} "grave" was created earlier and {a2: a3} "grave" came later,
then first "grave" must be removed as tomb-on-tomb.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Change Shard's garbage remover to interrupt iterating over the metabase
graveyard when the buffer is full to the max size (`WithRemoverBatchSize`
Shard's option).
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Make `DB.IterateOverGraveyard` to immediately return nil if GraveHandler
returns ErrInterruptIterator.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Make object delete service to use network information to calculate and set
expiration of the created tombstone.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Add new epoch event handler to GC that finds all expired tombstones and
marks them and underlying objects to be removed. Shard uses callbacks
provided by the storage engine to mark underlying objects.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Implement `DB.IterateCoveredByTombstones` method that iterates over graves
and handles all objects under one of the tombstones.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Add new epoch event handler to GC that finds all expired non-tombstone
objects and marks them to be removed.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Implement `DB.IterateExpired` method that iterates over the objects in
metabase that are expired at particular epoch.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Group handlers of the particular event to a WaitGroup and wait for it before
the next event handling. This will ensure that all handlers complete and
prevent potential conflicts between past and present jobs.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
`Shard.Init` method creates a new GC instance from shard configuration and
starts GC's workers through `init` call. In initial implementation GC
routines are indefinite and can be killed only with by application shutdown.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Shard's GC component consists of:
* asynchronous remover that periodically wake up and removes all garbage
objects from the shard, and goes to sleep for particular time interval;
* external event listener that distributes jobs between workers;
* group of workers that can handle a single job related to particular
external event.
Remover and event listener represents go-routines which are started by
`init` method (calls from `Shard.Init`). In initial version all event
handlers are interrupted: this means that next event of the same type will
interrupt previous handling and start the new one.
GC is fully encapsulated in Shard. All GC configurations are reflected in
Shard's configuration.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Implement `DB.IterateOverGraveyard` method that iterates over all graves and
passes passes their descriptors (new type `Grave`) to handler (new type
`GraveHandler`). `Grave` currently have buried object address and garbage
flag.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Replace single target address in `InhumePrm` with the list of addresses.
Change corresponding parameter in `WithTarget` and `MarkAsGarbage` methods
to variadic.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Replace single target address in `InhumePrm` with the list of addresses.
Rename `WithAddress` method to `WithAddresses` and change parameter to
variadic.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Make `StorageEngine.Delete` to execute `Inhume` operation with
`MarkAsGarbage` parameter on the `Shard` that holds the object. Searching of
the particular shard is performed through iterating over HRW-sorted shards.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Implement `InhumePrm.MarkAsGarbage` method that leads to marking object as
garbage in metabase. Update `InhumePrm.WithTarget` doc indicating a conflict
with the new method.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Implement `InhumePrm.WithGCMark` method that marks the object as garbage in
graveyard. Update `InhumePrm.WithTombstoneAddress` doc indicating a conflict
with the new method. Update `Inhume` function doc about tombstone address
parameter.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Delete operation of Metabase is performed on group of objects. The set being
removed can contain descendants of a common parent. In the case when all
descendants of a parent object are deleted, it must also be deleted from
the metabase. In the previous implementation, this was not done due to the
chosen approach to counting references to the parent.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
The lifetime of an object can be limited by specifying a correspondin
well-known attribute. Node should refuse to save expired objects.
Checking objects in FormatValidator is extended with an expiration attribute
parsing step.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
In previous implementation StorageEngine.Inhume operation forced Shard
.Inhume call on all internal shards. There is a need to inhume object in a
single shard. To achieve this, Inhume operation is performed in next steps:
1. iterate over sorted shards, check object presence through Exists call;
2. if object exists at any shard in step 1 => inhume it and return on
success;
3. if no shards contain the object => iterate over sorted shards again and
try to inhume the object at first possible shard;
4. if all Inhume calls are failed => return an error.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
All node info attribute transformations can't guarantee
the order of attributes. However it should be consistent
otherwise smart-contract won't be able to collect signatures
and approve transaction.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Node info validator may change node attributes, e.g. update
it with human-readable location attributes based on LOCODE.
So inner ring node should provide new node info binary to
smart contract.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Scanning subdivision csv-table entries one-by-one takes significant time and
system resources. To speed up random access to table records, on the first
call, the table is pumped into memory (map). On subsequent calls, I/O
operations are not performed.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Scanning csv-table entries one-by-one takes significant time and system
resources. To speed up random access to table records, on the first call,
the table is pumped into memory (map). On subsequent calls, I/O operations
are not performed.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Inner ring Server does not modify LOCODE database (Put method), thus it is
better to open it in RO mode.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Add ReadOnly function that returns Option that enables read-only mode in DB.
RO mode can be used by processes that won't modify the DB in order to not
acquire write flock.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Set timeout option of BoltDB Open operation to 3s in order to prevent
indefinite waiting for file lock.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Implement DB interface required by LOCODE validator on new wrapper over the
LOCODE Bolt DB (Record on new wrapper over LOCODE Bolt DB entries).
Construct LOCODE validator and pass it to Netmap processor's constructor as
NodeValidator parameter.
Thus, candidates for a network map must set LOCODE attribute for which there
is an entry in the NeoFS location database.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Keep list of functions which are called first when the server starts (method
Server.Start). If any of the starters returns an error, the server will not
start. Such starters will mainly be used for resources that need to be
initialized after a successful server construction, but before its main work
(e.g. local files).
Keep list of functions which are called when the server stops (Server.Stop
method). Such closers will mainly be used for resources that need to be
released after server shutdown (e.g. initialized by starters).
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Define a structure for dealing with the geographic location of nodes.
Implement VerifyAndUpdate (with the same purpose as NodeValidator interface)
that checks LOCODE attribute and fills other attributes of the location.
Technically the entity is a wrapper over the NeoFS location database: it
maps the node LOCODE to the database record from which the new attributes
are generated.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Define NodeValidator interface of the entity that checks and finalizes
NodeInfo structure. Add NodeValidator to Netmap processor. Pass NodeInfo
structures of network map candidates to NodeValidator in order to verify it
and prepare to final state required by network.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Define NeoFS location database based on BoltDB. Implement methods to save
the record by key (Put) and to read the record by key (Get).
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Define database of Earth's polygons in GeoJSON format. Implement resolving
of geo point to continent in which it is located through point-in-polygon
calculation.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Implement airport database based on csv OpenFlights table. Implement
UN/LOCODE entry matcher. Implement country namespace.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Define structure of keys and records of the location database. Define the
interfaces of all components necessary for the formation of the database.
Implement the function of filling the database.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Define the data types needed to work with LOCODE's in NeoFS (country code,
location code, coordinates). Implement string parsers for new types.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Check if `new(big.Int)` will be efficient later and replace
all `big.NewInt()` in code or leave it as it is.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
TxTable used twice in context to transfer assets to
and from banking account. There is no need to store
instance of table persistently.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Some transfers from container owners into bank account may
fail due to lack of assets, so we have to deal with remaining
amount of assets in banking account.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Add SignWithRFC6979 option to signature verification function since eACL
table are signed by users with this option.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Since the contract started returning the table signature, it became
necessary to check its correctness.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Basic settlement context is a main structure that
implement logic of basic settlement phases: collecting
assets from container owners and then distributing them
to storage nodes.
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
Implement route Builder interface on wrapper over the container placement
builder, Component implies exactly one transfer to each of the most weight
nodes of the container (according to some weighing algorithm).
Implementation is planned for use when transferring local estimates of
storage nodes.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Implement a component for transmitting the value of the used container space
along a route defined in the system. Implement WriterProvider interface on
it. By implementation, it is the link between the route planner and the
point-to-point transmitter, and abstracts from the implementation of both of
them. In the future, this implementation will be used as a transmitter of
local estimates of storage nodes among themselves.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Implement API methods of the Container contracts client corresponding
to the calls of the contract for storing the used space of the container
("putContainerSize", "getContainerSize", "listContainerSizes"). Extend
the wrapper over the client with methods abstracted from sidechen calls.
In particular, the method of storing the value will be used to record
the estimates of the used space of containers calculated by the network
participants.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Implement functions to wrap Writer or Iterator. The resulting wrapper
provides WriterProvider or IteratorProvider interface respectively.
Such a wrapper can be used as a single storage instance provider
regardless of context.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
Implement a component that stores the values of the used space of
containers. The storage allows you to write several values for a fixed
container and epoch number, and read the averaged estimates of all
accumulated values. All values are stored in memory. This component is
planned to be used as an accumulator of opinions from various network
participants about the fullness of the container.
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>