| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
* console: fix typo in comment
* contracts/release: fix typo in comment
* core: fix typo in comment
* eth: fix typo in comment
* miner: fix typo in comment
|
|
|
|
|
|
|
|
| |
* cmd, consensus, core, miner: instatx clique for --dev
* cmd, consensus, clique: support configurable --dev block times
* cmd, core: allow --dev to use persistent storage too
|
| |
|
| |
|
|
|
|
|
|
| |
* core: only fire one chain head per batch
* miner: announce chan events synchronously
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ethdb: add Putter interface and Has method
* ethdb: improve docs and add IdealBatchSize
* ethdb: remove memory batch lock
Batches are not safe for concurrent use.
* core: use ethdb.Putter for Write* functions
This covers the easy cases.
* core/state: simplify StateSync
* trie: optimize local node check
* ethdb: add ValueSize to Batch
* core: optimize HasHeader check
This avoids one random database read get the block number. For many uses
of HasHeader, the expectation is that it's actually there. Using Has
avoids a load + decode of the value.
* core: write fast sync block data in batches
Collect writes into batches up to the ideal size instead of issuing many
small, concurrent writes.
* eth/downloader: commit larger state batches
Collect nodes into a batch up to the ideal size instead of committing
whenever a node is received.
* core: optimize HasBlock check
This avoids a random database read to get the number.
* core: use numberCache in HasHeader
numberCache has higher capacity, increasing the odds of finding the
header without a database lookup.
* core: write imported block data using a batch
Restore batch writes of state and add blocks, tx entries, receipts to
the same batch. The change also simplifies the miner.
This commit also removes posting of logs when a forked block is imported.
* core: fix DB write error handling
* ethdb: use RLock for Has
* core: fix HasBlock comment
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* core: remove redundant storage of transactions and receipts
* core, eth, internal: new transaction schema usage polishes
* eth: implement upgrade mechanism for db deduplication
* core, eth: drop old sequential key db upgrader
* eth: close last iterator on successful db upgrage
* core: prefix the lookup entries to make their purpose clearer
|
|
|
|
|
|
|
|
|
| |
With this commit, core/state's access to the underlying key/value database is
mediated through an interface. Database errors are tracked in StateDB and
returned by CommitTo or the new Error method.
Motivation for this change: We can remove the light client's duplicated copy of
core/state. The light client now supports node iteration, so tracing and storage
enumeration can work with the light client (not implemented in this commit).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit is a preparation for the upcoming metropolis hardfork. It
prepares the state, core and vm packages such that integration with
metropolis becomes less of a hassle.
* Difficulty calculation requires header instead of individual
parameters
* statedb.StartRecord renamed to statedb.Prepare and added Finalise
method required by metropolis, which removes unwanted accounts from
the state (i.e. selfdestruct)
* State keeps record of destructed objects (in addition to dirty
objects)
* core/vm pre-compiles may now return errors
* core/vm pre-compiles gas check now take the full byte slice as argument
instead of just the size
* core/vm now keeps several hard-fork instruction tables instead of a
single instruction table and removes the need for hard-fork checks in
the instructions
* core/vm contains a empty restruction function which is added in
preparation of metropolis write-only mode operations
* Adds the bn256 curve
* Adds and sets the metropolis chain config block parameters (2^64-1)
|
| |
|
|
|
|
|
|
| |
* consensus, core, ethstats: use engine specific block beneficiary
* core, eth, les, miner: use explicit beneficiary during mining
|
| |
|
| |
|
|
|
|
|
| |
This commit adds pluggable consensus engines to go-ethereum. In short, it
introduces a generic consensus interface, and refactors the entire codebase to
use this interface.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* common: remove CurrencyToString
Move denomination values to params instead.
* common: delete dead code
* common: move big integer operations to common/math
This commit consolidates all big integer operations into common/math and
adds tests and documentation.
There should be no change in semantics for BigPow, BigMin, BigMax, S256,
U256, Exp and their behaviour is now locked in by tests.
The BigD, BytesToBig and Bytes2Big functions don't provide additional
value, all uses are replaced by new(big.Int).SetBytes().
BigToBytes is now called PaddedBigBytes, its minimum output size
parameter is now specified as the number of bytes instead of bits. The
single use of this function is in the EVM's MSTORE instruction.
Big and String2Big are replaced by ParseBig, which is slightly stricter.
It previously accepted leading zeros for hexadecimal inputs but treated
decimal inputs as octal if a leading zero digit was present.
ParseUint64 is used in places where String2Big was used to decode a
uint64.
The new functions MustParseBig and MustParseUint64 are now used in many
places where parsing errors were previously ignored.
* common: delete unused big integer variables
* accounts/abi: replace uses of BytesToBig with use of encoding/binary
* common: remove BytesToBig
* common: remove Bytes2Big
* common: remove BigTrue
* cmd/utils: add BigFlag and use it for error-checked integer flags
While here, remove environment variable processing for DirectoryFlag
because we don't use it.
* core: add missing error checks in genesis block parser
* common: remove String2Big
* cmd/evm: use utils.BigFlag
* common/math: check for 256 bit overflow in ParseBig
This is supposed to prevent silent overflow/truncation of values in the
genesis block JSON. Without this check, a genesis block that set a
balance larger than 256 bits would lead to weird behaviour in the VM.
* cmd/utils: fixup import
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Reworked the EVM gas instructions to use 64bit integers rather than
arbitrary size big ints. All gas operations, be it additions,
multiplications or divisions, are checked and guarded against 64 bit
integer overflows.
In additon, most of the protocol paramaters in the params package have
been converted to uint64 and are now constants rather than variables.
* common/math: added overflow check ops
* core: vmenv, env renamed to evm
* eth, internal/ethapi, les: unmetered eth_call and cancel methods
* core/vm: implemented big.Int pool for evm instructions
* core/vm: unexported intPool methods & verification methods
* core/vm: added memoryGasCost overflow check and test
|
|
|
|
| |
This reverts commit 8b57c494908637a5c0e74f8f7a13b3218e026757.
|
| |
|
|\
| |
| | |
event: add new Subscription type and related utilities
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The Subscription type is gone, all uses are replaced by
*TypeMuxSubscription. This change is prep-work for the
introduction of the new Subscription type in a later commit.
gorename -from '"github.com/ethereum/go-ethereum/event"::Event' -to TypeMuxEvent
gorename -from '"github.com/ethereum/go-ethereum/event"::muxsub' -to TypeMuxSubscription
gofmt -w -r 'Subscription -> *TypeMuxSubscription' ./event/*.go
find . -name '*.go' -and -not -regex '\./vendor/.*' \| xargs gofmt -w -r 'event.Subscription -> *event.TypeMuxSubscription'
|
|/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Reworked the EVM gas instructions to use 64bit integers rather than
arbitrary size big ints. All gas operations, be it additions,
multiplications or divisions, are checked and guarded against 64 bit
integer overflows.
In additon, most of the protocol paramaters in the params package have
been converted to uint64 and are now constants rather than variables.
* common/math: added overflow check ops
* core: vmenv, env renamed to evm
* eth, internal/ethapi, les: unmetered eth_call and cancel methods
* core/vm: implemented big.Int pool for evm instructions
* core/vm: unexported intPool methods & verification methods
* core/vm: added memoryGasCost overflow check and test
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
This significantly reduces the dependency closure of ethclient, which no
longer depends on core/vm as of this change.
All uses of vm.Logs are replaced by []*types.Log. NewLog is gone too,
the constructor simply returned a literal.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The run loop, which previously contained custom opcode executes have been
removed and has been simplified to a few checks.
Each operation consists of 4 elements: execution function, gas cost function,
stack validation function and memory size function. The execution function
implements the operation's runtime behaviour, the gas cost function implements
the operation gas costs function and greatly depends on the memory and stack,
the stack validation function validates the stack and makes sure that enough
items can be popped off and pushed on and the memory size function calculates
the memory required for the operation and returns it.
This commit also allows the EVM to go unmetered. This is helpful for offline
operations such as contract calls.
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
The transaction pool keeps track of the current nonce in its local pendingState. When a
new block comes in the pendingState is reset. During the reset it fetches multiple times
the current state through the use of the currentState callback. When a second block comes
in during the reset its possible that the state changes during the reset. If that block
holds transactions that are currently in the pool the local pendingState that is used to
determine nonces can get out of sync.
|
|
|
|
|
|
|
|
| |
* miner: removed unnecessary state.Copy()
* eth: made use of new miner method without state copying
* miner: More documentation about new method
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit implements EIP158 part 1, 2, 3 & 4
1. If an account is empty it's no longer written to the trie. An empty
account is defined as (balance=0, nonce=0, storage=0, code=0).
2. Delete an empty account if it's touched
3. An empty account is redefined as either non-existent or empty.
4. Zero value calls and zero value suicides no longer consume the 25k
reation costs.
params: moved core/config to params
Signed-off-by: Jeffrey Wilcke <jeffrey@ethereum.org>
|
|
|
| |
The pending state was not copied while not mining, leading to a data race.
|
|
|
|
|
|
|
|
|
|
| |
This commit replaces the deep-copy based state revert mechanism with a
linear complexity journal. This commit also hides several internal
StateDB methods to limit the number of ways in which calling code can
use the journal incorrectly.
As usual consultation and bug fixes to the initial implementation were
provided by @karalabe, @obscuren and @Arachnid. Thank you!
|
| |
|
| |
|
|\
| |
| | |
miner: Prevent attempts to close nil quit channel in agent (fixes #2948)
|
| |
| |
| |
| |
| |
| | |
#2948)
Also remove the now un-needed mutex locking in Start() and Stop()
|
| | |
|
| | |
|
|/ |
|
|
|
|
|
| |
This ensures that package core doesn't depend on package accounts and
resolves an age-old TODO.
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Shutting down geth prints hundreds of annoying error messages in some
cases. The errors appear because the Stop method of eth.ProtocolManager,
miner.Miner and core.TxPool is asynchronous. Left over peer sessions
generate events which are processed after Stop even though the database
has already been closed.
The fix is to make Stop synchronous using sync.WaitGroup.
For eth.ProtocolManager, in order to make use of WaitGroup safe, we need
a way to stop new peer sessions from being added while waiting on the
WaitGroup. The eth protocol Run function now selects on a signaling
channel and adds to the WaitGroup only if ProtocolManager is not
shutting down.
For miner.worker and core.TxPool the number of goroutines is static,
WaitGroup can be used in the usual way without additional
synchronisation.
|
| |
|
|
|
|
|
|
| |
- Manager.Accounts no longer returns an error.
- Manager methods take Account instead of common.Address.
- All uses of Account with unkeyed fields are converted.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
This PR introduces a 10% probability that you'll run the client with the
JIT enabled testing the new client and helps us potentially catch
errors when reported.
This feature is **disabled** for miners (disabling the JIT completely).
The JIT can however be force for miners if they enable both --jitvm and
--forcejit.
|
|
|
|
|
|
|
|
|
| |
Added chain configuration options and write out during genesis database
insertion. If no "config" was found, nothing is written to the database.
Configurations are written on a per genesis base. This means
that any chain (which is identified by it's genesis hash) can have their
own chain settings.
|
|\
| |
| | |
core, core/vm, tests: changed the initialisation behaviour of the EVM
|
| |
| |
| |
| |
| | |
The EVM is now initialised with an additional configured object that
allows you to turn on debugging options.
|
|/ |
|
| |
|
|
|
|
|
|
| |
* Removed some strange code that didn't apply state reverting properly
* Refactored code setting from vm & state transition to the executioner
* Updated tests
|
|
|
|
|
|
| |
Pending logs are now filterable through the Go API. Filter API changed
such that each filter type has it's own bucket and adding filter
explicitly requires you specify the bucket to put it in.
|
| |
|
| |
|
|\
| |
| | |
core, core/types, miner: fix transaction nonce-price combo sort
|
| | |
|
|/ |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
This removes the burden on a single object to take care of all
validation and state processing. Now instead the validation is done by
the `core.BlockValidator` (`types.Validator`) that takes care of both
header and uncle validation through the `ValidateBlock` method and state
validation through the `ValidateState` method. The state processing is
done by a new object `core.StateProcessor` (`types.Processor`) and
accepts a new state as input and uses that to process the given block's
transactions (and uncles for rewords) to calculate the state root for
the next block (P_n + 1).
|
|
|
|
|
|
| |
This PR fixes an issue where the remote worker was stopped twice and not
properly handled. This adds a synchronised running check to the start
and stop methods preventing closing of a channel more than once.
|
|
|
|
|
|
|
|
|
|
|
| |
There are a bunch of changes required to make this work:
- in miner: allow unregistering agents, fix RemoteAgent.Stop
- in eth/filters: make FilterSystem.Stop not crash
- in rpc/comms: move listen loop to platform-independent code
Fixes #1930. I ran the shell loop there for a few minutes and didn't see
any changes in the memory profile.
|
|\
| |
| | |
eth/63 fast synchronization algorithm
|
| | |
|
|/
|
|
|
|
|
| |
The amount of gas available for tx execution was tracked in the
StateObject representing the coinbase account. This commit makes the gas
counter a separate type in package core, which avoids unintended
consequences of intertwining the counter with state logic.
|
|\
| |
| | |
core, eth/filters, miner, xeth: Optimised log filtering
|
| |
| |
| |
| |
| |
| |
| | |
Log filtering is now using a MIPmap like approach where addresses of
logs are added to a mapped bloom bin. The current levels for the MIP are
in ranges of 1.000.000, 500.000, 100.000, 50.000, 1.000. Logs are
therefor filtered in batches of 1.000.
|
|\ \
| | |
| | | |
all: Add GPU mining, disabled by default
|
| | | |
|
| |/
|/| |
|
| | |
|
| |
| |
| |
| |
| |
| | |
* Renamed ChainManager to BlockChain
* Checkpointing is no longer required and never really properly worked
when the state was corrupted.
|
|/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Moved `vm.Transfer` to `core` package and changed execution to call
`env.Transfer` instead of `core.Transfer` directly.
* core/vm: byte code VM moved to jump table instead of switch
* Moved `vm.Transfer` to `core` package and changed execution to call
`env.Transfer` instead of `core.Transfer` directly.
* Byte code VM now shares the same code as the JITVM
* Renamed Context to Contract
* Changed initialiser of state transition & unexported methods
* Removed the Execution object and refactor `Call`, `CallCode` &
`Create` in to their own functions instead of being methods.
* Removed the hard dep on the state for the VM. The VM now
depends on a Database interface returned by the environment. In the
process the core now depends less on the statedb by usage of the env
* Moved `Log` from package `core/state` to package `core/vm`.
|
| |
|
|\
| |
| | |
core, eth, miner: use pure header validation
|
| | |
|
|/ |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
| |
currently, under normal circumstances, you always set the timestamp to previous.Time() + 1.
credits to https://www.reddit.com/r/ethereum/comments/3jcs5r/code_avg_block_time_vs_difficulty_adjustment/cuoi4op
style
|
| |
|
| |
|
| |
|
| |
|
| |
|
|\
| |
| | |
cmd/geth, eth: added canonical extra data
|
| | |
|
|/ |
|
| |
|
|\
| |
| | |
core, miner: added difficulty bomb
|
| | |
|
|/ |
|
|
|
|
| |
I forgot to update one instance of "go-ethereum" in commit 3f047be5a.
|
|
|
|
|
| |
All code outside of cmd/ is licensed as LGPL. The headers
now reflect this by calling the whole work "the go-ethereum library".
|
| |
|
|
|
|
| |
Moved the state sync so it only syncs the state when the block mining yield a possitive result
|
|
|
|
|
|
|
|
|
| |
Work is now handled and carried over multiple sessions. Previously one
session only was assumed, potentially resulting in invalid (outdated)
work
* Larger work / result queue
* Full validation option
|
|\
| |
| | |
miner, xeth: fire log event during mining. Fix return raw tx
|
| | |
|
|/ |
|
| |
|
| |
|
| |
|
|
|
|
|
| |
Removed VM errors from the consensus errors. They now used for output
only.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Update => SyncIntermediate
* Added SyncObjects
SyncIntermediate only updates whatever has changed, but, as a side
effect, requires much more disk space.
SyncObjects will only sync whatever is required for a block and will not
save intermediate state to disk. As drawback this requires more time
when more txs come in.
|
|
|
|
|
| |
* Added GetReceiptsFromBlock, GetReceipt, PutReceipts
* Added ContractAddress to receipt. See #1042
|
| |
|
|
|
|
|
|
|
|
| |
* Miners do now verify their own header, not their state.
* Changed old putTx and putReceipts to be exported
* Moved writing of transactions and receipts out of the block processer
in to the chain manager. Closes #1386
* Miner post ChainHeadEvent & ChainEvent. Closes #1388
|
| |
|
|
|
|
|
|
|
|
| |
This fixes an issue with the lru cache not being available when calling
WriteBlock. WriteBlock previously always assumed to be called from the
InsertChain where the lru cache was always created prior to calling
WriteBlock. When being called from the worker this could lead in to a
nil pointer exception being thrown and causing database corruption.
|
|\
| |
| |
| |
| |
| | |
Conflicts:
core/chain_manager.go
miner/worker.go
|
| | |
|
| | |
|
| | |
|
| | |
|
|/ |
|
|
|
|
|
|
| |
* BuyGas => SubGas
* RefundGas => AddGas
* SetGasPool => SetGasLimit
|
| |
|
| |
|
|
|
|
| |
@see trace https://gist.github.com/eupraxic/87fdfefe702c51d5944d
|
|
|
|
|
|
|
|
| |
Removed the managed tx state from the chain manager to the transaction
pool where it's much easier to keep track of nonces (and manage them).
The transaction pool now also uses the queue and pending txs differently
where queued txs are now moved over to the pending queue (i.e. txs ready
for processing and propagation).
|
| |
|
| |
|
|
|
|
|
|
|
| |
* Miner should no longer generate blocks with a time stamp less or equal
than it's parent.
* Future blocks are no longer processed and queued directly.
Closes #1118
|
| |
|
|
|
|
| |
if you track stale blocks, then you quickly overflow your ring buffer in the local network case where you're mining every block and generating a lot of stales.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
This helps determine which blocks are unlikely to end up as uncles
* Store the 5 most recent locally mined block numbers
* On every imported block, check if the 5-deep block num is in that store
* Also confirm that the block is signed with miner's coinbase
Why not just check the coinbase? This log is useful if you're running
multiple miners and want to know if *this* miner is performing well.
|
| |
|
| |
|
| |
|
| |
|
|\
| |
| | |
Parallelise nonce checks
|
| | |
|
| | |
|
|/ |
|
|
|
|
| |
Start event has moved because it could possibly could stall the miner
|
| |
|
| |
|
| |
|
|
|
|
| |
Fork resolving fixes #940
|
| |
|
|\
| |
| | |
Make read of ethash hashrate atomic and update ethash godep
|
| | |
|
| | |
|
|/ |
|
|
|
|
| |
* Also fix address types post-rebase
|
|
|
|
| |
Miner does not ignore low gas txs from accounts that are owned.
|
|
|
|
|
| |
Miner threads are now settable through the admin interface (closes #897)
and specify 0 CPU worker threads when eth_getWork is called (closes #916)
|
|
|
|
| |
Ensures that the Get Work results are a consistent length. Closes #917
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
* core: Added GasPriceChange event
* eth: When one of the DB flush methods error a fatal error log message
is given. Hopefully this will prevent corrupted databases from
occuring.
* miner: remove transactions with low gas price. Closes #906, #903
|
| |
|
| |
|
| |
|
|
|
|
|
| |
* --gasprice "<num>" flag
* admin.miner.setGasPrice( <num> )
|
| |
|
| |
|
|
|
|
|
|
| |
* Changed CalcGasLimit to no longer need current block
* Added a gas * price + value on tx validation
* Transactions in the pool are now re-validated once every X
|
| |
|
| |
|
|
|
|
| |
64bit atomic operations are not available on all 32bit platforms.
|
|
|
|
|
|
|
|
|
| |
When worker encounters a gas limit error, subsequent txs should be
ignored from that particular account. This will prevent:
1. Nonce errors been thrown all around
2. The "Known tx" error. Closes #719
3. Repeated contract address. Closes #731
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
| |
Processing transactions should continue when a transaction throws a gas
limit reached error. Other transactions may actually succeed.
|
|
|
|
|
|
|
|
|
|
| |
The transaction pool will now some easily be able to pre determine the
validity of a transaction by checking the following:
* Account existst
* gas limit higher than the instrinsic gas
* enough funds to pay upfront costs
* nonce check
|
|
|
|
|
|
|
| |
Logs are now recorded per transactions instead of tossing them out after
each transaction. This should also fix an issue with
`eth_getFilterLogs` (#629) Also now implemented are the `transactionHash,
blockHash, transactionIndex, logIndex` on logs. Closes #654.
|
| |
|
| |
|
| |
|
|
|
|
|
|
| |
* miner control moved to `admin.miner`
* miner option to set extra data
* block extra now bytes
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
| |
The uncle rewards were changed in the block processor. This change will
reflect those changes in the miner as well.
|
|
|
|
| |
* Miners could stall because the worker wasn't aware the miner was done
|
| |
|
|
|
|
|
| |
* In case of uncle mining (e.g. same TS) the miner would stop if all
threads happened to mine a potential uncle
|
| |
|
|
|
|
|
| |
* Instead of delivering `Work` to the `Worker`, push a complete Block to
the `Worker` so that each agent can work on their own block.
|
| |
|
| |
|
| |
|
| |
|
|\ |
|
| | |
|
|/ |
|
|
|
|
|
| |
* WIP missing arguments for submitting new work
* GetWork **done**
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
| |
This avoids having to query the coinbase when creating the miner, which
in turn eliminates the dreaded startup error when no accounts are set
up. Later, this will also allow us to simply restart the miner when the
user picks a different coinbase.
This causes a lot of changes in other packages. These are included in
this commit because they're impossible to separate.
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|\
| |
| |
| |
| |
| |
| |
| |
| |
| | |
ethersphere-jsonlogs
Conflicts:
eth/block_pool.go
eth/block_pool_test.go
eth/protocol_test.go
miner/worker.go
|
| |\ |
|
| | | |
|
| | | |
|
|\| | |
|
| |/ |
|
| | |
|
|/ |
|